@likec4/diagram 1.2.1 → 1.3.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 (56) hide show
  1. package/dist/LikeC4Diagram.d.ts +1 -1
  2. package/dist/LikeC4Diagram.props.d.ts +21 -3
  3. package/dist/index.mjs +1335 -1240
  4. package/dist/state/DiagramContext.d.ts +2263 -175
  5. package/dist/state/diagramStore.d.ts +2272 -180
  6. package/dist/state/useDiagramStore.d.ts +2409 -321
  7. package/dist/style.css +123 -92
  8. package/dist/theme.css.d.ts +0 -1
  9. package/dist/ui/OptionsPanel.d.ts +3 -1
  10. package/dist/xyflow/XYFlow.d.ts +2 -1
  11. package/dist/xyflow/XYFlowInner.d.ts +1 -1
  12. package/dist/xyflow/const.d.ts +1 -1
  13. package/dist/xyflow/diagram-to-xyflow.d.ts +1 -1
  14. package/dist/xyflow/edges/RelationshipEdge.d.ts +3 -4
  15. package/dist/xyflow/edges/utils.d.ts +4 -2
  16. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +3 -1
  17. package/dist/xyflow/nodes/element/ElementNode.d.ts +1 -1
  18. package/dist/xyflow/nodes/element/index.d.ts +1 -1
  19. package/dist/xyflow/types.d.ts +2 -2
  20. package/dist/xyflow/utils.d.ts +3 -0
  21. package/package.json +15 -14
  22. package/src/LikeC4Diagram.css.ts +4 -4
  23. package/src/LikeC4Diagram.props.ts +23 -2
  24. package/src/LikeC4Diagram.tsx +79 -31
  25. package/src/globals.css.ts +0 -1
  26. package/src/mantine/theme.ts +1 -0
  27. package/src/state/DiagramContext.tsx +0 -1
  28. package/src/state/diagramStore.ts +177 -100
  29. package/src/theme.css.ts +0 -1
  30. package/src/ui/DiagramTitlePanel.tsx +3 -3
  31. package/src/ui/DynamicViewWalkthrough.css.ts +3 -2
  32. package/src/ui/DynamicViewWalkthrough.tsx +36 -17
  33. package/src/ui/OptionsPanel.tsx +12 -12
  34. package/src/ui/options/NodeOptions.tsx +16 -19
  35. package/src/xyflow/FitviewOnDiagramChange.tsx +15 -23
  36. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +3 -6
  37. package/src/xyflow/SyncWithDiagram.tsx +21 -2
  38. package/src/xyflow/XYFlow.tsx +20 -23
  39. package/src/xyflow/XYFlowEvents.tsx +26 -8
  40. package/src/xyflow/XYFlowInner.tsx +5 -4
  41. package/src/xyflow/const.ts +1 -1
  42. package/src/xyflow/diagram-to-xyflow.ts +5 -31
  43. package/src/xyflow/edges/RelationshipEdge.tsx +158 -112
  44. package/src/xyflow/edges/edges.css.ts +32 -21
  45. package/src/xyflow/edges/utils.ts +5 -2
  46. package/src/xyflow/hooks/useLayoutConstraints.ts +17 -3
  47. package/src/xyflow/nodes/compound/CompoundNode.css.ts +40 -32
  48. package/src/xyflow/nodes/compound/CompoundNode.tsx +36 -26
  49. package/src/xyflow/nodes/element/ElementNode.tsx +20 -6
  50. package/src/xyflow/nodes/element/element.css.ts +15 -15
  51. package/src/xyflow/nodes/element/index.ts +1 -1
  52. package/src/xyflow/nodes/shared/NavigateToBtn.tsx +7 -3
  53. package/src/xyflow/types.ts +5 -2
  54. package/src/xyflow/utils.ts +48 -0
  55. package/dist/ui/index.d.ts +0 -2
  56. package/src/ui/index.ts +0 -3
