system-canvas-standalone 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12759,12 +12759,12 @@ var SystemCanvas = (() => {
12759
12759
  render: () => render,
12760
12760
  themes: () => themes
12761
12761
  });
12762
- var import_react24 = __toESM(require_react(), 1);
12762
+ var import_react25 = __toESM(require_react(), 1);
12763
12763
  var import_client = __toESM(require_client(), 1);
12764
12764
 
12765
12765
  // ../react/dist/components/SystemCanvas.js
12766
12766
  var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
12767
- var import_react23 = __toESM(require_react(), 1);
12767
+ var import_react24 = __toESM(require_react(), 1);
12768
12768
 
12769
12769
  // ../core/dist/themes/dark.js
12770
12770
  var darkTheme = {
@@ -15349,7 +15349,7 @@ var SystemCanvas = (() => {
15349
15349
  var import_react7 = __toESM(require_react(), 1);
15350
15350
  var clipboardSnapshot = null;
15351
15351
  function useMultiSelectClipboard(options) {
15352
- const { selectedIdsRef, nodesRef, edgesRef, viewport, onNodeAdd, onEdgeAdd, canvasRef, getCursorScreenPos } = options;
15352
+ const { selectedIdsRef, nodesRef, edgesRef, viewport, onNodeAdd, onEdgeAdd, canvasRef, getCursorScreenPos, onBeginBatch, onEndBatch } = options;
15353
15353
  const getCursorScreenPosRef = (0, import_react7.useRef)(getCursorScreenPos);
15354
15354
  getCursorScreenPosRef.current = getCursorScreenPos;
15355
15355
  const onNodeAddRef = (0, import_react7.useRef)(onNodeAdd);
@@ -15358,6 +15358,10 @@ var SystemCanvas = (() => {
15358
15358
  onEdgeAddRef.current = onEdgeAdd;
15359
15359
  const canvasRefRef = (0, import_react7.useRef)(canvasRef);
15360
15360
  canvasRefRef.current = canvasRef;
15361
+ const onBeginBatchRef = (0, import_react7.useRef)(onBeginBatch);
15362
+ onBeginBatchRef.current = onBeginBatch;
15363
+ const onEndBatchRef = (0, import_react7.useRef)(onEndBatch);
15364
+ onEndBatchRef.current = onEndBatch;
15361
15365
  (0, import_react7.useEffect)(() => {
15362
15366
  const handler = (e) => {
15363
15367
  const active = document.activeElement;
@@ -15430,12 +15434,14 @@ var SystemCanvas = (() => {
15430
15434
  toNode: oldToNew.get(edge.toNode)
15431
15435
  }));
15432
15436
  const ref = canvasRefRef.current;
15437
+ onBeginBatchRef.current?.();
15433
15438
  for (const node of clonedNodes) {
15434
15439
  onNodeAddRef.current(node, ref);
15435
15440
  }
15436
15441
  for (const edge of clonedEdges) {
15437
15442
  onEdgeAddRef.current(edge, ref);
15438
15443
  }
15444
+ onEndBatchRef.current?.();
15439
15445
  e.preventDefault();
15440
15446
  return;
15441
15447
  }
@@ -15447,8 +15453,298 @@ var SystemCanvas = (() => {
15447
15453
  }, [selectedIdsRef, nodesRef, edgesRef, viewport]);
15448
15454
  }
15449
15455
 
15450
- // ../react/dist/hooks/useZoomNavigation.js
15456
+ // ../react/dist/hooks/useCommandHistory.js
15451
15457
  var import_react8 = __toESM(require_react(), 1);
15458
+ function getCanvasRef(cmd) {
15459
+ if (cmd.type === "batch") {
15460
+ return cmd.commands.length > 0 ? getCanvasRef(cmd.commands[0]) : void 0;
15461
+ }
15462
+ return cmd.canvasRef;
15463
+ }
15464
+ function useCommandHistory(options) {
15465
+ const { nodesRef, edgesRef, onNodeAdd, onNodeUpdate, onNodesUpdate, onNodeDelete, onNodesDelete, onEdgeAdd, onEdgeUpdate, onEdgeDelete, maxDepth = 50, enabled = true, onUndo, onRedo } = options;
15466
+ const onNodeAddRef = (0, import_react8.useRef)(onNodeAdd);
15467
+ onNodeAddRef.current = onNodeAdd;
15468
+ const onNodeUpdateRef = (0, import_react8.useRef)(onNodeUpdate);
15469
+ onNodeUpdateRef.current = onNodeUpdate;
15470
+ const onNodesUpdateRef = (0, import_react8.useRef)(onNodesUpdate);
15471
+ onNodesUpdateRef.current = onNodesUpdate;
15472
+ const onNodeDeleteRef = (0, import_react8.useRef)(onNodeDelete);
15473
+ onNodeDeleteRef.current = onNodeDelete;
15474
+ const onNodesDeleteRef = (0, import_react8.useRef)(onNodesDelete);
15475
+ onNodesDeleteRef.current = onNodesDelete;
15476
+ const onEdgeAddRef = (0, import_react8.useRef)(onEdgeAdd);
15477
+ onEdgeAddRef.current = onEdgeAdd;
15478
+ const onEdgeUpdateRef = (0, import_react8.useRef)(onEdgeUpdate);
15479
+ onEdgeUpdateRef.current = onEdgeUpdate;
15480
+ const onEdgeDeleteRef = (0, import_react8.useRef)(onEdgeDelete);
15481
+ onEdgeDeleteRef.current = onEdgeDelete;
15482
+ const undoStack = (0, import_react8.useRef)([]);
15483
+ const redoStack = (0, import_react8.useRef)([]);
15484
+ const isUndoingRef = (0, import_react8.useRef)(false);
15485
+ const pendingBatchRef = (0, import_react8.useRef)(null);
15486
+ const [canUndo, setCanUndo] = (0, import_react8.useState)(false);
15487
+ const [canRedo, setCanRedo] = (0, import_react8.useState)(false);
15488
+ function syncBooleans() {
15489
+ setCanUndo(undoStack.current.length > 0);
15490
+ setCanRedo(redoStack.current.length > 0);
15491
+ }
15492
+ function pushCommand(cmd) {
15493
+ if (pendingBatchRef.current) {
15494
+ pendingBatchRef.current.push(cmd);
15495
+ return;
15496
+ }
15497
+ undoStack.current.push(cmd);
15498
+ if (undoStack.current.length > maxDepth)
15499
+ undoStack.current.shift();
15500
+ redoStack.current = [];
15501
+ syncBooleans();
15502
+ }
15503
+ function applyInverse(cmd) {
15504
+ switch (cmd.type) {
15505
+ case "node:add":
15506
+ onNodeDeleteRef.current?.(cmd.node.id, cmd.canvasRef);
15507
+ break;
15508
+ case "node:delete":
15509
+ onNodeAddRef.current?.(cmd.node, cmd.canvasRef);
15510
+ break;
15511
+ case "node:update":
15512
+ onNodeUpdateRef.current?.(cmd.id, cmd.prev, cmd.canvasRef);
15513
+ break;
15514
+ case "nodes:update":
15515
+ onNodesUpdateRef.current?.(cmd.updates.map((u) => ({ id: u.id, patch: u.prev })), cmd.canvasRef);
15516
+ break;
15517
+ case "nodes:delete":
15518
+ for (const node of cmd.nodes) {
15519
+ onNodeAddRef.current?.(node, cmd.canvasRef);
15520
+ }
15521
+ break;
15522
+ case "edge:add":
15523
+ onEdgeDeleteRef.current?.(cmd.edge.id, cmd.canvasRef);
15524
+ break;
15525
+ case "edge:delete":
15526
+ onEdgeAddRef.current?.(cmd.edge, cmd.canvasRef);
15527
+ break;
15528
+ case "edge:update":
15529
+ onEdgeUpdateRef.current?.(cmd.id, cmd.prev, cmd.canvasRef);
15530
+ break;
15531
+ case "batch":
15532
+ for (let i = cmd.commands.length - 1; i >= 0; i--) {
15533
+ applyInverse(cmd.commands[i]);
15534
+ }
15535
+ break;
15536
+ }
15537
+ }
15538
+ function applyForward(cmd) {
15539
+ switch (cmd.type) {
15540
+ case "node:add":
15541
+ onNodeAddRef.current?.(cmd.node, cmd.canvasRef);
15542
+ break;
15543
+ case "node:delete":
15544
+ onNodeDeleteRef.current?.(cmd.node.id, cmd.canvasRef);
15545
+ break;
15546
+ case "node:update":
15547
+ onNodeUpdateRef.current?.(cmd.id, cmd.patch, cmd.canvasRef);
15548
+ break;
15549
+ case "nodes:update":
15550
+ onNodesUpdateRef.current?.(cmd.updates.map((u) => ({ id: u.id, patch: u.patch })), cmd.canvasRef);
15551
+ break;
15552
+ case "nodes:delete":
15553
+ onNodesDeleteRef.current?.(cmd.nodes.map((n) => n.id), cmd.canvasRef);
15554
+ break;
15555
+ case "edge:add":
15556
+ onEdgeAddRef.current?.(cmd.edge, cmd.canvasRef);
15557
+ break;
15558
+ case "edge:delete":
15559
+ onEdgeDeleteRef.current?.(cmd.edge.id, cmd.canvasRef);
15560
+ break;
15561
+ case "edge:update":
15562
+ onEdgeUpdateRef.current?.(cmd.id, cmd.patch, cmd.canvasRef);
15563
+ break;
15564
+ case "batch":
15565
+ for (const c of cmd.commands) {
15566
+ applyForward(c);
15567
+ }
15568
+ break;
15569
+ }
15570
+ }
15571
+ const undo = (0, import_react8.useCallback)(() => {
15572
+ if (!enabled)
15573
+ return;
15574
+ const cmd = undoStack.current.pop();
15575
+ if (!cmd)
15576
+ return;
15577
+ isUndoingRef.current = true;
15578
+ applyInverse(cmd);
15579
+ isUndoingRef.current = false;
15580
+ redoStack.current.push(cmd);
15581
+ syncBooleans();
15582
+ onUndo?.(getCanvasRef(cmd));
15583
+ }, [enabled, onUndo]);
15584
+ const redo = (0, import_react8.useCallback)(() => {
15585
+ if (!enabled)
15586
+ return;
15587
+ const cmd = redoStack.current.pop();
15588
+ if (!cmd)
15589
+ return;
15590
+ isUndoingRef.current = true;
15591
+ applyForward(cmd);
15592
+ isUndoingRef.current = false;
15593
+ undoStack.current.push(cmd);
15594
+ if (undoStack.current.length > maxDepth)
15595
+ undoStack.current.shift();
15596
+ syncBooleans();
15597
+ onRedo?.(getCanvasRef(cmd));
15598
+ }, [enabled, onRedo, maxDepth]);
15599
+ const beginBatch = (0, import_react8.useCallback)(() => {
15600
+ if (!enabled)
15601
+ return;
15602
+ pendingBatchRef.current = [];
15603
+ }, [enabled]);
15604
+ const endBatch = (0, import_react8.useCallback)(() => {
15605
+ if (!enabled)
15606
+ return;
15607
+ const cmds = pendingBatchRef.current;
15608
+ pendingBatchRef.current = null;
15609
+ if (!cmds || cmds.length === 0)
15610
+ return;
15611
+ if (cmds.length === 1) {
15612
+ pushCommand(cmds[0]);
15613
+ return;
15614
+ }
15615
+ undoStack.current.push({ type: "batch", commands: cmds });
15616
+ if (undoStack.current.length > maxDepth)
15617
+ undoStack.current.shift();
15618
+ redoStack.current = [];
15619
+ syncBooleans();
15620
+ }, [enabled, maxDepth]);
15621
+ const wrappedOnNodeAdd = (0, import_react8.useCallback)(
15622
+ (node, canvasRef) => {
15623
+ if (enabled && !isUndoingRef.current) {
15624
+ pushCommand({ type: "node:add", node, canvasRef });
15625
+ }
15626
+ onNodeAddRef.current?.(node, canvasRef);
15627
+ },
15628
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15629
+ [enabled]
15630
+ );
15631
+ const wrappedOnNodeUpdate = (0, import_react8.useCallback)(
15632
+ (id2, patch, canvasRef) => {
15633
+ if (enabled && !isUndoingRef.current) {
15634
+ const node = nodesRef.current?.find((n) => n.id === id2);
15635
+ if (node) {
15636
+ const prev = Object.fromEntries(Object.keys(patch).map((k) => [k, node[k]]));
15637
+ pushCommand({ type: "node:update", id: id2, prev, patch, canvasRef });
15638
+ }
15639
+ }
15640
+ onNodeUpdateRef.current?.(id2, patch, canvasRef);
15641
+ },
15642
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15643
+ [enabled, nodesRef]
15644
+ );
15645
+ const wrappedOnNodesUpdate = (0, import_react8.useCallback)(
15646
+ (updates, canvasRef) => {
15647
+ if (enabled && !isUndoingRef.current) {
15648
+ const enriched = [];
15649
+ for (const u of updates) {
15650
+ const node = nodesRef.current?.find((n) => n.id === u.id);
15651
+ if (node) {
15652
+ const prev = Object.fromEntries(Object.keys(u.patch).map((k) => [k, node[k]]));
15653
+ enriched.push({ id: u.id, prev, patch: u.patch });
15654
+ }
15655
+ }
15656
+ if (enriched.length > 0) {
15657
+ pushCommand({ type: "nodes:update", updates: enriched, canvasRef });
15658
+ }
15659
+ }
15660
+ onNodesUpdateRef.current?.(updates, canvasRef);
15661
+ },
15662
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15663
+ [enabled, nodesRef]
15664
+ );
15665
+ const wrappedOnNodeDelete = (0, import_react8.useCallback)(
15666
+ (nodeId, canvasRef) => {
15667
+ if (enabled && !isUndoingRef.current) {
15668
+ const node = nodesRef.current?.find((n) => n.id === nodeId);
15669
+ if (node) {
15670
+ pushCommand({ type: "node:delete", node, canvasRef });
15671
+ }
15672
+ }
15673
+ onNodeDeleteRef.current?.(nodeId, canvasRef);
15674
+ },
15675
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15676
+ [enabled, nodesRef]
15677
+ );
15678
+ const wrappedOnNodesDelete = (0, import_react8.useCallback)(
15679
+ (nodeIds, canvasRef) => {
15680
+ if (enabled && !isUndoingRef.current) {
15681
+ const nodes = nodesRef.current?.filter((n) => nodeIds.includes(n.id)) ?? [];
15682
+ if (nodes.length > 0) {
15683
+ pushCommand({ type: "nodes:delete", nodes, canvasRef });
15684
+ }
15685
+ }
15686
+ onNodesDeleteRef.current?.(nodeIds, canvasRef);
15687
+ },
15688
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15689
+ [enabled, nodesRef]
15690
+ );
15691
+ const wrappedOnEdgeAdd = (0, import_react8.useCallback)(
15692
+ (edge, canvasRef) => {
15693
+ if (enabled && !isUndoingRef.current) {
15694
+ pushCommand({ type: "edge:add", edge, canvasRef });
15695
+ }
15696
+ onEdgeAddRef.current?.(edge, canvasRef);
15697
+ },
15698
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15699
+ [enabled]
15700
+ );
15701
+ const wrappedOnEdgeUpdate = (0, import_react8.useCallback)(
15702
+ (id2, patch, canvasRef) => {
15703
+ if (enabled && !isUndoingRef.current) {
15704
+ const edge = edgesRef.current?.find((e) => e.id === id2);
15705
+ if (edge) {
15706
+ const prev = Object.fromEntries(Object.keys(patch).map((k) => [k, edge[k]]));
15707
+ pushCommand({ type: "edge:update", id: id2, prev, patch, canvasRef });
15708
+ }
15709
+ }
15710
+ onEdgeUpdateRef.current?.(id2, patch, canvasRef);
15711
+ },
15712
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15713
+ [enabled, edgesRef]
15714
+ );
15715
+ const wrappedOnEdgeDelete = (0, import_react8.useCallback)(
15716
+ (edgeId, canvasRef) => {
15717
+ if (enabled && !isUndoingRef.current) {
15718
+ const edge = edgesRef.current?.find((e) => e.id === edgeId);
15719
+ if (edge) {
15720
+ pushCommand({ type: "edge:delete", edge, canvasRef });
15721
+ }
15722
+ }
15723
+ onEdgeDeleteRef.current?.(edgeId, canvasRef);
15724
+ },
15725
+ // eslint-disable-next-line react-hooks/exhaustive-deps
15726
+ [enabled, edgesRef]
15727
+ );
15728
+ return {
15729
+ wrappedOnNodeAdd,
15730
+ wrappedOnNodeUpdate,
15731
+ wrappedOnNodesUpdate,
15732
+ wrappedOnNodeDelete,
15733
+ wrappedOnNodesDelete,
15734
+ wrappedOnEdgeAdd,
15735
+ wrappedOnEdgeUpdate,
15736
+ wrappedOnEdgeDelete,
15737
+ beginBatch,
15738
+ endBatch,
15739
+ undo,
15740
+ redo,
15741
+ canUndo,
15742
+ canRedo
15743
+ };
15744
+ }
15745
+
15746
+ // ../react/dist/hooks/useZoomNavigation.js
15747
+ var import_react9 = __toESM(require_react(), 1);
15452
15748
  function expandRect(rect, factor) {
15453
15749
  if (factor === 1)
15454
15750
  return rect;
@@ -15486,16 +15782,16 @@ var SystemCanvas = (() => {
15486
15782
  }
15487
15783
  function useZoomNavigation(options) {
15488
15784
  const { enabled, config, nodes, currentCanvas, parentFrame, canvases, onResolveCanvas, onSeedCanvas, theme, getViewportSize, getCursorScreenPos, onEnter, onExit } = options;
15489
- const committingRef = (0, import_react8.useRef)(false);
15490
- (0, import_react8.useEffect)(() => {
15785
+ const committingRef = (0, import_react9.useRef)(false);
15786
+ (0, import_react9.useEffect)(() => {
15491
15787
  committingRef.current = false;
15492
15788
  }, [currentCanvas]);
15493
- const exitArmedRef = (0, import_react8.useRef)(false);
15494
- (0, import_react8.useEffect)(() => {
15789
+ const exitArmedRef = (0, import_react9.useRef)(false);
15790
+ (0, import_react9.useEffect)(() => {
15495
15791
  exitArmedRef.current = false;
15496
15792
  }, [currentCanvas, parentFrame]);
15497
- const prefetchRef = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
15498
- const prefetch = (0, import_react8.useCallback)((ref) => {
15793
+ const prefetchRef = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
15794
+ const prefetch = (0, import_react9.useCallback)((ref) => {
15499
15795
  if (!onResolveCanvas)
15500
15796
  return;
15501
15797
  if (canvases?.[ref])
@@ -15513,7 +15809,7 @@ var SystemCanvas = (() => {
15513
15809
  state.loading = false;
15514
15810
  });
15515
15811
  }, [canvases, onResolveCanvas, onSeedCanvas]);
15516
- const handleViewportChange = (0, import_react8.useCallback)((vp) => {
15812
+ const handleViewportChange = (0, import_react9.useCallback)((vp) => {
15517
15813
  if (!enabled)
15518
15814
  return;
15519
15815
  if (committingRef.current)
@@ -15652,7 +15948,7 @@ var SystemCanvas = (() => {
15652
15948
  onEnter,
15653
15949
  onExit
15654
15950
  ]);
15655
- const clearCommitting = (0, import_react8.useCallback)(() => {
15951
+ const clearCommitting = (0, import_react9.useCallback)(() => {
15656
15952
  committingRef.current = false;
15657
15953
  }, []);
15658
15954
  return { handleViewportChange, clearCommitting };
@@ -15660,10 +15956,10 @@ var SystemCanvas = (() => {
15660
15956
 
15661
15957
  // ../react/dist/components/Viewport.js
15662
15958
  var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
15663
- var import_react17 = __toESM(require_react(), 1);
15959
+ var import_react18 = __toESM(require_react(), 1);
15664
15960
 
15665
15961
  // ../react/dist/hooks/useViewport.js
15666
- var import_react9 = __toESM(require_react(), 1);
15962
+ var import_react10 = __toESM(require_react(), 1);
15667
15963
 
15668
15964
  // ../../node_modules/d3-dispatch/src/dispatch.js
15669
15965
  var noop = { value: () => {
@@ -18406,13 +18702,13 @@ var SystemCanvas = (() => {
18406
18702
  // ../react/dist/hooks/useViewport.js
18407
18703
  function useViewport(options) {
18408
18704
  const { minZoom, maxZoom, defaultViewport, onViewportChange, marqueeActiveRef } = options;
18409
- const svgRef = (0, import_react9.useRef)(null);
18410
- const groupRef = (0, import_react9.useRef)(null);
18411
- const viewport = (0, import_react9.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
18412
- const zoomBehaviorRef = (0, import_react9.useRef)(null);
18413
- const onViewportChangeRef = (0, import_react9.useRef)(onViewportChange);
18705
+ const svgRef = (0, import_react10.useRef)(null);
18706
+ const groupRef = (0, import_react10.useRef)(null);
18707
+ const viewport = (0, import_react10.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
18708
+ const zoomBehaviorRef = (0, import_react10.useRef)(null);
18709
+ const onViewportChangeRef = (0, import_react10.useRef)(onViewportChange);
18414
18710
  onViewportChangeRef.current = onViewportChange;
18415
- (0, import_react9.useEffect)(() => {
18711
+ (0, import_react10.useEffect)(() => {
18416
18712
  const svg = svgRef.current;
18417
18713
  const group = groupRef.current;
18418
18714
  if (!svg || !group)
@@ -18452,7 +18748,7 @@ var SystemCanvas = (() => {
18452
18748
  selection2.on(".zoom", null);
18453
18749
  };
18454
18750
  }, [minZoom, maxZoom]);
18455
- const fitToContent = (0, import_react9.useCallback)((nodes, animate = true) => {
18751
+ const fitToContent = (0, import_react10.useCallback)((nodes, animate = true) => {
18456
18752
  const svg = svgRef.current;
18457
18753
  if (!svg || !zoomBehaviorRef.current || nodes.length === 0)
18458
18754
  return;
@@ -18465,13 +18761,13 @@ var SystemCanvas = (() => {
18465
18761
  select_default2(svg).call(zoomBehaviorRef.current.transform, t);
18466
18762
  }
18467
18763
  }, []);
18468
- const resetZoom = (0, import_react9.useCallback)(() => {
18764
+ const resetZoom = (0, import_react10.useCallback)(() => {
18469
18765
  const svg = svgRef.current;
18470
18766
  if (!svg || !zoomBehaviorRef.current)
18471
18767
  return;
18472
18768
  select_default2(svg).transition().duration(400).call(zoomBehaviorRef.current.transform, identity2);
18473
18769
  }, []);
18474
- const setTransform = (0, import_react9.useCallback)((transform2, options2) => {
18770
+ const setTransform = (0, import_react10.useCallback)((transform2, options2) => {
18475
18771
  const svg = svgRef.current;
18476
18772
  if (!svg || !zoomBehaviorRef.current)
18477
18773
  return;
@@ -18483,7 +18779,7 @@ var SystemCanvas = (() => {
18483
18779
  sel.call(zoomBehaviorRef.current.transform, t);
18484
18780
  }
18485
18781
  }, []);
18486
- const zoomToNode = (0, import_react9.useCallback)((node, onComplete, options2) => {
18782
+ const zoomToNode = (0, import_react10.useCallback)((node, onComplete, options2) => {
18487
18783
  const svg = svgRef.current;
18488
18784
  if (!svg || !zoomBehaviorRef.current) {
18489
18785
  onComplete?.();
@@ -18677,9 +18973,9 @@ var SystemCanvas = (() => {
18677
18973
 
18678
18974
  // ../react/dist/components/RefIndicator.js
18679
18975
  var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
18680
- var import_react10 = __toESM(require_react(), 1);
18976
+ var import_react11 = __toESM(require_react(), 1);
18681
18977
  function RefIndicator({ node, theme, nodeX, nodeY, nodeWidth, nodeHeight, strokeColor, strokeWidth, corner = "bottom-right", size: sizeProp, onNavigate }) {
18682
- const [hover, setHover] = (0, import_react10.useState)(false);
18978
+ const [hover, setHover] = (0, import_react11.useState)(false);
18683
18979
  const iconKind = theme.node.refIndicator.icon;
18684
18980
  if (iconKind === "none")
18685
18981
  return null;
@@ -18750,7 +19046,7 @@ var SystemCanvas = (() => {
18750
19046
 
18751
19047
  // ../react/dist/components/CategorySlotsLayer.js
18752
19048
  var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
18753
- var import_react12 = __toESM(require_react(), 1);
19049
+ var import_react13 = __toESM(require_react(), 1);
18754
19050
 
18755
19051
  // ../react/dist/primitives/NodeColorFill.js
18756
19052
  var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
@@ -18870,9 +19166,9 @@ var SystemCanvas = (() => {
18870
19166
 
18871
19167
  // ../react/dist/primitives/NodeText.js
18872
19168
  var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
18873
- var import_react11 = __toESM(require_react(), 1);
19169
+ var import_react12 = __toESM(require_react(), 1);
18874
19170
  function NodeText({ region, value, theme, color: color2, fill, align = "start", fontWeight = 500, uppercase = false, useLabelFont = false, fontFamily, fontSize: fontSizeProp, wrap = false, maxLines, lineHeight: lineHeightProp, verticalAlign = "top" }) {
18875
- const reactId = (0, import_react11.useId)();
19171
+ const reactId = (0, import_react12.useId)();
18876
19172
  const safeId = reactId.replace(/:/g, "");
18877
19173
  if (!value)
18878
19174
  return null;
@@ -18946,8 +19242,8 @@ var SystemCanvas = (() => {
18946
19242
  // ../react/dist/components/CategorySlotsLayer.js
18947
19243
  function CategorySlotsLayer({ node, theme, canvases, slots: slotsProp }) {
18948
19244
  const slots = slotsProp ?? getCategorySlots(node, theme);
18949
- const regions = (0, import_react12.useMemo)(() => computeCategorySlotRegions(node, theme, slots), [node, theme, slots]);
18950
- const reactId = (0, import_react12.useId)();
19245
+ const regions = (0, import_react13.useMemo)(() => computeCategorySlotRegions(node, theme, slots), [node, theme, slots]);
19246
+ const reactId = (0, import_react13.useId)();
18951
19247
  const clipId = `sc-edge-clip-${reactId.replace(/:/g, "")}`;
18952
19248
  if (!slots)
18953
19249
  return null;
@@ -19180,7 +19476,7 @@ var SystemCanvas = (() => {
19180
19476
 
19181
19477
  // ../react/dist/components/ResizeHandles.js
19182
19478
  var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
19183
- var import_react13 = __toESM(require_react(), 1);
19479
+ var import_react14 = __toESM(require_react(), 1);
19184
19480
  var HANDLE_SIZE = 7;
19185
19481
  var CORNERS = [
19186
19482
  { corner: "nw", cursor: "nwse-resize", anchor: "nw" },
@@ -19191,7 +19487,7 @@ var SystemCanvas = (() => {
19191
19487
  var cornerInset = (cornerRadius) => Math.min(cornerRadius * 0.25, 3);
19192
19488
  function ResizeHandles({ node, theme, onHandlePointerDown }) {
19193
19489
  const { x, y, width, height } = node;
19194
- const [hoveredCorner, setHoveredCorner] = (0, import_react13.useState)(null);
19490
+ const [hoveredCorner, setHoveredCorner] = (0, import_react14.useState)(null);
19195
19491
  const handleColor = node.resolvedStroke ?? theme.node.labelColor;
19196
19492
  const i = cornerInset(node.resolvedCornerRadius);
19197
19493
  const anchorPos = (anchor) => {
@@ -19302,7 +19598,7 @@ var SystemCanvas = (() => {
19302
19598
 
19303
19599
  // ../react/dist/components/NodeEditor.js
19304
19600
  var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
19305
- var import_react14 = __toESM(require_react(), 1);
19601
+ var import_react15 = __toESM(require_react(), 1);
19306
19602
  function NodeEditor({ node, theme, onCommit, onCancel }) {
19307
19603
  const editableFields = useCategoryFields(node, theme);
19308
19604
  if (editableFields) {
@@ -19321,11 +19617,11 @@ var SystemCanvas = (() => {
19321
19617
  }
19322
19618
  function SingleFieldEditor({ node, theme, onCommit, onCancel }) {
19323
19619
  const initial = getInitialValue(node);
19324
- const [value, setValue] = (0, import_react14.useState)(initial);
19325
- const textareaRef = (0, import_react14.useRef)(null);
19326
- const inputRef = (0, import_react14.useRef)(null);
19327
- const committedRef = (0, import_react14.useRef)(false);
19328
- (0, import_react14.useEffect)(() => {
19620
+ const [value, setValue] = (0, import_react15.useState)(initial);
19621
+ const textareaRef = (0, import_react15.useRef)(null);
19622
+ const inputRef = (0, import_react15.useRef)(null);
19623
+ const committedRef = (0, import_react15.useRef)(false);
19624
+ (0, import_react15.useEffect)(() => {
19329
19625
  const el = textareaRef.current ?? inputRef.current;
19330
19626
  if (el) {
19331
19627
  el.focus();
@@ -19421,10 +19717,10 @@ var SystemCanvas = (() => {
19421
19717
  }
19422
19718
  }
19423
19719
  function FormEditor({ node, theme, fields, onCommit, onCancel }) {
19424
- const initial = (0, import_react14.useMemo)(() => readInitialValues(node, fields), [node, fields]);
19425
- const [values, setValues] = (0, import_react14.useState)(initial);
19426
- const committedRef = (0, import_react14.useRef)(false);
19427
- const panelRef = (0, import_react14.useRef)(null);
19720
+ const initial = (0, import_react15.useMemo)(() => readInitialValues(node, fields), [node, fields]);
19721
+ const [values, setValues] = (0, import_react15.useState)(initial);
19722
+ const committedRef = (0, import_react15.useRef)(false);
19723
+ const panelRef = (0, import_react15.useRef)(null);
19428
19724
  const width = Math.max(node.width, 240);
19429
19725
  const height = Math.max(node.height, 36 + fields.length * 44);
19430
19726
  const commit = () => {
@@ -19453,7 +19749,7 @@ var SystemCanvas = (() => {
19453
19749
  const stopPointer = (e) => {
19454
19750
  e.stopPropagation();
19455
19751
  };
19456
- (0, import_react14.useEffect)(() => {
19752
+ (0, import_react15.useEffect)(() => {
19457
19753
  const el = panelRef.current;
19458
19754
  if (!el)
19459
19755
  return;
@@ -19583,13 +19879,13 @@ var SystemCanvas = (() => {
19583
19879
 
19584
19880
  // ../react/dist/components/EdgeLabelEditor.js
19585
19881
  var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
19586
- var import_react15 = __toESM(require_react(), 1);
19882
+ var import_react16 = __toESM(require_react(), 1);
19587
19883
  var EDITOR_WIDTH = 110;
19588
19884
  function EdgeLabelEditor({ initialLabel, midpoint, theme, onCommit, onCancel }) {
19589
- const [value, setValue] = (0, import_react15.useState)(initialLabel);
19590
- const inputRef = (0, import_react15.useRef)(null);
19591
- const committedRef = (0, import_react15.useRef)(false);
19592
- (0, import_react15.useEffect)(() => {
19885
+ const [value, setValue] = (0, import_react16.useState)(initialLabel);
19886
+ const inputRef = (0, import_react16.useRef)(null);
19887
+ const committedRef = (0, import_react16.useRef)(false);
19888
+ (0, import_react16.useEffect)(() => {
19593
19889
  const el = inputRef.current;
19594
19890
  if (el) {
19595
19891
  el.focus();
@@ -19644,7 +19940,7 @@ var SystemCanvas = (() => {
19644
19940
 
19645
19941
  // ../react/dist/components/ConnectionHandles.js
19646
19942
  var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
19647
- var import_react16 = __toESM(require_react(), 1);
19943
+ var import_react17 = __toESM(require_react(), 1);
19648
19944
  var SIDES = ["top", "right", "bottom", "left"];
19649
19945
  var HANDLE_RADIUS = 4;
19650
19946
  var HANDLE_HIT_RADIUS = 10;
@@ -19653,9 +19949,9 @@ var SystemCanvas = (() => {
19653
19949
  var HOVER_SCALE = 1.42;
19654
19950
  var HOVER_TRANSITION_MS = 120;
19655
19951
  function ConnectionHandles({ node, theme, onHandlePointerDown, immediate, activeSide }) {
19656
- const [visible, setVisible] = (0, import_react16.useState)(!!immediate);
19657
- const [hoveredSide, setHoveredSide] = (0, import_react16.useState)(null);
19658
- (0, import_react16.useEffect)(() => {
19952
+ const [visible, setVisible] = (0, import_react17.useState)(!!immediate);
19953
+ const [hoveredSide, setHoveredSide] = (0, import_react17.useState)(null);
19954
+ (0, import_react17.useEffect)(() => {
19659
19955
  if (immediate) {
19660
19956
  setVisible(true);
19661
19957
  return;
@@ -19742,7 +20038,7 @@ var SystemCanvas = (() => {
19742
20038
  // ../react/dist/components/Viewport.js
19743
20039
  var HOVER_PADDING = 10;
19744
20040
  var EDGE_PROXIMITY = 16;
19745
- var Viewport = (0, import_react17.forwardRef)(function Viewport2({ nodes, edges, nodeMap, theme, edgeStyle, columns, rows, canvases, minZoom, maxZoom, defaultViewport, onViewportChange, onNodeClick, onNodeDoubleClick, onNodeNavigate, onEdgeClick, onEdgeDoubleClick, onCanvasClick, onCanvasContextMenu, onNodeContextMenu, onEdgeContextMenu, onNodePointerDown, selectedIds, editingId, selectedEdgeId, editingEdgeId, dragOverrides, dropTargetId, marqueeRect, marqueeActiveRef, resizeOverrides, onResizeHandlePointerDown, onEditorCommit, onEditorCancel, onEdgeEditorCommit, onEdgeEditorCancel, pendingEdge, onConnectionHandlePointerDown, edgeCreateEnabled, autoFit = "canvas-change", canvasRef, handoffTransform, onHandoffApplied, handoffFadeMs = 0 }, ref) {
20041
+ var Viewport = (0, import_react18.forwardRef)(function Viewport2({ nodes, edges, nodeMap, theme, edgeStyle, columns, rows, canvases, minZoom, maxZoom, defaultViewport, onViewportChange, onNodeClick, onNodeDoubleClick, onNodeNavigate, onEdgeClick, onEdgeDoubleClick, onCanvasClick, onCanvasContextMenu, onNodeContextMenu, onEdgeContextMenu, onNodePointerDown, selectedIds, editingId, selectedEdgeId, editingEdgeId, dragOverrides, dropTargetId, marqueeRect, marqueeActiveRef, resizeOverrides, onResizeHandlePointerDown, onEditorCommit, onEditorCancel, onEdgeEditorCommit, onEdgeEditorCancel, pendingEdge, onConnectionHandlePointerDown, edgeCreateEnabled, autoFit = "canvas-change", canvasRef, handoffTransform, onHandoffApplied, handoffFadeMs = 0 }, ref) {
19746
20042
  const { svgRef, groupRef, viewport, fitToContent, zoomToNode, setTransform } = useViewport({
19747
20043
  minZoom,
19748
20044
  maxZoom,
@@ -19750,10 +20046,10 @@ var SystemCanvas = (() => {
19750
20046
  onViewportChange,
19751
20047
  marqueeActiveRef
19752
20048
  });
19753
- const navigatingRef = (0, import_react17.useRef)(false);
19754
- const fadeRafRef = (0, import_react17.useRef)(null);
19755
- const fadeTimeoutRef = (0, import_react17.useRef)(null);
19756
- const triggerFade = (0, import_react17.useCallback)((durationMs) => {
20049
+ const navigatingRef = (0, import_react18.useRef)(false);
20050
+ const fadeRafRef = (0, import_react18.useRef)(null);
20051
+ const fadeTimeoutRef = (0, import_react18.useRef)(null);
20052
+ const triggerFade = (0, import_react18.useCallback)((durationMs) => {
19757
20053
  if (durationMs <= 0)
19758
20054
  return;
19759
20055
  const g = groupRef.current;
@@ -19776,7 +20072,7 @@ var SystemCanvas = (() => {
19776
20072
  }, durationMs + 16);
19777
20073
  });
19778
20074
  }, []);
19779
- (0, import_react17.useEffect)(() => {
20075
+ (0, import_react18.useEffect)(() => {
19780
20076
  return () => {
19781
20077
  if (fadeRafRef.current !== null)
19782
20078
  cancelAnimationFrame(fadeRafRef.current);
@@ -19784,10 +20080,10 @@ var SystemCanvas = (() => {
19784
20080
  clearTimeout(fadeTimeoutRef.current);
19785
20081
  };
19786
20082
  }, []);
19787
- const [hoveredNodeId, setHoveredNodeId] = (0, import_react17.useState)(null);
19788
- const [hoveredSide, setHoveredSide] = (0, import_react17.useState)(null);
19789
- const cursorPosRef = (0, import_react17.useRef)(null);
19790
- (0, import_react17.useImperativeHandle)(ref, () => ({
20083
+ const [hoveredNodeId, setHoveredNodeId] = (0, import_react18.useState)(null);
20084
+ const [hoveredSide, setHoveredSide] = (0, import_react18.useState)(null);
20085
+ const cursorPosRef = (0, import_react18.useRef)(null);
20086
+ (0, import_react18.useImperativeHandle)(ref, () => ({
19791
20087
  zoomToNode: (node, onComplete, options) => {
19792
20088
  navigatingRef.current = true;
19793
20089
  zoomToNode(node, onComplete, options);
@@ -19798,7 +20094,7 @@ var SystemCanvas = (() => {
19798
20094
  getViewport: () => viewport.current ?? { x: 0, y: 0, zoom: 1 },
19799
20095
  getCursorScreenPos: () => cursorPosRef.current
19800
20096
  }));
19801
- const renderNodes = (0, import_react17.useMemo)(() => {
20097
+ const renderNodes = (0, import_react18.useMemo)(() => {
19802
20098
  const hasDrag = dragOverrides && dragOverrides.size > 0;
19803
20099
  const hasResize = resizeOverrides && resizeOverrides.size > 0;
19804
20100
  if (!hasDrag && !hasResize)
@@ -19811,7 +20107,7 @@ var SystemCanvas = (() => {
19811
20107
  return d ? { ...n, x: d.x, y: d.y } : n;
19812
20108
  });
19813
20109
  }, [nodes, dragOverrides, resizeOverrides]);
19814
- const renderNodeMap = (0, import_react17.useMemo)(() => {
20110
+ const renderNodeMap = (0, import_react18.useMemo)(() => {
19815
20111
  const hasDrag = dragOverrides && dragOverrides.size > 0;
19816
20112
  const hasResize = resizeOverrides && resizeOverrides.size > 0;
19817
20113
  if (!hasDrag && !hasResize)
@@ -19822,11 +20118,11 @@ var SystemCanvas = (() => {
19822
20118
  }
19823
20119
  return m;
19824
20120
  }, [renderNodes, nodeMap, dragOverrides, resizeOverrides]);
19825
- const latestNodesRef = (0, import_react17.useRef)(nodes);
19826
- (0, import_react17.useEffect)(() => {
20121
+ const latestNodesRef = (0, import_react18.useRef)(nodes);
20122
+ (0, import_react18.useEffect)(() => {
19827
20123
  latestNodesRef.current = nodes;
19828
20124
  }, [nodes]);
19829
- const fitNow = (0, import_react17.useCallback)(() => {
20125
+ const fitNow = (0, import_react18.useCallback)(() => {
19830
20126
  const current = latestNodesRef.current;
19831
20127
  if (current.length === 0)
19832
20128
  return;
@@ -19836,7 +20132,7 @@ var SystemCanvas = (() => {
19836
20132
  fitToContent(current, animate);
19837
20133
  });
19838
20134
  }, [fitToContent]);
19839
- (0, import_react17.useEffect)(() => {
20135
+ (0, import_react18.useEffect)(() => {
19840
20136
  if (defaultViewport)
19841
20137
  return;
19842
20138
  if (autoFit !== "always")
@@ -19845,8 +20141,8 @@ var SystemCanvas = (() => {
19845
20141
  return;
19846
20142
  fitNow();
19847
20143
  }, [nodes, autoFit, defaultViewport, fitNow]);
19848
- const fittedForRef = (0, import_react17.useRef)(null);
19849
- (0, import_react17.useEffect)(() => {
20144
+ const fittedForRef = (0, import_react18.useRef)(null);
20145
+ (0, import_react18.useEffect)(() => {
19850
20146
  if (defaultViewport)
19851
20147
  return;
19852
20148
  if (autoFit !== "canvas-change" && autoFit !== "initial")
@@ -19878,7 +20174,7 @@ var SystemCanvas = (() => {
19878
20174
  triggerFade
19879
20175
  ]);
19880
20176
  const editingNode = editingId ? renderNodes.find((n) => n.id === editingId) ?? null : null;
19881
- const handleSvgPointerMove = (0, import_react17.useCallback)((event) => {
20177
+ const handleSvgPointerMove = (0, import_react18.useCallback)((event) => {
19882
20178
  const svg = svgRef.current;
19883
20179
  if (!svg)
19884
20180
  return;
@@ -19930,7 +20226,7 @@ var SystemCanvas = (() => {
19930
20226
  setHoveredSide((prev) => prev === null ? prev : null);
19931
20227
  }
19932
20228
  }, [edgeCreateEnabled, renderNodes, svgRef, viewport]);
19933
- const handleSvgPointerLeave = (0, import_react17.useCallback)(() => {
20229
+ const handleSvgPointerLeave = (0, import_react18.useCallback)(() => {
19934
20230
  setHoveredNodeId(null);
19935
20231
  setHoveredSide(null);
19936
20232
  cursorPosRef.current = null;
@@ -19969,7 +20265,7 @@ var SystemCanvas = (() => {
19969
20265
 
19970
20266
  // ../react/dist/components/Breadcrumbs.js
19971
20267
  var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
19972
- var import_react18 = __toESM(require_react(), 1);
20268
+ var import_react19 = __toESM(require_react(), 1);
19973
20269
  function Breadcrumbs({ breadcrumbs, theme, onNavigate }) {
19974
20270
  if (breadcrumbs.length <= 1)
19975
20271
  return null;
@@ -19990,7 +20286,7 @@ var SystemCanvas = (() => {
19990
20286
  backdropFilter: "blur(8px)"
19991
20287
  }, children: breadcrumbs.map((crumb, index) => {
19992
20288
  const isLast = index === breadcrumbs.length - 1;
19993
- return (0, import_jsx_runtime23.jsxs)(import_react18.default.Fragment, { children: [index > 0 && (0, import_jsx_runtime23.jsx)("span", { style: {
20289
+ return (0, import_jsx_runtime23.jsxs)(import_react19.default.Fragment, { children: [index > 0 && (0, import_jsx_runtime23.jsx)("span", { style: {
19994
20290
  color: theme.separatorColor,
19995
20291
  margin: "0 2px"
19996
20292
  }, children: "/" }), (0, import_jsx_runtime23.jsx)("span", { onClick: isLast ? void 0 : () => onNavigate(index), style: {
@@ -20014,11 +20310,11 @@ var SystemCanvas = (() => {
20014
20310
 
20015
20311
  // ../react/dist/components/AddNodeButton.js
20016
20312
  var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
20017
- var import_react19 = __toESM(require_react(), 1);
20313
+ var import_react20 = __toESM(require_react(), 1);
20018
20314
  function AddNodeButton({ options, addNode: addNode2, theme }) {
20019
- const [open, setOpen] = (0, import_react19.useState)(false);
20020
- const rootRef = (0, import_react19.useRef)(null);
20021
- (0, import_react19.useEffect)(() => {
20315
+ const [open, setOpen] = (0, import_react20.useState)(false);
20316
+ const rootRef = (0, import_react20.useRef)(null);
20317
+ (0, import_react20.useEffect)(() => {
20022
20318
  if (!open)
20023
20319
  return;
20024
20320
  function onDocClick(e) {
@@ -20107,7 +20403,7 @@ var SystemCanvas = (() => {
20107
20403
  } });
20108
20404
  }
20109
20405
  function MenuRow({ theme, option, onClick }) {
20110
- const [hover, setHover] = (0, import_react19.useState)(false);
20406
+ const [hover, setHover] = (0, import_react20.useState)(false);
20111
20407
  const swatchSize = 18;
20112
20408
  return (0, import_jsx_runtime24.jsxs)("div", { role: "button", onClick, onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), style: {
20113
20409
  display: "flex",
@@ -20143,12 +20439,12 @@ var SystemCanvas = (() => {
20143
20439
 
20144
20440
  // ../react/dist/components/LaneHeaders.js
20145
20441
  var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
20146
- var import_react20 = __toESM(require_react(), 1);
20442
+ var import_react21 = __toESM(require_react(), 1);
20147
20443
  function LaneHeaders({ columns, rows, theme, getViewport, width, height, pinned = true }) {
20148
20444
  const hasColumns = columns && columns.length > 0;
20149
20445
  const hasRows = rows && rows.length > 0;
20150
- const [viewport, setViewport] = (0, import_react20.useState)(() => getViewport());
20151
- (0, import_react20.useEffect)(() => {
20446
+ const [viewport, setViewport] = (0, import_react21.useState)(() => getViewport());
20447
+ (0, import_react21.useEffect)(() => {
20152
20448
  if (!hasColumns && !hasRows)
20153
20449
  return;
20154
20450
  let raf = 0;
@@ -20222,7 +20518,7 @@ var SystemCanvas = (() => {
20222
20518
 
20223
20519
  // ../react/dist/components/NodeToolbar.js
20224
20520
  var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
20225
- var import_react21 = __toESM(require_react(), 1);
20521
+ var import_react22 = __toESM(require_react(), 1);
20226
20522
  var NODE_GAP = 10;
20227
20523
  var FLIP_MARGIN = 8;
20228
20524
  var PADDING = 6;
@@ -20231,8 +20527,8 @@ var SystemCanvas = (() => {
20231
20527
  var BUTTON_SIZE = 28;
20232
20528
  var DELETE_SIZE = 14;
20233
20529
  function NodeToolbar({ node, theme, onPatch, onDelete, getViewport, containerWidth, containerHeight, render: render2, selectedNodes, onMultiPatch }) {
20234
- const [viewport, setViewport] = (0, import_react21.useState)(() => getViewport());
20235
- (0, import_react21.useEffect)(() => {
20530
+ const [viewport, setViewport] = (0, import_react22.useState)(() => getViewport());
20531
+ (0, import_react22.useEffect)(() => {
20236
20532
  let raf = 0;
20237
20533
  let lastX = -Infinity;
20238
20534
  let lastY = -Infinity;
@@ -20252,7 +20548,7 @@ var SystemCanvas = (() => {
20252
20548
  }, [getViewport]);
20253
20549
  const isMulti = selectedNodes != null && selectedNodes.length > 1;
20254
20550
  const align = theme.toolbarAlign ?? "center";
20255
- const { anchorTopY, anchorBottomY, anchorX } = (0, import_react21.useMemo)(() => {
20551
+ const { anchorTopY, anchorBottomY, anchorX } = (0, import_react22.useMemo)(() => {
20256
20552
  if (isMulti && selectedNodes) {
20257
20553
  const minX = Math.min(...selectedNodes.map((n) => n.x));
20258
20554
  const maxX = Math.max(...selectedNodes.map((n) => n.x + n.width));
@@ -20269,9 +20565,9 @@ var SystemCanvas = (() => {
20269
20565
  }, [isMulti, selectedNodes, align, node]);
20270
20566
  const topAnchor = canvasToScreen(anchorX, anchorTopY, viewport);
20271
20567
  const bottomAnchor = canvasToScreen(anchorX, anchorBottomY, viewport);
20272
- const toolbarRef = (0, import_react21.useRef)(null);
20273
- const [size, setSize] = (0, import_react21.useState)({ width: 0, height: 0 });
20274
- (0, import_react21.useEffect)(() => {
20568
+ const toolbarRef = (0, import_react22.useRef)(null);
20569
+ const [size, setSize] = (0, import_react22.useState)({ width: 0, height: 0 });
20570
+ (0, import_react22.useEffect)(() => {
20275
20571
  const el = toolbarRef.current;
20276
20572
  if (!el)
20277
20573
  return;
@@ -20331,7 +20627,7 @@ var SystemCanvas = (() => {
20331
20627
  }
20332
20628
  function MultiToolbarContent({ selectedNodes, theme, onMultiPatch, onDelete }) {
20333
20629
  const representativeNode = selectedNodes[0];
20334
- const groups = (0, import_react21.useMemo)(() => getNodeActionsForNode(representativeNode, theme), [representativeNode, theme]);
20630
+ const groups = (0, import_react22.useMemo)(() => getNodeActionsForNode(representativeNode, theme), [representativeNode, theme]);
20335
20631
  const showDelete = theme.showToolbarDelete === true;
20336
20632
  const swatchGroups = groups.filter((g) => g.kind === "swatches" || g.kind == null);
20337
20633
  const otherGroups = groups.filter((g) => g.kind !== "swatches" && g.kind != null && g.kind !== "menu");
@@ -20345,7 +20641,7 @@ var SystemCanvas = (() => {
20345
20641
  const actions = filterActionsForNode(group, representativeNode);
20346
20642
  if (actions.length === 0)
20347
20643
  return null;
20348
- return (0, import_jsx_runtime26.jsxs)(import_react21.default.Fragment, { children: [i > 0 && (0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: actions.map((action) => {
20644
+ return (0, import_jsx_runtime26.jsxs)(import_react22.default.Fragment, { children: [i > 0 && (0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: actions.map((action) => {
20349
20645
  const active = action.isActive?.(representativeNode) ?? false;
20350
20646
  const handleClick = () => {
20351
20647
  const patch = resolveActionPatch(action, representativeNode);
@@ -20357,7 +20653,7 @@ var SystemCanvas = (() => {
20357
20653
  const actions = filterActionsForNode(group, representativeNode);
20358
20654
  if (actions.length === 0)
20359
20655
  return null;
20360
- return (0, import_jsx_runtime26.jsxs)(import_react21.default.Fragment, { children: [(0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: actions.map((action) => {
20656
+ return (0, import_jsx_runtime26.jsxs)(import_react22.default.Fragment, { children: [(0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: actions.map((action) => {
20361
20657
  const active = action.isActive?.(representativeNode) ?? false;
20362
20658
  const handleClick = () => {
20363
20659
  const patch = resolveActionPatch(action, representativeNode);
@@ -20368,9 +20664,9 @@ var SystemCanvas = (() => {
20368
20664
  }), showDelete && (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [(0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)(DeleteButton, { theme, onDelete })] })] });
20369
20665
  }
20370
20666
  function DefaultToolbarContent({ node, theme, onPatch, onDelete }) {
20371
- const groups = (0, import_react21.useMemo)(() => getNodeActionsForNode(node, theme), [node, theme]);
20667
+ const groups = (0, import_react22.useMemo)(() => getNodeActionsForNode(node, theme), [node, theme]);
20372
20668
  const showDelete = theme.showToolbarDelete === true;
20373
- return (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [groups.map((group, i) => (0, import_jsx_runtime26.jsxs)(import_react21.default.Fragment, { children: [i > 0 && (0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)(ActionGroupView, { group, node, theme, onPatch })] }, group.id)), showDelete && (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [(0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)(DeleteButton, { theme, onDelete })] })] });
20669
+ return (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [groups.map((group, i) => (0, import_jsx_runtime26.jsxs)(import_react22.default.Fragment, { children: [i > 0 && (0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)(ActionGroupView, { group, node, theme, onPatch })] }, group.id)), showDelete && (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [(0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)(DeleteButton, { theme, onDelete })] })] });
20374
20670
  }
20375
20671
  function Divider2({ theme }) {
20376
20672
  return (0, import_jsx_runtime26.jsx)("div", { style: {
@@ -20437,9 +20733,9 @@ var SystemCanvas = (() => {
20437
20733
  } }) : (0, import_jsx_runtime26.jsx)("span", { style: { fontSize: 10 }, children: action.label.slice(0, 2) }) });
20438
20734
  }
20439
20735
  function MenuGroup({ group, actions, node, theme, onPatch }) {
20440
- const [open, setOpen] = (0, import_react21.useState)(false);
20441
- const wrapRef = (0, import_react21.useRef)(null);
20442
- (0, import_react21.useEffect)(() => {
20736
+ const [open, setOpen] = (0, import_react22.useState)(false);
20737
+ const wrapRef = (0, import_react22.useRef)(null);
20738
+ (0, import_react22.useEffect)(() => {
20443
20739
  if (!open)
20444
20740
  return;
20445
20741
  const onDown = (e) => {
@@ -20526,18 +20822,18 @@ var SystemCanvas = (() => {
20526
20822
 
20527
20823
  // ../react/dist/components/NodeContextMenuOverlay.js
20528
20824
  var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
20529
- var import_react22 = __toESM(require_react(), 1);
20825
+ var import_react23 = __toESM(require_react(), 1);
20530
20826
  var ESTIMATED_MENU_WIDTH = 200;
20531
20827
  var MIN_MENU_WIDTH = 160;
20532
20828
  var VIEWPORT_MARGIN = 8;
20533
20829
  function NodeContextMenuOverlay({ state, config, theme, onClose }) {
20534
- const rootRef = (0, import_react22.useRef)(null);
20535
- const [hoveredId, setHoveredId] = (0, import_react22.useState)(null);
20536
- (0, import_react22.useEffect)(() => {
20830
+ const rootRef = (0, import_react23.useRef)(null);
20831
+ const [hoveredId, setHoveredId] = (0, import_react23.useState)(null);
20832
+ (0, import_react23.useEffect)(() => {
20537
20833
  if (state)
20538
20834
  setHoveredId(null);
20539
20835
  }, [state]);
20540
- (0, import_react22.useEffect)(() => {
20836
+ (0, import_react23.useEffect)(() => {
20541
20837
  if (!state)
20542
20838
  return;
20543
20839
  function onDown(e) {
@@ -20645,8 +20941,8 @@ var SystemCanvas = (() => {
20645
20941
  // ../react/dist/components/SystemCanvas.js
20646
20942
  var CASCADE_WINDOW_MS = 1500;
20647
20943
  var CASCADE_OFFSET = 20;
20648
- var SystemCanvas = (0, import_react23.forwardRef)(function SystemCanvas2({ canvas, onResolveCanvas, canvases, rootLabel = "Home", onNavigate, onBreadcrumbClick, onBreadcrumbsChange, onNodeClick, onNodeDoubleClick, onEdgeClick, onEdgeDoubleClick, onContextMenu, onSelectionChange, nodeContextMenu, editable = false, onNodeAdd, onNodeUpdate, onNodesUpdate, onNodeDelete, onNodesDelete, onEdgeUpdate, onEdgeDelete, onEdgeAdd, canDropNodeOn, onNodeDrop, renderAddNodeButton, showNodeToolbar = true, renderNodeToolbar, theme: themeProp, themes: customThemes, edgeStyle = "bezier", defaultViewport, minZoom: minZoomProp, maxZoom, onViewportChange, autoFit = "canvas-change", laneHeaders = "pinned", snapToLanes = false, zoomNavigation = false, className, style }, forwardedRef) {
20649
- const zoomNavConfig = (0, import_react23.useMemo)(() => {
20944
+ var SystemCanvas = (0, import_react24.forwardRef)(function SystemCanvas2({ canvas, onResolveCanvas, canvases, rootLabel = "Home", onNavigate, onBreadcrumbClick, onBreadcrumbsChange, onNodeClick, onNodeDoubleClick, onEdgeClick, onEdgeDoubleClick, onContextMenu, onSelectionChange, nodeContextMenu, editable = false, onNodeAdd, onNodeUpdate, onNodesUpdate, onNodeDelete, onNodesDelete, onEdgeUpdate, onEdgeDelete, onEdgeAdd, canDropNodeOn, onNodeDrop, renderAddNodeButton, showNodeToolbar = true, renderNodeToolbar, theme: themeProp, themes: customThemes, edgeStyle = "bezier", defaultViewport, minZoom: minZoomProp, maxZoom, onViewportChange, autoFit = "canvas-change", laneHeaders = "pinned", snapToLanes = false, zoomNavigation = false, historyDepth, onUndo, onRedo, className, style }, forwardedRef) {
20945
+ const zoomNavConfig = (0, import_react24.useMemo)(() => {
20650
20946
  const defaults = {
20651
20947
  enterThreshold: 0.66,
20652
20948
  exitThreshold: 0.33,
@@ -20671,16 +20967,16 @@ var SystemCanvas = (() => {
20671
20967
  }, [zoomNavigation]);
20672
20968
  const effectiveMaxZoom = maxZoom ?? (zoomNavConfig.enabled ? 16 : 4);
20673
20969
  const effectiveMinZoom = minZoomProp ?? (zoomNavConfig.enabled ? 0.01 : 0.1);
20674
- (0, import_react23.useEffect)(() => {
20970
+ (0, import_react24.useEffect)(() => {
20675
20971
  const env = globalThis.process?.env?.NODE_ENV;
20676
20972
  if (editable && !canvases && env !== "production") {
20677
20973
  console.warn("[system-canvas] `editable` is enabled but `canvases` prop is missing. Edits to sub-canvases will not be reflected without a synchronous ref \u2192 CanvasData map.");
20678
20974
  }
20679
20975
  }, [editable, canvases]);
20680
- const [parentFrames, setParentFrames] = (0, import_react23.useState)([]);
20681
- const [pendingHandoff, setPendingHandoff] = (0, import_react23.useState)(null);
20682
- const suppressNextHandoffClearRef = (0, import_react23.useRef)(false);
20683
- const handleBreadcrumbClick = (0, import_react23.useCallback)((index) => {
20976
+ const [parentFrames, setParentFrames] = (0, import_react24.useState)([]);
20977
+ const [pendingHandoff, setPendingHandoff] = (0, import_react24.useState)(null);
20978
+ const suppressNextHandoffClearRef = (0, import_react24.useRef)(false);
20979
+ const handleBreadcrumbClick = (0, import_react24.useCallback)((index) => {
20684
20980
  setParentFrames((prev) => prev.slice(0, index));
20685
20981
  if (suppressNextHandoffClearRef.current) {
20686
20982
  suppressNextHandoffClearRef.current = false;
@@ -20697,10 +20993,10 @@ var SystemCanvas = (() => {
20697
20993
  onNavigate,
20698
20994
  onBreadcrumbClick: handleBreadcrumbClick
20699
20995
  });
20700
- (0, import_react23.useEffect)(() => {
20996
+ (0, import_react24.useEffect)(() => {
20701
20997
  onBreadcrumbsChange?.(breadcrumbs);
20702
20998
  }, [breadcrumbs, onBreadcrumbsChange]);
20703
- const theme = (0, import_react23.useMemo)(() => {
20999
+ const theme = (0, import_react24.useMemo)(() => {
20704
21000
  const registry = { ...themes, ...customThemes };
20705
21001
  const resolveByName = (name) => name && registry[name] ? registry[name] : null;
20706
21002
  if (themeProp) {
@@ -20711,22 +21007,22 @@ var SystemCanvas = (() => {
20711
21007
  }
20712
21008
  return resolveByName(currentCanvas.theme?.base) ?? resolveByName(canvas.theme?.base) ?? darkTheme;
20713
21009
  }, [themeProp, customThemes, currentCanvas.theme?.base, canvas.theme?.base]);
20714
- const { nodes, edges, nodeMap } = (0, import_react23.useMemo)(() => {
21010
+ const { nodes, edges, nodeMap } = (0, import_react24.useMemo)(() => {
20715
21011
  const resolved = resolveCanvas(currentCanvas, theme);
20716
21012
  const map = buildNodeMap(resolved.nodes);
20717
21013
  return { nodes: resolved.nodes, edges: resolved.edges, nodeMap: map };
20718
21014
  }, [currentCanvas, theme]);
20719
- const nodesRef = (0, import_react23.useRef)(nodes);
21015
+ const nodesRef = (0, import_react24.useRef)(nodes);
20720
21016
  nodesRef.current = nodes;
20721
- const viewportStateRef = (0, import_react23.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
20722
- const viewportHandleRef = (0, import_react23.useRef)(null);
20723
- const navigateToRefRef = (0, import_react23.useRef)(navigateToRef);
21017
+ const viewportStateRef = (0, import_react24.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
21018
+ const viewportHandleRef = (0, import_react24.useRef)(null);
21019
+ const navigateToRefRef = (0, import_react24.useRef)(navigateToRef);
20724
21020
  navigateToRefRef.current = navigateToRef;
20725
- const navigateToBreadcrumbRef = (0, import_react23.useRef)(navigateToBreadcrumb);
21021
+ const navigateToBreadcrumbRef = (0, import_react24.useRef)(navigateToBreadcrumb);
20726
21022
  navigateToBreadcrumbRef.current = navigateToBreadcrumb;
20727
- const breadcrumbsRef = (0, import_react23.useRef)(breadcrumbs);
21023
+ const breadcrumbsRef = (0, import_react24.useRef)(breadcrumbs);
20728
21024
  breadcrumbsRef.current = breadcrumbs;
20729
- (0, import_react23.useImperativeHandle)(forwardedRef, () => ({
21025
+ (0, import_react24.useImperativeHandle)(forwardedRef, () => ({
20730
21026
  zoomIntoNode: (nodeId, options) => {
20731
21027
  return new Promise((resolve) => {
20732
21028
  const node = nodesRef.current.find((n) => n.id === nodeId);
@@ -20758,11 +21054,11 @@ var SystemCanvas = (() => {
20758
21054
  navigateToBreadcrumbRef.current(0);
20759
21055
  }
20760
21056
  }), [forwardedRef]);
20761
- const [editingId, setEditingId] = (0, import_react23.useState)(null);
20762
- const [selectedEdgeId, setSelectedEdgeId] = (0, import_react23.useState)(null);
20763
- const [editingEdgeId, setEditingEdgeId] = (0, import_react23.useState)(null);
20764
- const svgProxyRef = (0, import_react23.useRef)(null);
20765
- const containerRef = (0, import_react23.useRef)(null);
21057
+ const [editingId, setEditingId] = (0, import_react24.useState)(null);
21058
+ const [selectedEdgeId, setSelectedEdgeId] = (0, import_react24.useState)(null);
21059
+ const [editingEdgeId, setEditingEdgeId] = (0, import_react24.useState)(null);
21060
+ const svgProxyRef = (0, import_react24.useRef)(null);
21061
+ const containerRef = (0, import_react24.useRef)(null);
20766
21062
  const { selectedIds, selectNode, toggleNode, selectAll, clearSelection, marqueeRect, marqueeActiveRef } = useMultiSelect({
20767
21063
  svgRef: svgProxyRef,
20768
21064
  viewport: viewportStateRef,
@@ -20770,37 +21066,55 @@ var SystemCanvas = (() => {
20770
21066
  containerRef,
20771
21067
  enabled: editable
20772
21068
  });
20773
- const selectedIdsRef = (0, import_react23.useRef)(selectedIds);
20774
- (0, import_react23.useEffect)(() => {
21069
+ const selectedIdsRef = (0, import_react24.useRef)(selectedIds);
21070
+ (0, import_react24.useEffect)(() => {
20775
21071
  selectedIdsRef.current = selectedIds;
20776
21072
  }, [selectedIds]);
20777
- const edgesRef = (0, import_react23.useRef)(edges);
20778
- (0, import_react23.useEffect)(() => {
21073
+ const edgesRef = (0, import_react24.useRef)(edges);
21074
+ (0, import_react24.useEffect)(() => {
20779
21075
  edgesRef.current = edges;
20780
21076
  }, [edges]);
21077
+ const { wrappedOnNodeAdd, wrappedOnNodeUpdate, wrappedOnNodesUpdate, wrappedOnNodeDelete, wrappedOnNodesDelete, wrappedOnEdgeAdd, wrappedOnEdgeUpdate, wrappedOnEdgeDelete, beginBatch, endBatch, undo, redo } = useCommandHistory({
21078
+ nodesRef,
21079
+ edgesRef,
21080
+ onNodeAdd,
21081
+ onNodeUpdate,
21082
+ onNodesUpdate,
21083
+ onNodeDelete,
21084
+ onNodesDelete,
21085
+ onEdgeAdd,
21086
+ onEdgeUpdate,
21087
+ onEdgeDelete,
21088
+ maxDepth: historyDepth ?? 50,
21089
+ enabled: editable,
21090
+ onUndo,
21091
+ onRedo
21092
+ });
20781
21093
  useMultiSelectClipboard({
20782
21094
  selectedIdsRef,
20783
21095
  nodesRef,
20784
21096
  edgesRef,
20785
21097
  viewport: viewportStateRef,
20786
21098
  canvasContainerRef: containerRef,
20787
- onNodeAdd: (node) => onNodeAdd?.(node, currentCanvasRef),
20788
- onEdgeAdd: (edge) => onEdgeAdd?.(edge, currentCanvasRef),
21099
+ onNodeAdd: (node) => wrappedOnNodeAdd(node, currentCanvasRef),
21100
+ onEdgeAdd: (edge) => wrappedOnEdgeAdd(edge, currentCanvasRef),
20789
21101
  canvasRef: currentCanvasRef,
20790
- getCursorScreenPos: () => viewportHandleRef.current?.getCursorScreenPos() ?? null
21102
+ getCursorScreenPos: () => viewportHandleRef.current?.getCursorScreenPos() ?? null,
21103
+ onBeginBatch: beginBatch,
21104
+ onEndBatch: endBatch
20791
21105
  });
20792
- (0, import_react23.useEffect)(() => {
21106
+ (0, import_react24.useEffect)(() => {
20793
21107
  clearSelection();
20794
21108
  setEditingId(null);
20795
21109
  setSelectedEdgeId(null);
20796
21110
  setEditingEdgeId(null);
20797
21111
  }, [currentCanvasRef]);
20798
- const onSelectionChangeRef = (0, import_react23.useRef)(onSelectionChange);
20799
- (0, import_react23.useEffect)(() => {
21112
+ const onSelectionChangeRef = (0, import_react24.useRef)(onSelectionChange);
21113
+ (0, import_react24.useEffect)(() => {
20800
21114
  onSelectionChangeRef.current = onSelectionChange;
20801
21115
  }, [onSelectionChange]);
20802
- const lastEmittedSelectionRef = (0, import_react23.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
20803
- (0, import_react23.useEffect)(() => {
21116
+ const lastEmittedSelectionRef = (0, import_react24.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
21117
+ (0, import_react24.useEffect)(() => {
20804
21118
  const cb = onSelectionChangeRef.current;
20805
21119
  let next = null;
20806
21120
  if (selectedIds.size > 1) {
@@ -20842,8 +21156,8 @@ var SystemCanvas = (() => {
20842
21156
  }
20843
21157
  cb?.(next);
20844
21158
  }, [selectedIds, selectedEdgeId, currentCanvasRef, nodeMap, edges]);
20845
- const [containerSize, setContainerSize] = (0, import_react23.useState)({ width: 0, height: 0 });
20846
- (0, import_react23.useEffect)(() => {
21159
+ const [containerSize, setContainerSize] = (0, import_react24.useState)({ width: 0, height: 0 });
21160
+ (0, import_react24.useEffect)(() => {
20847
21161
  const el = containerRef.current;
20848
21162
  if (!el)
20849
21163
  return;
@@ -20858,8 +21172,8 @@ var SystemCanvas = (() => {
20858
21172
  }, []);
20859
21173
  const hasLanes = currentCanvas.columns && currentCanvas.columns.length > 0 || currentCanvas.rows && currentCanvas.rows.length > 0;
20860
21174
  const showLaneHeaders = hasLanes && laneHeaders !== "none";
20861
- const getViewportState = (0, import_react23.useCallback)(() => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 }, []);
20862
- const applyLaneSnap = (0, import_react23.useCallback)((id2, patch) => {
21175
+ const getViewportState = (0, import_react24.useCallback)(() => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 }, []);
21176
+ const applyLaneSnap = (0, import_react24.useCallback)((id2, patch) => {
20863
21177
  if (!snapToLanes)
20864
21178
  return patch;
20865
21179
  const cols = currentCanvas.columns;
@@ -20884,25 +21198,25 @@ var SystemCanvas = (() => {
20884
21198
  }
20885
21199
  return final;
20886
21200
  }, [snapToLanes, currentCanvas.columns, currentCanvas.rows]);
20887
- const commitResize = (0, import_react23.useCallback)((id2, patch) => {
20888
- onNodeUpdate?.(id2, applyLaneSnap(id2, patch), currentCanvasRef);
20889
- }, [onNodeUpdate, currentCanvasRef, applyLaneSnap]);
20890
- const commitDragBatch = (0, import_react23.useCallback)((updates) => {
21201
+ const commitResize = (0, import_react24.useCallback)((id2, patch) => {
21202
+ wrappedOnNodeUpdate(id2, applyLaneSnap(id2, patch), currentCanvasRef);
21203
+ }, [wrappedOnNodeUpdate, currentCanvasRef, applyLaneSnap]);
21204
+ const commitDragBatch = (0, import_react24.useCallback)((updates) => {
20891
21205
  const final = updates.map((u) => ({
20892
21206
  id: u.id,
20893
21207
  patch: applyLaneSnap(u.id, u.patch)
20894
21208
  }));
20895
21209
  if (onNodesUpdate) {
20896
- onNodesUpdate(final, currentCanvasRef);
21210
+ wrappedOnNodesUpdate(final, currentCanvasRef);
20897
21211
  return;
20898
21212
  }
20899
21213
  if (!onNodeUpdate)
20900
21214
  return;
20901
21215
  for (const { id: id2, patch } of final) {
20902
- onNodeUpdate(id2, patch, currentCanvasRef);
21216
+ wrappedOnNodeUpdate(id2, patch, currentCanvasRef);
20903
21217
  }
20904
- }, [onNodeUpdate, onNodesUpdate, currentCanvasRef, applyLaneSnap]);
20905
- const handleNodeDrop = (0, import_react23.useCallback)((sources, target) => {
21218
+ }, [wrappedOnNodeUpdate, wrappedOnNodesUpdate, onNodeUpdate, onNodesUpdate, currentCanvasRef, applyLaneSnap]);
21219
+ const handleNodeDrop = (0, import_react24.useCallback)((sources, target) => {
20906
21220
  onNodeDrop?.(sources, target, { canvasRef: currentCanvasRef });
20907
21221
  }, [onNodeDrop, currentCanvasRef]);
20908
21222
  const { dragOverrides, dropTargetId, onPointerDown: onNodePointerDown } = useNodeDrag({
@@ -20919,7 +21233,7 @@ var SystemCanvas = (() => {
20919
21233
  onCommit: commitResize
20920
21234
  });
20921
21235
  const singleSelectedId = selectedIds.size === 1 ? Array.from(selectedIds)[0] : null;
20922
- const selectedResolvedNode = (0, import_react23.useMemo)(() => {
21236
+ const selectedResolvedNode = (0, import_react24.useMemo)(() => {
20923
21237
  if (!singleSelectedId)
20924
21238
  return null;
20925
21239
  const base = nodeMap.get(singleSelectedId);
@@ -20936,16 +21250,16 @@ var SystemCanvas = (() => {
20936
21250
  return base;
20937
21251
  }, [singleSelectedId, nodeMap, dragOverrides, resizeOverrides]);
20938
21252
  svgProxyRef.current = viewportHandleRef.current?.getSvgElement() ?? null;
20939
- const handleEdgeCreated = (0, import_react23.useCallback)((edge) => {
20940
- onEdgeAdd?.(edge, currentCanvasRef);
20941
- }, [onEdgeAdd, currentCanvasRef]);
21253
+ const handleEdgeCreated = (0, import_react24.useCallback)((edge) => {
21254
+ wrappedOnEdgeAdd(edge, currentCanvasRef);
21255
+ }, [wrappedOnEdgeAdd, currentCanvasRef]);
20942
21256
  const { pending: pendingEdge, onHandlePointerDown: onConnectionHandlePointerDown } = useEdgeCreate({
20943
21257
  svgRef: svgProxyRef,
20944
21258
  viewport: viewportStateRef,
20945
21259
  nodesRef,
20946
21260
  onCreate: handleEdgeCreated
20947
21261
  });
20948
- const handleNavigableNodeClick = (0, import_react23.useCallback)((node) => {
21262
+ const handleNavigableNodeClick = (0, import_react24.useCallback)((node) => {
20949
21263
  const frame2 = {
20950
21264
  parentCanvasRef: currentCanvasRef,
20951
21265
  parentNodeRect: {
@@ -20972,7 +21286,7 @@ var SystemCanvas = (() => {
20972
21286
  navigateToRef(node);
20973
21287
  }
20974
21288
  }, [navigateToRef, currentCanvasRef, zoomNavConfig.enabled]);
20975
- const handleZoomEnter = (0, import_react23.useCallback)((node, targetTransform) => {
21289
+ const handleZoomEnter = (0, import_react24.useCallback)((node, targetTransform) => {
20976
21290
  const frame2 = {
20977
21291
  parentCanvasRef: currentCanvasRef,
20978
21292
  parentNodeRect: {
@@ -20986,7 +21300,7 @@ var SystemCanvas = (() => {
20986
21300
  setPendingHandoff(targetTransform);
20987
21301
  navigateToRef(node);
20988
21302
  }, [currentCanvasRef, navigateToRef]);
20989
- const handleZoomExit = (0, import_react23.useCallback)((targetTransform) => {
21303
+ const handleZoomExit = (0, import_react24.useCallback)((targetTransform) => {
20990
21304
  setPendingHandoff(targetTransform);
20991
21305
  suppressNextHandoffClearRef.current = true;
20992
21306
  navigateToBreadcrumb(breadcrumbs.length - 2);
@@ -21013,26 +21327,26 @@ var SystemCanvas = (() => {
21013
21327
  onEnter: handleZoomEnter,
21014
21328
  onExit: handleZoomExit
21015
21329
  });
21016
- const handleViewportChange = (0, import_react23.useCallback)((vp) => {
21330
+ const handleViewportChange = (0, import_react24.useCallback)((vp) => {
21017
21331
  viewportStateRef.current = vp;
21018
21332
  handleZoomNavViewportChange(vp);
21019
21333
  onViewportChange?.(vp);
21020
21334
  }, [handleZoomNavViewportChange, onViewportChange]);
21021
- const handleHandoffApplied = (0, import_react23.useCallback)(() => {
21335
+ const handleHandoffApplied = (0, import_react24.useCallback)(() => {
21022
21336
  setPendingHandoff(null);
21023
21337
  clearZoomNavCommitting();
21024
21338
  }, [clearZoomNavCommitting]);
21025
- const handleBeginEdit = (0, import_react23.useCallback)((node) => {
21339
+ const handleBeginEdit = (0, import_react24.useCallback)((node) => {
21026
21340
  setEditingId(node.id);
21027
21341
  }, []);
21028
- const handleBeginEditEdge = (0, import_react23.useCallback)((edge) => {
21342
+ const handleBeginEditEdge = (0, import_react24.useCallback)((edge) => {
21029
21343
  setEditingEdgeId(edge.id);
21030
21344
  }, []);
21031
- const [contextMenuState, setContextMenuState] = (0, import_react23.useState)(null);
21032
- (0, import_react23.useEffect)(() => {
21345
+ const [contextMenuState, setContextMenuState] = (0, import_react24.useState)(null);
21346
+ (0, import_react24.useEffect)(() => {
21033
21347
  setContextMenuState(null);
21034
21348
  }, [currentCanvasRef]);
21035
- const handleContextMenu = (0, import_react23.useCallback)((event) => {
21349
+ const handleContextMenu = (0, import_react24.useCallback)((event) => {
21036
21350
  onContextMenu?.(event);
21037
21351
  if (!nodeContextMenu)
21038
21352
  return;
@@ -21075,27 +21389,27 @@ var SystemCanvas = (() => {
21075
21389
  onSelectEdge: setSelectedEdgeId,
21076
21390
  onBeginEditEdge: handleBeginEditEdge
21077
21391
  });
21078
- const handleEditorCommit = (0, import_react23.useCallback)((patch) => {
21392
+ const handleEditorCommit = (0, import_react24.useCallback)((patch) => {
21079
21393
  if (editingId) {
21080
- onNodeUpdate?.(editingId, patch, currentCanvasRef);
21394
+ wrappedOnNodeUpdate(editingId, patch, currentCanvasRef);
21081
21395
  }
21082
21396
  setEditingId(null);
21083
- }, [editingId, onNodeUpdate, currentCanvasRef]);
21084
- const handleEditorCancel = (0, import_react23.useCallback)(() => {
21397
+ }, [editingId, wrappedOnNodeUpdate, currentCanvasRef]);
21398
+ const handleEditorCancel = (0, import_react24.useCallback)(() => {
21085
21399
  setEditingId(null);
21086
21400
  }, []);
21087
- const handleEdgeEditorCommit = (0, import_react23.useCallback)((patch) => {
21401
+ const handleEdgeEditorCommit = (0, import_react24.useCallback)((patch) => {
21088
21402
  if (editingEdgeId) {
21089
- onEdgeUpdate?.(editingEdgeId, patch, currentCanvasRef);
21403
+ wrappedOnEdgeUpdate(editingEdgeId, patch, currentCanvasRef);
21090
21404
  }
21091
21405
  setEditingEdgeId(null);
21092
- }, [editingEdgeId, onEdgeUpdate, currentCanvasRef]);
21093
- const handleEdgeEditorCancel = (0, import_react23.useCallback)(() => {
21406
+ }, [editingEdgeId, wrappedOnEdgeUpdate, currentCanvasRef]);
21407
+ const handleEdgeEditorCancel = (0, import_react24.useCallback)(() => {
21094
21408
  setEditingEdgeId(null);
21095
21409
  }, []);
21096
- const lastAddRef = (0, import_react23.useRef)(null);
21097
- const menuOptions = (0, import_react23.useMemo)(() => getNodeMenuOptions(currentCanvas, theme), [currentCanvas, theme]);
21098
- const addNode2 = (0, import_react23.useCallback)((option, position) => {
21410
+ const lastAddRef = (0, import_react24.useRef)(null);
21411
+ const menuOptions = (0, import_react24.useMemo)(() => getNodeMenuOptions(currentCanvas, theme), [currentCanvas, theme]);
21412
+ const addNode2 = (0, import_react24.useCallback)((option, position) => {
21099
21413
  let x, y;
21100
21414
  if (position) {
21101
21415
  x = position.x;
@@ -21125,9 +21439,9 @@ var SystemCanvas = (() => {
21125
21439
  lastAddRef.current = { t: now2, offset: nextOffset };
21126
21440
  }
21127
21441
  const node = createNodeFromOption(option, Math.round(x), Math.round(y), void 0, theme);
21128
- onNodeAdd?.(node, currentCanvasRef);
21129
- }, [onNodeAdd, currentCanvasRef, theme]);
21130
- const handleKeyDown = (0, import_react23.useCallback)((e) => {
21442
+ wrappedOnNodeAdd(node, currentCanvasRef);
21443
+ }, [wrappedOnNodeAdd, currentCanvasRef, theme]);
21444
+ const handleKeyDown = (0, import_react24.useCallback)((e) => {
21131
21445
  if (!editable)
21132
21446
  return;
21133
21447
  if (e.key === "Escape") {
@@ -21139,6 +21453,16 @@ var SystemCanvas = (() => {
21139
21453
  }
21140
21454
  if (editingId || editingEdgeId)
21141
21455
  return;
21456
+ if ((e.metaKey || e.ctrlKey) && !e.shiftKey && e.key === "z") {
21457
+ e.preventDefault();
21458
+ undo();
21459
+ return;
21460
+ }
21461
+ if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === "z") {
21462
+ e.preventDefault();
21463
+ redo();
21464
+ return;
21465
+ }
21142
21466
  if ((e.metaKey || e.ctrlKey) && e.key === "a") {
21143
21467
  e.preventDefault();
21144
21468
  selectAll();
@@ -21147,16 +21471,16 @@ var SystemCanvas = (() => {
21147
21471
  if (e.key === "Delete" || e.key === "Backspace") {
21148
21472
  if (selectedIds.size > 1) {
21149
21473
  e.preventDefault();
21150
- onNodesDelete?.(Array.from(selectedIds), currentCanvasRef);
21474
+ wrappedOnNodesDelete(Array.from(selectedIds), currentCanvasRef);
21151
21475
  clearSelection();
21152
21476
  } else if (selectedIds.size === 1) {
21153
21477
  const id2 = Array.from(selectedIds)[0];
21154
21478
  e.preventDefault();
21155
- onNodeDelete?.(id2, currentCanvasRef);
21479
+ wrappedOnNodeDelete(id2, currentCanvasRef);
21156
21480
  clearSelection();
21157
21481
  } else if (selectedEdgeId) {
21158
21482
  e.preventDefault();
21159
- onEdgeDelete?.(selectedEdgeId, currentCanvasRef);
21483
+ wrappedOnEdgeDelete(selectedEdgeId, currentCanvasRef);
21160
21484
  setSelectedEdgeId(null);
21161
21485
  }
21162
21486
  }
@@ -21166,12 +21490,14 @@ var SystemCanvas = (() => {
21166
21490
  editingEdgeId,
21167
21491
  selectedIds,
21168
21492
  selectedEdgeId,
21169
- onNodeDelete,
21170
- onNodesDelete,
21171
- onEdgeDelete,
21493
+ wrappedOnNodeDelete,
21494
+ wrappedOnNodesDelete,
21495
+ wrappedOnEdgeDelete,
21172
21496
  currentCanvasRef,
21173
21497
  clearSelection,
21174
- selectAll
21498
+ selectAll,
21499
+ undo,
21500
+ redo
21175
21501
  ]);
21176
21502
  const renderProps = { options: menuOptions, addNode: addNode2, theme };
21177
21503
  return (0, import_jsx_runtime28.jsxs)("div", { ref: containerRef, className: `system-canvas ${className ?? ""}`, tabIndex: editable ? 0 : -1, onKeyDown: handleKeyDown, style: {
@@ -21194,9 +21520,9 @@ var SystemCanvas = (() => {
21194
21520
  fontSize: 12,
21195
21521
  backdropFilter: "blur(8px)"
21196
21522
  }, children: "Loading..." }), (0, import_jsx_runtime28.jsx)(Viewport, { ref: viewportHandleRef, nodes, edges, nodeMap, theme, edgeStyle, columns: currentCanvas.columns, rows: currentCanvas.rows, canvases, minZoom: effectiveMinZoom, maxZoom: effectiveMaxZoom, defaultViewport, autoFit, canvasRef: currentCanvasRef, handoffTransform: pendingHandoff, onHandoffApplied: handleHandoffApplied, handoffFadeMs: zoomNavConfig.fadeDuration, onViewportChange: handleViewportChange, onNodeClick: handleNodeClick, onNodeDoubleClick: handleNodeDoubleClick, onNodeNavigate: handleNodeNavigate, onEdgeClick: handleEdgeClick, onEdgeDoubleClick: handleEdgeDoubleClick, onCanvasClick: editable ? handleCanvasClick : void 0, onCanvasContextMenu: handleCanvasContextMenu, onNodeContextMenu: handleNodeContextMenu, onEdgeContextMenu: handleEdgeContextMenu, onNodePointerDown: editable ? onNodePointerDown : void 0, selectedIds: editable ? selectedIds : void 0, marqueeRect: editable ? marqueeRect : null, marqueeActiveRef: editable ? marqueeActiveRef : void 0, editingId: editable ? editingId : null, selectedEdgeId: editable ? selectedEdgeId : null, editingEdgeId: editable ? editingEdgeId : null, dragOverrides, dropTargetId, resizeOverrides, onResizeHandlePointerDown: editable ? onResizeHandlePointerDown : void 0, onEditorCommit: handleEditorCommit, onEditorCancel: handleEditorCancel, onEdgeEditorCommit: handleEdgeEditorCommit, onEdgeEditorCancel: handleEdgeEditorCancel, pendingEdge: editable ? pendingEdge : null, onConnectionHandlePointerDown: editable ? onConnectionHandlePointerDown : void 0, edgeCreateEnabled: editable }), showLaneHeaders && (0, import_jsx_runtime28.jsx)(LaneHeaders, { columns: currentCanvas.columns, rows: currentCanvas.rows, theme, getViewport: getViewportState, width: containerSize.width, height: containerSize.height, pinned: laneHeaders === "pinned" }), editable && showNodeToolbar && selectedIds.size === 1 && selectedResolvedNode && !editingId && (0, import_jsx_runtime28.jsx)(NodeToolbar, { node: selectedResolvedNode, theme, onPatch: (update) => {
21197
- onNodeUpdate?.(selectedResolvedNode.id, update, currentCanvasRef);
21523
+ wrappedOnNodeUpdate(selectedResolvedNode.id, update, currentCanvasRef);
21198
21524
  }, onDelete: () => {
21199
- onNodeDelete?.(selectedResolvedNode.id, currentCanvasRef);
21525
+ wrappedOnNodeDelete(selectedResolvedNode.id, currentCanvasRef);
21200
21526
  clearSelection();
21201
21527
  }, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height, render: renderNodeToolbar }), editable && showNodeToolbar && selectedIds.size > 1 && !editingId && (() => {
21202
21528
  const selectedResolvedNodes = Array.from(selectedIds).map((id2) => nodeMap.get(id2)).filter((n) => n != null);
@@ -21206,10 +21532,10 @@ var SystemCanvas = (() => {
21206
21532
  return (0, import_jsx_runtime28.jsx)(NodeToolbar, { node: anchorNode, selectedNodes: selectedResolvedNodes, theme, onPatch: () => {
21207
21533
  }, onMultiPatch: (patch) => {
21208
21534
  for (const id2 of selectedIds) {
21209
- onNodeUpdate?.(id2, patch, currentCanvasRef);
21535
+ wrappedOnNodeUpdate(id2, patch, currentCanvasRef);
21210
21536
  }
21211
21537
  }, onDelete: () => {
21212
- onNodesDelete?.(Array.from(selectedIds), currentCanvasRef);
21538
+ wrappedOnNodesDelete(Array.from(selectedIds), currentCanvasRef);
21213
21539
  clearSelection();
21214
21540
  }, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height });
21215
21541
  })(), editable && (renderAddNodeButton ? renderAddNodeButton(renderProps) : (0, import_jsx_runtime28.jsx)(AddNodeButton, { ...renderProps })), nodeContextMenu && (0, import_jsx_runtime28.jsx)(NodeContextMenuOverlay, { state: contextMenuState, config: nodeContextMenu, theme, onClose: () => setContextMenuState(null) })] });
@@ -21323,7 +21649,7 @@ var SystemCanvas = (() => {
21323
21649
  onEdgeUpdate: handleEdgeUpdate,
21324
21650
  onEdgeDelete: handleEdgeDelete
21325
21651
  };
21326
- root2.render(import_react24.default.createElement(SystemCanvas, props));
21652
+ root2.render(import_react25.default.createElement(SystemCanvas, props));
21327
21653
  };
21328
21654
  doRender();
21329
21655
  return {