@dagrejs/dagre 3.0.0 → 3.1.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 (35) hide show
  1. package/dist/dagre.cjs.js +1 -1
  2. package/dist/dagre.cjs.js.map +3 -3
  3. package/dist/dagre.esm.js +1 -1
  4. package/dist/dagre.esm.js.map +3 -3
  5. package/dist/dagre.js +486 -54
  6. package/dist/dagre.js.map +3 -3
  7. package/dist/dagre.min.js +1 -1
  8. package/dist/dagre.min.js.map +3 -3
  9. package/dist/types/lib/acyclic.d.ts +1 -1
  10. package/dist/types/lib/acyclic.d.ts.map +1 -1
  11. package/dist/types/lib/add-border-segments.d.ts.map +1 -1
  12. package/dist/types/lib/coordinate-system.d.ts +22 -0
  13. package/dist/types/lib/coordinate-system.d.ts.map +1 -1
  14. package/dist/types/lib/layout.d.ts.map +1 -1
  15. package/dist/types/lib/nesting-graph.d.ts.map +1 -1
  16. package/dist/types/lib/order/index.d.ts +2 -8
  17. package/dist/types/lib/order/index.d.ts.map +1 -1
  18. package/dist/types/lib/order/init-order.d.ts +2 -2
  19. package/dist/types/lib/order/init-order.d.ts.map +1 -1
  20. package/dist/types/lib/order/sort-subgraph.d.ts +5 -2
  21. package/dist/types/lib/order/sort-subgraph.d.ts.map +1 -1
  22. package/dist/types/lib/order/sort.d.ts +3 -1
  23. package/dist/types/lib/order/sort.d.ts.map +1 -1
  24. package/dist/types/lib/parent-dummy-chains.d.ts.map +1 -1
  25. package/dist/types/lib/position/bk.d.ts +2 -2
  26. package/dist/types/lib/position/bk.d.ts.map +1 -1
  27. package/dist/types/lib/position/index.d.ts +1 -1
  28. package/dist/types/lib/position/index.d.ts.map +1 -1
  29. package/dist/types/lib/rank/index.d.ts.map +1 -1
  30. package/dist/types/lib/types.d.ts +24 -6
  31. package/dist/types/lib/types.d.ts.map +1 -1
  32. package/dist/types/lib/util.d.ts +3 -2
  33. package/dist/types/lib/util.d.ts.map +1 -1
  34. package/dist/types/lib/version.d.ts +1 -1
  35. package/package.json +2 -2
package/dist/dagre.js CHANGED
@@ -769,9 +769,34 @@ var dagre = (() => {
769
769
  }, {});
770
770
  }
771
771
  var GRAPH_NODE = "\0";
772
+ function compareByOldOrder(oldNodes, nodeA, nodeB) {
773
+ var _a, _b, _c, _d, _e, _f;
774
+ if (!(oldNodes && nodeA && nodeB && nodeA.dummy === "edge" && nodeB.dummy === "edge" && nodeA.edgeObj && nodeB.edgeObj && oldNodes[nodeA.edgeObj.v] && oldNodes[nodeB.edgeObj.v] && oldNodes[nodeA.edgeObj.w] && oldNodes[nodeB.edgeObj.w])) {
775
+ return 0;
776
+ }
777
+ let isForward = true;
778
+ if (nodeA.edgeObj.w === nodeB.edgeObj.w) {
779
+ isForward = false;
780
+ }
781
+ const targetRank = isForward ? (_b = (_a = oldNodes[nodeA.edgeObj.v]) == null ? void 0 : _a.rank) != null ? _b : NaN + 1 : (_d = (_c = oldNodes[nodeA.edgeObj.w]) == null ? void 0 : _c.rank) != null ? _d : NaN - 1;
782
+ const oldA = Object.entries(oldNodes).find((n) => {
783
+ var _a2, _b2;
784
+ return ((_a2 = n[1].edgeObj) == null ? void 0 : _a2.v) === nodeA.edgeObj.v && ((_b2 = n[1].edgeObj) == null ? void 0 : _b2.w) === nodeA.edgeObj.w && n[1].rank === targetRank;
785
+ });
786
+ const oldB = Object.entries(oldNodes).find((n) => {
787
+ var _a2, _b2;
788
+ return ((_a2 = n[1].edgeObj) == null ? void 0 : _a2.v) === nodeB.edgeObj.v && ((_b2 = n[1].edgeObj) == null ? void 0 : _b2.w) === nodeB.edgeObj.w && n[1].rank === targetRank;
789
+ });
790
+ if (!oldA || !oldB) {
791
+ return 0;
792
+ }
793
+ const oldOrderA = (_e = oldA[1].order) != null ? _e : NaN;
794
+ const oldOrderB = (_f = oldB[1].order) != null ? _f : NaN;
795
+ return isNaN(oldOrderA - oldOrderB) ? 0 : oldOrderA - oldOrderB;
796
+ }
772
797
 
773
798
  // lib/version.ts
774
- var version = "3.0.0";
799
+ var version = "3.1.0";
775
800
 
776
801
  // lib/data/list.ts