package/dist/index.mjs CHANGED
@@ -2,21 +2,22 @@ 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);
4
4
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
- import { createContext, memo, useState, forwardRef, useCallback, useMemo, useEffect, useRef, useContext, useLayoutEffect, useId } from "react";
5
+ import { createContext, memo, useState, forwardRef, useCallback, useMemo, useRef, useEffect, 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, 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";
12
9
  import { DEV } from "esm-env";
13
10
  import { shallowEqual, deepEqual } from "fast-equals";
11
+ import { m, AnimatePresence, LazyMotion, domAnimation } from "framer-motion";
12
+ import { Box, MantineContext, ActionIcon, Text, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, Stack, Group, Anchor, CopyButton, Button, Paper, Spoiler, Divider, TooltipGroup, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Slider, SegmentedControl, Card } from "@mantine/core";
13
+ import { isArray, isNullish, entries, reduce, hasSubObject, hasAtLeast as hasAtLeast$1, isTruthy, first, last, clamp as clamp$1, isNumber, keys, takeWhile, isNonNull } from "remeda";
14
+ import { invariant, hasAtLeast, isAncestor, nonNullable, StepEdgeId, nonexhaustive, extractStep, defaultTheme, ElementShapes } from "@likec4/core";
14
15
  import { subscribeWithSelector, devtools } from "zustand/middleware";
15
- import { useFirstMountState, useCustomCompareEffect, useDebouncedEffect } from "@react-hookz/web";
16
+ import { useFirstMountState, useCustomCompareEffect, useDebouncedEffect, useIsomorphicLayoutEffect as useIsomorphicLayoutEffect$1 } from "@react-hookz/web";
17
+ import { assignInlineVars } from "@vanilla-extract/dynamic";
16
18
  import { line, curveCatmullRomOpen } from "d3-shape";
17
- import { motion, AnimatePresence } from "framer-motion";
18
- import { useLocalStorage } from "@mantine/hooks";
19
- import { IconPlayerPlayFilled, IconPlayerSkipBackFilled, IconPlayerStopFilled, IconPlayerSkipForwardFilled } from "@tabler/icons-react";
19
+ import { IconZoomScan, IconPlayerPlayFilled, IconPlayerSkipBackFilled, IconPlayerStopFilled, IconPlayerSkipForwardFilled } from "@tabler/icons-react";
20
+ import { useLocalStorage, useHotkeys } from "@mantine/hooks";
20
21
  function cc(names) {
21
22
  if (typeof names == "string" || typeof names == "number") return "" + names;
22
23
  let out = "";
@@ -52,7 +53,7 @@ Dispatch.prototype = dispatch.prototype = {
52
53
  on: function(typename, callback) {
53
54
  var _ = this._, T = parseTypenames$1(typename + "", _), t2, i = -1, n = T.length;
54
55
  if (arguments.length < 2) {
55
- for (; ++i < n; ) if ((t2 = (typename = T[i]).type) && (t2 = get$2(_[t2], typename.name))) return t2;
56
+ for (; ++i < n; ) if ((t2 = (typename = T[i]).type) && (t2 = get$1(_[t2], typename.name))) return t2;
56
57
  return;
57
58
  }
58
59
  if (callback != null && typeof callback != "function") throw new Error("invalid callback: " + callback);
@@ -76,7 +77,7 @@ Dispatch.prototype = dispatch.prototype = {
76
77
  for (var t2 = this._[type], i = 0, n = t2.length; i < n; ++i) t2[i].value.apply(that, args);
77
78
  }
78
79
  };
79
- function get$2(type, name) {
80
+ function get$1(type, name) {
80
81
  for (var i = 0, n = type.length, c; i < n; ++i)
81
82
  if ((c = type[i]).name === name)
82
83
  return c.value;
@@ -125,7 +126,7 @@ function selector$5(selector2) {
125
126
  }
126
127
  function selection_select(select2) {
127
128
  typeof select2 != "function" && (select2 = selector$5(select2));
128
- for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j)
129
+ for (var groups = this._groups, m2 = groups.length, subgroups = new Array(m2), j = 0; j < m2; ++j)
129
130
  for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i)
130
131
  (node = group[i]) && (subnode = select2.call(node, node.__data__, i, group)) && ("__data__" in node && (subnode.__data__ = node.__data__), subgroup[i] = subnode);
131
132
  return new Selection$1(subgroups, this._parents);
@@ -148,7 +149,7 @@ function arrayAll(select2) {
148
149
  }
149
150
  function selection_selectAll(select2) {
150
151
  typeof select2 == "function" ? select2 = arrayAll(select2) : select2 = selectorAll(select2);
151
- for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j)
152
+ for (var groups = this._groups, m2 = groups.length, subgroups = [], parents = [], j = 0; j < m2; ++j)
152
153
  for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i)
153
154
  (node = group[i]) && (subgroups.push(select2.call(node, node.__data__, i, group)), parents.push(node));
154
155
  return new Selection$1(subgroups, parents);
@@ -189,7 +190,7 @@ function selection_selectChildren(match) {
189
190
  }
190
191
  function selection_filter(match) {
191
192
  typeof match != "function" && (match = matcher(match));
192
- for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j)
193
+ for (var groups = this._groups, m2 = groups.length, subgroups = new Array(m2), j = 0; j < m2; ++j)
193
194
  for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i)
194
195
  (node = group[i]) && match.call(node, node.__data__, i, group) && subgroup.push(node);
195
196
  return new Selection$1(subgroups, this._parents);
@@ -245,7 +246,7 @@ function selection_data(value, key) {
245
246
  if (!arguments.length) return Array.from(this, datum);
246
247
  var bind = key ? bindKey : bindIndex, parents = this._parents, groups = this._groups;
247
248
  typeof value != "function" && (value = constant$3(value));
248
- for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
249
+ for (var m2 = groups.length, update = new Array(m2), enter = new Array(m2), exit = new Array(m2), j = 0; j < m2; ++j) {
249
250
  var parent = parents[j], group = groups[j], groupLength = group.length, data = arraylike(value.call(parent, parent && parent.__data__, j, parents)), dataLength = data.length, enterGroup = enter[j] = new Array(dataLength), updateGroup = update[j] = new Array(dataLength), exitGroup = exit[j] = new Array(groupLength);
250
251
  bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
251
252
  for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0)
@@ -267,7 +268,7 @@ function selection_join(onenter, onupdate, onexit) {
267
268
  return typeof onenter == "function" ? (enter = onenter(enter), enter && (enter = enter.selection())) : enter = enter.append(onenter + ""), onupdate != null && (update = onupdate(update), update && (update = update.selection())), onexit == null ? exit.remove() : onexit(exit), enter && update ? enter.merge(update).order() : update;
268
269
  }
269
270
  function selection_merge(context) {
270
- for (var selection2 = context.selection ? context.selection() : context, groups0 = this._groups, groups1 = selection2._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j)
271
+ for (var selection2 = context.selection ? context.selection() : context, groups0 = this._groups, groups1 = selection2._groups, m0 = groups0.length, m1 = groups1.length, m2 = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m2; ++j)
271
272
  for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i)
272
273
  (node = group0[i] || group1[i]) && (merge[i] = node);
273
274
  for (; j < m0; ++j)
@@ -275,7 +276,7 @@ function selection_merge(context) {
275
276
  return new Selection$1(merges, this._parents);
276
277
  }
277
278
  function selection_order() {
278
- for (var groups = this._groups, j = -1, m = groups.length; ++j < m; )
279
+ for (var groups = this._groups, j = -1, m2 = groups.length; ++j < m2; )
279
280
  for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0; )
280
281
  (node = group[i]) && (next && node.compareDocumentPosition(next) ^ 4 && next.parentNode.insertBefore(node, next), next = node);
281
282
  return this;
@@ -285,7 +286,7 @@ function selection_sort(compare) {
285
286
  function compareNode(a, b) {
286
287
  return a && b ? compare(a.__data__, b.__data__) : !a - !b;
287
288
  }
288
- for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
289
+ for (var groups = this._groups, m2 = groups.length, sortgroups = new Array(m2), j = 0; j < m2; ++j) {
289
290
  for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i)
290
291
  (node = group[i]) && (sortgroup[i] = node);
291
292
  sortgroup.sort(compareNode);
@@ -303,7 +304,7 @@ function selection_nodes() {
303
304
  return Array.from(this);
304
305
  }
305
306
  function selection_node() {
306
- for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j)
307
+ for (var groups = this._groups, j = 0, m2 = groups.length; j < m2; ++j)
307
308
  for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
308
309
  var node = group[i];
309
310
  if (node) return node;
@@ -319,7 +320,7 @@ function selection_empty() {
319
320
  return !this.node();
320
321
  }
321
322
  function selection_each(callback) {
322
- for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j)
323
+ for (var groups = this._groups, j = 0, m2 = groups.length; j < m2; ++j)
323
324
  for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i)
324
325
  (node = group[i]) && callback.call(node, node.__data__, i, group);
325
326
  return this;
@@ -556,7 +557,7 @@ function onRemove(typename) {
556
557
  return function() {
557
558
  var on = this.__on;
558
559
  if (on) {
559
- for (var j = 0, i = -1, m = on.length, o; j < m; ++j)
560
+ for (var j = 0, i = -1, m2 = on.length, o; j < m2; ++j)
560
561
  o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name ? this.removeEventListener(o.type, o.listener, o.options) : on[++i] = o;
561
562
  ++i ? on.length = i : delete this.__on;
562
563
  }
@@ -566,7 +567,7 @@ function onAdd(typename, value, options) {
566
567
  return function() {
567
568
  var on = this.__on, o, listener = contextListener(value);
568
569
  if (on) {
569
- for (var j = 0, m = on.length; j < m; ++j)
570
+ for (var j = 0, m2 = on.length; j < m2; ++j)
570
571
  if ((o = on[j]).type === typename.type && o.name === typename.name) {
571
572
  this.removeEventListener(o.type, o.listener, o.options), this.addEventListener(o.type, o.listener = listener, o.options = options), o.value = value;
572
573
  return;
@@ -580,7 +581,7 @@ function selection_on(typename, value, options) {
580
581
  if (arguments.length < 2) {
581
582
  var on = this.node().__on;
582
583
  if (on) {
583
- for (var j = 0, m = on.length, o; j < m; ++j)
584
+ for (var j = 0, m2 = on.length, o; j < m2; ++j)
584
585
  for (i = 0, o = on[j]; i < n; ++i)
585
586
  if ((t2 = typenames[i]).type === o.type && t2.name === o.name)
586
587
  return o.value;
@@ -608,7 +609,7 @@ function selection_dispatch(type, params) {
608
609
  return this.each((typeof params == "function" ? dispatchFunction : dispatchConstant)(type, params));
609
610
  }
610
611
  function* selection_iterator() {
611
- for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j)
612
+ for (var groups = this._groups, j = 0, m2 = groups.length; j < m2; ++j)
612
613
  for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i)
613
614
  (node = group[i]) && (yield node);
614
615
  }
@@ -1029,8 +1030,8 @@ function color_formatRgb() {
1029
1030
  return this.rgb().formatRgb();
1030
1031
  }
1031
1032
  function color(format) {
1032
- var m, l;
1033
- return format = (format + "").trim().toLowerCase(), (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) : l === 3 ? new Rgb(m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, (m & 15) << 4 | m & 15, 1) : l === 8 ? rgba(m >> 24 & 255, m >> 16 & 255, m >> 8 & 255, (m & 255) / 255) : l === 4 ? rgba(m >> 12 & 15 | m >> 8 & 240, m >> 8 & 15 | m >> 4 & 240, m >> 4 & 15 | m & 240, ((m & 15) << 4 | m & 15) / 255) : null) : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) : named.hasOwnProperty(format) ? rgbn(named[format]) : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;
1033
+ var m2, l;
1034
+ return format = (format + "").trim().toLowerCase(), (m2 = reHex.exec(format)) ? (l = m2[1].length, m2 = parseInt(m2[1], 16), l === 6 ? rgbn(m2) : l === 3 ? new Rgb(m2 >> 8 & 15 | m2 >> 4 & 240, m2 >> 4 & 15 | m2 & 240, (m2 & 15) << 4 | m2 & 15, 1) : l === 8 ? rgba(m2 >> 24 & 255, m2 >> 16 & 255, m2 >> 8 & 255, (m2 & 255) / 255) : l === 4 ? rgba(m2 >> 12 & 15 | m2 >> 8 & 240, m2 >> 8 & 15 | m2 >> 4 & 240, m2 >> 4 & 15 | m2 & 240, ((m2 & 15) << 4 | m2 & 15) / 255) : null) : (m2 = reRgbInteger.exec(format)) ? new Rgb(m2[1], m2[2], m2[3], 1) : (m2 = reRgbPercent.exec(format)) ? new Rgb(m2[1] * 255 / 100, m2[2] * 255 / 100, m2[3] * 255 / 100, 1) : (m2 = reRgbaInteger.exec(format)) ? rgba(m2[1], m2[2], m2[3], m2[4]) : (m2 = reRgbaPercent.exec(format)) ? rgba(m2[1] * 255 / 100, m2[2] * 255 / 100, m2[3] * 255 / 100, m2[4]) : (m2 = reHslPercent.exec(format)) ? hsla(m2[1], m2[2] / 100, m2[3] / 100, 1) : (m2 = reHslaPercent.exec(format)) ? hsla(m2[1], m2[2] / 100, m2[3] / 100, m2[4]) : named.hasOwnProperty(format) ? rgbn(named[format]) : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) : null;
1034
1035
  }
1035
1036
  function rgbn(n) {
1036
1037
  return new Rgb(n >> 16 & 255, n >> 8 & 255, n & 255, 1);
@@ -1218,8 +1219,8 @@ function decompose(a, b, c, d, e, f) {
1218
1219
  }
1219
1220
  var svgNode;
1220
1221
  function parseCss(value) {
1221
- const m = new (typeof DOMMatrix == "function" ? DOMMatrix : WebKitCSSMatrix)(value + "");
1222
- return m.isIdentity ? identity$1 : decompose(m.a, m.b, m.c, m.d, m.e, m.f);
1222
+ const m2 = new (typeof DOMMatrix == "function" ? DOMMatrix : WebKitCSSMatrix)(value + "");
1223
+ return m2.isIdentity ? identity$1 : decompose(m2.a, m2.b, m2.c, m2.d, m2.e, m2.f);
1223
1224
  }
1224
1225
  function parseSvg(value) {
1225
1226
  return value == null || (svgNode || (svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g")), svgNode.setAttribute("transform", value), !(value = svgNode.transform.baseVal.consolidate())) ? identity$1 : (value = value.matrix, decompose(value.a, value.b, value.c, value.d, value.e, value.f));
@@ -1377,16 +1378,16 @@ function schedule(node, name, id2, index2, group, timing) {
1377
1378
  });
1378
1379
  }
1379
1380
  function init(node, id2) {
1380
- var schedule2 = get$1(node, id2);
1381
+ var schedule2 = get(node, id2);
1381
1382
  if (schedule2.state > CREATED) throw new Error("too late; already scheduled");
1382
1383
  return schedule2;
1383
1384
  }
1384
1385
  function set(node, id2) {
1385
- var schedule2 = get$1(node, id2);
1386
+ var schedule2 = get(node, id2);
1386
1387
  if (schedule2.state > STARTED) throw new Error("too late; already running");
1387
1388
  return schedule2;
1388
1389
  }
1389
- function get$1(node, id2) {
1390
+ function get(node, id2) {
1390
1391
  var schedule2 = node.__transition;
1391
1392
  if (!schedule2 || !(schedule2 = schedule2[id2])) throw new Error("transition not found");
1392
1393
  return schedule2;
@@ -1478,7 +1479,7 @@ function tweenFunction(id2, name, value) {
1478
1479
  function transition_tween(name, value) {
1479
1480
  var id2 = this._id;
1480
1481
  if (name += "", arguments.length < 2) {
1481
- for (var tween = get$1(this.node(), id2).tween, i = 0, n = tween.length, t2; i < n; ++i)
1482
+ for (var tween = get(this.node(), id2).tween, i = 0, n = tween.length, t2; i < n; ++i)
1482
1483
  if ((t2 = tween[i]).name === name)
1483
1484
  return t2.value;
1484
1485
  return null;
@@ -1491,7 +1492,7 @@ function tweenValue(transition, name, value) {
1491
1492
  var schedule2 = set(this, id2);
1492
1493
  (schedule2.value || (schedule2.value = {}))[name] = value.apply(this, arguments);
1493
1494
  }), function(node) {
1494
- return get$1(node, id2).value[name];
1495
+ return get(node, id2).value[name];
1495
1496
  };
1496
1497
  }
1497
1498
  function interpolate(a, b) {
@@ -1586,7 +1587,7 @@ function delayConstant(id2, value) {
1586
1587
  }
1587
1588
  function transition_delay(value) {
1588
1589
  var id2 = this._id;
1589
- return arguments.length ? this.each((typeof value == "function" ? delayFunction : delayConstant)(id2, value)) : get$1(this.node(), id2).delay;
1590
+ return arguments.length ? this.each((typeof value == "function" ? delayFunction : delayConstant)(id2, value)) : get(this.node(), id2).delay;
1590
1591
  }
1591
1592
  function durationFunction(id2, value) {
1592
1593
  return function() {
@@ -1600,7 +1601,7 @@ function durationConstant(id2, value) {
1600
1601
  }
1601
1602
  function transition_duration(value) {
1602
1603
  var id2 = this._id;
1603
- return arguments.length ? this.each((typeof value == "function" ? durationFunction : durationConstant)(id2, value)) : get$1(this.node(), id2).duration;
1604
+ return arguments.length ? this.each((typeof value == "function" ? durationFunction : durationConstant)(id2, value)) : get(this.node(), id2).duration;
1604
1605
  }
1605
1606
  function easeConstant(id2, value) {
1606
1607
  if (typeof value != "function") throw new Error();
@@ -1610,7 +1611,7 @@ function easeConstant(id2, value) {
1610
1611
  }
1611
1612
  function transition_ease(value) {
1612
1613
  var id2 = this._id;
1613
- return arguments.length ? this.each(easeConstant(id2, value)) : get$1(this.node(), id2).ease;
1614
+ return arguments.length ? this.each(easeConstant(id2, value)) : get(this.node(), id2).ease;
1614
1615
  }
1615
1616
  function easeVarying(id2, value) {
1616
1617
  return function() {
@@ -1625,14 +1626,14 @@ function transition_easeVarying(value) {
1625
1626
  }
1626
1627
  function transition_filter(match) {
1627
1628
  typeof match != "function" && (match = matcher(match));
1628
- for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j)
1629
+ for (var groups = this._groups, m2 = groups.length, subgroups = new Array(m2), j = 0; j < m2; ++j)
1629
1630
  for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i)
1630
1631
  (node = group[i]) && match.call(node, node.__data__, i, group) && subgroup.push(node);
1631
1632
  return new Transition(subgroups, this._parents, this._name, this._id);
1632
1633
  }
1633
1634
  function transition_merge(transition) {
1634
1635
  if (transition._id !== this._id) throw new Error();
1635
- for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j)
1636
+ for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m2 = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m2; ++j)
1636
1637
  for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i)
1637
1638
  (node = group0[i] || group1[i]) && (merge[i] = node);
1638
1639
  for (; j < m0; ++j)
@@ -1654,7 +1655,7 @@ function onFunction(id2, name, listener) {
1654
1655
  }
1655
1656
  function transition_on(name, listener) {
1656
1657
  var id2 = this._id;
1657
- return arguments.length < 2 ? get$1(this.node(), id2).on.on(name) : this.each(onFunction(id2, name, listener));
1658
+ return arguments.length < 2 ? get(this.node(), id2).on.on(name) : this.each(onFunction(id2, name, listener));
1658
1659
  }
1659
1660
  function removeFunction(id2) {
1660
1661
  return function() {
@@ -1669,18 +1670,18 @@ function transition_remove() {
1669
1670
  function transition_select(select2) {
1670
1671
  var name = this._name, id2 = this._id;
1671
1672
  typeof select2 != "function" && (select2 = selector$5(select2));
1672
- for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j)
1673
+ for (var groups = this._groups, m2 = groups.length, subgroups = new Array(m2), j = 0; j < m2; ++j)
1673
1674
  for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i)
1674
- (node = group[i]) && (subnode = select2.call(node, node.__data__, i, group)) && ("__data__" in node && (subnode.__data__ = node.__data__), subgroup[i] = subnode, schedule(subgroup[i], name, id2, i, subgroup, get$1(node, id2)));
1675
+ (node = group[i]) && (subnode = select2.call(node, node.__data__, i, group)) && ("__data__" in node && (subnode.__data__ = node.__data__), subgroup[i] = subnode, schedule(subgroup[i], name, id2, i, subgroup, get(node, id2)));
1675
1676
  return new Transition(subgroups, this._parents, name, id2);
1676
1677
  }
1677
1678
  function transition_selectAll(select2) {
1678
1679
  var name = this._name, id2 = this._id;
1679
1680
  typeof select2 != "function" && (select2 = selectorAll(select2));
1680
- for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j)
1681
+ for (var groups = this._groups, m2 = groups.length, subgroups = [], parents = [], j = 0; j < m2; ++j)
1681
1682
  for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i)
1682
1683
  if (node = group[i]) {
1683
- for (var children2 = select2.call(node, node.__data__, i, group), child, inherit2 = get$1(node, id2), k = 0, l = children2.length; k < l; ++k)
1684
+ for (var children2 = select2.call(node, node.__data__, i, group), child, inherit2 = get(node, id2), k = 0, l = children2.length; k < l; ++k)
1684
1685
  (child = children2[k]) && schedule(child, name, id2, k, children2, inherit2);
1685
1686
  subgroups.push(children2), parents.push(node);
1686
1687
  }
@@ -1782,10 +1783,10 @@ function transition_textTween(value) {
1782
1783
  return this.tween(key, textTween(value));
1783
1784
  }
1784
1785
  function transition_transition() {
1785
- for (var name = this._name, id0 = this._id, id1 = newId(), groups = this._groups, m = groups.length, j = 0; j < m; ++j)
1786
+ for (var name = this._name, id0 = this._id, id1 = newId(), groups = this._groups, m2 = groups.length, j = 0; j < m2; ++j)
1786
1787
  for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i)
1787
1788
  if (node = group[i]) {
1788
- var inherit2 = get$1(node, id0);
1789
+ var inherit2 = get(node, id0);
1789
1790
  schedule(node, name, id1, i, group, {
1790
1791
  time: inherit2.time + inherit2.delay + inherit2.duration,
1791
1792
  delay: 0,
@@ -1866,7 +1867,7 @@ function inherit(node, id2) {
1866
1867
  function selection_transition(name) {
1867
1868
  var id2, timing;
1868
1869
  name instanceof Transition ? (id2 = name._id, name = name._name) : (id2 = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "");
1869
- for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j)
1870
+ for (var groups = this._groups, m2 = groups.length, j = 0; j < m2; ++j)
1870
1871
  for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i)
1871
1872
  (node = group[i]) && schedule(node, name, id2, i, group, timing || inherit(node, id2));
1872
1873
  return new Transition(groups, this._parents, name, id2);
@@ -2401,7 +2402,7 @@ function evaluateAbsolutePosition(position, parentId, nodeLookup, nodeOrigin = [
2401
2402
  let nextParentId = parentId;
2402
2403
  const positionAbsolute = { ...position };
2403
2404
  for (; nextParentId; ) {
2404
- const parent = nodeLookup.get(parentId);
2405
+ const parent = nodeLookup.get(nextParentId);
2405
2406
  if (nextParentId = parent == null ? void 0 : parent.parentId, parent) {
2406
2407
  const origin = parent.origin || nodeOrigin, xOffset = (parent.measured.width ?? 0) * origin[0], yOffset = (parent.measured.height ?? 0) * origin[1];
2407
2408
  positionAbsolute.x += parent.position.x - xOffset, positionAbsolute.y += parent.position.y - yOffset;
@@ -2436,21 +2437,21 @@ const isMouseEvent = (event) => "clientX" in event, getEventPosition = (event, b
2436
2437
  x: evtX - ((bounds == null ? void 0 : bounds.left) ?? 0),
2437
2438
  y: evtY - ((bounds == null ? void 0 : bounds.top) ?? 0)
2438
2439
  };
2439
- }, getHandleBounds = (selector2, nodeElement, zoom2, nodeOrigin = [0, 0]) => {
2440
+ }, getHandleBounds = (selector2, nodeElement, nodeBounds, zoom2, nodeOrigin = [0, 0]) => {
2440
2441
  const handles = nodeElement.querySelectorAll(selector2);
2441
2442
  if (!handles || !handles.length)
2442
2443
  return null;
2443
- const handlesArray = Array.from(handles), nodeBounds = nodeElement.getBoundingClientRect(), nodeOffset = {
2444
- x: nodeBounds.width * nodeOrigin[0],
2445
- y: nodeBounds.height * nodeOrigin[1]
2444
+ const handlesArray = Array.from(handles), nodeOffset = {
2445
+ x: nodeBounds.left + nodeBounds.width * nodeOrigin[0],
2446
+ y: nodeBounds.top + nodeBounds.height * nodeOrigin[1]
2446
2447
  };
2447
2448
  return handlesArray.map((handle) => {
2448
2449
  const handleBounds = handle.getBoundingClientRect();
2449
2450
  return {
2450
2451
  id: handle.getAttribute("data-handleid"),
2451
2452
  position: handle.getAttribute("data-handlepos"),
2452
- x: (handleBounds.left - nodeBounds.left - nodeOffset.x) / zoom2,
2453
- y: (handleBounds.top - nodeBounds.top - nodeOffset.y) / zoom2,
2453
+ x: (handleBounds.left - nodeOffset.x) / zoom2,
2454
+ y: (handleBounds.top - nodeOffset.y) / zoom2,
2454
2455
  ...getDimensions(handle)
2455
2456
  };
2456
2457
  });
@@ -2816,21 +2817,24 @@ function updateNodeInternals(updates, nodeLookup, parentLookup, domNode, nodeOri
2816
2817
  }, updatedInternals = !0;
2817
2818
  else if (node) {
2818
2819
  const dimensions = getDimensions(update.nodeElement), dimensionChanged = node.measured.width !== dimensions.width || node.measured.height !== dimensions.height;
2819
- !!(dimensions.width && dimensions.height && (dimensionChanged || !node.internals.handleBounds || update.force)) && (node.measured = dimensions, node.internals = {
2820
- ...node.internals,
2821
- handleBounds: {
2822
- source: getHandleBounds(".source", update.nodeElement, zoom2, node.origin || nodeOrigin),
2823
- target: getHandleBounds(".target", update.nodeElement, zoom2, node.origin || nodeOrigin)
2824
- }
2825
- }, updatedInternals = !0, dimensionChanged && (changes.push({
2826
- id: node.id,
2827
- type: "dimensions",
2828
- dimensions
2829
- }), node.expandParent && node.parentId && parentExpandChildren.push({
2830
- id: node.id,
2831
- parentId: node.parentId,
2832
- rect: nodeToRect(node, nodeOrigin)
2833
- })));
2820
+ if (!!(dimensions.width && dimensions.height && (dimensionChanged || !node.internals.handleBounds || update.force))) {
2821
+ const nodeBounds = update.nodeElement.getBoundingClientRect();
2822
+ node.measured = dimensions, node.internals = {
2823
+ ...node.internals,
2824
+ handleBounds: {
2825
+ source: getHandleBounds(".source", update.nodeElement, nodeBounds, zoom2, node.origin || nodeOrigin),
2826
+ target: getHandleBounds(".target", update.nodeElement, nodeBounds, zoom2, node.origin || nodeOrigin)
2827
+ }
2828
+ }, updatedInternals = !0, dimensionChanged && (changes.push({
2829
+ id: node.id,
2830
+ type: "dimensions",
2831
+ dimensions
2832
+ }), node.expandParent && node.parentId && parentExpandChildren.push({
2833
+ id: node.id,
2834
+ parentId: node.parentId,
2835
+ rect: nodeToRect(node, nodeOrigin)
2836
+ }));
2837
+ }
2834
2838
  }
2835
2839
  }), parentExpandChildren.length > 0) {
2836
2840
  const parentExpandChanges = handleExpandParent(parentExpandChildren, nodeLookup, parentLookup, nodeOrigin);
@@ -2935,7 +2939,7 @@ function getEventHandlerParams({ nodeId, dragItems, nodeLookup }) {
2935
2939
  ];
2936
2940
  }
2937
2941
  function XYDrag({ onNodeMouseDown, getStoreItems, onDragStart, onDrag, onDragStop }) {
2938
- let lastPos = { x: null, y: null }, autoPanId = 0, dragItems = /* @__PURE__ */ new Map(), autoPanStarted = !1, mousePosition = { x: 0, y: 0 }, containerBounds = null, dragStarted = !1, d3Selection = null;
2942
+ let lastPos = { x: null, y: null }, autoPanId = 0, dragItems = /* @__PURE__ */ new Map(), autoPanStarted = !1, mousePosition = { x: 0, y: 0 }, containerBounds = null, dragStarted = !1, d3Selection = null, abortDrag = !1;
2939
2943
  function update({ noDragClassName, handleSelector, domNode, isSelectable, nodeId }) {
2940
2944
  d3Selection = select(domNode);
2941
2945
  function updateNodes({ x, y }, dragEvent) {
@@ -3005,16 +3009,18 @@ function XYDrag({ onNodeMouseDown, getStoreItems, onDragStart, onDrag, onDragSto
3005
3009
  }
3006
3010
  const d3DragInstance = drag().on("start", (event) => {
3007
3011
  const { domNode: domNode2, nodeDragThreshold, transform: transform2, snapGrid, snapToGrid } = getStoreItems();
3008
- nodeDragThreshold === 0 && startDrag(event), lastPos = getPointerPosition(event.sourceEvent, { transform: transform2, snapGrid, snapToGrid }), containerBounds = (domNode2 == null ? void 0 : domNode2.getBoundingClientRect()) || null, mousePosition = getEventPosition(event.sourceEvent, containerBounds);
3012
+ abortDrag = !1, nodeDragThreshold === 0 && startDrag(event), lastPos = getPointerPosition(event.sourceEvent, { transform: transform2, snapGrid, snapToGrid }), containerBounds = (domNode2 == null ? void 0 : domNode2.getBoundingClientRect()) || null, mousePosition = getEventPosition(event.sourceEvent, containerBounds);
3009
3013
  }).on("drag", (event) => {
3010
3014
  const { autoPanOnNodeDrag, transform: transform2, snapGrid, snapToGrid, nodeDragThreshold } = getStoreItems(), pointerPos = getPointerPosition(event.sourceEvent, { transform: transform2, snapGrid, snapToGrid });
3011
- if (!autoPanStarted && autoPanOnNodeDrag && dragStarted && (autoPanStarted = !0, autoPan()), !dragStarted) {
3012
- const x = pointerPos.xSnapped - (lastPos.x ?? 0), y = pointerPos.ySnapped - (lastPos.y ?? 0);
3013
- Math.sqrt(x * x + y * y) > nodeDragThreshold && startDrag(event);
3015
+ if (event.sourceEvent.type === "touchmove" && event.sourceEvent.touches.length > 1 && (abortDrag = !0), !abortDrag) {
3016
+ if (!autoPanStarted && autoPanOnNodeDrag && dragStarted && (autoPanStarted = !0, autoPan()), !dragStarted) {
3017
+ const x = pointerPos.xSnapped - (lastPos.x ?? 0), y = pointerPos.ySnapped - (lastPos.y ?? 0);
3018
+ Math.sqrt(x * x + y * y) > nodeDragThreshold && startDrag(event);
3019
+ }
3020
+ (lastPos.x !== pointerPos.xSnapped || lastPos.y !== pointerPos.ySnapped) && dragItems && dragStarted && (mousePosition = getEventPosition(event.sourceEvent, containerBounds), updateNodes(pointerPos, event.sourceEvent));
3014
3021
  }
3015
- (lastPos.x !== pointerPos.xSnapped || lastPos.y !== pointerPos.ySnapped) && dragItems && dragStarted && (mousePosition = getEventPosition(event.sourceEvent, containerBounds), updateNodes(pointerPos, event.sourceEvent));
3016
3022
  }).on("end", (event) => {
3017
- if (dragStarted && (autoPanStarted = !1, dragStarted = !1, cancelAnimationFrame(autoPanId), dragItems.size > 0)) {
3023
+ if (!(!dragStarted || abortDrag) && (autoPanStarted = !1, dragStarted = !1, cancelAnimationFrame(autoPanId), dragItems.size > 0)) {
3018
3024
  const { nodeLookup, updateNodePositions, onNodeDragStop, onSelectionDragStop } = getStoreItems();
3019
3025
  if (updateNodePositions(dragItems, !1), onDragStop || onNodeDragStop || !nodeId && onSelectionDragStop) {
3020
3026
  const [currentNode, currentNodes] = getEventHandlerParams({
@@ -3288,10 +3294,15 @@ function createPanZoomEndHandler({ zoomPanValues, panOnDrag, panOnScroll, onDrag
3288
3294
  }
3289
3295
  function createFilter({ zoomActivationKeyPressed, zoomOnScroll, zoomOnPinch, panOnDrag, panOnScroll, zoomOnDoubleClick, userSelectionActive, noWheelClassName, noPanClassName, lib }) {
3290
3296
  return (event) => {
3297
+ var _a;
3291
3298
  const zoomScroll = zoomActivationKeyPressed || zoomOnScroll, pinchZoom = zoomOnPinch && event.ctrlKey;
3292
3299
  if (event.button === 1 && event.type === "mousedown" && (isWrappedWithClass(event, `${lib}-flow__node`) || isWrappedWithClass(event, `${lib}-flow__edge`)))
3293
3300
  return !0;
3294
- if (!panOnDrag && !zoomScroll && !panOnScroll && !zoomOnDoubleClick && !zoomOnPinch || userSelectionActive || isWrappedWithClass(event, noWheelClassName) && event.type === "wheel" || isWrappedWithClass(event, noPanClassName) && (event.type !== "wheel" || panOnScroll && event.type === "wheel" && !zoomActivationKeyPressed) || !zoomOnPinch && event.ctrlKey && event.type === "wheel" || !zoomScroll && !panOnScroll && !pinchZoom && event.type === "wheel" || !panOnDrag && (event.type === "mousedown" || event.type === "touchstart") || Array.isArray(panOnDrag) && !panOnDrag.includes(event.button) && event.type === "mousedown")
3301
+ if (!panOnDrag && !zoomScroll && !panOnScroll && !zoomOnDoubleClick && !zoomOnPinch || userSelectionActive || isWrappedWithClass(event, noWheelClassName) && event.type === "wheel" || isWrappedWithClass(event, noPanClassName) && (event.type !== "wheel" || panOnScroll && event.type === "wheel" && !zoomActivationKeyPressed) || !zoomOnPinch && event.ctrlKey && event.type === "wheel")
3302
+ return !1;
3303
+ if (!zoomOnPinch && event.type === "touchstart" && ((_a = event.touches) == null ? void 0 : _a.length) > 1)
3304
+ return event.preventDefault(), !1;
3305
+ if (!zoomScroll && !panOnScroll && !pinchZoom && event.type === "wheel" || !panOnDrag && (event.type === "mousedown" || event.type === "touchstart") || Array.isArray(panOnDrag) && !panOnDrag.includes(event.button) && event.type === "mousedown")
3295
3306
  return !1;
3296
3307
  const buttonAllowed = Array.isArray(panOnDrag) && panOnDrag.includes(event.button) || !event.button || event.button <= 1;
3297
3308
  return (!event.ctrlKey || event.type === "wheel") && buttonAllowed;
@@ -3964,7 +3975,7 @@ function elementToRemoveChange(item) {
3964
3975
  type: "remove"
3965
3976
  };
3966
3977
  }
3967
- const isNode = (element2) => isNodeBase(element2);
3978
+ const isNode = (element2) => isNodeBase(element2), isEdge = (element2) => isEdgeBase(element2);
3968
3979
  function fixedForwardRef(render) {
3969
3980
  return forwardRef(render);
3970
3981
  }
@@ -4026,6 +4037,8 @@ function useReactFlow() {
4026
4037
  const viewportHelper = useViewportHelper(), store = useStoreApi(), batchContext = useBatchContext(), viewportInitialized = useStore(selector$m), generalHelper = useMemo(() => {
4027
4038
  const getInternalNode = (id2) => store.getState().nodeLookup.get(id2), setNodes = (payload) => {
4028
4039
  batchContext.nodeQueue.push(payload);
4040
+ }, setEdges = (payload) => {
4041
+ batchContext.edgeQueue.push(payload);
4029
4042
  }, getNodeRect = (node) => {
4030
4043
  var _a, _b;
4031
4044
  const { nodeLookup, nodeOrigin } = store.getState(), nodeToUse = isNode(node) ? node : nodeLookup.get(node.id), position = nodeToUse.parentId ? evaluateAbsolutePosition(nodeToUse.position, nodeToUse.parentId, nodeLookup, nodeOrigin) : nodeToUse.position, nodeWithPosition = {
@@ -4044,6 +4057,14 @@ function useReactFlow() {
4044
4057
  }
4045
4058
  return node;
4046
4059
  }));
4060
+ }, updateEdge2 = (id2, edgeUpdate, options = { replace: !1 }) => {
4061
+ setEdges((prevEdges) => prevEdges.map((edge) => {
4062
+ if (edge.id === id2) {
4063
+ const nextEdge = typeof edgeUpdate == "function" ? edgeUpdate(edge) : edgeUpdate;
4064
+ return options.replace && isEdge(nextEdge) ? nextEdge : { ...edge, ...nextEdge };
4065
+ }
4066
+ return edge;
4067
+ }));
4047
4068
  };
4048
4069
  return {
4049
4070
  getNodes: () => store.getState().nodes.map((n) => ({ ...n })),
@@ -4058,9 +4079,7 @@ function useReactFlow() {
4058
4079
  },
4059
4080
  getEdge: (id2) => store.getState().edgeLookup.get(id2),
4060
4081
  setNodes,
4061
- setEdges: (payload) => {
4062
- batchContext.edgeQueue.push(payload);
4063
- },
4082
+ setEdges,
4064
4083
  addNodes: (payload) => {
4065
4084
  const newNodes = Array.isArray(payload) ? payload : [payload];
4066
4085
  batchContext.nodeQueue.push((nodes) => [...nodes, ...newNodes]);
@@ -4122,6 +4141,13 @@ function useReactFlow() {
4122
4141
  const nextData = typeof dataUpdate == "function" ? dataUpdate(node) : dataUpdate;
4123
4142
  return options.replace ? { ...node, data: nextData } : { ...node, data: { ...node.data, ...nextData } };
4124
4143
  }, options);
4144
+ },
4145
+ updateEdge: updateEdge2,
4146
+ updateEdgeData: (id2, dataUpdate, options = { replace: !1 }) => {
4147
+ updateEdge2(id2, (edge) => {
4148
+ const nextData = typeof dataUpdate == "function" ? dataUpdate(edge) : dataUpdate;
4149
+ return options.replace ? { ...edge, data: nextData } : { ...edge, data: { ...edge.data, ...nextData } };
4150
+ }, options);
4125
4151
  }
4126
4152
  };
4127
4153
  }, []);
@@ -4608,7 +4634,8 @@ function useResizeObserver() {
4608
4634
  const id2 = entry.target.getAttribute("data-id");
4609
4635
  updates.set(id2, {
4610
4636
  id: id2,
4611
- nodeElement: entry.target
4637
+ nodeElement: entry.target,
4638
+ force: !0
4612
4639
  });
4613
4640
  }), updateNodeInternals2(updates);
4614
4641
  }));
@@ -4617,10 +4644,10 @@ function useResizeObserver() {
4617
4644
  }, [resizeObserver]), resizeObserver;
4618
4645
  }
4619
4646
  function useNodeObserver({ node, nodeType, hasDimensions, resizeObserver }) {
4620
- const store = useStoreApi(), nodeRef = useRef(null), observedNode = useRef(null), prevSourcePosition = useRef(node.sourcePosition), prevTargetPosition = useRef(node.targetPosition), prevType = useRef(nodeType), isInitialized = hasDimensions && !!node.internals.handleBounds && !node.hidden;
4647
+ const store = useStoreApi(), nodeRef = useRef(null), observedNode = useRef(null), prevSourcePosition = useRef(node.sourcePosition), prevTargetPosition = useRef(node.targetPosition), prevType = useRef(nodeType), isInitialized = hasDimensions && !!node.internals.handleBounds;
4621
4648
  return useEffect(() => {
4622
- nodeRef.current && (!isInitialized || observedNode.current !== nodeRef.current) && (observedNode.current && (resizeObserver == null || resizeObserver.unobserve(observedNode.current)), resizeObserver == null || resizeObserver.observe(nodeRef.current), observedNode.current = nodeRef.current);
4623
- }, [isInitialized]), useEffect(() => () => {
4649
+ nodeRef.current && !node.hidden && (!isInitialized || observedNode.current !== nodeRef.current) && (observedNode.current && (resizeObserver == null || resizeObserver.unobserve(observedNode.current)), resizeObserver == null || resizeObserver.observe(nodeRef.current), observedNode.current = nodeRef.current);
4650
+ }, [isInitialized, node.hidden]), useEffect(() => () => {
4624
4651
  observedNode.current && (resizeObserver == null || resizeObserver.unobserve(observedNode.current), observedNode.current = null);
4625
4652
  }, []), useEffect(() => {
4626
4653
  if (nodeRef.current) {
@@ -4700,7 +4727,7 @@ function NodeWrapper({ id: id2, onClick, onMouseEnter, onMouseMove, onMouseLeave
4700
4727
  visibility: hasDimensions ? "visible" : "hidden",
4701
4728
  ...node.style,
4702
4729
  ...inlineDimensions
4703
- }, "data-id": id2, "data-testid": `rf__node-${id2}`, onMouseEnter: onMouseEnterHandler, onMouseMove: onMouseMoveHandler, onMouseLeave: onMouseLeaveHandler, onContextMenu: onContextMenuHandler, onClick: onSelectNodeHandler, onDoubleClick: onDoubleClickHandler, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : void 0, "aria-describedby": disableKeyboardA11y ? void 0 : `${ARIA_NODE_DESC_KEY}-${rfId}`, "aria-label": node.ariaLabel, children: jsx(Provider, { value: id2, children: jsx(NodeComponent, { id: id2, data: node.data, type: nodeType, positionAbsoluteX: clampedPosition.x, positionAbsoluteY: clampedPosition.y, selected: node.selected, isConnectable, sourcePosition: node.sourcePosition, targetPosition: node.targetPosition, dragging, dragHandle: node.dragHandle, zIndex: internals.z, ...nodeDimensions }) }) });
4730
+ }, "data-id": id2, "data-testid": `rf__node-${id2}`, onMouseEnter: onMouseEnterHandler, onMouseMove: onMouseMoveHandler, onMouseLeave: onMouseLeaveHandler, onContextMenu: onContextMenuHandler, onClick: onSelectNodeHandler, onDoubleClick: onDoubleClickHandler, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : void 0, "aria-describedby": disableKeyboardA11y ? void 0 : `${ARIA_NODE_DESC_KEY}-${rfId}`, "aria-label": node.ariaLabel, children: jsx(Provider, { value: id2, children: jsx(NodeComponent, { id: id2, data: node.data, type: nodeType, positionAbsoluteX: clampedPosition.x, positionAbsoluteY: clampedPosition.y, selected: node.selected, selectable: isSelectable, draggable: isDraggable, deletable: node.deletable ?? !0, isConnectable, sourcePosition: node.sourcePosition, targetPosition: node.targetPosition, dragging, dragHandle: node.dragHandle, zIndex: internals.z, parentId: node.parentId, ...nodeDimensions }) }) });
4704
4731
  }
4705
4732
  const selector$d = (s) => ({
4706
4733
  nodesDraggable: s.nodesDraggable,
@@ -4792,18 +4819,18 @@ const Marker = ({ id: id2, type, color: color2, width = 12.5, height = 12.5, mar
4792
4819
  MarkerDefinitions.displayName = "MarkerDefinitions";
4793
4820
  var MarkerDefinitions$1 = memo(MarkerDefinitions);
4794
4821
  function EdgeTextComponent({ x, y, label, labelStyle = {}, labelShowBg = !0, labelBgStyle = {}, labelBgPadding = [2, 4], labelBgBorderRadius = 2, children: children2, className, ...rest }) {
4795
- const [edgeTextBbox, setEdgeTextBbox] = useState({ x: 1, y: 0, width: 0, height: 0 }), edgeTextClasses = cc(["react-flow__edge-textwrapper", className]), onEdgeTextRefChange = useCallback((edgeRef) => {
4796
- if (edgeRef === null)
4797
- return;
4798
- const textBbox = edgeRef.getBBox();
4799
- setEdgeTextBbox({
4800
- x: textBbox.x,
4801
- y: textBbox.y,
4802
- width: textBbox.width,
4803
- height: textBbox.height
4804
- });
4805
- }, []);
4806
- return typeof label > "u" || !label ? null : jsxs("g", { transform: `translate(${x - edgeTextBbox.width / 2} ${y - edgeTextBbox.height / 2})`, className: edgeTextClasses, visibility: edgeTextBbox.width ? "visible" : "hidden", ...rest, children: [labelShowBg && jsx("rect", { width: edgeTextBbox.width + 2 * labelBgPadding[0], x: -labelBgPadding[0], y: -labelBgPadding[1], height: edgeTextBbox.height + 2 * labelBgPadding[1], className: "react-flow__edge-textbg", style: labelBgStyle, rx: labelBgBorderRadius, ry: labelBgBorderRadius }), jsx("text", { className: "react-flow__edge-text", y: edgeTextBbox.height / 2, dy: "0.3em", ref: onEdgeTextRefChange, style: labelStyle, children: label }), children2] });
4822
+ const [edgeTextBbox, setEdgeTextBbox] = useState({ x: 1, y: 0, width: 0, height: 0 }), edgeTextClasses = cc(["react-flow__edge-textwrapper", className]), edgeTextRef = useRef(null);
4823
+ return useEffect(() => {
4824
+ if (edgeTextRef.current) {
4825
+ const textBbox = edgeTextRef.current.getBBox();
4826
+ setEdgeTextBbox({
4827
+ x: textBbox.x,
4828
+ y: textBbox.y,
4829
+ width: textBbox.width,
4830
+ height: textBbox.height
4831
+ });
4832
+ }
4833
+ }, [label]), typeof label > "u" || !label ? null : jsxs("g", { transform: `translate(${x - edgeTextBbox.width / 2} ${y - edgeTextBbox.height / 2})`, className: edgeTextClasses, visibility: edgeTextBbox.width ? "visible" : "hidden", ...rest, children: [labelShowBg && jsx("rect", { width: edgeTextBbox.width + 2 * labelBgPadding[0], x: -labelBgPadding[0], y: -labelBgPadding[1], height: edgeTextBbox.height + 2 * labelBgPadding[1], className: "react-flow__edge-textbg", style: labelBgStyle, rx: labelBgBorderRadius, ry: labelBgBorderRadius }), jsx("text", { className: "react-flow__edge-text", y: edgeTextBbox.height / 2, dy: "0.3em", ref: edgeTextRef, style: labelStyle, children: label }), children2] });
4807
4834
  }
4808
4835
  EdgeTextComponent.displayName = "EdgeText";
4809
4836
  const EdgeText = memo(EdgeTextComponent);
@@ -5037,7 +5064,7 @@ function EdgeWrapper({ id: id2, edgesFocusable, edgesUpdatable, elementsSelectab
5037
5064
  updating: updateHover,
5038
5065
  selectable: isSelectable
5039
5066
  }
5040
- ]), onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : "img", "data-id": id2, "data-testid": `rf__edge-${id2}`, "aria-label": edge.ariaLabel === null ? void 0 : edge.ariaLabel || `Edge from ${edge.source} to ${edge.target}`, "aria-describedby": isFocusable ? `${ARIA_EDGE_DESC_KEY}-${rfId}` : void 0, ref: edgeRef, children: [!updating && jsx(EdgeComponent, { id: id2, source: edge.source, target: edge.target, type: edge.type, selected: edge.selected, animated: edge.animated, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, labelBgPadding: edge.labelBgPadding, labelBgBorderRadius: edge.labelBgBorderRadius, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data: edge.data, style: edge.style, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle, markerStart: markerStartUrl, markerEnd: markerEndUrl, pathOptions: "pathOptions" in edge ? edge.pathOptions : void 0, interactionWidth: edge.interactionWidth }), isUpdatable && jsx(EdgeUpdateAnchors, { edge, isUpdatable, edgeUpdaterRadius, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, setUpdateHover, setUpdating, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle })] }) });
5067
+ ]), onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : "img", "data-id": id2, "data-testid": `rf__edge-${id2}`, "aria-label": edge.ariaLabel === null ? void 0 : edge.ariaLabel || `Edge from ${edge.source} to ${edge.target}`, "aria-describedby": isFocusable ? `${ARIA_EDGE_DESC_KEY}-${rfId}` : void 0, ref: edgeRef, children: [!updating && jsx(EdgeComponent, { id: id2, source: edge.source, target: edge.target, type: edge.type, selected: edge.selected, animated: edge.animated, selectable: isSelectable, deletable: edge.deletable ?? !0, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, labelBgPadding: edge.labelBgPadding, labelBgBorderRadius: edge.labelBgBorderRadius, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data: edge.data, style: edge.style, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle, markerStart: markerStartUrl, markerEnd: markerEndUrl, pathOptions: "pathOptions" in edge ? edge.pathOptions : void 0, interactionWidth: edge.interactionWidth }), isUpdatable && jsx(EdgeUpdateAnchors, { edge, isUpdatable, edgeUpdaterRadius, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, setUpdateHover, setUpdating, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle })] }) });
5041
5068
  }
5042
5069
  const selector$c = (s) => ({
5043
5070
  width: s.width,
@@ -5781,6 +5808,31 @@ function clsx() {
5781
5808
  for (var e, t2, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t2 = r(e)) && (n && (n += " "), n += t2);
5782
5809
  return n;
5783
5810
  }
5811
+ function getDefaultExportFromCjs(x) {
5812
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x;
5813
+ }
5814
+ var tilg = { exports: {} }, __defProp2 = Object.defineProperty, __getOwnPropDesc = Object.getOwnPropertyDescriptor, __getOwnPropNames = Object.getOwnPropertyNames, __hasOwnProp = Object.prototype.hasOwnProperty, __export = (target, all) => {
5815
+ for (var name in all)
5816
+ __defProp2(target, name, { get: all[name], enumerable: !0 });
5817
+ }, __copyProps = (to, from, except, desc) => {
5818
+ if (from && typeof from == "object" || typeof from == "function")
5819
+ for (let key of __getOwnPropNames(from))
5820
+ !__hasOwnProp.call(to, key) && key !== except && __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
5821
+ return to;
5822
+ }, __toCommonJS = (mod) => __copyProps(__defProp2({}, "__esModule", { value: !0 }), mod), production_exports = {};
5823
+ __export(production_exports, {
5824
+ default: () => useTilg$1
5825
+ });
5826
+ var production = __toCommonJS(production_exports);
5827
+ function useTilg$1(...args) {
5828
+ return args.length ? args[0] : (_strings, ...innerArgs) => {
5829
+ if (innerArgs && innerArgs.length)
5830
+ return innerArgs[0];
5831
+ };
5832
+ }
5833
+ tilg.exports = production;
5834
+ var tilgExports = tilg.exports;
5835
+ const useTilg = /* @__PURE__ */ getDefaultExportFromCjs(tilgExports);
5784
5836
  var rootClassName = "likec4-diagram-root", keepAspectRatioContainer = "_2h8g8h0", cssReactFlow = "_2h8g8h1", cssDisablePan = "_2h8g8h2", cssTransparentBg = "_2h8g8h3", cssNoControls = "_2h8g8h4";
5785
5837
  function KeepAspectRatioContainer({
5786
5838
  children: children2,
@@ -6978,573 +7030,87 @@ function WhenInitialized({ children: children2 }) {
6978
7030
  );
6979
7031
  }, [isInitialized]), isInitialized ? /* @__PURE__ */ jsx(Fragment, { children: children2 }) : null;
6980
7032
  }
6981
- const useXYFlow = useReactFlow, useXYNodesData = useNodesData;
6982
- function useXYStore(selector2, equalityFn) {
6983
- return useStore(
6984
- // @ts-expect-error - types are not correct
6985
- selector2,
6986
- equalityFn ?? shallowEqual
6987
- );
6988
- }
6989
- const useXYStoreApi = useStoreApi;
6990
- class Rect {
6991
- constructor() {
6992
- __publicField(this, "id");
6993
- __publicField(this, "minX", new Variable());
6994
- __publicField(this, "minY", new Variable());
6995
- __publicField(this, "maxX", new Variable());
6996
- __publicField(this, "maxY", new Variable());
6997
- }
6998
- get x() {
6999
- return this.minX;
7000
- }
7001
- get y() {
7002
- return this.minY;
7003
- }
7004
- get positionAbsolute() {
7005
- return {
7006
- x: this.x.value(),
7007
- y: this.y.value()
7008
- };
7009
- }
7010
- get dimensions() {
7011
- return {
7012
- width: this.maxX.value() - this.minX.value(),
7013
- height: this.maxY.value() - this.minY.value()
7014
- };
7015
- }
7016
- // Position relative to parent
7017
- get position() {
7018
- const positionAbsolute = this.positionAbsolute;
7019
- if (!this.parent)
7020
- return positionAbsolute;
7021
- const parentPosition = this.parent.positionAbsolute;
7022
- return {
7023
- x: positionAbsolute.x - parentPosition.x,
7024
- y: positionAbsolute.y - parentPosition.y
7025
- };
7026
- }
7027
- }
7028
- class Compound extends Rect {
7029
- constructor(solver, xynode, parent = null) {
7030
- super();
7031
- __publicField(this, "children", []);
7032
- this.solver = solver, this.parent = parent, this.id = xynode.id, solver.createConstraint(this.maxX, Operator.Ge, this.minX), solver.createConstraint(this.maxY, Operator.Ge, this.minY), parent && parent.addChild(this);
7033
- }
7034
- addChild(rect) {
7035
- this.children.push(rect);
7036
- const leftPadding = new Expression(
7037
- rect.minX,
7038
- [-1, this.minX]
7039
- ), { weak } = Strength;
7040
- this.solver.createConstraint(leftPadding, Operator.Ge, 40), this.solver.createConstraint(leftPadding, Operator.Eq, 40, weak);
7041
- const topPadding = new Expression(
7042
- rect.minY,
7043
- [-1, this.minY]
7044
- );
7045
- this.solver.createConstraint(topPadding, Operator.Ge, 60), this.solver.createConstraint(topPadding, Operator.Eq, 60, weak);
7046
- const rightPadding = new Expression(
7047
- this.maxX,
7048
- [-1, rect.maxX]
7049
- );
7050
- this.solver.createConstraint(rightPadding, Operator.Ge, 40), this.solver.createConstraint(rightPadding, Operator.Eq, 40, weak);
7051
- const bottomPadding = new Expression(
7052
- this.maxY,
7053
- [-1, rect.maxY]
7054
- );
7055
- this.solver.createConstraint(bottomPadding, Operator.Ge, 40), this.solver.createConstraint(bottomPadding, Operator.Eq, 40, weak);
7056
- }
7033
+ const { abs: abs$1, cos: cos$1, sin: sin$1, acos: acos$1, atan2, sqrt: sqrt$1, pow } = Math;
7034
+ function crt(v) {
7035
+ return v < 0 ? -pow(-v, 1 / 3) : pow(v, 1 / 3);
7057
7036
  }
7058
- class Leaf extends Rect {
7059
- constructor(solver, xynode, parent = null, isEditing = !1) {
7060
- super(), this.parent = parent, this.isEditing = isEditing, this.id = xynode.id;
7061
- const x = Math.ceil(xynode.internals.positionAbsolute.x), y = Math.ceil(xynode.internals.positionAbsolute.y), { width, height } = getNodeDimensions(xynode);
7062
- if (this.maxX = new Expression(this.minX, Math.ceil(width)), this.maxY = new Expression(this.minY, Math.ceil(height)), isEditing) {
7063
- const superStrong = Strength.create(100, 0, 0);
7064
- solver.addEditVariable(this.minX, superStrong), solver.addEditVariable(this.minY, superStrong), solver.suggestValue(this.minX, x), solver.suggestValue(this.minY, y);
7065
- } else {
7066
- const halfMedium = Strength.create(0, 1, 0, 0.5);
7067
- solver.createConstraint(this.minX, Operator.Eq, x, halfMedium), solver.createConstraint(this.minY, Operator.Eq, y, halfMedium);
7068
- }
7069
- parent && parent.addChild(this);
7070
- }
7071
- }
7072
- function createLayoutConstraints(xyflow, xyflowApi, draggingNodeId) {
7073
- var _a;
7074
- const { parentLookup, nodeLookup } = xyflowApi.getState(), solver = new Solver(), rects = /* @__PURE__ */ new Map(), traverse = new Array();
7075
- for (const [, xynode] of nodeLookup)
7076
- isNullish(xynode.parentId) && traverse.push({
7077
- xynode,
7078
- parent: null
7079
- });
7080
- for (; traverse.length > 0; ) {
7081
- const { xynode, parent } = traverse.shift(), isDragging = xynode.dragging === !0 || xynode.id === draggingNodeId, shouldTraverse = !isDragging && xynode.type === "compound" && isAncestor(xynode.id, draggingNodeId), rect = shouldTraverse ? new Compound(solver, xynode, parent) : new Leaf(solver, xynode, parent, isDragging);
7082
- rects.set(xynode.id, rect), shouldTraverse && ((_a = parentLookup.get(xynode.id)) == null || _a.forEach((child) => {
7083
- traverse.push({
7084
- xynode: child,
7085
- parent: rect
7086
- });
7087
- }));
7088
- }
7089
- solver.updateVariables(), solver.maxIterations = 1e3;
7090
- function updateXYFlowNodes() {
7091
- solver.updateVariables(), xyflow.setNodes(
7092
- (nodes) => nodes.map((n) => {
7093
- if (n.id === draggingNodeId || n.dragging === !0)
7094
- return n;
7095
- const rect = rects.get(n.id);
7096
- if (!rect)
7097
- return n;
7098
- const dimensions = rect.dimensions, newXY = rect.position;
7099
- return newXY.x !== n.position.x || newXY.y !== n.position.y ? {
7100
- ...n,
7101
- position: rect.position,
7102
- width: dimensions.width,
7103
- height: dimensions.height,
7104
- measured: dimensions
7105
- } : dimensions.width !== n.width || dimensions.height !== n.height ? {
7106
- ...n,
7107
- width: dimensions.width,
7108
- height: dimensions.height,
7109
- measured: dimensions
7110
- } : n;
7111
- })
7112
- );
7113
- }
7114
- let animationFrameId = null;
7115
- function onNodeDrag(xynode) {
7116
- const pos = nodeLookup.get(xynode.id).internals.positionAbsolute, rect = nonNullable(rects.get(xynode.id));
7117
- solver.suggestValue(rect.minX, Math.ceil(pos.x)), solver.suggestValue(rect.minY, Math.ceil(pos.y)), animationFrameId ?? (animationFrameId = requestAnimationFrame(() => {
7118
- updateXYFlowNodes(), animationFrameId = null;
7119
- }));
7120
- }
7121
- return {
7122
- onNodeDrag,
7123
- updateXYFlowNodes
7124
- };
7125
- }
7126
- function useLayoutConstraints() {
7127
- const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), solverRef = useRef();
7128
- return useMemo(() => ({
7129
- onNodeDragStart: (_event, xynode) => {
7130
- const { xyflow } = diagramApi.getState();
7131
- solverRef.current = createLayoutConstraints(xyflow, xyflowApi, xynode.id);
7132
- },
7133
- onNodeDrag: (_event, xynode) => {
7134
- var _a;
7135
- invariant(solverRef.current, "solverRef.current should be defined"), (_a = solverRef.current) == null || _a.onNodeDrag(xynode);
7136
- },
7137
- onNodeDragStop: (_event, _xynode) => {
7138
- solverRef.current = void 0;
7139
- }
7140
- }), [xyflowApi]);
7141
- }
7142
- const ZIndexes = {
7143
- Compound: 1,
7144
- Edge: 2,
7145
- Element: 3
7146
- }, MinZoom = 0.05, StringSet = Set, DEFAULT_PROPS = {
7147
- initialized: !1,
7148
- xyflowSynced: !1,
7149
- previousViews: [],
7150
- viewportChanged: !1,
7151
- activeDynamicViewStep: null,
7152
- focusedNodeId: null,
7153
- hoveredNodeId: null,
7154
- hoveredEdgeId: null,
7155
- lastClickedNodeId: null,
7156
- lastClickedEdgeId: null,
7157
- dimmed: new StringSet(),
7158
- lastOnNavigate: null,
7159
- onChange: null,
7160
- onNavigateTo: null,
7161
- onNodeClick: null,
7162
- onNodeContextMenu: null,
7163
- onCanvasContextMenu: null,
7164
- onEdgeClick: null,
7165
- onEdgeContextMenu: null,
7166
- onCanvasClick: null,
7167
- onCanvasDblClick: null
7168
- }, noReplace = !1;
7169
- let storeDevId = 1;
7170
- const EmptyStringSet = new StringSet();
7171
- function createDiagramStore(props) {
7172
- return createWithEqualityFn(
7173
- subscribeWithSelector(
7174
- devtools(
7175
- (set2, get2) => ({
7176
- ...DEFAULT_PROPS,
7177
- ...props,
7178
- isDynamicView: () => {
7179
- var _a;
7180
- return ((_a = get2().view) == null ? void 0 : _a.__) === "dynamic";
7181
- },
7182
- updateView: (nextView) => {
7183
- let {
7184
- dimmed: dimmed2,
7185
- xyflowSynced,
7186
- view: current,
7187
- lastOnNavigate,
7188
- previousViews,
7189
- focusedNodeId,
7190
- lastClickedNodeId,
7191
- lastClickedEdgeId,
7192
- activeDynamicViewStep,
7193
- hoveredEdgeId,
7194
- hoveredNodeId
7195
- } = get2();
7196
- if (shallowEqual(current, nextView)) {
7197
- xyflowSynced || set2({ xyflowSynced: !0 }, noReplace, "updateView: xyflow synced"), DEV && console.debug("store: skip updateView");
7198
- return;
7199
- }
7200
- if (current.id === nextView.id) {
7201
- const nodeIds = new StringSet(nextView.nodes.map((n) => n.id)), edgeIds = new StringSet(nextView.edges.map((e) => e.id));
7202
- 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) {
7203
- let nextDimmed = new StringSet([...dimmed2].filter((id2) => nodeIds.has(id2) || edgeIds.has(id2)));
7204
- nextDimmed.size !== dimmed2.size && (dimmed2 = nextDimmed);
7205
- }
7206
- } else
7207
- 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 = [
7208
- current,
7209
- ...previousViews.filter((v) => v.id !== nextView.id && v.id !== current.id)
7210
- ], xyflowSynced = !1;
7211
- set2(
7212
- {
7213
- view: nextView,
7214
- activeDynamicViewStep,
7215
- xyflowSynced,
7216
- lastOnNavigate,
7217
- previousViews,
7218
- lastClickedNodeId,
7219
- lastClickedEdgeId,
7220
- focusedNodeId,
7221
- hoveredEdgeId,
7222
- hoveredNodeId,
7223
- dimmed: dimmed2
7224
- },
7225
- noReplace,
7226
- "update-view"
7227
- );
7228
- },
7229
- focusOnNode: (nodeId) => {
7230
- const { focusedNodeId, view } = get2();
7231
- if (nodeId !== focusedNodeId) {
7232
- const notDimmed = new StringSet([nodeId]), dimmed2 = new StringSet();
7233
- for (const edge of view.edges)
7234
- edge.source === nodeId || edge.target === nodeId ? (notDimmed.add(edge.source), notDimmed.add(edge.target)) : dimmed2.add(edge.id);
7235
- for (const node of view.nodes)
7236
- notDimmed.has(node.id) || dimmed2.add(node.id);
7237
- set2(
7238
- {
7239
- activeDynamicViewStep: null,
7240
- focusedNodeId: nodeId,
7241
- dimmed: dimmed2
7242
- },
7243
- noReplace,
7244
- `focus on node: ${nodeId}`
7245
- );
7246
- }
7247
- },
7248
- setHoveredNode: (nodeId) => {
7249
- nodeId !== get2().hoveredNodeId && set2({ hoveredNodeId: nodeId }, noReplace, nodeId ? "setHoveredNode" : "unsetHoveredNode");
7250
- },
7251
- setHoveredEdge: (edgeId) => {
7252
- edgeId !== get2().hoveredEdgeId && set2({ hoveredEdgeId: edgeId }, noReplace, edgeId ? "setHoveredEdge" : "unsetHoveredEdge");
7253
- },
7254
- setLastClickedNode: (nodeId) => {
7255
- nodeId !== get2().lastClickedNodeId && set2({ lastClickedNodeId: nodeId }, noReplace, nodeId ? "setLastClickedNode" : "unsetLastClickedNode");
7256
- },
7257
- setLastClickedEdge: (edgeId) => {
7258
- edgeId !== get2().lastClickedEdgeId && set2({ lastClickedEdgeId: edgeId }, noReplace, edgeId ? "setLastClickedEdge" : "unsetLastClickedEdge");
7259
- },
7260
- resetLastClicked: () => {
7261
- let {
7262
- focusedNodeId,
7263
- lastClickedNodeId,
7264
- lastClickedEdgeId
7265
- } = get2();
7266
- (focusedNodeId || lastClickedNodeId || lastClickedEdgeId) && set2(
7267
- {
7268
- focusedNodeId: null,
7269
- lastClickedNodeId: null,
7270
- lastClickedEdgeId: null,
7271
- dimmed: EmptyStringSet
7272
- },
7273
- noReplace,
7274
- "resetLastClicked"
7275
- );
7276
- },
7277
- getElement: (fqn) => {
7278
- const { view } = get2();
7279
- return view.nodes.find(({ id: id2 }) => id2 === fqn) ?? null;
7280
- },
7281
- triggerOnChange: (changes) => {
7282
- var _a, _b;
7283
- DEV && console.debug("triggerOnChange", changes);
7284
- const newShapes = /* @__PURE__ */ new Map(), newColor = /* @__PURE__ */ new Map(), newOpacity = /* @__PURE__ */ new Map(), newBorder = /* @__PURE__ */ new Map();
7285
- for (const change of changes) {
7286
- change.op !== "change-element-style" && nonexhaustive(change.op);
7287
- for (const target of change.targets)
7288
- for (const [key, value] of entries.strict(change.style))
7289
- switch (key) {
7290
- case "shape":
7291
- newShapes.set(target, value);
7292
- break;
7293
- case "color":
7294
- newColor.set(target, value);
7295
- break;
7296
- case "opacity":
7297
- newOpacity.set(target, value);
7298
- break;
7299
- case "border":
7300
- newBorder.set(target, value);
7301
- break;
7302
- default:
7303
- nonexhaustive(key);
7304
- }
7305
- }
7306
- get2().xyflow.setNodes(
7307
- (nodes) => nodes.map((node) => {
7308
- var _a2, _b2;
7309
- let element2 = node.data.element;
7310
- const shape = newShapes.get(element2.id);
7311
- shape && shape !== element2.shape && (element2 = {
7312
- ...element2,
7313
- shape
7314
- });
7315
- const color2 = newColor.get(element2.id);
7316
- color2 && color2 !== element2.color && (element2 = {
7317
- ...element2,
7318
- color: color2
7319
- });
7320
- const opacity = newOpacity.get(element2.id);
7321
- opacity && opacity !== ((_a2 = element2.style) == null ? void 0 : _a2.opacity) && (element2 = {
7322
- ...element2,
7323
- style: {
7324
- ...element2.style,
7325
- opacity
7326
- }
7327
- });
7328
- const border = newBorder.get(element2.id);
7329
- return border && border !== ((_b2 = element2.style) == null ? void 0 : _b2.border) && (element2 = {
7330
- ...element2,
7331
- style: {
7332
- ...element2.style,
7333
- border
7334
- }
7335
- }), element2 === node.data.element ? node : {
7336
- ...node,
7337
- data: {
7338
- ...node.data,
7339
- element: element2
7340
- }
7341
- };
7342
- })
7343
- ), (_b = (_a = get2()).onChange) == null || _b.call(_a, { changes });
7344
- },
7345
- triggerOnNavigateTo: (xynodeId, event) => {
7346
- var _a, _b;
7347
- const { xyflow, view } = get2(), xynode = xyflow.getInternalNode(xynodeId), element2 = xynode == null ? void 0 : xynode.data.element;
7348
- invariant(!!xynode && (element2 == null ? void 0 : element2.navigateTo), `node is not navigable: ${xynodeId}`);
7349
- const dimensions = getNodeDimensions(xynode);
7350
- set2(
7351
- {
7352
- lastClickedNodeId: xynodeId,
7353
- lastOnNavigate: {
7354
- fromView: view.id,
7355
- toView: element2.navigateTo,
7356
- element: element2,
7357
- elementCenterScreenPosition: xyflow.flowToScreenPosition({
7358
- x: xynode.internals.positionAbsolute.x + dimensions.width / 2,
7359
- y: xynode.internals.positionAbsolute.y + dimensions.height / 2
7360
- }),
7361
- positionCorrected: !1
7362
- }
7363
- },
7364
- noReplace,
7365
- "triggerOnNavigateTo"
7366
- ), (_b = (_a = get2()).onNavigateTo) == null || _b.call(
7367
- _a,
7368
- element2.navigateTo,
7369
- event,
7370
- element2,
7371
- xynode.internals.userNode
7372
- );
7373
- },
7374
- fitDiagram: (xyStore) => {
7375
- const { width, height, panZoom } = xyStore.getState(), { fitViewPadding, view, focusedNodeId } = get2(), bounds = {
7376
- x: 0,
7377
- y: 0,
7378
- width: view.width,
7379
- height: view.height
7380
- }, viewport = getViewportForBounds(bounds, width, height, MinZoom, 1, fitViewPadding);
7381
- panZoom == null || panZoom.setViewport(viewport, { duration: 400 }), focusedNodeId && set2(
7382
- {
7383
- focusedNodeId: null,
7384
- dimmed: EmptyStringSet
7385
- },
7386
- noReplace,
7387
- "unfocus"
7388
- );
7389
- },
7390
- nextDynamicStep: (increment = 1) => {
7391
- const { view, activeDynamicViewStep, xyflow, fitViewPadding } = get2();
7392
- invariant(view.__ === "dynamic", "view is not dynamic");
7393
- const nextStep = (activeDynamicViewStep ?? 0) + increment, edgeId = StepEdgeId(nextStep), dimmed2 = new StringSet();
7394
- let edge = null;
7395
- for (const e of xyflow.getEdges()) {
7396
- if (e.id === edgeId) {
7397
- edge = e;
7398
- continue;
7399
- }
7400
- dimmed2.add(e.id);
7401
- }
7402
- invariant(!!edge, `edge not found: ${edgeId}`);
7403
- const selected2 = [];
7404
- for (const n of xyflow.getNodes()) {
7405
- if (n.id === edge.source || n.id === edge.target) {
7406
- selected2.push(n);
7407
- continue;
7408
- }
7409
- dimmed2.add(n.id);
7410
- }
7411
- xyflow.fitView({
7412
- duration: 400,
7413
- maxZoom: 1,
7414
- minZoom: MinZoom,
7415
- padding: fitViewPadding,
7416
- nodes: selected2
7417
- }), set2({
7418
- focusedNodeId: null,
7419
- activeDynamicViewStep: nextStep,
7420
- dimmed: dimmed2
7421
- });
7422
- },
7423
- stopDynamicView: () => {
7424
- const { xyflow, fitViewPadding } = get2();
7425
- set2({
7426
- activeDynamicViewStep: null,
7427
- dimmed: EmptyStringSet
7428
- }), xyflow.fitView({
7429
- duration: 400,
7430
- maxZoom: 1,
7431
- minZoom: MinZoom,
7432
- padding: fitViewPadding
7433
- });
7434
- }
7435
- }),
7436
- {
7437
- name: `DiagramStore ${storeDevId++} - ${props.view.id}`,
7438
- enabled: DEV
7439
- }
7440
- )
7441
- ),
7442
- shallow
7443
- );
7444
- }
7445
- const DiagramContext = createContext(null);
7446
- function DiagramContextProvider({ children: children2, view, ...props }) {
7447
- const xyflow = useXYFlow(), store = useRef();
7448
- return store.current || (store.current = createDiagramStore({
7449
- xyflow,
7450
- view,
7451
- ...props
7452
- })), useEffect(
7453
- () => {
7454
- var _a, _b;
7455
- ((_a = store.current) == null ? void 0 : _a.getState().xyflow) !== xyflow && ((_b = store.current) == null || _b.setState({ xyflow }, !1, "update xyflow"));
7456
- },
7457
- [xyflow]
7458
- ), useUpdateEffect(
7459
- () => {
7460
- if (!store.current) return;
7461
- const state = store.current.getState();
7462
- state.view !== view && state.updateView(view), hasSubObject(state, props) || store.current.setState(props, !1, "update incoming props");
7463
- },
7464
- [view, props]
7465
- ), /* @__PURE__ */ jsx(DiagramContext.Provider, { value: store.current, children: children2 });
7466
- }
7467
- const { abs: abs$1, cos: cos$1, sin: sin$1, acos: acos$1, atan2, sqrt: sqrt$1, pow } = Math;
7468
- function crt(v) {
7469
- return v < 0 ? -pow(-v, 1 / 3) : pow(v, 1 / 3);
7470
- }
7471
- 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 = {
7472
- // Legendre-Gauss abscissae with n=24 (x_i values, defined at i=n as the roots of the nth order Legendre polynomial Pn(x))
7473
- Tvalues: [
7474
- -0.06405689286260563,
7475
- 0.06405689286260563,
7476
- -0.1911188674736163,
7477
- 0.1911188674736163,
7478
- -0.3150426796961634,
7479
- 0.3150426796961634,
7480
- -0.4337935076260451,
7481
- 0.4337935076260451,
7482
- -0.5454214713888396,
7483
- 0.5454214713888396,
7484
- -0.6480936519369755,
7485
- 0.6480936519369755,
7486
- -0.7401241915785544,
7487
- 0.7401241915785544,
7488
- -0.820001985973903,
7489
- 0.820001985973903,
7490
- -0.8864155270044011,
7491
- 0.8864155270044011,
7492
- -0.9382745520027328,
7493
- 0.9382745520027328,
7494
- -0.9747285559713095,
7495
- 0.9747285559713095,
7496
- -0.9951872199970213,
7497
- 0.9951872199970213
7498
- ],
7499
- // Legendre-Gauss weights with n=24 (w_i values, defined by a function linked to in the Bezier primer article)
7500
- Cvalues: [
7501
- 0.12793819534675216,
7502
- 0.12793819534675216,
7503
- 0.1258374563468283,
7504
- 0.1258374563468283,
7505
- 0.12167047292780339,
7506
- 0.12167047292780339,
7507
- 0.1155056680537256,
7508
- 0.1155056680537256,
7509
- 0.10744427011596563,
7510
- 0.10744427011596563,
7511
- 0.09761865210411388,
7512
- 0.09761865210411388,
7513
- 0.08619016153195327,
7514
- 0.08619016153195327,
7515
- 0.0733464814110803,
7516
- 0.0733464814110803,
7517
- 0.05929858491543678,
7518
- 0.05929858491543678,
7519
- 0.04427743881741981,
7520
- 0.04427743881741981,
7521
- 0.028531388628933663,
7522
- 0.028531388628933663,
7523
- 0.0123412297999872,
7524
- 0.0123412297999872
7525
- ],
7526
- arcfn: function(t2, derivativeFn) {
7527
- const d = derivativeFn(t2);
7528
- let l = d.x * d.x + d.y * d.y;
7529
- return typeof d.z < "u" && (l += d.z * d.z), sqrt$1(l);
7530
- },
7531
- compute: function(t2, points, _3d) {
7532
- if (t2 === 0)
7533
- return points[0].t = 0, points[0];
7534
- const order = points.length - 1;
7535
- if (t2 === 1)
7536
- return points[order].t = 1, points[order];
7537
- const mt = 1 - t2;
7538
- let p = points;
7539
- if (order === 0)
7540
- return points[0].t = t2, points[0];
7541
- if (order === 1) {
7542
- const ret = {
7543
- x: mt * p[0].x + t2 * p[1].x,
7544
- y: mt * p[0].y + t2 * p[1].y,
7545
- t: t2
7546
- };
7547
- return _3d && (ret.z = mt * p[0].z + t2 * p[1].z), ret;
7037
+ 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 = {
7038
+ // Legendre-Gauss abscissae with n=24 (x_i values, defined at i=n as the roots of the nth order Legendre polynomial Pn(x))
7039
+ Tvalues: [
7040
+ -0.06405689286260563,
7041
+ 0.06405689286260563,
7042
+ -0.1911188674736163,
7043
+ 0.1911188674736163,
7044
+ -0.3150426796961634,
7045
+ 0.3150426796961634,
7046
+ -0.4337935076260451,
7047
+ 0.4337935076260451,
7048
+ -0.5454214713888396,
7049
+ 0.5454214713888396,
7050
+ -0.6480936519369755,
7051
+ 0.6480936519369755,
7052
+ -0.7401241915785544,
7053
+ 0.7401241915785544,
7054
+ -0.820001985973903,
7055
+ 0.820001985973903,
7056
+ -0.8864155270044011,
7057
+ 0.8864155270044011,
7058
+ -0.9382745520027328,
7059
+ 0.9382745520027328,
7060
+ -0.9747285559713095,
7061
+ 0.9747285559713095,
7062
+ -0.9951872199970213,
7063
+ 0.9951872199970213
7064
+ ],
7065
+ // Legendre-Gauss weights with n=24 (w_i values, defined by a function linked to in the Bezier primer article)
7066
+ Cvalues: [
7067
+ 0.12793819534675216,
7068
+ 0.12793819534675216,
7069
+ 0.1258374563468283,
7070
+ 0.1258374563468283,
7071
+ 0.12167047292780339,
7072
+ 0.12167047292780339,
7073
+ 0.1155056680537256,
7074
+ 0.1155056680537256,
7075
+ 0.10744427011596563,
7076
+ 0.10744427011596563,
7077
+ 0.09761865210411388,
7078
+ 0.09761865210411388,
7079
+ 0.08619016153195327,
7080
+ 0.08619016153195327,
7081
+ 0.0733464814110803,
7082
+ 0.0733464814110803,
7083
+ 0.05929858491543678,
7084
+ 0.05929858491543678,
7085
+ 0.04427743881741981,
7086
+ 0.04427743881741981,
7087
+ 0.028531388628933663,
7088
+ 0.028531388628933663,
7089
+ 0.0123412297999872,
7090
+ 0.0123412297999872
7091
+ ],
7092
+ arcfn: function(t2, derivativeFn) {
7093
+ const d = derivativeFn(t2);
7094
+ let l = d.x * d.x + d.y * d.y;
7095
+ return typeof d.z < "u" && (l += d.z * d.z), sqrt$1(l);
7096
+ },
7097
+ compute: function(t2, points, _3d) {
7098
+ if (t2 === 0)
7099
+ return points[0].t = 0, points[0];
7100
+ const order = points.length - 1;
7101
+ if (t2 === 1)
7102
+ return points[order].t = 1, points[order];
7103
+ const mt = 1 - t2;
7104
+ let p = points;
7105
+ if (order === 0)
7106
+ return points[0].t = t2, points[0];
7107
+ if (order === 1) {
7108
+ const ret = {
7109
+ x: mt * p[0].x + t2 * p[1].x,
7110
+ y: mt * p[0].y + t2 * p[1].y,
7111
+ t: t2
7112
+ };
7113
+ return _3d && (ret.z = mt * p[0].z + t2 * p[1].z), ret;
7548
7114
  }
7549
7115
  if (order < 4) {
7550
7116
  let mt2 = mt * mt, t22 = t2 * t2, a, b, c, d = 0;
@@ -7605,8 +7171,8 @@ const pi$1 = Math.PI, tau = 2 * pi$1, quart = pi$1 / 2, epsilon = 1e-6, nMax = N
7605
7171
  }
7606
7172
  return dpoints;
7607
7173
  },
7608
- between: function(v, m, M) {
7609
- return m <= v && v <= M || utils.approximately(v, m) || utils.approximately(v, M);
7174
+ between: function(v, m2, M) {
7175
+ return m2 <= v && v <= M || utils.approximately(v, m2) || utils.approximately(v, M);
7610
7176
  },
7611
7177
  approximately: function(a, b, precision) {
7612
7178
  return abs$1(a - b) <= (precision || epsilon);
@@ -7757,38 +7323,38 @@ const pi$1 = Math.PI, tau = 2 * pi$1, quart = pi$1 / 2, epsilon = 1e-6, nMax = N
7757
7323
  },
7758
7324
  roots: function(points, line2) {
7759
7325
  line2 = line2 || { p1: { x: 0, y: 0 }, p2: { x: 1, y: 0 } };
7760
- const order = points.length - 1, aligned = utils.align(points, line2), reduce = function(t2) {
7326
+ const order = points.length - 1, aligned = utils.align(points, line2), reduce2 = function(t2) {
7761
7327
  return 0 <= t2 && t2 <= 1;
7762
7328
  };
7763
7329
  if (order === 2) {
7764
7330
  const a2 = aligned[0].y, b2 = aligned[1].y, c2 = aligned[2].y, d2 = a2 - 2 * b2 + c2;
7765
7331
  if (d2 !== 0) {
7766
7332
  const m1 = -sqrt$1(b2 * b2 - a2 * c2), m2 = -a2 + b2, v12 = -(m1 + m2) / d2, v2 = -(-m1 + m2) / d2;
7767
- return [v12, v2].filter(reduce);
7333
+ return [v12, v2].filter(reduce2);
7768
7334
  } else if (b2 !== c2 && d2 === 0)
7769
- return [(2 * b2 - c2) / (2 * b2 - 2 * c2)].filter(reduce);
7335
+ return [(2 * b2 - c2) / (2 * b2 - 2 * c2)].filter(reduce2);
7770
7336
  return [];
7771
7337
  }
7772
7338
  const pa = aligned[0].y, pb = aligned[1].y, pc = aligned[2].y, pd = aligned[3].y;
7773
7339
  let d = -pa + 3 * pb - 3 * pc + pd, a = 3 * pa - 6 * pb + 3 * pc, b = -3 * pa + 3 * pb, c = pa;
7774
7340
  if (utils.approximately(d, 0)) {
7775
7341
  if (utils.approximately(a, 0))
7776
- return utils.approximately(b, 0) ? [] : [-c / b].filter(reduce);
7342
+ return utils.approximately(b, 0) ? [] : [-c / b].filter(reduce2);
7777
7343
  const q3 = sqrt$1(b * b - 4 * a * c), a2 = 2 * a;
7778
- return [(q3 - b) / a2, (-b - q3) / a2].filter(reduce);
7344
+ return [(q3 - b) / a2, (-b - q3) / a2].filter(reduce2);
7779
7345
  }
7780
7346
  a /= d, b /= d, c /= d;
7781
7347
  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;
7782
7348
  let u1, v1, x1, x2, x3;
7783
7349
  if (discriminant < 0) {
7784
7350
  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;
7785
- 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);
7351
+ 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(reduce2);
7786
7352
  } else {
7787
7353
  if (discriminant === 0)
7788
- return u1 = q2 < 0 ? crt(-q2) : -crt(q2), x1 = 2 * u1 - a / 3, x2 = -u1 - a / 3, [x1, x2].filter(reduce);
7354
+ return u1 = q2 < 0 ? crt(-q2) : -crt(q2), x1 = 2 * u1 - a / 3, x2 = -u1 - a / 3, [x1, x2].filter(reduce2);
7789
7355
  {
7790
7356
  const sd = sqrt$1(discriminant);
7791
- return u1 = crt(-q2 + sd), v1 = crt(q2 + sd), [u1 - v1 - a / 3].filter(reduce);
7357
+ return u1 = crt(-q2 + sd), v1 = crt(q2 + sd), [u1 - v1 - a / 3].filter(reduce2);
7792
7358
  }
7793
7359
  }
7794
7360
  },
@@ -7875,8 +7441,8 @@ const pi$1 = Math.PI, tau = 2 * pi$1, quart = pi$1 / 2, epsilon = 1e-6, nMax = N
7875
7441
  },
7876
7442
  getccenter: function(p1, p2, p3) {
7877
7443
  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);
7878
- 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), _;
7879
- 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;
7444
+ let s = atan2(p1.y - arc.y, p1.x - arc.x), m2 = atan2(p2.y - arc.y, p2.x - arc.x), e = atan2(p3.y - arc.y, p3.x - arc.x), _;
7445
+ return s < e ? ((s > m2 || m2 > e) && (s += tau), s > e && (_ = e, e = s, s = _)) : e < m2 && m2 < s ? (_ = e, e = s, s = _) : e += tau, arc.s = s, arc.e = e, arc.r = r2, arc;
7880
7446
  },
7881
7447
  numberSort: function(a, b) {
7882
7448
  return a - b;
@@ -8110,8 +7676,8 @@ class Bezier {
8110
7676
  x: r2.y * r1.z - r2.z * r1.y,
8111
7677
  y: r2.z * r1.x - r2.x * r1.z,
8112
7678
  z: r2.x * r1.y - r2.y * r1.x
8113
- }, m = sqrt(c.x * c.x + c.y * c.y + c.z * c.z);
8114
- c.x /= m, c.y /= m, c.z /= m;
7679
+ }, m2 = sqrt(c.x * c.x + c.y * c.y + c.z * c.z);
7680
+ c.x /= m2, c.y /= m2, c.z /= m2;
8115
7681
  const R = [
8116
7682
  c.x * c.x,
8117
7683
  c.x * c.y - c.z,
@@ -8265,8 +7831,8 @@ class Bezier {
8265
7831
  y: p.y - o.y
8266
7832
  }, rc = distanceFn ? distanceFn((t2 + 1) / order) : d;
8267
7833
  distanceFn && !clockwise && (rc = -rc);
8268
- var m = sqrt(ov.x * ov.x + ov.y * ov.y);
8269
- ov.x /= m, ov.y /= m, np[t2 + 1] = {
7834
+ var m2 = sqrt(ov.x * ov.x + ov.y * ov.y);
7835
+ ov.x /= m2, ov.y /= m2, np[t2 + 1] = {
8270
7836
  x: p.x + rc * ov.x,
8271
7837
  y: p.y + rc * ov.y
8272
7838
  };
@@ -8382,38 +7948,589 @@ class Bezier {
8382
7948
  x: arc.x + arc.r * cos(arc.e),
8383
7949
  y: arc.y + arc.r * sin(arc.e)
8384
7950
  };
8385
- arc.e += utils.angle({ x: arc.x, y: arc.y }, d, this.get(1));
7951
+ arc.e += utils.angle({ x: arc.x, y: arc.y }, d, this.get(1));
7952
+ }
7953
+ break;
7954
+ }
7955
+ t_e = t_e + (t_e - t_s) / 2;
7956
+ } else
7957
+ t_e = t_m;
7958
+ while (!done && safety++ < 100);
7959
+ if (safety >= 100)
7960
+ break;
7961
+ prev_arc = prev_arc || arc, circles.push(prev_arc), t_s = prev_e;
7962
+ } while (t_e < 1);
7963
+ return circles;
7964
+ }
7965
+ }
7966
+ function toDomPrecision(v) {
7967
+ return v === null ? 0.01 : Math.round(v * 100) / 100;
7968
+ }
7969
+ function bezierControlPoints(diagramEdge) {
7970
+ let [start2, ...bezierPoints] = diagramEdge.points;
7971
+ invariant(start2, "start should be defined");
7972
+ const handles = [
7973
+ // start
7974
+ ];
7975
+ for (; hasAtLeast(bezierPoints, 3); ) {
7976
+ 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();
7977
+ inflections.length === 0 && inflections.push(0.5), inflections.forEach((t2) => {
7978
+ const { x, y } = bezier.get(t2);
7979
+ handles.push({
7980
+ x: toDomPrecision(x),
7981
+ y: toDomPrecision(y)
7982
+ });
7983
+ }), bezierPoints = rest, start2 = end;
7984
+ }
7985
+ return invariant(bezierPoints.length === 0, "all points should be consumed"), diagramEdge.dir === "back" && handles.length > 0 && handles.reverse(), handles;
7986
+ }
7987
+ const isClose = (a, b) => Math.abs(a - b) < 3.1;
7988
+ function isSamePoint$1(a, b) {
7989
+ const [ax, ay] = isArray(a) ? a : [a.x, a.y], [bx, by] = isArray(b) ? b : [b.x, b.y];
7990
+ return isClose(ax, bx) && isClose(ay, by);
7991
+ }
7992
+ const useXYFlow = useReactFlow, useXYNodesData = useNodesData;
7993
+ function useXYStore(selector2, equalityFn) {
7994
+ return useStore(
7995
+ // @ts-expect-error - types are not correct
7996
+ selector2,
7997
+ equalityFn ?? shallowEqual
7998
+ );
7999
+ }
8000
+ const useXYStoreApi = useStoreApi;
8001
+ class Rect {
8002
+ constructor() {
8003
+ __publicField(this, "id");
8004
+ __publicField(this, "minX", new Variable());
8005
+ __publicField(this, "minY", new Variable());
8006
+ __publicField(this, "maxX", new Variable());
8007
+ __publicField(this, "maxY", new Variable());
8008
+ }
8009
+ get x() {
8010
+ return this.minX;
8011
+ }
8012
+ get y() {
8013
+ return this.minY;
8014
+ }
8015
+ get positionAbsolute() {
8016
+ return {
8017
+ x: this.x.value(),
8018
+ y: this.y.value()
8019
+ };
8020
+ }
8021
+ get dimensions() {
8022
+ return {
8023
+ width: this.maxX.value() - this.minX.value(),
8024
+ height: this.maxY.value() - this.minY.value()
8025
+ };
8026
+ }
8027
+ // Position relative to parent
8028
+ get position() {
8029
+ const positionAbsolute = this.positionAbsolute;
8030
+ if (!this.parent)
8031
+ return positionAbsolute;
8032
+ const parentPosition = this.parent.positionAbsolute;
8033
+ return {
8034
+ x: positionAbsolute.x - parentPosition.x,
8035
+ y: positionAbsolute.y - parentPosition.y
8036
+ };
8037
+ }
8038
+ }
8039
+ class Compound extends Rect {
8040
+ constructor(solver, xynode, parent = null) {
8041
+ super();
8042
+ __publicField(this, "children", []);
8043
+ this.solver = solver, this.parent = parent, this.id = xynode.id, solver.createConstraint(this.maxX, Operator.Ge, this.minX), solver.createConstraint(this.maxY, Operator.Ge, this.minY), parent && parent.addChild(this);
8044
+ }
8045
+ addChild(rect) {
8046
+ this.children.push(rect);
8047
+ const leftPadding = new Expression(
8048
+ rect.minX,
8049
+ [-1, this.minX]
8050
+ ), { weak } = Strength;
8051
+ this.solver.createConstraint(leftPadding, Operator.Ge, 40), this.solver.createConstraint(leftPadding, Operator.Eq, 40, weak);
8052
+ const topPadding = new Expression(
8053
+ rect.minY,
8054
+ [-1, this.minY]
8055
+ );
8056
+ this.solver.createConstraint(topPadding, Operator.Ge, 60), this.solver.createConstraint(topPadding, Operator.Eq, 60, weak);
8057
+ const rightPadding = new Expression(
8058
+ this.maxX,
8059
+ [-1, rect.maxX]
8060
+ );
8061
+ this.solver.createConstraint(rightPadding, Operator.Ge, 40), this.solver.createConstraint(rightPadding, Operator.Eq, 40, weak);
8062
+ const bottomPadding = new Expression(
8063
+ this.maxY,
8064
+ [-1, rect.maxY]
8065
+ );
8066
+ this.solver.createConstraint(bottomPadding, Operator.Ge, 40), this.solver.createConstraint(bottomPadding, Operator.Eq, 40, weak);
8067
+ }
8068
+ }
8069
+ class Leaf extends Rect {
8070
+ constructor(solver, xynode, parent = null, isEditing = !1) {
8071
+ super(), this.parent = parent, this.isEditing = isEditing, this.id = xynode.id;
8072
+ const x = Math.ceil(xynode.internals.positionAbsolute.x), y = Math.ceil(xynode.internals.positionAbsolute.y), { width, height } = getNodeDimensions(xynode);
8073
+ if (this.maxX = new Expression(this.minX, Math.ceil(width)), this.maxY = new Expression(this.minY, Math.ceil(height)), isEditing) {
8074
+ const superStrong = Strength.create(100, 0, 0);
8075
+ solver.addEditVariable(this.minX, superStrong), solver.addEditVariable(this.minY, superStrong), solver.suggestValue(this.minX, x), solver.suggestValue(this.minY, y);
8076
+ } else {
8077
+ const halfMedium = Strength.create(0, 1, 0, 0.5);
8078
+ solver.createConstraint(this.minX, Operator.Eq, x, halfMedium), solver.createConstraint(this.minY, Operator.Eq, y, halfMedium);
8079
+ }
8080
+ parent && parent.addChild(this);
8081
+ }
8082
+ }
8083
+ function createLayoutConstraints(xyflow, xyflowApi, draggingNodeId) {
8084
+ var _a;
8085
+ const { parentLookup, nodeLookup } = xyflowApi.getState(), solver = new Solver(), rects = /* @__PURE__ */ new Map(), traverse = new Array();
8086
+ for (const [, xynode] of nodeLookup)
8087
+ isNullish(xynode.parentId) && traverse.push({
8088
+ xynode,
8089
+ parent: null
8090
+ });
8091
+ for (; traverse.length > 0; ) {
8092
+ const { xynode, parent } = traverse.shift(), isDragging = xynode.dragging === !0 || xynode.id === draggingNodeId, shouldTraverse = !isDragging && xynode.type === "compound" && isAncestor(xynode.id, draggingNodeId), rect = shouldTraverse ? new Compound(solver, xynode, parent) : new Leaf(solver, xynode, parent, isDragging);
8093
+ rects.set(xynode.id, rect), shouldTraverse && ((_a = parentLookup.get(xynode.id)) == null || _a.forEach((child) => {
8094
+ traverse.push({
8095
+ xynode: child,
8096
+ parent: rect
8097
+ });
8098
+ }));
8099
+ }
8100
+ solver.updateVariables(), solver.maxIterations = 1e3;
8101
+ function updateXYFlowNodes() {
8102
+ solver.updateVariables(), xyflow.setNodes(
8103
+ (nodes) => nodes.map((n) => {
8104
+ if (n.id === draggingNodeId || n.dragging === !0)
8105
+ return n;
8106
+ const rect = rects.get(n.id);
8107
+ if (!rect)
8108
+ return n;
8109
+ const dimensions = rect.dimensions, newXY = rect.position;
8110
+ return newXY.x !== n.position.x || newXY.y !== n.position.y ? {
8111
+ ...n,
8112
+ position: rect.position,
8113
+ width: dimensions.width,
8114
+ height: dimensions.height,
8115
+ measured: dimensions
8116
+ } : dimensions.width !== n.width || dimensions.height !== n.height ? {
8117
+ ...n,
8118
+ width: dimensions.width,
8119
+ height: dimensions.height,
8120
+ measured: dimensions
8121
+ } : n;
8122
+ })
8123
+ );
8124
+ }
8125
+ let animationFrameId = null;
8126
+ function onNodeDrag(xynode) {
8127
+ const pos = nodeLookup.get(xynode.id).internals.positionAbsolute, rect = nonNullable(rects.get(xynode.id));
8128
+ solver.suggestValue(rect.minX, Math.ceil(pos.x)), solver.suggestValue(rect.minY, Math.ceil(pos.y)), animationFrameId ?? (animationFrameId = requestAnimationFrame(() => {
8129
+ updateXYFlowNodes(), animationFrameId = null;
8130
+ }));
8131
+ }
8132
+ return {
8133
+ onNodeDrag,
8134
+ updateXYFlowNodes
8135
+ };
8136
+ }
8137
+ function useLayoutConstraints() {
8138
+ const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), solverRef = useRef(), dragStartedAt = useRef({
8139
+ x: 0,
8140
+ y: 0
8141
+ });
8142
+ return useMemo(() => ({
8143
+ onNodeDragStart: (event, xynode) => {
8144
+ dragStartedAt.current = {
8145
+ x: event.clientX,
8146
+ y: event.clientY
8147
+ };
8148
+ const { xyflow } = diagramApi.getState();
8149
+ solverRef.current = createLayoutConstraints(xyflow, xyflowApi, xynode.id);
8150
+ },
8151
+ onNodeDrag: (_event, xynode) => {
8152
+ var _a;
8153
+ invariant(solverRef.current, "solverRef.current should be defined"), (_a = solverRef.current) == null || _a.onNodeDrag(xynode);
8154
+ },
8155
+ onNodeDragStop: (event, _xynode) => {
8156
+ isSamePoint$1(dragStartedAt.current, { x: event.clientX, y: event.clientY }) || diagramApi.getState().triggerSaveManualLayout(xyflowApi), solverRef.current = void 0;
8157
+ }
8158
+ }), [xyflowApi, diagramApi]);
8159
+ }
8160
+ const ZIndexes = {
8161
+ Compound: 1,
8162
+ Edge: 2,
8163
+ Element: 3
8164
+ }, MinZoom = 0.1, StringSet = Set, DEFAULT_PROPS = {
8165
+ viewSyncState: "synced",
8166
+ viewSyncDebounceTimeout: null,
8167
+ initialized: !1,
8168
+ xyflowSynced: !1,
8169
+ previousViews: [],
8170
+ viewportChanged: !1,
8171
+ activeDynamicViewStep: null,
8172
+ focusedNodeId: null,
8173
+ hoveredNodeId: null,
8174
+ hoveredEdgeId: null,
8175
+ lastClickedNodeId: null,
8176
+ lastClickedEdgeId: null,
8177
+ dimmed: new StringSet(),
8178
+ lastOnNavigate: null,
8179
+ onChange: null,
8180
+ onNavigateTo: null,
8181
+ onNodeClick: null,
8182
+ onNodeContextMenu: null,
8183
+ onCanvasContextMenu: null,
8184
+ onEdgeClick: null,
8185
+ onEdgeContextMenu: null,
8186
+ onCanvasClick: null,
8187
+ onCanvasDblClick: null
8188
+ }, noReplace = !1;
8189
+ let storeDevId = 1;
8190
+ const EmptyStringSet = new StringSet();
8191
+ function createDiagramStore(props) {
8192
+ return createWithEqualityFn(
8193
+ subscribeWithSelector(
8194
+ devtools(
8195
+ (set2, get2) => ({
8196
+ ...DEFAULT_PROPS,
8197
+ ...props,
8198
+ isDynamicView: () => {
8199
+ var _a;
8200
+ return ((_a = get2().view) == null ? void 0 : _a.__) === "dynamic";
8201
+ },
8202
+ updateView: (nextView) => {
8203
+ let {
8204
+ viewSyncDebounceTimeout,
8205
+ viewSyncState,
8206
+ xyflow,
8207
+ dimmed: dimmed2,
8208
+ xyflowSynced,
8209
+ view: current,
8210
+ lastOnNavigate,
8211
+ previousViews,
8212
+ focusedNodeId,
8213
+ lastClickedNodeId,
8214
+ lastClickedEdgeId,
8215
+ activeDynamicViewStep,
8216
+ hoveredEdgeId,
8217
+ hoveredNodeId
8218
+ } = get2();
8219
+ if (viewSyncDebounceTimeout && (clearTimeout(viewSyncDebounceTimeout), viewSyncDebounceTimeout = null), shallowEqual(current, nextView)) {
8220
+ (!xyflowSynced || viewSyncState === "changed") && set2(
8221
+ {
8222
+ viewSyncState: "synced",
8223
+ xyflowSynced: !0
8224
+ },
8225
+ noReplace,
8226
+ "updateView: xyflow synced"
8227
+ ), DEV && console.debug("store: skip updateView");
8228
+ return;
8229
+ }
8230
+ if (current.id === nextView.id) {
8231
+ const nodeIds = new StringSet(nextView.nodes.map((n) => n.id)), edgeIds = new StringSet(nextView.edges.map((e) => e.id));
8232
+ 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, current.edges], [nextView.nodes, nextView.edges]), dimmed2.size > 0) {
8233
+ let nextDimmed = new StringSet([...dimmed2].filter((id2) => nodeIds.has(id2) || edgeIds.has(id2)));
8234
+ nextDimmed.size !== dimmed2.size && (dimmed2 = nextDimmed);
8235
+ }
8236
+ } else {
8237
+ if (lastOnNavigate && lastOnNavigate.toView !== nextView.id && lastOnNavigate.fromView !== nextView.id && (lastOnNavigate = null), !lastOnNavigate) {
8238
+ const zoom2 = xyflow.getZoom();
8239
+ xyflow.setCenter(nextView.width / 2, nextView.height / 2, { zoom: zoom2 });
8240
+ }
8241
+ lastClickedEdgeId = null, lastClickedNodeId = null, hoveredEdgeId = null, hoveredNodeId = null, focusedNodeId = null, activeDynamicViewStep = null, dimmed2 = EmptyStringSet, previousViews = [
8242
+ current,
8243
+ ...previousViews.filter((v) => v.id !== nextView.id && v.id !== current.id)
8244
+ ], xyflowSynced = !1;
8245
+ }
8246
+ set2(
8247
+ {
8248
+ viewSyncState: "synced",
8249
+ viewSyncDebounceTimeout,
8250
+ view: nextView,
8251
+ activeDynamicViewStep,
8252
+ xyflowSynced,
8253
+ lastOnNavigate,
8254
+ previousViews,
8255
+ lastClickedNodeId,
8256
+ lastClickedEdgeId,
8257
+ focusedNodeId,
8258
+ hoveredEdgeId,
8259
+ hoveredNodeId,
8260
+ dimmed: dimmed2
8261
+ },
8262
+ noReplace,
8263
+ "update-view"
8264
+ );
8265
+ },
8266
+ focusOnNode: (nodeId) => {
8267
+ const { focusedNodeId, view } = get2();
8268
+ if (nodeId !== focusedNodeId) {
8269
+ const notDimmed = new StringSet([nodeId]), dimmed2 = new StringSet();
8270
+ for (const edge of view.edges)
8271
+ edge.source === nodeId || edge.target === nodeId ? (notDimmed.add(edge.source), notDimmed.add(edge.target)) : dimmed2.add(edge.id);
8272
+ for (const node of view.nodes)
8273
+ notDimmed.has(node.id) || dimmed2.add(node.id);
8274
+ set2(
8275
+ {
8276
+ activeDynamicViewStep: null,
8277
+ focusedNodeId: nodeId,
8278
+ dimmed: dimmed2
8279
+ },
8280
+ noReplace,
8281
+ `focus on node: ${nodeId}`
8282
+ );
8283
+ }
8284
+ },
8285
+ setHoveredNode: (nodeId) => {
8286
+ nodeId !== get2().hoveredNodeId && set2({ hoveredNodeId: nodeId }, noReplace, nodeId ? "setHoveredNode" : "unsetHoveredNode");
8287
+ },
8288
+ setHoveredEdge: (edgeId) => {
8289
+ edgeId !== get2().hoveredEdgeId && set2({ hoveredEdgeId: edgeId }, noReplace, edgeId ? "setHoveredEdge" : "unsetHoveredEdge");
8290
+ },
8291
+ setLastClickedNode: (nodeId) => {
8292
+ nodeId !== get2().lastClickedNodeId && set2({ lastClickedNodeId: nodeId }, noReplace, nodeId ? "setLastClickedNode" : "unsetLastClickedNode");
8293
+ },
8294
+ setLastClickedEdge: (edgeId) => {
8295
+ edgeId !== get2().lastClickedEdgeId && set2({ lastClickedEdgeId: edgeId }, noReplace, edgeId ? "setLastClickedEdge" : "unsetLastClickedEdge");
8296
+ },
8297
+ resetLastClicked: () => {
8298
+ let {
8299
+ activeDynamicViewStep,
8300
+ focusedNodeId,
8301
+ lastClickedNodeId,
8302
+ lastClickedEdgeId
8303
+ } = get2();
8304
+ (activeDynamicViewStep || focusedNodeId || lastClickedNodeId || lastClickedEdgeId) && set2(
8305
+ {
8306
+ activeDynamicViewStep: null,
8307
+ focusedNodeId: null,
8308
+ lastClickedNodeId: null,
8309
+ lastClickedEdgeId: null,
8310
+ dimmed: EmptyStringSet
8311
+ },
8312
+ noReplace,
8313
+ "resetLastClicked"
8314
+ );
8315
+ },
8316
+ getElement: (fqn) => {
8317
+ const { view } = get2();
8318
+ return view.nodes.find(({ id: id2 }) => id2 === fqn) ?? null;
8319
+ },
8320
+ triggerChangeElementStyle: (change) => {
8321
+ DEV && console.debug("triggerChangeElementStyle", change);
8322
+ const { view, updateView, onChange } = get2();
8323
+ let hasChanges = !1;
8324
+ const nodes = view.nodes.map((origin) => {
8325
+ var _a, _b;
8326
+ if (!change.targets.includes(origin.id))
8327
+ return origin;
8328
+ let element2 = origin;
8329
+ for (const [key, value] of entries.strict(change.style))
8330
+ switch (key) {
8331
+ case "shape":
8332
+ value !== element2.shape && (element2 = {
8333
+ ...element2,
8334
+ shape: value
8335
+ });
8336
+ break;
8337
+ case "color":
8338
+ value !== element2.color && (element2 = {
8339
+ ...element2,
8340
+ color: value
8341
+ });
8342
+ break;
8343
+ case "opacity":
8344
+ value !== ((_a = element2.style) == null ? void 0 : _a.opacity) && (element2 = {
8345
+ ...element2,
8346
+ style: {
8347
+ ...element2.style,
8348
+ opacity: value
8349
+ }
8350
+ });
8351
+ break;
8352
+ case "border":
8353
+ value !== ((_b = element2.style) == null ? void 0 : _b.border) && (element2 = {
8354
+ ...element2,
8355
+ style: {
8356
+ ...element2.style,
8357
+ border: value
8358
+ }
8359
+ });
8360
+ break;
8361
+ default:
8362
+ nonexhaustive(key);
8363
+ }
8364
+ return element2 !== origin ? (hasChanges = !0, element2) : origin;
8365
+ });
8366
+ hasChanges && (updateView({
8367
+ ...view,
8368
+ nodes
8369
+ }), onChange && set2({ viewSyncState: "changed" }, noReplace, "change sync state")), onChange == null || onChange({ change });
8370
+ },
8371
+ triggerSaveManualLayout: (xystore) => {
8372
+ let { viewSyncDebounceTimeout: debounced, onChange } = get2();
8373
+ if (!onChange) {
8374
+ DEV && console.debug("ignore triggerSaveManualLayout, as no onChange handler is set");
8375
+ return;
8376
+ }
8377
+ debounced && clearTimeout(debounced), debounced = setTimeout(() => {
8378
+ const { nodeLookup } = xystore.getState(), { xyflow, onChange: onChange2 } = get2(), movedNodes = new StringSet(), nodes = reduce([...nodeLookup.values()], (acc, node) => {
8379
+ const dimensions = getNodeDimensions(node);
8380
+ return isSamePoint$1(node.internals.positionAbsolute, node.data.element.position) || movedNodes.add(node.id), acc[node.data.fqn] = {
8381
+ x: node.internals.positionAbsolute.x,
8382
+ y: node.internals.positionAbsolute.y,
8383
+ width: dimensions.width,
8384
+ height: dimensions.height
8385
+ }, acc;
8386
+ }, {}), edges = reduce(xyflow.getEdges(), (acc, { source, target, data }) => {
8387
+ let controlPoints = data.controlPoints;
8388
+ return !controlPoints && (movedNodes.has(source) || movedNodes.has(target)) && (controlPoints = bezierControlPoints(data.edge)), controlPoints && (acc[data.edge.id] = {
8389
+ controlPoints
8390
+ }), acc;
8391
+ }, {}), change = {
8392
+ op: "save-manual-layout",
8393
+ nodes,
8394
+ edges
8395
+ };
8396
+ DEV && console.debug("triggerSaveManualLayout", change), set2({ viewSyncDebounceTimeout: null }, noReplace, "clear debounce timeout"), onChange2 == null || onChange2({ change });
8397
+ }, 5e3), set2(
8398
+ {
8399
+ viewSyncDebounceTimeout: debounced,
8400
+ viewSyncState: "changed"
8401
+ },
8402
+ noReplace,
8403
+ "change sync state"
8404
+ );
8405
+ },
8406
+ triggerOnNavigateTo: (xynodeId, event) => {
8407
+ var _a, _b;
8408
+ const { xyflow, view } = get2(), xynode = xyflow.getInternalNode(xynodeId), element2 = xynode == null ? void 0 : xynode.data.element;
8409
+ invariant(!!xynode && (element2 == null ? void 0 : element2.navigateTo), `node is not navigable: ${xynodeId}`), set2(
8410
+ {
8411
+ lastClickedNodeId: xynodeId,
8412
+ lastOnNavigate: {
8413
+ fromView: view.id,
8414
+ toView: element2.navigateTo,
8415
+ element: element2,
8416
+ elementScreenPosition: xyflow.flowToScreenPosition({
8417
+ x: xynode.internals.positionAbsolute.x,
8418
+ // + dimensions.width / 2,
8419
+ y: xynode.internals.positionAbsolute.y
8420
+ // + dimensions.height / 2
8421
+ }),
8422
+ positionCorrected: !1
8423
+ }
8424
+ },
8425
+ noReplace,
8426
+ "triggerOnNavigateTo"
8427
+ ), (_b = (_a = get2()).onNavigateTo) == null || _b.call(
8428
+ _a,
8429
+ element2.navigateTo,
8430
+ event,
8431
+ element2,
8432
+ xynode.internals.userNode
8433
+ );
8434
+ },
8435
+ fitDiagram: (xyStore) => {
8436
+ const { width, height, panZoom } = xyStore.getState(), { fitViewPadding, view, focusedNodeId } = get2(), bounds = {
8437
+ x: 0,
8438
+ y: 0,
8439
+ width: view.width,
8440
+ height: view.height
8441
+ }, viewport = getViewportForBounds(bounds, width, height, MinZoom, 1, fitViewPadding);
8442
+ panZoom == null || panZoom.setViewport(viewport, { duration: 500 }), focusedNodeId && set2(
8443
+ {
8444
+ focusedNodeId: null,
8445
+ dimmed: EmptyStringSet
8446
+ },
8447
+ noReplace,
8448
+ "unfocus"
8449
+ );
8450
+ },
8451
+ nextDynamicStep: (increment = 1) => {
8452
+ const { view, activeDynamicViewStep, xyflow, fitViewPadding } = get2();
8453
+ invariant(view.__ === "dynamic", "view is not dynamic");
8454
+ const nextStep = (activeDynamicViewStep ?? 0) + increment;
8455
+ if (nextStep <= 0 || nextStep > view.edges.length)
8456
+ return;
8457
+ const edgeId = StepEdgeId(nextStep), dimmed2 = new StringSet();
8458
+ let edge = null;
8459
+ for (const e of xyflow.getEdges()) {
8460
+ if (e.id === edgeId) {
8461
+ edge = e;
8462
+ continue;
8463
+ }
8464
+ dimmed2.add(e.id);
8386
8465
  }
8387
- break;
8466
+ invariant(!!edge, `edge not found: ${edgeId}`);
8467
+ const selected2 = [];
8468
+ for (const n of xyflow.getNodes()) {
8469
+ if (n.id === edge.source || n.id === edge.target) {
8470
+ selected2.push(n);
8471
+ continue;
8472
+ }
8473
+ dimmed2.add(n.id);
8474
+ }
8475
+ xyflow.fitView({
8476
+ duration: 400,
8477
+ maxZoom: 1,
8478
+ minZoom: MinZoom,
8479
+ padding: fitViewPadding,
8480
+ nodes: selected2
8481
+ }), set2({
8482
+ focusedNodeId: null,
8483
+ activeDynamicViewStep: nextStep,
8484
+ dimmed: dimmed2
8485
+ });
8486
+ },
8487
+ stopDynamicView: () => {
8488
+ const { xyflow, fitViewPadding } = get2();
8489
+ set2({
8490
+ activeDynamicViewStep: null,
8491
+ dimmed: EmptyStringSet
8492
+ }), xyflow.fitView({
8493
+ duration: 400,
8494
+ maxZoom: 1,
8495
+ minZoom: MinZoom,
8496
+ padding: fitViewPadding
8497
+ });
8388
8498
  }
8389
- t_e = t_e + (t_e - t_s) / 2;
8390
- } else
8391
- t_e = t_m;
8392
- while (!done && safety++ < 100);
8393
- if (safety >= 100)
8394
- break;
8395
- prev_arc = prev_arc || arc, circles.push(prev_arc), t_s = prev_e;
8396
- } while (t_e < 1);
8397
- return circles;
8398
- }
8499
+ }),
8500
+ {
8501
+ name: `DiagramStore ${storeDevId++} - ${props.view.id}`,
8502
+ enabled: DEV
8503
+ }
8504
+ )
8505
+ ),
8506
+ shallow
8507
+ );
8399
8508
  }
8400
- function deriveEdgePoints(bezierSpline) {
8401
- let [start2, ...bezierPoints] = bezierSpline;
8402
- invariant(start2, "start should be defined");
8403
- const handles = [
8404
- // start
8405
- ];
8406
- for (; hasAtLeast(bezierPoints, 3); ) {
8407
- 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();
8408
- inflections.length === 0 && inflections.push(0.5), inflections.forEach((t2) => {
8409
- const { x, y } = bezier.get(t2);
8410
- handles.push([x, y]);
8411
- }), bezierPoints = rest, start2 = end;
8412
- }
8413
- return invariant(bezierPoints.length === 0, "all points should be consumed"), handles;
8509
+ const DiagramContext = createContext(null);
8510
+ function DiagramContextProvider({ children: children2, view, ...props }) {
8511
+ const xyflow = useXYFlow(), store = useRef();
8512
+ return store.current || (store.current = createDiagramStore({
8513
+ xyflow,
8514
+ view,
8515
+ ...props
8516
+ })), useEffect(
8517
+ () => {
8518
+ var _a, _b;
8519
+ ((_a = store.current) == null ? void 0 : _a.getState().xyflow) !== xyflow && ((_b = store.current) == null || _b.setState({ xyflow }, !1, "update xyflow"));
8520
+ },
8521
+ [xyflow]
8522
+ ), useUpdateEffect(
8523
+ () => {
8524
+ if (!store.current) return;
8525
+ const state = store.current.getState();
8526
+ state.view !== view && state.updateView(view), hasSubObject(state, props) || store.current.setState(props, !1, "update incoming props");
8527
+ },
8528
+ [view, props]
8529
+ ), /* @__PURE__ */ jsx(DiagramContext.Provider, { value: store.current, children: children2 });
8414
8530
  }
8415
8531
  const nodeZIndex = (node) => node.level + 1;
8416
8532
  function diagramViewToXYFlowData(view, opts) {
8533
+ var _a, _b;
8417
8534
  const isDynamicView = view.__ === "dynamic", editor = {
8418
8535
  nodes: [],
8419
8536
  edges: []
@@ -8425,7 +8542,7 @@ function diagramViewToXYFlowData(view, opts) {
8425
8542
  for (; next = traverse.pop(); ) {
8426
8543
  const { node, parent } = next;
8427
8544
  node.children.length > 0 && traverse.unshift(...node.children.map((child) => ({ node: nodeById(child), parent: node })));
8428
- const isCompound = hasAtLeast(node.children, 1), position = {
8545
+ const isCompound = hasAtLeast$1(node.children, 1), position = {
8429
8546
  x: node.position[0],
8430
8547
  y: node.position[1]
8431
8548
  };
@@ -8478,8 +8595,8 @@ function diagramViewToXYFlowData(view, opts) {
8478
8595
  });
8479
8596
  }
8480
8597
  for (const edge of view.edges) {
8481
- const source = edge.source, target = edge.target, id2 = ns + edge.id, controlPoints = deriveEdgePoints(edge.points);
8482
- invariant(hasAtLeast(edge.points, 2), "edge should have at least 2 points");
8598
+ const source = edge.source, target = edge.target, id2 = ns + edge.id;
8599
+ invariant(hasAtLeast$1(edge.points, 2), "edge should have at least 2 points");
8483
8600
  const level = Math.max(nodeZIndex(nodeById(source)), nodeZIndex(nodeById(target)));
8484
8601
  editor.edges.push({
8485
8602
  id: id2,
@@ -8491,7 +8608,7 @@ function diagramViewToXYFlowData(view, opts) {
8491
8608
  data: {
8492
8609
  edge,
8493
8610
  type: "bezier",
8494
- controlPoints,
8611
+ controlPoints: ((_b = (_a = view.manualLayout) == null ? void 0 : _a.edges[edge.id]) == null ? void 0 : _b.controlPoints) || null,
8495
8612
  headPoint: edge.headArrowPoint ?? null,
8496
8613
  tailPoint: edge.tailArrowPoint ?? null,
8497
8614
  stepNum: isDynamicView ? extractStep(edge.id) : null,
@@ -8509,9 +8626,6 @@ function diagramViewToXYFlowData(view, opts) {
8509
8626
  }
8510
8627
  return editor;
8511
8628
  }
8512
- function toDomPrecision(v) {
8513
- return v === null ? 0.01 : Math.round(v * 100) / 100;
8514
- }
8515
8629
  function selectDimensions(state) {
8516
8630
  return `${Math.round(state.width)}:${Math.round(state.height)}`;
8517
8631
  }
@@ -8523,8 +8637,8 @@ function FitViewOnViewportResize({ diagramApi, xyflowApi }) {
8523
8637
  focusedNodeId || prevDimensionsRef.current === dimensions || (fitDiagram(xyflowApi), prevDimensionsRef.current = dimensions);
8524
8638
  },
8525
8639
  [dimensions, diagramApi, xyflowApi],
8526
- 200,
8527
- 800
8640
+ 250,
8641
+ 1e3
8528
8642
  ), null;
8529
8643
  }
8530
8644
  function selector$2({ view, xyflowSynced, viewportChanged, lastOnNavigate, ...s }) {
@@ -8553,25 +8667,21 @@ function FitViewOnDiagramChange() {
8553
8667
  waitCorrection,
8554
8668
  elFrom,
8555
8669
  elTo
8556
- } = useDiagramState(selector$2), diagramApi = useDiagramStoreApi(), processedRef = useRef(pendingViewId);
8670
+ } = useDiagramState(selector$2, shallowEqual), diagramApi = useDiagramStoreApi(), processedRef = useRef(pendingViewId);
8557
8671
  return useEffect(() => {
8558
8672
  if (!(!xyflowSynced || pendingViewId === processedRef.current)) {
8559
- if (waitCorrection && elTo && elFrom) {
8560
- const [x, y, zoom2] = xyflowApi.getState().transform, { xyflow, lastOnNavigate } = diagramApi.getState(), nextZoom = Math.min(
8561
- elFrom.width / elTo.width,
8562
- elFrom.height / elTo.height
8563
- ), centerFrom = lastOnNavigate.elementCenterScreenPosition;
8564
- nextZoom !== 1 && nextZoom < zoom2 && (xyflowApi.setState({ transform: [x, y, nextZoom] }), xyflow.setViewport({
8565
- x,
8566
- y,
8567
- zoom: nextZoom
8568
- }));
8569
- const centerTo = xyflow.flowToScreenPosition({
8570
- x: elTo.position[0] + elTo.width / 2,
8571
- y: elTo.position[1] + elTo.height / 2
8673
+ if (waitCorrection) {
8674
+ invariant(elTo, "elTo should be defined"), invariant(elFrom, "elFrom should be defined");
8675
+ const { xyflow, lastOnNavigate } = diagramApi.getState();
8676
+ invariant(lastOnNavigate, "lastOnNavigate should be defined");
8677
+ const fromPos = lastOnNavigate.elementScreenPosition, toPos = xyflow.flowToScreenPosition({
8678
+ x: elTo.position[0],
8679
+ // + elFrom.width / 2,
8680
+ y: elTo.position[1]
8681
+ // + elFrom.height / 2
8572
8682
  }), diff = {
8573
- x: toDomPrecision(centerFrom.x - centerTo.x),
8574
- y: toDomPrecision(centerFrom.y - centerTo.y)
8683
+ x: toDomPrecision(fromPos.x - toPos.x),
8684
+ y: toDomPrecision(fromPos.y - toPos.y)
8575
8685
  };
8576
8686
  xyflowApi.getState().panBy(diff), diagramApi.setState({ lastOnNavigate: null });
8577
8687
  return;
@@ -8596,8 +8706,8 @@ function SelectEdgesOnNodeFocus() {
8596
8706
  type: "select",
8597
8707
  selected: !0
8598
8708
  });
8599
- const anotherNode = nodeLookup.get(edge.source === focusedNodeId ? edge.target : edge.source);
8600
- anotherNode && fitViewNodes.add(anotherNode);
8709
+ const anotherNode = nonNullable(nodeLookup.get(edge.source === focusedNodeId ? edge.target : edge.source));
8710
+ fitViewNodes.add(anotherNode);
8601
8711
  } else edge.selected && edgeChanges.push({
8602
8712
  id: edge.id,
8603
8713
  type: "select",
@@ -8614,8 +8724,7 @@ function SelectEdgesOnNodeFocus() {
8614
8724
  type: "select",
8615
8725
  selected: !0
8616
8726
  }), edgeChanges.length > 0 && triggerEdgeChanges(edgeChanges), triggerNodeChanges(nodeChanges), fitView2({
8617
- includeHiddenNodes: !0,
8618
- duration: 300,
8727
+ duration: 350,
8619
8728
  padding: 0.1,
8620
8729
  minZoom: MinZoom,
8621
8730
  maxZoom: Math.max(1, transform2[2]),
@@ -8651,9 +8760,13 @@ function SyncWithDiagram() {
8651
8760
  } : update;
8652
8761
  })), setEdges(updates.edges.map((update) => {
8653
8762
  const existing = edgeLookup.get(update.id);
8654
- return existing ? deepEqual(existing.data.edge, update.data.edge) ? existing : {
8763
+ return existing ? deepEqual(existing.data.controlPoints, update.data.controlPoints) && deepEqual(existing.data.edge, update.data.edge) ? existing : {
8655
8764
  ...existing,
8656
- ...update
8765
+ ...update,
8766
+ data: {
8767
+ ...existing.data,
8768
+ ...update.data
8769
+ }
8657
8770
  } : update;
8658
8771
  })), diagramStoreApi.setState(
8659
8772
  {
@@ -8664,123 +8777,28 @@ function SyncWithDiagram() {
8664
8777
  );
8665
8778
  }, [xyflowSynced, xyflowApi, diagramStoreApi]), null;
8666
8779
  }
8667
- function getVarName(variable) {
8668
- var matches = variable.match(/^var\((.*)\)$/);
8669
- return matches ? matches[1] : variable;
8670
- }
8671
- function get(obj, path) {
8672
- var result = obj;
8673
- for (var key of path) {
8674
- if (!(key in result))
8675
- throw new Error("Path ".concat(path.join(" -> "), " does not exist in object"));
8676
- result = result[key];
8677
- }
8678
- return result;
8679
- }
8680
- function walkObject(obj, fn) {
8681
- var path = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : [], clone = {};
8682
- for (var key in obj) {
8683
- var _value = obj[key], currentPath = [...path, key];
8684
- typeof _value == "string" || typeof _value == "number" || _value == null ? clone[key] = fn(_value, currentPath) : typeof _value == "object" && !Array.isArray(_value) ? clone[key] = walkObject(_value, fn, currentPath) : console.warn('Skipping invalid key "'.concat(currentPath.join("."), '". Should be a string, number, null or object. Received: "').concat(Array.isArray(_value) ? "Array" : typeof _value, '"'));
8685
- }
8686
- return clone;
8687
- }
8688
- function assignInlineVars(varsOrContract, tokens) {
8689
- var styles = {};
8690
- if (typeof tokens == "object") {
8691
- var _contract = varsOrContract;
8692
- walkObject(tokens, (value2, path) => {
8693
- if (value2 != null) {
8694
- var varName2 = get(_contract, path);
8695
- styles[getVarName(varName2)] = String(value2);
8696
- }
8697
- });
8698
- } else {
8699
- var _vars = varsOrContract;
8700
- for (var varName in _vars) {
8701
- var value = _vars[varName];
8702
- value != null && (styles[getVarName(varName)] = value);
8703
- }
8704
- }
8705
- return Object.defineProperty(styles, "toString", {
8706
- value: function() {
8707
- return Object.keys(this).map((key) => "".concat(key, ":").concat(this[key])).join(";");
8708
- },
8709
- writable: !1
8710
- }), styles;
8711
- }
8712
8780
  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";
8713
- function getNodeIntersectionFromCenterToPoint(intersectionNode, [x1, y1]) {
8781
+ function getNodeIntersectionFromCenterToPoint(intersectionNode, { x: x1, y: y1 }) {
8714
8782
  const {
8715
8783
  width: intersectionNodeWidth,
8716
8784
  height: intersectionNodeHeight
8717
8785
  } = 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;
8718
- return [x, y];
8719
- }
8720
- function getNodeIntersection(intersectionNode, targetNode) {
8721
- const {
8722
- width: intersectionNodeWidth,
8723
- height: intersectionNodeHeight
8724
- } = getNodeDimensions(intersectionNode), {
8725
- width: targetNodeWidth,
8726
- height: targetNodeHeight
8727
- } = getNodeDimensions(targetNode), intersectionNodePosition = intersectionNode.internals.positionAbsolute, targetPosition = targetNode.internals.positionAbsolute, w = intersectionNodeWidth / 2, h = intersectionNodeHeight / 2, x2 = intersectionNodePosition.x + w, y2 = intersectionNodePosition.y + h, x1 = targetPosition.x + targetNodeWidth / 2, y1 = targetPosition.y + targetNodeHeight / 2, 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;
8728
8786
  return { x, y };
8729
8787
  }
8730
- function getPointPosition(node, intersectionPoint) {
8731
- const n = {
8732
- // x: node.data.element.position[0],
8733
- // y: node.data.element.position[1],
8734
- ...node.internals.positionAbsolute,
8735
- ...getNodeDimensions(node)
8736
- }, nx = Math.round(n.x), ny = Math.round(n.y), px = Math.round(intersectionPoint.x), py = Math.round(intersectionPoint.y);
8737
- let handlePosition = Position.Top;
8738
- px <= nx + 1 ? handlePosition = Position.Left : px >= nx + n.width - 1 ? handlePosition = Position.Right : py <= ny + 1 ? handlePosition = Position.Top : py >= n.y + n.height - 1 && (handlePosition = Position.Bottom);
8739
- let handleWidth = 8, handleHeight = 8, offsetX = 0, offsetY = 0;
8740
- switch (handlePosition) {
8741
- case Position.Left:
8742
- offsetX = -handleWidth;
8743
- break;
8744
- case Position.Right:
8745
- offsetX = handleWidth;
8746
- break;
8747
- case Position.Top:
8748
- offsetY = -handleHeight;
8749
- break;
8750
- case Position.Bottom:
8751
- offsetY = handleHeight;
8752
- break;
8753
- }
8754
- return [
8755
- intersectionPoint.x + offsetX,
8756
- intersectionPoint.y + offsetY,
8757
- handlePosition
8758
- ];
8759
- }
8760
- function getEdgeParams(source, target) {
8761
- const sourceIntersectionPoint = getNodeIntersection(source, target), targetIntersectionPoint = getNodeIntersection(target, source), [sx, sy, sourcePos] = getPointPosition(source, sourceIntersectionPoint), [tx, ty, targetPos] = getPointPosition(target, targetIntersectionPoint);
8762
- return {
8763
- sx,
8764
- sy,
8765
- tx,
8766
- ty,
8767
- sourcePos,
8768
- targetPos
8769
- };
8770
- }
8771
8788
  function bezierPath(bezierSpline) {
8772
8789
  let [start2, ...points] = bezierSpline;
8773
8790
  invariant(start2, "start should be defined");
8774
8791
  let path = `M ${start2[0]},${start2[1]}`;
8775
- for (; hasAtLeast(points, 3); ) {
8792
+ for (; hasAtLeast$1(points, 3); ) {
8776
8793
  const [cp1, cp2, end, ...rest] = points;
8777
8794
  path = path + ` C ${cp1[0]},${cp1[1]} ${cp2[0]},${cp2[1]} ${end[0]},${end[1]}`, points = rest;
8778
8795
  }
8779
8796
  return invariant(points.length === 0, "all points should be consumed"), path;
8780
8797
  }
8781
- 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(
8782
- ([a, b]) => isSamePoint(a[0], b[0]) && isSamePoint(a[1], b[1])
8783
- ), curve = line().curve(curveCatmullRomOpen), RelationshipEdge = /* @__PURE__ */ memo(function({
8798
+ const isSame = (a, b) => Math.abs(a - b) < 3.1, isSamePoint = (a, b) => {
8799
+ const [ax, ay] = isArray(a) ? a : [a.x, a.y], [bx, by] = isArray(b) ? b : [b.x, b.y];
8800
+ return isSame(ax, bx) && isSame(ay, by);
8801
+ }, sameControlPoints = (a, b) => a === b ? !0 : !a || !b || a.length !== b.length ? !1 : a.every((ap, i) => isSamePoint(ap, b[i])), isEqualProps$2 = (prev, next) => prev.id === next.id && prev.source === next.source && prev.target === next.target && deepEqual(prev.selected ?? !1, next.selected ?? !1) && isSame(prev.sourceX, next.sourceX) && isSame(prev.sourceY, next.sourceY) && isSame(prev.targetX, next.targetX) && isSame(prev.targetY, next.targetY) && deepEqual(prev.data.stepNum, next.data.stepNum) && sameControlPoints(prev.data.controlPoints, next.data.controlPoints) && deepEqual(prev.data.edge, next.data.edge), curve = line().curve(curveCatmullRomOpen).x((d) => d.x).y((d) => d.y), RelationshipEdge = /* @__PURE__ */ memo(function({
8784
8802
  id: id2,
8785
8803
  data,
8786
8804
  selected: _selected,
@@ -8789,38 +8807,76 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 3.1, isSamePosition = (a, [bx, b
8789
8807
  target,
8790
8808
  interactionWidth
8791
8809
  }) {
8792
- var _a, _b, _c, _d;
8793
- 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) => ({
8794
- isActive: s.activeDynamicViewStep !== null && s.activeDynamicViewStep === data.stepNum,
8810
+ var _a, _b;
8811
+ const diagramStore = useDiagramStoreApi(), xyflowStore = useXYStoreApi(), { isActive, isEditable, isEdgePathEditable, isHovered, isDimmed } = useDiagramState((s) => ({
8812
+ isEditable: s.readonly !== !0,
8813
+ isEdgePathEditable: s.readonly !== !0 && s.experimentalEdgeEditing === !0,
8814
+ isActive: s.focusedNodeId === source || s.focusedNodeId === target || s.activeDynamicViewStep !== null && s.activeDynamicViewStep === data.stepNum,
8795
8815
  isHovered: s.hoveredEdgeId === id2,
8796
8816
  isDimmed: s.dimmed.has(id2)
8797
- })), line2 = diagramEdge.line ?? "dashed", isDotted = line2 === "dotted", isDashed = isDotted || line2 === "dashed";
8817
+ })), { nodeLookup, edgeLookup } = xyflowStore.getState(), sourceNode = nonNullable(nodeLookup.get(source), `source node ${source} not found`), targetNode = nonNullable(nodeLookup.get(target), `target node ${target} not found`), isModified = isEditable && (isTruthy(data.controlPoints) || !isSamePoint(sourceNode.internals.positionAbsolute, sourceNode.data.element.position) || !isSamePoint(targetNode.internals.positionAbsolute, targetNode.data.element.position)), {
8818
+ label,
8819
+ edge: {
8820
+ points: diagramEdgePoints,
8821
+ line: line2 = "dashed",
8822
+ color: color2 = "gray",
8823
+ ...diagramEdge
8824
+ }
8825
+ } = data;
8826
+ let controlPoints = data.controlPoints ?? bezierControlPoints(data.edge);
8827
+ const isStepEdge = data.stepNum !== null, isDotted = line2 === "dotted", isDashed = isDotted || line2 === "dashed";
8798
8828
  let strokeDasharray;
8799
8829
  isDotted ? strokeDasharray = "1,8" : isDashed && (strokeDasharray = "8,10");
8800
- const marker = `url(#arrow-${id2})`;
8801
- let edgePath, labelX, labelY;
8802
- if (!isModified)
8803
- 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;
8804
- else {
8805
- const { sx, sy, tx, ty, sourcePos, targetPos } = getEdgeParams(sourceNode, targetNode), [_edgePath, _labelX, _labelY] = getBezierPath({
8806
- sourceX: sx,
8807
- sourceY: sy,
8808
- sourcePosition: sourcePos,
8809
- targetPosition: targetPos,
8810
- targetX: tx,
8811
- targetY: ty
8812
- });
8813
- edgePath = _edgePath, labelX = _labelX, labelY = _labelY;
8814
- const sourceCenterPos = getNodePositionWithOrigin(sourceNode, [-0.5, -0.5]), targetCenterPos = getNodePositionWithOrigin(targetNode, [-0.5, -0.5]);
8815
- edgePath = curve([
8816
- [sourceCenterPos.positionAbsolute.x, sourceCenterPos.positionAbsolute.y],
8830
+ let labelX = (label == null ? void 0 : label.bbox.x) ?? 0, labelY = (label == null ? void 0 : label.bbox.y) ?? 0;
8831
+ const [labelPos, setLabelPosition] = useState({
8832
+ x: labelX,
8833
+ y: labelY
8834
+ });
8835
+ let edgePath;
8836
+ if (isModified) {
8837
+ labelX = labelPos.x, labelY = labelPos.y;
8838
+ const sourceCenterPos = getNodePositionWithOrigin(sourceNode, [-0.5, -0.5]), targetCenterPos = getNodePositionWithOrigin(targetNode, [-0.5, -0.5]), points = [
8839
+ sourceCenterPos.positionAbsolute,
8817
8840
  getNodeIntersectionFromCenterToPoint(sourceNode, first(controlPoints)),
8818
8841
  ...controlPoints,
8819
8842
  getNodeIntersectionFromCenterToPoint(targetNode, last(controlPoints)),
8820
- [targetCenterPos.positionAbsolute.x, targetCenterPos.positionAbsolute.y]
8821
- ]);
8822
- }
8823
- return /* @__PURE__ */ jsxs(
8843
+ targetCenterPos.positionAbsolute
8844
+ ];
8845
+ edgePath = nonNullable(curve(points));
8846
+ } else
8847
+ edgePath = bezierPath(diagramEdgePoints);
8848
+ const svgPathRef = useRef(null);
8849
+ useIsomorphicLayoutEffect$1(() => {
8850
+ const path = svgPathRef.current;
8851
+ if (!path) return;
8852
+ const dompoint = path.getPointAtLength(path.getTotalLength() * 0.5), point = {
8853
+ x: Math.round(dompoint.x),
8854
+ y: Math.round(dompoint.y)
8855
+ };
8856
+ setLabelPosition((current) => isSamePoint(current, point) ? current : point);
8857
+ }, [edgePath]);
8858
+ const onControlPointerDown = (index2, e) => {
8859
+ const { domNode } = xyflowStore.getState();
8860
+ if (!domNode) return;
8861
+ const { xyflow } = diagramStore.getState();
8862
+ e.stopPropagation();
8863
+ let hasMoved = !1, pointer2 = { x: e.clientX, y: e.clientY };
8864
+ const onPointerMove = (e2) => {
8865
+ if (!isSamePoint(pointer2, [e2.clientX, e2.clientY])) {
8866
+ hasMoved = !0, pointer2 = { x: e2.clientX, y: e2.clientY };
8867
+ const { x, y } = xyflow.screenToFlowPosition(pointer2, { snapToGrid: !1 }), newControlPoints = controlPoints.slice();
8868
+ newControlPoints[index2] = {
8869
+ x: toDomPrecision(x),
8870
+ y: toDomPrecision(y)
8871
+ }, xyflow.updateEdgeData(id2, { controlPoints: newControlPoints });
8872
+ }
8873
+ }, onPointerUp = () => {
8874
+ domNode.removeEventListener("pointermove", onPointerMove), domNode.removeEventListener("pointerup", onPointerUp), hasMoved && diagramStore.getState().triggerSaveManualLayout(xyflowStore);
8875
+ };
8876
+ domNode.addEventListener("pointermove", onPointerMove), domNode.addEventListener("pointerup", onPointerUp, { once: !0 });
8877
+ }, marker = `url(#arrow-${id2})`;
8878
+ let markerStart = diagramEdge.tailArrow ? marker : void 0, markerEnd = diagramEdge.headArrow ? marker : void 0;
8879
+ return isModified && diagramEdge.dir === "back" && ([markerStart, markerEnd] = [markerEnd, markerStart]), /* @__PURE__ */ jsxs(
8824
8880
  "g",
8825
8881
  {
8826
8882
  className: clsx([
@@ -8832,38 +8888,62 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 3.1, isSamePosition = (a, [bx, b
8832
8888
  "data-edge-active": isActive,
8833
8889
  "data-edge-hovered": isHovered,
8834
8890
  children: [
8835
- /* @__PURE__ */ jsx("g", { className: markerContext, children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
8836
- "marker",
8837
- {
8838
- id: `arrow-${id2}`,
8839
- viewBox: "0 0 16 10",
8840
- refX: isModified ? "12" : "10",
8841
- refY: "5",
8842
- markerWidth: "5",
8843
- markerHeight: "4",
8844
- markerUnits: "strokeWidth",
8845
- preserveAspectRatio: "xMaxYMid meet",
8846
- orient: "auto-start-reverse",
8847
- children: /* @__PURE__ */ jsx("path", { d: "M 0 0 L 16 5 L 0 10 z", stroke: "context-stroke", fill: "context-stroke" })
8848
- }
8849
- ) }) }),
8891
+ /* @__PURE__ */ jsxs("g", { className: markerContext, children: [
8892
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
8893
+ "marker",
8894
+ {
8895
+ id: `arrow-${id2}`,
8896
+ viewBox: "0 0 16 10",
8897
+ refX: isModified ? "15" : "1",
8898
+ refY: "5",
8899
+ markerWidth: "5",
8900
+ markerHeight: "4",
8901
+ markerUnits: "strokeWidth",
8902
+ preserveAspectRatio: "xMaxYMid meet",
8903
+ orient: "auto-start-reverse",
8904
+ children: /* @__PURE__ */ jsx("path", { d: "M 0 0 L 16 5 L 0 10 z", stroke: "context-stroke", fill: "context-stroke" })
8905
+ }
8906
+ ) }),
8907
+ /* @__PURE__ */ jsx(
8908
+ "path",
8909
+ {
8910
+ className: clsx("react-flow__edge-path", edgePathBg),
8911
+ d: edgePath,
8912
+ style: style2,
8913
+ strokeLinecap: "round"
8914
+ }
8915
+ ),
8916
+ /* @__PURE__ */ jsx(
8917
+ "path",
8918
+ {
8919
+ ref: svgPathRef,
8920
+ className: clsx("react-flow__edge-path", cssEdgePath),
8921
+ d: edgePath,
8922
+ style: style2,
8923
+ strokeLinecap: "round",
8924
+ strokeDasharray,
8925
+ markerStart,
8926
+ markerEnd
8927
+ }
8928
+ )
8929
+ ] }),
8850
8930
  /* @__PURE__ */ jsx(
8851
- RelationshipPath,
8931
+ "path",
8852
8932
  {
8853
- edgePath,
8854
- interactionWidth: interactionWidth ?? 10,
8855
- strokeDasharray,
8856
- markerStart: diagramEdge.tailArrow ? marker : void 0,
8857
- markerEnd: diagramEdge.headArrow ? marker : void 0,
8858
- style: style2
8933
+ className: clsx("react-flow__edge-interaction"),
8934
+ d: edgePath,
8935
+ fill: "none",
8936
+ strokeOpacity: 0,
8937
+ strokeWidth: interactionWidth ?? 10
8859
8938
  }
8860
8939
  ),
8861
- isModified && controlPoints.map((p, i) => /* @__PURE__ */ jsx(
8940
+ isEdgePathEditable && controlPoints.map((p, i) => /* @__PURE__ */ jsx(
8862
8941
  "circle",
8863
8942
  {
8943
+ onPointerDown: (e) => onControlPointerDown(i, e),
8864
8944
  className: controlPoint,
8865
- cx: p[0],
8866
- cy: p[1],
8945
+ cx: p.x,
8946
+ cy: p.y,
8867
8947
  r: 3
8868
8948
  },
8869
8949
  i
@@ -8879,13 +8959,16 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 3.1, isSamePosition = (a, [bx, b
8879
8959
  "data-likec4-color": color2,
8880
8960
  style: {
8881
8961
  ...assignInlineVars({
8882
- [varLabelX]: Math.floor(labelX) + "px",
8883
- [varLabelY]: Math.floor(labelY) + "px"
8962
+ [varLabelX]: isModified ? `calc(${labelX}px - 10%)` : `${labelX}px`,
8963
+ [varLabelY]: isModified ? `${labelY - 5}px` : `${labelY}px`
8884
8964
  }),
8965
+ ...isEdgePathEditable && {
8966
+ pointerEvents: "none"
8967
+ },
8885
8968
  ...data.label && {
8886
8969
  maxWidth: data.label.bbox.width + 12
8887
8970
  },
8888
- zIndex: ((_c = edgeLookup.get(id2)) == null ? void 0 : _c.zIndex) ?? ZIndexes.Edge
8971
+ zIndex: ((_a = edgeLookup.get(id2)) == null ? void 0 : _a.zIndex) ?? ZIndexes.Edge
8889
8972
  },
8890
8973
  mod: {
8891
8974
  "data-edge-hovered": isHovered,
@@ -8893,148 +8976,71 @@ const isSamePoint = (a, b) => Math.abs(a - b) < 3.1, isSamePosition = (a, [bx, b
8893
8976
  },
8894
8977
  children: [
8895
8978
  isStepEdge && /* @__PURE__ */ jsx(Box, { className: stepEdgeNumber, children: data.stepNum }),
8896
- ((_d = data.label) == null ? void 0 : _d.text) && /* @__PURE__ */ jsx(Box, { className: edgeLabelText, children: data.label.text })
8979
+ ((_b = data.label) == null ? void 0 : _b.text) && /* @__PURE__ */ jsx(Box, { className: edgeLabelText, children: data.label.text })
8897
8980
  ]
8898
8981
  }
8899
8982
  ) })
8900
8983
  ]
8901
8984
  }
8902
8985
  );
8903
- }, isEqualProps), RelationshipPath = ({
8904
- edgePath,
8905
- interactionWidth,
8906
- strokeDasharray,
8907
- markerStart,
8908
- markerEnd,
8909
- style: style2
8910
- }) => /* @__PURE__ */ jsxs(Fragment, { children: [
8911
- /* @__PURE__ */ jsx(
8912
- "path",
8913
- {
8914
- className: clsx("react-flow__edge-path", edgePathBg),
8915
- d: edgePath,
8916
- style: style2,
8917
- strokeLinecap: "round"
8918
- }
8919
- ),
8920
- /* @__PURE__ */ jsx(
8921
- "path",
8922
- {
8923
- className: clsx("react-flow__edge-path", cssEdgePath),
8924
- d: edgePath,
8925
- style: style2,
8926
- strokeLinecap: "round",
8927
- strokeDasharray,
8928
- markerStart,
8929
- markerEnd
8930
- }
8931
- ),
8932
- /* @__PURE__ */ jsx(
8933
- "path",
8934
- {
8935
- className: clsx("react-flow__edge-interaction"),
8936
- d: edgePath,
8937
- fill: "none",
8938
- strokeOpacity: 0,
8939
- strokeWidth: interactionWidth
8940
- }
8941
- )
8942
- ] }), Link = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
8943
- "svg",
8944
- {
8945
- ref,
8946
- className: clsx("icon icon-tabler", className),
8947
- stroke: "currentColor",
8948
- fill: "currentColor",
8949
- strokeWidth: "0",
8950
- viewBox: "0 0 20 20",
8951
- height: "20",
8952
- width: "20",
8953
- xmlns: "http://www.w3.org/2000/svg",
8954
- ...props,
8955
- children: /* @__PURE__ */ jsx(
8956
- "path",
8957
- {
8958
- fillRule: "evenodd",
8959
- d: "M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z",
8960
- clipRule: "evenodd"
8961
- }
8962
- )
8963
- }
8964
- )), ZoomIn = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
8965
- "svg",
8966
- {
8967
- ref,
8968
- xmlns: "http://www.w3.org/2000/svg",
8969
- className: clsx("icon icon-tabler icon-tabler-zoom-in", className),
8970
- width: "24",
8971
- height: "24",
8972
- viewBox: "0 0 24 24",
8973
- strokeWidth: "1.5",
8974
- stroke: "currentColor",
8975
- fill: "none",
8976
- strokeLinecap: "round",
8977
- strokeLinejoin: "round",
8978
- ...props,
8979
- children: [
8980
- /* @__PURE__ */ jsx("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
8981
- /* @__PURE__ */ jsx("path", { d: "M10 10m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0" }),
8982
- /* @__PURE__ */ jsx("path", { d: "M7 10l6 0" }),
8983
- /* @__PURE__ */ jsx("path", { d: "M10 7l0 6" }),
8984
- /* @__PURE__ */ jsx("path", { d: "M21 21l-6 -6" })
8985
- ]
8986
- }
8987
- ));
8986
+ }, isEqualProps$2);
8988
8987
  function NavigateToBtn({ xynodeId, className }) {
8989
8988
  const diagramApi = useDiagramStoreApi();
8990
8989
  return /* @__PURE__ */ jsx(
8991
8990
  ActionIcon,
8992
8991
  {
8993
8992
  className: clsx("nodrag nopan", className),
8994
- radius: "xl",
8993
+ radius: "md",
8995
8994
  onPointerDownCapture: (e) => e.stopPropagation(),
8996
8995
  onClick: (event) => {
8997
8996
  event.stopPropagation(), diagramApi.getState().triggerOnNavigateTo(xynodeId, event);
8998
8997
  },
8999
8998
  onDoubleClick: (event) => event.stopPropagation(),
9000
- children: /* @__PURE__ */ jsx(ZoomIn, {})
8999
+ children: /* @__PURE__ */ jsx(
9000
+ IconZoomScan,
9001
+ {
9002
+ style: {
9003
+ width: "75%",
9004
+ height: "75%"
9005
+ }
9006
+ }
9007
+ )
9001
9008
  }
9002
9009
  );
9003
9010
  }
9004
- var container$3 = "lbtzdo0", dimmed$1 = "lbtzdo1", varTransparency = "var(--lbtzdo2)", compoundBody = "lbtzdo3", transparent = "lbtzdo6", title$2 = "lbtzdo7", indicator$1 = "lbtzdob", navigateBtn = "lbtzdod";
9005
- const CompoundNodeMemo = /* @__PURE__ */ memo(function({
9011
+ var container$3 = "lbtzdo0", dimmed$1 = "lbtzdo1", varOpacity = "var(--lbtzdo2)", varBorderTransparency = "var(--lbtzdo3)", compoundBody = "lbtzdo4", transparent = "lbtzdo6", title$2 = "lbtzdo7", titleWithNavigation = "lbtzdo8", indicator$1 = "lbtzdoc", navigateBtn = "lbtzdoe";
9012
+ const isEqualProps$1 = (prev, next) => prev.id === next.id && deepEqual(prev.data.element, next.data.element), CompoundNodeMemo = /* @__PURE__ */ memo(function({
9006
9013
  id: id2,
9007
9014
  data: {
9008
9015
  element: element2
9009
9016
  }
9010
9017
  }) {
9011
- const { color: color2, style: style2, depth = 1, ...compound } = element2, opacity = style2.opacity ?? 100, { isHovered, isDimmed, hasOnNavigateTo } = useDiagramState((s) => ({
9018
+ DEV && useTilg();
9019
+ const { color: color2, style: style2, depth = 1, ...compound } = element2, opacity = clamp$1((style2.opacity ?? 100) / 100, {
9020
+ min: 0,
9021
+ max: 1
9022
+ }), borderTransparency = clamp$1(50 - opacity * 50, {
9023
+ min: 0,
9024
+ max: 50
9025
+ }), { isHovered, isDimmed, hasOnNavigateTo } = useDiagramState((s) => ({
9012
9026
  isHovered: s.hoveredNodeId === id2,
9013
9027
  isDimmed: s.dimmed.has(id2),
9014
9028
  hasOnNavigateTo: !!s.onNavigateTo
9015
- })), isnavigable = !!compound.navigateTo && hasOnNavigateTo, transparency = clamp$1(100 - opacity, {
9016
- min: 0,
9017
- max: 99
9018
- });
9029
+ })), isnavigable = !!compound.navigateTo && hasOnNavigateTo;
9019
9030
  return /* @__PURE__ */ jsxs(
9020
9031
  Box,
9021
9032
  {
9022
9033
  className: clsx(
9023
9034
  container$3,
9024
9035
  "likec4-compound-node",
9025
- opacity < 100 && "likec4-compound-transparent",
9036
+ opacity < 1 && "likec4-compound-transparent",
9026
9037
  isDimmed && dimmed$1
9027
9038
  ),
9028
9039
  mod: {
9029
9040
  "compound-depth": depth,
9030
9041
  "likec4-color": color2,
9031
- "likec4-shape": compound.shape,
9032
- "likec4-navigable": isnavigable,
9033
9042
  hovered: isHovered
9034
9043
  },
9035
- style: assignInlineVars({
9036
- [varTransparency]: transparency + "%"
9037
- }),
9038
9044
  children: [
9039
9045
  /* @__PURE__ */ jsx(
9040
9046
  Handle,
@@ -9057,15 +9063,27 @@ const CompoundNodeMemo = /* @__PURE__ */ memo(function({
9057
9063
  /* @__PURE__ */ jsx(
9058
9064
  "div",
9059
9065
  {
9060
- className: clsx(compoundBody, opacity < 100 && transparent, "likec4-compound"),
9061
- style: {
9062
- borderStyle: opacity < 100 ? style2.border : void 0
9063
- },
9066
+ className: clsx(
9067
+ compoundBody,
9068
+ opacity < 1 && transparent,
9069
+ "likec4-compound"
9070
+ ),
9071
+ style: opacity < 1 ? {
9072
+ ...assignInlineVars({
9073
+ [varBorderTransparency]: `${borderTransparency}%`,
9074
+ [varOpacity]: opacity.toFixed(2)
9075
+ }),
9076
+ borderStyle: style2.border ?? "dashed"
9077
+ } : void 0,
9064
9078
  children: /* @__PURE__ */ jsx(
9065
9079
  Text,
9066
9080
  {
9067
9081
  component: "div",
9068
- className: clsx(title$2, "likec4-compound-title"),
9082
+ className: clsx(
9083
+ title$2,
9084
+ isnavigable && titleWithNavigation,
9085
+ "likec4-compound-title"
9086
+ ),
9069
9087
  children: compound.title
9070
9088
  }
9071
9089
  )
@@ -9083,7 +9101,7 @@ const CompoundNodeMemo = /* @__PURE__ */ memo(function({
9083
9101
  ]
9084
9102
  }
9085
9103
  );
9086
- });
9104
+ }, isEqualProps$1);
9087
9105
  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";
9088
9106
  function ElementIcon({
9089
9107
  node,
@@ -9112,6 +9130,29 @@ function ElementIcon({
9112
9130
  }
9113
9131
  );
9114
9132
  }
9133
+ const Link = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
9134
+ "svg",
9135
+ {
9136
+ ref,
9137
+ className: clsx("icon icon-tabler", className),
9138
+ stroke: "currentColor",
9139
+ fill: "currentColor",
9140
+ strokeWidth: "0",
9141
+ viewBox: "0 0 20 20",
9142
+ height: "20",
9143
+ width: "20",
9144
+ xmlns: "http://www.w3.org/2000/svg",
9145
+ ...props,
9146
+ children: /* @__PURE__ */ jsx(
9147
+ "path",
9148
+ {
9149
+ fillRule: "evenodd",
9150
+ d: "M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z",
9151
+ clipRule: "evenodd"
9152
+ }
9153
+ )
9154
+ }
9155
+ ));
9115
9156
  var elementLink = "_4ysv0o0", trigger = "_4ysv0o1";
9116
9157
  function ElementLink({
9117
9158
  element: element2
@@ -9372,8 +9413,7 @@ const selectedScale = 1.015, variants = {
9372
9413
  // tap: {
9373
9414
  // scale: 0.9
9374
9415
  // }
9375
- };
9376
- function ElementNode({
9416
+ }, isEqualProps = (prev, next) => prev.id === next.id && deepEqual(prev.selected ?? !1, next.selected ?? !1) && deepEqual(prev.dragging ?? !1, next.dragging ?? !1) && deepEqual(prev.width ?? 0, next.width ?? 0) && deepEqual(prev.height ?? 0, next.height ?? 0) && deepEqual(prev.data.element, next.data.element), ElementNodeMemo = memo(function({
9377
9417
  id: id2,
9378
9418
  data: {
9379
9419
  element: element$1
@@ -9383,6 +9423,7 @@ function ElementNode({
9383
9423
  width,
9384
9424
  height
9385
9425
  }) {
9426
+ DEV && useTilg();
9386
9427
  const { isHovered, isDimmed, hasOnNavigateTo, isHovercards, isInteractive } = useDiagramState((s) => ({
9387
9428
  isHovered: s.hoveredNodeId === id2,
9388
9429
  isDimmed: s.dimmed.has(id2),
@@ -9406,7 +9447,7 @@ function ElementNode({
9406
9447
  break;
9407
9448
  }
9408
9449
  return /* @__PURE__ */ jsxs(
9409
- motion.div,
9450
+ m.div,
9410
9451
  {
9411
9452
  id: id2,
9412
9453
  className: clsx([
@@ -9500,29 +9541,11 @@ function ElementNode({
9500
9541
  ]
9501
9542
  }
9502
9543
  );
9503
- }
9504
- function literalToEnum(value) {
9505
- switch (value) {
9506
- case "dots":
9507
- return BackgroundVariant.Dots;
9508
- case "lines":
9509
- return BackgroundVariant.Lines;
9510
- case "cross":
9511
- return BackgroundVariant.Cross;
9512
- default:
9513
- nonexhaustive(value);
9514
- }
9515
- }
9516
- function XYFlowBackground({ background }) {
9517
- if (typeof background == "string")
9518
- return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(background) });
9519
- const { variant, ...rest } = background;
9520
- return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(variant), ...rest });
9521
- }
9544
+ }, isEqualProps);
9522
9545
  function useXYFlowEvents() {
9523
- const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), dblclickTimeout = useRef(), dbclickLock = () => dblclickTimeout.current !== void 0 ? !0 : (dblclickTimeout.current = window.setTimeout(() => {
9546
+ const diagramApi = useDiagramStoreApi(), xyflowApi = useXYStoreApi(), lastClickTimestamp = useRef(), dblclickTimeout = useRef(), dbclickLock = () => dblclickTimeout.current !== void 0 ? !0 : (dblclickTimeout.current = window.setTimeout(() => {
9524
9547
  dblclickTimeout.current = void 0;
9525
- }, 250), !1), hoveredNodeFromOnEdgeEnterRef = useRef("");
9548
+ }, 250), !1), lastClickWasRecent = (ms = 1500) => lastClickTimestamp.current && Date.now() - lastClickTimestamp.current < ms, hoveredNodeFromOnEdgeEnterRef = useRef("");
9526
9549
  return useMemo(() => ({
9527
9550
  onDoubleClick: (event) => {
9528
9551
  const {
@@ -9536,8 +9559,14 @@ function useXYFlowEvents() {
9536
9559
  onPaneClick: (event) => {
9537
9560
  if (dbclickLock())
9538
9561
  return;
9539
- const { focusedNodeId, fitDiagram, onCanvasClick, resetLastClicked } = diagramApi.getState();
9540
- focusedNodeId && (fitDiagram(xyflowApi), onCanvasClick || event.stopPropagation()), resetLastClicked(), onCanvasClick == null || onCanvasClick(event);
9562
+ const {
9563
+ focusedNodeId,
9564
+ activeDynamicViewStep,
9565
+ fitDiagram,
9566
+ onCanvasClick,
9567
+ resetLastClicked
9568
+ } = diagramApi.getState();
9569
+ (focusedNodeId || activeDynamicViewStep) && (fitDiagram(xyflowApi), onCanvasClick || event.stopPropagation()), resetLastClicked(), onCanvasClick == null || onCanvasClick(event);
9541
9570
  },
9542
9571
  onNodeContextMenu: (event, xynode) => {
9543
9572
  var _a, _b;
@@ -9561,12 +9590,17 @@ function useXYFlowEvents() {
9561
9590
  },
9562
9591
  onNodeClick: (event, xynode) => {
9563
9592
  const {
9593
+ zoomable,
9594
+ fitViewEnabled,
9564
9595
  focusedNodeId,
9565
9596
  focusOnNode,
9566
9597
  onNodeClick,
9598
+ lastClickedNodeId,
9567
9599
  setLastClickedNode
9568
9600
  } = diagramApi.getState();
9569
- setLastClickedNode(xynode.id), focusedNodeId && focusedNodeId !== xynode.id && (focusOnNode(xynode.id), onNodeClick || event.stopPropagation()), onNodeClick == null || onNodeClick({
9601
+ setLastClickedNode(xynode.id);
9602
+ const focusPossible = zoomable && fitViewEnabled, shallChangeFocus = !!focusedNodeId && focusedNodeId !== xynode.id, clickedRecently = isNullish(focusedNodeId) && lastClickedNodeId === xynode.id && lastClickWasRecent();
9603
+ focusPossible && (shallChangeFocus || clickedRecently) && (focusOnNode(xynode.id), onNodeClick || event.stopPropagation()), lastClickTimestamp.current = Date.now(), onNodeClick == null || onNodeClick({
9570
9604
  element: xynode.data.element,
9571
9605
  xynode,
9572
9606
  event
@@ -9597,9 +9631,7 @@ function useXYFlowEvents() {
9597
9631
  viewportChanged !== diagramApi.getState().viewportChanged && diagramApi.setState({ viewportChanged }, !1, `viewport-changed: ${viewportChanged}`);
9598
9632
  },
9599
9633
  onNodeMouseEnter: (_event, xynode) => {
9600
- hoveredNodeFromOnEdgeEnterRef.current = "";
9601
- const { hoveredNodeId, setHoveredNode } = diagramApi.getState();
9602
- hoveredNodeId !== xynode.id && setHoveredNode(xynode.id);
9634
+ hoveredNodeFromOnEdgeEnterRef.current = "", diagramApi.getState().setHoveredNode(xynode.id);
9603
9635
  },
9604
9636
  onNodeMouseLeave: (_event, xynode) => {
9605
9637
  const { hoveredNodeId, setHoveredNode } = diagramApi.getState();
@@ -9614,12 +9646,12 @@ function useXYFlowEvents() {
9614
9646
  },
9615
9647
  onEdgeMouseLeave: (_event, xyedge) => {
9616
9648
  const { hoveredEdgeId, setHoveredEdge, hoveredNodeId, setHoveredNode } = diagramApi.getState();
9617
- hoveredEdgeId === xyedge.id && setHoveredEdge(null), hoveredNodeId === hoveredNodeFromOnEdgeEnterRef.current && (hoveredNodeFromOnEdgeEnterRef.current = "", setHoveredNode(null));
9649
+ hoveredEdgeId === xyedge.id && setHoveredEdge(null), hoveredNodeId === hoveredNodeFromOnEdgeEnterRef.current && setHoveredNode(null), hoveredNodeFromOnEdgeEnterRef.current = "";
9618
9650
  }
9619
9651
  }), [diagramApi, xyflowApi]);
9620
9652
  }
9621
9653
  const nodeTypes = {
9622
- element: ElementNode,
9654
+ element: ElementNodeMemo,
9623
9655
  compound: CompoundNodeMemo
9624
9656
  }, edgeTypes = {
9625
9657
  relationship: RelationshipEdge
@@ -9627,7 +9659,12 @@ const nodeTypes = {
9627
9659
  nodesSelectable: s.nodesSelectable || s.focusedNodeId !== null,
9628
9660
  nodesDraggable: s.nodesDraggable,
9629
9661
  fitView: s.fitViewEnabled,
9630
- fitViewPadding: s.fitViewPadding,
9662
+ fitViewOptions: {
9663
+ minZoom: MinZoom,
9664
+ maxZoom: 1,
9665
+ padding: s.fitViewPadding,
9666
+ includeHiddenNodes: !0
9667
+ },
9631
9668
  hasOnNavigateTo: !!s.onNavigateTo,
9632
9669
  hasOnNodeClick: !!s.onNodeClick,
9633
9670
  hasOnNodeContextMenu: !!s.onNodeContextMenu,
@@ -9638,17 +9675,19 @@ const nodeTypes = {
9638
9675
  pannable: s.pannable
9639
9676
  });
9640
9677
  function XYFlow({
9678
+ colorMode = "system",
9641
9679
  className,
9642
9680
  children: children2,
9643
9681
  defaultNodes,
9644
9682
  defaultEdges,
9645
9683
  style: style2
9646
9684
  }) {
9685
+ DEV && useTilg();
9647
9686
  const xyflowApi = useXYStoreApi(), diagramApi = useDiagramStoreApi(), {
9648
9687
  nodesSelectable,
9649
9688
  nodesDraggable,
9650
9689
  fitView: fitView2,
9651
- fitViewPadding,
9690
+ fitViewOptions,
9652
9691
  pannable,
9653
9692
  zoomable,
9654
9693
  hasOnNodeClick,
@@ -9657,7 +9696,7 @@ function XYFlow({
9657
9696
  hasOnCanvasContextMenu,
9658
9697
  hasOnEdgeContextMenu,
9659
9698
  hasOnEdgeClick
9660
- } = useDiagramState(selector$1), layoutConstraints = useLayoutConstraints(), handlers = useXYFlowEvents(), { colorScheme } = useMantineColorScheme(), colorMode = colorScheme !== "auto" ? colorScheme : void 0;
9699
+ } = useDiagramState(selector$1, deepEqual), layoutConstraints = useLayoutConstraints(), handlers = useXYFlowEvents();
9661
9700
  return useOnViewportChange({
9662
9701
  onEnd: ({ x, y, zoom: zoom2 }) => {
9663
9702
  const rounded = {
@@ -9684,12 +9723,7 @@ function XYFlow({
9684
9723
  maxZoom: zoomable ? 1.9 : 1,
9685
9724
  minZoom: zoomable ? MinZoom : 1,
9686
9725
  fitView: fitView2,
9687
- fitViewOptions: {
9688
- minZoom: MinZoom,
9689
- maxZoom: 1,
9690
- padding: fitViewPadding,
9691
- includeHiddenNodes: !0
9692
- },
9726
+ fitViewOptions,
9693
9727
  preventScrolling: zoomable || pannable,
9694
9728
  defaultMarkerColor: "var(--xy-edge-stroke)",
9695
9729
  noDragClassName: "nodrag",
@@ -9721,9 +9755,9 @@ function XYFlow({
9721
9755
  onNodeClick: handlers.onNodeClick,
9722
9756
  onNodeDoubleClick: handlers.onNodeDoubleClick,
9723
9757
  onEdgeClick: handlers.onEdgeClick,
9724
- onInit: () => {
9758
+ onInit: useCallback(() => {
9725
9759
  diagramApi.setState({ initialized: !0 }, !1, "initialized");
9726
- },
9760
+ }, [diagramApi]),
9727
9761
  ...hasOnNodeContextMenu && {
9728
9762
  onNodeContextMenu: handlers.onNodeContextMenu
9729
9763
  },
@@ -9737,9 +9771,148 @@ function XYFlow({
9737
9771
  }
9738
9772
  );
9739
9773
  }
9740
- var container$1 = "_2jkb2y0", buttons = "_2jkb2y1", btn = "_2jkb2y3";
9774
+ var container$1 = "hbkbtj0", paper = "hbkbtj1", title = "hbkbtj2", description = "hbkbtj3";
9775
+ const selector = (s) => ({
9776
+ id: s.view.id,
9777
+ title: s.view.title ?? "untitled",
9778
+ description: s.view.description,
9779
+ links: s.view.links
9780
+ });
9781
+ function DiagramTitlePanel() {
9782
+ const { id: id2, title: title$12, description: description$12, links } = useDiagramState(selector), [isCollapsed, setCollapsed] = useLocalStorage({
9783
+ key: "diagram-title-panel-collapsed",
9784
+ defaultValue: !1
9785
+ }), toggle = () => setCollapsed((v) => !v);
9786
+ return /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
9787
+ m.div,
9788
+ {
9789
+ initial: { opacity: 0.05, scale: 0.7 },
9790
+ animate: { opacity: 1, scale: 1 },
9791
+ exit: {
9792
+ opacity: 0.05,
9793
+ scale: 0.6
9794
+ },
9795
+ className: clsx("react-flow__panel", container$1),
9796
+ style: {
9797
+ transformOrigin: "left center"
9798
+ },
9799
+ children: /* @__PURE__ */ jsx(
9800
+ Paper,
9801
+ {
9802
+ radius: "sm",
9803
+ withBorder: !isCollapsed,
9804
+ className: paper,
9805
+ p: isCollapsed ? "xs" : "lg",
9806
+ onDoubleClick: (e) => e.stopPropagation(),
9807
+ children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", justify: "stretch", align: "stretch", children: [
9808
+ /* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", onClick: toggle, style: { cursor: "pointer" }, children: [
9809
+ /* @__PURE__ */ jsx(
9810
+ Text,
9811
+ {
9812
+ component: "div",
9813
+ flex: "1",
9814
+ size: isCollapsed ? "sm" : "lg",
9815
+ fw: 500,
9816
+ lh: 1.1,
9817
+ className: title,
9818
+ children: title$12
9819
+ }
9820
+ ),
9821
+ /* @__PURE__ */ jsxs(
9822
+ Text,
9823
+ {
9824
+ hidden: isCollapsed,
9825
+ component: "div",
9826
+ flex: "0 0 auto",
9827
+ inline: !0,
9828
+ size: "xs",
9829
+ fz: 9,
9830
+ fw: 500,
9831
+ c: "dimmed",
9832
+ style: {
9833
+ userSelect: "all"
9834
+ },
9835
+ children: [
9836
+ /* @__PURE__ */ jsxs("span", { style: { userSelect: "none" }, children: [
9837
+ "id:",
9838
+ " "
9839
+ ] }),
9840
+ id2
9841
+ ]
9842
+ }
9843
+ )
9844
+ ] }),
9845
+ !isCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
9846
+ description$12 && /* @__PURE__ */ jsx(
9847
+ Spoiler,
9848
+ {
9849
+ maxHeight: 42,
9850
+ showLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "show more" }),
9851
+ hideLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "hide" }),
9852
+ children: /* @__PURE__ */ jsx(
9853
+ Text,
9854
+ {
9855
+ component: "div",
9856
+ size: "sm",
9857
+ className: description,
9858
+ children: description$12 || "no description"
9859
+ }
9860
+ )
9861
+ }
9862
+ ),
9863
+ !description$12 && /* @__PURE__ */ jsx(
9864
+ Text,
9865
+ {
9866
+ component: "div",
9867
+ size: "xs",
9868
+ c: "dimmed",
9869
+ children: "no description"
9870
+ }
9871
+ ),
9872
+ links && /* @__PURE__ */ jsx(
9873
+ Stack,
9874
+ {
9875
+ gap: 3,
9876
+ justify: "stretch",
9877
+ align: "stretch",
9878
+ children: links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", align: "center", gap: "sm", children: [
9879
+ /* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(
9880
+ Anchor,
9881
+ {
9882
+ href: link,
9883
+ target: "_blank",
9884
+ fz: "xs",
9885
+ truncate: "end",
9886
+ display: "inline-block",
9887
+ w: "100%",
9888
+ children: link
9889
+ }
9890
+ ) }),
9891
+ /* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(
9892
+ Button,
9893
+ {
9894
+ size: "compact-xs",
9895
+ fz: "10",
9896
+ variant: "light",
9897
+ onClick: copy,
9898
+ color: copied ? "teal" : "gray",
9899
+ children: copied ? "copied" : "copy"
9900
+ }
9901
+ ) })
9902
+ ] }, link))
9903
+ }
9904
+ )
9905
+ ] })
9906
+ ] })
9907
+ }
9908
+ )
9909
+ },
9910
+ id2
9911
+ ) });
9912
+ }
9913
+ var container = "_2jkb2y0", buttons = "_2jkb2y1", btn = "_2jkb2y3";
9741
9914
  function DynamicViewWalkthrough() {
9742
- const {
9915
+ const isMobile = useXYStore((s) => s.width <= 750), {
9743
9916
  nextDynamicStep,
9744
9917
  stopDynamicView,
9745
9918
  activeDynamicViewStep,
@@ -9749,17 +9922,30 @@ function DynamicViewWalkthrough() {
9749
9922
  stopDynamicView: s.stopDynamicView,
9750
9923
  activeDynamicViewStep: s.activeDynamicViewStep,
9751
9924
  hasNextSteps: (s.activeDynamicViewStep ?? 1) < s.view.edges.length
9752
- })), buttonProps = {
9925
+ })), isActive = isNumber(activeDynamicViewStep);
9926
+ useHotkeys(
9927
+ isActive ? [
9928
+ ["ArrowLeft", () => nextDynamicStep(-1)],
9929
+ ["ArrowRight", () => nextDynamicStep()],
9930
+ ["Escape", (e) => {
9931
+ e.stopImmediatePropagation(), stopDynamicView();
9932
+ }, { preventDefault: !0 }]
9933
+ ] : [
9934
+ ["ArrowLeft", () => nextDynamicStep()],
9935
+ ["ArrowRight", () => nextDynamicStep()]
9936
+ ]
9937
+ );
9938
+ const buttonProps = {
9753
9939
  className: btn,
9754
- size: "compact-xl",
9755
- radius: "xl"
9940
+ size: isMobile ? "compact-md" : "lg",
9941
+ radius: isMobile ? "lg" : "xl"
9756
9942
  }, nextStep = (increment = 1) => (e) => {
9757
9943
  e.stopPropagation(), nextDynamicStep(increment);
9758
9944
  };
9759
9945
  return /* @__PURE__ */ jsxs(
9760
9946
  Box,
9761
9947
  {
9762
- className: clsx("react-flow__panel", container$1),
9948
+ className: clsx("react-flow__panel", container),
9763
9949
  children: [
9764
9950
  isNullish(activeDynamicViewStep) && /* @__PURE__ */ jsx(
9765
9951
  Button,
@@ -9783,23 +9969,25 @@ function DynamicViewWalkthrough() {
9783
9969
  children: /* @__PURE__ */ jsx(IconPlayerSkipBackFilled, {})
9784
9970
  }
9785
9971
  ),
9786
- /* @__PURE__ */ jsx(
9972
+ /* @__PURE__ */ jsxs(
9787
9973
  Button,
9788
9974
  {
9789
9975
  ...buttonProps,
9790
- px: "sm",
9976
+ px: hasNextSteps ? "md" : "xl",
9791
9977
  onClick: (e) => {
9792
9978
  e.stopPropagation(), stopDynamicView();
9793
9979
  },
9794
- children: /* @__PURE__ */ jsx(IconPlayerStopFilled, {})
9980
+ children: [
9981
+ hasNextSteps && /* @__PURE__ */ jsx(IconPlayerStopFilled, {}),
9982
+ !hasNextSteps && "End"
9983
+ ]
9795
9984
  }
9796
9985
  ),
9797
- /* @__PURE__ */ jsx(
9986
+ hasNextSteps && /* @__PURE__ */ jsx(
9798
9987
  Button,
9799
9988
  {
9800
9989
  ...buttonProps,
9801
9990
  pr: "lg",
9802
- disabled: !hasNextSteps,
9803
9991
  onClick: nextStep(),
9804
9992
  children: /* @__PURE__ */ jsx(IconPlayerSkipForwardFilled, {})
9805
9993
  }
@@ -9824,20 +10012,20 @@ const {
9824
10012
  }));
9825
10013
  function NodeOptions({ selectedNodeIds }) {
9826
10014
  const diagramApi = useDiagramStoreApi(), nodes = useXYNodesData(selectedNodeIds);
9827
- if (!hasAtLeast(nodes, 1))
10015
+ if (!hasAtLeast$1(nodes, 1))
9828
10016
  return null;
9829
10017
  if (nodes.length !== selectedNodeIds.length)
9830
10018
  throw new Error("NodeOptions: nodes and props.nodes should have the same length");
9831
10019
  const showShapeOption = nodes.some((node) => node.type === "element"), [firstNode, ...rest] = nodes, showOpacityOption = rest.length === 0 && firstNode.type === "compound", triggerChange = (style2) => {
9832
10020
  const targets = nodes.map((node) => node.data.element.id);
9833
- invariant(hasAtLeast(targets, 1), "At least one target is required"), diagramApi.getState().triggerOnChange([{
10021
+ invariant(hasAtLeast$1(targets, 1), "At least one target is required"), diagramApi.getState().triggerChangeElementStyle({
9834
10022
  op: "change-element-style",
9835
10023
  style: style2,
9836
10024
  targets
9837
- }]);
10025
+ });
9838
10026
  };
9839
10027
  return /* @__PURE__ */ jsxs(Stack, { children: [
9840
- /* @__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 ]" }) }),
10028
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Text, { size: "xs", c: rest.length > 0 ? "dimmed" : "", truncate: !0, children: rest.length === 0 ? firstNode.data.element.title : "[ multiple ]" }) }),
9841
10029
  showShapeOption && /* @__PURE__ */ jsx(
9842
10030
  ShapeOption,
9843
10031
  {
@@ -9856,7 +10044,7 @@ function NodeOptions({ selectedNodeIds }) {
9856
10044
  }
9857
10045
  }
9858
10046
  ),
9859
- showOpacityOption && /* @__PURE__ */ jsxs(Box, { children: [
10047
+ showOpacityOption && /* @__PURE__ */ jsxs("div", { children: [
9860
10048
  /* @__PURE__ */ jsx(Divider, { label: "opacity and border", labelPosition: "left" }),
9861
10049
  /* @__PURE__ */ jsx(
9862
10050
  OpacityOption,
@@ -9889,7 +10077,7 @@ function Colors({
9889
10077
  const changeColor = (color2) => () => {
9890
10078
  selectedColor !== color2 && onColorChange(color2);
9891
10079
  };
9892
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(TooltipGroup, { openDelay: 400, closeDelay: 300, children: [
10080
+ return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(TooltipGroup, { openDelay: 400, closeDelay: 300, children: [
9893
10081
  /* @__PURE__ */ jsx(Divider, { label: "color", labelPosition: "left" }),
9894
10082
  /* @__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(
9895
10083
  Tooltip,
@@ -9941,7 +10129,7 @@ function ShapeOption({
9941
10129
  onShapeChange
9942
10130
  }) {
9943
10131
  let selectedShape = firstNode.data.element.shape;
9944
- return takeWhile(nodes, (node) => node.data.element.shape !== selectedShape ? (selectedShape = null, !1) : !0), /* @__PURE__ */ jsxs(Box, { children: [
10132
+ return takeWhile(nodes, (node) => node.data.element.shape !== selectedShape ? (selectedShape = null, !1) : !0), /* @__PURE__ */ jsxs("div", { children: [
9945
10133
  /* @__PURE__ */ jsx(Divider, { label: "shape", labelPosition: "left" }),
9946
10134
  /* @__PURE__ */ jsx(
9947
10135
  Select,
@@ -9965,7 +10153,7 @@ function NavigateToOption({
9965
10153
  nodes: [node, ...nodes]
9966
10154
  }) {
9967
10155
  const isMultiple = nodes.length >= 1;
9968
- return /* @__PURE__ */ jsxs(Box, { children: [
10156
+ return /* @__PURE__ */ jsxs("div", { children: [
9969
10157
  /* @__PURE__ */ jsx(Divider, { label: "navigate to", labelPosition: "left" }),
9970
10158
  /* @__PURE__ */ jsx(
9971
10159
  Select,
@@ -9989,7 +10177,7 @@ function OpacityOption({
9989
10177
  }) {
9990
10178
  let selectedOpacity = node.data.element.style.opacity ?? 100;
9991
10179
  const [value, setValue] = useState(selectedOpacity);
9992
- return useEffect(() => {
10180
+ return useUpdateEffect(() => {
9993
10181
  setValue(selectedOpacity);
9994
10182
  }, [selectedOpacity]), /* @__PURE__ */ jsx(
9995
10183
  Slider,
@@ -10009,7 +10197,7 @@ function BorderStyleOption({
10009
10197
  }) {
10010
10198
  let selecteBorderStyle = node.data.element.style.border ?? "dashed";
10011
10199
  const [value, setValue] = useState(selecteBorderStyle);
10012
- return useEffect(() => {
10200
+ return useUpdateEffect(() => {
10013
10201
  setValue(selecteBorderStyle);
10014
10202
  }, [selecteBorderStyle]), /* @__PURE__ */ jsx(Box, { mt: "md", children: /* @__PURE__ */ jsx(
10015
10203
  SegmentedControl,
@@ -10031,15 +10219,15 @@ function BorderStyleOption({
10031
10219
  ) });
10032
10220
  }
10033
10221
  var panel = "_1lmzt1h0";
10034
- function OptionsPanel() {
10222
+ const OptionsPanelMemo = memo(function() {
10035
10223
  const isFocusDisabled = useDiagramState((s) => isNullish(s.focusedNodeId)), [selectedNodes, setSelectedNodes] = useState([]);
10036
10224
  return useOnSelectionChange({
10037
10225
  onChange: ({ nodes }) => {
10038
- const next = nodes.map((n) => n.id).sort();
10039
- setSelectedNodes((prev) => shallowEqual(prev, next) ? prev : next);
10226
+ const next = nodes.map((n) => n.id);
10227
+ setSelectedNodes((prev) => deepEqual(prev, next) ? prev : next);
10040
10228
  }
10041
10229
  }), /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isFocusDisabled && selectedNodes.length > 0 && /* @__PURE__ */ jsx(
10042
- motion.div,
10230
+ m.div,
10043
10231
  {
10044
10232
  initial: { opacity: 0, scale: 0.85 },
10045
10233
  animate: { opacity: 1, scale: 1 },
@@ -10055,147 +10243,26 @@ function OptionsPanel() {
10055
10243
  children: /* @__PURE__ */ jsx(Card, { shadow: "sm", children: /* @__PURE__ */ jsx(NodeOptions, { selectedNodeIds: selectedNodes }) })
10056
10244
  }
10057
10245
  ) });
10246
+ }), OptionsPanel2 = OptionsPanelMemo;
10247
+ function literalToEnum(value) {
10248
+ switch (value) {
10249
+ case "dots":
10250
+ return BackgroundVariant.Dots;
10251
+ case "lines":
10252
+ return BackgroundVariant.Lines;
10253
+ case "cross":
10254
+ return BackgroundVariant.Cross;
10255
+ default:
10256
+ nonexhaustive(value);
10257
+ }
10058
10258
  }
10059
- var container = "hbkbtj0", paper = "hbkbtj1", title = "hbkbtj2", description = "hbkbtj3";
10060
- const selector = (s) => ({
10061
- id: s.view.id,
10062
- title: s.view.title ?? "untitled",
10063
- description: s.view.description,
10064
- links: s.view.links
10065
- });
10066
- function DiagramTitlePanel() {
10067
- const { id: id2, title: title$12, description: description$12, links } = useDiagramState(selector), [isCollapsed, setCollapsed] = useLocalStorage({
10068
- key: "diagram-title-panel-collapsed",
10069
- defaultValue: !1
10070
- }), toggle = () => setCollapsed((v) => !v);
10071
- return /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
10072
- motion.div,
10073
- {
10074
- initial: { opacity: 0.05, scale: 0.7 },
10075
- animate: { opacity: 1, scale: 1 },
10076
- exit: {
10077
- opacity: 0.05,
10078
- scale: 0.6
10079
- },
10080
- className: clsx("react-flow__panel", container),
10081
- style: {
10082
- transformOrigin: "left center"
10083
- },
10084
- children: /* @__PURE__ */ jsx(
10085
- Paper,
10086
- {
10087
- radius: "sm",
10088
- withBorder: !isCollapsed,
10089
- className: paper,
10090
- p: isCollapsed ? "xs" : "lg",
10091
- onDoubleClick: (e) => e.stopPropagation(),
10092
- children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", justify: "stretch", align: "stretch", children: [
10093
- /* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", onClick: toggle, style: { cursor: "pointer" }, children: [
10094
- /* @__PURE__ */ jsx(
10095
- Text,
10096
- {
10097
- component: "div",
10098
- flex: "1",
10099
- size: isCollapsed ? "sm" : "lg",
10100
- fw: 500,
10101
- lh: 1.1,
10102
- className: title,
10103
- children: title$12
10104
- }
10105
- ),
10106
- /* @__PURE__ */ jsxs(
10107
- Text,
10108
- {
10109
- hidden: isCollapsed,
10110
- component: "div",
10111
- flex: "0 0 auto",
10112
- inline: !0,
10113
- size: "xs",
10114
- fz: 9,
10115
- fw: 500,
10116
- c: "dimmed",
10117
- style: {
10118
- userSelect: "all"
10119
- },
10120
- children: [
10121
- /* @__PURE__ */ jsxs("span", { style: { userSelect: "none" }, children: [
10122
- "id:",
10123
- " "
10124
- ] }),
10125
- id2
10126
- ]
10127
- }
10128
- )
10129
- ] }),
10130
- !isCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
10131
- description$12 && /* @__PURE__ */ jsx(
10132
- Spoiler,
10133
- {
10134
- maxHeight: 42,
10135
- showLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "show more" }),
10136
- hideLabel: /* @__PURE__ */ jsx(Button, { color: "gray", variant: "light", fz: "10", size: "compact-xs", children: "hide" }),
10137
- children: /* @__PURE__ */ jsx(
10138
- Text,
10139
- {
10140
- component: "div",
10141
- size: "sm",
10142
- className: description,
10143
- children: description$12 || "no description"
10144
- }
10145
- )
10146
- }
10147
- ),
10148
- !description$12 && /* @__PURE__ */ jsx(
10149
- Text,
10150
- {
10151
- component: "div",
10152
- size: "xs",
10153
- c: "dimmed",
10154
- children: "no description"
10155
- }
10156
- ),
10157
- links && /* @__PURE__ */ jsx(
10158
- Stack,
10159
- {
10160
- gap: 3,
10161
- justify: "stretch",
10162
- align: "stretch",
10163
- children: links.map((link) => /* @__PURE__ */ jsxs(Group, { wrap: "nowrap", align: "center", gap: "sm", children: [
10164
- /* @__PURE__ */ jsx(Box, { flex: "1", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx(
10165
- Anchor,
10166
- {
10167
- href: link,
10168
- target: "_blank",
10169
- fz: "xs",
10170
- truncate: "end",
10171
- display: "inline-block",
10172
- w: "100%",
10173
- children: link
10174
- }
10175
- ) }),
10176
- /* @__PURE__ */ jsx(CopyButton, { value: link, children: ({ copied, copy }) => /* @__PURE__ */ jsx(
10177
- Button,
10178
- {
10179
- size: "compact-xs",
10180
- fz: "10",
10181
- variant: "light",
10182
- onClick: copy,
10183
- color: copied ? "teal" : "gray",
10184
- children: copied ? "copied" : "copy"
10185
- }
10186
- ) })
10187
- ] }, link))
10188
- }
10189
- )
10190
- ] })
10191
- ] })
10192
- }
10193
- )
10194
- },
10195
- id2
10196
- ) });
10259
+ function XYFlowBackground({ background }) {
10260
+ if (typeof background == "string")
10261
+ return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(background) });
10262
+ const { variant, ...rest } = background;
10263
+ return /* @__PURE__ */ jsx(Background, { variant: literalToEnum(variant), ...rest });
10197
10264
  }
10198
- function XYFlowInner({
10265
+ const XYFlowInner = memo(function({
10199
10266
  children: children2,
10200
10267
  background,
10201
10268
  controls,
@@ -10214,12 +10281,12 @@ function XYFlowInner({
10214
10281
  return /* @__PURE__ */ jsxs(Fragment, { children: [
10215
10282
  background !== "transparent" && background !== "solid" && /* @__PURE__ */ jsx(XYFlowBackground, { background }),
10216
10283
  controls && /* @__PURE__ */ jsx(Controls, { position: "bottom-right" }),
10217
- readonly === !1 && /* @__PURE__ */ jsx(OptionsPanel, {}),
10284
+ readonly === !1 && /* @__PURE__ */ jsx(OptionsPanel2, {}),
10218
10285
  !isDynamicViewActive && showDiagramTitle === !0 && /* @__PURE__ */ jsx(DiagramTitlePanel, {}),
10219
10286
  isDynamicView2 && enableDynamicViewWalkthrough && /* @__PURE__ */ jsx(DynamicViewWalkthrough, {}),
10220
10287
  children2
10221
10288
  ] });
10222
- }
10289
+ }, shallowEqual);
10223
10290
  function LikeC4Diagram({
10224
10291
  view,
10225
10292
  className,
@@ -10231,13 +10298,14 @@ function LikeC4Diagram({
10231
10298
  nodesSelectable = !readonly,
10232
10299
  nodesDraggable = !readonly,
10233
10300
  background = "dots",
10234
- controls = !readonly,
10301
+ controls = !1,
10235
10302
  showElementLinks = !0,
10236
10303
  showDiagramTitle = !0,
10237
10304
  enableDynamicViewWalkthrough = !0,
10238
10305
  initialWidth,
10239
10306
  initialHeight,
10240
10307
  keepAspectRatio = !1,
10308
+ experimentalEdgeEditing = !1,
10241
10309
  onCanvasClick,
10242
10310
  onCanvasContextMenu,
10243
10311
  onCanvasDblClick,
@@ -10248,7 +10316,7 @@ function LikeC4Diagram({
10248
10316
  onNodeClick,
10249
10317
  onNodeContextMenu
10250
10318
  }) {
10251
- console.log("LikeC4Diagram");
10319
+ DEV && useTilg();
10252
10320
  const initialRef = useRef();
10253
10321
  if (!initialRef.current) {
10254
10322
  const initial = diagramViewToXYFlowData(view, {
@@ -10279,6 +10347,7 @@ function LikeC4Diagram({
10279
10347
  showElementLinks,
10280
10348
  nodesDraggable,
10281
10349
  nodesSelectable,
10350
+ experimentalEdgeEditing,
10282
10351
  onCanvasClick,
10283
10352
  onCanvasContextMenu,
10284
10353
  onEdgeClick,
@@ -10288,50 +10357,76 @@ function LikeC4Diagram({
10288
10357
  onChange,
10289
10358
  onNavigateTo,
10290
10359
  onCanvasDblClick,
10291
- children: /* @__PURE__ */ jsxs(
10360
+ children: /* @__PURE__ */ jsx(LazyMotion, { features: domAnimation, strict: !0, children: /* @__PURE__ */ jsx(
10292
10361
  KeepAspectRatioContainer,
10293
10362
  {
10294
10363
  className: clsx(rootClassName, className),
10295
10364
  enabled: keepAspectRatio,
10296
10365
  width: view.width,
10297
10366
  height: view.height,
10298
- children: [
10299
- /* @__PURE__ */ jsx(
10300
- XYFlow,
10301
- {
10302
- className: clsx(
10303
- "likec4-diagram",
10304
- cssReactFlow,
10305
- controls === !1 && cssNoControls,
10306
- pannable !== !0 && cssDisablePan,
10307
- background === "transparent" && cssTransparentBg
10308
- ),
10309
- defaultNodes: initialRef.current.defaultNodes,
10310
- defaultEdges: initialRef.current.defaultEdges,
10311
- children: /* @__PURE__ */ jsx(
10312
- XYFlowInner,
10313
- {
10314
- showDiagramTitle,
10315
- enableDynamicViewWalkthrough,
10316
- background,
10317
- controls
10318
- }
10319
- )
10320
- }
10321
- ),
10322
- /* @__PURE__ */ jsxs(WhenInitialized, { children: [
10323
- /* @__PURE__ */ jsx(SyncWithDiagram, {}),
10324
- fitView2 && /* @__PURE__ */ jsx(FitViewOnDiagramChange, {}),
10325
- fitView2 && zoomable && /* @__PURE__ */ jsx(SelectEdgesOnNodeFocus, {})
10326
- ] })
10327
- ]
10367
+ children: /* @__PURE__ */ jsx(
10368
+ LikeC4DiagramInnerMemo,
10369
+ {
10370
+ defaultNodes: initialRef.current.defaultNodes,
10371
+ defaultEdges: initialRef.current.defaultEdges,
10372
+ fitView: fitView2,
10373
+ zoomable,
10374
+ background,
10375
+ controls,
10376
+ pannable,
10377
+ showDiagramTitle,
10378
+ enableDynamicViewWalkthrough
10379
+ }
10380
+ )
10328
10381
  }
10329
- )
10382
+ ) })
10330
10383
  }
10331
10384
  )
10332
10385
  }
10333
10386
  ) });
10334
10387
  }
10388
+ const LikeC4DiagramInnerMemo = memo(function({
10389
+ background,
10390
+ fitView: fitView2,
10391
+ zoomable,
10392
+ controls,
10393
+ pannable,
10394
+ defaultNodes,
10395
+ defaultEdges,
10396
+ showDiagramTitle,
10397
+ enableDynamicViewWalkthrough
10398
+ }) {
10399
+ return DEV && useTilg(), /* @__PURE__ */ jsxs(Fragment, { children: [
10400
+ /* @__PURE__ */ jsx(
10401
+ XYFlow,
10402
+ {
10403
+ defaultNodes,
10404
+ defaultEdges,
10405
+ className: clsx(
10406
+ "likec4-diagram",
10407
+ cssReactFlow,
10408
+ controls === !1 && cssNoControls,
10409
+ pannable !== !0 && cssDisablePan,
10410
+ background === "transparent" && cssTransparentBg
10411
+ ),
10412
+ children: /* @__PURE__ */ jsx(
10413
+ XYFlowInner,
10414
+ {
10415
+ showDiagramTitle,
10416
+ enableDynamicViewWalkthrough,
10417
+ background,
10418
+ controls
10419
+ }
10420
+ )
10421
+ }
10422
+ ),
10423
+ /* @__PURE__ */ jsxs(WhenInitialized, { children: [
10424
+ /* @__PURE__ */ jsx(SyncWithDiagram, {}),
10425
+ fitView2 && /* @__PURE__ */ jsx(FitViewOnDiagramChange, {}),
10426
+ fitView2 && zoomable && /* @__PURE__ */ jsx(SelectEdgesOnNodeFocus, {})
10427
+ ] })
10428
+ ] });
10429
+ }, shallowEqual);
10335
10430
  function StaticLikeC4Diagram({
10336
10431
  view,
10337
10432
  fitView: fitView2 = !0,