@weasel-js/diagram 1.10.0 → 1.10.1

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.
package/dist/layout.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { j as BodyFloor, k as BodyNodeSpec, B as BodySpec, l as Bounds, m as BuildBodyOptions, C as COMPASS, p as DEFAULT_NODE_GAP, q as DEFAULT_PORTS, r as DEFAULT_RANK_GAP, f as DiagramNode, u as ForceBody, F as ForceOptions, v as ForceRelaxation, i as Graph, x as GraphEdge, z as GraphNode, H as LayoutAxes, I as LayoutDirection, L as LayoutFn, g as LayoutOptions, h as LayoutResult, M as MeasureRowText, O as Outline, P as Port, c as PortAnchor, e as PortSpec, a as PortsOptions, R as Row, J as RowBox, K as RowNodeData, N as RowPort, Q as RowPortBox, S as RowTextStyle, T as Slot, U as axesFor, V as backEdges, W as bodyOutline, Y as boxForContent, Z as buildBody, $ as canvasMeasure, a0 as contentBox, aw as extent, a5 as force, a6 as forceRelaxation, a7 as forestOf, a8 as graphOrder, ab as layered, ac as layoutBody, ad as layoutRowPorts, ae as measureBody, af as outlinePath, ag as outlinePolyline, ah as packAcross, aj as pinnedSet, ak as portOf, al as portsOf, am as portsOnOutline, ao as ranksOf, ap as rayHit, aq as seededOrder, ar as settle, as as sizeToBody, at as translated, au as tree, av as untilSettled } from './layout.entry-CIdRpG2i.js';
1
+ export { k as BodyFloor, l as BodyNodeSpec, B as BodySpec, m as Bounds, n as BuildBodyOptions, C as COMPASS, q as DEFAULT_NODE_GAP, r as DEFAULT_PORTS, s as DEFAULT_RANK_GAP, f as DiagramNode, v as ForceBody, F as ForceOptions, w as ForceRelaxation, i as Graph, y as GraphEdge, A as GraphNode, I as LayoutAxes, j as LayoutDirection, L as LayoutFn, g as LayoutOptions, h as LayoutResult, M as MeasureRowText, O as Outline, P as Port, c as PortAnchor, e as PortSpec, a as PortsOptions, R as Row, J as RowBox, K as RowNodeData, N as RowPort, Q as RowPortBox, S as RowTextStyle, T as Slot, U as axesFor, V as backEdges, W as bodyOutline, Y as boxForContent, Z as buildBody, $ as canvasMeasure, a0 as contentBox, aw as extent, a5 as force, a6 as forceRelaxation, a7 as forestOf, a8 as graphOrder, ab as layered, ac as layoutBody, ad as layoutRowPorts, ae as measureBody, af as outlinePath, ag as outlinePolyline, ah as packAcross, aj as pinnedSet, ak as portOf, al as portsOf, am as portsOnOutline, ao as ranksOf, ap as rayHit, aq as seededOrder, ar as settle, as as sizeToBody, at as translated, au as tree, av as untilSettled } from './layout.entry-BUkiRKuX.js';
2
2
  import '@weasel-js/geom';
3
3
  import '@weasel-js/core/math';
4
4
  import '@weasel-js/simulation';
@@ -150,6 +150,9 @@ interface GraphGroup {
150
150
  members: readonly string[];
151
151
  /** Room the box keeps around what it holds, in world units. */
152
152
  inset: GroupInset;
153
+ /** The narrowest its box may be across the world x axis, which a layout
154
+ * leaves room for. */
155
+ minWidth?: number;
153
156
  /** The group this one is directly inside. */
154
157
  parent?: string;
155
158
  }
@@ -411,6 +414,9 @@ interface DiagramGroup {
411
414
  /** Room the box keeps around its members, in world units: one number for
412
415
  * every side, or per side. Default 12 on each. */
413
416
  inset?: number | Partial<GroupInset>;
417
+ /** The narrowest the box may be, in world units, as room for its label.
418
+ * A box its members leave narrower grows evenly on both sides. */
419
+ minWidth?: number;
414
420
  }
415
421
  /** A port resolved against a node's current pose: where it is in world
416
422
  * coordinates, and which way an edge leaves it. */
