Signal Lab
{{ trial_id }}
{ const ok = await window.mojoConfirm({title:'Clear graph',message:'Remove all nodes and connections?',confirmLabel:'Clear',cancelLabel:'Cancel',variant:'warning'}); if(ok){ mojoLabClear(); window.mojoLabMarkSaved?.(); } }"
@mojo:lab-activate-tab.document="$nextTick(() => {
const el = document.getElementById('lab-canvas');
if (el) {
mojoLabClearHistory();
mojoLabInit(el, columns, labGraph);
// only override mojoLabInit's baseline when the tab has a known saved state;
// null means 'freshly loaded or blank' and mojoLabInit already set the right baseline
const tab = labTabs.find(t => t.id === labActiveTabId);
if (tab && tab.savedState !== null) window.mojoLabSetSavedState?.(tab.savedState);
}
mojoLabSetContext(columns, labSchemas, labName);
})"
x-init="
const _labInitCanvas = () => $nextTick(() => {
const el = document.getElementById('lab-canvas');
if (el) {
mojoLabInit(el, columns, labGraph);
const tab = labTabs.find(t => t.id === labActiveTabId);
if (tab && tab.savedState !== null) window.mojoLabSetSavedState?.(tab.savedState);
}
mojoLabSetContext(columns, labSchemas, labName);
});
$watch('labOpen', (open) => {
try { localStorage.setItem('mojo:lab:open', open ? '1' : '0'); } catch {}
if (!open) _saveTabs();
if (open) _labInitCanvas();
});
if (labOpen) _labInitCanvas();
$watch('labSchemas', (s) => { if (labOpen) mojoLabSetContext(columns, s, labName); });
$watch('labName', (n) => { if (labOpen) mojoLabSetContext(columns, labSchemas, n); });
">
Right-click → add node
+
Z
Undo
+
⇧
Redo
+
S
Save
+
C
Clear
Del
Remove
+
⇧
+
A
Arrange
+
⇧
+
F
Fit
Scroll to zoom · drag to pan