@likec4/diagram 1.1.1 → 1.2.0

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.
Files changed (74) hide show
  1. package/dist/KeepAspectRatioContainer.d.ts +1 -1
  2. package/dist/LikeC4Diagram.d.ts +1 -1
  3. package/dist/LikeC4Diagram.props.d.ts +7 -2
  4. package/dist/StaticLikeC4Diagram.d.ts +1 -1
  5. package/dist/index.d.ts +0 -1
  6. package/dist/index.mjs +2517 -1326
  7. package/dist/mantine/EnsureMantine.d.ts +1 -1
  8. package/dist/state/DiagramContext.d.ts +2125 -10
  9. package/dist/state/WhenInitialized.d.ts +1 -1
  10. package/dist/state/diagramStore.d.ts +2133 -10
  11. package/dist/state/useDiagramStore.d.ts +2124 -9
  12. package/dist/style.css +210 -136
  13. package/dist/theme.css.d.ts +1 -0
  14. package/dist/ui/DiagramTitlePanel.d.ts +1 -2
  15. package/dist/ui/DynamicViewWalkthrough.css.d.ts +3 -0
  16. package/dist/ui/DynamicViewWalkthrough.d.ts +1 -0
  17. package/dist/ui/OptionsPanel.d.ts +1 -2
  18. package/dist/ui/index.d.ts +1 -0
  19. package/dist/ui/options/NodeOptions.d.ts +1 -2
  20. package/dist/xyflow/FitviewOnDiagramChange.d.ts +4 -2
  21. package/dist/xyflow/SyncWithDiagram.d.ts +1 -2
  22. package/dist/xyflow/XYFlow.d.ts +4 -7
  23. package/dist/xyflow/XYFlowBackground.d.ts +5 -4
  24. package/dist/xyflow/XYFlowEvents.d.ts +57 -63
  25. package/dist/xyflow/XYFlowInner.d.ts +11 -0
  26. package/dist/xyflow/diagram-to-xyflow.d.ts +1 -1
  27. package/dist/xyflow/edges/RelationshipEdge.d.ts +14 -14
  28. package/dist/xyflow/edges/edges.css.d.ts +4 -2
  29. package/dist/xyflow/edges/utils.d.ts +2 -0
  30. package/dist/xyflow/hooks/useXYFlow.d.ts +126 -126
  31. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +1 -0
  32. package/dist/xyflow/nodes/element/ElementIcon.d.ts +1 -1
  33. package/dist/xyflow/nodes/element/ElementLink.d.ts +1 -1
  34. package/dist/xyflow/nodes/element/ElementNode.d.ts +1 -1
  35. package/dist/xyflow/nodes/element/ElementShapeSvg.d.ts +2 -2
  36. package/dist/xyflow/nodes/element/element.css.d.ts +2 -1
  37. package/dist/xyflow/nodes/shared/NavigateToBtn.d.ts +1 -2
  38. package/dist/xyflow/types.d.ts +18 -18
  39. package/package.json +19 -16
  40. package/src/KeepAspectRatioContainer.tsx +1 -1
  41. package/src/LikeC4Diagram.css.ts +2 -0
  42. package/src/LikeC4Diagram.props.ts +9 -4
  43. package/src/LikeC4Diagram.tsx +17 -11
  44. package/src/StaticLikeC4Diagram.tsx +1 -0
  45. package/src/globals.css.ts +1 -0
  46. package/src/index.ts +0 -3
  47. package/src/state/DiagramContext.tsx +21 -12
  48. package/src/state/diagramStore.ts +177 -38
  49. package/src/theme.css.ts +1 -0
  50. package/src/ui/DiagramTitlePanel.css.ts +2 -1
  51. package/src/ui/DiagramTitlePanel.tsx +3 -4
  52. package/src/ui/DynamicViewWalkthrough.css.ts +46 -0
  53. package/src/ui/DynamicViewWalkthrough.tsx +86 -0
  54. package/src/ui/OptionsPanel.tsx +5 -3
  55. package/src/ui/index.ts +1 -0
  56. package/src/ui/options/NodeOptions.tsx +23 -24
  57. package/src/xyflow/FitviewOnDiagramChange.tsx +89 -69
  58. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +57 -39
  59. package/src/xyflow/SyncWithDiagram.tsx +55 -107
  60. package/src/xyflow/XYFlow.tsx +51 -35
  61. package/src/xyflow/XYFlowBackground.tsx +7 -5
  62. package/src/xyflow/XYFlowEvents.tsx +97 -92
  63. package/src/xyflow/XYFlowInner.tsx +50 -0
  64. package/src/xyflow/diagram-to-xyflow.ts +16 -21
  65. package/src/xyflow/edges/RelationshipEdge.tsx +70 -34
  66. package/src/xyflow/edges/edges.css.ts +68 -34
  67. package/src/xyflow/edges/utils.ts +31 -0
  68. package/src/xyflow/nodes/compound/CompoundNode.css.ts +6 -2
  69. package/src/xyflow/nodes/compound/CompoundNode.tsx +6 -3
  70. package/src/xyflow/nodes/element/ElementLink.tsx +13 -3
  71. package/src/xyflow/nodes/element/ElementNode.tsx +24 -19
  72. package/src/xyflow/nodes/element/element.css.ts +9 -2
  73. package/src/xyflow/nodes/shared/NavigateToBtn.tsx +1 -0
  74. package/src/xyflow/types.ts +7 -8
package/dist/index.mjs CHANGED
@@ -2,21 +2,21 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => (__defNormalProp(obj, typeof key != "symbol" ? key + "" : key, value), value);
4
4
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
- import { createContext, memo, useState, useEffect, useContext, useMemo, forwardRef, useCallback, useRef, useLayoutEffect, useId } from "react";
5
+ import { createContext, memo, useState, forwardRef, useCallback, useMemo, useEffect, useRef, useContext, useLayoutEffect, useId } from "react";
6
6
  import { createWithEqualityFn, useStoreWithEqualityFn } from "zustand/traditional";
7
7
  import { shallow } from "zustand/shallow";
8
8
  import { createPortal } from "react-dom";
9
- import { Box, MantineContext, Paper, Stack, Group, Text, Spoiler, Button, Anchor, CopyButton, Divider, TooltipGroup, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Slider, SegmentedControl, Card, ActionIcon, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, useMantineColorScheme } from "@mantine/core";
10
- import { invariant, isAncestor, nonNullable, nonexhaustive, defaultTheme, ElementShapes } from "@likec4/core";
9
+ import { Box, MantineContext, ActionIcon, Text, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, Stack, Group, Anchor, CopyButton, Button, useMantineColorScheme, Divider, TooltipGroup, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Slider, SegmentedControl, Card, Paper, Spoiler } from "@mantine/core";
10
+ import { isNullish, entries, hasSubObject, hasAtLeast, first, last, zip, clamp as clamp$1, isNumber, keys, takeWhile, isNonNull } from "remeda";
11
+ import { invariant, isAncestor, nonNullable, StepEdgeId, nonexhaustive, extractStep, defaultTheme, ElementShapes } from "@likec4/core";
11
12
  import { DEV } from "esm-env";
12
13
  import { shallowEqual, deepEqual } from "fast-equals";
13
- import { isNullish, entries, keys, hasAtLeast, takeWhile, clamp as clamp$1, isNumber } from "remeda";
14
14
  import { subscribeWithSelector, devtools } from "zustand/middleware";
15
- import { useFirstMountState, useCustomCompareEffect, useDebouncedCallback, useRafEffect, useDebouncedEffect } from "@react-hookz/web";
16
- import { AnimatePresence, motion } from "framer-motion";
17
- import { useLocalStorage } from "@mantine/hooks";
15
+ import { useFirstMountState, useCustomCompareEffect, useDebouncedEffect } from "@react-hookz/web";
18
16
  import { line, curveCatmullRomOpen } from "d3-shape";