@@ -796,4 +802,4 @@ declare function rayHit(poly: readonly number[], center: {
796
802
  */
797
803
  declare function portsOnOutline(ports: readonly Port[], outline: Outline, bounds: Bounds): Port[];
798
804
 
799
- export { canvasMeasure as $, type GraphNodeLike as A, type BodySpec as B, COMPASS as C, type DiagramNodeLike as D, type GroupInset as E, type ForceOptions as F, type GraphSource as G, type LayoutAxes as H, type LayoutDirection as I, type RowBox as J, type RowNodeData as K, type LayoutFn as L, type MeasureRowText as M, type RowPort as N, type Outline as O, type Port as P, type RowPortBox as Q, type Row as R, type RowTextStyle as S, type Slot as T, axesFor as U, backEdges as V, bodyOutline as W, bodyTrait as X, boxForContent as Y, buildBody as Z, buildGraph as _, type PortsOptions as a, contentBox as a0, createDiagramNodes as a1, dataKeyReader as a2, diagramNodeOf as a3, expandGroupEdges as a4, force as a5, forceRelaxation as a6, forestOf as a7, graphOrder as a8, insetOf as a9, isPinned as aa, layered as ab, layoutBody as ac, layoutRowPorts as ad, measureBody as ae, outlinePath as af, outlinePolyline as ag, packAcross as ah, packClusters as ai, pinnedSet as aj, portOf as ak, portsOf as al, portsOnOutline as am, rankGaps as an, ranksOf as ao, rayHit as ap, seededOrder as aq, settle as ar, sizeToBody as as, translated as at, tree as au, untilSettled as av, extent as aw, type DiagramNodeReader as b, type PortAnchor as c, type DiagramGroup as d, type PortSpec as e, type DiagramNode as f, type LayoutOptions as g, type LayoutResult as h, type Graph as i, type BodyFloor as j, type BodyNodeSpec as k, type Bounds as l, type BuildBodyOptions as m, type BuildGraphOptions as n, DEFAULT_GROUP_INSET as o, DEFAULT_NODE_GAP as p, DEFAULT_PORTS as q, DEFAULT_RANK_GAP as r, DIAGRAM_TRAIT_KEY as s, type DiagramNodeEntry as t, type ForceBody as u, type ForceRelaxation as v, type Forest as w, type GraphEdge as x, type GraphGroup as y, type GraphNode as z };
805
+ export { canvasMeasure as $, type GraphNode as A, type BodySpec as B, COMPASS as C, type DiagramNodeLike as D, type GraphNodeLike as E, type ForceOptions as F, type GraphSource as G, type GroupInset as H, type LayoutAxes as I, type RowBox as J, type RowNodeData as K, type LayoutFn as L, type MeasureRowText as M, type RowPort as N, type Outline as O, type Port as P, type RowPortBox as Q, type Row as R, type RowTextStyle as S, type Slot as T, axesFor as U, backEdges as V, bodyOutline as W, bodyTrait as X, boxForContent as Y, buildBody as Z, buildGraph as _, type PortsOptions as a, contentBox as a0, createDiagramNodes as a1, dataKeyReader as a2, diagramNodeOf as a3, expandGroupEdges as a4, force as a5, forceRelaxation as a6, forestOf as a7, graphOrder as a8, insetOf as a9, isPinned as aa, layered as ab, layoutBody as ac, layoutRowPorts as ad, measureBody as ae, outlinePath as af, outlinePolyline as ag, packAcross as ah, packClusters as ai, pinnedSet as aj, portOf as ak, portsOf as al, portsOnOutline as am, rankGaps as an, ranksOf as ao, rayHit as ap, seededOrder as aq, settle as ar, sizeToBody as as, translated as at, tree as au, untilSettled as av, extent as aw, type DiagramNodeReader as b, type PortAnchor as c, type DiagramGroup as d, type PortSpec as e, type DiagramNode as f, type LayoutOptions as g, type LayoutResult as h, type Graph as i, type LayoutDirection as j, type BodyFloor as k, type BodyNodeSpec as l, type Bounds as m, type BuildBodyOptions as n, type BuildGraphOptions as o, DEFAULT_GROUP_INSET as p, DEFAULT_NODE_GAP as q, DEFAULT_PORTS as r, DEFAULT_RANK_GAP as s, DIAGRAM_TRAIT_KEY as t, type DiagramNodeEntry as u, type ForceBody as v, type ForceRelaxation as w, type Forest as x, type GraphEdge as y, type GraphGroup as z };
package/dist/layout.js CHANGED
@@ -1,3 +1,3 @@
1
- export { COMPASS, DEFAULT_NODE_GAP, DEFAULT_PORTS, DEFAULT_RANK_GAP, axesFor, backEdges, bodyOutline, boxForContent, buildBody, canvasMeasure, contentBox, extent, force, forceRelaxation, forestOf, graphOrder, layered, layoutBody, layoutRowPorts, measureBody, outlinePath, outlinePolyline, packAcross, pinnedSet, portOf, portsOf, portsOnOutline, ranksOf, rayHit, seededOrder, settle, sizeToBody, translated, tree, untilSettled } from './chunk-BWQJYEA3.js';
1
+ export { COMPASS, DEFAULT_NODE_GAP, DEFAULT_PORTS, DEFAULT_RANK_GAP, axesFor, backEdges, bodyOutline, boxForContent, buildBody, canvasMeasure, contentBox, extent, force, forceRelaxation, forestOf, graphOrder, layered, layoutBody, layoutRowPorts, measureBody, outlinePath, outlinePolyline, packAcross, pinnedSet, portOf, portsOf, portsOnOutline, ranksOf, rayHit, seededOrder, settle, sizeToBody, translated, tree, untilSettled } from './chunk-JZ4CVLAB.js';
2
2
  //# sourceMappingURL=layout.js.map
3
3
  //# sourceMappingURL=layout.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weasel-js/diagram",
3
- "version": "1.10.0",
3
+ "version": "1.10.1",
4
4
  "description": "Node-link diagramming for weasel: any scene node becomes a diagram participant, with ports on its perimeter and an optional body builder for flowchart-shaped boxes.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -21,11 +21,11 @@
21
21
  },
22
22
  "peerDependencies": {
23
23
  "react": ">=18",
24
- "@weasel-js/animator": "1.10.0",
25
- "@weasel-js/core": "1.10.0",
26
- "@weasel-js/font": "1.10.0",
27
- "@weasel-js/geom": "1.10.0",
28
- "@weasel-js/simulation": "1.10.0"
24
+ "@weasel-js/animator": "1.10.1",
25
+ "@weasel-js/core": "1.10.1",
26
+ "@weasel-js/font": "1.10.1",
27
+ "@weasel-js/geom": "1.10.1",
28
+ "@weasel-js/simulation": "1.10.1"
29
29
  },
30
30
  "author": "orochi235",
31
31
  "homepage": "https://orochi235.github.io/weasel/",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/outline.ts","../src/onOutline.ts","../src/trait.ts","../src/ports.ts","../src/body.ts","../src/layout.ts","../src/cluster.ts","../src/forceGroups.ts","../src/force.ts","../src/barycenter.ts","../src/layered.ts","../src/tree.ts"],"names":["left","right","top","bottom","center","settle","start","x","cursor"],"mappings":"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","file":"chunk-BWQJYEA3.js","sourcesContent":["/**\n * The shapes a built body can wear, as paths in the node's bounds.\n *\n * These are the flowchart vocabulary — a decision is a diamond, an I/O step a\n * parallelogram, a terminator a stadium — plus `'rect'` for everything else and\n * a `Path` escape hatch for a shape the vocabulary does not have. The path is\n * built in world coordinates from the bounds it is given, the same way the\n * kit's own `clipFromPose` factories are.\n */\nimport { PathBuilder, polygonFromPoints, rectPath, type Path } from '@weasel-js/core/math';\n\n/** An axis-aligned box. This is `PoseDescriptor.getBounds`'s return shape\n * minus its optional `rotation`, deliberately: an outline is built in the\n * shape's own unrotated frame, and the caller reads rotation separately\n * through `getRotation` and applies it to the finished path. */\nexport interface Bounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** A named flowchart shape, or a path a consumer built themselves. */\nexport type Outline = 'rect' | 'diamond' | 'stadium' | 'parallelogram' | Path;\n\n/** How far a parallelogram's top edge leans past its bottom one, as a\n * fraction of the box's width. The flowchart convention. */\nconst LEAN = 0.2;\n\n/** Cubic approximation of a quarter circle. A stadium's ends are two of these\n * each, which is the same construction `ellipsePath` uses. */\nconst KAPPA = 0.5522847498307936;\n\n/** The path `outline` describes inside `bounds`. A zero-area box gives a\n * zero-area rect rather than a degenerate polygon. */\nexport function outlinePath(outline: Outline, bounds: Bounds): Path {\n if (typeof outline !== 'string') return outline;\n const { x, y, width: w, height: h } = bounds;\n if (w <= 0 || h <= 0) return rectPath(x, y, Math.max(w, 0), Math.max(h, 0));\n\n switch (outline) {\n case 'rect':\n return rectPath(x, y, w, h);\n\n case 'diamond':\n return polygonFromPoints([\n { x: x + w / 2, y },\n { x: x + w, y: y + h / 2 },\n { x: x + w / 2, y: y + h },\n { x, y: y + h / 2 },\n ]);\n\n case 'parallelogram': {\n // The lean is clamped so a narrow box cannot fold through itself.\n const lean = Math.min(w * LEAN, w / 2);\n return polygonFromPoints([\n { x: x + lean, y },\n { x: x + w, y },\n { x: x + w - lean, y: y + h },\n { x, y: y + h },\n ]);\n }\n\n case 'stadium':\n return stadiumPath(x, y, w, h);\n }\n}\n\n/** A rect with semicircular ends — the Minkowski sum of a segment and a disc,\n * which puts the flat edges along the box's *longer* axis. A tall box is a\n * pill standing up, not an ellipse. */\nfunction stadiumPath(x: number, y: number, w: number, h: number): Path {\n const r = Math.min(w, h) / 2;\n const k = r * KAPPA;\n const b = new PathBuilder();\n\n if (w >= h) {\n const left = x + r;\n const right = x + w - r;\n const top = y;\n const bottom = y + h;\n const midY = y + h / 2;\n return b\n .moveTo(left, top)\n .lineTo(right, top)\n .curveTo(right + k, top, x + w, midY - k, x + w, midY)\n .curveTo(x + w, midY + k, right + k, bottom, right, bottom)\n .lineTo(left, bottom)\n .curveTo(left - k, bottom, x, midY + k, x, midY)\n .curveTo(x, midY - k, left - k, top, left, top)\n .close()\n .build();\n }\n\n const top = y + r;\n const bottom = y + h - r;\n const left = x;\n const right = x + w;\n const midX = x + w / 2;\n return b\n .moveTo(right, top)\n .lineTo(right, bottom)\n .curveTo(right, bottom + k, midX + k, y + h, midX, y + h)\n .curveTo(midX - k, y + h, left, bottom + k, left, bottom)\n .lineTo(left, top)\n .curveTo(left, top - k, midX - k, y, midX, y)\n .curveTo(midX + k, y, right, top - k, right, top)\n .close()\n .build();\n}\n\n/**\n * The largest axis-aligned box a shape's content can occupy without leaving\n * the shape. Rows lay out in here, not in the bounds — a diamond's corners and\n * a parallelogram's lean are outside its own box, and a label placed against\n * the bounding box lands there and gets clipped away by the silhouette.\n *\n * Conservative rather than exact: the inscribed rect of a rhombus is exact,\n * and a stadium reports the flat span between its rounded ends, which gives up\n * a little height near them.\n */\nexport function contentBox(outline: Outline, bounds: Bounds): Bounds {\n if (typeof outline !== 'string') return bounds;\n const { x, y, width: w, height: h } = bounds;\n switch (outline) {\n case 'rect':\n return bounds;\n case 'diamond':\n // Half the width and half the height, centered — the inscribed rect.\n return { x: x + w / 4, y: y + h / 4, width: w / 2, height: h / 2 };\n case 'parallelogram': {\n const lean = Math.min(w * LEAN, w / 2);\n return { x: x + lean, y, width: Math.max(w - lean * 2, 0), height: h };\n }\n case 'stadium': {\n const r = Math.min(w, h) / 2;\n return w >= h\n ? { x: x + r, y, width: Math.max(w - r * 2, 0), height: h }\n : { x, y: y + r, width: w, height: Math.max(h - r * 2, 0) };\n }\n }\n}\n\n/**\n * The box whose {@link contentBox} is at least `content` — the inverse, for\n * sizing a node to what its rows measured.\n *\n * The stadium case is the only inexact one: its inset depends on the height it\n * is solving for, so it assumes the wide orientation and adds one height's\n * worth of end caps.\n */\nexport function boxForContent(\n outline: Outline,\n content: { width: number; height: number },\n): { width: number; height: number } {\n if (typeof outline !== 'string') return content;\n switch (outline) {\n case 'rect':\n return content;\n case 'diamond':\n return { width: content.width * 2, height: content.height * 2 };\n case 'parallelogram':\n return { width: content.width / (1 - LEAN * 2), height: content.height };\n case 'stadium':\n return { width: content.width + content.height, height: content.height };\n }\n}\n","/**\n * Moving a port from the node's bounding box onto the shape it is drawn as.\n *\n * A port is placed as a fraction of the node's bounds, which is what makes it\n * survive a resize. For a rect that is already on the outline; for anything\n * else it can be well outside the ink — a parallelogram's west port floats in\n * the gap beside its leaning edge, and an edge that ends there ends in empty\n * space. So the point is cast back onto the outline along the ray from the\n * node's center, which is the direction an edge leaves anyway.\n */\nimport { PATH_C, PATH_L, PATH_M, PATH_Q, PATH_Z, flattenCubic, type Path } from '@weasel-js/core/math';\nimport { outlinePath, type Bounds, type Outline } from './outline';\nimport type { Port } from './types';\n\n/** Curve flattening tolerance, in world units. Finer than a port is wide. */\nconst TOLERANCE = 0.25;\n\n/** The outline as a closed polyline: `[x0, y0, x1, y1, …]`. */\nexport function outlinePolyline(outline: Outline, bounds: Bounds): number[] {\n const path = outlinePath(outline, bounds);\n return flattenPath(path);\n}\n\nfunction flattenPath(path: Path): number[] {\n if (path.kind === 'rect') {\n const { x, y, width: w, height: h } = path;\n return [x, y, x + w, y, x + w, y + h, x, y + h, x, y];\n }\n const out: number[] = [];\n const { commands, coords } = path as { commands: Uint8Array; coords: Float32Array };\n let ci = 0;\n let cx = 0;\n let cy = 0;\n let sx = 0;\n let sy = 0;\n for (const cmd of commands) {\n if (cmd === PATH_M) {\n cx = coords[ci]!; cy = coords[ci + 1]!; ci += 2;\n sx = cx; sy = cy;\n out.push(cx, cy);\n } else if (cmd === PATH_L) {\n cx = coords[ci]!; cy = coords[ci + 1]!; ci += 2;\n out.push(cx, cy);\n } else if (cmd === PATH_C) {\n const x1 = coords[ci]!, y1 = coords[ci + 1]!;\n const x2 = coords[ci + 2]!, y2 = coords[ci + 3]!;\n const x3 = coords[ci + 4]!, y3 = coords[ci + 5]!;\n ci += 6;\n flattenCubic(cx, cy, x1, y1, x2, y2, x3, y3, TOLERANCE, out);\n cx = x3; cy = y3;\n } else if (cmd === PATH_Q) {\n // Elevated to a cubic rather than given its own flattener.\n const qx = coords[ci]!, qy = coords[ci + 1]!;\n const x3 = coords[ci + 2]!, y3 = coords[ci + 3]!;\n ci += 4;\n flattenCubic(\n cx, cy,\n cx + (2 / 3) * (qx - cx), cy + (2 / 3) * (qy - cy),\n x3 + (2 / 3) * (qx - x3), y3 + (2 / 3) * (qy - y3),\n x3, y3, TOLERANCE, out,\n );\n cx = x3; cy = y3;\n } else if (cmd === PATH_Z) {\n out.push(sx, sy);\n cx = sx; cy = sy;\n }\n }\n // Close it, so a ray leaving through the last edge still finds a crossing.\n if (out.length >= 2 && (out[0] !== out[out.length - 2] || out[1] !== out[out.length - 1])) {\n out.push(out[0]!, out[1]!);\n }\n return out;\n}\n\n/**\n * Where the ray from `center` through `point` last crosses `poly`, or `null`\n * when it never does.\n *\n * The *last* crossing rather than the first: a concave outline can be crossed\n * more than once, and the far side is the boundary an edge should attach to.\n */\nexport function rayHit(\n poly: readonly number[],\n center: { x: number; y: number },\n point: { x: number; y: number },\n): { x: number; y: number } | null {\n const dx = point.x - center.x;\n const dy = point.y - center.y;\n if (dx === 0 && dy === 0) return null;\n let bestT = -Infinity;\n let hit: { x: number; y: number } | null = null;\n for (let i = 0; i + 3 < poly.length; i += 2) {\n const ax = poly[i]!, ay = poly[i + 1]!;\n const bx = poly[i + 2]!, by = poly[i + 3]!;\n const ex = bx - ax;\n const ey = by - ay;\n const denom = dx * ey - dy * ex;\n if (denom === 0) continue;\n // t along the ray, u along the segment.\n const t = ((ax - center.x) * ey - (ay - center.y) * ex) / denom;\n const u = ((ax - center.x) * dy - (ay - center.y) * dx) / denom;\n if (t < 0 || u < 0 || u > 1) continue;\n if (t > bestT) {\n bestT = t;\n hit = { x: center.x + dx * t, y: center.y + dy * t };\n }\n }\n return hit;\n}\n\n/**\n * Every port moved onto `outline`. A port the ray misses — one at the node's\n * dead center, with no direction to cast along — is left where it was.\n */\nexport function portsOnOutline(\n ports: readonly Port[],\n outline: Outline,\n bounds: Bounds,\n): Port[] {\n if (bounds.width <= 0 || bounds.height <= 0) return [...ports];\n const poly = outlinePolyline(outline, bounds);\n const center = { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 };\n return ports.map((port) => {\n const hit = rayHit(poly, center, port.point);\n return hit === null ? port : { ...port, point: hit };\n });\n}\n","/**\n * Reading the `DiagramNode` trait off a scene node.\n *\n * Two ways to attach it:\n *\n * - **On the node.** `data.diagram` holds the trait.\n * - **By kind.** A consumer declares once which data shapes take part, and\n * every matching node gets the trait without being stamped — a predicate\n * over `data`, first match wins.\n *\n * A reader is a plain function, so a consumer whose data lives somewhere else\n * passes their own.\n */\nimport type { DiagramNode } from './types';\n\n/** The key on a node's `data` the default reader looks under. */\nexport const DIAGRAM_TRAIT_KEY = 'diagram';\n\n/** All a reader looks at. Deliberately not `SceneNode`: naming `TPose` there\n * would put it in a contravariant position for no gain, since nothing here\n * reads a pose. */\nexport interface DiagramNodeLike {\n id: string;\n kind: 'leaf' | 'container';\n data: unknown;\n}\n\n/** Answers \"is this node a diagram participant, and on what terms\" — `null`\n * for a node that takes no part. */\nexport type DiagramNodeReader = (node: DiagramNodeLike) => DiagramNode | null;\n\n/** One class of participant, declared once for every node whose data matches.\n * Mirrors `NodeRoutingEntry`. */\nexport interface DiagramNodeEntry {\n /** Unique within a reader; the same vocabulary as `NodeRoutingEntry.name`. */\n name: string;\n matches: (data: unknown) => boolean;\n /** The trait every matching node carries. A function when it varies with the\n * node's own data — a pipeline stage whose ports come from its rows. */\n trait: DiagramNode | ((data: unknown) => DiagramNode);\n}\n\n/** The trait on the node's own `data.diagram`, or `null`.\n *\n * An edge's trait lives under the same key, so `from` and `to` are what tells\n * the two apart. Without that test an edge reads as a participant declaring\n * no ports, and collects the four defaults on the degenerate pose an edge\n * carries. An edge label's `label` trait and an anchored node's `anchor` are\n * excluded the same way. */\nexport const dataKeyReader: DiagramNodeReader = (node) => {\n const data = node.data;\n if (data === null || typeof data !== 'object') return null;\n const trait = (data as Record<string, unknown>)[DIAGRAM_TRAIT_KEY];\n if (trait === null || typeof trait !== 'object') return null;\n if ('from' in trait && 'to' in trait) return null;\n if ('label' in trait || 'anchor' in trait) return null;\n return trait as DiagramNode;\n};\n\n/**\n * A reader over declared kinds. A trait on the node's own data still wins, so\n * a single node can opt out of, or override, whatever its kind says. Throws on\n * a duplicate `name`.\n */\nexport function createDiagramNodes(entries: readonly DiagramNodeEntry[]): DiagramNodeReader {\n const seen = new Set<string>();\n for (const entry of entries) {\n if (seen.has(entry.name)) {\n throw new Error(`createDiagramNodes: duplicate entry name \"${entry.name}\"`);\n }\n seen.add(entry.name);\n }\n return (node) => {\n const own = dataKeyReader(node);\n if (own !== null) return own;\n for (const entry of entries) {\n if (!entry.matches(node.data)) continue;\n return typeof entry.trait === 'function' ? entry.trait(node.data) : entry.trait;\n }\n return null;\n };\n}\n\n/** The trait `node` carries, through `read` (default: its own `data.diagram`). */\nexport function diagramNodeOf(\n node: DiagramNodeLike,\n read: DiagramNodeReader = dataKeyReader,\n): DiagramNode | null {\n return read(node);\n}\n\n/** True when layout must leave this node where it is. */\nexport function isPinned(node: DiagramNodeLike, read?: DiagramNodeReader): boolean {\n return diagramNodeOf(node, read)?.pinned === true;\n}\n","/**\n * Where a node's ports are, in world coordinates.\n *\n * A port is placed in the node's **unrotated** bounds, then carried through\n * the pose's rotation — the same pivot every other kit reader uses, the AABB\n * center. Bounds come from the pose descriptor rather than from `pose.width`\n * and friends, so a node whose pose is a path, an ellipse or anything else a\n * consumer wired is connectable on the same terms as a rect.\n */\nimport {\n AUTO_POSE_DESCRIPTOR,\n rotatePoint,\n type PoseDescriptor,\n type Vec2,\n} from '@weasel-js/core/math';\nimport { outlinePolyline, rayHit } from './onOutline';\nimport { diagramNodeOf, type DiagramNodeLike, type DiagramNodeReader } from './trait';\nimport type { Port, PortAnchor, PortSpec } from './types';\n\n/** The eight anchors almost everything wants, named the way a compass is. */\nexport const COMPASS = {\n nw: { u: 0, v: 0 },\n n: { u: 0.5, v: 0 },\n ne: { u: 1, v: 0 },\n e: { u: 1, v: 0.5 },\n se: { u: 1, v: 1 },\n s: { u: 0.5, v: 1 },\n sw: { u: 0, v: 1 },\n w: { u: 0, v: 0.5 },\n} as const satisfies Record<string, PortAnchor>;\n\n/**\n * What a node carrying no `ports` gets: the four edge midpoints of its own\n * bounds. Every node has bounds, so every node is connectable without saying\n * anything.\n */\nexport const DEFAULT_PORTS: readonly PortSpec[] = Object.freeze([\n { id: 'n', at: COMPASS.n },\n { id: 'e', at: COMPASS.e },\n { id: 's', at: COMPASS.s },\n { id: 'w', at: COMPASS.w },\n]);\n\n/** How ports are resolved against a node: its bounds, and its trait. */\nexport interface PortsOptions<TPose> {\n /** Reads the AABB a port is placed in, and the node's rotation. Defaults to\n * the kit's `AUTO_POSE_DESCRIPTOR`, which handles rect and path poses. */\n geometry?: PoseDescriptor<TPose>;\n /** How the `DiagramNode` trait is read off a node. */\n read?: DiagramNodeReader;\n}\n\n/**\n * The direction the anchor implies: away from the center of the bounds.\n *\n * `(2u-1, 2v-1)` is the anchor in a box that runs -1..1, which is exactly that\n * direction — an edge midpoint gets the axis-aligned normal, a corner gets the\n * diagonal. It is deliberately not scaled by the node's aspect: this is a\n * heading a router leaves along, not a point on the outline. A port at the\n * dead center has no direction, and says so.\n */\nfunction normalOf(at: PortAnchor): Vec2 | null {\n const x = at.u * 2 - 1;\n const y = at.v * 2 - 1;\n const len = Math.hypot(x, y);\n if (len === 0) return null;\n return { x: x / len, y: y / len };\n}\n\n/**\n * Every port on `node`, resolved against `pose`.\n *\n * Pass the pose the node is **painted** at — `effectivePose(scene, node)` —\n * not `node.pose`. A port that answers from the document pose while the node\n * is mid-drag puts an edge somewhere the user can see the node is not.\n */\nexport function portsOf<TPose>(\n node: DiagramNodeLike,\n pose: TPose,\n opts: PortsOptions<TPose> = {},\n): Port[] {\n const trait = diagramNodeOf(node, opts.read);\n if (trait === null) return [];\n const geometry = opts.geometry ?? (AUTO_POSE_DESCRIPTOR as PoseDescriptor<TPose>);\n const bounds = geometry.getBounds(pose);\n const rotation = geometry.getRotation?.(pose) ?? 0;\n const cx = bounds.x + bounds.width / 2;\n const cy = bounds.y + bounds.height / 2;\n // A port is anchored in the bounds so it survives a resize, but it has to\n // *sit* on the shape: a parallelogram's west anchor is in the gap beside its\n // leaning edge, and an edge ending there ends in empty space. Flattened once\n // per call, not once per port.\n const poly = trait.outline === undefined || bounds.width <= 0 || bounds.height <= 0\n ? null\n : outlinePolyline(trait.outline, bounds);\n\n return (trait.ports ?? DEFAULT_PORTS).map((spec) => {\n const anchored: Vec2 = {\n x: bounds.x + spec.at.u * bounds.width,\n y: bounds.y + spec.at.v * bounds.height,\n };\n const flat = (poly === null ? null : rayHit(poly, { x: cx, y: cy }, anchored)) ?? anchored;\n const normal = spec.normal === undefined ? normalOf(spec.at) : spec.normal;\n if (rotation === 0) {\n return { id: spec.id, nodeId: node.id, point: flat, normal, ...typeOf(spec) };\n }\n return {\n id: spec.id,\n nodeId: node.id,\n point: rotatePoint(flat.x, flat.y, cx, cy, rotation),\n // A direction rotates about the origin, not about the node's center.\n normal: normal === null ? null : rotatePoint(normal.x, normal.y, 0, 0, rotation),\n ...typeOf(spec),\n };\n });\n}\n\n/** One named port, or `undefined` when the node has no such port. */\nexport function portOf<TPose>(\n node: DiagramNodeLike,\n pose: TPose,\n portId: string,\n opts: PortsOptions<TPose> = {},\n): Port | undefined {\n return portsOf(node, pose, opts).find((p) => p.id === portId);\n}\n\n/** Spread rather than assigned, so a port with no type has no `type` key at\n * all — `exactOptionalPropertyTypes` rejects an explicit `undefined`. */\nfunction typeOf(spec: PortSpec): { type?: string } {\n return spec.type === undefined ? {} : { type: spec.type };\n}\n","/**\n * The optional body builder: what a node looks like when it should read as a\n * flowchart box or a visual-programming operator, rather than as whatever\n * scene node it already was.\n *\n * **The body measures a floor; the author sets the rest.** Rows measure to a\n * `{ minWidth, minHeight }` and the node's pose is the max of that and what\n * the author gave it. Adding a port row can grow a node; nothing here ever\n * shrinks one back.\n *\n * Text measurement is a seam rather than an import: measuring needs a 2D\n * context, which a geometry module has no business owning.\n */\nimport { cssFamilyName } from '@weasel-js/font';\nimport { boxForContent, contentBox, outlinePath, type Bounds, type Outline } from './outline';\nimport { COMPASS } from './ports';\nimport type { DiagramNode, PortSpec } from './types';\n\n/** One line of body content. */\nexport type Row =\n /** Text. `label` is the node's name; `field` is a named value. */\n | { kind: 'label'; text: string; style?: RowTextStyle }\n | { kind: 'field'; label: string; value: string; style?: RowTextStyle }\n /** A row that carries ports on its own left and right edges. */\n | { kind: 'ports'; left?: readonly RowPort[]; right?: readonly RowPort[]; height?: number }\n /** Reserved space a consumer paints into. */\n | { kind: 'slot'; height: number; id?: string };\n\n/** A port declared on a row rather than on the node's perimeter. */\nexport interface RowPort {\n id: string;\n /** Label shown beside it, and what the row measures against. */\n label?: string;\n type?: string;\n}\n\n/** The subset of a text style the body measures against. Deliberately small:\n * a full `ResolvedTextStyle` belongs to whatever paints the row. */\nexport interface RowTextStyle {\n fontSize?: number;\n fontFamily?: string;\n bold?: boolean;\n}\n\n/** Measures one run of text. Returns its advance width and its line height. */\nexport type MeasureRowText = (text: string, style: RowTextStyle) => { width: number; height: number };\n\n/** A body's content: the outline it draws and the rows stacked inside it. */\nexport interface BodySpec {\n outline: Outline;\n rows: readonly Row[];\n /** Space between the outline and its rows. Default 8. */\n padding?: number;\n /** Space between adjacent rows. Default 4. */\n gap?: number;\n /** Where the rows sit as a block when the body is taller than they need. Default `'center'`. */\n verticalAlign?: 'top' | 'center' | 'bottom';\n /** The perimeter ports, replacing the four compass midpoints. A `ports`\n * row's own ports are added either way. */\n ports?: readonly PortSpec[];\n}\n\n/** What {@link buildBody} emits: the `AddNodeSpec` fields it fills in. Named\n * structurally rather than imported so a consumer whose scene is typed\n * differently can still spread one. */\nexport interface BodyNodeSpec<TData, TLayer extends string, TPose> {\n kind: 'container' | 'leaf';\n layer: TLayer;\n pose: TPose;\n data: TData;\n id?: string;\n parent?: string;\n /** Set `false` on every leaf the builder emits: the innermost hit wins, so a\n * row that answers a press is a body that cannot be dragged. */\n pickable?: boolean;\n}\n\n/** The floor a body's content puts under its node's size. */\nexport interface BodyFloor {\n minWidth: number;\n minHeight: number;\n}\n\n/** Where one row landed, in the same frame as the bounds it was laid out in.\n * A `ports` row's own ports anchor to this box. */\nexport interface RowBox extends Bounds {\n row: Row;\n index: number;\n}\n\n/** Where one row port's label sits, in the same frame as the row box it was\n * laid out in. Its vertical center is also where the port itself attaches, so\n * a label and the port it names cannot drift apart. */\nexport interface RowPortBox extends Bounds {\n port: RowPort;\n side: 'left' | 'right';\n /** Position within its own side, top to bottom. */\n index: number;\n}\n\nconst DEFAULT_PADDING = 8;\nconst DEFAULT_GAP = 4;\n/** What a row is worth when nothing measures its text, so a body laid out\n * headlessly is not zero-height. */\nconst FALLBACK_LINE = 16;\n\n/** Adapts the kit's `measureText` for a caller holding a 2D context. Pass the\n * same context the renderer measures with, or the floor will not match what\n * is painted. */\nexport function canvasMeasure(\n ctx: { measureText(text: string): { width: number } ; font: string },\n): MeasureRowText {\n return (text, style) => {\n const size = style.fontSize ?? FALLBACK_LINE;\n ctx.font = `${style.bold === true ? 'bold ' : ''}${size}px ${cssFamilyName(style.fontFamily ?? 'sans-serif')}`;\n return { width: ctx.measureText(text).width, height: Math.ceil(size * 1.2) };\n };\n}\n\n/** What each row is worth on its own, before padding and gaps. */\nfunction measureRow(row: Row, measure: MeasureRowText | undefined): { width: number; height: number } {\n const text = (s: string, style?: RowTextStyle): { width: number; height: number } =>\n measure === undefined\n ? {\n width: s.length * (style?.fontSize ?? FALLBACK_LINE) * 0.6,\n height: style?.fontSize === undefined ? FALLBACK_LINE : Math.ceil(style.fontSize * 1.2),\n }\n : measure(s, style ?? {});\n\n switch (row.kind) {\n case 'label':\n return text(row.text, row.style);\n case 'field': {\n // Label and value sit on one line with a gap between them.\n const l = text(row.label, row.style);\n const v = text(row.value, row.style);\n return { width: l.width + DEFAULT_GAP * 2 + v.width, height: Math.max(l.height, v.height) };\n }\n case 'ports': {\n const side = (ports: readonly RowPort[] | undefined): number =>\n (ports ?? []).reduce((w, p) => Math.max(w, p.label === undefined ? 0 : text(p.label).width), 0);\n const rows = Math.max(row.left?.length ?? 0, row.right?.length ?? 0, 1);\n return {\n width: side(row.left) + DEFAULT_GAP * 2 + side(row.right),\n height: row.height ?? rows * FALLBACK_LINE,\n };\n }\n case 'slot':\n return { width: 0, height: row.height };\n }\n}\n\n/**\n * The smallest box `spec`'s rows fit in. A node's pose is maxed against this,\n * never set to it.\n */\nexport function measureBody(spec: BodySpec, measure?: MeasureRowText): BodyFloor {\n const padding = spec.padding ?? DEFAULT_PADDING;\n const gap = spec.gap ?? DEFAULT_GAP;\n let width = 0;\n let height = 0;\n for (const [i, row] of spec.rows.entries()) {\n const m = measureRow(row, measure);\n width = Math.max(width, m.width);\n height += m.height + (i > 0 ? gap : 0);\n }\n // The rows fit the *content* box; the node's own box has to be whatever\n // contains that, or a diamond's label lands outside the diamond.\n const box = boxForContent(spec.outline, {\n width: width + padding * 2,\n height: height + padding * 2,\n });\n return { minWidth: box.width, minHeight: box.height };\n}\n\n/**\n * The authored size, grown to fit the body. Never shrinks: a row removed\n * leaves the node the size the author last saw it at.\n */\nexport function sizeToBody<TPose extends Bounds>(pose: TPose, floor: BodyFloor): TPose {\n const width = Math.max(pose.width, floor.minWidth);\n const height = Math.max(pose.height, floor.minHeight);\n if (width === pose.width && height === pose.height) return pose;\n return { ...pose, width, height };\n}\n\n/** Where each row sits inside `bounds`, top to bottom. Rows keep their\n * measured heights rather than sharing out the leftover; `verticalAlign`\n * places the block of them within it. */\nexport function layoutBody(\n spec: BodySpec,\n bounds: Bounds,\n measure?: MeasureRowText,\n): RowBox[] {\n const padding = spec.padding ?? DEFAULT_PADDING;\n const gap = spec.gap ?? DEFAULT_GAP;\n const inner = contentBox(spec.outline, bounds);\n const width = Math.max(inner.width - padding * 2, 0);\n const heights = spec.rows.map((row) => measureRow(row, measure).height);\n const used = heights.reduce((sum, h) => sum + h, 0) + gap * Math.max(heights.length - 1, 0);\n const slack = Math.max(inner.height - padding * 2 - used, 0);\n const share = { top: 0, center: 0.5, bottom: 1 }[spec.verticalAlign ?? 'center'];\n let y = inner.y + padding + slack * share;\n return spec.rows.map((row, index) => {\n const h = heights[index];\n const box: RowBox = { row, index, x: inner.x + padding, y, width, height: h };\n y += h + gap;\n return box;\n });\n}\n\n/**\n * Where each of a `ports` row's ports goes inside `box`.\n *\n * Both sides are cut into the same number of slots — the longer side's count —\n * so the nth input faces the nth output whichever side has more. A label box\n * is as wide as its own text and pinned to its own edge of the row; an\n * unlabeled port gets a zero-width box there, which is still where it attaches.\n */\nexport function layoutRowPorts(\n row: Extract<Row, { kind: 'ports' }>,\n box: Bounds,\n measure?: MeasureRowText,\n): RowPortBox[] {\n const width = (label: string | undefined): number =>\n label === undefined ? 0 : measureRow({ kind: 'label', text: label }, measure).width;\n const slots = Math.max(row.left?.length ?? 0, row.right?.length ?? 0, 1);\n const slotHeight = box.height / slots;\n const out: RowPortBox[] = [];\n const side = (ports: readonly RowPort[] | undefined, which: 'left' | 'right'): void => {\n for (const [index, port] of (ports ?? []).entries()) {\n const w = width(port.label);\n out.push({\n port,\n side: which,\n index,\n x: which === 'left' ? box.x : box.x + box.width - w,\n y: box.y + index * slotHeight,\n width: w,\n height: slotHeight,\n });\n }\n };\n side(row.left, 'left');\n side(row.right, 'right');\n return out;\n}\n\n/**\n * The `DiagramNode` trait a built body implies: perimeter ports for the\n * outline, plus one port per `ports`-row entry, anchored to that row's own\n * left or right edge.\n *\n * Anchors are normalized against `bounds`, so they survive the node being\n * resized.\n *\n * **A row port on a side takes that side's compass default with it.** Both sit\n * on the same edge, and a row near the vertical middle puts one exactly on top\n * of `w` or `e` — where the later region wins the hit and the other is\n * grabbable nowhere.\n */\nexport function bodyTrait(spec: BodySpec, bounds: Bounds, measure?: MeasureRowText): DiagramNode {\n const outline = spec.outline;\n const compass: readonly PortSpec[] = spec.ports ?? [\n { id: 'n', at: COMPASS.n },\n { id: 'e', at: COMPASS.e },\n { id: 's', at: COMPASS.s },\n { id: 'w', at: COMPASS.w },\n ];\n if (bounds.height <= 0) return { outline, ports: [...compass] };\n\n const rowPorts: PortSpec[] = [];\n let hasLeft = false;\n let hasRight = false;\n for (const box of layoutBody(spec, bounds, measure)) {\n if (box.row.kind !== 'ports') continue;\n for (const pb of layoutRowPorts(box.row, box, measure)) {\n if (pb.side === 'left') hasLeft = true;\n else hasRight = true;\n const v = (pb.y + pb.height / 2 - bounds.y) / bounds.height;\n rowPorts.push(withType(\n { id: pb.port.id, at: { u: pb.side === 'left' ? 0 : 1, v } },\n pb.port.type,\n ));\n }\n }\n const kept = spec.ports !== undefined ? compass : compass.filter((p) =>\n !(p.id === 'w' && hasLeft) && !(p.id === 'e' && hasRight));\n return { outline, ports: [...kept, ...rowPorts] };\n}\n\nfunction withType(spec: PortSpec, type: string | undefined): PortSpec {\n return type === undefined ? spec : { ...spec, type };\n}\n\n/** The outline path for a built body at `bounds` — what paints it, and what a\n * perimeter-hugging port will eventually be placed on. */\nexport function bodyOutline(spec: BodySpec, bounds: Bounds) {\n return outlinePath(spec.outline, bounds);\n}\n\n/** What a built body's rows are handed to, one call per row.\n *\n * `text` is the row's content already formatted — a `label`'s own text, or a\n * `field`'s `\"label: value\"` — so the common case needs no discrimination.\n * Return `null` for a row the consumer paints itself; `ports` and `slot` rows\n * arrive with `text` empty and are the usual ones to decline. */\nexport type RowNodeData<TData> = (text: string, box: RowBox) => TData | null;\n\n/** Options for {@link buildBody}: the layer and data of each node it emits.\n * Without `measure`, rows are sized from a fallback line height rather than\n * their text. */\nexport interface BuildBodyOptions<TData, TLayer extends string, TPose extends Bounds> {\n layer: TLayer;\n /** The container's id. Edges name it, so pass one for anything an edge or a\n * layout `pin` will refer to. */\n id?: string;\n measure?: MeasureRowText;\n /** The container's own data, given the trait the builder computed and the\n * pose it was computed against. */\n body: (trait: DiagramNode, pose: TPose) => TData;\n /** One row's data, or `null` to leave that row undrawn. */\n row: RowNodeData<TData>;\n /** One row port's label, or `null` to leave it undrawn. Ports with no\n * `label` are never offered. Omit to draw none. */\n portLabel?: (text: string, box: RowPortBox) => TData | null;\n}\n\n/**\n * The scene nodes a built body is: one container carrying the trait, and one\n * leaf per row that wants drawing.\n *\n * Rows are ordinary scene nodes rather than something this package paints, so\n * the kit's own text painter draws them and text editing, styling, and\n * selection work on them unchanged. The returned pose is `at` grown to fit the\n * body, never shrunk.\n */\nexport function buildBody<TData, TLayer extends string, TPose extends Bounds>(\n spec: BodySpec,\n at: TPose,\n opts: BuildBodyOptions<TData, TLayer, TPose>,\n): { pose: TPose; specs: BodyNodeSpec<TData, TLayer, TPose>[] } {\n const pose = sizeToBody(at, measureBody(spec, opts.measure));\n const specs: BodyNodeSpec<TData, TLayer, TPose>[] = [{\n kind: 'container',\n layer: opts.layer,\n pose,\n data: opts.body(bodyTrait(spec, pose, opts.measure), pose),\n ...(opts.id === undefined ? {} : { id: opts.id }),\n }];\n\n const leaf = (box: Bounds, data: TData): void => {\n specs.push({\n kind: 'leaf',\n layer: opts.layer,\n pose: { ...pose, x: box.x, y: box.y, width: box.width, height: box.height },\n data,\n pickable: false,\n ...(opts.id === undefined ? {} : { parent: opts.id }),\n });\n };\n\n const portLabel = opts.portLabel;\n for (const box of layoutBody(spec, pose, opts.measure)) {\n const data = opts.row(rowText(box.row), box);\n if (data !== null) leaf(box, data);\n if (portLabel === undefined || box.row.kind !== 'ports') continue;\n for (const pb of layoutRowPorts(box.row, box, opts.measure)) {\n if (pb.port.label === undefined) continue;\n const labelData = portLabel(pb.port.label, pb);\n if (labelData !== null) leaf(pb, labelData);\n }\n }\n return { pose, specs };\n}\n\n/** A row's content as one string: empty for a row that carries no text. */\nfunction rowText(row: Row): string {\n if (row.kind === 'label') return row.text;\n if (row.kind === 'field') return `${row.label}: ${row.value}`;\n return '';\n}\n","/**\n * Layout: where the participants go.\n *\n * A layout is a pure function of the graph — no scene, no ops, no history. It\n * hands back the new top-left for every node that **moves**, and a node already\n * standing where the layout wants it is absent from the answer.\n *\n * Three rules keep re-layout non-destructive:\n *\n * - **No RNG anywhere.** Every tiebreak falls back to the graph's own node\n * order.\n * - **Within-rank order is seeded from where the nodes already are**, read\n * off the cross axis, rather than from crossing-minimization.\n * - **A pin set nothing moves.** Pinned nodes are never in the result, and\n * the rest of the layout is translated to sit around them.\n *\n * `layered` and `tree` are idempotent; `force` is an iterative relaxation and\n * re-running it keeps relaxing.\n */\nimport type { Vec2 } from '@weasel-js/core/math';\nimport type { Graph, GraphNode } from './graph';\nimport type { Bounds } from './outline';\n\n/** Which way the ranks stack. `force` ignores it. */\nexport type LayoutDirection = 'down' | 'up' | 'right' | 'left';\n\n/** Options every layout takes. */\nexport interface LayoutOptions {\n /** Default `'down'`. */\n direction?: LayoutDirection;\n /** Between neighbors within a rank, in world units. Default 48. */\n nodeGap?: number;\n /** Between one rank and the next. Default 96. */\n rankGap?: number;\n /** How `layered` orders nodes within a rank. `'seeded'` (default) keeps\n * the order they already sit in; `'barycenter'` reorders to reduce edge\n * crossings, for a generated diagram with no arranged order to keep.\n * Other layouts ignore it. */\n order?: 'seeded' | 'barycenter';\n /** Ids layout must not move, on top of whatever carries `pinned: true`. */\n pin?: Iterable<string>;\n /** How far a node has to move to be worth moving, in world units. Default\n * `1e-6` — a float-noise floor, not a snapping quantum. Raise it to let a\n * `force` pass that has stopped doing anything useful commit nothing. */\n tolerance?: number;\n}\n\n/** The new top-left for each node that moves. A node that is already there is\n * absent, so an empty result means \"nothing to do\". */\nexport type LayoutResult = ReadonlyMap<string, Vec2>;\n\n/** Every layout in this package has this shape, and so does a consumer's. */\nexport type LayoutFn = (graph: Graph, opts?: LayoutOptions) => LayoutResult;\n\n/** `LayoutOptions.nodeGap`'s default, in world units. */\nexport const DEFAULT_NODE_GAP = 48;\n/** `LayoutOptions.rankGap`'s default, in world units. */\nexport const DEFAULT_RANK_GAP = 96;\nconst DEFAULT_TOLERANCE = 1e-6;\n\n/** Which world axis carries ranks, which carries within-rank order, and\n * whether ranks grow toward positive world coordinates. */\nexport interface LayoutAxes {\n rank: 'x' | 'y';\n cross: 'x' | 'y';\n /** `-1` for `'up'` and `'left'`, where the canonical frame is mirrored. */\n sign: 1 | -1;\n}\n\n/** The axes a direction lays ranks along. Default `'down'`. */\nexport function axesFor(direction: LayoutDirection = 'down'): LayoutAxes {\n switch (direction) {\n case 'up':\n return { rank: 'y', cross: 'x', sign: -1 };\n case 'right':\n return { rank: 'x', cross: 'y', sign: 1 };\n case 'left':\n return { rank: 'x', cross: 'y', sign: -1 };\n default:\n return { rank: 'y', cross: 'x', sign: 1 };\n }\n}\n\n/** A node's extent along one axis. */\nexport function extent(bounds: Bounds, axis: 'x' | 'y'): number {\n return axis === 'x' ? bounds.width : bounds.height;\n}\n\n/** A node's center along one axis — what within-rank order is seeded from. */\nexport function center(bounds: Bounds, axis: 'x' | 'y'): number {\n return axis === 'x' ? bounds.x + bounds.width / 2 : bounds.y + bounds.height / 2;\n}\n\n/** Every id layout must leave alone. */\nexport function pinnedSet(graph: Graph, opts: LayoutOptions = {}): Set<string> {\n const pinned = new Set<string>(opts.pin ?? []);\n for (const node of graph.nodes) {\n if (node.pinned) pinned.add(node.id);\n }\n return pinned;\n}\n\n/**\n * A placement in the canonical `(cross, rank)` frame, before it is turned into\n * world coordinates. `cross` and `rank` are the node's low corner along each.\n */\nexport interface Slot {\n cross: number;\n rank: number;\n}\n\n/**\n * Turn canonical slots into the positions to write: map the canonical frame\n * onto the world axes, translate the whole layout so it lands where the graph\n * already is, and drop everything that is pinned or that would not move.\n *\n * With a pin, the translation keeps the first pinned node exactly where it is.\n * Without one, it puts the layout's bounding box where the graph's already\n * starts, so a second run computes the same translation and writes nothing.\n */\nexport function settle(\n graph: Graph,\n slots: ReadonlyMap<string, Slot>,\n opts: LayoutOptions = {},\n): LayoutResult {\n const axes = axesFor(opts.direction);\n const pinned = pinnedSet(graph, opts);\n const tolerance = opts.tolerance ?? DEFAULT_TOLERANCE;\n\n const placed = new Map<string, Vec2>();\n for (const node of graph.nodes) {\n const slot = slots.get(node.id);\n if (slot === undefined) continue;\n const along = axes.sign === 1 ? slot.rank : -(slot.rank + extent(node.bounds, axes.rank));\n placed.set(\n node.id,\n axes.rank === 'y' ? { x: slot.cross, y: along } : { x: along, y: slot.cross },\n );\n }\n\n return translated(graph, placed, pinned, tolerance);\n}\n\n/**\n * Run `once` until a pass moves nothing, and answer with where that leaves\n * each node.\n *\n * A layout that keeps groups together can move an outsider out of a group's\n * column, which changes the order the next run would start from. `passes`\n * bounds an arrangement that never comes to rest.\n */\nexport function untilSettled(\n once: LayoutFn,\n graph: Graph,\n opts: LayoutOptions = {},\n passes = 8,\n): LayoutResult {\n const first = once(graph, opts);\n if (first.size === 0) return first;\n const at = new Map<string, Vec2>(first);\n for (let pass = 1; pass < passes; pass++) {\n const nodes = graph.nodes.map((node) => {\n const to = at.get(node.id);\n return to === undefined ? node : { ...node, bounds: { ...node.bounds, x: to.x, y: to.y } };\n });\n const byId = new Map(nodes.map((n) => [n.id, n]));\n const next = once({ ...graph, nodes, node: (id) => byId.get(id) }, opts);\n if (next.size === 0) break;\n for (const [id, to] of next) at.set(id, to);\n }\n const tolerance = opts.tolerance ?? DEFAULT_TOLERANCE;\n const out = new Map<string, Vec2>();\n for (const node of graph.nodes) {\n const to = at.get(node.id);\n if (to === undefined) continue;\n if (Math.abs(to.x - node.bounds.x) <= tolerance && Math.abs(to.y - node.bounds.y) <= tolerance) continue;\n out.set(node.id, to);\n }\n return out;\n}\n\n/**\n * {@link settle}'s second half, for a layout that already works in world\n * coordinates.\n */\nexport function translated(\n graph: Graph,\n placed: ReadonlyMap<string, Vec2>,\n pinned: ReadonlySet<string>,\n tolerance = DEFAULT_TOLERANCE,\n): LayoutResult {\n const anchor = anchorDelta(graph, placed, pinned);\n const out = new Map<string, Vec2>();\n for (const node of graph.nodes) {\n const at = placed.get(node.id);\n if (at === undefined || pinned.has(node.id)) continue;\n const x = at.x + anchor.x;\n const y = at.y + anchor.y;\n if (Math.abs(x - node.bounds.x) <= tolerance && Math.abs(y - node.bounds.y) <= tolerance) {\n continue;\n }\n out.set(node.id, { x, y });\n }\n return out;\n}\n\nfunction anchorDelta(\n graph: Graph,\n placed: ReadonlyMap<string, Vec2>,\n pinned: ReadonlySet<string>,\n): Vec2 {\n for (const node of graph.nodes) {\n if (!pinned.has(node.id)) continue;\n const at = placed.get(node.id);\n if (at !== undefined) return { x: node.bounds.x - at.x, y: node.bounds.y - at.y };\n }\n let minCurX = Infinity;\n let minCurY = Infinity;\n let minNewX = Infinity;\n let minNewY = Infinity;\n for (const node of graph.nodes) {\n const at = placed.get(node.id);\n if (at === undefined) continue;\n minCurX = Math.min(minCurX, node.bounds.x);\n minCurY = Math.min(minCurY, node.bounds.y);\n minNewX = Math.min(minNewX, at.x);\n minNewY = Math.min(minNewY, at.y);\n }\n if (!Number.isFinite(minCurX)) return { x: 0, y: 0 };\n return { x: minCurX - minNewX, y: minCurY - minNewY };\n}\n\n/**\n * Lay a list of nodes out along the cross axis, in the order given, and hand\n * back each one's low corner plus the total span.\n */\nexport function packAcross(\n nodes: readonly GraphNode[],\n axis: 'x' | 'y',\n gap: number,\n): { at: Map<string, number>; span: number } {\n const at = new Map<string, number>();\n let cursor = 0;\n for (const node of nodes) {\n at.set(node.id, cursor);\n cursor += extent(node.bounds, axis) + gap;\n }\n return { at, span: nodes.length === 0 ? 0 : cursor - gap };\n}\n\n/** Order within a rank: where the nodes already sit on the cross axis, with\n * graph order breaking a tie. Never a comparison that could reverse between\n * two runs on the same input. */\nexport function seededOrder(\n nodes: readonly GraphNode[],\n axis: 'x' | 'y',\n indexOf: (id: string) => number,\n): GraphNode[] {\n return [...nodes].sort((a, b) => {\n const d = center(a.bounds, axis) - center(b.bounds, axis);\n return d !== 0 ? d : indexOf(a.id) - indexOf(b.id);\n });\n}\n\n/** Each node's position in `graph.nodes`, for tiebreaks. */\nexport function graphOrder(graph: Graph): (id: string) => number {\n const index = new Map<string, number>();\n graph.nodes.forEach((node, i) => index.set(node.id, i));\n return (id) => index.get(id) ?? Number.MAX_SAFE_INTEGER;\n}\n","/**\n * Clusters: keeping a group's members together through a ranked layout.\n *\n * A group's box is the union of its members plus an inset, so the layout's job\n * is to leave a rectangle for it that nothing else enters. Each group gets a\n * **column** on the cross axis, reserved in every rank from its first member's\n * to its last — including a rank in between that holds none of its members, or\n * an outsider would land inside the box there. Groups keep one cross position\n * across every rank, so two groups' columns never cross and their boxes never\n * overlap. Ungrouped nodes pack around the columns rank by rank.\n *\n * A group may be a member of another: its column then sits inside its parent's.\n */\nimport type { Graph, GraphEdge, GraphGroup, GraphNode } from './graph';\nimport { extent, type LayoutAxes } from './layout';\n\n/** Room a group's box keeps around its members, in world units. */\nexport interface GroupInset {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\n/** A `DiagramGroup.inset` as all four sides. Default 12 on every side. */\nexport function insetOf(inset: number | Partial<GroupInset> | undefined): GroupInset {\n if (typeof inset === 'number') return { top: inset, right: inset, bottom: inset, left: inset };\n return {\n top: inset?.top ?? DEFAULT_GROUP_INSET,\n right: inset?.right ?? DEFAULT_GROUP_INSET,\n bottom: inset?.bottom ?? DEFAULT_GROUP_INSET,\n left: inset?.left ?? DEFAULT_GROUP_INSET,\n };\n}\n\n/** `DiagramGroup.inset`'s default on each side, in world units. */\nexport const DEFAULT_GROUP_INSET = 12;\n\n/** A group's inset turned into the canonical frame a layout works in. */\ninterface CanonicalInset {\n crossLo: number;\n crossHi: number;\n rankLo: number;\n rankHi: number;\n}\n\nfunction canonical(inset: GroupInset, axes: LayoutAxes): CanonicalInset {\n if (axes.rank === 'y') {\n return axes.sign === 1\n ? { crossLo: inset.left, crossHi: inset.right, rankLo: inset.top, rankHi: inset.bottom }\n : { crossLo: inset.left, crossHi: inset.right, rankLo: inset.bottom, rankHi: inset.top };\n }\n return axes.sign === 1\n ? { crossLo: inset.top, crossHi: inset.bottom, rankLo: inset.left, rankHi: inset.right }\n : { crossLo: inset.top, crossHi: inset.bottom, rankLo: inset.right, rankHi: inset.left };\n}\n\n/**\n * The gap between each rank and the next, widened so a group's box fits: the\n * widest inset of a group ending at rank `i` and of one starting at `i + 1`\n * both come on top of `rankGap`, since those two boxes can face each other\n * across it. A group's inset there includes that of any group nested in it\n * that ends, or starts, at the same rank. `rows` is the nodes of each rank.\n */\nexport function rankGaps(\n graph: Graph,\n rows: readonly (readonly GraphNode[])[],\n axes: LayoutAxes,\n rankGap: number,\n): number[] {\n const gaps = rows.slice(1).map(() => rankGap);\n const ends = new Map<number, number>();\n const starts = new Map<number, number>();\n const reach = (span: Span, side: 'lo' | 'hi'): number => {\n const own = canonical(span.group.inset, axes)[side === 'lo' ? 'rankLo' : 'rankHi'];\n const flush = span.children.filter((c) => c[side] === span[side]);\n return own + Math.max(0, ...flush.map((c) => reach(c, side)));\n };\n for (const span of groupSpans(graph, rows)) {\n ends.set(span.hi, Math.max(ends.get(span.hi) ?? 0, reach(span, 'hi')));\n starts.set(span.lo, Math.max(starts.get(span.lo) ?? 0, reach(span, 'lo')));\n }\n for (let i = 0; i < gaps.length; i++) {\n gaps[i] = Math.max(gaps[i]!, rankGap + (ends.get(i) ?? 0) + (starts.get(i + 1) ?? 0));\n }\n return gaps;\n}\n\n/** A group as the ranks see it: the ranks it reaches across, and the groups\n * nested directly in it. */\ninterface Span {\n group: GraphGroup;\n lo: number;\n hi: number;\n parent?: Span;\n children: Span[];\n}\n\nfunction groupSpans(graph: Graph, rows: readonly (readonly GraphNode[])[]): Span[] {\n const rankOf = new Map<string, number>();\n rows.forEach((row, i) => row.forEach((n) => rankOf.set(n.id, i)));\n const spans: Span[] = [];\n const byId = new Map<string, Span>();\n for (const group of graph.groups ?? []) {\n const ranks = group.members.map((id) => rankOf.get(id)).filter((r): r is number => r !== undefined);\n if (ranks.length === 0) continue;\n const span: Span = { group, lo: Math.min(...ranks), hi: Math.max(...ranks), children: [] };\n spans.push(span);\n byId.set(group.id, span);\n }\n for (const span of spans) {\n const parent = span.group.parent === undefined ? undefined : byId.get(span.group.parent);\n if (parent === undefined) continue;\n span.parent = parent;\n parent.children.push(span);\n }\n return spans;\n}\n\ntype Item =\n | { kind: 'node'; node: GraphNode; center: number }\n | { kind: 'group'; span: Span; center: number };\n\n/** A group's contents, packed: how wide they are, and where each node and\n * nested group starts from the group's inner low edge. */\ninterface Block {\n width: number;\n nodeAt: Map<string, number>;\n childAt: Map<Span, number>;\n}\n\n/**\n * Cross positions for every node, with each group's members kept in a column\n * of their own, and a nested group in a column inside its parent's.\n * `preferred` is where the layout would put each node's low corner with no\n * groups at all; nodes and columns keep that order and are only ever pushed\n * toward the high end, by as much as it takes to stop overlapping.\n */\nexport function packClusters(\n graph: Graph,\n rows: readonly (readonly GraphNode[])[],\n preferred: ReadonlyMap<string, number>,\n axes: LayoutAxes,\n nodeGap: number,\n): Map<string, number> {\n const spans = groupSpans(graph, rows);\n const spanById = new Map(spans.map((s) => [s.group.id, s]));\n const spanOf = (n: GraphNode): Span | undefined => (n.group === undefined ? undefined : spanById.get(n.group));\n const width = (n: GraphNode) => extent(n.bounds, axes.cross);\n const pref = (n: GraphNode) => preferred.get(n.id) ?? 0;\n const insets = new Map(spans.map((s) => [s, canonical(s.group.inset, axes)]));\n\n const centerOf = new Map<Span, number>();\n for (const span of spans) {\n const inside = new Set(span.group.members);\n let sum = 0;\n let count = 0;\n for (const row of rows) {\n for (const n of row) {\n if (!inside.has(n.id)) continue;\n sum += pref(n) + width(n) / 2;\n count++;\n }\n }\n centerOf.set(span, count === 0 ? 0 : sum / count);\n }\n\n /** What sits side by side in each rank at one level: the nodes directly in\n * `owner` and the groups directly in it, in the order of their centers. */\n const itemsByRow = (owner: Span | undefined, among: readonly Span[]): Item[][] =>\n rows.map((row, r) => {\n const items: Item[] = [];\n for (const node of row) {\n if (spanOf(node) === owner) items.push({ kind: 'node', node, center: pref(node) + width(node) / 2 });\n }\n for (const span of among) {\n if (r >= span.lo && r <= span.hi) items.push({ kind: 'group', span, center: centerOf.get(span)! });\n }\n // Stable, so equal centers keep the order the layout gave them.\n return items.map((item, i) => ({ item, i }))\n .sort((a, b) => a.item.center - b.item.center || a.i - b.i)\n .map(({ item }) => item);\n });\n\n /**\n * Walk each rank low to high, handing every node `nodeFloor` or the cursor,\n * whichever is higher, and every column its `start` or the cursor. Each pass\n * only ever raises a column's start, and a column is raised only by what\n * precedes it in some rank; the order is the same in every rank, so this\n * settles in at most one pass per column.\n */\n const settle = (\n byRow: readonly Item[][],\n start: Map<Span, number>,\n nodeFloor: (node: GraphNode) => number,\n origin: number,\n ): { nodeAt: Map<string, number>; ends: number[] } => {\n const nodeAt = new Map<string, number>();\n let ends: number[] = [];\n for (let pass = 0; pass <= start.size; pass++) {\n let raised = false;\n ends = byRow.map((items) => {\n let cursor = origin;\n for (const item of items) {\n if (item.kind === 'node') {\n const x = Math.max(nodeFloor(item.node), cursor);\n nodeAt.set(item.node.id, x);\n cursor = x + width(item.node) + nodeGap;\n continue;\n }\n const s = start.get(item.span)!;\n const x = Math.max(s, cursor);\n if (x > s) {\n start.set(item.span, x);\n raised = true;\n }\n cursor = x + outer(item.span) + nodeGap;\n }\n return items.length === 0 ? origin : cursor - nodeGap;\n });\n if (!raised) break;\n }\n return { nodeAt, ends };\n };\n\n const blocks = new Map<Span, Block>();\n const blockOf = (span: Span): Block => {\n const known = blocks.get(span);\n if (known !== undefined) return known;\n const byRow = itemsByRow(span, span.children);\n const childAt = new Map<Span, number>(span.children.map((c) => [c, 0]));\n const { nodeAt, ends } = settle(byRow, childAt, () => 0, 0);\n const block: Block = { width: Math.max(0, ...ends), nodeAt, childAt };\n // A rank no nested column passes through is free to sit in the middle.\n byRow.forEach((items, r) => {\n if (items.some((item) => item.kind === 'group')) return;\n const shift = (block.width - ends[r]!) / 2;\n for (const item of items) {\n if (item.kind === 'node') nodeAt.set(item.node.id, nodeAt.get(item.node.id)! + shift);\n }\n });\n blocks.set(span, block);\n return block;\n };\n function outer(span: Span): number {\n const inset = insets.get(span)!;\n return blockOf(span).width + inset.crossLo + inset.crossHi;\n }\n\n const roots = spans.filter((s) => s.parent === undefined);\n const start = new Map<Span, number>(roots.map((s) => [s, centerOf.get(s)! - outer(s) / 2]));\n const { nodeAt: at } = settle(itemsByRow(undefined, roots), start, pref, -Infinity);\n\n const place = (span: Span, from: number): void => {\n const origin = from + insets.get(span)!.crossLo;\n const block = blockOf(span);\n for (const [id, local] of block.nodeAt) at.set(id, origin + local);\n for (const [child, local] of block.childAt) place(child, origin + local);\n };\n for (const root of roots) place(root, start.get(root)!);\n return at;\n}\n\n/**\n * Edges as a layout should rank by: one into a group arrives at its entry\n * members — those no other member points at — and one out of it leaves from its\n * exit members. A group with no such member, a pure cycle, is all entries and\n * all exits. An edge between a group and something inside it, a member or a\n * nested group, is that group's internal business and ranks nothing beyond\n * what its member-to-member edges already do.\n */\nexport function expandGroupEdges(\n edges: readonly GraphEdge[],\n groups: readonly GraphGroup[],\n): GraphEdge[] {\n const byId = new Map(groups.map((g) => [g.id, g]));\n if (byId.size === 0) return [...edges];\n /** Whether `id`, a node or a group, is `group` or somewhere inside it. */\n const within = (id: string, group: GraphGroup): boolean => {\n if (!byId.has(id)) return group.members.includes(id);\n for (let at = byId.get(id); at !== undefined; at = at.parent === undefined ? undefined : byId.get(at.parent)) {\n if (at === group) return true;\n }\n return false;\n };\n\n const entries = new Map<string, readonly string[]>();\n const exits = new Map<string, readonly string[]>();\n for (const g of groups) {\n const inside = new Set(g.members);\n const pointedAt = new Set<string>();\n const pointing = new Set<string>();\n for (const e of edges) {\n if (inside.has(e.from) && inside.has(e.to) && e.from !== e.to) {\n pointedAt.add(e.to);\n pointing.add(e.from);\n }\n }\n const entry = g.members.filter((m) => !pointedAt.has(m));\n const exit = g.members.filter((m) => !pointing.has(m));\n entries.set(g.id, entry.length > 0 ? entry : g.members);\n exits.set(g.id, exit.length > 0 ? exit : g.members);\n }\n\n const out: GraphEdge[] = [];\n for (const e of edges) {\n const fromGroup = byId.has(e.from) ? e.from : undefined;\n const toGroup = byId.has(e.to) ? e.to : undefined;\n if (fromGroup === undefined && toGroup === undefined) {\n out.push(e);\n continue;\n }\n if (fromGroup !== undefined && within(e.to, byId.get(fromGroup)!)) continue;\n if (toGroup !== undefined && within(e.from, byId.get(toGroup)!)) continue;\n const froms = fromGroup !== undefined ? exits.get(fromGroup)! : [e.from];\n const tos = toGroup !== undefined ? entries.get(toGroup)! : [e.to];\n let k = 0;\n for (const from of froms) {\n for (const to of tos) out.push({ id: `${e.id}#${k++}`, from, to });\n }\n }\n return out;\n}\n","/**\n * What a group adds to the relaxation in `force.ts`: its members drawn\n * together, and its box kept clear of everything that is not in it.\n *\n * A group is its members and nothing else here — the box is recomputed from\n * where they are on every tick, the way the scene derives it: around its own\n * nodes and the boxes of the groups nested in it.\n */\nimport type { SimulationForce } from '@weasel-js/simulation';\nimport type { GraphGroup } from './graph';\nimport type { ForceBody } from './force';\n\ninterface GroupBodies {\n /** Every body inside, through any nested group. */\n members: ForceBody[];\n group: GraphGroup;\n parent?: GroupBodies;\n children: GroupBodies[];\n}\n\ninterface Box { x0: number; y0: number; x1: number; y1: number }\n\nfunction resolve(groups: readonly GraphGroup[], byId: ReadonlyMap<string, ForceBody>): GroupBodies[] {\n const out: GroupBodies[] = [];\n for (const group of groups) {\n const members = group.members.map((id) => byId.get(id)).filter((b) => b !== undefined);\n if (members.length > 0) out.push({ members, group, children: [] });\n }\n const byGroup = new Map(out.map((g) => [g.group.id, g]));\n for (const g of out) {\n const parent = g.group.parent === undefined ? undefined : byGroup.get(g.group.parent);\n if (parent === undefined) continue;\n g.parent = parent;\n parent.children.push(g);\n }\n return out;\n}\n\n/** A pull on each member toward its group's centroid. */\nexport function groupCohesion(\n groups: readonly GraphGroup[],\n byId: ReadonlyMap<string, ForceBody>,\n strength: number,\n): SimulationForce<ForceBody> {\n const resolved = resolve(groups, byId);\n return (alpha) => {\n for (const { members } of resolved) {\n let cx = 0;\n let cy = 0;\n for (const m of members) {\n cx += m.x;\n cy += m.y;\n }\n cx /= members.length;\n cy /= members.length;\n for (const m of members) {\n m.vx! += (cx - m.x) * strength * alpha;\n m.vy! += (cy - m.y) * strength * alpha;\n }\n }\n };\n}\n\n/** The box of `g`: around its bodies and its nested groups' boxes, grown by\n * its inset. A body inside a nested group is covered by that group's box. */\nfunction boxOf(g: GroupBodies): Box {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const m of g.members) {\n x0 = Math.min(x0, m.x - m.hw);\n y0 = Math.min(y0, m.y - m.hh);\n x1 = Math.max(x1, m.x + m.hw);\n y1 = Math.max(y1, m.y + m.hh);\n }\n for (const child of g.children) {\n const b = boxOf(child);\n x0 = Math.min(x0, b.x0);\n y0 = Math.min(y0, b.y0);\n x1 = Math.max(x1, b.x1);\n y1 = Math.max(y1, b.y1);\n }\n const { inset } = g.group;\n return { x0: x0 - inset.left, y0: y0 - inset.top, x1: x1 + inset.right, y1: y1 + inset.bottom };\n}\n\n/** How far `b` has to move to clear `a` by `padding`, along whichever axis is\n * shorter, or `null` when they are already clear. */\nfunction clearance(a: Box, b: Box, padding: number): { x: number; y: number } | null {\n const gapX = Math.min(a.x1, b.x1) - Math.max(a.x0, b.x0) + padding;\n const gapY = Math.min(a.y1, b.y1) - Math.max(a.y0, b.y0) + padding;\n if (gapX <= 0 || gapY <= 0) return null;\n const dx = (b.x0 + b.x1) - (a.x0 + a.x1);\n const dy = (b.y0 + b.y1) - (a.y0 + a.y1);\n return gapX < gapY\n ? { x: (Math.sign(dx) || 1) * gapX, y: 0 }\n : { x: 0, y: (Math.sign(dy) || 1) * gapY };\n}\n\n/** Whether `inner` is nested somewhere inside `outer`. */\nfunction holds(outer: GroupBodies, inner: GroupBodies): boolean {\n for (let at = inner.parent; at !== undefined; at = at.parent) {\n if (at === outer) return true;\n }\n return false;\n}\n\nfunction shove(bodies: readonly ForceBody[], x: number, y: number): void {\n for (const body of bodies) {\n body.vx! += x;\n body.vy! += y;\n }\n}\n\n/**\n * Push a group's box clear of every other group's and of every body outside\n * it, moving the group as a block. Like the box separation between nodes it is\n * not scaled by alpha: an overlap at the end of the run is as wrong as one at\n * the start.\n */\nexport function separateGroups(\n groups: readonly GraphGroup[],\n bodies: readonly ForceBody[],\n byId: ReadonlyMap<string, ForceBody>,\n padding: number,\n): SimulationForce<ForceBody> {\n const resolved = resolve(groups, byId);\n const memberSets = resolved.map((g) => new Set(g.members));\n return () => {\n const boxes = resolved.map(boxOf);\n for (let i = 0; i < resolved.length; i++) {\n for (let j = i + 1; j < resolved.length; j++) {\n if (holds(resolved[i]!, resolved[j]!) || holds(resolved[j]!, resolved[i]!)) continue;\n const push = clearance(boxes[i]!, boxes[j]!, padding);\n if (push === null) continue;\n shove(resolved[i]!.members, -push.x / 2, -push.y / 2);\n shove(resolved[j]!.members, push.x / 2, push.y / 2);\n }\n for (const body of bodies) {\n if (memberSets[i]!.has(body)) continue;\n const box = { x0: body.x - body.hw, y0: body.y - body.hh, x1: body.x + body.hw, y1: body.y + body.hh };\n const push = clearance(boxes[i]!, box, padding);\n if (push === null) continue;\n shove(resolved[i]!.members, -push.x / 2, -push.y / 2);\n body.vx! += push.x / 2;\n body.vy! += push.y / 2;\n }\n }\n };\n}\n","/**\n * `force` — relaxation, for a graph with no direction to read it in.\n *\n * Seeded from where the nodes already are rather than from a fresh random\n * scatter: an author who has arranged half a diagram gets that arrangement\n * relaxed, not replaced. There is no RNG in it at all — two coincident nodes\n * are separated along a golden-angle spiral keyed to their index.\n *\n * The forces are the naive O(n²) kind — right for tens to hundreds of nodes,\n * wrong for a 10k-node graph.\n *\n * **This is the one layout that is not idempotent.** A relaxation re-run from\n * its own output keeps relaxing; `direction` means nothing to it. Pins and the\n * `tolerance` option are what keep a second pass from scrambling a settled\n * diagram.\n */\nimport { createSimulation, type SimulationForce, type SimulationNode } from '@weasel-js/simulation';\nimport type { Graph } from './graph';\nimport { groupCohesion, separateGroups } from './forceGroups';\nimport {\n center,\n pinnedSet,\n translated,\n type LayoutFn,\n type LayoutOptions,\n type LayoutResult,\n} from './layout';\n\n/** Options for {@link force} and {@link forceRelaxation}. `direction` is\n * ignored. */\nexport interface ForceOptions extends LayoutOptions {\n /** Ticks to run. Default 300 — one full cooling schedule. */\n iterations?: number;\n /** Rest length of an edge, in world units. Default 160. */\n linkDistance?: number;\n /** How hard an edge pulls, 0..1. Default 0.35. */\n linkStrength?: number;\n /** Pairwise repulsion. Negative repels; default -3000. */\n charge?: number;\n /** How hard the graph is held around its own centroid. Default 0.02. */\n gravity?: number;\n /** Clear space kept between two boxes, in world units. Default 24. */\n padding?: number;\n /** How hard a group draws its members together, 0..1. Default 0.2. */\n groupStrength?: number;\n}\n\n/** One node as the relaxation sees it: a simulation point centered on the\n * node's box. */\nexport interface ForceBody extends SimulationNode {\n id: string;\n /** Half the node's box, so separation can work on the shape the author sees\n * rather than on a point. */\n hw: number;\n hh: number;\n}\n\nconst DEFAULTS = {\n iterations: 300,\n linkDistance: 160,\n linkStrength: 0.35,\n charge: -3000,\n gravity: 0.02,\n padding: 24,\n groupStrength: 0.2,\n} as const;\n\n/** The golden angle. Coincident nodes fan out along it, which spreads any\n * number of them without two landing on the same heading. */\nconst GOLDEN = Math.PI * (3 - Math.sqrt(5));\n/** How far the first coincident node is pushed, in world units. Small enough\n * to be invisible, large enough that the repulsion term is finite. */\nconst NUDGE = 0.5;\n\n/** Pairwise repulsion, applied to every pair once. */\nfunction charge(bodies: readonly ForceBody[], strength: number): SimulationForce<ForceBody> {\n return (alpha) => {\n for (let i = 0; i < bodies.length; i++) {\n const a = bodies[i]!;\n for (let j = i + 1; j < bodies.length; j++) {\n const b = bodies[j]!;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const d2 = dx * dx + dy * dy;\n if (d2 === 0) continue;\n const w = (strength * alpha) / d2;\n a.vx! += dx * w;\n a.vy! += dy * w;\n b.vx! -= dx * w;\n b.vy! -= dy * w;\n }\n }\n };\n}\n\n/** A spring per edge, pulling both ends toward `distance`. */\nfunction links(\n bodies: ReadonlyMap<string, ForceBody>,\n graph: Graph,\n distance: number,\n strength: number,\n): SimulationForce<ForceBody> {\n return (alpha) => {\n for (const edge of graph.edges) {\n const a = bodies.get(edge.from);\n const b = bodies.get(edge.to);\n if (a === undefined || b === undefined || a === b) continue;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const d = Math.hypot(dx, dy);\n if (d === 0) continue;\n const pull = ((d - distance) / d) * alpha * strength;\n a.vx! += dx * pull;\n a.vy! += dy * pull;\n b.vx! -= dx * pull;\n b.vy! -= dy * pull;\n }\n };\n}\n\n/**\n * Push overlapping boxes apart along whichever axis they overlap least.\n *\n * Charge alone is not enough: it treats a node as a point, so two wide boxes\n * whose centers are a comfortable distance apart still cover each other. Not\n * scaled by alpha — an overlap at the end of the run is exactly as wrong as\n * one at the start.\n */\nfunction separateBoxes(bodies: readonly ForceBody[], padding: number): SimulationForce<ForceBody> {\n return () => {\n for (let i = 0; i < bodies.length; i++) {\n const a = bodies[i]!;\n for (let j = i + 1; j < bodies.length; j++) {\n const b = bodies[j]!;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const gapX = a.hw + b.hw + padding - Math.abs(dx);\n const gapY = a.hh + b.hh + padding - Math.abs(dy);\n if (gapX <= 0 || gapY <= 0) continue;\n if (gapX < gapY) {\n const push = (Math.sign(dx) || 1) * gapX * 0.5;\n a.vx! -= push;\n b.vx! += push;\n } else {\n const push = (Math.sign(dy) || 1) * gapY * 0.5;\n a.vy! -= push;\n b.vy! += push;\n }\n }\n }\n };\n}\n\n/** A pull toward the seed centroid, so a component with nothing to hold it\n * does not drift off under pure repulsion. */\nfunction gravity(bodies: readonly ForceBody[], at: { x: number; y: number }, strength: number): SimulationForce<ForceBody> {\n return (alpha) => {\n for (const body of bodies) {\n body.vx! += (at.x - body.x) * strength * alpha;\n body.vy! += (at.y - body.y) * strength * alpha;\n }\n };\n}\n\n/**\n * The bodies and the force list, wound up and ready to tick.\n */\nexport interface ForceRelaxation {\n bodies: ForceBody[];\n byId: Map<string, ForceBody>;\n /** Ids the caller must not move: declared pins, held as `fx`/`fy`. */\n pinned: ReadonlySet<string>;\n sim: ReturnType<typeof createSimulation<ForceBody>>;\n /** Where a body's node's top-left sits, given the body's center. */\n placed(): Map<string, { x: number; y: number }>;\n}\n\n/** Wind up a relaxation of `graph` without ticking it: bodies seeded from\n * where the nodes are, pins held fixed. Tick `sim` yourself and read the\n * top-lefts from `placed()`. */\nexport function forceRelaxation(graph: Graph, opts: ForceOptions = {}): ForceRelaxation {\n const {\n linkDistance = DEFAULTS.linkDistance,\n linkStrength = DEFAULTS.linkStrength,\n charge: chargeStrength = DEFAULTS.charge,\n gravity: gravityStrength = DEFAULTS.gravity,\n padding = DEFAULTS.padding,\n groupStrength = DEFAULTS.groupStrength,\n } = opts;\n\n const pinned = pinnedSet(graph, opts);\n const bodies: ForceBody[] = graph.nodes.map((node) => {\n const body: ForceBody = {\n id: node.id,\n x: center(node.bounds, 'x'),\n y: center(node.bounds, 'y'),\n hw: node.bounds.width / 2,\n hh: node.bounds.height / 2,\n };\n // A pin is the integrator's own `fx`/`fy`, not a filter applied after the\n // fact: a pinned node has to hold its neighbors while they relax.\n if (pinned.has(node.id)) {\n body.fx = body.x;\n body.fy = body.y;\n }\n return body;\n });\n separate(bodies);\n\n const byId = new Map(bodies.map((b) => [b.id, b]));\n const centroid = {\n x: bodies.reduce((sum, b) => sum + b.x, 0) / bodies.length,\n y: bodies.reduce((sum, b) => sum + b.y, 0) / bodies.length,\n };\n\n const groups = graph.groups ?? [];\n const sim = createSimulation<ForceBody>({\n nodes: bodies,\n forces: [\n charge(bodies, chargeStrength),\n links(byId, graph, linkDistance, linkStrength),\n gravity(bodies, centroid, gravityStrength),\n separateBoxes(bodies, padding),\n ...(groups.length > 0\n ? [groupCohesion(groups, byId, groupStrength), separateGroups(groups, bodies, byId, padding)]\n : []),\n ],\n });\n\n return {\n bodies,\n byId,\n pinned,\n sim,\n placed() {\n const placed = new Map<string, { x: number; y: number }>();\n for (const node of graph.nodes) {\n const body = byId.get(node.id)!;\n placed.set(node.id, {\n x: body.x - node.bounds.width / 2,\n y: body.y - node.bounds.height / 2,\n });\n }\n return placed;\n },\n };\n}\n\n/** The force-directed layout. Unlike the others it is not idempotent: a\n * re-run keeps relaxing, so pins and `tolerance` are what hold a settled\n * diagram still. */\nexport const force = (graph: Graph, opts: ForceOptions = {}): LayoutResult => {\n if (graph.nodes.length === 0) return new Map();\n const relaxation = forceRelaxation(graph, opts);\n relaxation.sim.tick(opts.iterations ?? DEFAULTS.iterations);\n return translated(graph, relaxation.placed(), relaxation.pinned, opts.tolerance);\n};\n\n/** `ForceOptions` only widens `LayoutOptions`, so this is a `LayoutFn` — but\n * declaring it as one would hide the extra options from every caller. */\nforce satisfies LayoutFn;\n\n/** Push coincident bodies apart, deterministically. Two nodes at exactly the\n * same point feel no repulsion from each other and stay stacked forever. A\n * pinned body is counted but never moved — a pin outranks this. */\nfunction separate(bodies: ForceBody[]): void {\n const seen = new Map<string, number>();\n bodies.forEach((body, i) => {\n const key = `${body.x},${body.y}`;\n const nth = seen.get(key) ?? 0;\n seen.set(key, nth + 1);\n if (nth === 0 || body.fx != null || body.fy != null) return;\n const angle = GOLDEN * i;\n const radius = NUDGE * nth;\n body.x += Math.cos(angle) * radius;\n body.y += Math.sin(angle) * radius;\n });\n}\n","/**\n * Barycenter crossing reduction: each node moves to the mean position of its\n * neighbors in the adjacent rank, sweeping down then up a fixed number of\n * times. Ties keep the current order, so the result is a function of the\n * input order alone.\n */\nimport type { Graph, GraphNode } from './graph';\n\nconst SWEEPS = 4;\n\nexport function barycenterOrder(\n graph: Graph,\n rows: GraphNode[][],\n back: ReadonlySet<string>,\n): GraphNode[][] {\n const out = rows.map((row) => [...row]);\n const index = new Map<string, number>();\n const reindex = (row: GraphNode[]) => row.forEach((n, i) => index.set(n.id, i));\n out.forEach(reindex);\n\n const reorder = (row: GraphNode[], neighbors: (id: string) => string[]) => {\n const key = new Map<string, number>();\n for (const [i, n] of row.entries()) {\n const at = neighbors(n.id).map((id) => index.get(id)).filter((v): v is number => v !== undefined);\n key.set(n.id, at.length === 0 ? i : at.reduce((s, v) => s + v, 0) / at.length);\n }\n row.sort((a, b) => key.get(a.id)! - key.get(b.id)! || index.get(a.id)! - index.get(b.id)!);\n reindex(row);\n };\n\n const ups = (id: string) => graph.incoming(id).filter((e) => !back.has(e.id)).map((e) => e.from);\n const downs = (id: string) => graph.outgoing(id).filter((e) => !back.has(e.id)).map((e) => e.to);\n for (let s = 0; s < SWEEPS; s++) {\n for (let r = 1; r < out.length; r++) reorder(out[r]!, ups);\n for (let r = out.length - 2; r >= 0; r--) reorder(out[r]!, downs);\n }\n return out;\n}\n","/**\n * `layered` — ranks running one way, nodes running across.\n *\n * The flowchart / pipeline layout: an edge points from one rank to the next.\n * Ranks come from longest-path layering, which puts every node as far along as\n * its deepest predecessor allows.\n *\n * Cycles do not disqualify a graph. A depth-first walk in graph order names the\n * edges that close a cycle, layering ignores those, and they draw as edges\n * running back up the page. Which edges get named depends only on the node\n * order, so it is the same every run.\n *\n * This is not crossing-minimization by default (`order: 'barycenter'` does\n * reorder ranks): within a rank, nodes keep the order they already have on\n * the cross axis.\n */\nimport { barycenterOrder } from './barycenter';\nimport { packClusters, rankGaps } from './cluster';\nimport type { Graph, GraphNode } from './graph';\nimport {\n DEFAULT_NODE_GAP,\n DEFAULT_RANK_GAP,\n axesFor,\n extent,\n graphOrder,\n packAcross,\n seededOrder,\n settle,\n untilSettled,\n type LayoutFn,\n type Slot,\n} from './layout';\n\n/** Edge ids that close a cycle, found by a depth-first walk in graph order. */\nexport function backEdges(graph: Graph): Set<string> {\n const back = new Set<string>();\n const done = new Set<string>();\n const onStack = new Set<string>();\n\n const walk = (id: string): void => {\n if (done.has(id)) return;\n onStack.add(id);\n for (const edge of graph.outgoing(id)) {\n if (onStack.has(edge.to)) back.add(edge.id);\n else walk(edge.to);\n }\n onStack.delete(id);\n done.add(id);\n };\n\n for (const node of graph.nodes) walk(node.id);\n return back;\n}\n\n/** Longest-path rank per node: one past its deepest predecessor. */\nexport function ranksOf(graph: Graph, back: ReadonlySet<string>): Map<string, number> {\n const ranks = new Map<string, number>();\n const resolving = new Set<string>();\n\n const rankOf = (id: string): number => {\n const known = ranks.get(id);\n if (known !== undefined) return known;\n // Only reachable if `back` missed an edge; guarding here keeps a bad\n // cycle-breaker from recursing forever rather than reporting a wrong rank.\n if (resolving.has(id)) return 0;\n resolving.add(id);\n let rank = 0;\n for (const edge of graph.incoming(id)) {\n if (back.has(edge.id)) continue;\n rank = Math.max(rank, rankOf(edge.from) + 1);\n }\n resolving.delete(id);\n ranks.set(id, rank);\n return rank;\n };\n\n for (const node of graph.nodes) rankOf(node.id);\n return ranks;\n}\n\n/** The ranked layout: each edge points one rank further along `direction`.\n * Within a rank, nodes keep their current cross-axis order, so a re-run\n * moves nothing — except under `order: 'barycenter'`, which reorders them. */\nexport const layered: LayoutFn = (graph, opts = {}) =>\n // Barycenter ordering reorders on every run by design, so it has no\n // arrangement to settle on.\n ((graph.groups?.length ?? 0) > 0 && opts.order !== 'barycenter'\n ? untilSettled(layeredOnce, graph, opts)\n : layeredOnce(graph, opts));\n\nconst layeredOnce: LayoutFn = (graph, opts = {}) => {\n const axes = axesFor(opts.direction);\n const nodeGap = opts.nodeGap ?? DEFAULT_NODE_GAP;\n const rankGap = opts.rankGap ?? DEFAULT_RANK_GAP;\n const order = graphOrder(graph);\n\n const back = backEdges(graph);\n const ranks = ranksOf(graph, back);\n const byRank = new Map<number, GraphNode[]>();\n for (const node of graph.nodes) {\n const rank = ranks.get(node.id) ?? 0;\n const list = byRank.get(rank);\n if (list === undefined) byRank.set(rank, [node]);\n else list.push(node);\n }\n\n const rows = [...byRank.keys()].sort((a, b) => a - b);\n let ordered = rows.map((rank) => seededOrder(byRank.get(rank)!, axes.cross, order));\n if (opts.order === 'barycenter') ordered = barycenterOrder(graph, ordered, back);\n const packed = ordered.map((row) => packAcross(row, axes.cross, nodeGap));\n const widest = Math.max(0, ...packed.map((p) => p.span));\n const preferred = new Map<string, number>();\n for (const [i, row] of ordered.entries()) {\n const indent = (widest - packed[i]!.span) / 2;\n for (const node of row) preferred.set(node.id, indent + packed[i]!.at.get(node.id)!);\n }\n const grouped = (graph.groups?.length ?? 0) > 0;\n const crossAt = grouped ? packClusters(graph, ordered, preferred, axes, nodeGap) : preferred;\n const gaps = grouped ? rankGaps(graph, ordered, axes, rankGap) : ordered.slice(1).map(() => rankGap);\n\n const slots = new Map<string, Slot>();\n let along = 0;\n for (const [i, row] of ordered.entries()) {\n const depth = Math.max(0, ...row.map((n) => extent(n.bounds, axes.rank)));\n for (const node of row) {\n slots.set(node.id, {\n cross: crossAt.get(node.id)!,\n // Centered in its rank's band, so a tall node does not push its\n // neighbors' edges off the line they read along.\n rank: along + (depth - extent(node.bounds, axes.rank)) / 2,\n });\n }\n along += depth + (gaps[i] ?? 0);\n }\n\n return settle(graph, slots, opts);\n};\n","/**\n * `tree` — a parent centered over the block its children occupy.\n *\n * The hierarchy layout: org charts, file trees, decision trees. Depth is the\n * rank axis, so every child sits one band past its parent, and a subtree is\n * packed as a solid block so two siblings' descendants never interleave.\n *\n * A graph that is not a tree still lays out. Roots are the nodes nothing points\n * at, in graph order; a node reachable from two parents belongs to whichever\n * the depth-first walk reaches first; and anything the walk never reaches — a\n * disconnected part, or a pure cycle — becomes a root of its own. So the answer\n * is always a forest, and which forest depends only on the node order.\n *\n * The block packing is deliberately not Reingold–Tilford: it never slides a\n * deep subtree under a shallow neighbor's overhang. That costs horizontal\n * space and buys an invariant an author can rely on — a subtree's extent is a\n * rectangle, and dragging one never lands it inside another.\n */\nimport { packClusters, rankGaps } from './cluster';\nimport type { Graph, GraphNode } from './graph';\nimport {\n DEFAULT_NODE_GAP,\n DEFAULT_RANK_GAP,\n axesFor,\n extent,\n graphOrder,\n seededOrder,\n settle,\n untilSettled,\n type LayoutFn,\n type Slot,\n} from './layout';\n\n/** A graph read as trees: its roots, each node's children in order, and each node's depth. */\nexport interface Forest {\n roots: GraphNode[];\n children: Map<string, GraphNode[]>;\n depth: Map<string, number>;\n}\n\n/** The forest a depth-first walk in graph order finds. Exported because \"which\n * node ended up whose child\" is the question anyone debugging a tree layout\n * asks first. */\nexport function forestOf(graph: Graph, crossAxis: 'x' | 'y'): Forest {\n const order = graphOrder(graph);\n const children = new Map<string, GraphNode[]>();\n const depth = new Map<string, number>();\n const roots: GraphNode[] = [];\n\n const claim = (node: GraphNode, at: number): void => {\n depth.set(node.id, at);\n const kids: GraphNode[] = [];\n for (const edge of graph.outgoing(node.id)) {\n if (edge.to === node.id || depth.has(edge.to)) continue;\n const child = graph.node(edge.to);\n if (child === undefined) continue;\n // Claimed on sight rather than inside the recursion, so two siblings\n // sharing a descendant cannot both take it.\n depth.set(child.id, at + 1);\n kids.push(child);\n }\n const ordered = seededOrder(kids, crossAxis, order);\n children.set(node.id, ordered);\n for (const child of ordered) claim(child, at + 1);\n };\n\n const rootish = graph.nodes.filter((node) =>\n graph.incoming(node.id).every((edge) => edge.from === node.id));\n for (const node of seededOrder(rootish, crossAxis, order)) {\n if (depth.has(node.id)) continue;\n roots.push(node);\n claim(node, 0);\n }\n // Whatever the walk could not reach: a disconnected part, or a component\n // every node of which is inside a cycle.\n for (const node of graph.nodes) {\n if (depth.has(node.id)) continue;\n roots.push(node);\n claim(node, 0);\n }\n\n return { roots, children, depth };\n}\n\n/** The hierarchy layout: each parent centered over its children's block, one\n * rank per depth. A graph that is not a tree lays out as the forest\n * {@link forestOf} reads from it. */\nexport const tree: LayoutFn = (graph, opts = {}) =>\n ((graph.groups?.length ?? 0) > 0 ? untilSettled(treeOnce, graph, opts) : treeOnce(graph, opts));\n\nconst treeOnce: LayoutFn = (graph, opts = {}) => {\n const axes = axesFor(opts.direction);\n const nodeGap = opts.nodeGap ?? DEFAULT_NODE_GAP;\n const rankGap = opts.rankGap ?? DEFAULT_RANK_GAP;\n const { roots, children, depth } = forestOf(graph, axes.cross);\n\n const bands = new Map<number, number>();\n for (const node of graph.nodes) {\n const at = depth.get(node.id) ?? 0;\n bands.set(at, Math.max(bands.get(at) ?? 0, extent(node.bounds, axes.rank)));\n }\n const depths = [...bands.keys()].sort((a, b) => a - b);\n const rowsAt = depths.map((at) => graph.nodes.filter((n) => (depth.get(n.id) ?? 0) === at));\n const grouped = (graph.groups?.length ?? 0) > 0;\n const gaps = grouped ? rankGaps(graph, rowsAt, axes, rankGap) : depths.slice(1).map(() => rankGap);\n const bandStart = new Map<number, number>();\n let along = 0;\n for (const [i, at] of depths.entries()) {\n bandStart.set(at, along);\n along += bands.get(at)! + (gaps[i] ?? 0);\n }\n\n const slots = new Map<string, Slot>();\n\n /** How wide `node`'s whole subtree is on the cross axis: its children's\n * blocks side by side, or the node itself when that is wider. */\n const measured = new Map<string, number>();\n const measure = (node: GraphNode): number => {\n const known = measured.get(node.id);\n if (known !== undefined) return known;\n const kids = children.get(node.id) ?? [];\n let width = 0;\n for (const child of kids) width += measure(child);\n if (kids.length > 0) width += nodeGap * (kids.length - 1);\n const block = Math.max(extent(node.bounds, axes.cross), width);\n measured.set(node.id, block);\n return block;\n };\n\n /** Place `node`'s subtree with its block starting at `from`. */\n const place = (node: GraphNode, from: number): void => {\n const kids = children.get(node.id) ?? [];\n const block = measure(node);\n const width = kids.reduce((sum, k) => sum + measure(k), 0)\n + Math.max(0, kids.length - 1) * nodeGap;\n\n let cursor = from + (block - width) / 2;\n for (const child of kids) {\n place(child, cursor);\n cursor += measure(child) + nodeGap;\n }\n\n const own = extent(node.bounds, axes.cross);\n const at = depth.get(node.id) ?? 0;\n slots.set(node.id, {\n cross: from + (block - own) / 2,\n rank: bandStart.get(at)! + (bands.get(at)! - extent(node.bounds, axes.rank)) / 2,\n });\n };\n\n let cursor = 0;\n for (const root of roots) {\n place(root, cursor);\n cursor += measure(root) + nodeGap;\n }\n\n if (grouped) {\n // The subtree blocks are where each node would go; groups then push them\n // apart only as far as their columns need.\n const preferred = new Map([...slots].map(([id, slot]) => [id, slot.cross]));\n const ordered = rowsAt.map((row) => [...row].sort((a, b) => preferred.get(a.id)! - preferred.get(b.id)!));\n const crossAt = packClusters(graph, ordered, preferred, axes, nodeGap);\n for (const [id, slot] of slots) slots.set(id, { ...slot, cross: crossAt.get(id) ?? slot.cross });\n }\n\n return settle(graph, slots, opts);\n};\n"]}