@dagrejs/dagre
Version:
Graph layout for JavaScript
1,587 lines (1,569 loc) • 87 kB
JavaScript
"use strict";
var dagre = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// index.ts
var index_exports = {};
__export(index_exports, {
Graph: () => p,
debug: () => debugOrdering,
default: () => index_default,
graphlib: () => graphlib_esm_exports,
layout: () => layout,
util: () => util,
version: () => version
});
// node_modules/@dagrejs/graphlib/dist/graphlib.esm.js
var graphlib_esm_exports = {};
__export(graphlib_esm_exports, {
Graph: () => p,
alg: () => v,
json: () => G,
version: () => H
});
var V = Object.defineProperty;
var F = (s, e) => {
for (var t in e) V(s, t, { get: e[t], enumerable: true });
};
var p = class {
constructor(e) {
this._isDirected = true;
this._isMultigraph = false;
this._isCompound = false;
this._nodes = {};
this._in = {};
this._preds = {};
this._out = {};
this._sucs = {};
this._edgeObjs = {};
this._edgeLabels = {};
this._nodeCount = 0;
this._edgeCount = 0;
this._defaultNodeLabelFn = () => {
};
this._defaultEdgeLabelFn = () => {
};
e && (this._isDirected = "directed" in e ? e.directed : true, this._isMultigraph = "multigraph" in e ? e.multigraph : false, this._isCompound = "compound" in e ? e.compound : false), this._isCompound && (this._parent = {}, this._children = {}, this._children["\0"] = {});
}
isDirected() {
return this._isDirected;
}
isMultigraph() {
return this._isMultigraph;
}
isCompound() {
return this._isCompound;
}
setGraph(e) {
return this._label = e, this;
}
graph() {
return this._label;
}
setDefaultNodeLabel(e) {
return typeof e != "function" ? this._defaultNodeLabelFn = () => e : this._defaultNodeLabelFn = e, this;
}
nodeCount() {
return this._nodeCount;
}
nodes() {
return Object.keys(this._nodes);
}
sources() {
return this.nodes().filter((e) => Object.keys(this._in[e]).length === 0);
}
sinks() {
return this.nodes().filter((e) => Object.keys(this._out[e]).length === 0);
}
setNodes(e, t) {
return e.forEach((n) => {
t !== void 0 ? this.setNode(n, t) : this.setNode(n);
}), this;
}
setNode(e, t) {
return e in this._nodes ? (arguments.length > 1 && (this._nodes[e] = t), this) : (this._nodes[e] = arguments.length > 1 ? t : this._defaultNodeLabelFn(e), this._isCompound && (this._parent[e] = "\0", this._children[e] = {}, this._children["\0"][e] = true), this._in[e] = {}, this._preds[e] = {}, this._out[e] = {}, this._sucs[e] = {}, ++this._nodeCount, this);
}
node(e) {
return this._nodes[e];
}
hasNode(e) {
return e in this._nodes;
}
removeNode(e) {
if (e in this._nodes) {
let t = (n) => this.removeEdge(this._edgeObjs[n]);
delete this._nodes[e], this._isCompound && (this._removeFromParentsChildList(e), delete this._parent[e], this.children(e).forEach((n) => {
this.setParent(n);
}), delete this._children[e]), Object.keys(this._in[e]).forEach(t), delete this._in[e], delete this._preds[e], Object.keys(this._out[e]).forEach(t), delete this._out[e], delete this._sucs[e], --this._nodeCount;
}
return this;
}
setParent(e, t) {
if (!this._isCompound) throw new Error("Cannot set parent in a non-compound graph");
if (t === void 0) t = "\0";
else {
t += "";
for (let n = t; n !== void 0; n = this.parent(n)) if (n === e) throw new Error("Setting " + t + " as parent of " + e + " would create a cycle");
this.setNode(t);
}
return this.setNode(e), this._removeFromParentsChildList(e), this._parent[e] = t, this._children[t][e] = true, this;
}
parent(e) {
if (this._isCompound) {
let t = this._parent[e];
if (t !== "\0") return t;
}
}
children(e = "\0") {
if (this._isCompound) {
let t = this._children[e];
if (t) return Object.keys(t);
} else {
if (e === "\0") return this.nodes();
if (this.hasNode(e)) return [];
}
return [];
}
predecessors(e) {
let t = this._preds[e];
if (t) return Object.keys(t);
}
successors(e) {
let t = this._sucs[e];
if (t) return Object.keys(t);
}
neighbors(e) {
let t = this.predecessors(e);
if (t) {
let n = new Set(t);
for (let i of this.successors(e)) n.add(i);
return Array.from(n.values());
}
}
isLeaf(e) {
let t;
return this.isDirected() ? t = this.successors(e) : t = this.neighbors(e), t.length === 0;
}
filterNodes(e) {
let t = new this.constructor({ directed: this._isDirected, multigraph: this._isMultigraph, compound: this._isCompound });
t.setGraph(this.graph()), Object.entries(this._nodes).forEach(([r, o]) => {
e(r) && t.setNode(r, o);
}), Object.values(this._edgeObjs).forEach((r) => {
t.hasNode(r.v) && t.hasNode(r.w) && t.setEdge(r, this.edge(r));
});
let n = {}, i = (r) => {
let o = this.parent(r);
return !o || t.hasNode(o) ? (n[r] = o != null ? o : void 0, o != null ? o : void 0) : o in n ? n[o] : i(o);
};
return this._isCompound && t.nodes().forEach((r) => t.setParent(r, i(r))), t;
}
setDefaultEdgeLabel(e) {
return typeof e != "function" ? this._defaultEdgeLabelFn = () => e : this._defaultEdgeLabelFn = e, this;
}
edgeCount() {
return this._edgeCount;
}
edges() {
return Object.values(this._edgeObjs);
}
setPath(e, t) {
return e.reduce((n, i) => (t !== void 0 ? this.setEdge(n, i, t) : this.setEdge(n, i), i)), this;
}
setEdge(e, t, n, i) {
let r, o, d, a, c = false;
typeof e == "object" && e !== null && "v" in e ? (r = e.v, o = e.w, d = e.name, arguments.length === 2 && (a = t, c = true)) : (r = e, o = t, d = i, arguments.length > 2 && (a = n, c = true)), r = "" + r, o = "" + o, d !== void 0 && (d = "" + d);
let h = b(this._isDirected, r, o, d);
if (h in this._edgeLabels) return c && (this._edgeLabels[h] = a), this;
if (d !== void 0 && !this._isMultigraph) throw new Error("Cannot set a named edge when isMultigraph = false");
this.setNode(r), this.setNode(o), this._edgeLabels[h] = c ? a : this._defaultEdgeLabelFn(r, o, d);
let u = J(this._isDirected, r, o, d);
return r = u.v, o = u.w, Object.freeze(u), this._edgeObjs[h] = u, k(this._preds[o], r), k(this._sucs[r], o), this._in[o][h] = u, this._out[r][h] = u, this._edgeCount++, this;
}
edge(e, t, n) {
let i = arguments.length === 1 ? N(this._isDirected, e) : b(this._isDirected, e, t, n);
return this._edgeLabels[i];
}
edgeAsObj(e, t, n) {
let i = arguments.length === 1 ? this.edge(e) : this.edge(e, t, n);
return typeof i != "object" ? { label: i } : i;
}
hasEdge(e, t, n) {
return (arguments.length === 1 ? N(this._isDirected, e) : b(this._isDirected, e, t, n)) in this._edgeLabels;
}
removeEdge(e, t, n) {
let i = arguments.length === 1 ? N(this._isDirected, e) : b(this._isDirected, e, t, n), r = this._edgeObjs[i];
if (r) {
let o = r.v, d = r.w;
delete this._edgeLabels[i], delete this._edgeObjs[i], x(this._preds[d], o), x(this._sucs[o], d), delete this._in[d][i], delete this._out[o][i], this._edgeCount--;
}
return this;
}
inEdges(e, t) {
return this.isDirected() ? this.filterEdges(this._in[e], e, t) : this.nodeEdges(e, t);
}
outEdges(e, t) {
return this.isDirected() ? this.filterEdges(this._out[e], e, t) : this.nodeEdges(e, t);
}
nodeEdges(e, t) {
if (e in this._nodes) return this.filterEdges({ ...this._in[e], ...this._out[e] }, e, t);
}
_removeFromParentsChildList(e) {
delete this._children[this._parent[e]][e];
}
filterEdges(e, t, n) {
if (!e) return;
let i = Object.values(e);
return n ? i.filter((r) => r.v === t && r.w === n || r.v === n && r.w === t) : i;
}
};
function k(s, e) {
s[e] ? s[e]++ : s[e] = 1;
}
function x(s, e) {
s[e] !== void 0 && !--s[e] && delete s[e];
}
function b(s, e, t, n) {
let i = "" + e, r = "" + t;
if (!s && i > r) {
let o = i;
i = r, r = o;
}
return i + "" + r + "" + (n === void 0 ? "\0" : n);
}
function J(s, e, t, n) {
let i = "" + e, r = "" + t;
if (!s && i > r) {
let d = i;
i = r, r = d;
}
let o = { v: i, w: r };
return n && (o.name = n), o;
}
function N(s, e) {
return b(s, e.v, e.w, e.name);
}
var H = "4.0.1";
var G = {};
F(G, { read: () => z, write: () => U });
function U(s) {
let e = { options: { directed: s.isDirected(), multigraph: s.isMultigraph(), compound: s.isCompound() }, nodes: Y(s), edges: K(s) }, t = s.graph();
return t !== void 0 && (e.value = structuredClone(t)), e;
}
function Y(s) {
return s.nodes().map((e) => {
let t = s.node(e), n = s.parent(e), i = { v: e };
return t !== void 0 && (i.value = t), n !== void 0 && (i.parent = n), i;
});
}
function K(s) {
return s.edges().map((e) => {
let t = s.edge(e), n = { v: e.v, w: e.w };
return e.name !== void 0 && (n.name = e.name), t !== void 0 && (n.value = t), n;
});
}
function z(s) {
let e = new p(s.options);
return s.value !== void 0 && e.setGraph(s.value), s.nodes.forEach((t) => {
e.setNode(t.v, t.value), t.parent && e.setParent(t.v, t.parent);
}), s.edges.forEach((t) => {
e.setEdge({ v: t.v, w: t.w, name: t.name }, t.value);
}), e;
}
var v = {};
F(v, { CycleException: () => l, bellmanFord: () => m, components: () => R, dijkstra: () => E, dijkstraAll: () => P, findCycles: () => I, floydWarshall: () => D, isAcyclic: () => O, postorder: () => T, preorder: () => A, prim: () => W, shortestPaths: () => S, tarjan: () => y, topsort: () => L });
var Q = () => 1;
function m(s, e, t, n) {
return $(s, String(e), t || Q, n || function(i) {
return s.outEdges(i);
});
}
function $(s, e, t, n) {
let i = {}, r, o = 0, d = s.nodes(), a = function(u) {
let g = t(u);
i[u.v].distance + g < i[u.w].distance && (i[u.w] = { distance: i[u.v].distance + g, predecessor: u.v }, r = true);
}, c = function() {
d.forEach(function(u) {
n(u).forEach(function(g) {
let f = g.v === u ? g.v : g.w, M = f === g.v ? g.w : g.v;
a({ v: f, w: M });
});
});
};
d.forEach(function(u) {
let g = u === e ? 0 : Number.POSITIVE_INFINITY;
i[u] = { distance: g, predecessor: "" };
});
let h = d.length;
for (let u = 1; u < h && (r = false, o++, c(), !!r); u++) ;
if (o === h - 1 && (r = false, c(), r)) throw new Error("The graph contains a negative weight cycle");
return i;
}
function R(s) {
let e = {}, t = [], n;
function i(r) {
r in e || (e[r] = true, n.push(r), s.successors(r).forEach(i), s.predecessors(r).forEach(i));
}
return s.nodes().forEach(function(r) {
n = [], i(r), n.length && t.push(n);
}), t;
}
var _ = class {
constructor() {
this._arr = [];
this._keyIndices = {};
}
size() {
return this._arr.length;
}
keys() {
return this._arr.map((e) => e.key);
}
has(e) {
return e in this._keyIndices;
}
priority(e) {
let t = this._keyIndices[e];
if (t !== void 0) return this._arr[t].priority;
}
min() {
if (this.size() === 0) throw new Error("Queue underflow");
return this._arr[0].key;
}
add(e, t) {
let n = this._keyIndices, i = String(e);
if (!(i in n)) {
let r = this._arr, o = r.length;
return n[i] = o, r.push({ key: i, priority: t }), this._decrease(o), true;
}
return false;
}
removeMin() {
this._swap(0, this._arr.length - 1);
let e = this._arr.pop();
return delete this._keyIndices[e.key], this._heapify(0), e.key;
}
decrease(e, t) {
let n = this._keyIndices[e];
if (n === void 0) throw new Error(`Key not found: ${e}`);
let i = this._arr[n].priority;
if (t > i) throw new Error(`New priority is greater than current priority. Key: ${e} Old: ${i} New: ${t}`);
this._arr[n].priority = t, this._decrease(n);
}
_heapify(e) {
let t = this._arr, n = 2 * e, i = n + 1, r = e;
n < t.length && (r = t[n].priority < t[r].priority ? n : r, i < t.length && (r = t[i].priority < t[r].priority ? i : r), r !== e && (this._swap(e, r), this._heapify(r)));
}
_decrease(e) {
let t = this._arr, n = t[e].priority, i;
for (; e !== 0 && (i = e >> 1, !(t[i].priority < n)); ) this._swap(e, i), e = i;
}
_swap(e, t) {
let n = this._arr, i = this._keyIndices, r = n[e], o = n[t];
n[e] = o, n[t] = r, i[o.key] = e, i[r.key] = t;
}
};
var q = () => 1;
function E(s, e, t, n) {
let i = function(r) {
return s.outEdges(r);
};
return B(s, String(e), t || q, n || i);
}
function B(s, e, t, n) {
let i = {}, r = new _(), o, d, a = function(c) {
let h = c.v !== o ? c.v : c.w, u = i[h], g = t(c), f = d.distance + g;
if (g < 0) throw new Error("dijkstra does not allow negative edge weights. Bad edge: " + c + " Weight: " + g);
f < u.distance && (u.distance = f, u.predecessor = o, r.decrease(h, f));
};
for (s.nodes().forEach(function(c) {
let h = c === e ? 0 : Number.POSITIVE_INFINITY;
i[c] = { distance: h, predecessor: "" }, r.add(c, h);
}); r.size() > 0 && (o = r.removeMin(), d = i[o], d.distance !== Number.POSITIVE_INFINITY); ) n(o).forEach(a);
return i;
}
function P(s, e, t) {
return s.nodes().reduce(function(n, i) {
return n[i] = E(s, i, e, t), n;
}, {});
}
function y(s) {
let e = 0, t = [], n = {}, i = [];
function r(o) {
let d = n[o] = { onStack: true, lowlink: e, index: e++ };
if (t.push(o), s.successors(o).forEach(function(a) {
a in n ? n[a].onStack && (d.lowlink = Math.min(d.lowlink, n[a].index)) : (r(a), d.lowlink = Math.min(d.lowlink, n[a].lowlink));
}), d.lowlink === d.index) {
let a = [], c;
do
c = t.pop(), n[c].onStack = false, a.push(c);
while (o !== c);
i.push(a);
}
}
return s.nodes().forEach(function(o) {
o in n || r(o);
}), i;
}
function I(s) {
return y(s).filter(function(e) {
return e.length > 1 || e.length === 1 && s.hasEdge(e[0], e[0]);
});
}
var X = () => 1;
function D(s, e, t) {
return Z(s, e || X, t || function(n) {
return s.outEdges(n);
});
}
function Z(s, e, t) {
let n = {}, i = s.nodes();
return i.forEach(function(r) {
n[r] = {}, n[r][r] = { distance: 0, predecessor: "" }, i.forEach(function(o) {
r !== o && (n[r][o] = { distance: Number.POSITIVE_INFINITY, predecessor: "" });
}), t(r).forEach(function(o) {
let d = o.v === r ? o.w : o.v, a = e(o);
n[r][d] = { distance: a, predecessor: r };
});
}), i.forEach(function(r) {
let o = n[r];
i.forEach(function(d) {
let a = n[d];
i.forEach(function(c) {
let h = a[r], u = o[c], g = a[c], f = h.distance + u.distance;
f < g.distance && (g.distance = f, g.predecessor = u.predecessor);
});
});
}), n;
}
var l = class extends Error {
constructor(...e) {
super(...e);
}
};
function L(s) {
let e = {}, t = {}, n = [];
function i(r) {
if (r in t) throw new l();
r in e || (t[r] = true, e[r] = true, s.predecessors(r).forEach(i), delete t[r], n.push(r));
}
if (s.sinks().forEach(i), Object.keys(e).length !== s.nodeCount()) throw new l();
return n;
}
function O(s) {
try {
L(s);
} catch (e) {
if (e instanceof l) return false;
throw e;
}
return true;
}
function j(s, e, t, n, i) {
Array.isArray(e) || (e = [e]);
let r = ((d) => {
var a;
return (a = s.isDirected() ? s.successors(d) : s.neighbors(d)) != null ? a : [];
}), o = {};
return e.forEach(function(d) {
if (!s.hasNode(d)) throw new Error("Graph does not have node: " + d);
i = C(s, d, t === "post", o, r, n, i);
}), i;
}
function C(s, e, t, n, i, r, o) {
return e in n || (n[e] = true, t || (o = r(o, e)), i(e).forEach(function(d) {
o = C(s, d, t, n, i, r, o);
}), t && (o = r(o, e))), o;
}
function w(s, e, t) {
return j(s, e, t, function(n, i) {
return n.push(i), n;
}, []);
}
function T(s, e) {
return w(s, e, "post");
}
function A(s, e) {
return w(s, e, "pre");
}
function W(s, e) {
let t = new p(), n = {}, i = new _(), r;
function o(a) {
let c = a.v === r ? a.w : a.v, h = i.priority(c);
if (h !== void 0) {
let u = e(a);
u < h && (n[c] = r, i.decrease(c, u));
}
}
if (s.nodeCount() === 0) return t;
s.nodes().forEach(function(a) {
i.add(a, Number.POSITIVE_INFINITY), t.setNode(a);
}), i.decrease(s.nodes()[0], 0);
let d = false;
for (; i.size() > 0; ) {
if (r = i.removeMin(), r in n) t.setEdge(r, n[r]);
else {
if (d) throw new Error("Input graph is not connected: " + s);
d = true;
}
s.nodeEdges(r).forEach(o);
}
return t;
}
function S(s, e, t, n) {
return ee(s, e, t, n != null ? n : ((i) => {
let r = s.outEdges(i);
return r != null ? r : [];
}));
}
function ee(s, e, t, n) {
if (t === void 0) return E(s, e, t, n);
let i = false, r = s.nodes();
for (let o = 0; o < r.length; o++) {
let d = n(r[o]);
for (let a = 0; a < d.length; a++) {
let c = d[a], h = c.v === r[o] ? c.v : c.w, u = h === c.v ? c.w : c.v;
t({ v: h, w: u }) < 0 && (i = true);
}
if (i) return m(s, e, t, n);
}
return E(s, e, t, n);
}
// lib/util.ts
function addDummyNode(graph, type, attrs, name) {
let v2 = name;
while (graph.hasNode(v2)) {
v2 = uniqueId(name);
}
attrs.dummy = type;
graph.setNode(v2, attrs);
return v2;
}
function simplify(graph) {
const simplified = new p().setGraph(graph.graph());
graph.nodes().forEach((v2) => simplified.setNode(v2, graph.node(v2)));
graph.edges().forEach((e) => {
const simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 };
const label = graph.edge(e);
simplified.setEdge(e.v, e.w, {
weight: simpleLabel.weight + label.weight,
minlen: Math.max(simpleLabel.minlen, label.minlen)
});
});
return simplified;
}
function asNonCompoundGraph(graph) {
const simplified = new p({ multigraph: graph.isMultigraph() }).setGraph(graph.graph());
graph.nodes().forEach((v2) => {
if (!graph.children(v2).length) {
simplified.setNode(v2, graph.node(v2));
}
});
graph.edges().forEach((e) => {
simplified.setEdge(e, graph.edge(e));
});
return simplified;
}
function intersectRect(rect, point) {
const x2 = rect.x;
const y2 = rect.y;
const dx = point.x - x2;
const dy = point.y - y2;
let w2 = rect.width / 2;
let h = rect.height / 2;
if (!dx && !dy) {
throw new Error("Not possible to find intersection inside of the rectangle");
}
let sx, sy;
if (Math.abs(dy) * w2 > Math.abs(dx) * h) {
if (dy < 0) {
h = -h;
}
sx = h * dx / dy;
sy = h;
} else {
if (dx < 0) {
w2 = -w2;
}
sx = w2;
sy = w2 * dy / dx;
}
return { x: x2 + sx, y: y2 + sy };
}
function buildLayerMatrix(graph) {
const layering = range(maxRank(graph) + 1).map(() => []);
graph.nodes().forEach((v2) => {
const node = graph.node(v2);
const rank2 = node.rank;
if (rank2 !== void 0) {
if (!layering[rank2]) {
layering[rank2] = [];
}
layering[rank2][node.order] = v2;
}
});
return layering;
}
function normalizeRanks(graph) {
const nodeRanks = graph.nodes().map((v2) => {
const rank2 = graph.node(v2).rank;
if (rank2 === void 0) {
return Number.MAX_VALUE;
}
return rank2;
});
const min = applyWithChunking(Math.min, nodeRanks);
graph.nodes().forEach((v2) => {
const node = graph.node(v2);
if (Object.hasOwn(node, "rank")) {
node.rank -= min;
}
});
}
function removeEmptyRanks(graph) {
const nodeRanks = graph.nodes().map((v2) => graph.node(v2).rank).filter((rank2) => rank2 !== void 0);
const offset = applyWithChunking(Math.min, nodeRanks);
const layers = [];
graph.nodes().forEach((v2) => {
const rank2 = graph.node(v2).rank - offset;
if (!layers[rank2]) {
layers[rank2] = [];
}
layers[rank2].push(v2);
});
let delta = 0;
const nodeRankFactor = graph.graph().nodeRankFactor;
Array.from(layers).forEach((vs, i) => {
if (vs === void 0 && i % nodeRankFactor !== 0) {
--delta;
} else if (vs !== void 0 && delta) {
vs.forEach((v2) => graph.node(v2).rank += delta);
}
});
}
function addBorderNode(graph, prefix, rank2, order2) {
const node = {
width: 0,
height: 0
};
if (arguments.length >= 4) {
node.rank = rank2;
node.order = order2;
}
return addDummyNode(graph, "border", node, prefix);
}
function splitToChunks(array, chunkSize = CHUNKING_THRESHOLD) {
const chunks = [];
for (let i = 0; i < array.length; i += chunkSize) {
const chunk = array.slice(i, i + chunkSize);
chunks.push(chunk);
}
return chunks;
}
var CHUNKING_THRESHOLD = 65535;
function applyWithChunking(fn, argsArray) {
if (argsArray.length > CHUNKING_THRESHOLD) {
const chunks = splitToChunks(argsArray);
return fn(...chunks.map((chunk) => fn(...chunk)));
} else {
return fn(...argsArray);
}
}
function maxRank(graph) {
const nodes = graph.nodes();
const nodeRanks = nodes.map((v2) => {
const rank2 = graph.node(v2).rank;
if (rank2 === void 0) {
return Number.MIN_VALUE;
}
return rank2;
});
return applyWithChunking(Math.max, nodeRanks);
}
function partition(collection, fn) {
const result = { lhs: [], rhs: [] };
collection.forEach((value) => {
if (fn(value)) {
result.lhs.push(value);
} else {
result.rhs.push(value);
}
});
return result;
}
function time(name, fn) {
const start = Date.now();
try {
return fn();
} finally {
console.log(name + " time: " + (Date.now() - start) + "ms");
}
}
function notime(name, fn) {
return fn();
}
var idCounter = 0;
function uniqueId(prefix) {
const id = ++idCounter;
return prefix + ("" + id);
}
function range(start, limit, step = 1) {
if (limit == null) {
limit = start;
start = 0;
}
let endCon = (i) => i < limit;
if (step < 0) {
endCon = (i) => limit < i;
}
const range3 = [];
for (let i = start; endCon(i); i += step) {
range3.push(i);
}
return range3;
}
function pick(source, keys) {
const dest = {};
for (const key of keys) {
if (source[key] !== void 0) {
dest[key] = source[key];
}
}
return dest;
}
function mapValues(obj, funcOrProp) {
let func;
if (typeof funcOrProp === "string") {
func = (val) => val[funcOrProp];
} else {
func = funcOrProp;
}
return Object.entries(obj).reduce((acc, [k2, v2]) => {
acc[k2] = func(v2, k2);
return acc;
}, {});
}
function zipObject(props, values) {
return props.reduce((acc, key, i) => {
acc[key] = values[i];
return acc;
}, {});
}
var GRAPH_NODE = "\0";
// lib/version.ts
var version = "3.0.0";
// lib/data/list.ts
var List = class {
constructor() {
__publicField(this, "_sentinel");
const sentinel = {};
sentinel._next = sentinel._prev = sentinel;
this._sentinel = sentinel;
}
dequeue() {
const sentinel = this._sentinel;
const entry = sentinel._prev;
if (entry !== sentinel) {
unlink(entry);
return entry;
}
return void 0;
}
enqueue(entry) {
const sentinel = this._sentinel;
if (entry._prev && entry._next) {
unlink(entry);
}
entry._next = sentinel._next;
sentinel._next._prev = entry;
sentinel._next = entry;
entry._prev = sentinel;
}
toString() {
const strs = [];
const sentinel = this._sentinel;
let curr = sentinel._prev;
while (curr !== sentinel) {
strs.push(JSON.stringify(curr, filterOutLinks));
curr = curr._prev;
}
return "[" + strs.join(", ") + "]";
}
};
function unlink(entry) {
entry._prev._next = entry._next;
entry._next._prev = entry._prev;
delete entry._next;
delete entry._prev;
}
function filterOutLinks(k2, v2) {
if (k2 !== "_next" && k2 !== "_prev") {
return v2;
}
return void 0;
}
var list_default = List;
// lib/greedy-fas.ts
var DEFAULT_WEIGHT_FN = () => 1;
function greedyFAS(graph, weightFn) {
if (graph.nodeCount() <= 1) {
return [];
}
const state = buildState(graph, weightFn || DEFAULT_WEIGHT_FN);
const results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx);
return results.flatMap((edge) => graph.outEdges(edge.v, edge.w) || []);
}
function doGreedyFAS(g, buckets, zeroIdx) {
var _a;
let results = [];
const sources = buckets[buckets.length - 1];
const sinks = buckets[0];
let entry;
while (g.nodeCount()) {
while (entry = sinks.dequeue()) {
removeNode(g, buckets, zeroIdx, entry);
}
while (entry = sources.dequeue()) {
removeNode(g, buckets, zeroIdx, entry);
}
if (g.nodeCount()) {
for (let i = buckets.length - 2; i > 0; --i) {
entry = (_a = buckets[i]) == null ? void 0 : _a.dequeue();
if (entry) {
results = results.concat(removeNode(g, buckets, zeroIdx, entry, true) || []);
break;
}
}
}
}
return results;
}
function removeNode(graph, buckets, zeroIdx, entry, collectPredecessors) {
const collected = [];
const results = collectPredecessors ? collected : void 0;
(graph.inEdges(entry.v) || []).forEach((edge) => {
const weight = graph.edge(edge);
const uEntry = graph.node(edge.v);
if (collectPredecessors) {
collected.push({ v: edge.v, w: edge.w });
}
uEntry.out -= weight;
assignBucket(buckets, zeroIdx, uEntry);
});
(graph.outEdges(entry.v) || []).forEach((edge) => {
const weight = graph.edge(edge);
const w2 = edge.w;
const wEntry = graph.node(w2);
wEntry.in -= weight;
assignBucket(buckets, zeroIdx, wEntry);
});
graph.removeNode(entry.v);
return results;
}
function buildState(graph, weightFn) {
const fasGraph = new p();
let maxIn = 0;
let maxOut = 0;
graph.nodes().forEach((v2) => {
fasGraph.setNode(v2, { v: v2, in: 0, out: 0 });
});
graph.edges().forEach((edge) => {
const prevWeight = fasGraph.edge(edge.v, edge.w) || 0;
const weight = weightFn(edge);
const edgeWeight = prevWeight + weight;
fasGraph.setEdge(edge.v, edge.w, edgeWeight);
const vNode = fasGraph.node(edge.v);
const wNode = fasGraph.node(edge.w);
maxOut = Math.max(maxOut, vNode.out += weight);
maxIn = Math.max(maxIn, wNode.in += weight);
});
const buckets = range2(maxOut + maxIn + 3).map(() => new list_default());
const zeroIdx = maxIn + 1;
fasGraph.nodes().forEach((v2) => {
assignBucket(buckets, zeroIdx, fasGraph.node(v2));
});
return { graph: fasGraph, buckets, zeroIdx };
}
function assignBucket(buckets, zeroIdx, entry) {
var _a, _b, _c;
if (!entry.out) {
(_a = buckets[0]) == null ? void 0 : _a.enqueue(entry);
} else if (!entry.in) {
(_b = buckets[buckets.length - 1]) == null ? void 0 : _b.enqueue(entry);
} else {
(_c = buckets[entry.out - entry.in + zeroIdx]) == null ? void 0 : _c.enqueue(entry);
}
}
function range2(limit) {
const range3 = [];
for (let i = 0; i < limit; i++) {
range3.push(i);
}
return range3;
}
// lib/acyclic.ts
function run(graph) {
const fas = graph.graph().acyclicer === "greedy" ? greedyFAS(graph, weightFn(graph)) : dfsFAS(graph);
fas.forEach((e) => {
const label = graph.edge(e);
graph.removeEdge(e);
label.forwardName = e.name;
label.reversed = true;
graph.setEdge(e.w, e.v, label, uniqueId("rev"));
});
function weightFn(g) {
return (e) => {
return g.edge(e).weight;
};
}
}
function dfsFAS(graph) {
const fas = [];
const stack = {};
const visited = {};
function dfs2(v2) {
if (Object.hasOwn(visited, v2)) {
return;
}
visited[v2] = true;
stack[v2] = true;
graph.outEdges(v2).forEach((e) => {
if (Object.hasOwn(stack, e.w)) {
fas.push(e);
} else {
dfs2(e.w);
}
});
delete stack[v2];
}
graph.nodes().forEach(dfs2);
return fas;
}
function undo(graph) {
graph.edges().forEach((e) => {
const label = graph.edge(e);
if (label.reversed) {
graph.removeEdge(e);
const forwardName = label.forwardName;
delete label.reversed;
delete label.forwardName;
graph.setEdge(e.w, e.v, label, forwardName);
}
});
}
// lib/normalize.ts
function run2(graph) {
graph.graph().dummyChains = [];
graph.edges().forEach((edge) => normalizeEdge(graph, edge));
}
function normalizeEdge(graph, e) {
let v2 = e.v;
let vRank = graph.node(v2).rank;
const w2 = e.w;
const wRank = graph.node(w2).rank;
const name = e.name;
const edgeLabel = graph.edge(e);
const labelRank = edgeLabel.labelRank;
if (wRank === vRank + 1) return;
graph.removeEdge(e);
let dummy;
let attrs;
let i;
for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) {
edgeLabel.points = [];
attrs = {
width: 0,
height: 0,
edgeLabel,
edgeObj: e,
rank: vRank
};
dummy = addDummyNode(graph, "edge", attrs, "_d");
if (vRank === labelRank) {
attrs.width = edgeLabel.width;
attrs.height = edgeLabel.height;
attrs.dummy = "edge-label";
attrs.labelpos = edgeLabel.labelpos;
}
graph.setEdge(v2, dummy, { weight: edgeLabel.weight }, name);
if (i === 0) {
graph.graph().dummyChains.push(dummy);
}
v2 = dummy;
}
graph.setEdge(v2, w2, { weight: edgeLabel.weight }, name);
}
function undo2(graph) {
graph.graph().dummyChains.forEach((v2) => {
let node = graph.node(v2);
const origLabel = node.edgeLabel;
let w2;
graph.setEdge(node.edgeObj, origLabel);
while (node.dummy) {
w2 = graph.successors(v2)[0];
graph.removeNode(v2);
origLabel.points.push({ x: node.x, y: node.y });
if (node.dummy === "edge-label") {
origLabel.x = node.x;
origLabel.y = node.y;
origLabel.width = node.width;
origLabel.height = node.height;
}
v2 = w2;
node = graph.node(v2);
}
});
}
// lib/rank/util.ts
function longestPath(graph) {
const visited = {};
function dfs2(v2) {
const label = graph.node(v2);
if (Object.hasOwn(visited, v2)) {
return label.rank;
}
visited[v2] = true;
const outEdges = graph.outEdges(v2);
const outEdgesMinLens = outEdges ? outEdges.map((e) => {
if (e == null) {
return Number.POSITIVE_INFINITY;
}
return dfs2(e.w) - graph.edge(e).minlen;
}) : [];
let rank2 = applyWithChunking(Math.min, outEdgesMinLens);
if (rank2 === Number.POSITIVE_INFINITY) {
rank2 = 0;
}
return label.rank = rank2;
}
graph.sources().forEach(dfs2);
}
function slack(graph, edge) {
return graph.node(edge.w).rank - graph.node(edge.v).rank - graph.edge(edge).minlen;
}
// lib/rank/feasible-tree.ts
var feasible_tree_default = feasibleTree;
function feasibleTree(graph) {
const tree = new p({ directed: false });
const nodes = graph.nodes();
if (nodes.length === 0) {
throw new Error("Graph must have at least one node");
}
const start = nodes[0];
const size = graph.nodeCount();
tree.setNode(start, {});
let edge;
let delta;
while (tightTree(tree, graph) < size) {
edge = findMinSlackEdge(tree, graph);
if (!edge) break;
delta = tree.hasNode(edge.v) ? slack(graph, edge) : -slack(graph, edge);
shiftRanks(tree, graph, delta);
}
return tree;
}
function tightTree(tree, graph) {
function dfs2(v2) {
const nodeEdges = graph.nodeEdges(v2);
if (nodeEdges) {
nodeEdges.forEach((e) => {
const edgeV = e.v;
const w2 = v2 === edgeV ? e.w : edgeV;
if (!tree.hasNode(w2) && !slack(graph, e)) {
tree.setNode(w2, {});
tree.setEdge(v2, w2, {});
dfs2(w2);
}
});
}
}
tree.nodes().forEach(dfs2);
return tree.nodeCount();
}
function findMinSlackEdge(tree, graph) {
const edges = graph.edges();
return edges.reduce((acc, edge) => {
let edgeSlack = Number.POSITIVE_INFINITY;
if (tree.hasNode(edge.v) !== tree.hasNode(edge.w)) {
edgeSlack = slack(graph, edge);
}
if (edgeSlack < acc[0]) {
return [edgeSlack, edge];
}
return acc;
}, [Number.POSITIVE_INFINITY, null])[1];
}
function shiftRanks(tree, graph, delta) {
tree.nodes().forEach((v2) => graph.node(v2).rank += delta);
}
// lib/rank/network-simplex.ts
var { preorder, postorder } = v;
var network_simplex_default = networkSimplex;
networkSimplex.initLowLimValues = initLowLimValues;
networkSimplex.initCutValues = initCutValues;
networkSimplex.calcCutValue = calcCutValue;
networkSimplex.leaveEdge = leaveEdge;
networkSimplex.enterEdge = enterEdge;
networkSimplex.exchangeEdges = exchangeEdges;
function networkSimplex(graph) {
graph = simplify(graph);
longestPath(graph);
const t = feasible_tree_default(graph);
initLowLimValues(t);
initCutValues(t, graph);
let e;
let f;
while (e = leaveEdge(t)) {
f = enterEdge(t, graph, e);
exchangeEdges(t, graph, e, f);
}
}
function initCutValues(tree, graph) {
let visitedNodes = postorder(tree, tree.nodes());
visitedNodes = visitedNodes.slice(0, visitedNodes.length - 1);
visitedNodes.forEach((v2) => assignCutValue(tree, graph, v2));
}
function assignCutValue(tree, graph, child) {
const childLab = tree.node(child);
const parent = childLab.parent;
const edge = tree.edge(child, parent);
edge.cutvalue = calcCutValue(tree, graph, child);
}
function calcCutValue(tree, graph, child) {
const childLab = tree.node(child);
const parent = childLab.parent;
let childIsTail = true;
let graphEdge = graph.edge(child, parent);
let cutValue = 0;
if (!graphEdge) {
childIsTail = false;
graphEdge = graph.edge(parent, child);
}
cutValue = graphEdge.weight;
const nodeEdges = graph.nodeEdges(child);
if (nodeEdges) {
nodeEdges.forEach((edge) => {
const isOutEdge = edge.v === child;
const other = isOutEdge ? edge.w : edge.v;
if (other !== parent) {
const pointsToHead = isOutEdge === childIsTail;
const otherWeight = graph.edge(edge).weight;
cutValue += pointsToHead ? otherWeight : -otherWeight;
if (isTreeEdge(tree, child, other)) {
const treeEdge = tree.edge(child, other);
const otherCutValue = treeEdge.cutvalue;
cutValue += pointsToHead ? -otherCutValue : otherCutValue;
}
}
});
}
return cutValue;
}
function initLowLimValues(tree, root) {
if (arguments.length < 2) {
root = tree.nodes()[0];
}
dfsAssignLowLim(tree, {}, 1, root);
}
function dfsAssignLowLim(tree, visited, nextLim, v2, parent) {
const low = nextLim;
const label = tree.node(v2);
visited[v2] = true;
const neighbors = tree.neighbors(v2);
if (neighbors) {
neighbors.forEach((w2) => {
if (!Object.hasOwn(visited, w2)) {
nextLim = dfsAssignLowLim(tree, visited, nextLim, w2, v2);
}
});
}
label.low = low;
label.lim = nextLim++;
if (parent) {
label.parent = parent;
} else {
delete label.parent;
}
return nextLim;
}
function leaveEdge(tree) {
return tree.edges().find((e) => {
const edge = tree.edge(e);
return edge.cutvalue < 0;
});
}
function enterEdge(tree, graph, edge) {
let v2 = edge.v;
let w2 = edge.w;
if (!graph.hasEdge(v2, w2)) {
v2 = edge.w;
w2 = edge.v;
}
const vLabel = tree.node(v2);
const wLabel = tree.node(w2);
let tailLabel = vLabel;
let flip = false;
if (vLabel.lim > wLabel.lim) {
tailLabel = wLabel;
flip = true;
}
const candidates = graph.edges().filter((edge2) => {
return flip === isDescendant(tree, tree.node(edge2.v), tailLabel) && flip !== isDescendant(tree, tree.node(edge2.w), tailLabel);
});
return candidates.reduce((acc, edge2) => {
if (slack(graph, edge2) < slack(graph, acc)) {
return edge2;
}
return acc;
});
}
function exchangeEdges(t, g, e, f) {
const v2 = e.v;
const w2 = e.w;
t.removeEdge(v2, w2);
t.setEdge(f.v, f.w, {});
initLowLimValues(t);
initCutValues(t, g);
updateRanks(t, g);
}
function updateRanks(t, g) {
const root = t.nodes().find((v2) => {
const node = t.node(v2);
return !node.parent;
});
if (!root) return;
let vs = preorder(t, [root]);
vs = vs.slice(1);
vs.forEach((v2) => {
const treeNode = t.node(v2);
const parent = treeNode.parent;
let edge = g.edge(v2, parent);
let flipped = false;
if (!edge) {
edge = g.edge(parent, v2);
flipped = true;
}
g.node(v2).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen);
});
}
function isTreeEdge(tree, u, v2) {
return tree.hasEdge(u, v2);
}
function isDescendant(tree, vLabel, rootLabel) {
return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim;
}
// lib/rank/index.ts
var rank_default = rank;
function rank(graph) {
const ranker = graph.graph().ranker;
if (typeof ranker === "function") {
return ranker(graph);
}
switch (ranker) {
case "network-simplex":
networkSimplexRanker(graph);
break;
case "tight-tree":
tightTreeRanker(graph);
break;
case "longest-path":
longestPathRanker(graph);
break;
case "none":
break;
default:
networkSimplexRanker(graph);
}
}
var longestPathRanker = longestPath;
function tightTreeRanker(g) {
longestPath(g);
feasible_tree_default(g);
}
function networkSimplexRanker(g) {
network_simplex_default(g);
}
// lib/parent-dummy-chains.ts
var parent_dummy_chains_default = parentDummyChains;
function parentDummyChains(graph) {
const postorderNums = postorder2(graph);
graph.graph().dummyChains.forEach((v2) => {
let node = graph.node(v2);
const edgeObj = node.edgeObj;
const pathData = findPath(graph, postorderNums, edgeObj.v, edgeObj.w);
const path = pathData.path;
const lca = pathData.lca;
let pathIdx = 0;
let pathV = path[pathIdx];
let ascending = true;
while (v2 !== edgeObj.w) {
node = graph.node(v2);
if (ascending) {
while ((pathV = path[pathIdx]) !== lca && graph.node(pathV).maxRank < node.rank) {
pathIdx++;
}
if (pathV === lca) {
ascending = false;
}
}
if (!ascending) {
while (pathIdx < path.length - 1 && graph.node(path[pathIdx + 1]).minRank <= node.rank) {
pathIdx++;
}
pathV = path[pathIdx];
}
if (pathV !== void 0) {
graph.setParent(v2, pathV);
}
v2 = graph.successors(v2)[0];
}
});
}
function findPath(graph, postorderNums, v2, w2) {
const vPath = [];
const wPath = [];
const low = Math.min(postorderNums[v2].low, postorderNums[w2].low);
const lim = Math.max(postorderNums[v2].lim, postorderNums[w2].lim);
let parent;
parent = v2;
do {
parent = graph.parent(parent);
vPath.push(parent);
} while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim));
const lca = parent;
let wParent = w2;
while ((wParent = graph.parent(wParent)) !== lca) {
wPath.push(wParent);
}
return { path: vPath.concat(wPath.reverse()), lca };
}
function postorder2(graph) {
const result = {};
let lim = 0;
function dfs2(v2) {
const low = lim;
graph.children(v2).forEach(dfs2);
result[v2] = { low, lim: lim++ };
}
graph.children(GRAPH_NODE).forEach(dfs2);
return result;
}
// lib/nesting-graph.ts
function run3(graph) {
const root = addDummyNode(graph, "root", {}, "_root");
const depths = treeDepths(graph);
const depthsArr = Object.values(depths);
const height = applyWithChunking(Math.max, depthsArr) - 1;
const nodeSep = 2 * height + 1;
graph.graph().nestingRoot = root;
graph.edges().forEach((e) => graph.edge(e).minlen *= nodeSep);
const weight = sumWeights(graph) + 1;
graph.children(GRAPH_NODE).forEach((child) => dfs(graph, root, nodeSep, weight, height, depths, child));
graph.graph().nodeRankFactor = nodeSep;
}
function dfs(graph, root, nodeSep, weight, height, depths, v2) {
var _a;
const children = graph.children(v2);
if (!children.length) {
if (v2 !== root) {
graph.setEdge(root, v2, { weight: 0, minlen: nodeSep });
}
return;
}
const top = addBorderNode(graph, "_bt");
const bottom = addBorderNode(graph, "_bb");
const label = graph.node(v2);
graph.setParent(top, v2);
label.borderTop = top;
graph.setParent(bottom, v2);
label.borderBottom = bottom;
children.forEach((child) => {
var _a2;
dfs(graph, root, nodeSep, weight, height, depths, child);
const childNode = graph.node(child);
const childTop = childNode.borderTop ? childNode.borderTop : child;
const childBottom = childNode.borderBottom ? childNode.borderBottom : child;
const thisWeight = childNode.borderTop ? weight : 2 * weight;
const minlen = childTop !== childBottom ? 1 : height - ((_a2 = depths[v2]) != null ? _a2 : 0) + 1;
graph.setEdge(top, childTop, {
weight: thisWeight,
minlen,
nestingEdge: true
});
graph.setEdge(childBottom, bottom, {
weight: thisWeight,
minlen,
nestingEdge: true
});
});
if (!graph.parent(v2)) {
graph.setEdge(root, top, { weight: 0, minlen: height + ((_a = depths[v2]) != null ? _a : 0) });
}
}
function treeDepths(graph) {
const depths = {};
function dfs2(v2, depth) {
const children = graph.children(v2);
if (children && children.length) {
children.forEach((child) => dfs2(child, depth + 1));
}
depths[v2] = depth;
}
graph.children(GRAPH_NODE).forEach((v2) => dfs2(v2, 1));
return depths;
}
function sumWeights(graph) {
return graph.edges().reduce((acc, e) => acc + graph.edge(e).weight, 0);
}
function cleanup(graph) {
const graphLabel = graph.graph();
graph.removeNode(graphLabel.nestingRoot);
delete graphLabel.nestingRoot;
graph.edges().forEach((e) => {
const edge = graph.edge(e);
if (edge.nestingEdge) {
graph.removeEdge(e);
}
});
}
// lib/add-border-segments.ts
var add_border_segments_default = addBorderSegments;
function addBorderSegments(graph) {
function dfs2(v2) {
const children = graph.children(v2);
const node = graph.node(v2);
if (children.length) {
children.forEach(dfs2);
}
if (Object.hasOwn(node, "minRank")) {
node.borderLeft = [];
node.borderRight = [];
for (let rank2 = node.minRank, maxRank2 = node.maxRank + 1; rank2 < maxRank2; ++rank2) {
addBorderNode2(graph, "borderLeft", "_bl", v2, node, rank2);
addBorderNode2(graph, "borderRight", "_br", v2, node, rank2);
}
}
}
graph.children(GRAPH_NODE).forEach(dfs2);
}
function addBorderNode2(graph, prop, prefix, sg, sgNode, rank2) {
const label = { width: 0, height: 0, rank: rank2, borderType: prop };
const prev = sgNode[prop][rank2 - 1];
const curr = addDummyNode(graph, "border", label, prefix);
sgNode[prop][rank2] = curr;
graph.setParent(curr, sg);
if (prev) {
graph.setEdge(prev, curr, { weight: 1 });
}
}
// lib/coordinate-system.ts
function adjust(graph) {
var _a;
const rankDir = (_a = graph.graph().rankdir) == null ? void 0 : _a.toLowerCase();
if (rankDir === "lr" || rankDir === "rl") {
swapWidthHeight(graph);
}
}
function undo3(graph) {
var _a;
const rankDir = (_a = graph.graph().rankdir) == null ? void 0 : _a.toLowerCase();
if (rankDir === "bt" || rankDir === "rl") {
reverseY(graph);
}
if (rankDir === "lr" || rankDir === "rl") {
swapXY(graph);
swapWidthHeight(graph);
}
}
function swapWidthHeight(graph) {
graph.nodes().forEach((node) => swapWidthHeightOne(graph.node(node)));
graph.edges().forEach((edge) => swapWidthHeightOne(graph.edge(edge)));
}
function swapWidthHeightOne(attrs) {
const w2 = attrs.width;
attrs.width = attrs.height;
attrs.height = w2;
}
function reverseY(graph) {
graph.nodes().forEach((node) => reverseYOne(graph.node(node)));
graph.edges().forEach((edge) => {
var _a;
const edgeLabel = graph.edge(edge);
(_a = edgeLabel.points) == null ? void 0 : _a.forEach(reverseYOne);
if (Object.hasOwn(edgeLabel, "y")) {
reverseYOne(edgeLabel);
}
});
}
function reverseYOne(attrs) {
attrs.y = -attrs.y;
}
function swapXY(graph) {
graph.nodes().forEach((node) => swapXYOne(graph.node(node)));
graph.edges().forEach((edge) => {
var _a;
const edgeLabel = graph.edge(edge);
(_a = edgeLabel.points) == null ? void 0 : _a.forEach(swapXYOne);
if (Object.hasOwn(edgeLabel, "x")) {
swapXYOne(edgeLabel);
}
});
}
function swapXYOne(attrs) {
const x2 = attrs.x;
attrs.x = attrs.y;
attrs.y = x2;
}
// lib/order/init-order.ts
function initOrder(graph) {
const visited = {};
const simpleNodes = graph.nodes().filter((v2) => !graph.children(v2).length);
const simpleNodesRanks = simpleNodes.map((v2) => graph.node(v2).rank);
const maxRank2 = applyWithChunking(Math.max, simpleNodesRanks);
const layers = range(maxRank2 + 1).map(() => []);
function dfs2(v2) {
if (visited[v2]) return;
visited[v2] = true;
const node = graph.node(v2);
layers[node.rank].push(v2);
const successors = graph.successors(v2);
if (successors) {
successors.forEach(dfs2);
}
}
const orderedVs = simpleNodes.sort((a, b2) => graph.node(a).rank - graph.node(b2).rank);
orderedVs.forEach(dfs2);
return layers;
}
// lib/order/cross-count.ts
function crossCount(graph, layering) {
let cc = 0;
for (let i = 1; i < layering.length; ++i) {
cc += twoLayerCrossCount(graph, layering[i - 1], layering[i]);
}
return cc;
}
function twoLayerCrossCount(graph, northLayer, southLayer) {
const southPos = zipObject(southLayer, southLayer.map((v2, i) => i));
const southEntries = northLayer.flatMap((v2) => {
const edges = graph.outEdges(v2);
if (!edges) return [];
return edges.map((e) => {
return { pos: southPos[e.w], weight: graph.edge(e).weight };
}).sort((a, b2) => a.po