19
- var rootClassName = "likec4-diagram-root";
17
+ import { motion, AnimatePresence } from "framer-motion";
18
+ import { useLocalStorage } from "@mantine/hooks";
19
+ import { IconPlayerPlayFilled, IconPlayerSkipBackFilled, IconPlayerStopFilled, IconPlayerSkipForwardFilled } from "@tabler/icons-react";
20
20
  function cc(names) {
21
21
  if (typeof names == "string" || typeof names == "number")
22
22
  return "" + names;
@@ -32,10 +32,10 @@ function cc(names) {
32
32
  var noop$1 = { value: () => {
33
33
  } };
34
34
  function dispatch() {
35
- for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
36
- if (!(t = arguments[i] + "") || t in _ || /[\s.]/.test(t))
37
- throw new Error("illegal type: " + t);
38
- _[t] = [];
35
+ for (var i = 0, n = arguments.length, _ = {}, t2; i < n; ++i) {
36
+ if (!(t2 = arguments[i] + "") || t2 in _ || /[\s.]/.test(t2))
37
+ throw new Error("illegal type: " + t2);
38
+ _[t2] = [];
39
39
  }
40
40
  return new Dispatch(_);
41
41
  }
@@ -43,53 +43,53 @@ function Dispatch(_) {
43
43
  this._ = _;
44
44
  }
45
45
  function parseTypenames$1(typenames, types) {
46
- return typenames.trim().split(/^|\s+/).map(function(t) {
47
- var name = "", i = t.indexOf(".");
48
- if (i >= 0 && (name = t.slice(i + 1), t = t.slice(0, i)), t && !types.hasOwnProperty(t))
49
- throw new Error("unknown type: " + t);
50
- return { type: t, name };
46
+ return typenames.trim().split(/^|\s+/).map(function(t2) {
47
+ var name = "", i = t2.indexOf(".");
48
+ if (i >= 0 && (name = t2.slice(i + 1), t2 = t2.slice(0, i)), t2 && !types.hasOwnProperty(t2))
49
+ throw new Error("unknown type: " + t2);
50
+ return { type: t2, name };
51
51
  });
52
52
  }
53
53
  Dispatch.prototype = dispatch.prototype = {
54
54
  constructor: Dispatch,
55
55
  on: function(typename, callback) {
56
- var _ = this._, T = parseTypenames$1(typename + "", _), t, i = -1, n = T.length;
56
+ var _ = this._, T = parseTypenames$1(typename + "", _), t2, i = -1, n = T.length;
57
57
  if (arguments.length < 2) {
58
58
  for (; ++i < n; )
59
- if ((t = (typename = T[i]).type) && (t = get$2(_[t], typename.name)))
60
- return t;
59
+ if ((t2 = (typename = T[i]).type) && (t2 = get$2(_[t2], typename.name)))
60
+ return t2;
61
61
  return;
62
62
  }
63
63
  if (callback != null && typeof callback != "function")
64
64
  throw new Error("invalid callback: " + callback);
65
65
  for (; ++i < n; )
66
- if (t = (typename = T[i]).type)
67
- _[t] = set$1(_[t], typename.name, callback);
66
+ if (t2 = (typename = T[i]).type)
67
+ _[t2] = set$1(_[t2], typename.name, callback);
68
68
  else if (callback == null)
69
- for (t in _)
70
- _[t] = set$1(_[t], typename.name, null);
69
+ for (t2 in _)
70
+ _[t2] = set$1(_[t2], typename.name, null);
71
71
  return this;
72
72
  },
73
73
  copy: function() {
74
74
  var copy = {}, _ = this._;
75
- for (var t in _)
76
- copy[t] = _[t].slice();
75
+ for (var t2 in _)
76
+ copy[t2] = _[t2].slice();
77
77
  return new Dispatch(copy);
78
78
  },
79
79
  call: function(type, that) {
80
80
  if ((n = arguments.length - 2) > 0)
81
- for (var args = new Array(n), i = 0, n, t; i < n; ++i)
81
+ for (var args = new Array(n), i = 0, n, t2; i < n; ++i)
82
82
  args[i] = arguments[i + 2];
83
83
  if (!this._.hasOwnProperty(type))
84
84
  throw new Error("unknown type: " + type);
85
- for (t = this._[type], i = 0, n = t.length; i < n; ++i)
86
- t[i].value.apply(that, args);
85
+ for (t2 = this._[type], i = 0, n = t2.length; i < n; ++i)
86
+ t2[i].value.apply(that, args);
87
87
  },
88
88
  apply: function(type, that, args) {
89
89
  if (!this._.hasOwnProperty(type))
90
90
  throw new Error("unknown type: " + type);
91
- for (var t = this._[type], i = 0, n = t.length; i < n; ++i)
92
- t[i].value.apply(that, args);
91
+ for (var t2 = this._[type], i = 0, n = t2.length; i < n; ++i)
92
+ t2[i].value.apply(that, args);
93
93
  }
94
94
  };
95
95
  function get$2(type, name) {
@@ -571,9 +571,9 @@ function contextListener(listener) {
571
571
  };
572
572
  }
573
573
  function parseTypenames(typenames) {
574
- return typenames.trim().split(/^|\s+/).map(function(t) {
575
- var name = "", i = t.indexOf(".");
576
- return i >= 0 && (name = t.slice(i + 1), t = t.slice(0, i)), { type: t, name };
574
+ return typenames.trim().split(/^|\s+/).map(function(t2) {
575
+ var name = "", i = t2.indexOf(".");
576
+ return i >= 0 && (name = t2.slice(i + 1), t2 = t2.slice(0, i)), { type: t2, name };
577
577
  });
578
578
  }
579
579
  function onRemove(typename) {
@@ -600,13 +600,13 @@ function onAdd(typename, value, options) {
600
600
  };
601
601
  }
602
602
  function selection_on(typename, value, options) {
603
- var typenames = parseTypenames(typename + ""), i, n = typenames.length, t;
603
+ var typenames = parseTypenames(typename + ""), i, n = typenames.length, t2;
604
604
  if (arguments.length < 2) {
605
605
  var on = this.node().__on;
606
606
  if (on) {
607
607
  for (var j = 0, m = on.length, o; j < m; ++j)
608
608
  for (i = 0, o = on[j]; i < n; ++i)
609
- if ((t = typenames[i]).type === o.type && t.name === o.name)
609
+ if ((t2 = typenames[i]).type === o.type && t2.name === o.name)
610
610
  return o.value;
611
611
  }
612
612
  return;
@@ -1127,8 +1127,8 @@ function hslConvert(o) {
1127
1127
  if (o instanceof Hsl)
1128
1128
  return o;
1129
1129
  o = o.rgb();
1130
- var r2 = o.r / 255, g = o.g / 255, b = o.b / 255, min = Math.min(r2, g, b), max = Math.max(r2, g, b), h = NaN, s = max - min, l = (max + min) / 2;
1131
- return s ? (r2 === max ? h = (g - b) / s + (g < b) * 6 : g === max ? h = (b - r2) / s + 2 : h = (r2 - g) / s + 4, s /= l < 0.5 ? max + min : 2 - max - min, h *= 60) : s = l > 0 && l < 1 ? 0 : h, new Hsl(h, s, l, o.opacity);
1130
+ var r2 = o.r / 255, g = o.g / 255, b = o.b / 255, min2 = Math.min(r2, g, b), max2 = Math.max(r2, g, b), h = NaN, s = max2 - min2, l = (max2 + min2) / 2;
1131
+ return s ? (r2 === max2 ? h = (g - b) / s + (g < b) * 6 : g === max2 ? h = (b - r2) / s + 2 : h = (r2 - g) / s + 4, s /= l < 0.5 ? max2 + min2 : 2 - max2 - min2, h *= 60) : s = l > 0 && l < 1 ? 0 : h, new Hsl(h, s, l, o.opacity);
1132
1132
  }
1133
1133
  function hsl(h, s, l, opacity) {
1134
1134
  return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity ?? 1);
@@ -1174,13 +1174,13 @@ function hsl2rgb(h, m1, m2) {
1174
1174
  }
1175
1175
  const constant$1 = (x) => () => x;
1176
1176
  function linear(a, d) {
1177
- return function(t) {
1178
- return a + t * d;
1177
+ return function(t2) {
1178
+ return a + t2 * d;
1179
1179
  };
1180
1180
  }
1181
1181
  function exponential(a, b, y) {
1182
- return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
1183
- return Math.pow(a + t * b, y);
1182
+ return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t2) {
1183
+ return Math.pow(a + t2 * b, y);
1184
1184
  };
1185
1185
  }
1186
1186
  function gamma(y) {
@@ -1196,15 +1196,15 @@ const interpolateRgb = function rgbGamma(y) {
1196
1196
  var color2 = gamma(y);
1197
1197
  function rgb$1(start2, end) {
1198
1198
  var r2 = color2((start2 = rgb(start2)).r, (end = rgb(end)).r), g = color2(start2.g, end.g), b = color2(start2.b, end.b), opacity = nogamma(start2.opacity, end.opacity);
1199
- return function(t) {
1200
- return start2.r = r2(t), start2.g = g(t), start2.b = b(t), start2.opacity = opacity(t), start2 + "";
1199
+ return function(t2) {
1200
+ return start2.r = r2(t2), start2.g = g(t2), start2.b = b(t2), start2.opacity = opacity(t2), start2 + "";
1201
1201
  };
1202
1202
  }
1203
1203
  return rgb$1.gamma = rgbGamma, rgb$1;
1204
1204
  }(1);
1205
1205
  function interpolateNumber(a, b) {
1206
- return a = +a, b = +b, function(t) {
1207
- return a * (1 - t) + b * t;
1206
+ return a = +a, b = +b, function(t2) {
1207
+ return a * (1 - t2) + b * t2;
1208
1208
  };
1209
1209
  }
1210
1210
  var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, reB = new RegExp(reA.source, "g");
@@ -1214,17 +1214,17 @@ function zero(b) {
1214
1214
  };
1215
1215
  }
1216
1216
  function one(b) {
1217
- return function(t) {
1218
- return b(t) + "";
1217
+ return function(t2) {
1218
+ return b(t2) + "";
1219
1219
  };
1220
1220
  }
1221
1221
  function interpolateString(a, b) {
1222
1222
  var bi = reA.lastIndex = reB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = [];
1223
1223
  for (a = a + "", b = b + ""; (am = reA.exec(a)) && (bm = reB.exec(b)); )
1224
1224
  (bs = bm.index) > bi && (bs = b.slice(bi, bs), s[i] ? s[i] += bs : s[++i] = bs), (am = am[0]) === (bm = bm[0]) ? s[i] ? s[i] += bm : s[++i] = bm : (s[++i] = null, q.push({ i, x: interpolateNumber(am, bm) })), bi = reB.lastIndex;
1225
- return bi < b.length && (bs = b.slice(bi), s[i] ? s[i] += bs : s[++i] = bs), s.length < 2 ? q[0] ? one(q[0].x) : zero(b) : (b = q.length, function(t) {
1225
+ return bi < b.length && (bs = b.slice(bi), s[i] ? s[i] += bs : s[++i] = bs), s.length < 2 ? q[0] ? one(q[0].x) : zero(b) : (b = q.length, function(t2) {
1226
1226
  for (var i2 = 0, o; i2 < b; ++i2)
1227
- s[(o = q[i2]).i] = o.x(t);
1227
+ s[(o = q[i2]).i] = o.x(t2);
1228
1228
  return s.join("");
1229
1229
  });
1230
1230
  }
@@ -1281,9 +1281,9 @@ function interpolateTransform(parse, pxComma, pxParen, degParen) {
1281
1281
  }
1282
1282
  return function(a, b) {
1283
1283
  var s = [], q = [];
1284
- return a = parse(a), b = parse(b), translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q), rotate(a.rotate, b.rotate, s, q), skewX(a.skewX, b.skewX, s, q), scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q), a = b = null, function(t) {
1284
+ return a = parse(a), b = parse(b), translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q), rotate(a.rotate, b.rotate, s, q), skewX(a.skewX, b.skewX, s, q), scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q), a = b = null, function(t2) {
1285
1285
  for (var i = -1, n = q.length, o; ++i < n; )
1286
- s[(o = q[i]).i] = o.x(t);
1286
+ s[(o = q[i]).i] = o.x(t2);
1287
1287
  return s.join("");
1288
1288
  };
1289
1289
  };
@@ -1302,17 +1302,17 @@ const interpolateZoom = function zoomRho(rho, rho2, rho4) {
1302
1302
  function zoom2(p0, p1) {
1303
1303
  var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2], dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, i, S;
1304
1304
  if (d2 < epsilon2)
1305
- S = Math.log(w1 / w0) / rho, i = function(t) {
1305
+ S = Math.log(w1 / w0) / rho, i = function(t2) {
1306
1306
  return [
1307
- ux0 + t * dx,
1308
- uy0 + t * dy,
1309
- w0 * Math.exp(rho * t * S)
1307
+ ux0 + t2 * dx,
1308
+ uy0 + t2 * dy,
1309
+ w0 * Math.exp(rho * t2 * S)
1310
1310
  ];
1311
1311
  };
1312
1312
  else {
1313
1313
  var d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
1314
- S = (r1 - r0) / rho, i = function(t) {
1315
- var s = t * S, coshr0 = cosh(r0), u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
1314
+ S = (r1 - r0) / rho, i = function(t2) {
1315
+ var s = t2 * S, coshr0 = cosh(r0), u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
1316
1316
  return [
1317
1317
  ux0 + u * dx,
1318
1318
  uy0 + u * dy,
@@ -1351,13 +1351,13 @@ Timer.prototype = timer.prototype = {
1351
1351
  }
1352
1352
  };
1353
1353
  function timer(callback, delay, time) {
1354
- var t = new Timer();
1355
- return t.restart(callback, delay, time), t;
1354
+ var t2 = new Timer();
1355
+ return t2.restart(callback, delay, time), t2;
1356
1356
  }
1357
1357
  function timerFlush() {
1358
1358
  now(), ++frame;
1359
- for (var t = taskHead, e; t; )
1360
- (e = clockNow - t._time) >= 0 && t._call.call(void 0, e), t = t._next;
1359
+ for (var t2 = taskHead, e; t2; )
1360
+ (e = clockNow - t2._time) >= 0 && t2._call.call(void 0, e), t2 = t2._next;
1361
1361
  --frame;
1362
1362
  }
1363
1363
  function wake() {
@@ -1385,10 +1385,10 @@ function sleep(time) {
1385
1385
  }
1386
1386
  }
1387
1387
  function timeout(callback, delay, time) {
1388
- var t = new Timer();
1389
- return delay = delay == null ? 0 : +delay, t.restart((elapsed) => {
1390
- t.stop(), callback(elapsed + delay);
1391
- }, delay, time), t;
1388
+ var t2 = new Timer();
1389
+ return delay = delay == null ? 0 : +delay, t2.restart((elapsed) => {
1390
+ t2.stop(), callback(elapsed + delay);
1391
+ }, delay, time), t2;
1392
1392
  }
1393
1393
  var emptyOn = dispatch("start", "end", "cancel", "interrupt"), emptyTween = [], CREATED = 0, SCHEDULED = 1, STARTING = 2, STARTED = 3, RUNNING = 4, ENDING = 5, ENDED = 6;
1394
1394
  function schedule(node, name, id2, index2, group, timing) {
@@ -1456,8 +1456,8 @@ function create(node, id2, self) {
1456
1456
  }
1457
1457
  }
1458
1458
  function tick(elapsed) {
1459
- for (var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), i = -1, n = tween.length; ++i < n; )
1460
- tween[i].call(node, t);
1459
+ for (var t2 = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1), i = -1, n = tween.length; ++i < n; )
1460
+ tween[i].call(node, t2);
1461
1461
  self.state === ENDING && (self.on.call("end", node, node.__data__, self.index, self.group), stop());
1462
1462
  }
1463
1463
  function stop() {
@@ -1509,12 +1509,12 @@ function tweenFunction(id2, name, value) {
1509
1509
  var schedule2 = set(this, id2), tween = schedule2.tween;
1510
1510
  if (tween !== tween0) {
1511
1511
  tween1 = (tween0 = tween).slice();
1512
- for (var t = { name, value }, i = 0, n = tween1.length; i < n; ++i)
1512
+ for (var t2 = { name, value }, i = 0, n = tween1.length; i < n; ++i)
1513
1513
  if (tween1[i].name === name) {
1514
- tween1[i] = t;
1514
+ tween1[i] = t2;
1515
1515
  break;
1516
1516
  }
1517
- i === n && tween1.push(t);
1517
+ i === n && tween1.push(t2);
1518
1518
  }
1519
1519
  schedule2.tween = tween1;
1520
1520
  };
@@ -1522,9 +1522,9 @@ function tweenFunction(id2, name, value) {
1522
1522
  function transition_tween(name, value) {
1523
1523
  var id2 = this._id;
1524
1524
  if (name += "", arguments.length < 2) {
1525
- for (var tween = get$1(this.node(), id2).tween, i = 0, n = tween.length, t; i < n; ++i)
1526
- if ((t = tween[i]).name === name)
1527
- return t.value;
1525
+ for (var tween = get$1(this.node(), id2).tween, i = 0, n = tween.length, t2; i < n; ++i)
1526
+ if ((t2 = tween[i]).name === name)
1527
+ return t2.value;
1528
1528
  return null;
1529
1529
  }
1530
1530
  return this.each((value == null ? tweenRemove : tweenFunction)(id2, name, value));
@@ -1585,13 +1585,13 @@ function transition_attr(name, value) {
1585
1585
  return this.attrTween(name, typeof value == "function" ? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, "attr." + name, value)) : value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname) : (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value));
1586
1586
  }
1587
1587
  function attrInterpolate(name, i) {
1588
- return function(t) {
1589
- this.setAttribute(name, i.call(this, t));
1588
+ return function(t2) {
1589
+ this.setAttribute(name, i.call(this, t2));
1590
1590
  };
1591
1591
  }
1592
1592
  function attrInterpolateNS(fullname, i) {
1593
- return function(t) {
1594
- this.setAttributeNS(fullname.space, fullname.local, i.call(this, t));
1593
+ return function(t2) {
1594
+ this.setAttributeNS(fullname.space, fullname.local, i.call(this, t2));
1595
1595
  };
1596
1596
  }
1597
1597
  function attrTweenNS(fullname, value) {
@@ -1691,9 +1691,9 @@ function transition_merge(transition) {
1691
1691
  return new Transition(merges, this._parents, this._name, this._id);
1692
1692
  }
1693
1693
  function start(name) {
1694
- return (name + "").trim().split(/^|\s+/).every(function(t) {
1695
- var i = t.indexOf(".");
1696
- return i >= 0 && (t = t.slice(0, i)), !t || t === "start";
1694
+ return (name + "").trim().split(/^|\s+/).every(function(t2) {
1695
+ var i = t2.indexOf(".");
1696
+ return i >= 0 && (t2 = t2.slice(0, i)), !t2 || t2 === "start";
1697
1697
  });
1698
1698
  }
1699
1699
  function onFunction(id2, name, listener) {
@@ -1781,15 +1781,15 @@ function transition_style(name, value, priority) {
1781
1781
  return value == null ? this.styleTween(name, styleNull(name, i)).on("end.style." + name, styleRemove(name)) : typeof value == "function" ? this.styleTween(name, styleFunction(name, i, tweenValue(this, "style." + name, value))).each(styleMaybeRemove(this._id, name)) : this.styleTween(name, styleConstant(name, i, value), priority).on("end.style." + name, null);
1782
1782
  }
1783
1783
  function styleInterpolate(name, i, priority) {
1784
- return function(t) {
1785
- this.style.setProperty(name, i.call(this, t), priority);
1784
+ return function(t2) {
1785
+ this.style.setProperty(name, i.call(this, t2), priority);
1786
1786
  };
1787
1787
  }
1788
1788
  function styleTween(name, value, priority) {
1789
- var t, i0;
1789
+ var t2, i0;
1790
1790
  function tween() {
1791
1791
  var i = value.apply(this, arguments);
1792
- return i !== i0 && (t = (i0 = i) && styleInterpolate(name, i, priority)), t;
1792
+ return i !== i0 && (t2 = (i0 = i) && styleInterpolate(name, i, priority)), t2;
1793
1793
  }
1794
1794
  return tween._value = value, tween;
1795
1795
  }
@@ -1818,8 +1818,8 @@ function transition_text(value) {
1818
1818
  return this.tween("text", typeof value == "function" ? textFunction(tweenValue(this, "text", value)) : textConstant(value == null ? "" : value + ""));
1819
1819
  }
1820
1820
  function textInterpolate(i) {
1821
- return function(t) {
1822
- this.textContent = i.call(this, t);
1821
+ return function(t2) {
1822
+ this.textContent = i.call(this, t2);
1823
1823
  };
1824
1824
  }
1825
1825
  function textTween(value) {
@@ -1906,8 +1906,8 @@ Transition.prototype = {
1906
1906
  end: transition_end,
1907
1907
  [Symbol.iterator]: selection_prototype[Symbol.iterator]
1908
1908
  };
1909
- function cubicInOut(t) {
1910
- return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
1909
+ function cubicInOut(t2) {
1910
+ return ((t2 *= 2) <= 1 ? t2 * t2 * t2 : (t2 -= 2) * t2 * t2 + 2) / 2;
1911
1911
  }
1912
1912
  var defaultTiming = {
1913
1913
  time: null,
@@ -2052,8 +2052,8 @@ function zoom() {
2052
2052
  }, null, event);
2053
2053
  }, zoom2.translateTo = function(selection2, x, y, p, event) {
2054
2054
  zoom2.transform(selection2, function() {
2055
- var e = extent.apply(this, arguments), t = this.__zoom, p0 = p == null ? centroid(e) : typeof p == "function" ? p.apply(this, arguments) : p;
2056
- return constrain(identity.translate(p0[0], p0[1]).scale(t.k).translate(
2055
+ var e = extent.apply(this, arguments), t2 = this.__zoom, p0 = p == null ? centroid(e) : typeof p == "function" ? p.apply(this, arguments) : p;
2056
+ return constrain(identity.translate(p0[0], p0[1]).scale(t2.k).translate(
2057
2057
  typeof x == "function" ? -x.apply(this, arguments) : -x,
2058
2058
  typeof y == "function" ? -y.apply(this, arguments) : -y
2059
2059
  ), e, translateExtent);
@@ -2076,14 +2076,14 @@ function zoom() {
2076
2076
  gesture(this, arguments).event(event).end();
2077
2077
  }).tween("zoom", function() {
2078
2078
  var that = this, args = arguments, g = gesture(that, args).event(event), e = extent.apply(that, args), p = point == null ? centroid(e) : typeof point == "function" ? point.apply(that, args) : point, w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]), a = that.__zoom, b = typeof transform2 == "function" ? transform2.apply(that, args) : transform2, i = interpolate2(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
2079
- return function(t) {
2080
- if (t === 1)
2081
- t = b;
2079
+ return function(t2) {
2080
+ if (t2 === 1)
2081
+ t2 = b;
2082
2082
  else {
2083
- var l = i(t), k = w / l[2];
2084
- t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k);
2083
+ var l = i(t2), k = w / l[2];
2084
+ t2 = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k);
2085
2085
  }
2086
- g.zoom(null, t);
2086
+ g.zoom(null, t2);
2087
2087
  };
2088
2088
  });
2089
2089
  }
@@ -2125,15 +2125,15 @@ function zoom() {
2125
2125
  function wheeled(event, ...args) {
2126
2126
  if (!filter2.apply(this, arguments))
2127
2127
  return;
2128
- var g = gesture(this, args).event(event), t = this.__zoom, k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t.k * Math.pow(2, wheelDelta2.apply(this, arguments)))), p = pointer(event);
2128
+ var g = gesture(this, args).event(event), t2 = this.__zoom, k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], t2.k * Math.pow(2, wheelDelta2.apply(this, arguments)))), p = pointer(event);
2129
2129
  if (g.wheel)
2130
- (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) && (g.mouse[1] = t.invert(g.mouse[0] = p)), clearTimeout(g.wheel);
2130
+ (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) && (g.mouse[1] = t2.invert(g.mouse[0] = p)), clearTimeout(g.wheel);
2131
2131
  else {
2132
- if (t.k === k)
2132
+ if (t2.k === k)
2133
2133
  return;
2134
- g.mouse = [p, t.invert(p)], interrupt(this), g.start();
2134
+ g.mouse = [p, t2.invert(p)], interrupt(this), g.start();
2135
2135
  }
2136
- noevent(event), g.wheel = setTimeout(wheelidled, wheelDelay), g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
2136
+ noevent(event), g.wheel = setTimeout(wheelidled, wheelDelay), g.zoom("mouse", constrain(translate(scale(t2, k), g.mouse[0], g.mouse[1]), g.extent, translateExtent));
2137
2137
  function wheelidled() {
2138
2138
  g.wheel = null, g.end();
2139
2139
  }
@@ -2162,9 +2162,9 @@ function zoom() {
2162
2162
  }
2163
2163
  function touchstarted(event, ...args) {
2164
2164
  if (filter2.apply(this, arguments)) {
2165
- var touches = event.touches, n = touches.length, g = gesture(this, args, event.changedTouches.length === n).event(event), started, i, t, p;
2165
+ var touches = event.touches, n = touches.length, g = gesture(this, args, event.changedTouches.length === n).event(event), started, i, t2, p;
2166
2166
  for (nopropagation(event), i = 0; i < n; ++i)
2167
- t = touches[i], p = pointer(t, this), p = [p, this.__zoom.invert(p), t.identifier], g.touch0 ? !g.touch1 && g.touch0[2] !== p[2] && (g.touch1 = p, g.taps = 0) : (g.touch0 = p, started = !0, g.taps = 1 + !!touchstarting);
2167
+ t2 = touches[i], p = pointer(t2, this), p = [p, this.__zoom.invert(p), t2.identifier], g.touch0 ? !g.touch1 && g.touch0[2] !== p[2] && (g.touch1 = p, g.taps = 0) : (g.touch0 = p, started = !0, g.taps = 1 + !!touchstarting);
2168
2168
  touchstarting && (touchstarting = clearTimeout(touchstarting)), started && (g.taps < 2 && (touchfirst = p[0], touchstarting = setTimeout(function() {
2169
2169
  touchstarting = null;
2170
2170
  }, touchDelay)), interrupt(this), g.start());
@@ -2172,29 +2172,29 @@ function zoom() {
2172
2172
  }
2173
2173
  function touchmoved(event, ...args) {
2174
2174
  if (this.__zooming) {
2175
- var g = gesture(this, args).event(event), touches = event.changedTouches, n = touches.length, i, t, p, l;
2175
+ var g = gesture(this, args).event(event), touches = event.changedTouches, n = touches.length, i, t2, p, l;
2176
2176
  for (noevent(event), i = 0; i < n; ++i)
2177
- t = touches[i], p = pointer(t, this), g.touch0 && g.touch0[2] === t.identifier ? g.touch0[0] = p : g.touch1 && g.touch1[2] === t.identifier && (g.touch1[0] = p);
2178
- if (t = g.that.__zoom, g.touch1) {
2177
+ t2 = touches[i], p = pointer(t2, this), g.touch0 && g.touch0[2] === t2.identifier ? g.touch0[0] = p : g.touch1 && g.touch1[2] === t2.identifier && (g.touch1[0] = p);
2178
+ if (t2 = g.that.__zoom, g.touch1) {
2179
2179
  var p0 = g.touch0[0], l0 = g.touch0[1], p1 = g.touch1[0], l1 = g.touch1[1], dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp, dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
2180
- t = scale(t, Math.sqrt(dp / dl)), p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2], l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
2180
+ t2 = scale(t2, Math.sqrt(dp / dl)), p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2], l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
2181
2181
  } else if (g.touch0)
2182
2182
  p = g.touch0[0], l = g.touch0[1];
2183
2183
  else
2184
2184
  return;
2185
- g.zoom("touch", constrain(translate(t, p, l), g.extent, translateExtent));
2185
+ g.zoom("touch", constrain(translate(t2, p, l), g.extent, translateExtent));
2186
2186
  }
2187
2187
  }
2188
2188
  function touchended(event, ...args) {
2189
2189
  if (this.__zooming) {
2190
- var g = gesture(this, args).event(event), touches = event.changedTouches, n = touches.length, i, t;
2190
+ var g = gesture(this, args).event(event), touches = event.changedTouches, n = touches.length, i, t2;
2191
2191
  for (nopropagation(event), touchending && clearTimeout(touchending), touchending = setTimeout(function() {
2192
2192
  touchending = null;
2193
2193
  }, touchDelay), i = 0; i < n; ++i)
2194
- t = touches[i], g.touch0 && g.touch0[2] === t.identifier ? delete g.touch0 : g.touch1 && g.touch1[2] === t.identifier && delete g.touch1;
2194
+ t2 = touches[i], g.touch0 && g.touch0[2] === t2.identifier ? delete g.touch0 : g.touch1 && g.touch1[2] === t2.identifier && delete g.touch1;
2195
2195
  if (g.touch1 && !g.touch0 && (g.touch0 = g.touch1, delete g.touch1), g.touch0)
2196
2196
  g.touch0[1] = this.__zoom.invert(g.touch0[0]);
2197
- else if (g.end(), g.taps === 2 && (t = pointer(t, this), Math.hypot(touchfirst[0] - t[0], touchfirst[1] - t[1]) < tapDistance)) {
2197
+ else if (g.end(), g.taps === 2 && (t2 = pointer(t2, this), Math.hypot(touchfirst[0] - t2[0], touchfirst[1] - t2[1]) < tapDistance)) {
2198
2198
  var p = select(this).on("dblclick.zoom");
2199
2199
  p && p.apply(this, arguments);
2200
2200
  }
@@ -2269,7 +2269,7 @@ var Position;
2269
2269
  (function(Position2) {
2270
2270
  Position2.Left = "left", Position2.Top = "top", Position2.Right = "right", Position2.Bottom = "bottom";
2271
2271
  })(Position || (Position = {}));
2272
- const isEdgeBase = (element) => "id" in element && "source" in element && "target" in element, isNodeBase = (element) => "id" in element && "position" in element && !("source" in element) && !("target" in element), getNodePositionWithOrigin = (node, nodeOrigin = [0, 0]) => {
2272
+ const isEdgeBase = (element2) => "id" in element2 && "source" in element2 && "target" in element2, isNodeBase = (element2) => "id" in element2 && "position" in element2 && !("source" in element2) && !("target" in element2), getNodePositionWithOrigin = (node, nodeOrigin = [0, 0]) => {
2273
2273
  const { width, height } = getNodeDimensions(node), positionAbsolute = "internals" in node ? node.internals.positionAbsolute : node.position, origin = node.origin || nodeOrigin, offsetX = width * origin[0], offsetY = height * origin[1];
2274
2274
  return {
2275
2275
  position: {
@@ -2387,10 +2387,10 @@ async function getElementsToRemove({ nodesToRemove = [], edgesToRemove = [], nod
2387
2387
  });
2388
2388
  return typeof onBeforeDeleteResult == "boolean" ? onBeforeDeleteResult ? { edges: matchingEdges, nodes: matchingNodes } : { edges: [], nodes: [] } : onBeforeDeleteResult;
2389
2389
  }
2390
- const clamp = (val, min = 0, max = 1) => Math.min(Math.max(val, min), max), clampPosition = (position = { x: 0, y: 0 }, extent) => ({
2390
+ const clamp = (val, min2 = 0, max2 = 1) => Math.min(Math.max(val, min2), max2), clampPosition = (position = { x: 0, y: 0 }, extent) => ({
2391
2391
  x: clamp(position.x, extent[0][0], extent[1][0]),
2392
2392
  y: clamp(position.y, extent[0][1], extent[1][1])
2393
- }), calcAutoPanVelocity = (value, min, max) => value < min ? clamp(Math.abs(value - min), 1, 50) / 50 : value > max ? -clamp(Math.abs(value - max), 1, 50) / 50 : 0, calcAutoPan = (pos, bounds) => {
2393
+ }), calcAutoPanVelocity = (value, min2, max2) => value < min2 ? clamp(Math.abs(value - min2), 1, 50) / 50 : value > max2 ? -clamp(Math.abs(value - max2), 1, 50) / 50 : 0, calcAutoPan = (pos, bounds) => {
2394
2394
  const xMovement = calcAutoPanVelocity(pos.x, 35, bounds.width - 35) * 20, yMovement = calcAutoPanVelocity(pos.y, 35, bounds.height - 35) * 20;
2395
2395
  return [xMovement, yMovement];
2396
2396
  }, getBoundsOfBoxes = (box1, box2) => ({
@@ -2489,9 +2489,9 @@ function getPointerPosition(event, { snapGrid = [0, 0], snapToGrid = !1, transfo
2489
2489
  const getDimensions = (node) => ({
2490
2490
  width: node.offsetWidth,
2491
2491
  height: node.offsetHeight
2492
- }), getHostForElement = (element) => {
2492
+ }), getHostForElement = (element2) => {
2493
2493
  var _a;
2494
- return ((_a = element.getRootNode) == null ? void 0 : _a.call(element)) || (window == null ? void 0 : window.document);
2494
+ return ((_a = element2.getRootNode) == null ? void 0 : _a.call(element2)) || (window == null ? void 0 : window.document);
2495
2495
  }, inputTags = ["INPUT", "SELECT", "TEXTAREA"];
2496
2496
  function isInputDOMNode(event) {
2497
2497
  var _a, _b;
@@ -3960,10 +3960,10 @@ function applyChanges(changes, elements) {
3960
3960
  const elementChanges = changesMap.get(change.id);
3961
3961
  elementChanges ? elementChanges.push(change) : changesMap.set(change.id, [change]);
3962
3962
  }
3963
- for (const element of elements) {
3964
- const changes2 = changesMap.get(element.id);
3963
+ for (const element2 of elements) {
3964
+ const changes2 = changesMap.get(element2.id);
3965
3965
  if (!changes2) {
3966
- updatedElements.push(element);
3966
+ updatedElements.push(element2);
3967
3967
  continue;
3968
3968
  }
3969
3969
  if (changes2[0].type === "remove")
@@ -3972,25 +3972,25 @@ function applyChanges(changes, elements) {
3972
3972
  updatedElements.push({ ...changes2[0].item });
3973
3973
  continue;
3974
3974
  }
3975
- const updatedElement = { ...element };
3975
+ const updatedElement = { ...element2 };
3976
3976
  for (const change of changes2)
3977
3977
  applyChange(change, updatedElement);
3978
3978
  updatedElements.push(updatedElement);
3979
3979
  }
3980
3980
  return updatedElements;
3981
3981
  }
3982
- function applyChange(change, element) {
3982
+ function applyChange(change, element2) {
3983
3983
  switch (change.type) {
3984
3984
  case "select": {
3985
- element.selected = change.selected;
3985
+ element2.selected = change.selected;
3986
3986
  break;
3987
3987
  }
3988
3988
  case "position": {
3989
- typeof change.position < "u" && (element.position = change.position), typeof change.dragging < "u" && (element.dragging = change.dragging);
3989
+ typeof change.position < "u" && (element2.position = change.position), typeof change.dragging < "u" && (element2.dragging = change.dragging);
3990
3990
  break;
3991
3991
  }
3992
3992
  case "dimensions": {
3993
- typeof change.dimensions < "u" && (element.measured ?? (element.measured = {}), element.measured.width = change.dimensions.width, element.measured.height = change.dimensions.height, change.setAttributes && (element.width = change.dimensions.width, element.height = change.dimensions.height)), typeof change.resizing == "boolean" && (element.resizing = change.resizing);
3993
+ typeof change.dimensions < "u" && (element2.measured ?? (element2.measured = {}), element2.measured.width = change.dimensions.width, element2.measured.height = change.dimensions.height, change.setAttributes && (element2.width = change.dimensions.width, element2.height = change.dimensions.height)), typeof change.resizing == "boolean" && (element2.resizing = change.resizing);
3994
3994
  break;
3995
3995
  }
3996
3996
  }
@@ -4033,7 +4033,7 @@ function elementToRemoveChange(item) {
4033
4033
  type: "remove"
4034
4034
  };
4035
4035
  }
4036
- const isNode = (element) => isNodeBase(element);
4036
+ const isNode = (element2) => isNodeBase(element2);
4037
4037
  function fixedForwardRef(render) {
4038
4038
  return forwardRef(render);
4039
4039
  }
@@ -5483,6 +5483,16 @@ function EdgeLabelRenderer({ children: children2 }) {
5483
5483
  const edgeLabelRenderer = useStore(selector$8);
5484
5484
  return edgeLabelRenderer ? createPortal(children2, edgeLabelRenderer) : null;
5485
5485
  }
5486
+ function useOnViewportChange({ onStart, onChange, onEnd }) {
5487
+ const store = useStoreApi();
5488
+ useEffect(() => {
5489
+ store.setState({ onViewportChangeStart: onStart });
5490
+ }, [onStart]), useEffect(() => {
5491
+ store.setState({ onViewportChange: onChange });
5492
+ }, [onChange]), useEffect(() => {
5493
+ store.setState({ onViewportChangeEnd: onEnd });
5494
+ }, [onEnd]);
5495
+ }
5486
5496
  function useOnSelectionChange({ onChange }) {
5487
5497
  const store = useStoreApi();
5488
5498
  useEffect(() => {
@@ -5493,19 +5503,6 @@ function useOnSelectionChange({ onChange }) {
5493
5503
  };
5494
5504
  }, [onChange]);
5495
5505
  }
5496
- const selector$6 = (options) => (s) => {
5497
- if (s.nodeLookup.size === 0)
5498
- return !1;
5499
- for (const [, { hidden, internals }] of s.nodeLookup)
5500
- if ((options.includeHiddenNodes || !hidden) && (internals.handleBounds === void 0 || !nodeHasDimensions(internals.userNode)))
5501
- return !1;
5502
- return !0;
5503
- }, defaultOptions = {
5504
- includeHiddenNodes: !1
5505
- };
5506
- function useNodesInitialized(options = defaultOptions) {
5507
- return useStore(selector$6(options));
5508
- }
5509
5506
  function useNodesData(nodeIds) {
5510
5507
  return useStore(useCallback((s) => {
5511
5508
  const data = [], isArrayOfIds = Array.isArray(nodeIds), _nodeIds = isArrayOfIds ? nodeIds : [nodeIds];
@@ -5609,7 +5606,7 @@ function MiniMapNodeComponent({ id: id2, x, y, width, height, style: style2, col
5609
5606
  strokeWidth
5610
5607
  }, shapeRendering, onClick: onClick ? (event) => onClick(event, id2) : void 0 });
5611
5608
  }
5612
- const MiniMapNode = memo(MiniMapNodeComponent), selector$2 = (s) => s.nodeOrigin, selectorNodeIds = (s) => s.nodes.map((node) => node.id), getAttrFunction = (func) => func instanceof Function ? func : () => func;
5609
+ const MiniMapNode = memo(MiniMapNodeComponent), selector$2$1 = (s) => s.nodeOrigin, selectorNodeIds = (s) => s.nodes.map((node) => node.id), getAttrFunction = (func) => func instanceof Function ? func : () => func;
5613
5610
  function MiniMapNodes({
5614
5611
  nodeStrokeColor,
5615
5612
  nodeColor,
@@ -5621,7 +5618,7 @@ function MiniMapNodes({
5621
5618
  nodeComponent: NodeComponent = MiniMapNode,
5622
5619
  onClick
5623
5620
  }) {
5624
- const nodeIds = useStore(selectorNodeIds, shallow), nodeOrigin = useStore(selector$2), nodeColorFunc = getAttrFunction(nodeColor), nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor), nodeClassNameFunc = getAttrFunction(nodeClassName), shapeRendering = typeof window > "u" || window.chrome ? "crispEdges" : "geometricPrecision";
5621
+ const nodeIds = useStore(selectorNodeIds, shallow), nodeOrigin = useStore(selector$2$1), nodeColorFunc = getAttrFunction(nodeColor), nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor), nodeClassNameFunc = getAttrFunction(nodeClassName), shapeRendering = typeof window > "u" || window.chrome ? "crispEdges" : "geometricPrecision";
5625
5622
  return jsx(Fragment, { children: nodeIds.map((nodeId) => (
5626
5623
  // The split of responsibilities between MiniMapNodes and
5627
5624
  // NodeComponentWrapper may appear weird. However, it’s designed to
@@ -5842,25 +5839,25 @@ function ResizeControl({ nodeId, position, variant = ResizeControlVariant.Handle
5842
5839
  }
5843
5840
  memo(ResizeControl);
5844
5841
  function r(e) {
5845
- var t, f, n = "";
5842
+ var t2, f, n = "";
5846
5843
  if (typeof e == "string" || typeof e == "number")
5847
5844
  n += e;
5848
5845
  else if (typeof e == "object")
5849
5846
  if (Array.isArray(e)) {
5850
5847
  var o = e.length;
5851
- for (t = 0; t < o; t++)
5852
- e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
5848
+ for (t2 = 0; t2 < o; t2++)
5849
+ e[t2] && (f = r(e[t2])) && (n && (n += " "), n += f);
5853
5850
  } else
5854
5851
  for (f in e)
5855
5852
  e[f] && (n && (n += " "), n += f);
5856
5853
  return n;
5857
5854
  }
5858
5855
  function clsx() {
5859
- for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++)
5860
- (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
5856
+ for (var e, t2, f = 0, n = "", o = arguments.length; f < o; f++)
5857
+ (e = arguments[f]) && (t2 = r(e)) && (n && (n += " "), n += t2);
5861
5858
  return n;
5862
5859
  }
5863
- var keepAspectRatioContainer = "_2h8g8h0", cssReactFlow = "_2h8g8h1", cssDisablePan = "_2h8g8h2", cssTransparentBg = "_2h8g8h3", cssNoControls = "_2h8g8h4";
5860
+ var rootClassName = "likec4-diagram-root", keepAspectRatioContainer = "_2h8g8h0", cssReactFlow = "_2h8g8h1", cssDisablePan = "_2h8g8h2", cssTransparentBg = "_2h8g8h3", cssNoControls = "_2h8g8h4";
5864
5861
  function KeepAspectRatioContainer({
5865
5862
  children: children2,
5866
5863
  width,
@@ -5878,7 +5875,7 @@ function KeepAspectRatioContainer({
5878
5875
  style: enabled ? {
5879
5876
  ...style2,
5880
5877
  aspectRatio: `${Math.ceil(width)}/${Math.ceil(height)}`,
5881
- maxHeight: Math.ceil(height)
5878
+ maxHeight: `var(--likec4-view-max-height, ${Math.ceil(height)}px)`
5882
5879
  } : style2,
5883
5880
  children: children2
5884
5881
  }
@@ -5997,8 +5994,8 @@ class IndexedMap {
5997
5994
  if (i === void 0)
5998
5995
  return;
5999
5996
  this.index[key.id()] = void 0;
6000
- const pair = this.array[i], last = this.array.pop();
6001
- return pair !== last && (this.array[i] = last, this.index[last.first.id()] = i), pair;
5997
+ const pair = this.array[i], last2 = this.array.pop();
5998
+ return pair !== last2 && (this.array[i] = last2, this.index[last2.first.id()] = i), pair;
6002
5999
  }
6003
6000
  /**
6004
6001
  * Create a copy of this associative array.
@@ -6019,10 +6016,10 @@ class Pair {
6019
6016
  * @param first The first item of the pair.
6020
6017
  * @param second The second item of the pair.
6021
6018
  */
6022
- constructor(first, second) {
6019
+ constructor(first2, second) {
6023
6020
  __publicField(this, "first");
6024
6021
  __publicField(this, "second");
6025
- this.first = first, this.second = second;
6022
+ this.first = first2, this.second = second;
6026
6023
  }
6027
6024
  /**
6028
6025
  * Create a copy of the pair.
@@ -6436,7 +6433,7 @@ class Solver {
6436
6433
  * @return {Constraint[]}
6437
6434
  */
6438
6435
  getConstraints() {
6439
- return this._cnMap.array.map(({ first }) => first);
6436
+ return this._cnMap.array.map(({ first: first2 }) => first2);
6440
6437
  }
6441
6438
  /**
6442
6439
  * Add an edit variable to the solver.
@@ -6773,7 +6770,7 @@ class Solver {
6773
6770
  * @private
6774
6771
  */
6775
6772
  _getMarkerLeavingSymbol(marker) {
6776
- let dmax = Number.MAX_VALUE, r1 = dmax, r2 = dmax, invalid = INVALID_SYMBOL, first = invalid, second = invalid, third = invalid, rows = this._rowMap;
6773
+ let dmax = Number.MAX_VALUE, r1 = dmax, r2 = dmax, invalid = INVALID_SYMBOL, first2 = invalid, second = invalid, third = invalid, rows = this._rowMap;
6777
6774
  for (let i = 0, n = rows.size(); i < n; ++i) {
6778
6775
  let pair = rows.itemAt(i), row = pair.second, c = row.coefficientFor(marker);
6779
6776
  if (c === 0)
@@ -6783,13 +6780,13 @@ class Solver {
6783
6780
  third = symbol;
6784
6781
  else if (c < 0) {
6785
6782
  let r3 = -row.constant() / c;
6786
- r3 < r1 && (r1 = r3, first = symbol);
6783
+ r3 < r1 && (r1 = r3, first2 = symbol);
6787
6784
  } else {
6788
6785
  let r3 = row.constant() / c;
6789
6786
  r3 < r2 && (r2 = r3, second = symbol);
6790
6787
  }
6791
6788
  }
6792
- return first !== invalid ? first : second !== invalid ? second : third;
6789
+ return first2 !== invalid ? first2 : second !== invalid ? second : third;
6793
6790
  }
6794
6791
  /**
6795
6792
  * Remove the effects of a constraint on the objective function.
@@ -7222,15 +7219,18 @@ const ZIndexes = {
7222
7219
  Compound: 1,
7223
7220
  Edge: 2,
7224
7221
  Element: 3
7225
- }, MinZoom = 0.05, DEFAULT_PROPS = {
7222
+ }, MinZoom = 0.05, StringSet = Set, DEFAULT_PROPS = {
7226
7223
  initialized: !1,
7224
+ xyflowSynced: !1,
7227
7225
  previousViews: [],
7228
7226
  viewportChanged: !1,
7227
+ activeDynamicViewStep: null,
7229
7228
  focusedNodeId: null,
7230
7229
  hoveredNodeId: null,
7231
7230
  hoveredEdgeId: null,
7232
7231
  lastClickedNodeId: null,
7233
7232
  lastClickedEdgeId: null,
7233
+ dimmed: new StringSet(),
7234
7234
  lastOnNavigate: null,
7235
7235
  onChange: null,
7236
7236
  onNavigateTo: null,
@@ -7243,7 +7243,7 @@ const ZIndexes = {
7243
7243
  onCanvasDblClick: null
7244
7244
  }, noReplace = !1;
7245
7245
  let storeDevId = 1;
7246
- const containsWithId = (arr, id2) => arr.some((x) => x.id === id2);
7246
+ const EmptyStringSet = new StringSet();
7247
7247
  function createDiagramStore(props) {
7248
7248
  return createWithEqualityFn(
7249
7249
  subscribeWithSelector(
@@ -7251,39 +7251,76 @@ function createDiagramStore(props) {
7251
7251
  (set2, get2) => ({
7252
7252
  ...DEFAULT_PROPS,
7253
7253
  ...props,
7254
- updateView: (view) => {
7254
+ isDynamicView: () => {
7255
+ var _a;
7256
+ return ((_a = get2().view) == null ? void 0 : _a.__) === "dynamic";
7257
+ },
7258
+ updateView: (nextView) => {
7255
7259
  let {
7256
- view: currentView,
7260
+ dimmed: dimmed2,
7261
+ xyflowSynced,
7262
+ view: current,
7257
7263
  lastOnNavigate,
7258
7264
  previousViews,
7259
7265
  focusedNodeId,
7260
7266
  lastClickedNodeId,
7261
7267
  lastClickedEdgeId,
7268
+ activeDynamicViewStep,
7262
7269
  hoveredEdgeId,
7263
7270
  hoveredNodeId
7264
7271
  } = get2();
7265
- if (shallowEqual(currentView, view)) {
7266
- DEV && console.debug("store: skip updateView");
7272
+ if (shallowEqual(current, nextView)) {
7273
+ xyflowSynced || set2({ xyflowSynced: !0 }, noReplace, "updateView: xyflow synced"), DEV && console.debug("store: skip updateView");
7267
7274
  return;
7268
7275
  }
7269
- lastOnNavigate && lastOnNavigate.toView !== view.id && lastOnNavigate.fromView !== view.id && (lastOnNavigate = null), currentView.id === view.id ? (lastClickedNodeId && !containsWithId(view.nodes, lastClickedNodeId) && (lastClickedNodeId = null), hoveredNodeId && !containsWithId(view.nodes, hoveredNodeId) && (hoveredNodeId = null), focusedNodeId && !containsWithId(view.nodes, focusedNodeId) && (focusedNodeId = null), lastClickedEdgeId && !containsWithId(view.edges, lastClickedEdgeId) && (lastClickedEdgeId = null), hoveredEdgeId && !containsWithId(view.edges, hoveredEdgeId) && (hoveredEdgeId = null)) : (lastClickedEdgeId = null, lastClickedNodeId = null, hoveredEdgeId = null, hoveredNodeId = null, focusedNodeId = null, previousViews = [
7270
- currentView,
7271
- ...previousViews.filter((v) => v.id !== view.id && v.id !== currentView.id)
7272
- ]), set2(
7276
+ if (current.id === nextView.id) {
7277
+ const nodeIds = new StringSet(nextView.nodes.map((n) => n.id)), edgeIds = new StringSet(nextView.edges.map((e) => e.id));
7278
+ if (lastClickedNodeId && !nodeIds.has(lastClickedNodeId) && (lastClickedNodeId = null), hoveredNodeId && !nodeIds.has(hoveredNodeId) && (hoveredNodeId = null), focusedNodeId && !nodeIds.has(focusedNodeId) && (focusedNodeId = null), lastClickedEdgeId && !edgeIds.has(lastClickedEdgeId) && (lastClickedEdgeId = null), hoveredEdgeId && !edgeIds.has(hoveredEdgeId) && (hoveredEdgeId = null), activeDynamicViewStep && !edgeIds.has(StepEdgeId(activeDynamicViewStep)) && (activeDynamicViewStep = null), xyflowSynced = deepEqual(current.nodes, nextView.nodes) && deepEqual(current.edges, nextView.edges), !xyflowSynced) {
7279
+ let nextDimmed = new StringSet([...dimmed2].filter((id2) => nodeIds.has(id2) || edgeIds.has(id2)));
7280
+ nextDimmed.size !== dimmed2.size && (dimmed2 = nextDimmed);
7281
+ }
7282
+ } else
7283
+ lastOnNavigate && lastOnNavigate.toView !== nextView.id && lastOnNavigate.fromView !== nextView.id && (lastOnNavigate = null), lastClickedEdgeId = null, lastClickedNodeId = null, hoveredEdgeId = null, hoveredNodeId = null, focusedNodeId = null, activeDynamicViewStep = null, dimmed2 = EmptyStringSet, previousViews = [
7284
+ current,
7285
+ ...previousViews.filter((v) => v.id !== nextView.id && v.id !== current.id)
7286
+ ], xyflowSynced = !1;
7287
+ set2(
7273
7288
  {
7274
- view,
7289
+ view: nextView,
7290
+ activeDynamicViewStep,
7291
+ xyflowSynced,
7275
7292
  lastOnNavigate,
7276
7293
  previousViews,
7277
7294
  lastClickedNodeId,
7278
7295
  lastClickedEdgeId,
7279
7296
  focusedNodeId,
7280
7297
  hoveredEdgeId,
7281
- hoveredNodeId
7298
+ hoveredNodeId,
7299
+ dimmed: dimmed2
7282
7300
  },
7283
7301
  noReplace,
7284
7302
  "update-view"
7285
7303
  );
7286
7304
  },
7305
+ focusOnNode: (nodeId) => {
7306
+ const { focusedNodeId, view } = get2();
7307
+ if (nodeId !== focusedNodeId) {
7308
+ const notDimmed = new StringSet([nodeId]), dimmed2 = new StringSet();
7309
+ for (const edge of view.edges)
7310
+ edge.source === nodeId || edge.target === nodeId ? (notDimmed.add(edge.source), notDimmed.add(edge.target)) : dimmed2.add(edge.id);
7311
+ for (const node of view.nodes)
7312
+ notDimmed.has(node.id) || dimmed2.add(node.id);
7313
+ set2(
7314
+ {
7315
+ activeDynamicViewStep: null,
7316
+ focusedNodeId: nodeId,
7317
+ dimmed: dimmed2
7318
+ },
7319
+ noReplace,
7320
+ `focus on node: ${nodeId}`
7321
+ );
7322
+ }
7323
+ },
7287
7324
  setHoveredNode: (nodeId) => {
7288
7325
  nodeId !== get2().hoveredNodeId && set2({ hoveredNodeId: nodeId }, noReplace, nodeId ? "setHoveredNode" : "unsetHoveredNode");
7289
7326
  },
@@ -7306,7 +7343,8 @@ function createDiagramStore(props) {
7306
7343
  {
7307
7344
  focusedNodeId: null,
7308
7345
  lastClickedNodeId: null,
7309
- lastClickedEdgeId: null
7346
+ lastClickedEdgeId: null,
7347
+ dimmed: EmptyStringSet
7310
7348
  },
7311
7349
  noReplace,
7312
7350
  "resetLastClicked"
@@ -7344,37 +7382,37 @@ function createDiagramStore(props) {
7344
7382
  get2().xyflow.setNodes(
7345
7383
  (nodes) => nodes.map((node) => {
7346
7384
  var _a2, _b2;
7347
- let element = node.data.element;
7348
- const shape = newShapes.get(element.id);
7349
- shape && shape !== element.shape && (element = {
7350
- ...element,
7385
+ let element2 = node.data.element;
7386
+ const shape = newShapes.get(element2.id);
7387
+ shape && shape !== element2.shape && (element2 = {
7388
+ ...element2,
7351
7389
  shape
7352
7390
  });
7353
- const color2 = newColor.get(element.id);
7354
- color2 && color2 !== element.color && (element = {
7355
- ...element,
7391
+ const color2 = newColor.get(element2.id);
7392
+ color2 && color2 !== element2.color && (element2 = {
7393
+ ...element2,
7356
7394
  color: color2
7357
7395
  });
7358
- const opacity = newOpacity.get(element.id);
7359
- opacity && opacity !== ((_a2 = element.style) == null ? void 0 : _a2.opacity) && (element = {
7360
- ...element,
7396
+ const opacity = newOpacity.get(element2.id);
7397
+ opacity && opacity !== ((_a2 = element2.style) == null ? void 0 : _a2.opacity) && (element2 = {
7398
+ ...element2,
7361
7399
  style: {
7362
- ...element.style,
7400
+ ...element2.style,
7363
7401
  opacity
7364
7402
  }
7365
7403
  });
7366
- const border = newBorder.get(element.id);
7367
- return border && border !== ((_b2 = element.style) == null ? void 0 : _b2.border) && (element = {
7368
- ...element,
7404
+ const border = newBorder.get(element2.id);
7405
+ return border && border !== ((_b2 = element2.style) == null ? void 0 : _b2.border) && (element2 = {
7406
+ ...element2,
7369
7407
  style: {
7370
- ...element.style,
7408
+ ...element2.style,
7371
7409
  border
7372
7410
  }
7373
- }), element === node.data.element ? node : {
7411
+ }), element2 === node.data.element ? node : {
7374
7412
  ...node,
7375
7413
  data: {
7376
7414
  ...node.data,
7377
- element
7415
+ element: element2
7378
7416
  }
7379
7417
  };
7380
7418
  })
@@ -7382,16 +7420,16 @@ function createDiagramStore(props) {
7382
7420
  },
7383
7421
  triggerOnNavigateTo: (xynodeId, event) => {
7384
7422
  var _a, _b;
7385
- const { xyflow, view } = get2(), xynode = xyflow.getInternalNode(xynodeId), element = xynode == null ? void 0 : xynode.data.element;
7386
- invariant(!!xynode && (element == null ? void 0 : element.navigateTo), `node is not navigable: ${xynodeId}`);
7423
+ const { xyflow, view } = get2(), xynode = xyflow.getInternalNode(xynodeId), element2 = xynode == null ? void 0 : xynode.data.element;
7424
+ invariant(!!xynode && (element2 == null ? void 0 : element2.navigateTo), `node is not navigable: ${xynodeId}`);
7387
7425
  const dimensions = getNodeDimensions(xynode);
7388
7426
  set2(
7389
7427
  {
7390
7428
  lastClickedNodeId: xynodeId,
7391
7429
  lastOnNavigate: {
7392
7430
  fromView: view.id,
7393
- toView: element.navigateTo,
7394
- element,
7431
+ toView: element2.navigateTo,
7432
+ element: element2,
7395
7433
  elementCenterScreenPosition: xyflow.flowToScreenPosition({
7396
7434
  x: xynode.internals.positionAbsolute.x + dimensions.width / 2,
7397
7435
  y: xynode.internals.positionAbsolute.y + dimensions.height / 2
@@ -7403,22 +7441,72 @@ function createDiagramStore(props) {
7403
7441
  "triggerOnNavigateTo"
7404
7442
  ), (_b = (_a = get2()).onNavigateTo) == null || _b.call(
7405
7443
  _a,
7406
- element.navigateTo,
7444
+ element2.navigateTo,
7407
7445
  event,
7408
- element,
7446
+ element2,
7409
7447
  xynode.internals.userNode
7410
7448
  );
7411
7449
  },
7412
- fitDiagram: (centerNode) => {
7413
- const { fitViewPadding, xyflow, focusedNodeId } = get2();
7450
+ fitDiagram: (xyStore) => {
7451
+ const { width, height, panZoom } = xyStore.getState(), { fitViewPadding, view, focusedNodeId } = get2(), bounds = {
7452
+ x: 0,
7453
+ y: 0,
7454
+ width: view.width,
7455
+ height: view.height
7456
+ }, viewport = getViewportForBounds(bounds, width, height, MinZoom, 1, fitViewPadding);
7457
+ panZoom == null || panZoom.setViewport(viewport, { duration: 400 }), focusedNodeId && set2(
7458
+ {
7459
+ focusedNodeId: null,
7460
+ dimmed: EmptyStringSet
7461
+ },
7462
+ noReplace,
7463
+ "unfocus"
7464
+ );
7465
+ },
7466
+ nextDynamicStep: (increment = 1) => {
7467
+ const { view, activeDynamicViewStep, xyflow, fitViewPadding } = get2();
7468
+ invariant(view.__ === "dynamic", "view is not dynamic");
7469
+ const nextStep = (activeDynamicViewStep ?? 0) + increment, edgeId = StepEdgeId(nextStep), dimmed2 = new StringSet();
7470
+ let edge = null;
7471
+ for (const e of xyflow.getEdges()) {
7472
+ if (e.id === edgeId) {
7473
+ edge = e;
7474
+ continue;
7475
+ }
7476
+ dimmed2.add(e.id);
7477
+ }
7478
+ invariant(!!edge, `edge not found: ${edgeId}`);
7479
+ const selected2 = [];
7480
+ for (const n of xyflow.getNodes()) {
7481
+ if (n.id === edge.source || n.id === edge.target) {
7482
+ selected2.push(n);
7483
+ continue;
7484
+ }
7485
+ dimmed2.add(n.id);
7486
+ }
7414
7487
  xyflow.fitView({
7415
- includeHiddenNodes: !0,
7416
- duration: centerNode && focusedNodeId ? 300 : 400,
7417
- padding: fitViewPadding,
7488
+ duration: 400,
7489
+ maxZoom: 1,
7418
7490
  minZoom: MinZoom,
7491
+ padding: fitViewPadding,
7492
+ nodes: selected2
7493
+ }), set2({
7494
+ focusedNodeId: null,
7495
+ activeDynamicViewStep: nextStep,
7496
+ dimmed: dimmed2
7497
+ });
7498
+ },
7499
+ stopDynamicView: () => {
7500
+ const { xyflow, fitViewPadding } = get2();
7501
+ set2({
7502
+ activeDynamicViewStep: null,
7503
+ dimmed: EmptyStringSet
7504
+ }), xyflow.fitView({
7505
+ duration: 400,
7419
7506
  maxZoom: 1,
7420
- ...centerNode && { nodes: [centerNode] }
7421
- }), centerNode && focusedNodeId !== centerNode.id && set2({ focusedNodeId: centerNode.id }, noReplace, "focus node"), !centerNode && focusedNodeId && set2({ focusedNodeId: null }, noReplace, "unfocus");
7507
+ minZoom: MinZoom,
7508
+ padding: fitViewPadding
7509
+ });
7422
7510
  }
7423
7511
  }),
7424
7512
  {
@@ -7437,412 +7525,965 @@ function DiagramContextProvider({ children: children2, view, ...props }) {
7437
7525
  xyflow,
7438
7526
  view,
7439
7527
  ...props
7440
- })), useUpdateEffect(
7441
- () => {
7442
- var _a;
7443
- return (_a = store.current) == null ? void 0 : _a.setState({ xyflow }, !1, "update xyflow");
7444
- },
7445
- [xyflow],
7446
- Object.is
7447
- ), useUpdateEffect(
7528
+ })), useEffect(
7448
7529
  () => {
7449
- var _a;
7450
- return (_a = store.current) == null ? void 0 : _a.getState().updateView(view);
7530
+ var _a, _b;
7531
+ ((_a = store.current) == null ? void 0 : _a.getState().xyflow) !== xyflow && ((_b = store.current) == null || _b.setState({ xyflow }, !1, "update xyflow"));
7451
7532
  },
7452
- [view]
7533
+ [xyflow]
7453
7534
  ), useUpdateEffect(
7454
7535
  () => {
7455
- var _a;
7456
- return (_a = store.current) == null ? void 0 : _a.setState(props, !1, "update incoming props");
7536
+ if (!store.current)
7537
+ return;
7538
+ const state = store.current.getState();
7539
+ state.view !== view && state.updateView(view), hasSubObject(state, props) || store.current.setState(props, !1, "update incoming props");
7457
7540
  },
7458
- [props]
7541
+ [view, props]
7459
7542
  ), /* @__PURE__ */ jsx(DiagramContext.Provider, { value: store.current, children: children2 });
7460
7543
  }
7461
- var container$3 = "hbkbtj0", paper = "hbkbtj1", title$2 = "hbkbtj2", description$1 = "hbkbtj3";
7462
- const selector$1 = (s) => ({
7463
- id: s.view.id,
7464
- title: s.view.title ?? "untitled",
7465
- description: s.view.description,
7466
- links: s.view.links
7467
- });
7468
- function DiagramTitlePanel() {
7469
- const { id: id2, title: title2, description: description2, links } = useDiagramState(selector$1), [isCollapsed, setCollapsed] = useLocalStorage({
7470
- key: "diagram-title-panel-collapsed",
7471
- defaultValue: !1
7472
- }), toggle = () => setCollapsed((v) => !v);
7473
- return /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
7474
- motion.div,
7475
- {
7476
- initial: { opacity: 0.05, scale: 0.7 },
7477
- animate: { opacity: 1, scale: 1 },
7478
- exit: {
7479
- opacity: 0.05,
7480
- scale: 0.6
7481
- },
7482
- className: clsx("react-flow__panel", container$3),
7483
- style: {
7484
- transformOrigin: "left center"
7485
- },
7486
- children: /* @__PURE__ */ jsx(
7487
- Paper,
7488
- {
7489
- radius: "sm",
7490
- withBorder: !isCollapsed,
7491
- className: paper,
7492
- p: isCollapsed ? "sm" : "md",
7493
- onDoubleClick: (e) => e.stopPropagation(),
7494
- children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", justify: "stretch", align: "stretch", children: [
7495
- /* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", onClick: toggle, style: { cursor: "pointer" }, children: [
7496
- /* @__PURE__ */ jsx(
7497
- Text,
7498
- {
7499
- component: "div",
7500
- flex: "1",
7501
- size: isCollapsed ? "sm" : "lg",
7502
- fw: 500,
7503
- lh: 1.1,
7504
- className: title$2,
7505
- children: title2
7506
- }
7507
- ),
7508
- /* @__PURE__ */ jsxs(
7509
- Text,
7510
- {
7511
- hidden: isCollapsed,
7512
- component: "div",
7513
- flex: "0 0 auto",
7514
- inline: !0,
7515
- size: "xs",
7516
- fz: 9,
7517
- fw: 500,
7518
- c: "dimmed",
7519
- style: {
7520
- userSelect: "all"
7521
- },
7522
- children: [
7523
- /* @__PURE__ */ jsxs("span", { style: { userSelect: "none" }, children: [
7524
- "id:",
7525
- " "
7526
- ] }),
7527
- id2
7528
- ]
7529
- }
7530
- )
7531
- ] }),
7532
- !isCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
7533
- description2 && /* @__PURE__ */ jsx(
7534
- Spoiler,
7535
- {
7536
- maxHeight: 42,
7537
- showLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "show more" }),
7538
- hideLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "hide" }),
7539
- children: /* @__PURE__ */ jsx(
7540
- Text,
7541
- {
7542
- component: "div",
7543
- size: "sm",
7544
- className: description$1,
7545
- children: description2 || "no description"
7546
- }
7547
- )
7548
- }
7549
- ),
7550
- !description2 && /* @__PURE__ */ jsx(
7551
- Text,
7552
- {
7553
- component: "div",
7554
- size: "xs",
7555
- c: "dimmed",
7556
- children: "no description"
7557
- }
7558
- ),
7559
- links && /* @__PURE__ */ jsx(
7560
- Stack,
7561
- {
7562
- gap: 3,
7563
- justify: "stretch",
7564
- align: "stretch",
7565
- children: links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", align: "center", gap: "sm", children: [
7566
- /* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(
7567
- Anchor,
7568
- {
7569
- href: link,
7570
- target: "_blank",
7571
- fz: "xs",
7572
- truncate: "end",
7573
- display: "inline-block",
7574
- w: "100%",
7575
- children: link
7576
- }
7577
- ) }),
7578
- /* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(
7579
- Button,
7580
- {
7581
- size: "compact-xs",
7582
- fz: "10",
7583
- variant: "light",
7584
- onClick: copy,
7585
- color: copied ? "teal" : "gray",
7586
- children: copied ? "copied" : "copy"
7587
- }
7588
- ) })
7589
- ] }, link))
7590
- }
7591
- )
7592
- ] })
7593
- ] })
7594
- }
7595
- )
7596
- },
7597
- id2
7598
- ) });
7599
- }
7600
- var panel = "_1lmzt1h0";
7601
- const {
7602
- primary,
7603
- secondary,
7604
- muted,
7605
- ...otherColors
7606
- } = defaultTheme.elements, themedColors = [
7607
- { key: "primary", value: primary.fill },
7608
- { key: "secondary", value: secondary.fill },
7609
- { key: "muted", value: muted.fill }
7610
- ], colors = keys.strict(otherColors).map((key) => ({
7611
- key,
7612
- value: defaultTheme.elements[key].fill
7613
- }));
7614
- function NodeOptions({ selectedNodeIds }) {
7615
- const diagramApi = useDiagramStoreApi(), nodes = useXYNodesData(selectedNodeIds);
7616
- if (!hasAtLeast(nodes, 1))
7617
- return null;
7618
- if (nodes.length !== selectedNodeIds.length)
7619
- throw new Error("NodeOptions: nodes and props.nodes should have the same length");
7620
- const showShapeOption = nodes.some((node) => node.type === "element"), [firstNode, ...rest] = nodes, showOpacityOption = rest.length === 0 && firstNode.type === "compound", triggerChange = (style2) => {
7621
- const targets = nodes.map((node) => node.data.element.id);
7622
- invariant(hasAtLeast(targets, 1), "At least one target is required"), diagramApi.getState().triggerOnChange([{
7623
- op: "change-element-style",
7624
- style: style2,
7625
- targets
7626
- }]);
7627
- };
7628
- return /* @__PURE__ */ jsxs(Stack, { children: [
7629
- /* @__PURE__ */ jsx(Box, { maw: 200, children: /* @__PURE__ */ jsx(Text, { size: "xs", c: rest.length > 0 ? "dimmed" : "", truncate: !0, children: rest.length === 0 ? firstNode.data.element.title : "[ multiple ]" }) }),
7630
- showShapeOption && /* @__PURE__ */ jsx(
7631
- ShapeOption,
7544
+ const { abs: abs$1, cos: cos$1, sin: sin$1, acos: acos$1, atan2, sqrt: sqrt$1, pow } = Math;
7545
+ function crt(v) {
7546
+ return v < 0 ? -pow(-v, 1 / 3) : pow(v, 1 / 3);
7547
+ }
7548
+ const pi$1 = Math.PI, tau = 2 * pi$1, quart = pi$1 / 2, epsilon = 1e-6, nMax = Number.MAX_SAFE_INTEGER || 9007199254740991, nMin = Number.MIN_SAFE_INTEGER || -9007199254740991, ZERO = { x: 0, y: 0, z: 0 }, utils = {
7549
+ // Legendre-Gauss abscissae with n=24 (x_i values, defined at i=n as the roots of the nth order Legendre polynomial Pn(x))
7550
+ Tvalues: [
7551
+ -0.06405689286260563,
7552
+ 0.06405689286260563,
7553
+ -0.1911188674736163,
7554
+ 0.1911188674736163,
7555
+ -0.3150426796961634,
7556
+ 0.3150426796961634,
7557
+ -0.4337935076260451,
7558
+ 0.4337935076260451,
7559
+ -0.5454214713888396,
7560
+ 0.5454214713888396,
7561
+ -0.6480936519369755,
7562
+ 0.6480936519369755,
7563
+ -0.7401241915785544,
7564
+ 0.7401241915785544,
7565
+ -0.820001985973903,
7566
+ 0.820001985973903,
7567
+ -0.8864155270044011,
7568
+ 0.8864155270044011,
7569
+ -0.9382745520027328,
7570
+ 0.9382745520027328,
7571
+ -0.9747285559713095,
7572
+ 0.9747285559713095,
7573
+ -0.9951872199970213,
7574
+ 0.9951872199970213
7575
+ ],
7576
+ // Legendre-Gauss weights with n=24 (w_i values, defined by a function linked to in the Bezier primer article)
7577
+ Cvalues: [
7578
+ 0.12793819534675216,
7579
+ 0.12793819534675216,
7580
+ 0.1258374563468283,
7581
+ 0.1258374563468283,
7582
+ 0.12167047292780339,
7583
+ 0.12167047292780339,
7584
+ 0.1155056680537256,
7585
+ 0.1155056680537256,
7586
+ 0.10744427011596563,
7587
+ 0.10744427011596563,
7588
+ 0.09761865210411388,
7589
+ 0.09761865210411388,
7590
+ 0.08619016153195327,
7591
+ 0.08619016153195327,
7592
+ 0.0733464814110803,
7593
+ 0.0733464814110803,
7594
+ 0.05929858491543678,
7595
+ 0.05929858491543678,
7596
+ 0.04427743881741981,
7597
+ 0.04427743881741981,
7598
+ 0.028531388628933663,
7599
+ 0.028531388628933663,
7600
+ 0.0123412297999872,
7601
+ 0.0123412297999872
7602
+ ],
7603
+ arcfn: function(t2, derivativeFn) {
7604
+ const d = derivativeFn(t2);
7605
+ let l = d.x * d.x + d.y * d.y;
7606
+ return typeof d.z < "u" && (l += d.z * d.z), sqrt$1(l);
7607
+ },
7608
+ compute: function(t2, points, _3d) {
7609
+ if (t2 === 0)
7610
+ return points[0].t = 0, points[0];
7611
+ const order = points.length - 1;
7612
+ if (t2 === 1)
7613
+ return points[order].t = 1, points[order];
7614
+ const mt = 1 - t2;
7615
+ let p = points;
7616
+ if (order === 0)
7617
+ return points[0].t = t2, points[0];
7618
+ if (order === 1) {
7619
+ const ret = {
7620
+ x: mt * p[0].x + t2 * p[1].x,
7621
+ y: mt * p[0].y + t2 * p[1].y,
7622
+ t: t2
7623
+ };
7624
+ return _3d && (ret.z = mt * p[0].z + t2 * p[1].z), ret;
7625
+ }
7626
+ if (order < 4) {
7627
+ let mt2 = mt * mt, t22 = t2 * t2, a, b, c, d = 0;
7628
+ order === 2 ? (p = [p[0], p[1], p[2], ZERO], a = mt2, b = mt * t2 * 2, c = t22) : order === 3 && (a = mt2 * mt, b = mt2 * t2 * 3, c = mt * t22 * 3, d = t2 * t22);
7629
+ const ret = {
7630
+ x: a * p[0].x + b * p[1].x + c * p[2].x + d * p[3].x,
7631
+ y: a * p[0].y + b * p[1].y + c * p[2].y + d * p[3].y,
7632
+ t: t2
7633
+ };
7634
+ return _3d && (ret.z = a * p[0].z + b * p[1].z + c * p[2].z + d * p[3].z), ret;
7635
+ }
7636
+ const dCpts = JSON.parse(JSON.stringify(points));
7637
+ for (; dCpts.length > 1; ) {
7638
+ for (let i = 0; i < dCpts.length - 1; i++)
7639
+ dCpts[i] = {
7640
+ x: dCpts[i].x + (dCpts[i + 1].x - dCpts[i].x) * t2,
7641
+ y: dCpts[i].y + (dCpts[i + 1].y - dCpts[i].y) * t2
7642
+ }, typeof dCpts[i].z < "u" && (dCpts[i].z = dCpts[i].z + (dCpts[i + 1].z - dCpts[i].z) * t2);
7643
+ dCpts.splice(dCpts.length - 1, 1);
7644
+ }
7645
+ return dCpts[0].t = t2, dCpts[0];
7646
+ },
7647
+ computeWithRatios: function(t2, points, ratios, _3d) {
7648
+ const mt = 1 - t2, r2 = ratios, p = points;
7649
+ let f1 = r2[0], f2 = r2[1], f3 = r2[2], f4 = r2[3], d;
7650
+ if (f1 *= mt, f2 *= t2, p.length === 2)
7651
+ return d = f1 + f2, {
7652
+ x: (f1 * p[0].x + f2 * p[1].x) / d,
7653
+ y: (f1 * p[0].y + f2 * p[1].y) / d,
7654
+ z: _3d ? (f1 * p[0].z + f2 * p[1].z) / d : !1,
7655
+ t: t2
7656
+ };
7657
+ if (f1 *= mt, f2 *= 2 * mt, f3 *= t2 * t2, p.length === 3)
7658
+ return d = f1 + f2 + f3, {
7659
+ x: (f1 * p[0].x + f2 * p[1].x + f3 * p[2].x) / d,
7660
+ y: (f1 * p[0].y + f2 * p[1].y + f3 * p[2].y) / d,
7661
+ z: _3d ? (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z) / d : !1,
7662
+ t: t2
7663
+ };
7664
+ if (f1 *= mt, f2 *= 1.5 * mt, f3 *= 3 * mt, f4 *= t2 * t2 * t2, p.length === 4)
7665
+ return d = f1 + f2 + f3 + f4, {
7666
+ x: (f1 * p[0].x + f2 * p[1].x + f3 * p[2].x + f4 * p[3].x) / d,
7667
+ y: (f1 * p[0].y + f2 * p[1].y + f3 * p[2].y + f4 * p[3].y) / d,
7668
+ z: _3d ? (f1 * p[0].z + f2 * p[1].z + f3 * p[2].z + f4 * p[3].z) / d : !1,
7669
+ t: t2
7670
+ };
7671
+ },
7672
+ derive: function(points, _3d) {
7673
+ const dpoints = [];
7674
+ for (let p = points, d = p.length, c = d - 1; d > 1; d--, c--) {
7675
+ const list = [];
7676
+ for (let j = 0, dpt; j < c; j++)
7677
+ dpt = {
7678
+ x: c * (p[j + 1].x - p[j].x),
7679
+ y: c * (p[j + 1].y - p[j].y)
7680
+ }, _3d && (dpt.z = c * (p[j + 1].z - p[j].z)), list.push(dpt);
7681
+ dpoints.push(list), p = list;
7682
+ }
7683
+ return dpoints;
7684
+ },
7685
+ between: function(v, m, M) {
7686
+ return m <= v && v <= M || utils.approximately(v, m) || utils.approximately(v, M);
7687
+ },
7688
+ approximately: function(a, b, precision) {
7689
+ return abs$1(a - b) <= (precision || epsilon);
7690
+ },
7691
+ length: function(derivativeFn) {
7692
+ const len = utils.Tvalues.length;
7693
+ let sum = 0;
7694
+ for (let i = 0, t2; i < len; i++)
7695
+ t2 = 0.5 * utils.Tvalues[i] + 0.5, sum += utils.Cvalues[i] * utils.arcfn(t2, derivativeFn);
7696
+ return 0.5 * sum;
7697
+ },
7698
+ map: function(v, ds, de, ts, te) {
7699
+ const d1 = de - ds, d2 = te - ts, v2 = v - ds, r2 = v2 / d1;
7700
+ return ts + d2 * r2;
7701
+ },
7702
+ lerp: function(r2, v1, v2) {
7703
+ const ret = {
7704
+ x: v1.x + r2 * (v2.x - v1.x),
7705
+ y: v1.y + r2 * (v2.y - v1.y)
7706
+ };
7707
+ return v1.z !== void 0 && v2.z !== void 0 && (ret.z = v1.z + r2 * (v2.z - v1.z)), ret;
7708
+ },
7709
+ pointToString: function(p) {
7710
+ let s = p.x + "/" + p.y;
7711
+ return typeof p.z < "u" && (s += "/" + p.z), s;
7712
+ },
7713
+ pointsToString: function(points) {
7714
+ return "[" + points.map(utils.pointToString).join(", ") + "]";
7715
+ },
7716
+ copy: function(obj) {
7717
+ return JSON.parse(JSON.stringify(obj));
7718
+ },
7719
+ angle: function(o, v1, v2) {
7720
+ const dx1 = v1.x - o.x, dy1 = v1.y - o.y, dx2 = v2.x - o.x, dy2 = v2.y - o.y, cross = dx1 * dy2 - dy1 * dx2, dot = dx1 * dx2 + dy1 * dy2;
7721
+ return atan2(cross, dot);
7722
+ },
7723
+ // round as string, to avoid rounding errors
7724
+ round: function(v, d) {
7725
+ const s = "" + v, pos = s.indexOf(".");
7726
+ return parseFloat(s.substring(0, pos + 1 + d));
7727
+ },
7728
+ dist: function(p1, p2) {
7729
+ const dx = p1.x - p2.x, dy = p1.y - p2.y;
7730
+ return sqrt$1(dx * dx + dy * dy);
7731
+ },
7732
+ closest: function(LUT, point) {
7733
+ let mdist = pow(2, 63), mpos, d;
7734
+ return LUT.forEach(function(p, idx) {
7735
+ d = utils.dist(point, p), d < mdist && (mdist = d, mpos = idx);
7736
+ }), { mdist, mpos };
7737
+ },
7738
+ abcratio: function(t2, n) {
7739
+ if (n !== 2 && n !== 3)
7740
+ return !1;
7741
+ if (typeof t2 > "u")
7742
+ t2 = 0.5;
7743
+ else if (t2 === 0 || t2 === 1)
7744
+ return t2;
7745
+ const bottom = pow(t2, n) + pow(1 - t2, n), top = bottom - 1;
7746
+ return abs$1(top / bottom);
7747
+ },
7748
+ projectionratio: function(t2, n) {
7749
+ if (n !== 2 && n !== 3)
7750
+ return !1;
7751
+ if (typeof t2 > "u")
7752
+ t2 = 0.5;
7753
+ else if (t2 === 0 || t2 === 1)
7754
+ return t2;
7755
+ const top = pow(1 - t2, n), bottom = pow(t2, n) + top;
7756
+ return top / bottom;
7757
+ },
7758
+ lli8: function(x1, y1, x2, y2, x3, y3, x4, y4) {
7759
+ const nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4), ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4), d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
7760
+ return d == 0 ? !1 : { x: nx / d, y: ny / d };
7761
+ },
7762
+ lli4: function(p1, p2, p3, p4) {
7763
+ const x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y, x3 = p3.x, y3 = p3.y, x4 = p4.x, y4 = p4.y;
7764
+ return utils.lli8(x1, y1, x2, y2, x3, y3, x4, y4);
7765
+ },
7766
+ lli: function(v1, v2) {
7767
+ return utils.lli4(v1, v1.c, v2, v2.c);
7768
+ },
7769
+ makeline: function(p1, p2) {
7770
+ return new Bezier(
7771
+ p1.x,
7772
+ p1.y,
7773
+ (p1.x + p2.x) / 2,
7774
+ (p1.y + p2.y) / 2,
7775
+ p2.x,
7776
+ p2.y
7777
+ );
7778
+ },
7779
+ findbbox: function(sections) {
7780
+ let mx = nMax, my = nMax, MX = nMin, MY = nMin;
7781
+ return sections.forEach(function(s) {
7782
+ const bbox = s.bbox();
7783
+ mx > bbox.x.min && (mx = bbox.x.min), my > bbox.y.min && (my = bbox.y.min), MX < bbox.x.max && (MX = bbox.x.max), MY < bbox.y.max && (MY = bbox.y.max);
7784
+ }), {
7785
+ x: { min: mx, mid: (mx + MX) / 2, max: MX, size: MX - mx },
7786
+ y: { min: my, mid: (my + MY) / 2, max: MY, size: MY - my }
7787
+ };
7788
+ },
7789
+ shapeintersections: function(s1, bbox1, s2, bbox2, curveIntersectionThreshold) {
7790
+ if (!utils.bboxoverlap(bbox1, bbox2))
7791
+ return [];
7792
+ const intersections = [], a1 = [s1.startcap, s1.forward, s1.back, s1.endcap], a2 = [s2.startcap, s2.forward, s2.back, s2.endcap];
7793
+ return a1.forEach(function(l1) {
7794
+ l1.virtual || a2.forEach(function(l2) {
7795
+ if (l2.virtual)
7796
+ return;
7797
+ const iss = l1.intersects(l2, curveIntersectionThreshold);
7798
+ iss.length > 0 && (iss.c1 = l1, iss.c2 = l2, iss.s1 = s1, iss.s2 = s2, intersections.push(iss));
7799
+ });
7800
+ }), intersections;
7801
+ },
7802
+ makeshape: function(forward, back, curveIntersectionThreshold) {
7803
+ const bpl = back.points.length, fpl = forward.points.length, start2 = utils.makeline(back.points[bpl - 1], forward.points[0]), end = utils.makeline(forward.points[fpl - 1], back.points[0]), shape = {
7804
+ startcap: start2,
7805
+ forward,
7806
+ back,
7807
+ endcap: end,
7808
+ bbox: utils.findbbox([start2, forward, back, end])
7809
+ };
7810
+ return shape.intersections = function(s2) {
7811
+ return utils.shapeintersections(
7812
+ shape,
7813
+ shape.bbox,
7814
+ s2,
7815
+ s2.bbox,
7816
+ curveIntersectionThreshold
7817
+ );
7818
+ }, shape;
7819
+ },
7820
+ getminmax: function(curve2, d, list) {
7821
+ if (!list)
7822
+ return { min: 0, max: 0 };
7823
+ let min2 = nMax, max2 = nMin, t2, c;
7824
+ list.indexOf(0) === -1 && (list = [0].concat(list)), list.indexOf(1) === -1 && list.push(1);
7825
+ for (let i = 0, len = list.length; i < len; i++)
7826
+ t2 = list[i], c = curve2.get(t2), c[d] < min2 && (min2 = c[d]), c[d] > max2 && (max2 = c[d]);
7827
+ return { min: min2, mid: (min2 + max2) / 2, max: max2, size: max2 - min2 };
7828
+ },
7829
+ align: function(points, line2) {
7830
+ const tx = line2.p1.x, ty = line2.p1.y, a = -atan2(line2.p2.y - ty, line2.p2.x - tx), d = function(v) {
7831
+ return {
7832
+ x: (v.x - tx) * cos$1(a) - (v.y - ty) * sin$1(a),
7833
+ y: (v.x - tx) * sin$1(a) + (v.y - ty) * cos$1(a)
7834
+ };
7835
+ };
7836
+ return points.map(d);
7837
+ },
7838
+ roots: function(points, line2) {
7839
+ line2 = line2 || { p1: { x: 0, y: 0 }, p2: { x: 1, y: 0 } };
7840
+ const order = points.length - 1, aligned = utils.align(points, line2), reduce = function(t2) {
7841
+ return 0 <= t2 && t2 <= 1;
7842
+ };
7843
+ if (order === 2) {
7844
+ const a2 = aligned[0].y, b2 = aligned[1].y, c2 = aligned[2].y, d2 = a2 - 2 * b2 + c2;
7845
+ if (d2 !== 0) {
7846
+ const m1 = -sqrt$1(b2 * b2 - a2 * c2), m2 = -a2 + b2, v12 = -(m1 + m2) / d2, v2 = -(-m1 + m2) / d2;
7847
+ return [v12, v2].filter(reduce);
7848
+ } else if (b2 !== c2 && d2 === 0)
7849
+ return [(2 * b2 - c2) / (2 * b2 - 2 * c2)].filter(reduce);
7850
+ return [];
7851
+ }
7852
+ const pa = aligned[0].y, pb = aligned[1].y, pc = aligned[2].y, pd = aligned[3].y;
7853
+ let d = -pa + 3 * pb - 3 * pc + pd, a = 3 * pa - 6 * pb + 3 * pc, b = -3 * pa + 3 * pb, c = pa;
7854
+ if (utils.approximately(d, 0)) {
7855
+ if (utils.approximately(a, 0))
7856
+ return utils.approximately(b, 0) ? [] : [-c / b].filter(reduce);
7857
+ const q3 = sqrt$1(b * b - 4 * a * c), a2 = 2 * a;
7858
+ return [(q3 - b) / a2, (-b - q3) / a2].filter(reduce);
7859
+ }
7860
+ a /= d, b /= d, c /= d;
7861
+ const p = (3 * b - a * a) / 3, p3 = p / 3, q = (2 * a * a * a - 9 * a * b + 27 * c) / 27, q2 = q / 2, discriminant = q2 * q2 + p3 * p3 * p3;
7862
+ let u1, v1, x1, x2, x3;
7863
+ if (discriminant < 0) {
7864
+ const mp3 = -p / 3, mp33 = mp3 * mp3 * mp3, r2 = sqrt$1(mp33), t2 = -q / (2 * r2), cosphi = t2 < -1 ? -1 : t2 > 1 ? 1 : t2, phi = acos$1(cosphi), crtr = crt(r2), t1 = 2 * crtr;
7865
+ return x1 = t1 * cos$1(phi / 3) - a / 3, x2 = t1 * cos$1((phi + tau) / 3) - a / 3, x3 = t1 * cos$1((phi + 2 * tau) / 3) - a / 3, [x1, x2, x3].filter(reduce);
7866
+ } else {
7867
+ if (discriminant === 0)
7868
+ return u1 = q2 < 0 ? crt(-q2) : -crt(q2), x1 = 2 * u1 - a / 3, x2 = -u1 - a / 3, [x1, x2].filter(reduce);
7632
7869
  {
7633
- nodes,
7634
- onShapeChange: (shape) => {
7635
- triggerChange({ shape });
7636
- }
7870
+ const sd = sqrt$1(discriminant);
7871
+ return u1 = crt(-q2 + sd), v1 = crt(q2 + sd), [u1 - v1 - a / 3].filter(reduce);
7637
7872
  }
7638
- ),
7639
- /* @__PURE__ */ jsx(
7640
- Colors,
7641
- {
7642
- nodes,
7643
- onColorChange: (color2) => {
7644
- triggerChange({ color: color2 });
7645
- }
7646
- }
7647
- ),
7648
- /* @__PURE__ */ jsx(NavigateToOption, { nodes }),
7649
- /* @__PURE__ */ jsx(Box, { children: showOpacityOption && /* @__PURE__ */ jsxs(Fragment, { children: [
7650
- /* @__PURE__ */ jsx(Divider, { label: "opacity and border", labelPosition: "left" }),
7651
- /* @__PURE__ */ jsx(
7652
- OpacityOption,
7653
- {
7654
- node: firstNode,
7655
- onOpacityChange: (opacity) => {
7656
- triggerChange({ opacity });
7657
- }
7658
- }
7659
- ),
7660
- /* @__PURE__ */ jsx(
7661
- BorderStyleOption,
7662
- {
7663
- node: firstNode,
7664
- onChange: (border) => {
7665
- triggerChange({ border });
7666
- }
7667
- }
7668
- )
7669
- ] }) }, firstNode.id)
7670
- ] });
7671
- }
7672
- function Colors({
7673
- nodes: [firstNode, ...nodes],
7674
- onColorChange
7675
- }) {
7676
- let selectedColor = firstNode.data.element.color;
7677
- takeWhile(nodes, (node) => node.data.element.color !== selectedColor ? (selectedColor = null, !1) : !0);
7678
- const changeColor = (color2) => () => {
7679
- selectedColor !== color2 && onColorChange(color2);
7680
- };
7681
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(TooltipGroup, { openDelay: 400, closeDelay: 300, children: [
7682
- /* @__PURE__ */ jsx(Divider, { label: "color", labelPosition: "left" }),
7683
- /* @__PURE__ */ jsx(Flex, { mt: "xs", maw: 150, gap: "xs", justify: "flex-start", align: "flex-start", direction: "row", wrap: "wrap", children: themedColors.map(({ key, value }) => /* @__PURE__ */ jsx(
7684
- Tooltip,
7685
- {
7686
- label: key,
7687
- fz: "xs",
7688
- color: "dark",
7689
- offset: 2,
7690
- transitionProps: { duration: 140, transition: "slide-up" },
7691
- children: /* @__PURE__ */ jsx(
7692
- ColorSwatch,
7693
- {
7694
- color: value,
7695
- size: 20,
7696
- withShadow: !0,
7697
- onClick: changeColor(key),
7698
- style: { color: "#fff", cursor: "pointer" },
7699
- children: selectedColor === key && /* @__PURE__ */ jsx(CheckIcon, { style: { width: rem(12), height: rem(12) } })
7700
- }
7701
- )
7702
- },
7703
- key
7704
- )) }),
7705
- /* @__PURE__ */ jsx(Flex, { mt: "sm", maw: 150, gap: "xs", justify: "flex-start", align: "flex-start", direction: "row", wrap: "wrap", children: colors.map(({ key, value }) => /* @__PURE__ */ jsx(
7706
- Tooltip,
7707
- {
7708
- label: key,
7709
- fz: "xs",
7710
- color: "dark",
7711
- offset: 2,
7712
- transitionProps: { duration: 140, transition: "slide-up" },
7713
- children: /* @__PURE__ */ jsx(
7714
- ColorSwatch,
7715
- {
7716
- color: value,
7717
- size: 20,
7718
- onClick: changeColor(key),
7719
- style: { color: "#fff", cursor: "pointer" },
7720
- children: selectedColor === key && /* @__PURE__ */ jsx(CheckIcon, { style: { width: rem(12), height: rem(12) } })
7721
- }
7722
- )
7723
- },
7724
- key
7725
- )) })
7726
- ] }) });
7727
- }
7728
- function ShapeOption({
7729
- nodes: [firstNode, ...nodes],
7730
- onShapeChange
7731
- }) {
7732
- let selectedShape = firstNode.data.element.shape;
7733
- return takeWhile(nodes, (node) => node.data.element.shape !== selectedShape ? (selectedShape = null, !1) : !0), /* @__PURE__ */ jsxs(Box, { children: [
7734
- /* @__PURE__ */ jsx(Divider, { label: "shape", labelPosition: "left" }),
7735
- /* @__PURE__ */ jsx(
7736
- Select,
7737
- {
7738
- mt: "xs",
7739
- size: "xs",
7740
- variant: "filled",
7741
- value: selectedShape,
7742
- placeholder: "[ multiple ]",
7743
- data: ElementShapes,
7744
- allowDeselect: !1,
7745
- checkIconPosition: "right",
7746
- onChange: (value) => {
7747
- !value || value === selectedShape || onShapeChange(value);
7748
- }
7873
+ }
7874
+ },
7875
+ droots: function(p) {
7876
+ if (p.length === 3) {
7877
+ const a = p[0], b = p[1], c = p[2], d = a - 2 * b + c;
7878
+ if (d !== 0) {
7879
+ const m1 = -sqrt$1(b * b - a * c), m2 = -a + b, v1 = -(m1 + m2) / d, v2 = -(-m1 + m2) / d;
7880
+ return [v1, v2];
7881
+ } else if (b !== c && d === 0)
7882
+ return [(2 * b - c) / (2 * (b - c))];
7883
+ return [];
7884
+ }
7885
+ if (p.length === 2) {
7886
+ const a = p[0], b = p[1];
7887
+ return a !== b ? [a / (a - b)] : [];
7888
+ }
7889
+ return [];
7890
+ },
7891
+ curvature: function(t2, d1, d2, _3d, kOnly) {
7892
+ let num, dnm, adk, dk, k = 0, r2 = 0;
7893
+ const d = utils.compute(t2, d1), dd = utils.compute(t2, d2), qdsum = d.x * d.x + d.y * d.y;
7894
+ if (_3d ? (num = sqrt$1(
7895
+ pow(d.y * dd.z - dd.y * d.z, 2) + pow(d.z * dd.x - dd.z * d.x, 2) + pow(d.x * dd.y - dd.x * d.y, 2)
7896
+ ), dnm = pow(qdsum + d.z * d.z, 3 / 2)) : (num = d.x * dd.y - d.y * dd.x, dnm = pow(qdsum, 3 / 2)), num === 0 || dnm === 0)
7897
+ return { k: 0, r: 0 };
7898
+ if (k = num / dnm, r2 = dnm / num, !kOnly) {
7899
+ const pk = utils.curvature(t2 - 1e-3, d1, d2, _3d, !0).k, nk = utils.curvature(t2 + 1e-3, d1, d2, _3d, !0).k;
7900
+ dk = (nk - k + (k - pk)) / 2, adk = (abs$1(nk - k) + abs$1(k - pk)) / 2;
7901
+ }
7902
+ return { k, r: r2, dk, adk };
7903
+ },
7904
+ inflections: function(points) {
7905
+ if (points.length < 4)
7906
+ return [];
7907
+ const p = utils.align(points, { p1: points[0], p2: points.slice(-1)[0] }), a = p[2].x * p[1].y, b = p[3].x * p[1].y, c = p[1].x * p[2].y, d = p[3].x * p[2].y, v1 = 18 * (-3 * a + 2 * b + 3 * c - d), v2 = 18 * (3 * a - b - 3 * c), v3 = 18 * (c - a);
7908
+ if (utils.approximately(v1, 0)) {
7909
+ if (!utils.approximately(v2, 0)) {
7910
+ let t2 = -v3 / v2;
7911
+ if (0 <= t2 && t2 <= 1)
7912
+ return [t2];
7749
7913
  }
7750
- )
7751
- ] });
7752
- }
7753
- function NavigateToOption({
7754
- nodes: [node, ...nodes]
7755
- }) {
7756
- const isMultiple = nodes.length >= 1;
7757
- return /* @__PURE__ */ jsxs(Box, { children: [
7758
- /* @__PURE__ */ jsx(Divider, { label: "navigate to", labelPosition: "left" }),
7759
- /* @__PURE__ */ jsx(
7760
- Select,
7761
- {
7762
- mt: "xs",
7763
- size: "xs",
7764
- variant: "filled",
7765
- value: isMultiple ? null : node.data.element.navigateTo ?? null,
7766
- disabled: isMultiple,
7767
- placeholder: isMultiple ? "[ multiple ]" : "select",
7768
- data: node.data.element.navigateTo ? [{ value: node.data.element.navigateTo, label: node.data.element.navigateTo }] : [],
7769
- allowDeselect: !0,
7770
- checkIconPosition: "right"
7914
+ return [];
7915
+ }
7916
+ const d2 = 2 * v1;
7917
+ if (utils.approximately(d2, 0))
7918
+ return [];
7919
+ const trm = v2 * v2 - 4 * v1 * v3;
7920
+ if (trm < 0)
7921
+ return [];
7922
+ const sq = Math.sqrt(trm);
7923
+ return [(sq - v2) / d2, -(v2 + sq) / d2].filter(function(r2) {
7924
+ return 0 <= r2 && r2 <= 1;
7925
+ });
7926
+ },
7927
+ bboxoverlap: function(b1, b2) {
7928
+ const dims = ["x", "y"], len = dims.length;
7929
+ for (let i = 0, dim, l, t2, d; i < len; i++)
7930
+ if (dim = dims[i], l = b1[dim].mid, t2 = b2[dim].mid, d = (b1[dim].size + b2[dim].size) / 2, abs$1(l - t2) >= d)
7931
+ return !1;
7932
+ return !0;
7933
+ },
7934
+ expandbox: function(bbox, _bbox) {
7935
+ _bbox.x.min < bbox.x.min && (bbox.x.min = _bbox.x.min), _bbox.y.min < bbox.y.min && (bbox.y.min = _bbox.y.min), _bbox.z && _bbox.z.min < bbox.z.min && (bbox.z.min = _bbox.z.min), _bbox.x.max > bbox.x.max && (bbox.x.max = _bbox.x.max), _bbox.y.max > bbox.y.max && (bbox.y.max = _bbox.y.max), _bbox.z && _bbox.z.max > bbox.z.max && (bbox.z.max = _bbox.z.max), bbox.x.mid = (bbox.x.min + bbox.x.max) / 2, bbox.y.mid = (bbox.y.min + bbox.y.max) / 2, bbox.z && (bbox.z.mid = (bbox.z.min + bbox.z.max) / 2), bbox.x.size = bbox.x.max - bbox.x.min, bbox.y.size = bbox.y.max - bbox.y.min, bbox.z && (bbox.z.size = bbox.z.max - bbox.z.min);
7936
+ },
7937
+ pairiteration: function(c1, c2, curveIntersectionThreshold) {
7938
+ const c1b = c1.bbox(), c2b = c2.bbox(), r2 = 1e5, threshold = curveIntersectionThreshold || 0.5;
7939
+ if (c1b.x.size + c1b.y.size < threshold && c2b.x.size + c2b.y.size < threshold)
7940
+ return [
7941
+ (r2 * (c1._t1 + c1._t2) / 2 | 0) / r2 + "/" + (r2 * (c2._t1 + c2._t2) / 2 | 0) / r2
7942
+ ];
7943
+ let cc1 = c1.split(0.5), cc2 = c2.split(0.5), pairs = [
7944
+ { left: cc1.left, right: cc2.left },
7945
+ { left: cc1.left, right: cc2.right },
7946
+ { left: cc1.right, right: cc2.right },
7947
+ { left: cc1.right, right: cc2.left }
7948
+ ];
7949
+ pairs = pairs.filter(function(pair) {
7950
+ return utils.bboxoverlap(pair.left.bbox(), pair.right.bbox());
7951
+ });
7952
+ let results = [];
7953
+ return pairs.length === 0 || (pairs.forEach(function(pair) {
7954
+ results = results.concat(
7955
+ utils.pairiteration(pair.left, pair.right, threshold)
7956
+ );
7957
+ }), results = results.filter(function(v, i) {
7958
+ return results.indexOf(v) === i;
7959
+ })), results;
7960
+ },
7961
+ getccenter: function(p1, p2, p3) {
7962
+ const dx1 = p2.x - p1.x, dy1 = p2.y - p1.y, dx2 = p3.x - p2.x, dy2 = p3.y - p2.y, dx1p = dx1 * cos$1(quart) - dy1 * sin$1(quart), dy1p = dx1 * sin$1(quart) + dy1 * cos$1(quart), dx2p = dx2 * cos$1(quart) - dy2 * sin$1(quart), dy2p = dx2 * sin$1(quart) + dy2 * cos$1(quart), mx1 = (p1.x + p2.x) / 2, my1 = (p1.y + p2.y) / 2, mx2 = (p2.x + p3.x) / 2, my2 = (p2.y + p3.y) / 2, mx1n = mx1 + dx1p, my1n = my1 + dy1p, mx2n = mx2 + dx2p, my2n = my2 + dy2p, arc = utils.lli8(mx1, my1, mx1n, my1n, mx2, my2, mx2n, my2n), r2 = utils.dist(arc, p1);
7963
+ let s = atan2(p1.y - arc.y, p1.x - arc.x), m = atan2(p2.y - arc.y, p2.x - arc.x), e = atan2(p3.y - arc.y, p3.x - arc.x), _;
7964
+ return s < e ? ((s > m || m > e) && (s += tau), s > e && (_ = e, e = s, s = _)) : e < m && m < s ? (_ = e, e = s, s = _) : e += tau, arc.s = s, arc.e = e, arc.r = r2, arc;
7965
+ },
7966
+ numberSort: function(a, b) {
7967
+ return a - b;
7968
+ }
7969
+ };
7970
+ class PolyBezier {
7971
+ constructor(curves) {
7972
+ this.curves = [], this._3d = !1, curves && (this.curves = curves, this._3d = this.curves[0]._3d);
7973
+ }
7974
+ valueOf() {
7975
+ return this.toString();
7976
+ }
7977
+ toString() {
7978
+ return "[" + this.curves.map(function(curve2) {
7979
+ return utils.pointsToString(curve2.points);
7980
+ }).join(", ") + "]";
7981
+ }
7982
+ addCurve(curve2) {
7983
+ this.curves.push(curve2), this._3d = this._3d || curve2._3d;
7984
+ }
7985
+ length() {
7986
+ return this.curves.map(function(v) {
7987
+ return v.length();
7988
+ }).reduce(function(a, b) {
7989
+ return a + b;
7990
+ });
7991
+ }
7992
+ curve(idx) {
7993
+ return this.curves[idx];
7994
+ }
7995
+ bbox() {
7996
+ const c = this.curves;
7997
+ for (var bbox = c[0].bbox(), i = 1; i < c.length; i++)
7998
+ utils.expandbox(bbox, c[i].bbox());
7999
+ return bbox;
8000
+ }
8001
+ offset(d) {
8002
+ const offset = [];
8003
+ return this.curves.forEach(function(v) {
8004
+ offset.push(...v.offset(d));
8005
+ }), new PolyBezier(offset);
8006
+ }
8007
+ }
8008
+ const { abs, min, max, cos, sin, acos, sqrt } = Math, pi = Math.PI;
8009
+ class Bezier {
8010
+ constructor(coords) {
8011
+ let args = coords && coords.forEach ? coords : Array.from(arguments).slice(), coordlen = !1;
8012
+ if (typeof args[0] == "object") {
8013
+ coordlen = args.length;
8014
+ const newargs = [];
8015
+ args.forEach(function(point2) {
8016
+ ["x", "y", "z"].forEach(function(d) {
8017
+ typeof point2[d] < "u" && newargs.push(point2[d]);
8018
+ });
8019
+ }), args = newargs;
8020
+ }
8021
+ let higher = !1;
8022
+ const len = args.length;
8023
+ if (coordlen) {
8024
+ if (coordlen > 4) {
8025
+ if (arguments.length !== 1)
8026
+ throw new Error(
8027
+ "Only new Bezier(point[]) is accepted for 4th and higher order curves"
8028
+ );
8029
+ higher = !0;
7771
8030
  }
7772
- )
7773
- ] });
7774
- }
7775
- function OpacityOption({
7776
- node,
7777
- onOpacityChange
7778
- }) {
7779
- let selectedOpacity = node.data.element.style.opacity ?? 100;
7780
- const [value, setValue] = useState(selectedOpacity);
7781
- return useEffect(() => {
7782
- setValue(selectedOpacity);
7783
- }, [selectedOpacity]), /* @__PURE__ */ jsx(
7784
- Slider,
7785
- {
7786
- mt: "xs",
7787
- size: "sm",
7788
- color: "dark",
7789
- value,
7790
- onChange: setValue,
7791
- onChangeEnd: onOpacityChange
8031
+ } else if (len !== 6 && len !== 8 && len !== 9 && len !== 12 && arguments.length !== 1)
8032
+ throw new Error(
8033
+ "Only new Bezier(point[]) is accepted for 4th and higher order curves"
8034
+ );
8035
+ const _3d = this._3d = !higher && (len === 9 || len === 12) || coords && coords[0] && typeof coords[0].z < "u", points = this.points = [];
8036
+ for (let idx = 0, step = _3d ? 3 : 2; idx < len; idx += step) {
8037
+ var point = {
8038
+ x: args[idx],
8039
+ y: args[idx + 1]
8040
+ };
8041
+ _3d && (point.z = args[idx + 2]), points.push(point);
8042
+ }
8043
+ const order = this.order = points.length - 1, dims = this.dims = ["x", "y"];
8044
+ _3d && dims.push("z"), this.dimlen = dims.length;
8045
+ const aligned = utils.align(points, { p1: points[0], p2: points[order] }), baselength = utils.dist(points[0], points[order]);
8046
+ this._linear = aligned.reduce((t2, p) => t2 + abs(p.y), 0) < baselength / 50, this._lut = [], this._t1 = 0, this._t2 = 1, this.update();
8047
+ }
8048
+ static quadraticFromPoints(p1, p2, p3, t2) {
8049
+ if (typeof t2 > "u" && (t2 = 0.5), t2 === 0)
8050
+ return new Bezier(p2, p2, p3);
8051
+ if (t2 === 1)
8052
+ return new Bezier(p1, p2, p2);
8053
+ const abc = Bezier.getABC(2, p1, p2, p3, t2);
8054
+ return new Bezier(p1, abc.A, p3);
8055
+ }
8056
+ static cubicFromPoints(S, B, E, t2, d1) {
8057
+ typeof t2 > "u" && (t2 = 0.5);
8058
+ const abc = Bezier.getABC(3, S, B, E, t2);
8059
+ typeof d1 > "u" && (d1 = utils.dist(B, abc.C));
8060
+ const d2 = d1 * (1 - t2) / t2, selen = utils.dist(S, E), lx = (E.x - S.x) / selen, ly = (E.y - S.y) / selen, bx1 = d1 * lx, by1 = d1 * ly, bx2 = d2 * lx, by2 = d2 * ly, e1 = { x: B.x - bx1, y: B.y - by1 }, e2 = { x: B.x + bx2, y: B.y + by2 }, A = abc.A, v1 = { x: A.x + (e1.x - A.x) / (1 - t2), y: A.y + (e1.y - A.y) / (1 - t2) }, v2 = { x: A.x + (e2.x - A.x) / t2, y: A.y + (e2.y - A.y) / t2 }, nc1 = { x: S.x + (v1.x - S.x) / t2, y: S.y + (v1.y - S.y) / t2 }, nc2 = {
8061
+ x: E.x + (v2.x - E.x) / (1 - t2),
8062
+ y: E.y + (v2.y - E.y) / (1 - t2)
8063
+ };
8064
+ return new Bezier(S, nc1, nc2, E);
8065
+ }
8066
+ static getUtils() {
8067
+ return utils;
8068
+ }
8069
+ getUtils() {
8070
+ return Bezier.getUtils();
8071
+ }
8072
+ static get PolyBezier() {
8073
+ return PolyBezier;
8074
+ }
8075
+ valueOf() {
8076
+ return this.toString();
8077
+ }
8078
+ toString() {
8079
+ return utils.pointsToString(this.points);
8080
+ }
8081
+ toSVG() {
8082
+ if (this._3d)
8083
+ return !1;
8084
+ const p = this.points, x = p[0].x, y = p[0].y, s = ["M", x, y, this.order === 2 ? "Q" : "C"];
8085
+ for (let i = 1, last2 = p.length; i < last2; i++)
8086
+ s.push(p[i].x), s.push(p[i].y);
8087
+ return s.join(" ");
8088
+ }
8089
+ setRatios(ratios) {
8090
+ if (ratios.length !== this.points.length)
8091
+ throw new Error("incorrect number of ratio values");
8092
+ this.ratios = ratios, this._lut = [];
8093
+ }
8094
+ verify() {
8095
+ const print = this.coordDigest();
8096
+ print !== this._print && (this._print = print, this.update());
8097
+ }
8098
+ coordDigest() {
8099
+ return this.points.map(function(c, pos) {
8100
+ return "" + pos + c.x + c.y + (c.z ? c.z : 0);
8101
+ }).join("");
8102
+ }
8103
+ update() {
8104
+ this._lut = [], this.dpoints = utils.derive(this.points, this._3d), this.computedirection();
8105
+ }
8106
+ computedirection() {
8107
+ const points = this.points, angle = utils.angle(points[0], points[this.order], points[1]);
8108
+ this.clockwise = angle > 0;
8109
+ }
8110
+ length() {
8111
+ return utils.length(this.derivative.bind(this));
8112
+ }
8113
+ static getABC(order = 2, S, B, E, t2 = 0.5) {
8114
+ const u = utils.projectionratio(t2, order), um = 1 - u, C = {
8115
+ x: u * S.x + um * E.x,
8116
+ y: u * S.y + um * E.y
8117
+ }, s = utils.abcratio(t2, order);
8118
+ return { A: {
8119
+ x: B.x + (B.x - C.x) / s,
8120
+ y: B.y + (B.y - C.y) / s
8121
+ }, B, C, S, E };
8122
+ }
8123
+ getABC(t2, B) {
8124
+ B = B || this.get(t2);
8125
+ let S = this.points[0], E = this.points[this.order];
8126
+ return Bezier.getABC(this.order, S, B, E, t2);
8127
+ }
8128
+ getLUT(steps) {
8129
+ if (this.verify(), steps = steps || 100, this._lut.length === steps + 1)
8130
+ return this._lut;
8131
+ this._lut = [], steps++, this._lut = [];
8132
+ for (let i = 0, p, t2; i < steps; i++)
8133
+ t2 = i / (steps - 1), p = this.compute(t2), p.t = t2, this._lut.push(p);
8134
+ return this._lut;
8135
+ }
8136
+ on(point, error) {
8137
+ error = error || 5;
8138
+ const lut = this.getLUT(), hits = [];
8139
+ for (let i = 0, c, t2 = 0; i < lut.length; i++)
8140
+ c = lut[i], utils.dist(c, point) < error && (hits.push(c), t2 += i / lut.length);
8141
+ return hits.length ? t /= hits.length : !1;
8142
+ }
8143
+ project(point) {
8144
+ const LUT = this.getLUT(), l = LUT.length - 1, closest = utils.closest(LUT, point), mpos = closest.mpos, t1 = (mpos - 1) / l, t2 = (mpos + 1) / l, step = 0.1 / l;
8145
+ let mdist = closest.mdist, t3 = t1, ft = t3, p;
8146
+ mdist += 1;
8147
+ for (let d; t3 < t2 + step; t3 += step)
8148
+ p = this.compute(t3), d = utils.dist(point, p), d < mdist && (mdist = d, ft = t3);
8149
+ return ft = ft < 0 ? 0 : ft > 1 ? 1 : ft, p = this.compute(ft), p.t = ft, p.d = mdist, p;
8150
+ }
8151
+ get(t2) {
8152
+ return this.compute(t2);
8153
+ }
8154
+ point(idx) {
8155
+ return this.points[idx];
8156
+ }
8157
+ compute(t2) {
8158
+ return this.ratios ? utils.computeWithRatios(t2, this.points, this.ratios, this._3d) : utils.compute(t2, this.points, this._3d, this.ratios);
8159
+ }
8160
+ raise() {
8161
+ const p = this.points, np = [p[0]], k = p.length;
8162
+ for (let i = 1, pi2, pim; i < k; i++)
8163
+ pi2 = p[i], pim = p[i - 1], np[i] = {
8164
+ x: (k - i) / k * pi2.x + i / k * pim.x,
8165
+ y: (k - i) / k * pi2.y + i / k * pim.y
8166
+ };
8167
+ return np[k] = p[k - 1], new Bezier(np);
8168
+ }
8169
+ derivative(t2) {
8170
+ return utils.compute(t2, this.dpoints[0], this._3d);
8171
+ }
8172
+ dderivative(t2) {
8173
+ return utils.compute(t2, this.dpoints[1], this._3d);
8174
+ }
8175
+ align() {
8176
+ let p = this.points;
8177
+ return new Bezier(utils.align(p, { p1: p[0], p2: p[p.length - 1] }));
8178
+ }
8179
+ curvature(t2) {
8180
+ return utils.curvature(t2, this.dpoints[0], this.dpoints[1], this._3d);
8181
+ }
8182
+ inflections() {
8183
+ return utils.inflections(this.points);
8184
+ }
8185
+ normal(t2) {
8186
+ return this._3d ? this.__normal3(t2) : this.__normal2(t2);
8187
+ }
8188
+ __normal2(t2) {
8189
+ const d = this.derivative(t2), q = sqrt(d.x * d.x + d.y * d.y);
8190
+ return { t: t2, x: -d.y / q, y: d.x / q };
8191
+ }
8192
+ __normal3(t2) {
8193
+ const r1 = this.derivative(t2), r2 = this.derivative(t2 + 0.01), q1 = sqrt(r1.x * r1.x + r1.y * r1.y + r1.z * r1.z), q2 = sqrt(r2.x * r2.x + r2.y * r2.y + r2.z * r2.z);
8194
+ r1.x /= q1, r1.y /= q1, r1.z /= q1, r2.x /= q2, r2.y /= q2, r2.z /= q2;
8195
+ const c = {
8196
+ x: r2.y * r1.z - r2.z * r1.y,
8197
+ y: r2.z * r1.x - r2.x * r1.z,
8198
+ z: r2.x * r1.y - r2.y * r1.x
8199
+ }, m = sqrt(c.x * c.x + c.y * c.y + c.z * c.z);
8200
+ c.x /= m, c.y /= m, c.z /= m;
8201
+ const R = [
8202
+ c.x * c.x,
8203
+ c.x * c.y - c.z,
8204
+ c.x * c.z + c.y,
8205
+ c.x * c.y + c.z,
8206
+ c.y * c.y,
8207
+ c.y * c.z - c.x,
8208
+ c.x * c.z - c.y,
8209
+ c.y * c.z + c.x,
8210
+ c.z * c.z
8211
+ ];
8212
+ return {
8213
+ t: t2,
8214
+ x: R[0] * r1.x + R[1] * r1.y + R[2] * r1.z,
8215
+ y: R[3] * r1.x + R[4] * r1.y + R[5] * r1.z,
8216
+ z: R[6] * r1.x + R[7] * r1.y + R[8] * r1.z
8217
+ };
8218
+ }
8219
+ hull(t2) {
8220
+ let p = this.points, _p = [], q = [], idx = 0;
8221
+ for (q[idx++] = p[0], q[idx++] = p[1], q[idx++] = p[2], this.order === 3 && (q[idx++] = p[3]); p.length > 1; ) {
8222
+ _p = [];
8223
+ for (let i = 0, pt, l = p.length - 1; i < l; i++)
8224
+ pt = utils.lerp(t2, p[i], p[i + 1]), q[idx++] = pt, _p.push(pt);
8225
+ p = _p;
8226
+ }
8227
+ return q;
8228
+ }
8229
+ split(t1, t2) {
8230
+ if (t1 === 0 && t2)
8231
+ return this.split(t2).left;
8232
+ if (t2 === 1)
8233
+ return this.split(t1).right;
8234
+ const q = this.hull(t1), result = {
8235
+ left: this.order === 2 ? new Bezier([q[0], q[3], q[5]]) : new Bezier([q[0], q[4], q[7], q[9]]),
8236
+ right: this.order === 2 ? new Bezier([q[5], q[4], q[2]]) : new Bezier([q[9], q[8], q[6], q[3]]),
8237
+ span: q
8238
+ };
8239
+ return result.left._t1 = utils.map(0, 0, 1, this._t1, this._t2), result.left._t2 = utils.map(t1, 0, 1, this._t1, this._t2), result.right._t1 = utils.map(t1, 0, 1, this._t1, this._t2), result.right._t2 = utils.map(1, 0, 1, this._t1, this._t2), t2 ? (t2 = utils.map(t2, t1, 1, 0, 1), result.right.split(t2).left) : result;
8240
+ }
8241
+ extrema() {
8242
+ const result = {};
8243
+ let roots = [];
8244
+ return this.dims.forEach(
8245
+ (function(dim) {
8246
+ let mfn = function(v) {
8247
+ return v[dim];
8248
+ }, p = this.dpoints[0].map(mfn);
8249
+ result[dim] = utils.droots(p), this.order === 3 && (p = this.dpoints[1].map(mfn), result[dim] = result[dim].concat(utils.droots(p))), result[dim] = result[dim].filter(function(t2) {
8250
+ return t2 >= 0 && t2 <= 1;
8251
+ }), roots = roots.concat(result[dim].sort(utils.numberSort));
8252
+ }).bind(this)
8253
+ ), result.values = roots.sort(utils.numberSort).filter(function(v, idx) {
8254
+ return roots.indexOf(v) === idx;
8255
+ }), result;
8256
+ }
8257
+ bbox() {
8258
+ const extrema = this.extrema(), result = {};
8259
+ return this.dims.forEach(
8260
+ (function(d) {
8261
+ result[d] = utils.getminmax(this, d, extrema[d]);
8262
+ }).bind(this)
8263
+ ), result;
8264
+ }
8265
+ overlaps(curve2) {
8266
+ const lbbox = this.bbox(), tbbox = curve2.bbox();
8267
+ return utils.bboxoverlap(lbbox, tbbox);
8268
+ }
8269
+ offset(t2, d) {
8270
+ if (typeof d < "u") {
8271
+ const c = this.get(t2), n = this.normal(t2), ret = {
8272
+ c,
8273
+ n,
8274
+ x: c.x + n.x * d,
8275
+ y: c.y + n.y * d
8276
+ };
8277
+ return this._3d && (ret.z = c.z + n.z * d), ret;
7792
8278
  }
7793
- );
7794
- }
7795
- function BorderStyleOption({
7796
- node,
7797
- onChange
7798
- }) {
7799
- let selecteBorderStyle = node.data.element.style.border ?? "dashed";
7800
- const [value, setValue] = useState(selecteBorderStyle);
7801
- return useEffect(() => {
7802
- setValue(selecteBorderStyle);
7803
- }, [selecteBorderStyle]), /* @__PURE__ */ jsx(Box, { mt: "md", children: /* @__PURE__ */ jsx(
7804
- SegmentedControl,
7805
- {
7806
- size: "xs",
7807
- fullWidth: !0,
7808
- withItemsBorders: !1,
7809
- value,
7810
- onChange: (v) => {
7811
- setValue(v), onChange(v);
7812
- },
7813
- data: [
7814
- { label: "Solid", value: "solid" },
7815
- { label: "Dashed", value: "dashed" },
7816
- { label: "Dotted", value: "dotted" },
7817
- { label: "None", value: "none" }
7818
- ]
8279
+ if (this._linear) {
8280
+ const nv = this.normal(0), coords = this.points.map(function(p) {
8281
+ const ret = {
8282
+ x: p.x + t2 * nv.x,
8283
+ y: p.y + t2 * nv.y
8284
+ };
8285
+ return p.z && nv.z && (ret.z = p.z + t2 * nv.z), ret;
8286
+ });
8287
+ return [new Bezier(coords)];
7819
8288
  }
7820
- ) });
7821
- }
7822
- function OptionsPanel() {
7823
- const [selectedNodes, setSelectedNodes] = useState([]);
7824
- return useOnSelectionChange({
7825
- onChange: ({ nodes }) => {
7826
- const next = nodes.map((n) => n.id).sort();
7827
- setSelectedNodes((prev) => shallowEqual(prev, next) ? prev : next);
8289
+ return this.reduce().map(function(s) {
8290
+ return s._linear ? s.offset(t2)[0] : s.scale(t2);
8291
+ });
8292
+ }
8293
+ simple() {
8294
+ if (this.order === 3) {
8295
+ const a1 = utils.angle(this.points[0], this.points[3], this.points[1]), a2 = utils.angle(this.points[0], this.points[3], this.points[2]);
8296
+ if (a1 > 0 && a2 < 0 || a1 < 0 && a2 > 0)
8297
+ return !1;
7828
8298
  }
7829
- }), /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: selectedNodes.length > 0 && /* @__PURE__ */ jsx(
7830
- motion.div,
7831
- {
7832
- initial: { opacity: 0, scale: 0.85 },
7833
- animate: { opacity: 1, scale: 1 },
7834
- exit: {
7835
- opacity: 0,
7836
- scale: 0.85
7837
- },
7838
- transition: { duration: 0.14 },
7839
- className: clsx("react-flow__panel", panel),
7840
- style: {
7841
- transformOrigin: "center right"
7842
- },
7843
- children: /* @__PURE__ */ jsx(Card, { shadow: "sm", children: /* @__PURE__ */ jsx(NodeOptions, { selectedNodeIds: selectedNodes }) })
8299
+ const n1 = this.normal(0), n2 = this.normal(1);
8300
+ let s = n1.x * n2.x + n1.y * n2.y;
8301
+ return this._3d && (s += n1.z * n2.z), abs(acos(s)) < pi / 3;
8302
+ }
8303
+ reduce() {
8304
+ let i, t1 = 0, t2 = 0, step = 0.01, segment, pass1 = [], pass2 = [], extrema = this.extrema().values;
8305
+ for (extrema.indexOf(0) === -1 && (extrema = [0].concat(extrema)), extrema.indexOf(1) === -1 && extrema.push(1), t1 = extrema[0], i = 1; i < extrema.length; i++)
8306
+ t2 = extrema[i], segment = this.split(t1, t2), segment._t1 = t1, segment._t2 = t2, pass1.push(segment), t1 = t2;
8307
+ return pass1.forEach(function(p1) {
8308
+ for (t1 = 0, t2 = 0; t2 <= 1; )
8309
+ for (t2 = t1 + step; t2 <= 1 + step; t2 += step)
8310
+ if (segment = p1.split(t1, t2), !segment.simple()) {
8311
+ if (t2 -= step, abs(t1 - t2) < step)
8312
+ return [];
8313
+ segment = p1.split(t1, t2), segment._t1 = utils.map(t1, 0, 1, p1._t1, p1._t2), segment._t2 = utils.map(t2, 0, 1, p1._t1, p1._t2), pass2.push(segment), t1 = t2;
8314
+ break;
8315
+ }
8316
+ t1 < 1 && (segment = p1.split(t1, 1), segment._t1 = utils.map(t1, 0, 1, p1._t1, p1._t2), segment._t2 = p1._t2, pass2.push(segment));
8317
+ }), pass2;
8318
+ }
8319
+ translate(v, d1, d2) {
8320
+ d2 = typeof d2 == "number" ? d2 : d1;
8321
+ const o = this.order;
8322
+ let d = this.points.map((_, i) => (1 - i / o) * d1 + i / o * d2);
8323
+ return new Bezier(
8324
+ this.points.map((p, i) => ({
8325
+ x: p.x + v.x * d[i],
8326
+ y: p.y + v.y * d[i]
8327
+ }))
8328
+ );
8329
+ }
8330
+ scale(d) {
8331
+ const order = this.order;
8332
+ let distanceFn = !1;
8333
+ if (typeof d == "function" && (distanceFn = d), distanceFn && order === 2)
8334
+ return this.raise().scale(distanceFn);
8335
+ const clockwise = this.clockwise, points = this.points;
8336
+ if (this._linear)
8337
+ return this.translate(
8338
+ this.normal(0),
8339
+ distanceFn ? distanceFn(0) : d,
8340
+ distanceFn ? distanceFn(1) : d
8341
+ );
8342
+ const r1 = distanceFn ? distanceFn(0) : d, r2 = distanceFn ? distanceFn(1) : d, v = [this.offset(0, 10), this.offset(1, 10)], np = [], o = utils.lli4(v[0], v[0].c, v[1], v[1].c);
8343
+ if (!o)
8344
+ throw new Error("cannot scale this curve. Try reducing it first.");
8345
+ return [0, 1].forEach(function(t2) {
8346
+ const p = np[t2 * order] = utils.copy(points[t2 * order]);
8347
+ p.x += (t2 ? r2 : r1) * v[t2].n.x, p.y += (t2 ? r2 : r1) * v[t2].n.y;
8348
+ }), distanceFn ? ([0, 1].forEach(function(t2) {
8349
+ if (!(order === 2 && t2)) {
8350
+ var p = points[t2 + 1], ov = {
8351
+ x: p.x - o.x,
8352
+ y: p.y - o.y
8353
+ }, rc = distanceFn ? distanceFn((t2 + 1) / order) : d;
8354
+ distanceFn && !clockwise && (rc = -rc);
8355
+ var m = sqrt(ov.x * ov.x + ov.y * ov.y);
8356
+ ov.x /= m, ov.y /= m, np[t2 + 1] = {
8357
+ x: p.x + rc * ov.x,
8358
+ y: p.y + rc * ov.y
8359
+ };
8360
+ }
8361
+ }), new Bezier(np)) : ([0, 1].forEach((t2) => {
8362
+ if (order === 2 && t2)
8363
+ return;
8364
+ const p = np[t2 * order], d2 = this.derivative(t2), p2 = { x: p.x + d2.x, y: p.y + d2.y };
8365
+ np[t2 + 1] = utils.lli4(p, p2, o, points[t2 + 1]);
8366
+ }), new Bezier(np));
8367
+ }
8368
+ outline(d1, d2, d3, d4) {
8369
+ if (d2 = d2 === void 0 ? d1 : d2, this._linear) {
8370
+ const n = this.normal(0), start2 = this.points[0], end = this.points[this.points.length - 1];
8371
+ let s, mid, e;
8372
+ d3 === void 0 && (d3 = d1, d4 = d2), s = { x: start2.x + n.x * d1, y: start2.y + n.y * d1 }, e = { x: end.x + n.x * d3, y: end.y + n.y * d3 }, mid = { x: (s.x + e.x) / 2, y: (s.y + e.y) / 2 };
8373
+ const fline = [s, mid, e];
8374
+ s = { x: start2.x - n.x * d2, y: start2.y - n.y * d2 }, e = { x: end.x - n.x * d4, y: end.y - n.y * d4 }, mid = { x: (s.x + e.x) / 2, y: (s.y + e.y) / 2 };
8375
+ const bline = [e, mid, s], ls2 = utils.makeline(bline[2], fline[0]), le2 = utils.makeline(fline[2], bline[0]), segments2 = [ls2, new Bezier(fline), le2, new Bezier(bline)];
8376
+ return new PolyBezier(segments2);
8377
+ }
8378
+ const reduced = this.reduce(), len = reduced.length, fcurves = [];
8379
+ let bcurves = [], p, alen = 0, tlen = this.length();
8380
+ const graduated = typeof d3 < "u" && typeof d4 < "u";
8381
+ function linearDistanceFunction(s, e, tlen2, alen2, slen) {
8382
+ return function(v) {
8383
+ const f1 = alen2 / tlen2, f2 = (alen2 + slen) / tlen2, d = e - s;
8384
+ return utils.map(v, 0, 1, s + f1 * d, s + f2 * d);
8385
+ };
7844
8386
  }
7845
- ) });
8387
+ reduced.forEach(function(segment) {
8388
+ const slen = segment.length();
8389
+ graduated ? (fcurves.push(
8390
+ segment.scale(linearDistanceFunction(d1, d3, tlen, alen, slen))
8391
+ ), bcurves.push(
8392
+ segment.scale(linearDistanceFunction(-d2, -d4, tlen, alen, slen))
8393
+ )) : (fcurves.push(segment.scale(d1)), bcurves.push(segment.scale(-d2))), alen += slen;
8394
+ }), bcurves = bcurves.map(function(s) {
8395
+ return p = s.points, p[3] ? s.points = [p[3], p[2], p[1], p[0]] : s.points = [p[2], p[1], p[0]], s;
8396
+ }).reverse();
8397
+ const fs = fcurves[0].points[0], fe = fcurves[len - 1].points[fcurves[len - 1].points.length - 1], bs = bcurves[len - 1].points[bcurves[len - 1].points.length - 1], be = bcurves[0].points[0], ls = utils.makeline(bs, fs), le = utils.makeline(fe, be), segments = [ls].concat(fcurves).concat([le]).concat(bcurves);
8398
+ return new PolyBezier(segments);
8399
+ }
8400
+ outlineshapes(d1, d2, curveIntersectionThreshold) {
8401
+ d2 = d2 || d1;
8402
+ const outline = this.outline(d1, d2).curves, shapes = [];
8403
+ for (let i = 1, len = outline.length; i < len / 2; i++) {
8404
+ const shape = utils.makeshape(
8405
+ outline[i],
8406
+ outline[len - i],
8407
+ curveIntersectionThreshold
8408
+ );
8409
+ shape.startcap.virtual = i > 1, shape.endcap.virtual = i < len / 2 - 1, shapes.push(shape);
8410
+ }
8411
+ return shapes;
8412
+ }
8413
+ intersects(curve2, curveIntersectionThreshold) {
8414
+ return curve2 ? curve2.p1 && curve2.p2 ? this.lineIntersects(curve2) : (curve2 instanceof Bezier && (curve2 = curve2.reduce()), this.curveintersects(
8415
+ this.reduce(),
8416
+ curve2,
8417
+ curveIntersectionThreshold
8418
+ )) : this.selfintersects(curveIntersectionThreshold);
8419
+ }
8420
+ lineIntersects(line2) {
8421
+ const mx = min(line2.p1.x, line2.p2.x), my = min(line2.p1.y, line2.p2.y), MX = max(line2.p1.x, line2.p2.x), MY = max(line2.p1.y, line2.p2.y);
8422
+ return utils.roots(this.points, line2).filter((t2) => {
8423
+ var p = this.get(t2);
8424
+ return utils.between(p.x, mx, MX) && utils.between(p.y, my, MY);
8425
+ });
8426
+ }
8427
+ selfintersects(curveIntersectionThreshold) {
8428
+ const reduced = this.reduce(), len = reduced.length - 2, results = [];
8429
+ for (let i = 0, result, left, right; i < len; i++)
8430
+ left = reduced.slice(i, i + 1), right = reduced.slice(i + 2), result = this.curveintersects(left, right, curveIntersectionThreshold), results.push(...result);
8431
+ return results;
8432
+ }
8433
+ curveintersects(c1, c2, curveIntersectionThreshold) {
8434
+ const pairs = [];
8435
+ c1.forEach(function(l) {
8436
+ c2.forEach(function(r2) {
8437
+ l.overlaps(r2) && pairs.push({ left: l, right: r2 });
8438
+ });
8439
+ });
8440
+ let intersections = [];
8441
+ return pairs.forEach(function(pair) {
8442
+ const result = utils.pairiteration(
8443
+ pair.left,
8444
+ pair.right,
8445
+ curveIntersectionThreshold
8446
+ );
8447
+ result.length > 0 && (intersections = intersections.concat(result));
8448
+ }), intersections;
8449
+ }
8450
+ arcs(errorThreshold) {
8451
+ return errorThreshold = errorThreshold || 0.5, this._iterate(errorThreshold, []);
8452
+ }
8453
+ _error(pc, np1, s, e) {
8454
+ const q = (e - s) / 4, c1 = this.get(s + q), c2 = this.get(e - q), ref = utils.dist(pc, np1), d1 = utils.dist(pc, c1), d2 = utils.dist(pc, c2);
8455
+ return abs(d1 - ref) + abs(d2 - ref);
8456
+ }
8457
+ _iterate(errorThreshold, circles) {
8458
+ let t_s = 0, t_e = 1, safety;
8459
+ do {
8460
+ safety = 0, t_e = 1;
8461
+ let np1 = this.get(t_s), np2, np3, arc, prev_arc, curr_good = !1, prev_good = !1, done, t_m = t_e, prev_e = 1;
8462
+ do
8463
+ if (prev_good = curr_good, prev_arc = arc, t_m = (t_s + t_e) / 2, np2 = this.get(t_m), np3 = this.get(t_e), arc = utils.getccenter(np1, np2, np3), arc.interval = {
8464
+ start: t_s,
8465
+ end: t_e
8466
+ }, curr_good = this._error(arc, np1, t_s, t_e) <= errorThreshold, done = prev_good && !curr_good, done || (prev_e = t_e), curr_good) {
8467
+ if (t_e >= 1) {
8468
+ if (arc.interval.end = prev_e = 1, prev_arc = arc, t_e > 1) {
8469
+ let d = {
8470
+ x: arc.x + arc.r * cos(arc.e),
8471
+ y: arc.y + arc.r * sin(arc.e)
8472
+ };
8473
+ arc.e += utils.angle({ x: arc.x, y: arc.y }, d, this.get(1));
8474
+ }
8475
+ break;
8476
+ }
8477
+ t_e = t_e + (t_e - t_s) / 2;
8478
+ } else
8479
+ t_e = t_m;
8480
+ while (!done && safety++ < 100);
8481
+ if (safety >= 100)
8482
+ break;
8483
+ prev_arc = prev_arc || arc, circles.push(prev_arc), t_s = prev_e;
8484
+ } while (t_e < 1);
8485
+ return circles;
8486
+ }
7846
8487
  }
7847
8488
  function deriveEdgePoints(bezierSpline) {
7848
8489
  let [start2, ...bezierPoints] = bezierSpline;
@@ -7851,25 +8492,17 @@ function deriveEdgePoints(bezierSpline) {
7851
8492
  // start
7852
8493
  ];
7853
8494
  for (; hasAtLeast(bezierPoints, 3); ) {
7854
- const [cp1, cp2, end, ...rest] = bezierPoints, [centerX, centerY] = getBezierEdgeCenter({
7855
- sourceX: start2[0],
7856
- sourceY: start2[1],
7857
- targetX: end[0],
7858
- targetY: end[1],
7859
- sourceControlX: cp1[0],
7860
- sourceControlY: cp1[1],
7861
- targetControlX: cp2[0],
7862
- targetControlY: cp2[1]
7863
- });
7864
- handles.push(
7865
- [centerX, centerY]
7866
- ), bezierPoints = rest, start2 = end;
8495
+ const [cp1, cp2, end, ...rest] = bezierPoints, bezier = new Bezier(start2[0], start2[1], cp1[0], cp1[1], cp2[0], cp2[1], end[0], end[1]), inflections = bezier.inflections();
8496
+ inflections.length === 0 && inflections.push(0.5), inflections.forEach((t2) => {
8497
+ const { x, y } = bezier.get(t2);
8498
+ handles.push([x, y]);
8499
+ }), bezierPoints = rest, start2 = end;
7867
8500
  }
7868
8501
  return invariant(bezierPoints.length === 0, "all points should be consumed"), handles;
7869
8502
  }
7870
8503
  const nodeZIndex = (node) => node.level + 1;
7871
8504
  function diagramViewToXYFlowData(view, opts) {
7872
- const editor = {
8505
+ const isDynamicView = view.__ === "dynamic", editor = {
7873
8506
  nodes: [],
7874
8507
  edges: []
7875
8508
  }, nodeLookup = /* @__PURE__ */ new Map(), traverse = view.nodes.reduce(
@@ -7949,10 +8582,11 @@ function diagramViewToXYFlowData(view, opts) {
7949
8582
  controlPoints,
7950
8583
  headPoint: edge.headArrowPoint ?? null,
7951
8584
  tailPoint: edge.tailArrowPoint ?? null,
7952
- label: edge.labelBBox && edge.label ? {
8585
+ stepNum: isDynamicView ? extractStep(edge.id) : null,
8586
+ label: edge.labelBBox ? {
7953
8587
  bbox: edge.labelBBox,
7954
8588
  // text: edge.labels ? edge.labels.map(l => l.text).join('\n') : ''
7955
- text: edge.label
8589
+ text: edge.label ?? ""
7956
8590
  } : null
7957
8591
  },
7958
8592
  // markerEnd: {
@@ -7963,132 +8597,162 @@ function diagramViewToXYFlowData(view, opts) {
7963
8597
  }
7964
8598
  return editor;
7965
8599
  }
8600
+ function toDomPrecision(v) {
8601
+ return v === null ? 0.01 : Math.round(v * 100) / 100;
8602
+ }
7966
8603
  function selectDimensions(state) {
7967
8604
  return `${Math.round(state.width)}:${Math.round(state.height)}`;
7968
8605
  }
7969
- function FitViewOnViewportResize({ diagramApi }) {
8606
+ function FitViewOnViewportResize({ diagramApi, xyflowApi }) {
7970
8607
  const dimensions = useXYStore(selectDimensions), prevDimensionsRef = useRef(dimensions);
7971
8608
  return useDebouncedEffect(
7972
8609
  () => {
7973
- prevDimensionsRef.current !== dimensions && (diagramApi.getState().fitDiagram(), prevDimensionsRef.current = dimensions);
8610
+ const { focusedNodeId, fitDiagram } = diagramApi.getState();
8611
+ focusedNodeId || prevDimensionsRef.current === dimensions || (fitDiagram(xyflowApi), prevDimensionsRef.current = dimensions);
7974
8612
  },
7975
- [dimensions],
7976
- 150
8613
+ [dimensions, diagramApi, xyflowApi],
8614
+ 200,
8615
+ 800
7977
8616
  ), null;
7978
8617
  }
7979
- const diagramChangeId = (s) => s.view.id + "_" + s.view.autoLayout + "_" + s.fitViewPadding;
7980
- function FitViewOnDiagramChanges() {
7981
- const diagramApi = useDiagramStoreApi(), [viewportMoved, setViewportMoved] = useState(diagramApi.getState().viewportChanged), [processedChangeId, setProcessed] = useState(diagramChangeId(diagramApi.getState())), [pendingChangeId, setPending] = useState(processedChangeId), isReady = useNodesInitialized({
7982
- includeHiddenNodes: !0
7983
- }), schedulePending = useDebouncedCallback(
7984
- (pendingChangeId2) => {
7985
- setPending(pendingChangeId2);
7986
- },
7987
- [setPending],
7988
- 75
7989
- );
7990
- return useEffect(
7991
- () => diagramApi.subscribe(
7992
- (s) => diagramChangeId(s),
7993
- schedulePending
7994
- ),
7995
- [diagramApi, schedulePending]
7996
- ), useEffect(
7997
- () => diagramApi.subscribe(
7998
- (s) => s.viewportChanged,
7999
- setViewportMoved
8000
- ),
8001
- [diagramApi, setViewportMoved]
8002
- ), useRafEffect(
8003
- () => {
8004
- !isReady || processedChangeId === pendingChangeId || (diagramApi.getState().fitDiagram(), setProcessed(pendingChangeId));
8005
- },
8006
- [isReady, processedChangeId, pendingChangeId, diagramApi]
8007
- ), !viewportMoved && isReady ? /* @__PURE__ */ jsx(FitViewOnViewportResize, { diagramApi }) : null;
8618
+ function selector$2({ view, xyflowSynced, viewportChanged, lastOnNavigate, ...s }) {
8619
+ const viewId = view.id + "_" + view.autoLayout + "_" + s.fitViewPadding, waitCorrection = lastOnNavigate && lastOnNavigate.toView === view.id && lastOnNavigate.positionCorrected === !1, elTo = waitCorrection ? view.nodes.find((n) => n.id === lastOnNavigate.element.id) : void 0;
8620
+ return waitCorrection && elTo ? {
8621
+ viewId,
8622
+ xyflowSynced,
8623
+ viewportChanged,
8624
+ waitCorrection: !0,
8625
+ elFrom: lastOnNavigate.element,
8626
+ elTo
8627
+ } : {
8628
+ viewId,
8629
+ xyflowSynced,
8630
+ viewportChanged,
8631
+ waitCorrection: !1,
8632
+ fromElement: null,
8633
+ toElement: null
8634
+ };
8008
8635
  }
8009
- const selectFitViewFlag = (s) => s.fitViewEnabled, FitViewOnDiagramChange = memo(() => useDiagramState(selectFitViewFlag) ? /* @__PURE__ */ jsx(FitViewOnDiagramChanges, {}) : null);
8010
- function toDomPrecision(v) {
8011
- return v === null ? 0.01 : Math.round(v * 100) / 100;
8636
+ function FitViewOnDiagramChange() {
8637
+ const xyflowApi = useXYStoreApi(), {
8638
+ viewId: pendingViewId,
8639
+ xyflowSynced,
8640
+ viewportChanged,
8641
+ waitCorrection,
8642
+ elFrom,
8643
+ elTo
8644
+ } = useDiagramState(selector$2), diagramApi = useDiagramStoreApi(), processedRef = useRef(pendingViewId);
8645
+ return useEffect(() => {
8646
+ if (!(!xyflowSynced || pendingViewId === processedRef.current)) {
8647
+ if (waitCorrection && elTo && elFrom) {
8648
+ const [x, y, zoom2] = xyflowApi.getState().transform, { xyflow, lastOnNavigate } = diagramApi.getState(), nextZoom = Math.min(
8649
+ elFrom.width / elTo.width,
8650
+ elFrom.height / elTo.height
8651
+ ), centerFrom = lastOnNavigate.elementCenterScreenPosition;
8652
+ nextZoom !== 1 && nextZoom < zoom2 && (xyflowApi.setState({ transform: [x, y, nextZoom] }), xyflow.setViewport({
8653
+ x,
8654
+ y,
8655
+ zoom: nextZoom
8656
+ }));
8657
+ const centerTo = xyflow.flowToScreenPosition({
8658
+ x: elTo.position[0] + elTo.width / 2,
8659
+ y: elTo.position[1] + elTo.height / 2
8660
+ }), diff = {
8661
+ x: toDomPrecision(centerFrom.x - centerTo.x),
8662
+ y: toDomPrecision(centerFrom.y - centerTo.y)
8663
+ };
8664
+ xyflowApi.getState().panBy(diff), diagramApi.setState({ lastOnNavigate: null });
8665
+ return;
8666
+ }
8667
+ processedRef.current = pendingViewId, diagramApi.getState().fitDiagram(xyflowApi);
8668
+ }
8669
+ }, [pendingViewId, xyflowSynced, waitCorrection]), !viewportChanged && xyflowSynced ? /* @__PURE__ */ jsx(FitViewOnViewportResize, { xyflowApi, diagramApi }) : null;
8670
+ }
8671
+ function SelectEdgesOnNodeFocus() {
8672
+ const focusedNodeId = useDiagramState((s) => s.focusedNodeId), diagramStore = useDiagramStoreApi(), xyflowApi = useXYStoreApi();
8673
+ return useUpdateEffect(() => {
8674
+ if (!focusedNodeId) {
8675
+ xyflowApi.getState().resetSelectedElements();
8676
+ return;
8677
+ }
8678
+ const edgeChanges = [], nodeChanges = [], { edgeLookup, nodeLookup, transform: transform2, triggerNodeChanges, fitView: fitView2, triggerEdgeChanges } = xyflowApi.getState(), fitViewNodes = /* @__PURE__ */ new Set();
8679
+ fitViewNodes.add(nonNullable(nodeLookup.get(focusedNodeId)));
8680
+ for (const [, edge] of edgeLookup)
8681
+ if (edge.source === focusedNodeId || edge.target === focusedNodeId) {
8682
+ edgeChanges.push({
8683
+ id: edge.id,
8684
+ type: "select",
8685
+ selected: !0
8686
+ });
8687
+ const anotherNode = nodeLookup.get(edge.source === focusedNodeId ? edge.target : edge.source);
8688
+ anotherNode && fitViewNodes.add(anotherNode);
8689
+ } else
8690
+ edge.selected && edgeChanges.push({
8691
+ id: edge.id,
8692
+ type: "select",
8693
+ selected: !1
8694
+ });
8695
+ for (const [, node] of nodeLookup)
8696
+ node.selected && node.id !== focusedNodeId && nodeChanges.push({
8697
+ id: node.id,
8698
+ type: "select",
8699
+ selected: !1
8700
+ });
8701
+ nodeChanges.push({
8702
+ id: focusedNodeId,
8703
+ type: "select",
8704
+ selected: !0
8705
+ }), edgeChanges.length > 0 && triggerEdgeChanges(edgeChanges), triggerNodeChanges(nodeChanges), fitView2({
8706
+ includeHiddenNodes: !0,
8707
+ duration: 300,
8708
+ padding: 0.1,
8709
+ minZoom: MinZoom,
8710
+ maxZoom: Math.max(1, transform2[2]),
8711
+ nodes: Array.from(fitViewNodes)
8712
+ });
8713
+ }, [diagramStore, xyflowApi, focusedNodeId]), null;
8714
+ }
8715
+ function SyncWithDiagram() {
8716
+ const xyflowSynced = useDiagramState((s) => s.xyflowSynced), xyflowApi = useXYStoreApi(), diagramStoreApi = useDiagramStoreApi();
8717
+ return useEffect(() => {
8718
+ if (xyflowSynced)
8719
+ return;
8720
+ const {
8721
+ view,
8722
+ nodesDraggable,
8723
+ nodesSelectable,
8724
+ focusedNodeId
8725
+ } = diagramStoreApi.getState(), updates = diagramViewToXYFlowData(view, {
8726
+ draggable: nodesDraggable,
8727
+ selectable: nodesSelectable || focusedNodeId !== null
8728
+ }), {
8729
+ nodeLookup,
8730
+ edgeLookup,
8731
+ setNodes,
8732
+ setEdges
8733
+ } = xyflowApi.getState();
8734
+ setNodes(updates.nodes.map((update) => {
8735
+ var _a;
8736
+ const existing = (_a = nodeLookup.get(update.id)) == null ? void 0 : _a.internals.userNode;
8737
+ return existing && existing.type === update.type && deepEqual(existing.parentId, update.parentId) ? deepEqual(existing.data.element, update.data.element) ? existing : {
8738
+ ...existing,
8739
+ ...update
8740
+ } : update;
8741
+ })), setEdges(updates.edges.map((update) => {
8742
+ const existing = edgeLookup.get(update.id);
8743
+ return existing ? deepEqual(existing.data.edge, update.data.edge) ? existing : {
8744
+ ...existing,
8745
+ ...update
8746
+ } : update;
8747
+ })), diagramStoreApi.setState(
8748
+ {
8749
+ xyflowSynced: !0
8750
+ },
8751
+ !1,
8752
+ "xyflowSynced"
8753
+ );
8754
+ }, [xyflowSynced, xyflowApi, diagramStoreApi]), null;
8012
8755
  }
8013
- const isSameNode = (a) => (b) => a.id === b.id && a.type === b.type && Object.is(a.parentId, b.parentId), SyncWithDiagram = memo(() => {
8014
- const _xyflow = useXYFlow(), xyflowRef = useRef(_xyflow);
8015
- xyflowRef.current = _xyflow;
8016
- const xyflowApi = useXYStoreApi(), diagramStoreApi = useDiagramStoreApi();
8017
- return useEffect(() => diagramStoreApi.subscribe(
8018
- // selector
8019
- (state) => ({
8020
- viewId: state.view.id,
8021
- nodes: state.view.nodes,
8022
- edges: state.view.edges
8023
- }),
8024
- // listener
8025
- ({ viewId, nodes, edges }) => {
8026
- const {
8027
- lastOnNavigate,
8028
- nodesDraggable,
8029
- nodesSelectable,
8030
- focusedNodeId
8031
- } = diagramStoreApi.getState(), updates = diagramViewToXYFlowData({ nodes, edges }, {
8032
- draggable: nodesDraggable,
8033
- selectable: nodesSelectable || focusedNodeId !== null
8034
- });
8035
- if (xyflowRef.current.setNodes(
8036
- (prev) => updates.nodes.map((update) => {
8037
- const existing = prev.find(isSameNode(update));
8038
- return existing ? deepEqual(existing.data.element, update.data.element) ? existing : {
8039
- ...existing,
8040
- ...update
8041
- } : update;
8042
- })
8043
- ), xyflowRef.current.setEdges(
8044
- (prev) => updates.edges.map((update) => {
8045
- const existing = prev.find((e) => e.id === update.id);
8046
- return existing ? deepEqual(existing.data, update.data) ? existing : {
8047
- ...existing,
8048
- ...update
8049
- } : update;
8050
- })
8051
- ), (lastOnNavigate == null ? void 0 : lastOnNavigate.toView) === viewId && lastOnNavigate.positionCorrected !== !0) {
8052
- const elFrom = lastOnNavigate.element, elTo = nodes.find((n) => n.id === elFrom.id);
8053
- if (elTo) {
8054
- const centerFrom = lastOnNavigate.elementCenterScreenPosition;
8055
- let nextZoom = Math.min(elFrom.width / elTo.width, elFrom.height / elTo.height);
8056
- requestAnimationFrame(() => {
8057
- requestAnimationFrame(() => {
8058
- const v = xyflowRef.current.getViewport();
8059
- nextZoom < v.zoom && (nextZoom = Math.max(nextZoom, v.zoom * 0.5), xyflowRef.current.setViewport({
8060
- x: v.x,
8061
- y: v.y,
8062
- zoom: nextZoom
8063
- }));
8064
- const centerTo = xyflowRef.current.flowToScreenPosition({
8065
- x: elTo.position[0] + elTo.width / 2,
8066
- y: elTo.position[1] + elTo.height / 2
8067
- }), diff = {
8068
- x: toDomPrecision(centerFrom.x - centerTo.x),
8069
- y: toDomPrecision(centerFrom.y - centerTo.y)
8070
- };
8071
- xyflowApi.getState().panBy(diff);
8072
- });
8073
- });
8074
- }
8075
- diagramStoreApi.setState(
8076
- {
8077
- lastOnNavigate: {
8078
- ...lastOnNavigate,
8079
- positionCorrected: !0
8080
- }
8081
- },
8082
- !1,
8083
- "positionCorrected"
8084
- );
8085
- }
8086
- },
8087
- {
8088
- equalityFn: shallowEqual
8089
- }
8090
- ), [xyflowApi, diagramStoreApi]), null;
8091
- });
8092
8756
  function getVarName(variable) {
8093
8757
  var matches = variable.match(/^var\((.*)\)$/);
8094
8758
  return matches ? matches[1] : variable;
@@ -8134,7 +8798,14 @@ function assignInlineVars(varsOrContract, tokens) {
8134
8798
  writable: !1
8135
8799
  }), styles;
8136
8800
  }
8137
- var container$2 = "bexn7q1", edgePathBg = "bexn7q2", fillStrokeCtx = "bexn7q3", cssEdgePath = "bexn7q6", varLabelX = "var(--bexn7q7)", varLabelY = "var(--bexn7q8)", edgeLabel = "bexn7qa", edgeLabelBody = "bexn7qb";
8801
+ var container$4 = "bexn7q1", dimmed$2 = "bexn7q2", edgePathBg = "bexn7q3", markerContext = "bexn7q4", controlPoint = "bexn7q5", cssEdgePath = "bexn7q7", varLabelX = "var(--bexn7q8)", varLabelY = "var(--bexn7q9)", edgeLabel = "bexn7qb", stepEdgeNumber = "bexn7qc", edgeLabelText = "bexn7qd";
8802
+ function getNodeIntersectionFromCenterToPoint(intersectionNode, [x1, y1]) {
8803
+ const {
8804
+ width: intersectionNodeWidth,
8805
+ height: intersectionNodeHeight
8806
+ } = getNodeDimensions(intersectionNode), intersectionNodePosition = intersectionNode.internals.positionAbsolute, w = intersectionNodeWidth / 2, h = intersectionNodeHeight / 2, x2 = intersectionNodePosition.x + w, y2 = intersectionNodePosition.y + h, xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h), yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h), a = 1 / (Math.abs(xx1) + Math.abs(yy1)), xx3 = a * xx1, yy3 = a * yy1, x = w * (xx3 + yy3) + x2, y = h * (-xx3 + yy3) + y2;
8807
+ return [x, y];
8808
+ }
8138
8809
  function getNodeIntersection(intersectionNode, targetNode) {
8139
8810
  const {
8140
8811
  width: intersectionNodeWidth,
@@ -8196,7 +8867,9 @@ function bezierPath(bezierSpline) {
8196
8867
  }
8197
8868
  return invariant(points.length === 0, "all points should be consumed"), path;
8198
8869
  }
8199
- const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, by]) => isSamePoint(a.x, bx) && isSamePoint(a.y, by), isEqualProps = (prev, next) => prev.id === next.id && prev.source === next.source && prev.target === next.target && deepEqual(prev.selected ?? !1, next.selected ?? !1) && isSamePoint(prev.sourceX, next.sourceX) && isSamePoint(prev.sourceY, next.sourceY) && isSamePoint(prev.targetX, next.targetX) && isSamePoint(prev.targetY, next.targetY) && deepEqual(prev.data, next.data), curve = line().curve(curveCatmullRomOpen.alpha(1)), RelationshipEdge = /* @__PURE__ */ memo(function({
8870
+ const isSamePoint = (a, b) => Math.abs(a - b) < 3.1, isSamePosition = (a, [bx, by]) => isSamePoint(a.x, bx) && isSamePoint(a.y, by), isEqualProps = (prev, next) => prev.id === next.id && prev.source === next.source && prev.target === next.target && deepEqual(prev.selected ?? !1, next.selected ?? !1) && isSamePoint(prev.sourceX, next.sourceX) && isSamePoint(prev.sourceY, next.sourceY) && isSamePoint(prev.targetX, next.targetX) && isSamePoint(prev.targetY, next.targetY) && deepEqual(prev.data.stepNum, next.data.stepNum) && deepEqual(prev.data.edge, next.data.edge) && zip(prev.data.controlPoints, next.data.controlPoints).every(
8871
+ ([a, b]) => isSamePoint(a[0], b[0]) && isSamePoint(a[1], b[1])
8872
+ ), curve = line().curve(curveCatmullRomOpen), RelationshipEdge = /* @__PURE__ */ memo(function({
8200
8873
  id: id2,
8201
8874
  data,
8202
8875
  selected: _selected,
@@ -8205,13 +8878,17 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
8205
8878
  target,
8206
8879
  interactionWidth
8207
8880
  }) {
8208
- var _a, _b, _c;
8209
- const { nodeLookup, edgeLookup } = useXYStoreApi().getState(), sourceNode = nonNullable(nodeLookup.get(source), `source node ${source} not found`), targetNode = nonNullable(nodeLookup.get(target), `target node ${target} not found`), isNotModified = isSamePosition(sourceNode.internals.positionAbsolute, sourceNode.data.element.position) && isSamePosition(targetNode.internals.positionAbsolute, targetNode.data.element.position), { edge: diagramEdge, controlPoints } = data, color2 = diagramEdge.color ?? "gray", isHovered = useDiagramState((s) => s.hoveredEdgeId === id2), line2 = diagramEdge.line ?? "dashed", isDotted = line2 === "dotted", isDashed = isDotted || line2 === "dashed";
8881
+ var _a, _b, _c, _d;
8882
+ const { nodeLookup, edgeLookup } = useXYStoreApi().getState(), sourceNode = nonNullable(nodeLookup.get(source), `source node ${source} not found`), targetNode = nonNullable(nodeLookup.get(target), `target node ${target} not found`), isModified = !isSamePosition(sourceNode.internals.positionAbsolute, sourceNode.data.element.position) || !isSamePosition(targetNode.internals.positionAbsolute, targetNode.data.element.position), { edge: diagramEdge, controlPoints } = data, color2 = diagramEdge.color ?? "gray", isStepEdge = data.stepNum !== null, { isActive, isHovered, isDimmed } = useDiagramState((s) => ({
8883
+ isActive: s.activeDynamicViewStep !== null && s.activeDynamicViewStep === data.stepNum,
8884
+ isHovered: s.hoveredEdgeId === id2,
8885
+ isDimmed: s.dimmed.has(id2)
8886
+ })), line2 = diagramEdge.line ?? "dashed", isDotted = line2 === "dotted", isDashed = isDotted || line2 === "dashed";
8210
8887
  let strokeDasharray;
8211
8888
  isDotted ? strokeDasharray = "1,8" : isDashed && (strokeDasharray = "8,10");
8212
8889
  const marker = `url(#arrow-${id2})`;
8213
8890
  let edgePath, labelX, labelY;
8214
- if (isNotModified)
8891
+ if (!isModified)
8215
8892
  edgePath = bezierPath(diagramEdge.points), labelX = ((_a = data.label) == null ? void 0 : _a.bbox.x) ?? 0, labelY = ((_b = data.label) == null ? void 0 : _b.bbox.y) ?? 0;
8216
8893
  else {
8217
8894
  const { sx, sy, tx, ty, sourcePos, targetPos } = getEdgeParams(sourceNode, targetNode), [_edgePath, _labelX, _labelY] = getBezierPath({
@@ -8226,59 +8903,92 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 2.1, isSamePosition = (a, [bx, b
8226
8903
  const sourceCenterPos = getNodePositionWithOrigin(sourceNode, [-0.5, -0.5]), targetCenterPos = getNodePositionWithOrigin(targetNode, [-0.5, -0.5]);
8227
8904
  edgePath = curve([
8228
8905
  [sourceCenterPos.positionAbsolute.x, sourceCenterPos.positionAbsolute.y],
8229
- [sx, sy],
8906
+ getNodeIntersectionFromCenterToPoint(sourceNode, first(controlPoints)),
8230
8907
  ...controlPoints,
8231
- [tx, ty],
8908
+ getNodeIntersectionFromCenterToPoint(targetNode, last(controlPoints)),
8232
8909
  [targetCenterPos.positionAbsolute.x, targetCenterPos.positionAbsolute.y]
8233
8910
  ]);
8234
8911
  }
8235
- return /* @__PURE__ */ jsxs("g", { className: clsx(container$2), "data-likec4-color": color2, "data-edge-hovered": isHovered, children: [
8236
- /* @__PURE__ */ jsx("g", { className: clsx(fillStrokeCtx), children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
8237
- "marker",
8238
- {
8239
- id: `arrow-${id2}`,
8240
- viewBox: "0 0 10 8",
8241
- refX: "0",
8242
- refY: "4",
8243
- markerWidth: "5",
8244
- markerHeight: "5",
8245
- markerUnits: "strokeWidth",
8246
- preserveAspectRatio: "xMaxYMid meet",
8247
- orient: "auto-start-reverse",
8248
- children: /* @__PURE__ */ jsx("path", { d: "M 0 0 L 10 4 L 0 8 z", stroke: "context-stroke", fill: "context-stroke" })
8249
- }
8250
- ) }) }),
8251
- /* @__PURE__ */ jsx(
8252
- RelationshipPath,
8253
- {
8254
- edgePath,
8255
- interactionWidth: interactionWidth ?? 10,
8256
- strokeDasharray,
8257
- markerStart: diagramEdge.tailArrow ? marker : void 0,
8258
- markerEnd: diagramEdge.headArrow ? marker : void 0,
8259
- style: style2
8260
- }
8261
- ),
8262
- data.label && /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsx(
8263
- Box,
8264
- {
8265
- className: clsx(container$2, edgeLabel),
8266
- "data-likec4-color": color2,
8267
- style: {
8268
- ...assignInlineVars({
8269
- [varLabelX]: toDomPrecision(labelX) + "px",
8270
- [varLabelY]: toDomPrecision(labelY) + "px"
8271
- }),
8272
- maxWidth: data.label.bbox.width + 10,
8273
- zIndex: ((_c = edgeLookup.get(id2)) == null ? void 0 : _c.zIndex) ?? ZIndexes.Edge
8274
- },
8275
- mod: {
8276
- "data-edge-hovered": isHovered
8277
- },
8278
- children: /* @__PURE__ */ jsx(Box, { className: edgeLabelBody, children: data.label.text })
8279
- }
8280
- ) })
8281
- ] });
8912
+ return /* @__PURE__ */ jsxs(
8913
+ "g",
8914
+ {
8915
+ className: clsx([
8916
+ container$4,
8917
+ isDimmed && dimmed$2
8918
+ ]),
8919
+ "data-likec4-color": color2,
8920
+ "data-edge-dir": diagramEdge.dir,
8921
+ "data-edge-active": isActive,
8922
+ "data-edge-hovered": isHovered,
8923
+ children: [
8924
+ /* @__PURE__ */ jsx("g", { className: markerContext, children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
8925
+ "marker",
8926
+ {
8927
+ id: `arrow-${id2}`,
8928
+ viewBox: "0 0 16 10",
8929
+ refX: isModified ? "12" : "10",
8930
+ refY: "5",
8931
+ markerWidth: "5",
8932
+ markerHeight: "4",
8933
+ markerUnits: "strokeWidth",
8934
+ preserveAspectRatio: "xMaxYMid meet",
8935
+ orient: "auto-start-reverse",
8936
+ children: /* @__PURE__ */ jsx("path", { d: "M 0 0 L 16 5 L 0 10 z", stroke: "context-stroke", fill: "context-stroke" })
8937
+ }
8938
+ ) }) }),
8939
+ /* @__PURE__ */ jsx(
8940
+ RelationshipPath,
8941
+ {
8942
+ edgePath,
8943
+ interactionWidth: interactionWidth ?? 10,
8944
+ strokeDasharray,
8945
+ markerStart: diagramEdge.tailArrow ? marker : void 0,
8946
+ markerEnd: diagramEdge.headArrow ? marker : void 0,
8947
+ style: style2
8948
+ }
8949
+ ),
8950
+ isModified && controlPoints.map((p, i) => /* @__PURE__ */ jsx(
8951
+ "circle",
8952
+ {
8953
+ className: controlPoint,
8954
+ cx: p[0],
8955
+ cy: p[1],
8956
+ r: 3
8957
+ },
8958
+ i
8959
+ )),
8960
+ (data.label || isStepEdge) && /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: /* @__PURE__ */ jsxs(
8961
+ Box,
8962
+ {
8963
+ className: clsx([
8964
+ container$4,
8965
+ edgeLabel,
8966
+ isDimmed && dimmed$2
8967
+ ]),
8968
+ "data-likec4-color": color2,
8969
+ style: {
8970
+ ...assignInlineVars({
8971
+ [varLabelX]: Math.floor(labelX) + "px",
8972
+ [varLabelY]: Math.floor(labelY) + "px"
8973
+ }),
8974
+ ...data.label && {
8975
+ maxWidth: data.label.bbox.width + 12
8976
+ },
8977
+ zIndex: ((_c = edgeLookup.get(id2)) == null ? void 0 : _c.zIndex) ?? ZIndexes.Edge
8978
+ },
8979
+ mod: {
8980
+ "data-edge-hovered": isHovered,
8981
+ "data-edge-active": isActive
8982
+ },
8983
+ children: [
8984
+ isStepEdge && /* @__PURE__ */ jsx(Box, { className: stepEdgeNumber, children: data.stepNum }),
8985
+ ((_d = data.label) == null ? void 0 : _d.text) && /* @__PURE__ */ jsx(Box, { className: edgeLabelText, children: data.label.text })
8986
+ ]
8987
+ }
8988
+ ) })
8989
+ ]
8990
+ }
8991
+ );
8282
8992
  }, isEqualProps), RelationshipPath = ({
8283
8993
  edgePath,
8284
8994
  interactionWidth,
@@ -8371,6 +9081,7 @@ function NavigateToBtn({ xynodeId, className }) {
8371
9081
  {
8372
9082
  className: clsx("nodrag nopan", className),
8373
9083
  radius: "xl",
9084
+ onPointerDownCapture: (e) => e.stopPropagation(),
8374
9085
  onClick: (event) => {
8375
9086
  event.stopPropagation(), diagramApi.getState().triggerOnNavigateTo(xynodeId, event);
8376
9087
  },
@@ -8379,27 +9090,29 @@ function NavigateToBtn({ xynodeId, className }) {
8379
9090
  }
8380
9091
  );
8381
9092
  }
8382
- var container$1 = "lbtzdo0", varTransparency = "var(--lbtzdo1)", compoundBody = "lbtzdo2", transparent = "lbtzdo5", title$1 = "lbtzdo6", indicator$1 = "lbtzdoa", navigateBtn = "lbtzdoc";
9093
+ var container$3 = "lbtzdo0", dimmed$1 = "lbtzdo1", varTransparency = "var(--lbtzdo2)", compoundBody = "lbtzdo3", transparent = "lbtzdo6", title$2 = "lbtzdo7", indicator$1 = "lbtzdob", navigateBtn = "lbtzdod";
8383
9094
  const CompoundNodeMemo = /* @__PURE__ */ memo(function({
8384
9095
  id: id2,
8385
9096
  data: {
8386
- element
9097
+ element: element2
8387
9098
  }
8388
9099
  }) {
8389
- const { color: color2, style: style2, depth = 1, ...compound } = element, opacity = style2.opacity ?? 100, { isHovered, hasOnNavigateTo } = useDiagramState((s) => ({
9100
+ const { color: color2, style: style2, depth = 1, ...compound } = element2, opacity = style2.opacity ?? 100, { isHovered, isDimmed, hasOnNavigateTo } = useDiagramState((s) => ({
8390
9101
  isHovered: s.hoveredNodeId === id2,
9102
+ isDimmed: s.dimmed.has(id2),
8391
9103
  hasOnNavigateTo: !!s.onNavigateTo
8392
9104
  })), isnavigable = !!compound.navigateTo && hasOnNavigateTo, transparency = clamp$1(100 - opacity, {
8393
9105
  min: 0,
8394
- max: 98
9106
+ max: 99
8395
9107
  });
8396
9108
  return /* @__PURE__ */ jsxs(
8397
9109
  Box,
8398
9110
  {
8399
9111
  className: clsx(
8400
- container$1,
9112
+ container$3,
8401
9113
  "likec4-compound-node",
8402
- opacity < 100 && "likec4-compound-transparent"
9114
+ opacity < 100 && "likec4-compound-transparent",
9115
+ isDimmed && dimmed$1
8403
9116
  ),
8404
9117
  mod: {
8405
9118
  "compound-depth": depth,
@@ -8441,7 +9154,7 @@ const CompoundNodeMemo = /* @__PURE__ */ memo(function({
8441
9154
  Text,
8442
9155
  {
8443
9156
  component: "div",
8444
- className: clsx(title$1, "likec4-compound-title"),
9157
+ className: clsx(title$2, "likec4-compound-title"),
8445
9158
  children: compound.title
8446
9159
  }
8447
9160
  )
@@ -8460,7 +9173,7 @@ const CompoundNodeMemo = /* @__PURE__ */ memo(function({
8460
9173
  }
8461
9174
  );
8462
9175
  });
8463
- var container = "_1b6tkn2", indicator = "_1b6tkn4", fillElementFill = "_1b6tkn5", fillMixStroke = "_1b6tkn7", title = "_1b6tkn8", description = "_1b6tkn9", technology = "_1b6tkna", cssElement = "_1b6tknb", iconMaxH = "var(--_1b6tknc)", elementIcon = "_1b6tknd", cssShapeSvg = "_1b6tkng", cssNavigateBtn = "_1b6tknh";
9176
+ var container$2 = "_1b6tkn2", dimmed = "_1b6tkn3", indicator = "_1b6tkn5", fillElementFill = "_1b6tkn6", fillMixStroke = "_1b6tkn8", title$1 = "_1b6tkn9", description$1 = "_1b6tkna", technology = "_1b6tknb", element = "_1b6tknc", iconMaxH = "var(--_1b6tknd)", elementIcon = "_1b6tkne", cssShapeSvg = "_1b6tknh", cssNavigateBtn = "_1b6tkni";
8464
9177
  function ElementIcon({
8465
9178
  node,
8466
9179
  paddingY = 32
@@ -8490,9 +9203,9 @@ function ElementIcon({
8490
9203
  }
8491
9204
  var elementLink = "_4ysv0o0", trigger = "_4ysv0o1";
8492
9205
  function ElementLink({
8493
- element
9206
+ element: element2
8494
9207
  }) {
8495
- invariant(element.links, "ElementLink: links are required");
9208
+ invariant(element2.links, "ElementLink: links are required");
8496
9209
  const id2 = useId();
8497
9210
  return /* @__PURE__ */ jsx("div", { className: elementLink, "data-likec4-linkid": id2, children: /* @__PURE__ */ jsxs(
8498
9211
  HoverCard,
@@ -8526,10 +9239,28 @@ function ElementLink({
8526
9239
  ]
8527
9240
  }
8528
9241
  ) }),
8529
- /* @__PURE__ */ jsx(HoverCardDropdown, { onClick: (e) => e.stopPropagation(), p: "xs", children: /* @__PURE__ */ jsx(Stack, { gap: "xs", children: element.links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", gap: "sm", children: [
8530
- /* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "clip", maxWidth: clamp$1(element.width, { min: 200, max: 400 }) }, children: /* @__PURE__ */ jsx(Anchor, { href: link, target: "_blank", fz: "13", truncate: "end", children: link }) }),
8531
- /* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Button, { size: "compact-xs", fz: "12", onClick: copy, color: copied ? "teal" : "gray", children: copied ? "Copied" : "Copy" }) })
8532
- ] }, link)) }) })
9242
+ /* @__PURE__ */ jsx(
9243
+ HoverCardDropdown,
9244
+ {
9245
+ onPointerDownCapture: (e) => e.stopPropagation(),
9246
+ onClick: (e) => e.stopPropagation(),
9247
+ p: "xs",
9248
+ children: /* @__PURE__ */ jsx(Stack, { gap: "xs", children: element2.links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", gap: "sm", children: [
9249
+ /* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "clip", maxWidth: clamp$1(element2.width, { min: 200, max: 400 }) }, children: /* @__PURE__ */ jsx(Anchor, { href: link, target: "_blank", fz: "13", truncate: "end", children: link }) }),
9250
+ /* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(
9251
+ Button,
9252
+ {
9253
+ size: "compact-xs",
9254
+ fz: "10",
9255
+ variant: "light",
9256
+ onClick: copy,
9257
+ color: copied ? "teal" : "gray",
9258
+ children: copied ? "copied" : "copy"
9259
+ }
9260
+ ) })
9261
+ ] }, link)) })
9262
+ }
9263
+ )
8533
9264
  ]
8534
9265
  }
8535
9266
  ) });
@@ -8580,551 +9311,1004 @@ function ElementShapeSvg({ shape, w, h }) {
8580
9311
  strokeWidth: 0
8581
9312
  }
8582
9313
  ),
8583
- /* @__PURE__ */ jsxs("g", { className: fillElementFill, strokeWidth: 0, children: [
8584
- /* @__PURE__ */ jsx("circle", { cx: 17, cy: h / 2, r: 12 }),
8585
- /* @__PURE__ */ jsx("rect", { x: 33, y: 12, width: w - 44, height: h - 24, rx: 5 })
8586
- ] })
8587
- ] });
8588
- case "browser":
8589
- return /* @__PURE__ */ jsxs(Fragment, { children: [
8590
- /* @__PURE__ */ jsx(
8591
- "rect",
9314
+ /* @__PURE__ */ jsxs("g", { className: fillElementFill, strokeWidth: 0, children: [
9315
+ /* @__PURE__ */ jsx("circle", { cx: 17, cy: h / 2, r: 12 }),
9316
+ /* @__PURE__ */ jsx("rect", { x: 33, y: 12, width: w - 44, height: h - 24, rx: 5 })
9317
+ ] })
9318
+ ] });
9319
+ case "browser":
9320
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9321
+ /* @__PURE__ */ jsx(
9322
+ "rect",
9323
+ {
9324
+ width: w,
9325
+ height: h,
9326
+ rx: 6,
9327
+ className: fillMixStroke,
9328
+ strokeWidth: 0
9329
+ }
9330
+ ),
9331
+ /* @__PURE__ */ jsxs("g", { className: fillElementFill, strokeWidth: 0, children: [
9332
+ /* @__PURE__ */ jsx("circle", { cx: 16, cy: 17, r: 7 }),
9333
+ /* @__PURE__ */ jsx("circle", { cx: 36, cy: 17, r: 7 }),
9334
+ /* @__PURE__ */ jsx("circle", { cx: 56, cy: 17, r: 7 }),
9335
+ /* @__PURE__ */ jsx("rect", { x: 70, y: 8, width: w - 80, height: 17, rx: 4 }),
9336
+ /* @__PURE__ */ jsx("rect", { x: 10, y: 32, width: w - 20, height: h - 42, rx: 4 })
9337
+ ] })
9338
+ ] });
9339
+ case "person":
9340
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9341
+ /* @__PURE__ */ jsx(
9342
+ "rect",
9343
+ {
9344
+ width: w,
9345
+ height: h,
9346
+ rx: 6,
9347
+ strokeWidth: 0
9348
+ }
9349
+ ),
9350
+ /* @__PURE__ */ jsx(
9351
+ "svg",
9352
+ {
9353
+ x: w - PersonIcon.width - 6,
9354
+ y: h - PersonIcon.height,
9355
+ width: PersonIcon.width,
9356
+ height: PersonIcon.height,
9357
+ viewBox: `0 0 ${PersonIcon.width} ${PersonIcon.height}`,
9358
+ className: fillMixStroke,
9359
+ children: /* @__PURE__ */ jsx(
9360
+ "path",
9361
+ {
9362
+ strokeWidth: 0,
9363
+ d: PersonIcon.path
9364
+ }
9365
+ )
9366
+ }
9367
+ )
9368
+ ] });
9369
+ case "queue": {
9370
+ const { path, rx, ry } = queueSVGPath(w, h);
9371
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9372
+ /* @__PURE__ */ jsx("path", { d: path, strokeWidth: 2 }),
9373
+ /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: ry, ry: ry - 0.75, rx, className: fillMixStroke, strokeWidth: 2 })
9374
+ ] });
9375
+ }
9376
+ case "storage":
9377
+ case "cylinder": {
9378
+ const { path, rx, ry } = cylinderSVGPath(w, h);
9379
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
9380
+ /* @__PURE__ */ jsx("path", { d: path, strokeWidth: 2 }),
9381
+ /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: ry, ry, rx: rx - 0.75, className: fillMixStroke, strokeWidth: 2 })
9382
+ ] });
9383
+ }
9384
+ case "rectangle":
9385
+ return /* @__PURE__ */ jsx(
9386
+ "rect",
9387
+ {
9388
+ width: w,
9389
+ height: h,
9390
+ rx: 6,
9391
+ strokeWidth: 0
9392
+ }
9393
+ );
9394
+ default:
9395
+ return nonexhaustive(shape);
9396
+ }
9397
+ }
9398
+ function SelectedIndicator({ shape, w, h }) {
9399
+ switch (shape) {
9400
+ case "queue":
9401
+ return /* @__PURE__ */ jsx("path", { d: queueSVGPath(w, h).path });
9402
+ case "storage":
9403
+ case "cylinder":
9404
+ return /* @__PURE__ */ jsx("path", { d: cylinderSVGPath(w, h).path });
9405
+ default:
9406
+ return /* @__PURE__ */ jsx(
9407
+ "rect",
9408
+ {
9409
+ x: -1,
9410
+ y: -1,
9411
+ width: w + 2,
9412
+ height: h + 2,
9413
+ rx: 6
9414
+ }
9415
+ );
9416
+ }
9417
+ }
9418
+ const selectedScale = 1.015, variants = {
9419
+ idle: (_, { scale }) => ({
9420
+ scale: 1,
9421
+ transition: {
9422
+ delay: isNumber(scale) && scale > selectedScale ? 0.075 : 0
9423
+ }
9424
+ }),
9425
+ selected: (_, { scale }) => ({
9426
+ scale: selectedScale,
9427
+ transition: {
9428
+ delay: isNumber(scale) && scale > selectedScale ? 0.075 : 0
9429
+ }
9430
+ }),
9431
+ // dimmed: {
9432
+ // filter: 'brightness(0.5)',
9433
+ // transition: {
9434
+ // duration: 0.8,
9435
+ // ease: 'easeInOut',
9436
+ // }
9437
+ // },
9438
+ // dragging: {
9439
+ // scale: selectedScale
9440
+ // },
9441
+ // hovered: {
9442
+ // scale: 1.08
9443
+ // },
9444
+ // hover: (_, {scale}) => isNumber(scale) && scale < 1.02 ? ({
9445
+ // scale: 1.08,
9446
+ // }) : ({
9447
+ // scale: 1.08,
9448
+ // transition: {
9449
+ // delay: 1
9450
+ // }
9451
+ // }),
9452
+ hovered: (_, { scale }) => ({
9453
+ scale: 1.06,
9454
+ transition: {
9455
+ delay: isNumber(scale) && scale !== 1 && scale !== selectedScale ? 0 : 0.15
9456
+ }
9457
+ }),
9458
+ tap: {
9459
+ scale: 0.975
9460
+ }
9461
+ // tap: {
9462
+ // scale: 0.9
9463
+ // }
9464
+ };
9465
+ function ElementNode({
9466
+ id: id2,
9467
+ data: {
9468
+ element: element$1
9469
+ },
9470
+ dragging,
9471
+ selected: selected2 = !1,
9472
+ width,
9473
+ height
9474
+ }) {
9475
+ const { isHovered, isDimmed, hasOnNavigateTo, isHovercards, isInteractive } = useDiagramState((s) => ({
9476
+ isHovered: s.hoveredNodeId === id2,
9477
+ isDimmed: s.dimmed.has(id2),
9478
+ isInteractive: s.nodesDraggable || s.nodesSelectable || !!s.onNavigateTo,
9479
+ isHovercards: s.showElementLinks,
9480
+ hasOnNavigateTo: !!s.onNavigateTo
9481
+ })), isNavigable = hasOnNavigateTo && !!element$1.navigateTo, w = toDomPrecision(width ?? element$1.width), h = toDomPrecision(height ?? element$1.height);
9482
+ let animate = "idle";
9483
+ switch (!0) {
9484
+ case (dragging && selected2):
9485
+ animate = "selected";
9486
+ break;
9487
+ case dragging:
9488
+ animate = "idle";
9489
+ break;
9490
+ case (isInteractive && isHovered):
9491
+ animate = "hovered";
9492
+ break;
9493
+ case selected2:
9494
+ animate = "selected";
9495
+ break;
9496
+ }
9497
+ return /* @__PURE__ */ jsxs(
9498
+ motion.div,
9499
+ {
9500
+ id: id2,
9501
+ className: clsx([
9502
+ container$2,
9503
+ isDimmed && dimmed,
9504
+ "likec4-element-node"
9505
+ ]),
9506
+ "data-likec4-color": element$1.color,
9507
+ "data-likec4-shape": element$1.shape,
9508
+ variants,
9509
+ initial: !1,
9510
+ animate,
9511
+ ...isInteractive && {
9512
+ whileTap: dragging ? animate : "tap"
9513
+ },
9514
+ children: [
9515
+ /* @__PURE__ */ jsx(
9516
+ Handle,
9517
+ {
9518
+ type: "target",
9519
+ position: Position.Top,
9520
+ style: { visibility: "hidden" }
9521
+ }
9522
+ ),
9523
+ /* @__PURE__ */ jsxs(
9524
+ "svg",
8592
9525
  {
9526
+ className: clsx(
9527
+ cssShapeSvg
9528
+ ),
9529
+ viewBox: `0 0 ${w} ${h}`,
8593
9530
  width: w,
8594
9531
  height: h,
8595
- rx: 6,
8596
- className: fillMixStroke,
8597
- strokeWidth: 0
9532
+ children: [
9533
+ /* @__PURE__ */ jsx("g", { className: indicator, children: /* @__PURE__ */ jsx(
9534
+ SelectedIndicator,
9535
+ {
9536
+ shape: element$1.shape,
9537
+ w,
9538
+ h
9539
+ }
9540
+ ) }),
9541
+ /* @__PURE__ */ jsx(
9542
+ ElementShapeSvg,
9543
+ {
9544
+ shape: element$1.shape,
9545
+ w,
9546
+ h
9547
+ }
9548
+ )
9549
+ ]
8598
9550
  }
8599
9551
  ),
8600
- /* @__PURE__ */ jsxs("g", { className: fillElementFill, strokeWidth: 0, children: [
8601
- /* @__PURE__ */ jsx("circle", { cx: 16, cy: 17, r: 7 }),
8602
- /* @__PURE__ */ jsx("circle", { cx: 36, cy: 17, r: 7 }),
8603
- /* @__PURE__ */ jsx("circle", { cx: 56, cy: 17, r: 7 }),
8604
- /* @__PURE__ */ jsx("rect", { x: 70, y: 8, width: w - 80, height: 17, rx: 4 }),
8605
- /* @__PURE__ */ jsx("rect", { x: 10, y: 32, width: w - 20, height: h - 42, rx: 4 })
8606
- ] })
8607
- ] });
8608
- case "person":
8609
- return /* @__PURE__ */ jsxs(Fragment, { children: [
9552
+ /* @__PURE__ */ jsxs("div", { className: clsx(element, "likec4-element"), children: [
9553
+ element$1.icon && /* @__PURE__ */ jsx(ElementIcon, { node: element$1 }),
9554
+ /* @__PURE__ */ jsx(
9555
+ Text,
9556
+ {
9557
+ component: "div",
9558
+ className: clsx(title$1, "likec4-element-title"),
9559
+ children: element$1.title
9560
+ }
9561
+ ),
9562
+ element$1.technology && /* @__PURE__ */ jsx(
9563
+ Text,
9564
+ {
9565
+ component: "div",
9566
+ className: clsx(technology, "likec4-element-technology"),
9567
+ children: element$1.technology
9568
+ }
9569
+ ),
9570
+ element$1.description && /* @__PURE__ */ jsx(
9571
+ Text,
9572
+ {
9573
+ component: "div",
9574
+ className: clsx(description$1, "likec4-element-description"),
9575
+ children: element$1.description
9576
+ }
9577
+ )
9578
+ ] }),
8610
9579
  /* @__PURE__ */ jsx(
8611
- "rect",
9580
+ Handle,
8612
9581
  {
8613
- width: w,
8614
- height: h,
8615
- rx: 6,
8616
- strokeWidth: 0
9582
+ type: "source",
9583
+ position: Position.Bottom,
9584
+ style: { visibility: "hidden" }
8617
9585
  }
8618
9586
  ),
8619
- /* @__PURE__ */ jsx(
8620
- "svg",
9587
+ isHovercards && element$1.links && /* @__PURE__ */ jsx(ElementLink, { element: element$1 }),
9588
+ isNavigable && /* @__PURE__ */ jsx(NavigateToBtn, { xynodeId: id2, className: cssNavigateBtn })
9589
+ ]
9590
+ }
9591
+ );
9592
+ }
9593
+ function literalToEnum(value) {
9594
+ switch (value) {
9595
+ case "dots":
9596
+ return BackgroundVariant.Dots;
9597
+ case "lines":
9598
+ return BackgroundVariant.Lines;
9599
+ case "cross":
9600
+ return BackgroundVariant.Cross;
9601
+ default:
9602
+ nonexhaustive(value);
9603
+ }
9604
+ }
9605
+ function XYFlowBackground({ background }) {
9606
+ if (typeof background == "string")
9607
+ return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(background) });
9608
+ const { variant, ...rest } = background;
9609
+ return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(variant), ...rest });
9610
+ }
9611
+ function useXYFlowEvents() {
9612
+ const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), dblclickTimeout = useRef(), dbclickLock = () => dblclickTimeout.current !== void 0 ? !0 : (dblclickTimeout.current = window.setTimeout(() => {
9613
+ dblclickTimeout.current = void 0;
9614
+ }, 250), !1), hoveredNodeFromOnEdgeEnterRef = useRef("");
9615
+ return useMemo(() => ({
9616
+ onDoubleClick: (event) => {
9617
+ const {
9618
+ fitViewEnabled,
9619
+ onCanvasDblClick,
9620
+ resetLastClicked,
9621
+ fitDiagram
9622
+ } = diagramApi.getState();
9623
+ fitViewEnabled && (fitDiagram(xyflowApi), onCanvasDblClick || event.stopPropagation()), resetLastClicked(), onCanvasDblClick == null || onCanvasDblClick(event);
9624
+ },
9625
+ onPaneClick: (event) => {
9626
+ if (dbclickLock())
9627
+ return;
9628
+ const { focusedNodeId, fitDiagram, onCanvasClick, resetLastClicked } = diagramApi.getState();
9629
+ focusedNodeId && (fitDiagram(xyflowApi), onCanvasClick || event.stopPropagation()), resetLastClicked(), onCanvasClick == null || onCanvasClick(event);
9630
+ },
9631
+ onNodeContextMenu: (event, xynode) => {
9632
+ var _a, _b;
9633
+ diagramApi.getState().setLastClickedNode(xynode.id), (_b = (_a = diagramApi.getState()).onNodeContextMenu) == null || _b.call(_a, {
9634
+ element: xynode.data.element,
9635
+ xynode,
9636
+ event
9637
+ });
9638
+ },
9639
+ onPaneContextMenu: (event) => {
9640
+ var _a, _b;
9641
+ diagramApi.getState().resetLastClicked(), (_b = (_a = diagramApi.getState()).onCanvasContextMenu) == null || _b.call(_a, event);
9642
+ },
9643
+ onEdgeContextMenu: (event, xyedge) => {
9644
+ var _a, _b;
9645
+ diagramApi.getState().setLastClickedEdge(xyedge.id), (_b = (_a = diagramApi.getState()).onEdgeContextMenu) == null || _b.call(_a, {
9646
+ relation: xyedge.data.edge,
9647
+ xyedge,
9648
+ event
9649
+ });
9650
+ },
9651
+ onNodeClick: (event, xynode) => {
9652
+ const {
9653
+ focusedNodeId,
9654
+ focusOnNode,
9655
+ onNodeClick,
9656
+ setLastClickedNode
9657
+ } = diagramApi.getState();
9658
+ setLastClickedNode(xynode.id), focusedNodeId && focusedNodeId !== xynode.id && (focusOnNode(xynode.id), onNodeClick || event.stopPropagation()), onNodeClick == null || onNodeClick({
9659
+ element: xynode.data.element,
9660
+ xynode,
9661
+ event
9662
+ });
9663
+ },
9664
+ onNodeDoubleClick: (event, xynode) => {
9665
+ const {
9666
+ focusedNodeId,
9667
+ zoomable,
9668
+ fitViewEnabled,
9669
+ fitDiagram,
9670
+ focusOnNode,
9671
+ setLastClickedNode
9672
+ } = diagramApi.getState();
9673
+ setLastClickedNode(xynode.id), (focusedNodeId || zoomable && fitViewEnabled) && (focusedNodeId === xynode.id ? fitDiagram(xyflowApi) : focusOnNode(xynode.id), event.stopPropagation());
9674
+ },
9675
+ onEdgeClick: (event, xyedge) => {
9676
+ diagramApi.getState().setLastClickedEdge(xyedge.id);
9677
+ const { focusedNodeId, focusOnNode, onEdgeClick } = diagramApi.getState();
9678
+ focusedNodeId && (focusedNodeId === xyedge.source || focusedNodeId === xyedge.target) && (focusOnNode(focusedNodeId === xyedge.source ? xyedge.target : xyedge.source), onEdgeClick || event.stopPropagation()), onEdgeClick == null || onEdgeClick({
9679
+ relation: xyedge.data.edge,
9680
+ xyedge,
9681
+ event
9682
+ });
9683
+ },
9684
+ onMoveEnd: (event, _viewport) => {
9685
+ const viewportChanged = !!event;
9686
+ viewportChanged !== diagramApi.getState().viewportChanged && diagramApi.setState({ viewportChanged }, !1, `viewport-changed: ${viewportChanged}`);
9687
+ },
9688
+ onNodeMouseEnter: (event, xynode) => {
9689
+ hoveredNodeFromOnEdgeEnterRef.current = "";
9690
+ const { hoveredNodeId, setHoveredNode } = diagramApi.getState();
9691
+ hoveredNodeId !== xynode.id && setHoveredNode(xynode.id);
9692
+ },
9693
+ onNodeMouseLeave: (event, xynode) => {
9694
+ const { hoveredNodeId, setHoveredNode } = diagramApi.getState();
9695
+ hoveredNodeId === xynode.id && setHoveredNode(null);
9696
+ },
9697
+ onEdgeMouseEnter: (event, { id: id2, source, target }) => {
9698
+ const { hoveredNodeId, focusedNodeId, setHoveredEdge, setHoveredNode } = diagramApi.getState();
9699
+ if (setHoveredEdge(id2), (focusedNodeId === source || focusedNodeId === target) && focusedNodeId !== hoveredNodeId) {
9700
+ const next = hoveredNodeFromOnEdgeEnterRef.current = source === focusedNodeId ? target : source;
9701
+ setHoveredNode(next);
9702
+ }
9703
+ },
9704
+ onEdgeMouseLeave: (event, xyedge) => {
9705
+ const { hoveredEdgeId, setHoveredEdge, hoveredNodeId, setHoveredNode } = diagramApi.getState();
9706
+ hoveredEdgeId === xyedge.id && setHoveredEdge(null), hoveredNodeId === hoveredNodeFromOnEdgeEnterRef.current && (hoveredNodeFromOnEdgeEnterRef.current = "", setHoveredNode(null));
9707
+ }
9708
+ }), [diagramApi, xyflowApi]);
9709
+ }
9710
+ const nodeTypes = {
9711
+ element: ElementNode,
9712
+ compound: CompoundNodeMemo
9713
+ }, edgeTypes = {
9714
+ relationship: RelationshipEdge
9715
+ }, selector$1 = (s) => ({
9716
+ nodesSelectable: s.nodesSelectable || s.focusedNodeId !== null,
9717
+ nodesDraggable: s.nodesDraggable,
9718
+ fitView: s.fitViewEnabled,
9719
+ fitViewPadding: s.fitViewPadding,
9720
+ hasOnNavigateTo: !!s.onNavigateTo,
9721
+ hasOnNodeClick: !!s.onNodeClick,
9722
+ hasOnNodeContextMenu: !!s.onNodeContextMenu,
9723
+ hasOnCanvasContextMenu: !!s.onCanvasContextMenu,
9724
+ hasOnEdgeContextMenu: !!s.onEdgeContextMenu,
9725
+ hasOnEdgeClick: !!s.onEdgeClick,
9726
+ zoomable: s.zoomable,
9727
+ pannable: s.pannable
9728
+ });
9729
+ function XYFlow({
9730
+ className,
9731
+ children: children2,
9732
+ defaultNodes,
9733
+ defaultEdges,
9734
+ style: style2
9735
+ }) {
9736
+ const xyflowApi = useXYStoreApi(), diagramApi = useDiagramStoreApi(), {
9737
+ nodesSelectable,
9738
+ nodesDraggable,
9739
+ fitView: fitView2,
9740
+ fitViewPadding,
9741
+ pannable,
9742
+ zoomable,
9743
+ hasOnNodeClick,
9744
+ hasOnNavigateTo,
9745
+ hasOnNodeContextMenu,
9746
+ hasOnCanvasContextMenu,
9747
+ hasOnEdgeContextMenu,
9748
+ hasOnEdgeClick
9749
+ } = useDiagramState(selector$1), layoutConstraints = useLayoutConstraints(), handlers = useXYFlowEvents(), { colorScheme } = useMantineColorScheme(), colorMode = colorScheme !== "auto" ? colorScheme : void 0;
9750
+ return useOnViewportChange({
9751
+ onEnd: ({ x, y, zoom: zoom2 }) => {
9752
+ const rounded = {
9753
+ x: Math.round(x),
9754
+ y: Math.round(y)
9755
+ };
9756
+ (x !== rounded.x || y !== rounded.y) && xyflowApi.setState({ transform: [rounded.x, rounded.y, zoom2] });
9757
+ }
9758
+ }), /* @__PURE__ */ jsx(
9759
+ index,
9760
+ {
9761
+ className,
9762
+ style: style2,
9763
+ ...colorMode && { colorMode },
9764
+ defaultNodes,
9765
+ defaultEdges,
9766
+ nodeTypes,
9767
+ edgeTypes,
9768
+ zoomOnPinch: zoomable,
9769
+ zoomOnScroll: !pannable && zoomable,
9770
+ ...!zoomable && {
9771
+ zoomActivationKeyCode: null
9772
+ },
9773
+ maxZoom: zoomable ? 1.9 : 1,
9774
+ minZoom: zoomable ? MinZoom : 1,
9775
+ fitView: fitView2,
9776
+ fitViewOptions: {
9777
+ minZoom: MinZoom,
9778
+ maxZoom: 1,
9779
+ padding: fitViewPadding,
9780
+ includeHiddenNodes: !0
9781
+ },
9782
+ preventScrolling: zoomable || pannable,
9783
+ defaultMarkerColor: "var(--xy-edge-stroke)",
9784
+ noDragClassName: "nodrag",
9785
+ noPanClassName: "nopan",
9786
+ panOnScroll: pannable,
9787
+ panOnDrag: pannable,
9788
+ elementsSelectable: nodesSelectable,
9789
+ nodesFocusable: nodesDraggable || nodesSelectable || hasOnNodeClick || hasOnNavigateTo,
9790
+ edgesFocusable: hasOnEdgeClick,
9791
+ ...!nodesSelectable && {
9792
+ selectionKeyCode: null
9793
+ },
9794
+ nodesDraggable,
9795
+ ...nodesDraggable && {
9796
+ onNodeDragStart: layoutConstraints.onNodeDragStart,
9797
+ onNodeDrag: layoutConstraints.onNodeDrag,
9798
+ onNodeDragStop: layoutConstraints.onNodeDragStop
9799
+ },
9800
+ zoomOnDoubleClick: !1,
9801
+ elevateNodesOnSelect: !1,
9802
+ selectNodesOnDrag: !1,
9803
+ onDoubleClick: handlers.onDoubleClick,
9804
+ onPaneClick: handlers.onPaneClick,
9805
+ onMoveEnd: handlers.onMoveEnd,
9806
+ onNodeMouseEnter: handlers.onNodeMouseEnter,
9807
+ onNodeMouseLeave: handlers.onNodeMouseLeave,
9808
+ onEdgeMouseEnter: handlers.onEdgeMouseEnter,
9809
+ onEdgeMouseLeave: handlers.onEdgeMouseLeave,
9810
+ onNodeClick: handlers.onNodeClick,
9811
+ onNodeDoubleClick: handlers.onNodeDoubleClick,
9812
+ onEdgeClick: handlers.onEdgeClick,
9813
+ onInit: () => {
9814
+ diagramApi.setState({ initialized: !0 }, !1, "initialized");
9815
+ },
9816
+ ...hasOnNodeContextMenu && {
9817
+ onNodeContextMenu: handlers.onNodeContextMenu
9818
+ },
9819
+ ...hasOnEdgeContextMenu && {
9820
+ onEdgeContextMenu: handlers.onEdgeContextMenu
9821
+ },
9822
+ ...hasOnCanvasContextMenu && {
9823
+ onPaneContextMenu: handlers.onPaneContextMenu
9824
+ },
9825
+ children: children2
9826
+ }
9827
+ );
9828
+ }
9829
+ var container$1 = "_2jkb2y0", buttons = "_2jkb2y1", btn = "_2jkb2y3";
9830
+ function DynamicViewWalkthrough() {
9831
+ const {
9832
+ nextDynamicStep,
9833
+ stopDynamicView,
9834
+ activeDynamicViewStep,
9835
+ hasNextSteps
9836
+ } = useDiagramState((s) => ({
9837
+ nextDynamicStep: s.nextDynamicStep,
9838
+ stopDynamicView: s.stopDynamicView,
9839
+ activeDynamicViewStep: s.activeDynamicViewStep,
9840
+ hasNextSteps: (s.activeDynamicViewStep ?? 1) < s.view.edges.length
9841
+ })), buttonProps = {
9842
+ className: btn,
9843
+ size: "compact-xl",
9844
+ radius: "xl"
9845
+ }, nextStep = (increment = 1) => (e) => {
9846
+ e.stopPropagation(), nextDynamicStep(increment);
9847
+ };
9848
+ return /* @__PURE__ */ jsxs(
9849
+ Box,
9850
+ {
9851
+ className: clsx("react-flow__panel", container$1),
9852
+ children: [
9853
+ isNullish(activeDynamicViewStep) && /* @__PURE__ */ jsx(
9854
+ Button,
8621
9855
  {
8622
- x: w - PersonIcon.width - 6,
8623
- y: h - PersonIcon.height,
8624
- width: PersonIcon.width,
8625
- height: PersonIcon.height,
8626
- viewBox: `0 0 ${PersonIcon.width} ${PersonIcon.height}`,
8627
- className: fillMixStroke,
8628
- children: /* @__PURE__ */ jsx(
8629
- "path",
8630
- {
8631
- strokeWidth: 0,
8632
- d: PersonIcon.path
8633
- }
8634
- )
9856
+ ...buttonProps,
9857
+ className: clsx(buttons, btn),
9858
+ rightSection: /* @__PURE__ */ jsx(IconPlayerPlayFilled, {}),
9859
+ onClick: nextStep(),
9860
+ px: "xl",
9861
+ children: "Start"
8635
9862
  }
8636
- )
8637
- ] });
8638
- case "queue": {
8639
- const { path, rx, ry } = queueSVGPath(w, h);
8640
- return /* @__PURE__ */ jsxs(Fragment, { children: [
8641
- /* @__PURE__ */ jsx("path", { d: path, strokeWidth: 2 }),
8642
- /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: ry, ry: ry - 0.75, rx, className: fillMixStroke, strokeWidth: 2 })
8643
- ] });
8644
- }
8645
- case "storage":
8646
- case "cylinder": {
8647
- const { path, rx, ry } = cylinderSVGPath(w, h);
8648
- return /* @__PURE__ */ jsxs(Fragment, { children: [
8649
- /* @__PURE__ */ jsx("path", { d: path, strokeWidth: 2 }),
8650
- /* @__PURE__ */ jsx("ellipse", { cx: rx, cy: ry, ry, rx: rx - 0.75, className: fillMixStroke, strokeWidth: 2 })
8651
- ] });
9863
+ ),
9864
+ isNumber(activeDynamicViewStep) && /* @__PURE__ */ jsxs(Button.Group, { className: buttons, children: [
9865
+ /* @__PURE__ */ jsx(
9866
+ Button,
9867
+ {
9868
+ ...buttonProps,
9869
+ pl: "lg",
9870
+ disabled: activeDynamicViewStep === 1,
9871
+ onClick: nextStep(-1),
9872
+ children: /* @__PURE__ */ jsx(IconPlayerSkipBackFilled, {})
9873
+ }
9874
+ ),
9875
+ /* @__PURE__ */ jsx(
9876
+ Button,
9877
+ {
9878
+ ...buttonProps,
9879
+ px: "sm",
9880
+ onClick: (e) => {
9881
+ e.stopPropagation(), stopDynamicView();
9882
+ },
9883
+ children: /* @__PURE__ */ jsx(IconPlayerStopFilled, {})
9884
+ }
9885
+ ),
9886
+ /* @__PURE__ */ jsx(
9887
+ Button,
9888
+ {
9889
+ ...buttonProps,
9890
+ pr: "lg",
9891
+ disabled: !hasNextSteps,
9892
+ onClick: nextStep(),
9893
+ children: /* @__PURE__ */ jsx(IconPlayerSkipForwardFilled, {})
9894
+ }
9895
+ )
9896
+ ] })
9897
+ ]
8652
9898
  }
8653
- case "rectangle":
8654
- return /* @__PURE__ */ jsx(
8655
- "rect",
9899
+ );
9900
+ }
9901
+ const {
9902
+ primary,
9903
+ secondary,
9904
+ muted,
9905
+ ...otherColors
9906
+ } = defaultTheme.elements, themedColors = [
9907
+ { key: "primary", value: primary.fill },
9908
+ { key: "secondary", value: secondary.fill },
9909
+ { key: "muted", value: muted.fill }
9910
+ ], colors = keys.strict(otherColors).map((key) => ({
9911
+ key,
9912
+ value: defaultTheme.elements[key].fill
9913
+ }));
9914
+ function NodeOptions({ selectedNodeIds }) {
9915
+ const diagramApi = useDiagramStoreApi(), nodes = useXYNodesData(selectedNodeIds);
9916
+ if (!hasAtLeast(nodes, 1))
9917
+ return null;
9918
+ if (nodes.length !== selectedNodeIds.length)
9919
+ throw new Error("NodeOptions: nodes and props.nodes should have the same length");
9920
+ const showShapeOption = nodes.some((node) => node.type === "element"), [firstNode, ...rest] = nodes, showOpacityOption = rest.length === 0 && firstNode.type === "compound", triggerChange = (style2) => {
9921
+ const targets = nodes.map((node) => node.data.element.id);
9922
+ invariant(hasAtLeast(targets, 1), "At least one target is required"), diagramApi.getState().triggerOnChange([{
9923
+ op: "change-element-style",
9924
+ style: style2,
9925
+ targets
9926
+ }]);
9927
+ };
9928
+ return /* @__PURE__ */ jsxs(Stack, { children: [
9929
+ /* @__PURE__ */ jsx(Box, { maw: 200, children: /* @__PURE__ */ jsx(Text, { size: "xs", c: rest.length > 0 ? "dimmed" : "", truncate: !0, children: rest.length === 0 ? firstNode.data.element.title : "[ multiple ]" }) }),
9930
+ showShapeOption && /* @__PURE__ */ jsx(
9931
+ ShapeOption,
9932
+ {
9933
+ nodes,
9934
+ onShapeChange: (shape) => {
9935
+ triggerChange({ shape });
9936
+ }
9937
+ }
9938
+ ),
9939
+ /* @__PURE__ */ jsx(
9940
+ Colors,
9941
+ {
9942
+ nodes,
9943
+ onColorChange: (color2) => {
9944
+ triggerChange({ color: color2 });
9945
+ }
9946
+ }
9947
+ ),
9948
+ showOpacityOption && /* @__PURE__ */ jsxs(Box, { children: [
9949
+ /* @__PURE__ */ jsx(Divider, { label: "opacity and border", labelPosition: "left" }),
9950
+ /* @__PURE__ */ jsx(
9951
+ OpacityOption,
8656
9952
  {
8657
- width: w,
8658
- height: h,
8659
- rx: 6,
8660
- strokeWidth: 0
9953
+ node: firstNode,
9954
+ onOpacityChange: (opacity) => {
9955
+ triggerChange({ opacity });
9956
+ }
8661
9957
  }
8662
- );
8663
- default:
8664
- return nonexhaustive(shape);
8665
- }
8666
- }
8667
- function SelectedIndicator({ shape, w, h }) {
8668
- switch (shape) {
8669
- case "queue":
8670
- return /* @__PURE__ */ jsx("path", { d: queueSVGPath(w, h).path });
8671
- case "storage":
8672
- case "cylinder":
8673
- return /* @__PURE__ */ jsx("path", { d: cylinderSVGPath(w, h).path });
8674
- default:
8675
- return /* @__PURE__ */ jsx(
8676
- "rect",
9958
+ ),
9959
+ /* @__PURE__ */ jsx(
9960
+ BorderStyleOption,
8677
9961
  {
8678
- x: -1,
8679
- y: -1,
8680
- width: w + 2,
8681
- height: h + 2,
8682
- rx: 6
9962
+ node: firstNode,
9963
+ onChange: (border) => {
9964
+ triggerChange({ border });
9965
+ }
8683
9966
  }
8684
- );
8685
- }
9967
+ )
9968
+ ] }, firstNode.id),
9969
+ /* @__PURE__ */ jsx(NavigateToOption, { nodes })
9970
+ ] });
8686
9971
  }
8687
- const selectedScale = 1.015, variants = {
8688
- idle: (_, { scale }) => ({
8689
- scale: 1,
8690
- transition: {
8691
- delay: isNumber(scale) && scale > selectedScale ? 0.075 : 0
8692
- }
8693
- }),
8694
- selected: (_, { scale }) => ({
8695
- scale: selectedScale,
8696
- transition: {
8697
- delay: isNumber(scale) && scale > selectedScale ? 0.075 : 0
8698
- }
8699
- }),
8700
- // dragging: {
8701
- // scale: selectedScale
8702
- // },
8703
- // hovered: {
8704
- // scale: 1.08
8705
- // },
8706
- // hover: (_, {scale}) => isNumber(scale) && scale < 1.02 ? ({
8707
- // scale: 1.08,
8708
- // }) : ({
8709
- // scale: 1.08,
8710
- // transition: {
8711
- // delay: 1
8712
- // }
8713
- // }),
8714
- hovered: (_, { scale }) => ({
8715
- scale: 1.06,
8716
- transition: {
8717
- delay: isNumber(scale) && scale !== 1 && scale !== selectedScale ? 0 : 0.15
8718
- }
8719
- }),
8720
- tap: {
8721
- scale: 0.975
8722
- }
8723
- // tap: {
8724
- // scale: 0.9
8725
- // }
8726
- };
8727
- function ElementNode({
8728
- id: id2,
8729
- data: {
8730
- element
8731
- },
8732
- dragging,
8733
- selected: selected2 = !1,
8734
- width,
8735
- height
9972
+ function Colors({
9973
+ nodes: [firstNode, ...nodes],
9974
+ onColorChange
8736
9975
  }) {
8737
- const { isHovered, hasOnNavigateTo, isHovercards, isInteractive } = useDiagramState((s) => ({
8738
- isHovered: s.hoveredNodeId === id2,
8739
- isInteractive: s.nodesDraggable || s.nodesSelectable || !!s.onNavigateTo,
8740
- isHovercards: s.showElementLinks,
8741
- hasOnNavigateTo: !!s.onNavigateTo
8742
- })), isNavigable = hasOnNavigateTo && !!element.navigateTo, w = toDomPrecision(width ?? element.width), h = toDomPrecision(height ?? element.height);
8743
- let animate = "idle";
8744
- switch (!0) {
8745
- case (dragging && selected2):
8746
- animate = "selected";
8747
- break;
8748
- case dragging:
8749
- animate = "idle";
8750
- break;
8751
- case (isInteractive && isHovered):
8752
- animate = "hovered";
8753
- break;
8754
- case selected2:
8755
- animate = "selected";
8756
- break;
8757
- }
8758
- return /* @__PURE__ */ jsxs(
8759
- motion.div,
8760
- {
8761
- id: id2,
8762
- className: clsx(container, "likec4-element-node"),
8763
- "data-likec4-color": element.color,
8764
- "data-likec4-shape": element.shape,
8765
- variants,
8766
- initial: !1,
8767
- animate,
8768
- ...isInteractive && {
8769
- whileTap: dragging ? animate : "tap"
8770
- },
8771
- children: [
8772
- /* @__PURE__ */ jsx(
8773
- Handle,
8774
- {
8775
- type: "target",
8776
- position: Position.Top,
8777
- style: { visibility: "hidden" }
8778
- }
8779
- ),
8780
- /* @__PURE__ */ jsxs(
8781
- "svg",
8782
- {
8783
- className: cssShapeSvg,
8784
- viewBox: `0 0 ${w} ${h}`,
8785
- width: w,
8786
- height: h,
8787
- children: [
8788
- /* @__PURE__ */ jsx("g", { className: indicator, children: /* @__PURE__ */ jsx(
8789
- SelectedIndicator,
8790
- {
8791
- shape: element.shape,
8792
- w,
8793
- h
8794
- }
8795
- ) }),
8796
- /* @__PURE__ */ jsx(
8797
- ElementShapeSvg,
8798
- {
8799
- shape: element.shape,
8800
- w,
8801
- h
8802
- }
8803
- )
8804
- ]
9976
+ let selectedColor = firstNode.data.element.color;
9977
+ takeWhile(nodes, (node) => node.data.element.color !== selectedColor ? (selectedColor = null, !1) : !0);
9978
+ const changeColor = (color2) => () => {
9979
+ selectedColor !== color2 && onColorChange(color2);
9980
+ };
9981
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(TooltipGroup, { openDelay: 400, closeDelay: 300, children: [
9982
+ /* @__PURE__ */ jsx(Divider, { label: "color", labelPosition: "left" }),
9983
+ /* @__PURE__ */ jsx(Flex, { mt: "xs", maw: 150, gap: "xs", justify: "flex-start", align: "flex-start", direction: "row", wrap: "wrap", children: themedColors.map(({ key, value }) => /* @__PURE__ */ jsx(
9984
+ Tooltip,
9985
+ {
9986
+ label: key,
9987
+ fz: "xs",
9988
+ color: "dark",
9989
+ offset: 2,
9990
+ transitionProps: { duration: 140, transition: "slide-up" },
9991
+ children: /* @__PURE__ */ jsx(
9992
+ ColorSwatch,
9993
+ {
9994
+ color: value,
9995
+ size: 20,
9996
+ withShadow: !0,
9997
+ onClick: changeColor(key),
9998
+ style: { color: "#fff", cursor: "pointer" },
9999
+ children: selectedColor === key && /* @__PURE__ */ jsx(CheckIcon, { style: { width: rem(12), height: rem(12) } })
8805
10000
  }
8806
- ),
8807
- /* @__PURE__ */ jsxs("div", { className: clsx(cssElement, "likec4-element"), children: [
8808
- element.icon && /* @__PURE__ */ jsx(ElementIcon, { node: element }),
8809
- /* @__PURE__ */ jsx(
8810
- Text,
8811
- {
8812
- component: "div",
8813
- className: clsx(title, "likec4-element-title"),
8814
- children: element.title
8815
- }
8816
- ),
8817
- element.technology && /* @__PURE__ */ jsx(
8818
- Text,
8819
- {
8820
- component: "div",
8821
- className: clsx(technology, "likec4-element-technology"),
8822
- children: element.technology
8823
- }
8824
- ),
8825
- element.description && /* @__PURE__ */ jsx(
8826
- Text,
8827
- {
8828
- component: "div",
8829
- className: clsx(description, "likec4-element-description"),
8830
- children: element.description
8831
- }
8832
- )
8833
- ] }),
8834
- /* @__PURE__ */ jsx(
8835
- Handle,
10001
+ )
10002
+ },
10003
+ key
10004
+ )) }),
10005
+ /* @__PURE__ */ jsx(Flex, { mt: "sm", maw: 150, gap: "xs", justify: "flex-start", align: "flex-start", direction: "row", wrap: "wrap", children: colors.map(({ key, value }) => /* @__PURE__ */ jsx(
10006
+ Tooltip,
10007
+ {
10008
+ label: key,
10009
+ fz: "xs",
10010
+ color: "dark",
10011
+ offset: 2,
10012
+ transitionProps: { duration: 140, transition: "slide-up" },
10013
+ children: /* @__PURE__ */ jsx(
10014
+ ColorSwatch,
8836
10015
  {
8837
- type: "source",
8838
- position: Position.Bottom,
8839
- style: { visibility: "hidden" }
10016
+ color: value,
10017
+ size: 20,
10018
+ onClick: changeColor(key),
10019
+ style: { color: "#fff", cursor: "pointer" },
10020
+ children: selectedColor === key && /* @__PURE__ */ jsx(CheckIcon, { style: { width: rem(12), height: rem(12) } })
8840
10021
  }
8841
- ),
8842
- isHovercards && element.links && /* @__PURE__ */ jsx(ElementLink, { element }),
8843
- isNavigable && /* @__PURE__ */ jsx(NavigateToBtn, { xynodeId: id2, className: cssNavigateBtn })
8844
- ]
8845
- }
8846
- );
8847
- }
8848
- function SelectEdgesOnNodeFocus() {
8849
- const focusedNodeId = useDiagramState((s) => s.focusedNodeId), xyflowApi = useXYStoreApi();
8850
- return useUpdateEffect(() => {
8851
- const edgeChanges = [], nodeChanges = [], { edges, nodes, triggerNodeChanges, triggerEdgeChanges } = xyflowApi.getState();
8852
- if (focusedNodeId) {
8853
- for (const edge of edges)
8854
- edge.source === focusedNodeId || edge.target === focusedNodeId ? edgeChanges.push({
8855
- id: edge.id,
8856
- type: "select",
8857
- selected: !0
8858
- }) : edge.selected && edgeChanges.push({
8859
- id: edge.id,
8860
- type: "select",
8861
- selected: !1
8862
- });
8863
- for (const node of nodes)
8864
- node.selected && node.id !== focusedNodeId && nodeChanges.push({
8865
- id: node.id,
8866
- type: "select",
8867
- selected: !1
8868
- });
8869
- nodeChanges.push({
8870
- id: focusedNodeId,
8871
- type: "select",
8872
- selected: !0
8873
- }), edgeChanges.length > 0 && triggerEdgeChanges(edgeChanges), nodeChanges.length > 0 && triggerNodeChanges(nodeChanges);
8874
- } else
8875
- xyflowApi.getState().resetSelectedElements();
8876
- }, [focusedNodeId]), null;
8877
- }
8878
- function literalToEnum(value) {
8879
- switch (value) {
8880
- case "dots":
8881
- return BackgroundVariant.Dots;
8882
- case "lines":
8883
- return BackgroundVariant.Lines;
8884
- case "cross":
8885
- return BackgroundVariant.Cross;
8886
- default:
8887
- nonexhaustive(value);
8888
- }
10022
+ )
10023
+ },
10024
+ key
10025
+ )) })
10026
+ ] }) });
8889
10027
  }
8890
- const XYFlowBackground = memo(({ background }) => {
8891
- if (typeof background == "string")
8892
- return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(background) });
8893
- const { variant, ...rest } = background;
8894
- return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(variant), ...rest });
8895
- }, deepEqual), viewportDomNode = (state) => {
8896
- var _a;
8897
- return ((_a = state.domNode) == null ? void 0 : _a.querySelector(".react-flow__viewport")) ?? null;
8898
- };
8899
- function useXYFlowEvents() {
8900
- const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), dblclickTimeout = useRef(), viewportRef = useRef(viewportDomNode(xyflowApi.getState())), dbclickGuarg = () => dblclickTimeout.current !== void 0 ? !0 : (dblclickTimeout.current = window.setTimeout(() => {
8901
- dblclickTimeout.current = void 0;
8902
- }, 250), !1), transformRef = useRef(""), cbRef = useRef();
8903
- return useEffect(() => xyflowApi.subscribe((state, prev) => {
8904
- (state.domNode !== prev.domNode || state.domNode && !viewportRef.current) && (viewportRef.current = viewportDomNode(state));
8905
- }), [xyflowApi]), useMemo(() => ({
8906
- onDoubleClick: (event) => {
8907
- diagramApi.getState().resetLastClicked();
8908
- const diagramState = diagramApi.getState();
8909
- if (diagramState.onCanvasDblClick) {
8910
- diagramState.onCanvasDblClick(event);
8911
- return;
8912
- }
8913
- if (diagramState.fitViewEnabled && diagramState.zoomable) {
8914
- diagramState.fitDiagram(), event.stopPropagation();
8915
- return;
8916
- }
8917
- },
8918
- onPaneClick: (event) => {
8919
- if (dbclickGuarg())
8920
- return;
8921
- const { focusedNodeId, fitDiagram, onCanvasClick, resetLastClicked } = diagramApi.getState();
8922
- if (resetLastClicked(), onCanvasClick) {
8923
- onCanvasClick(event);
8924
- return;
8925
- }
8926
- focusedNodeId && (fitDiagram(), event.stopPropagation());
8927
- },
8928
- onNodeContextMenu: (event, xynode) => {
8929
- var _a, _b;
8930
- diagramApi.getState().setLastClickedNode(xynode.id), (_b = (_a = diagramApi.getState()).onNodeContextMenu) == null || _b.call(_a, {
8931
- element: xynode.data.element,
8932
- xynode,
8933
- event
8934
- });
8935
- },
8936
- onPaneContextMenu: (event) => {
8937
- var _a, _b;
8938
- diagramApi.getState().resetLastClicked(), (_b = (_a = diagramApi.getState()).onCanvasContextMenu) == null || _b.call(_a, event);
8939
- },
8940
- onEdgeContextMenu: (event, xyedge) => {
8941
- var _a, _b;
8942
- diagramApi.getState().setLastClickedEdge(xyedge.id), (_b = (_a = diagramApi.getState()).onEdgeContextMenu) == null || _b.call(_a, {
8943
- relation: xyedge.data.edge,
8944
- xyedge,
8945
- event
8946
- });
8947
- },
8948
- onNodeClick: (event, xynode) => {
8949
- diagramApi.getState().setLastClickedNode(xynode.id);
8950
- const { focusedNodeId, fitDiagram, onNodeClick } = diagramApi.getState();
8951
- if (onNodeClick) {
8952
- onNodeClick({
8953
- element: xynode.data.element,
8954
- xynode,
8955
- event
8956
- });
8957
- return;
8958
- }
8959
- focusedNodeId && focusedNodeId !== xynode.id && (fitDiagram(xynode), event.stopPropagation());
8960
- },
8961
- onNodeDoubleClick: (event, xynode) => {
8962
- diagramApi.getState().setLastClickedNode(xynode.id);
8963
- const { zoomable, fitViewEnabled, fitDiagram, onNodeClick } = diagramApi.getState();
8964
- onNodeClick || zoomable && fitViewEnabled && (fitDiagram(xynode), event.stopPropagation());
8965
- },
8966
- onEdgeClick: (event, xyedge) => {
8967
- diagramApi.getState().setLastClickedEdge(xyedge.id);
8968
- const { focusedNodeId, fitDiagram, onEdgeClick, xyflow } = diagramApi.getState();
8969
- if (onEdgeClick) {
8970
- onEdgeClick({
8971
- relation: xyedge.data.edge,
8972
- xyedge,
8973
- event
8974
- });
8975
- return;
10028
+ function ShapeOption({
10029
+ nodes: [firstNode, ...nodes],
10030
+ onShapeChange
10031
+ }) {
10032
+ let selectedShape = firstNode.data.element.shape;
10033
+ return takeWhile(nodes, (node) => node.data.element.shape !== selectedShape ? (selectedShape = null, !1) : !0), /* @__PURE__ */ jsxs(Box, { children: [
10034
+ /* @__PURE__ */ jsx(Divider, { label: "shape", labelPosition: "left" }),
10035
+ /* @__PURE__ */ jsx(
10036
+ Select,
10037
+ {
10038
+ mt: "xs",
10039
+ size: "xs",
10040
+ variant: "filled",
10041
+ value: selectedShape,
10042
+ placeholder: "[ multiple ]",
10043
+ data: ElementShapes,
10044
+ allowDeselect: !1,
10045
+ checkIconPosition: "right",
10046
+ onChange: (value) => {
10047
+ !value || value === selectedShape || onShapeChange(value);
10048
+ }
8976
10049
  }
8977
- if (focusedNodeId && (focusedNodeId === xyedge.source || focusedNodeId === xyedge.target)) {
8978
- const nextFocus = focusedNodeId === xyedge.source ? xyedge.target : xyedge.source;
8979
- fitDiagram(xyflow.getNode(nextFocus)), event.stopPropagation();
10050
+ )
10051
+ ] });
10052
+ }
10053
+ function NavigateToOption({
10054
+ nodes: [node, ...nodes]
10055
+ }) {
10056
+ const isMultiple = nodes.length >= 1;
10057
+ return /* @__PURE__ */ jsxs(Box, { children: [
10058
+ /* @__PURE__ */ jsx(Divider, { label: "navigate to", labelPosition: "left" }),
10059
+ /* @__PURE__ */ jsx(
10060
+ Select,
10061
+ {
10062
+ mt: "xs",
10063
+ size: "xs",
10064
+ variant: "filled",
10065
+ value: isMultiple ? null : node.data.element.navigateTo ?? null,
10066
+ disabled: isMultiple,
10067
+ placeholder: isMultiple ? "[ multiple ]" : "select",
10068
+ data: node.data.element.navigateTo ? [{ value: node.data.element.navigateTo, label: node.data.element.navigateTo }] : [],
10069
+ allowDeselect: !0,
10070
+ checkIconPosition: "right"
8980
10071
  }
8981
- },
8982
- onMoveEnd: (event, _viewport) => {
8983
- const viewportChanged = !!event;
8984
- viewportChanged !== diagramApi.getState().viewportChanged && diagramApi.setState({ viewportChanged }, !1, `viewport-changed: ${viewportChanged}`);
8985
- },
8986
- onNodeMouseEnter: (event, xynode) => {
8987
- diagramApi.getState().setHoveredNode(xynode.id);
8988
- },
8989
- onNodeMouseLeave: (event, xynode) => {
8990
- diagramApi.getState().setHoveredNode(null);
8991
- },
8992
- onEdgeMouseEnter: (event, xyedge) => {
8993
- diagramApi.getState().setHoveredEdge(xyedge.id);
8994
- },
8995
- onEdgeMouseLeave: (event, xyedge) => {
8996
- diagramApi.getState().setHoveredEdge(null);
8997
- },
8998
- /**
8999
- * WOKAROUND:
9000
- * Viewport transform is not rounded to integers which results in blurry nodes on some resolution
9001
- * https://github.com/xyflow/xyflow/issues/3282
9002
- */
9003
- onViewportChange: ({ x, y, zoom: zoom2 }) => {
9004
- const scale = zoom2 != 1 ? zoom2.toFixed(6) : "1";
9005
- transformRef.current = `translate(${Math.round(x)}px, ${Math.round(y)}px) scale(${scale})`, cbRef.current ?? (cbRef.current = requestIdleCallback(() => {
9006
- cbRef.current = void 0, viewportRef.current && viewportRef.current.style.transform !== transformRef.current && (viewportRef.current.style.transform = transformRef.current);
9007
- }, {
9008
- timeout: 1e3
9009
- }));
9010
- }
9011
- }), [diagramApi, xyflowApi]);
10072
+ )
10073
+ ] });
9012
10074
  }
9013
- const nodeTypes = {
9014
- element: ElementNode,
9015
- compound: CompoundNodeMemo
9016
- }, edgeTypes = {
9017
- relationship: RelationshipEdge
9018
- }, selector = (s) => ({
9019
- nodesSelectable: s.nodesSelectable || s.focusedNodeId !== null,
9020
- nodesDraggable: s.nodesDraggable,
9021
- fitView: s.fitViewEnabled,
9022
- fitViewPadding: s.fitViewPadding,
9023
- hasOnNavigateTo: !!s.onNavigateTo,
9024
- hasOnNodeClick: !!s.onNodeClick,
9025
- hasOnNodeContextMenu: !!s.onNodeContextMenu,
9026
- hasOnCanvasContextMenu: !!s.onCanvasContextMenu,
9027
- hasOnEdgeContextMenu: !!s.onEdgeContextMenu,
9028
- hasOnEdgeClick: !!s.onEdgeClick,
9029
- zoomable: s.zoomable,
9030
- pannable: s.pannable
9031
- });
9032
- function XYFlowWrapper({
9033
- className,
9034
- children: children2,
9035
- defaultNodes,
9036
- defaultEdges,
9037
- controls,
9038
- background,
9039
- style: style2
10075
+ function OpacityOption({
10076
+ node,
10077
+ onOpacityChange
10078
+ }) {
10079
+ let selectedOpacity = node.data.element.style.opacity ?? 100;
10080
+ const [value, setValue] = useState(selectedOpacity);
10081
+ return useEffect(() => {
10082
+ setValue(selectedOpacity);
10083
+ }, [selectedOpacity]), /* @__PURE__ */ jsx(
10084
+ Slider,
10085
+ {
10086
+ mt: "xs",
10087
+ size: "sm",
10088
+ color: "dark",
10089
+ value,
10090
+ onChange: setValue,
10091
+ onChangeEnd: onOpacityChange
10092
+ }
10093
+ );
10094
+ }
10095
+ function BorderStyleOption({
10096
+ node,
10097
+ onChange
9040
10098
  }) {
9041
- const diagramApi = useDiagramStoreApi(), {
9042
- nodesSelectable,
9043
- nodesDraggable,
9044
- fitView: fitView2,
9045
- fitViewPadding,
9046
- pannable,
9047
- zoomable,
9048
- ...editor
9049
- } = useDiagramState(selector), layoutConstraints = useLayoutConstraints(), handlers = useXYFlowEvents(), isBgWithPattern = background !== "transparent" && background !== "solid", { colorScheme } = useMantineColorScheme(), colorMode = colorScheme !== "auto" ? colorScheme : void 0;
9050
- return /* @__PURE__ */ jsxs(
9051
- index,
10099
+ let selecteBorderStyle = node.data.element.style.border ?? "dashed";
10100
+ const [value, setValue] = useState(selecteBorderStyle);
10101
+ return useEffect(() => {
10102
+ setValue(selecteBorderStyle);
10103
+ }, [selecteBorderStyle]), /* @__PURE__ */ jsx(Box, { mt: "md", children: /* @__PURE__ */ jsx(
10104
+ SegmentedControl,
9052
10105
  {
9053
- className,
9054
- style: style2,
9055
- ...colorMode && { colorMode },
9056
- defaultNodes,
9057
- defaultEdges,
9058
- nodeTypes,
9059
- edgeTypes,
9060
- zoomOnPinch: zoomable,
9061
- zoomOnScroll: !pannable && zoomable,
9062
- ...!zoomable && {
9063
- zoomActivationKeyCode: null
9064
- },
9065
- maxZoom: zoomable ? 1.9 : 1,
9066
- minZoom: zoomable ? MinZoom : 1,
9067
- fitView: fitView2,
9068
- fitViewOptions: {
9069
- minZoom: MinZoom,
9070
- maxZoom: 1,
9071
- padding: fitViewPadding,
9072
- includeHiddenNodes: !0
9073
- },
9074
- preventScrolling: zoomable || pannable,
9075
- defaultMarkerColor: "var(--xy-edge-stroke)",
9076
- noDragClassName: "nodrag",
9077
- noPanClassName: "nopan",
9078
- panOnScroll: pannable,
9079
- panOnDrag: pannable,
9080
- elementsSelectable: nodesSelectable,
9081
- nodesFocusable: nodesDraggable || nodesSelectable || editor.hasOnNodeClick || editor.hasOnNavigateTo,
9082
- edgesFocusable: editor.hasOnEdgeClick,
9083
- ...!nodesSelectable && {
9084
- selectionKeyCode: null
9085
- },
9086
- nodesDraggable,
9087
- ...nodesDraggable && {
9088
- onNodeDragStart: layoutConstraints.onNodeDragStart,
9089
- onNodeDrag: layoutConstraints.onNodeDrag,
9090
- onNodeDragStop: layoutConstraints.onNodeDragStop
10106
+ size: "xs",
10107
+ fullWidth: !0,
10108
+ withItemsBorders: !1,
10109
+ value,
10110
+ onChange: (v) => {
10111
+ setValue(v), onChange(v);
9091
10112
  },
9092
- zoomOnDoubleClick: !1,
9093
- elevateNodesOnSelect: !1,
9094
- selectNodesOnDrag: !1,
9095
- onDoubleClick: handlers.onDoubleClick,
9096
- onPaneClick: handlers.onPaneClick,
9097
- onMoveEnd: handlers.onMoveEnd,
9098
- onNodeMouseEnter: handlers.onNodeMouseEnter,
9099
- onNodeMouseLeave: handlers.onNodeMouseLeave,
9100
- onEdgeMouseEnter: handlers.onEdgeMouseEnter,
9101
- onEdgeMouseLeave: handlers.onEdgeMouseLeave,
9102
- onNodeClick: handlers.onNodeClick,
9103
- onNodeDoubleClick: handlers.onNodeDoubleClick,
9104
- onEdgeClick: handlers.onEdgeClick,
9105
- onViewportChange: handlers.onViewportChange,
9106
- onInit: () => {
9107
- diagramApi.setState({ initialized: !0 }, !1, "initialized");
10113
+ data: [
10114
+ { label: "Solid", value: "solid" },
10115
+ { label: "Dashed", value: "dashed" },
10116
+ { label: "Dotted", value: "dotted" },
10117
+ { label: "None", value: "none" }
10118
+ ]
10119
+ }
10120
+ ) });
10121
+ }
10122
+ var panel = "_1lmzt1h0";
10123
+ function OptionsPanel() {
10124
+ const isFocusDisabled = useDiagramState((s) => isNullish(s.focusedNodeId)), [selectedNodes, setSelectedNodes] = useState([]);
10125
+ return useOnSelectionChange({
10126
+ onChange: ({ nodes }) => {
10127
+ const next = nodes.map((n) => n.id).sort();
10128
+ setSelectedNodes((prev) => shallowEqual(prev, next) ? prev : next);
10129
+ }
10130
+ }), /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isFocusDisabled && selectedNodes.length > 0 && /* @__PURE__ */ jsx(
10131
+ motion.div,
10132
+ {
10133
+ initial: { opacity: 0, scale: 0.85 },
10134
+ animate: { opacity: 1, scale: 1 },
10135
+ exit: {
10136
+ opacity: 0,
10137
+ scale: 0.85
9108
10138
  },
9109
- ...editor.hasOnNodeContextMenu && {
9110
- onNodeContextMenu: handlers.onNodeContextMenu
10139
+ transition: { duration: 0.14 },
10140
+ className: clsx("react-flow__panel", panel),
10141
+ style: {
10142
+ transformOrigin: "center right"
9111
10143
  },
9112
- ...editor.hasOnEdgeContextMenu && {
9113
- onEdgeContextMenu: handlers.onEdgeContextMenu
10144
+ children: /* @__PURE__ */ jsx(Card, { shadow: "sm", children: /* @__PURE__ */ jsx(NodeOptions, { selectedNodeIds: selectedNodes }) })
10145
+ }
10146
+ ) });
10147
+ }
10148
+ var container = "hbkbtj0", paper = "hbkbtj1", title = "hbkbtj2", description = "hbkbtj3";
10149
+ const selector = (s) => ({
10150
+ id: s.view.id,
10151
+ title: s.view.title ?? "untitled",
10152
+ description: s.view.description,
10153
+ links: s.view.links
10154
+ });
10155
+ function DiagramTitlePanel() {
10156
+ const { id: id2, title: title$12, description: description$12, links } = useDiagramState(selector), [isCollapsed, setCollapsed] = useLocalStorage({
10157
+ key: "diagram-title-panel-collapsed",
10158
+ defaultValue: !1
10159
+ }), toggle = () => setCollapsed((v) => !v);
10160
+ return /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
10161
+ motion.div,
10162
+ {
10163
+ initial: { opacity: 0.05, scale: 0.7 },
10164
+ animate: { opacity: 1, scale: 1 },
10165
+ exit: {
10166
+ opacity: 0.05,
10167
+ scale: 0.6
9114
10168
  },
9115
- ...editor.hasOnCanvasContextMenu && {
9116
- onPaneContextMenu: handlers.onPaneContextMenu
10169
+ className: clsx("react-flow__panel", container),
10170
+ style: {
10171
+ transformOrigin: "left center"
9117
10172
  },
9118
- children: [
9119
- isBgWithPattern && /* @__PURE__ */ jsx(XYFlowBackground, { background }),
9120
- controls && /* @__PURE__ */ jsx(Controls, { position: "bottom-right" }),
9121
- zoomable && !editor.hasOnNodeClick && /* @__PURE__ */ jsx(SelectEdgesOnNodeFocus, {}),
9122
- children2
9123
- ]
9124
- }
9125
- );
10173
+ children: /* @__PURE__ */ jsx(
10174
+ Paper,
10175
+ {
10176
+ radius: "sm",
10177
+ withBorder: !isCollapsed,
10178
+ className: paper,
10179
+ p: isCollapsed ? "xs" : "lg",
10180
+ onDoubleClick: (e) => e.stopPropagation(),
10181
+ children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", justify: "stretch", align: "stretch", children: [
10182
+ /* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", onClick: toggle, style: { cursor: "pointer" }, children: [
10183
+ /* @__PURE__ */ jsx(
10184
+ Text,
10185
+ {
10186
+ component: "div",
10187
+ flex: "1",
10188
+ size: isCollapsed ? "sm" : "lg",
10189
+ fw: 500,
10190
+ lh: 1.1,
10191
+ className: title,
10192
+ children: title$12
10193
+ }
10194
+ ),
10195
+ /* @__PURE__ */ jsxs(
10196
+ Text,
10197
+ {
10198
+ hidden: isCollapsed,
10199
+ component: "div",
10200
+ flex: "0 0 auto",
10201
+ inline: !0,
10202
+ size: "xs",
10203
+ fz: 9,
10204
+ fw: 500,
10205
+ c: "dimmed",
10206
+ style: {
10207
+ userSelect: "all"
10208
+ },
10209
+ children: [
10210
+ /* @__PURE__ */ jsxs("span", { style: { userSelect: "none" }, children: [
10211
+ "id:",
10212
+ " "
10213
+ ] }),
10214
+ id2
10215
+ ]
10216
+ }
10217
+ )
10218
+ ] }),
10219
+ !isCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
10220
+ description$12 && /* @__PURE__ */ jsx(
10221
+ Spoiler,
10222
+ {
10223
+ maxHeight: 42,
10224
+ showLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "show more" }),
10225
+ hideLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "hide" }),
10226
+ children: /* @__PURE__ */ jsx(
10227
+ Text,
10228
+ {
10229
+ component: "div",
10230
+ size: "sm",
10231
+ className: description,
10232
+ children: description$12 || "no description"
10233
+ }
10234
+ )
10235
+ }
10236
+ ),
10237
+ !description$12 && /* @__PURE__ */ jsx(
10238
+ Text,
10239
+ {
10240
+ component: "div",
10241
+ size: "xs",
10242
+ c: "dimmed",
10243
+ children: "no description"
10244
+ }
10245
+ ),
10246
+ links && /* @__PURE__ */ jsx(
10247
+ Stack,
10248
+ {
10249
+ gap: 3,
10250
+ justify: "stretch",
10251
+ align: "stretch",
10252
+ children: links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", align: "center", gap: "sm", children: [
10253
+ /* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(
10254
+ Anchor,
10255
+ {
10256
+ href: link,
10257
+ target: "_blank",
10258
+ fz: "xs",
10259
+ truncate: "end",
10260
+ display: "inline-block",
10261
+ w: "100%",
10262
+ children: link
10263
+ }
10264
+ ) }),
10265
+ /* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(
10266
+ Button,
10267
+ {
10268
+ size: "compact-xs",
10269
+ fz: "10",
10270
+ variant: "light",
10271
+ onClick: copy,
10272
+ color: copied ? "teal" : "gray",
10273
+ children: copied ? "copied" : "copy"
10274
+ }
10275
+ ) })
10276
+ ] }, link))
10277
+ }
10278
+ )
10279
+ ] })
10280
+ ] })
10281
+ }
10282
+ )
10283
+ },
10284
+ id2
10285
+ ) });
10286
+ }
10287
+ function XYFlowInner({
10288
+ children: children2,
10289
+ background,
10290
+ controls,
10291
+ showDiagramTitle,
10292
+ enableDynamicViewWalkthrough
10293
+ }) {
10294
+ const {
10295
+ isDynamicView: isDynamicView2,
10296
+ isDynamicViewActive,
10297
+ readonly
10298
+ } = useDiagramState((s) => ({
10299
+ isDynamicView: s.isDynamicView(),
10300
+ readonly: s.readonly,
10301
+ isDynamicViewActive: isNonNull(s.activeDynamicViewStep)
10302
+ }));
10303
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
10304
+ background !== "transparent" && background !== "solid" && /* @__PURE__ */ jsx(XYFlowBackground, { background }),
10305
+ controls && /* @__PURE__ */ jsx(Controls, { position: "bottom-right" }),
10306
+ readonly === !1 && /* @__PURE__ */ jsx(OptionsPanel, {}),
10307
+ !isDynamicViewActive && showDiagramTitle === !0 && /* @__PURE__ */ jsx(DiagramTitlePanel, {}),
10308
+ isDynamicView2 && enableDynamicViewWalkthrough && /* @__PURE__ */ jsx(DynamicViewWalkthrough, {}),
10309
+ children2
10310
+ ] });
9126
10311
  }
9127
- const XYFlow = memo(XYFlowWrapper);
9128
10312
  function LikeC4Diagram({
9129
10313
  view,
9130
10314
  className,
@@ -9136,9 +10320,10 @@ function LikeC4Diagram({
9136
10320
  nodesSelectable = !readonly,
9137
10321
  nodesDraggable = !readonly,
9138
10322
  background = "dots",
9139
- controls = !1,
10323
+ controls = !readonly,
9140
10324
  showElementLinks = !0,
9141
10325
  showDiagramTitle = !0,
10326
+ enableDynamicViewWalkthrough = !0,
9142
10327
  initialWidth,
9143
10328
  initialHeight,
9144
10329
  keepAspectRatio = !1,
@@ -9152,6 +10337,7 @@ function LikeC4Diagram({
9152
10337
  onNodeClick,
9153
10338
  onNodeContextMenu
9154
10339
  }) {
10340
+ console.log("LikeC4Diagram");
9155
10341
  const initialRef = useRef();
9156
10342
  if (!initialRef.current) {
9157
10343
  const initial = diagramViewToXYFlowData(view, {
@@ -9170,7 +10356,7 @@ function LikeC4Diagram({
9170
10356
  {
9171
10357
  fitView: fitView2,
9172
10358
  ...initialRef.current,
9173
- children: /* @__PURE__ */ jsxs(
10359
+ children: /* @__PURE__ */ jsx(
9174
10360
  DiagramContextProvider,
9175
10361
  {
9176
10362
  view,
@@ -9191,15 +10377,15 @@ function LikeC4Diagram({
9191
10377
  onChange,
9192
10378
  onNavigateTo,
9193
10379
  onCanvasDblClick,
9194
- children: [
9195
- /* @__PURE__ */ jsx(
9196
- KeepAspectRatioContainer,
9197
- {
9198
- className: clsx(rootClassName, className),
9199
- enabled: keepAspectRatio,
9200
- width: view.width,
9201
- height: view.height,
9202
- children: /* @__PURE__ */ jsxs(
10380
+ children: /* @__PURE__ */ jsxs(
10381
+ KeepAspectRatioContainer,
10382
+ {
10383
+ className: clsx(rootClassName, className),
10384
+ enabled: keepAspectRatio,
10385
+ width: view.width,
10386
+ height: view.height,
10387
+ children: [
10388
+ /* @__PURE__ */ jsx(
9203
10389
  XYFlow,
9204
10390
  {
9205
10391
  className: clsx(
@@ -9209,23 +10395,27 @@ function LikeC4Diagram({
9209
10395
  pannable !== !0 && cssDisablePan,
9210
10396
  background === "transparent" && cssTransparentBg
9211
10397
  ),
9212
- background,
9213
- controls,
9214
10398
  defaultNodes: initialRef.current.defaultNodes,
9215
10399
  defaultEdges: initialRef.current.defaultEdges,
9216
- children: [
9217
- readonly !== !0 && /* @__PURE__ */ jsx(OptionsPanel, {}),
9218
- showDiagramTitle === !0 && /* @__PURE__ */ jsx(DiagramTitlePanel, {})
9219
- ]
10400
+ children: /* @__PURE__ */ jsx(
10401
+ XYFlowInner,
10402
+ {
10403
+ showDiagramTitle,
10404
+ enableDynamicViewWalkthrough,
10405
+ background,
10406
+ controls
10407
+ }
10408
+ )
9220
10409
  }
9221
- )
9222
- }
9223
- ),
9224
- /* @__PURE__ */ jsxs(WhenInitialized, { children: [
9225
- /* @__PURE__ */ jsx(SyncWithDiagram, {}),
9226
- /* @__PURE__ */ jsx(FitViewOnDiagramChange, {})
9227
- ] })
9228
- ]
10410
+ ),
10411
+ /* @__PURE__ */ jsxs(WhenInitialized, { children: [
10412
+ /* @__PURE__ */ jsx(SyncWithDiagram, {}),
10413
+ fitView2 && /* @__PURE__ */ jsx(FitViewOnDiagramChange, {}),
10414
+ fitView2 && zoomable && /* @__PURE__ */ jsx(SelectEdgesOnNodeFocus, {})
10415
+ ] })
10416
+ ]
10417
+ }
10418
+ )
9229
10419
  }
9230
10420
  )
9231
10421
  }
@@ -9251,6 +10441,7 @@ function StaticLikeC4Diagram({
9251
10441
  background,
9252
10442
  showElementLinks: !0,
9253
10443
  showDiagramTitle: !1,
10444
+ enableDynamicViewWalkthrough: !1,
9254
10445
  nodesSelectable: !1,
9255
10446
  nodesDraggable: !1,
9256
10447
  ...rest