777
802
  var List = class {
@@ -925,8 +950,8 @@ var dagre = (() => {
925
950
  }
926
951
 
927
952
  // lib/acyclic.ts
928
- function run(graph) {
929
- const fas = graph.graph().acyclicer === "greedy" ? greedyFAS(graph, weightFn(graph)) : dfsFAS(graph);
953
+ function run(graph, oldGraph) {
954
+ const fas = graph.graph().acyclicer === "greedy" ? greedyFAS(graph, weightFn(graph)) : dfsFAS(graph, oldGraph != null ? oldGraph : null);
930
955
  fas.forEach((e) => {
931
956
  const label = graph.edge(e);
932
957
  graph.removeEdge(e);
@@ -940,7 +965,7 @@ var dagre = (() => {
940
965
  };
941
966
  }
942
967
  }
943
- function dfsFAS(graph) {
968
+ function dfsFAS(graph, oldGraph) {
944
969
  const fas = [];
945
970
  const stack = {};
946
971
  const visited = {};
@@ -959,7 +984,29 @@ var dagre = (() => {
959
984
  });
960
985
  delete stack[v2];
961
986
  }
962
- graph.nodes().forEach(dfs2);
987
+ function dfsDynamic(v2) {
988
+ var _a;
989
+ if (Object.hasOwn(visited, v2)) {
990
+ return;
991
+ }
992
+ visited[v2] = true;
993
+ stack[v2] = true;
994
+ (_a = graph.outEdges(v2)) == null ? void 0 : _a.forEach((e) => {
995
+ var _a2, _b;
996
+ if (Object.hasOwn(stack, e.w) || ((_a2 = oldGraph.node(v2)) == null ? void 0 : _a2.rank) > ((_b = oldGraph.node(e.w)) == null ? void 0 : _b.rank) && isReachedFromStartWithoutEdge(graph, e.w, e)) {
997
+ fas.push(e);
998
+ } else {
999
+ dfsDynamic(e.w);
1000
+ }
1001
+ });
1002
+ delete stack[v2];
1003
+ }
1004
+ let dfsFn = dfs2;
1005
+ if (oldGraph && typeof oldGraph.node === "function") {
1006
+ dfsFn = dfsDynamic;
1007
+ }
1008
+ graph.sources().forEach(dfsFn);
1009
+ graph.nodes().forEach(dfsFn);
963
1010
  return fas;
964
1011
  }
965
1012
  function undo(graph) {
@@ -974,6 +1021,25 @@ var dagre = (() => {
974
1021
  }
975
1022
  });
976
1023
  }
1024
+ function isReachedFromStartWithoutEdge(graph, node, ignoreEdge) {
1025
+ const localVisited = /* @__PURE__ */ new Set();
1026
+ function reverseDfs(v2) {
1027
+ var _a;
1028
+ if (graph.sources().includes(v2)) {
1029
+ return true;
1030
+ }
1031
+ localVisited.add(v2);
1032
+ for (const e of (_a = graph.inEdges(v2)) != null ? _a : []) {
1033
+ if (!(e.v === ignoreEdge.v && e.w === ignoreEdge.w) && !localVisited.has(e.v)) {
1034
+ if (reverseDfs(e.v)) {
1035
+ return true;
1036
+ }
1037
+ }
1038
+ }
1039
+ return false;
1040
+ }
1041
+ return reverseDfs(node);
1042
+ }
977
1043
 
978
1044
  // lib/normalize.ts
979
1045
  function run2(graph) {
@@ -1316,7 +1382,10 @@ var dagre = (() => {
1316
1382
  var parent_dummy_chains_default = parentDummyChains;
1317
1383
  function parentDummyChains(graph) {
1318
1384
  const postorderNums = postorder2(graph);
1319
- graph.graph().dummyChains.forEach((v2) => {
1385
+ const graphData = graph.graph();
1386
+ if (!Array.isArray(graphData.dummyChains)) return;
1387
+ const dummyChains = graphData.dummyChains;
1388
+ dummyChains.forEach((v2) => {
1320
1389
  let node = graph.node(v2);
1321
1390
  const edgeObj = node.edgeObj;
1322
1391
  const pathData = findPath(graph, postorderNums, edgeObj.v, edgeObj.w);
@@ -1388,7 +1457,9 @@ var dagre = (() => {
1388
1457
  graph.graph().nestingRoot = root;
1389
1458
  graph.edges().forEach((e) => graph.edge(e).minlen *= nodeSep);
1390
1459
  const weight = sumWeights(graph) + 1;
1391
- graph.children(GRAPH_NODE).forEach((child) => dfs(graph, root, nodeSep, weight, height, depths, child));
1460
+ graph.children(GRAPH_NODE).forEach((child) => {
1461
+ dfs(graph, root, nodeSep, weight, height, depths, child);
1462
+ });
1392
1463
  graph.graph().nodeRankFactor = nodeSep;
1393
1464
  }
1394
1465
  function dfs(graph, root, nodeSep, weight, height, depths, v2) {
@@ -1466,7 +1537,7 @@ var dagre = (() => {
1466
1537
  if (children.length) {
1467
1538
  children.forEach(dfs2);
1468
1539
  }
1469
- if (Object.hasOwn(node, "minRank")) {
1540
+ if (node && Object.hasOwn(node, "minRank")) {
1470
1541
  node.borderLeft = [];
1471
1542
  node.borderRight = [];
1472
1543
  for (let rank2 = node.minRank, maxRank2 = node.maxRank + 1; rank2 < maxRank2; ++rank2) {
@@ -1548,7 +1619,7 @@ var dagre = (() => {
1548
1619
  }
1549
1620
 
1550
1621
  // lib/order/init-order.ts
1551
- function initOrder(graph) {
1622
+ function initOrder(graph, oldNodes = null) {
1552
1623
  const visited = {};
1553
1624
  const simpleNodes = graph.nodes().filter((v2) => !graph.children(v2).length);
1554
1625
  const simpleNodesRanks = simpleNodes.map((v2) => graph.node(v2).rank);
@@ -1561,11 +1632,17 @@ var dagre = (() => {
1561
1632
  layers[node.rank].push(v2);
1562
1633
  const successors = graph.successors(v2);
1563
1634
  if (successors) {
1564
- successors.forEach(dfs2);
1635
+ const sortedSuccessors = [...successors].sort((a, b2) => compareOldOrder(a, b2));
1636
+ sortedSuccessors.forEach(dfs2);
1565
1637
  }
1566
1638
  }
1567
1639
  const orderedVs = simpleNodes.sort((a, b2) => graph.node(a).rank - graph.node(b2).rank);
1568
1640
  orderedVs.forEach(dfs2);
1641
+ function compareOldOrder(a, b2) {
1642
+ const nodeA = graph.node(a);
1643
+ const nodeB = graph.node(b2);
1644
+ return compareByOldOrder(oldNodes, nodeA, nodeB);
1645
+ }
1569
1646
  return layers;
1570
1647
  }
1571
1648
 
@@ -1709,7 +1786,19 @@ var dagre = (() => {
1709
1786
  }
1710
1787
 
1711
1788
  // lib/order/sort.ts
1712
- function sort(entries, biasRight) {
1789
+ function sort(entries, reversedPairs, oldNodes, graph, biasRight) {
1790
+ let resolvedReversedPairs = {};
1791
+ let resolvedOldNodes = null;
1792
+ let resolvedGraph = null;
1793
+ let resolvedBiasRight = biasRight;
1794
+ if (typeof reversedPairs === "boolean") {
1795
+ resolvedBiasRight = reversedPairs;
1796
+ resolvedReversedPairs = {};
1797
+ } else if (reversedPairs) {
1798
+ resolvedReversedPairs = reversedPairs;
1799
+ resolvedOldNodes = oldNodes != null ? oldNodes : null;
1800
+ resolvedGraph = graph != null ? graph : null;
1801
+ }
1713
1802
  const parts = partition(entries, (entry) => {
1714
1803
  return Object.hasOwn(entry, "barycenter");
1715
1804
  });
@@ -1719,7 +1808,11 @@ var dagre = (() => {
1719
1808
  let sum = 0;
1720
1809
  let weight = 0;
1721
1810
  let vsIndex = 0;
1722
- sortable.sort(compareWithBias(!!biasRight));
1811
+ sortable.sort(compareWithOldOrder(resolvedGraph, resolvedOldNodes, !!resolvedBiasRight));
1812
+ for (const [key, value] of Object.entries(resolvedReversedPairs)) {
1813
+ const keyIndex = sortable.findIndex((entry) => entry.vs[0] === key);
1814
+ sortable.splice(keyIndex + 1, 0, value);
1815
+ }
1723
1816
  vsIndex = consumeUnsortable(vs, unsortable, vsIndex);
1724
1817
  sortable.forEach((entry) => {
1725
1818
  vsIndex += entry.vs.length;
@@ -1744,19 +1837,36 @@ var dagre = (() => {
1744
1837
  }
1745
1838
  return index;
1746
1839
  }
1747
- function compareWithBias(bias) {
1840
+ function compareWithOldOrder(graph, oldNodes, bias) {
1748
1841
  return (entryV, entryW) => {
1749
1842
  if (entryV.barycenter < entryW.barycenter) {
1750
1843
  return -1;
1751
1844
  } else if (entryV.barycenter > entryW.barycenter) {
1752
1845
  return 1;
1753
1846
  }
1847
+ if (graph && (typeof entryV.vs[0] === "string" || typeof entryW.vs[0] === "string")) {
1848
+ const nodeV = graph.node(entryV.vs[0]);
1849
+ const nodeW = graph.node(entryW.vs[0]);
1850
+ const byOldOrder = compareByOldOrder(oldNodes, nodeV, nodeW);
1851
+ if (byOldOrder !== 0) {
1852
+ return byOldOrder;
1853
+ }
1854
+ }
1754
1855
  return !bias ? entryV.i - entryW.i : entryW.i - entryV.i;
1755
1856
  };
1756
1857
  }
1757
1858
 
1758
1859
  // lib/order/sort-subgraph.ts
1759
- function sortSubgraph(graph, v2, constraintGraph, biasRight) {
1860
+ function sortSubgraph(graph, v2, constraintGraph, oldNodes, biasRight) {
1861
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1862
+ let resolvedOldNodes = null;
1863
+ let resolvedBiasRight = biasRight;
1864
+ if (typeof oldNodes === "boolean") {
1865
+ resolvedBiasRight = oldNodes;
1866
+ resolvedOldNodes = null;
1867
+ } else if (oldNodes !== void 0) {
1868
+ resolvedOldNodes = oldNodes;
1869
+ }
1760
1870
  let movable = graph.children(v2);
1761
1871
  const node = graph.node(v2);
1762
1872
  const bl = node ? node.borderLeft : void 0;
@@ -1768,7 +1878,7 @@ var dagre = (() => {
1768
1878
  const barycenters = barycenter(graph, movable);
1769
1879
  barycenters.forEach((entry) => {
1770
1880
  if (graph.children(entry.v).length) {
1771
- const subgraphResult = sortSubgraph(graph, entry.v, constraintGraph, biasRight);
1881
+ const { result: subgraphResult } = sortSubgraph(graph, entry.v, constraintGraph, resolvedOldNodes, resolvedBiasRight);
1772
1882
  subgraphs[entry.v] = subgraphResult;
1773
1883
  if (Object.hasOwn(subgraphResult, "barycenter")) {
1774
1884
  mergeBarycenters(entry, subgraphResult);
@@ -1777,7 +1887,36 @@ var dagre = (() => {
1777
1887
  });
1778
1888
  const entries = resolveConflicts(barycenters, constraintGraph);
1779
1889
  expandSubgraphs(entries, subgraphs);
1780
- const result = sort(entries, biasRight);
1890
+ const reversedPairs = {};
1891
+ let usedBias = false;
1892
+ for (let i = 0; i < entries.length; i++) {
1893
+ for (let j2 = i + 1; j2 < entries.length; j2++) {
1894
+ if (!entries[i] || !entries[j2] || !((_a = entries[i]) == null ? void 0 : _a.barycenter) || !((_b = entries[j2]) == null ? void 0 : _b.barycenter)) {
1895
+ continue;
1896
+ }
1897
+ if (((_c = entries[i]) == null ? void 0 : _c.barycenter) === entries[j2].barycenter) {
1898
+ const nameI = (_e = (_d = entries[i]) == null ? void 0 : _d.vs[0]) != null ? _e : "";
1899
+ const nameJ = (_g = (_f = entries[j2]) == null ? void 0 : _f.vs[0]) != null ? _g : "";
1900
+ const nodeI = graph.node(nameI);
1901
+ const nodeJ = graph.node(nameJ);
1902
+ if (nodeI.dummy === "edge" && nodeJ.dummy === "edge" && ((_h = nodeI.edgeObj) == null ? void 0 : _h.v) === ((_i = nodeJ.edgeObj) == null ? void 0 : _i.v) && ((_j = nodeI.edgeObj) == null ? void 0 : _j.w) === ((_k = nodeJ.edgeObj) == null ? void 0 : _k.w)) {
1903
+ if (nodeI.edgeLabel.reversed) {
1904
+ reversedPairs[nameJ] = entries[i];
1905
+ entries.splice(i, 1);
1906
+ i--;
1907
+ break;
1908
+ } else {
1909
+ reversedPairs[nameI] = entries[j2];
1910
+ entries.splice(j2, 1);
1911
+ j2--;
1912
+ }
1913
+ } else {
1914
+ usedBias = true;
1915
+ }
1916
+ }
1917
+ }
1918
+ }
1919
+ const result = sort(entries, reversedPairs, resolvedOldNodes, graph, resolvedBiasRight);
1781
1920
  if (bl && br) {
1782
1921
  result.vs = [bl, result.vs, br].flat(1);
1783
1922
  const blPredecessors = graph.predecessors(bl);
@@ -1793,6 +1932,8 @@ var dagre = (() => {
1793
1932
  result.weight += 2;
1794
1933
  }
1795
1934
  }
1935
+ Object.defineProperty(result, "result", { value: result, enumerable: false, configurable: true, writable: true });
1936
+ Object.defineProperty(result, "usedBias", { value: usedBias, enumerable: false, configurable: true, writable: true });
1796
1937
  return result;
1797
1938
  }
1798
1939
  function expandSubgraphs(entries, subgraphs) {
@@ -1880,7 +2021,7 @@ var dagre = (() => {
1880
2021
  }
1881
2022
 
1882
2023
  // lib/order/index.ts
1883
- function order(graph, opts = {}) {
2024
+ function order(graph, opts = {}, oldNodes = null) {
1884
2025
  if (typeof opts.customOrder === "function") {
1885
2026
  opts.customOrder(graph, order);
1886
2027
  return;
@@ -1888,7 +2029,7 @@ var dagre = (() => {
1888
2029
  const maxRank2 = maxRank(graph);
1889
2030
  const downLayerGraphs = buildLayerGraphs(graph, range(1, maxRank2 + 1), "inEdges");
1890
2031
  const upLayerGraphs = buildLayerGraphs(graph, range(maxRank2 - 1, -1, -1), "outEdges");
1891
- let layering = initOrder(graph);
2032
+ let layering = initOrder(graph, oldNodes);
1892
2033
  assignOrder(graph, layering);
1893
2034
  if (opts.disableOptimalOrderHeuristic) {
1894
2035
  return;
@@ -1897,7 +2038,7 @@ var dagre = (() => {
1897
2038
  let best;
1898
2039
  const constraints = opts.constraints || [];
1899
2040
  for (let i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) {
1900
- sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2, constraints);
2041
+ sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2, constraints, oldNodes);
1901
2042
  layering = buildLayerMatrix(graph);
1902
2043
  const cc = crossCount(graph, layering);
1903
2044
  if (cc < bestCC) {
@@ -1935,12 +2076,16 @@ var dagre = (() => {
1935
2076
  return buildLayerGraph(graph, rank2, relationship, nodesByRank.get(rank2) || []);
1936
2077
  });
1937
2078
  }
1938
- function sweepLayerGraphs(layerGraphs, biasRight, constraints) {
2079
+ function sweepLayerGraphs(layerGraphs, switchBias, constraints, oldNodes) {
2080
+ let biasRight = true;
1939
2081
  const cg = new p();
1940
2082
  layerGraphs.forEach(function(lg) {
1941
2083
  constraints.forEach((con) => cg.setEdge(con.left, con.right));
1942
2084
  const root = lg.graph().root;
1943
- const sorted = sortSubgraph(lg, root, cg, biasRight);
2085
+ const { result: sorted, usedBias } = sortSubgraph(lg, root, cg, oldNodes, biasRight);
2086
+ if (switchBias && usedBias) {
2087
+ biasRight = !biasRight;
2088
+ }
1944
2089
  sorted.vs.forEach((v2, i) => lg.node(v2).order = i);
1945
2090
  addSubgraphConstraints(lg, cg, sorted.vs);
1946
2091
  });
@@ -2057,7 +2202,7 @@ var dagre = (() => {
2057
2202
  const conflictsV = conflicts[v2];
2058
2203
  return conflictsV !== void 0 && Object.hasOwn(conflictsV, w2);
2059
2204
  }
2060
- function verticalAlignment(graph, layering, conflicts, neighborFn) {
2205
+ function verticalAlignment(graph, layering, conflicts, neighborFn, corePath) {
2061
2206
  const root = {};
2062
2207
  const align = {};
2063
2208
  const pos = {};
@@ -2070,9 +2215,25 @@ var dagre = (() => {
2070
2215
  });
2071
2216
  layering.forEach((layer) => {
2072
2217
  let prevIdx = -1;
2073
- layer.forEach((v2) => {
2074
- const wsRaw = neighborFn(v2);
2218
+ let alreadyAlignedIndex = -1;
2219
+ let hasShifted = false;
2220
+ let modifiedLayer = layer;
2221
+ const coreNodeIndex = layer.findIndex((v2) => {
2222
+ return (corePath == null ? void 0 : corePath.includes(v2)) || isInCorePath(v2, graph, corePath);
2223
+ });
2224
+ if (coreNodeIndex > 0) {
2225
+ modifiedLayer = [layer[coreNodeIndex], ...layer.slice(0, coreNodeIndex), ...layer.slice(coreNodeIndex + 1)];
2226
+ hasShifted = true;
2227
+ }
2228
+ modifiedLayer.forEach((v2) => {
2229
+ var _a;
2230
+ let wsRaw = neighborFn(v2);
2075
2231
  if (wsRaw && wsRaw.length) {
2232
+ if (corePath == null ? void 0 : corePath.includes(v2)) {
2233
+ wsRaw = wsRaw.filter((w2) => {
2234
+ return isInCorePath(w2, graph, corePath);
2235
+ });
2236
+ }
2076
2237
  const ws = wsRaw.sort((a, b2) => {
2077
2238
  const posA = pos[a];
2078
2239
  const posB = pos[b2];
@@ -2083,12 +2244,17 @@ var dagre = (() => {
2083
2244
  const w2 = ws[i];
2084
2245
  if (w2 === void 0) continue;
2085
2246
  const posW = pos[w2];
2086
- if (posW !== void 0 && align[v2] === v2 && prevIdx < posW && !hasConflict(conflicts, v2, w2)) {
2247
+ if (posW !== void 0 && align[v2] === v2 && prevIdx < posW && pos[w2] !== alreadyAlignedIndex && !hasConflict(conflicts, v2, w2)) {
2087
2248
  const rootW = root[w2];
2088
2249
  if (rootW !== void 0) {
2089
2250
  align[w2] = v2;
2090
2251
  align[v2] = root[v2] = rootW;
2091
2252
  prevIdx = posW;
2253
+ if (hasShifted) {
2254
+ prevIdx = -1;
2255
+ alreadyAlignedIndex = (_a = pos[w2]) != null ? _a : -1;
2256
+ hasShifted = false;
2257
+ }
2092
2258
  }
2093
2259
  }
2094
2260
  }
@@ -2243,7 +2409,7 @@ var dagre = (() => {
2243
2409
  return (((_a = xs[1]) != null ? _a : 0) + ((_b = xs[2]) != null ? _b : 0)) / 2;
2244
2410
  });
2245
2411
  }
2246
- function positionX(graph) {
2412
+ function positionX(graph, corePath) {
2247
2413
  const layering = buildLayerMatrix(graph);
2248
2414
  const conflicts = Object.assign(
2249
2415
  findType1Conflicts(graph, layering),
@@ -2263,7 +2429,7 @@ var dagre = (() => {
2263
2429
  const result = vert === "u" ? graph.predecessors(v2) : graph.successors(v2);
2264
2430
  return result || [];
2265
2431
  };
2266
- const align = verticalAlignment(graph, adjustedLayering, conflicts, neighborFn);
2432
+ const align = verticalAlignment(graph, adjustedLayering, conflicts, neighborFn, corePath);
2267
2433
  let xs = horizontalCompaction(
2268
2434
  graph,
2269
2435
  adjustedLayering,
@@ -2324,12 +2490,21 @@ var dagre = (() => {
2324
2490
  function width(graph, v2) {
2325
2491
  return graph.node(v2).width;
2326
2492
  }
2493
+ function isInCorePath(v2, graph, corePath) {
2494
+ var _a;
2495
+ if (!corePath) return false;
2496
+ const edge = (_a = graph.node(v2)) == null ? void 0 : _a.edgeObj;
2497
+ if (!edge || graph.node(v2).edgeLabel.reversed) return false;
2498
+ const sourceIndex = corePath.indexOf(edge == null ? void 0 : edge.v);
2499
+ const targetIndex = corePath.indexOf(edge == null ? void 0 : edge.w);
2500
+ return sourceIndex !== -1 && targetIndex !== -1 && sourceIndex === (targetIndex + 1) % corePath.length || sourceIndex === (targetIndex - 1) % corePath.length;
2501
+ }
2327
2502
 
2328
2503
  // lib/position/index.ts
2329
- function position(graph) {
2504
+ function position(graph, corePath) {
2330
2505
  graph = asNonCompoundGraph(graph);
2331
2506
  positionY(graph);
2332
- Object.entries(positionX(graph)).forEach(([v2, x2]) => graph.node(v2).x = x2);
2507
+ Object.entries(positionX(graph, corePath)).forEach(([v2, x2]) => graph.node(v2).x = x2);
2333
2508
  }
2334
2509
  function positionY(graph) {
2335
2510
  const layering = buildLayerMatrix(graph);
@@ -2362,19 +2537,233 @@ var dagre = (() => {
2362
2537
  }
2363
2538
 
2364
2539
  // lib/layout.ts
2540
+ var _oldGraph = null;
2541
+ var _rawOldNodes = null;
2365
2542
  function layout(g, opts = {}) {
2366
- const time2 = opts.debugTiming ? time : notime;
2367
- return time2("layout", () => {
2368
- const layoutGraph = time2(" buildLayoutGraph", () => buildLayoutGraph(g));
2369
- time2(" runLayout", () => runLayout(layoutGraph, time2, opts));
2370
- time2(" updateInputGraph", () => updateInputGraph(g, layoutGraph));
2371
- return layoutGraph;
2543
+ recursiveClusterLayout(g, notime, opts);
2544
+ return g;
2545
+ }
2546
+ function topLevelChildOf(g, node, cluster) {
2547
+ let current = node;
2548
+ while (current !== void 0) {
2549
+ const parent = g.parent(current);
2550
+ if (parent === cluster) return current;
2551
+ current = parent;
2552
+ }
2553
+ return void 0;
2554
+ }
2555
+ function recursiveClusterLayout(g, time2, opts) {
2556
+ const clusterNodes = g.nodes().filter((v2) => g.children(v2).length);
2557
+ const clusterBounds = {};
2558
+ clusterNodes.forEach((v2) => {
2559
+ const node = g.node(v2);
2560
+ if (node && node.rankdir) {
2561
+ const subgraph = new p({ multigraph: true, compound: true });
2562
+ subgraph.setGraph({ rankdir: node.rankdir });
2563
+ const children = g.children(v2);
2564
+ children.forEach((childId) => {
2565
+ const childNode = { ...g.node(childId) };
2566
+ subgraph.setNode(childId, childNode);
2567
+ const parent = g.parent(childId);
2568
+ if (parent && parent !== v2 && children.includes(parent)) {
2569
+ subgraph.setParent(childId, parent);
2570
+ }
2571
+ });
2572
+ const proxiedEdges = /* @__PURE__ */ new Set();
2573
+ g.edges().forEach((e) => {
2574
+ const srcChild = topLevelChildOf(g, e.v, v2);
2575
+ const tgtChild = topLevelChildOf(g, e.w, v2);
2576
+ if (srcChild && tgtChild && srcChild !== tgtChild) {
2577
+ const key = `${srcChild}\0${tgtChild}`;
2578
+ if (!proxiedEdges.has(key)) {
2579
+ proxiedEdges.add(key);
2580
+ subgraph.setEdge(srcChild, tgtChild, { ...g.edge(e) });
2581
+ }
2582
+ }
2583
+ });
2584
+ recursiveClusterLayout(subgraph, time2, opts);
2585
+ const subLayoutG = buildLayoutGraph(subgraph);
2586
+ runLayout(subLayoutG, time2, opts);
2587
+ updateInputGraph(subgraph, subLayoutG);
2588
+ let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
2589
+ subgraph.nodes().forEach((u) => {
2590
+ if (u === v2) return;
2591
+ const n = subgraph.node(u);
2592
+ if (n && typeof n.x === "number" && typeof n.y === "number" && typeof n.width === "number" && typeof n.height === "number") {
2593
+ minX = Math.min(minX, n.x - n.width / 2);
2594
+ maxX = Math.max(maxX, n.x + n.width / 2);
2595
+ minY = Math.min(minY, n.y - n.height / 2);
2596
+ maxY = Math.max(maxY, n.y + n.height / 2);
2597
+ }
2598
+ });
2599
+ if (!isFinite(minX) || !isFinite(minY) || !isFinite(maxX) || !isFinite(maxY)) {
2600
+ minX = minY = 0;
2601
+ maxX = maxY = 0;
2602
+ }
2603
+ const width2 = maxX - minX;
2604
+ const height = maxY - minY;
2605
+ clusterBounds[v2] = {
2606
+ minX,
2607
+ minY,
2608
+ maxX,
2609
+ maxY,
2610
+ width: width2,
2611
+ height,
2612
+ offsetX: minX,
2613
+ offsetY: minY
2614
+ };
2615
+ node._dagreClusterSubgraph = subgraph;
2616
+ }
2617
+ });
2618
+ const isolatedClusters = [];
2619
+ const getAllDescendants = (nodeId) => {
2620
+ const result = [];
2621
+ const queue = (g.children(nodeId) || []).filter((c) => c !== nodeId);
2622
+ while (queue.length > 0) {
2623
+ const curr = queue.shift();
2624
+ result.push(curr);
2625
+ (g.children(curr) || []).filter((c) => c !== curr).forEach((c) => queue.push(c));
2626
+ }
2627
+ return result;
2628
+ };
2629
+ const rawClusterMap = /* @__PURE__ */ new Map();
2630
+ clusterNodes.forEach((v2) => {
2631
+ const node = g.node(v2);
2632
+ if (node && node.rankdir && clusterBounds[v2]) {
2633
+ rawClusterMap.set(v2, (g.children(v2) || []).filter((c) => c !== v2));
2634
+ }
2635
+ });
2636
+ const allDirectChildrenFlat = new Set([...rawClusterMap.values()].flat());
2637
+ const clusterChildrenMap = /* @__PURE__ */ new Map();
2638
+ rawClusterMap.forEach((_2, v2) => {
2639
+ if (!allDirectChildrenFlat.has(v2)) {
2640
+ clusterChildrenMap.set(v2, getAllDescendants(v2));
2641
+ }
2642
+ });
2643
+ const allIsolatedChildren = new Set(
2644
+ [...clusterChildrenMap.values()].flat()
2645
+ );
2646
+ const topLevelNode = (id) => {
2647
+ for (const [cId, ch] of clusterChildrenMap) {
2648
+ if (ch.includes(id)) return cId;
2649
+ }
2650
+ return id;
2651
+ };
2652
+ const allSavedEdges = [];
2653
+ g.edges().forEach((e) => {
2654
+ if (allIsolatedChildren.has(e.v) || allIsolatedChildren.has(e.w)) {
2655
+ allSavedEdges.push({ edge: e, label: g.edge(e) });
2656
+ }
2657
+ });
2658
+ const savedParents = /* @__PURE__ */ new Map();
2659
+ allIsolatedChildren.forEach((id) => {
2660
+ const p2 = g.parent(id);
2661
+ savedParents.set(id, typeof p2 === "string" ? p2 : void 0);
2662
+ });
2663
+ clusterChildrenMap.forEach((children, v2) => {
2664
+ const node = g.node(v2);
2665
+ const removedNodes = [];
2666
+ children.forEach((childId) => {
2667
+ const childNode = g.node(childId);
2668
+ if (!childNode) return;
2669
+ removedNodes.push({ id: childId, node: childNode, parent: savedParents.get(childId) });
2670
+ g.removeNode(childId);
2671
+ });
2672
+ const removedEdges = allSavedEdges.filter(
2673
+ ({ edge }) => children.includes(edge.v) || children.includes(edge.w)
2674
+ );
2675
+ const bounds = clusterBounds[v2];
2676
+ if (!node) return;
2677
+ isolatedClusters.push({
2678
+ clusterId: v2,
2679
+ subgraph: node._dagreClusterSubgraph,
2680
+ bounds,
2681
+ children,
2682
+ removedNodes,
2683
+ removedEdges
2684
+ });
2685
+ node.width = bounds.width;
2686
+ node.height = bounds.height;
2687
+ });
2688
+ const proxyEdgeKeys = /* @__PURE__ */ new Set();
2689
+ allSavedEdges.forEach(({ edge, label }) => {
2690
+ const effV = topLevelNode(edge.v);
2691
+ const effW = topLevelNode(edge.w);
2692
+ if (effV !== effW && g.hasNode(effV) && g.hasNode(effW)) {
2693
+ const key = `${effV}\0${effW}`;
2694
+ if (!proxyEdgeKeys.has(key)) {
2695
+ proxyEdgeKeys.add(key);
2696
+ g.setEdge(effV, effW, { ...label, width: 0, height: 0 });
2697
+ }
2698
+ }
2699
+ });
2700
+ const layoutG = buildLayoutGraph(g);
2701
+ runLayout(layoutG, time2, opts);
2702
+ updateInputGraph(g, layoutG);
2703
+ proxyEdgeKeys.forEach((key) => {
2704
+ const sep2 = key.indexOf("\0");
2705
+ const effV = key.slice(0, sep2);
2706
+ const effW = key.slice(sep2 + 1);
2707
+ if (g.hasEdge(effV, effW)) g.removeEdge(effV, effW);
2708
+ });
2709
+ isolatedClusters.forEach(({ clusterId, subgraph, bounds, removedNodes, removedEdges }) => {
2710
+ var _a, _b;
2711
+ const clusterNode = g.node(clusterId);
2712
+ const clusterX = (_a = clusterNode == null ? void 0 : clusterNode.x) != null ? _a : 0;
2713
+ const clusterY = (_b = clusterNode == null ? void 0 : clusterNode.y) != null ? _b : 0;
2714
+ const subgraphCenterX = (bounds.minX + bounds.maxX) / 2;
2715
+ const subgraphCenterY = (bounds.minY + bounds.maxY) / 2;
2716
+ removedNodes.forEach(({ id, node, parent }) => {
2717
+ g.setNode(id, node);
2718
+ if (parent !== void 0) g.setParent(id, parent);
2719
+ });
2720
+ removedEdges.forEach(({ edge, label }) => {
2721
+ g.setEdge(edge, label);
2722
+ });
2723
+ subgraph.nodes().forEach((u) => {
2724
+ if (u === clusterId) return;
2725
+ const subNode = subgraph.node(u);
2726
+ const mainNode = g.node(u);
2727
+ if (mainNode && subNode && typeof subNode.x === "number" && typeof subNode.y === "number") {
2728
+ mainNode.x = clusterX + (subNode.x - subgraphCenterX);
2729
+ mainNode.y = clusterY + (subNode.y - subgraphCenterY);
2730
+ }
2731
+ });
2732
+ delete clusterNode._dagreClusterSubgraph;
2733
+ });
2734
+ clusterNodes.forEach((v2) => {
2735
+ var _a, _b;
2736
+ const node = g.node(v2);
2737
+ const bounds = clusterBounds[v2];
2738
+ if (node && node.rankdir && node._dagreClusterSubgraph && bounds) {
2739
+ const subgraph = node._dagreClusterSubgraph;
2740
+ const parentX = (_a = node.x) != null ? _a : 0;
2741
+ const parentY = (_b = node.y) != null ? _b : 0;
2742
+ const subgraphCenterX = (bounds.minX + bounds.maxX) / 2;
2743
+ const subgraphCenterY = (bounds.minY + bounds.maxY) / 2;
2744
+ subgraph.nodes().forEach((u) => {
2745
+ if (u === v2) return;
2746
+ const subNode = subgraph.node(u);
2747
+ const mainNode = g.node(u);
2748
+ if (mainNode && subNode && typeof subNode.x === "number" && typeof subNode.y === "number") {
2749
+ const dx = subNode.x - subgraphCenterX;
2750
+ const dy = subNode.y - subgraphCenterY;
2751
+ mainNode.x = parentX + dx;
2752
+ mainNode.y = parentY + dy;
2753
+ }
2754
+ });
2755
+ delete node._dagreClusterSubgraph;
2756
+ }
2372
2757
  });
2373
2758
  }
2374
2759
  function runLayout(g, time2, opts) {
2760
+ if ((opts == null ? void 0 : opts.useDynamic) === false) {
2761
+ _oldGraph = null;
2762
+ _rawOldNodes = null;
2763
+ }
2375
2764
  time2(" makeSpaceForEdgeLabels", () => makeSpaceForEdgeLabels(g));
2376
2765
  time2(" removeSelfEdges", () => removeSelfEdges(g));
2377
- time2(" acyclic", () => run(g));
2766
+ time2(" acyclic", () => run(g, _oldGraph));
2378
2767
  time2(" nestingGraph.run", () => run3(g));
2379
2768
  time2(" rank", () => rank_default(asNonCompoundGraph(g)));
2380
2769
  time2(" injectEdgeLabelProxies", () => injectEdgeLabelProxies(g));
@@ -2386,11 +2775,12 @@ var dagre = (() => {
2386
2775
  time2(" normalize.run", () => run2(g));
2387
2776
  time2(" parentDummyChains", () => parent_dummy_chains_default(g));
2388
2777
  time2(" addBorderSegments", () => add_border_segments_default(g));
2389
- time2(" order", () => order(g, opts));
2778
+ time2(" order", () => order(g, opts, _rawOldNodes));
2390
2779
  time2(" insertSelfEdges", () => insertSelfEdges(g));
2391
2780
  time2(" adjustCoordinateSystem", () => adjust(g));
2392
- time2(" position", () => position(g));
2781
+ time2(" position", () => position(g, opts.corePath));
2393
2782
  time2(" positionSelfEdges", () => positionSelfEdges(g));
2783
+ _rawOldNodes = JSON.parse(JSON.stringify(g._nodes));
2394
2784
  time2(" removeBorderNodes", () => removeBorderNodes(g));
2395
2785
  time2(" normalize.undo", () => undo2(g));
2396
2786
  time2(" fixupEdgeLabelCoords", () => fixupEdgeLabelCoords(g));
@@ -2399,6 +2789,7 @@ var dagre = (() => {
2399
2789
  time2(" assignNodeIntersects", () => assignNodeIntersects(g));
2400
2790
  time2(" reversePoints", () => reversePointsForReversedEdges(g));
2401
2791
  time2(" acyclic.undo", () => undo(g));
2792
+ _oldGraph = g;
2402
2793
  }
2403
2794
  function updateInputGraph(inputGraph, layoutGraph) {
2404
2795
  inputGraph.nodes().forEach((v2) => {
@@ -2480,9 +2871,10 @@ var dagre = (() => {
2480
2871
  const graph = g.graph();
2481
2872
  graph.ranksep /= 2;
2482
2873
  g.edges().forEach((e) => {
2874
+ var _a;
2483
2875
  const edge = g.edge(e);
2484
2876
  edge.minlen *= 2;
2485
- if (edge.labelpos.toLowerCase() !== "c") {
2877
+ if (((_a = edge.labelpos) != null ? _a : "r").toLowerCase() !== "c") {
2486
2878
  if (graph.rankdir === "TB" || graph.rankdir === "BT") {
2487
2879
  edge.width += edge.labeloffset;
2488
2880
  } else {
@@ -2574,6 +2966,7 @@ var dagre = (() => {
2574
2966
  }
2575
2967
  function assignNodeIntersects(g) {
2576
2968
  g.edges().forEach((e) => {
2969
+ if (e.v === e.w) return;
2577
2970
  const edge = g.edge(e);
2578
2971
  const nodeV = g.node(e.v);
2579
2972
  const nodeW = g.node(e.w);
@@ -2654,6 +3047,7 @@ var dagre = (() => {
2654
3047
  let orderShift = 0;
2655
3048
  layer.forEach((v2, i) => {
2656
3049
  const node = g.node(v2);
3050
+ if (typeof node.rank !== "number") node.rank = 0;
2657
3051
  node.order = i + orderShift;
2658
3052
  (node.selfEdges || []).forEach((selfEdge) => {
2659
3053
  addDummyNode(g, "selfedge", {
@@ -2662,8 +3056,19 @@ var dagre = (() => {
2662
3056
  rank: node.rank,
2663
3057
  order: i + ++orderShift,
2664
3058
  e: selfEdge.e,
2665
- label: selfEdge.label
3059
+ edgeLabel: selfEdge.label
2666
3060
  }, "_se");
3061
+ if (!Array.isArray(selfEdge.label.points) || selfEdge.label.points.length !== 7) {
3062
+ selfEdge.label.points = [
3063
+ { x: 0, y: -10 },
3064
+ { x: 0, y: -10 },
3065
+ { x: 0, y: 0 },
3066
+ { x: 0, y: 10 },
3067
+ { x: 0, y: 10 },
3068
+ { x: 0, y: 0 },
3069
+ { x: 0, y: 0 }
3070
+ ];
3071
+ }
2667
3072
  });
2668
3073
  delete node.selfEdges;
2669
3074
  });
@@ -2672,24 +3077,51 @@ var dagre = (() => {
2672
3077
  function positionSelfEdges(g) {
2673
3078
  g.nodes().forEach((v2) => {
2674
3079
  const node = g.node(v2);
3080
+ const valid = (val) => typeof val === "number" && isFinite(val);
2675
3081
  if (node.dummy === "selfedge") {
2676
3082
  const selfEdgeNode = node;
2677
3083
  const selfNode = g.node(selfEdgeNode.e.v);
2678
- const x2 = selfNode.x + selfNode.width / 2;
2679
- const y2 = selfNode.y;
2680
- const dx = node.x - x2;
2681
- const dy = selfNode.height / 2;
2682
- g.setEdge(selfEdgeNode.e, selfEdgeNode.label);
2683
- g.removeNode(v2);
2684
- selfEdgeNode.label.points = [
2685
- { x: x2 + 2 * dx / 3, y: y2 - dy },
2686
- { x: x2 + 5 * dx / 6, y: y2 - dy },
2687
- { x: x2 + dx, y: y2 },
2688
- { x: x2 + 5 * dx / 6, y: y2 + dy },
2689
- { x: x2 + 2 * dx / 3, y: y2 + dy }
3084
+ const xVal = valid(selfNode == null ? void 0 : selfNode.x) ? selfNode.x : 0;
3085
+ const yVal = valid(selfNode == null ? void 0 : selfNode.y) ? selfNode.y : 0;
3086
+ const widthVal = valid(selfNode == null ? void 0 : selfNode.width) ? selfNode.width : 0;
3087
+ const heightVal = valid(selfNode == null ? void 0 : selfNode.height) ? selfNode.height : 0;
3088
+ const nodeX = valid(node.x) ? node.x : xVal;
3089
+ const nodeY = valid(node.y) ? node.y : yVal;
3090
+ const dx = widthVal / 2;
3091
+ const dy = heightVal / 2;
3092
+ selfEdgeNode.edgeLabel.points = [
3093
+ { x: nodeX + dx, y: nodeY - dy },
3094
+ { x: nodeX + dx, y: nodeY - dy },
3095
+ { x: nodeX, y: nodeY },
3096
+ { x: nodeX - dx, y: nodeY + dy },
3097
+ { x: nodeX - dx, y: nodeY + dy },
3098
+ { x: nodeX, y: nodeY },
3099
+ { x: nodeX, y: nodeY }
2690
3100
  ];
2691
- selfEdgeNode.label.x = node.x;
2692
- selfEdgeNode.label.y = node.y;
3101
+ selfEdgeNode.edgeLabel.x = nodeX;
3102
+ selfEdgeNode.edgeLabel.y = nodeY;
3103
+ g.setEdge(selfEdgeNode.e, selfEdgeNode.edgeLabel);
3104
+ g.removeNode(v2);
3105
+ } else if (node && Array.isArray(node.selfEdges)) {
3106
+ node.selfEdges.forEach((selfEdge) => {
3107
+ if (!Array.isArray(selfEdge.label.points) || selfEdge.label.points.length !== 7) {
3108
+ const xVal = valid(node.x) ? node.x : 0;
3109
+ const yVal = valid(node.y) ? node.y : 0;
3110
+ const widthVal = valid(node.width) ? node.width : 0;
3111
+ const heightVal = valid(node.height) ? node.height : 0;
3112
+ const dx = widthVal / 2;
3113
+ const dy = heightVal / 2;
3114
+ selfEdge.label.points = [
3115
+ { x: xVal + dx, y: yVal - dy },
3116
+ { x: xVal + dx, y: yVal - dy },
3117
+ { x: xVal, y: yVal },
3118
+ { x: xVal - dx, y: yVal + dy },
3119
+ { x: xVal - dx, y: yVal + dy },
3120
+ { x: xVal, y: yVal },
3121
+ { x: xVal, y: yVal }
3122
+ ];
3123
+ }
3124
+ });
2693
3125
  }
2694
3126
  });
2695
3127
  }