mermaid
Version:
Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.
8 lines • 648 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../src/rendering-util/createGraph.ts", "../../../src/rendering-util/rendering-elements/lineJump.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/adjustLayout.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/helpers.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/edgeLabelNodes.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/geometry.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/endpointClip.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/lrTransform.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/portSwap.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/terminalStub.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/materializedGeometry.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/detourSimplification.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/labelAnchoring.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/siblingSharedFaceRouting.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/sharedTrackNudging.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/direction/validation.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/postProcessing.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase0.helpers.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase1.cycles.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.options.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/config.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/driving-tree.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.crossCounts.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.multitree.core.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.multitree.order.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.crossOptimization.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.crossLaneAdjust.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.longestPath.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.gravity.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.laneAwareCompact.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase2.dummies.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase3.ordering.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/phase4.coordinates.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/laneOrdering.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/pipeline.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/orthogonalRouter/router.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/layoutCore.ts", "../../../src/rendering-util/layout-algorithms/swimlanes/index.ts"],
"sourcesContent": ["import type { Selection } from 'd3';\nimport * as graphlib from 'dagre-d3-es/src/graphlib/index.js';\nimport type { LayoutData } from './types.js';\nimport { getConfig } from '../diagram-api/diagramAPI.js';\nimport { insertNode } from './rendering-elements/nodes.js';\n\n// Update type:\ntype D3Selection<T extends SVGElement = SVGElement> = Selection<\n T,\n unknown,\n Element | null,\n unknown\n>;\n\n/**\n * Creates a graph by merging the graph construction and DOM element insertion.\n *\n * This function creates the graph, inserts the SVG groups (clusters, edgePaths, edgeLabels, nodes)\n * into the provided element, and uses `insertNode` to add nodes to the diagram. Node dimensions\n * are computed using each node's bounding box.\n *\n * @param element - The D3 selection in which the SVG groups are inserted.\n * @param data4Layout - The layout data containing nodes and edges.\n * @returns A promise resolving to an object containing the graph and the inserted groups.\n */\nexport async function createGraphWithElements(\n element: D3Selection,\n data4Layout: LayoutData\n): Promise<{\n graph: graphlib.Graph;\n groups: {\n clusters: D3Selection<SVGGElement>;\n edgePaths: D3Selection<SVGGElement>;\n edgeLabels: D3Selection<SVGGElement>;\n nodes: D3Selection<SVGGElement>;\n rootGroups: D3Selection<SVGGElement>;\n };\n nodeElements: Map<string, D3Selection<SVGElement | SVGGElement>>;\n}> {\n // Create a directed, multi graph.\n const graph = new graphlib.Graph({\n multigraph: true,\n compound: true,\n });\n const edgesToProcess = [...data4Layout.edges];\n const config = getConfig();\n // Create groups for clusters, edge paths, edge labels, and nodes.\n const rootGroups = element.insert('g').attr('class', 'root');\n const clusters = rootGroups.insert('g').attr('class', 'clusters');\n const edgePaths = rootGroups.insert('g').attr('class', 'edges edgePath');\n const edgeLabels = rootGroups.insert('g').attr('class', 'edgeLabels');\n const nodesGroup = rootGroups.insert('g').attr('class', 'nodes');\n\n const nodeElements = new Map<string, D3Selection<SVGElement | SVGGElement>>();\n\n // When the container element is detached (no real DOM \u2014 e.g. headless unit\n // tests that exercise the layout engine without rendering), `insertNode`\n // cannot measure labels and would dereference a null node. The browser\n // always passes a live container, so render + measure only when one exists;\n // otherwise still build the graph topology with unmeasured (0) sizes.\n const hasDom = element.node() != null;\n\n // Insert nodes into the DOM and add them to the graph.\n await Promise.all(\n data4Layout.nodes.map(async (node) => {\n if (node.isGroup) {\n graph.setNode(node.id, { ...node });\n } else {\n if (hasDom) {\n const childNodeEl = await insertNode(nodesGroup, node, { config, dir: node.dir });\n const boundingBox = childNodeEl.node()?.getBBox() ?? { width: 0, height: 0 };\n nodeElements.set(node.id, childNodeEl as D3Selection<SVGElement | SVGGElement>);\n node.width = boundingBox.width;\n node.height = boundingBox.height;\n }\n graph.setNode(node.id, { ...node });\n }\n })\n );\n // Add edges to the graph.\n\n for (const edge of edgesToProcess) {\n graph.setEdge(edge.start!, edge.end!, { ...edge }, edge.id);\n const edgeExists = data4Layout.edges.some((existingEdge) => existingEdge.id === edge.id);\n if (!edgeExists) {\n data4Layout.edges.push(edge);\n }\n }\n\n // DDLT size capture (dev / test tooling only). The capture module is loaded\n // via dynamic import so it is never bundled into the production render path:\n // in published builds `window.mermaidCaptureSizes` is unset, so this guard is\n // a single property read and the import resolves to a lazily-loaded chunk that\n // is only fetched when a developer explicitly enables capture.\n // See layout-algorithms/ddlt/sizeCapture.ts.\n if ((globalThis as unknown as { mermaidCaptureSizes?: boolean }).mermaidCaptureSizes) {\n const { captureNodeSizes } = await import('./layout-algorithms/ddlt/sizeCapture.js');\n captureNodeSizes(element, data4Layout);\n }\n\n return {\n graph,\n groups: { clusters, edgePaths, edgeLabels, nodes: nodesGroup, rootGroups },\n nodeElements,\n };\n}\n", "/**\n * Line jumps (\"hops\") for edge crossings.\n *\n * Detects true segment crossings between edge polylines and rewrites the SVG\n * path of the later edge so the crossing renders as either a small arc\n * (`jumpStyle: 'arc'`) or a visible break (`jumpStyle: 'gap'`).\n *\n * The pure functions (`findEdgeIntersections`, `processEdgesWithJumps`) are\n * DOM-free. The DOM-side `applyLineJumpsToSvg` helper reads geometry from\n * layout data and leaves curved (non-`M`/`L`) rendered paths untouched.\n */\n\nimport type { D3Selection } from '../../types.js';\nimport { markerOffsets } from '../../utils/lineWithOffset.js';\n\n/** Radius used by edges.js' generateRoundedPath. Kept in sync so rewritten\n * paths look like the originals at bends. */\nconst ROUNDED_CORNER_RADIUS = 5;\n\n/** Skip the jump if its clamped radius falls below this \u2014 avoids invisible\n * zero-length arcs on very crowded paths. */\nconst CORNER_EPSILON = 1e-5;\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface EdgeGeom {\n id: string;\n points: Point[];\n /**\n * Optional curve hint matching `edge.curve` from the rendering layer.\n * When set, line jumps are only applied for orthogonal-friendly curves\n * (`'linear'`, `'rounded'`, `'step'`, `'stepBefore'`, `'stepAfter'`, or\n * undefined). Other curves (basis, monotoneX, \u2026) are skipped to avoid\n * corrupting smoothed geometry.\n */\n curve?: string;\n /** Arrow type at the start (first point) \u2014 used to apply marker offset so\n * the rewritten path's endpoint matches the original rendered geometry and\n * the arrow marker orients correctly. */\n arrowTypeStart?: string;\n /** Arrow type at the end (last point). */\n arrowTypeEnd?: string;\n}\n\nexport interface LineJumpConfig {\n enabled: boolean;\n jumpRadius: number;\n jumpStyle: 'arc' | 'gap';\n}\n\nexport interface Crossing {\n jumpEdgeId: string;\n otherEdgeId: string;\n /** Index of the segment within the jumping edge's polyline. */\n segIndex: number;\n /** Position of the crossing along the jumping edge's segment, 0..1. */\n t: number;\n point: Point;\n}\n\nconst ENDPOINT_EPSILON = 1e-6;\n\ninterface Segment {\n a: Point;\n b: Point;\n}\n\nfunction buildSegmentList(points: Point[]): Segment[] {\n const segments: Segment[] = [];\n for (let i = 0; i < points.length - 1; i++) {\n segments.push({ a: points[i], b: points[i + 1] });\n }\n return segments;\n}\n\ninterface SegmentIntersection {\n point: Point;\n tA: number;\n tB: number;\n}\n\n/**\n * Parametric segment-segment intersection. Returns null if the segments are\n * parallel, do not intersect, or only meet at one of their endpoints (within\n * `ENDPOINT_EPSILON`). Endpoint rejection prevents normal joins, T-junctions,\n * and shared-start edges from being treated as crossings.\n */\nfunction segmentIntersection(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point\n): SegmentIntersection | null {\n const dxA = a2.x - a1.x;\n const dyA = a2.y - a1.y;\n const dxB = b2.x - b1.x;\n const dyB = b2.y - b1.y;\n\n const denom = dxA * dyB - dyA * dxB;\n if (denom === 0) {\n return null;\n }\n\n const dx = b1.x - a1.x;\n const dy = b1.y - a1.y;\n\n const tA = (dx * dyB - dy * dxB) / denom;\n const tB = (dx * dyA - dy * dxA) / denom;\n\n if (\n tA <= ENDPOINT_EPSILON ||\n tA >= 1 - ENDPOINT_EPSILON ||\n tB <= ENDPOINT_EPSILON ||\n tB >= 1 - ENDPOINT_EPSILON\n ) {\n return null;\n }\n\n return {\n point: { x: a1.x + tA * dxA, y: a1.y + tA * dyA },\n tA,\n tB,\n };\n}\n\n/** True if the segment is horizontally dominant (abs(dx) is at least abs(dy)).\n * Ties go to horizontal to keep pure-diagonal edges grouped with the\n * horizontal bucket \u2014 they don't occur in orthogonal layouts anyway. */\nfunction isHorizontalSeg(seg: Segment): boolean {\n return Math.abs(seg.b.x - seg.a.x) >= Math.abs(seg.b.y - seg.a.y);\n}\n\nexport function findEdgeIntersections(edges: EdgeGeom[]): Crossing[] {\n const crossings: Crossing[] = [];\n\n for (let i = 0; i < edges.length; i++) {\n const edgeA = edges[i];\n const segmentsA = buildSegmentList(edgeA.points);\n for (let j = i + 1; j < edges.length; j++) {\n const edgeB = edges[j];\n const segmentsB = buildSegmentList(edgeB.points);\n\n for (const [si, segA] of segmentsA.entries()) {\n for (const [sj, segB] of segmentsB.entries()) {\n const hit = segmentIntersection(segA.a, segA.b, segB.a, segB.b);\n if (!hit) {\n continue;\n }\n\n // Orthogonal-orientation rule: when one segment is horizontal-\n // dominant and the other vertical-dominant, the HORIZONTAL one\n // gets the jump (classic line-hop convention \u2014 arcs arch upward\n // over the vertical line beneath). Falls back to later-index-wins\n // when both segments share an orientation.\n const aHoriz = isHorizontalSeg(segA);\n const bHoriz = isHorizontalSeg(segB);\n const orthogonalPair = aHoriz !== bHoriz;\n const jumpOnA = orthogonalPair ? aHoriz : false;\n\n if (jumpOnA) {\n crossings.push({\n jumpEdgeId: edgeA.id,\n otherEdgeId: edgeB.id,\n segIndex: si,\n t: hit.tA,\n point: hit.point,\n });\n } else {\n crossings.push({\n jumpEdgeId: edgeB.id,\n otherEdgeId: edgeA.id,\n segIndex: sj,\n t: hit.tB,\n point: hit.point,\n });\n }\n }\n }\n }\n }\n\n return crossings;\n}\n\nfunction fmt(n: number): string {\n // Strip trailing zeros so \"5.00\" \u2192 \"5\"; keep up to 3 decimals otherwise.\n const rounded = Math.round(n * 1000) / 1000;\n return Number.isInteger(rounded) ? `${rounded}` : `${rounded}`;\n}\n\nfunction pointToString(p: Point): string {\n return `${fmt(p.x)},${fmt(p.y)}`;\n}\n\n/**\n * Determines the SVG arc sweep flag so the jump bumps in the conventional\n * direction: horizontal segments bump up (smaller y in SVG), vertical segments\n * bump right (larger x).\n */\nfunction getArcSweepFlag(seg: Segment): 0 | 1 {\n const dx = seg.b.x - seg.a.x;\n const dy = seg.b.y - seg.a.y;\n if (Math.abs(dx) >= Math.abs(dy)) {\n // Horizontal-dominant: bump up (smaller y in SVG's y-down frame).\n // Going +x \u2192 sweep=1 sweeps through increasing angle 180\u00B0\u2192270\u00B0\u21920\u00B0,\n // which passes through (mid, y-r) = up.\n // Going -x \u2192 sweep=0 (reverse direction) also lands the bump above.\n return dx >= 0 ? 1 : 0;\n }\n // Vertical-dominant: bump right (positive x).\n // Going +y \u2192 sweep=1; going -y \u2192 sweep=0.\n return dy >= 0 ? 1 : 0;\n}\n\ninterface JumpOnSegment {\n t: number;\n point: Point;\n /** Distance from segment start along the segment direction. */\n d: number;\n /** Effective radius after boundary + adjacency clamping. */\n r: number;\n}\n\nconst MIN_JUMP_RADIUS = 1e-3;\n\n/**\n * Shifts the first/last point inward along the edge direction by the amount\n * required for their arrow markers, matching `applyMarkerOffsetsToPoints` in\n * edges.js so the rewritten path ends exactly where the original did.\n */\nfunction applyMarkerOffsets(points: Point[], edge: EdgeGeom): Point[] {\n if (points.length < 2) {\n return points.map((p) => ({ ...p }));\n }\n const out = points.map((p) => ({ ...p }));\n const startOff =\n edge.arrowTypeStart && markerOffsets[edge.arrowTypeStart as keyof typeof markerOffsets];\n if (startOff) {\n const a = points[0];\n const b = points[1];\n const ang = Math.atan2(b.y - a.y, b.x - a.x);\n out[0].x = a.x + startOff * Math.cos(ang);\n out[0].y = a.y + startOff * Math.sin(ang);\n }\n const endOff =\n edge.arrowTypeEnd && markerOffsets[edge.arrowTypeEnd as keyof typeof markerOffsets];\n if (endOff) {\n const n = points.length;\n const a = points[n - 2];\n const b = points[n - 1];\n const ang = Math.atan2(b.y - a.y, b.x - a.x);\n out[n - 1].x = b.x - endOff * Math.cos(ang);\n out[n - 1].y = b.y - endOff * Math.sin(ang);\n }\n return out;\n}\n\n/**\n * Emits the arc or gap command for a crossing, in the segment's direction.\n * Returns the part strings; caller inserts them in order.\n */\nfunction emitJump(\n jump: JumpOnSegment,\n ux: number,\n uy: number,\n sweep: 0 | 1,\n style: 'arc' | 'gap'\n): string[] {\n const cx = jump.point.x;\n const cy = jump.point.y;\n const pre = { x: cx - ux * jump.r, y: cy - uy * jump.r };\n const post = { x: cx + ux * jump.r, y: cy + uy * jump.r };\n const out = [`L${pointToString(pre)}`];\n if (style === 'arc') {\n out.push(`A${fmt(jump.r)},${fmt(jump.r)} 0 0 ${sweep} ${pointToString(post)}`);\n } else {\n out.push(`M${pointToString(post)}`);\n }\n return out;\n}\n\n/**\n * Mirrors the corner-rounding logic of `generateRoundedPath` in edges.js:\n * given a bend at `curr` between segments `prev\u2192curr` and `curr\u2192next`,\n * computes (startX, startY) just before curr on the incoming segment and\n * (endX, endY) just after curr on the outgoing segment, plus the Q control\n * point (which is curr itself). Returns `null` if the angle is degenerate\n * and the caller should just emit a straight `L curr`.\n */\ninterface RoundedCorner {\n startX: number;\n startY: number;\n endX: number;\n endY: number;\n ctrlX: number;\n ctrlY: number;\n /** How much the start of the rounded corner eats into the incoming segment. */\n cutLen: number;\n}\nfunction computeRoundedCorner(\n prev: Point,\n curr: Point,\n next: Point,\n radius: number\n): RoundedCorner | null {\n const dx1 = curr.x - prev.x;\n const dy1 = curr.y - prev.y;\n const dx2 = next.x - curr.x;\n const dy2 = next.y - curr.y;\n const len1 = Math.hypot(dx1, dy1);\n const len2 = Math.hypot(dx2, dy2);\n if (len1 < CORNER_EPSILON || len2 < CORNER_EPSILON) {\n return null;\n }\n const nx1 = dx1 / len1;\n const ny1 = dy1 / len1;\n const nx2 = dx2 / len2;\n const ny2 = dy2 / len2;\n const dot = nx1 * nx2 + ny1 * ny2;\n const clamped = Math.max(-1, Math.min(1, dot));\n const angle = Math.acos(clamped);\n if (angle < CORNER_EPSILON || Math.abs(Math.PI - angle) < CORNER_EPSILON) {\n return null;\n }\n const cutLen = Math.min(radius / Math.sin(angle / 2), len1 / 2, len2 / 2);\n return {\n startX: curr.x - nx1 * cutLen,\n startY: curr.y - ny1 * cutLen,\n endX: curr.x + nx2 * cutLen,\n endY: curr.y + ny2 * cutLen,\n ctrlX: curr.x,\n ctrlY: curr.y,\n cutLen,\n };\n}\n\nfunction rewriteEdgePath(edge: EdgeGeom, jumps: Crossing[], config: LineJumpConfig): string {\n const rawPoints = edge.points;\n if (rawPoints.length < 2) {\n return '';\n }\n\n // Match edges.js: shift the first/last point inward so arrow markers line up.\n const points = applyMarkerOffsets(rawPoints, edge);\n const rounded = edge.curve === 'rounded';\n\n // Jumps are indexed into the ORIGINAL (un-offset) segment list. For mid-\n // segments (i > 0 and i < n-2) the offsets don't change anything, and for\n // the first/last segment the shift is tiny compared to jump radius so\n // reusing the same (segIndex, t) is fine.\n const segments = buildSegmentList(points);\n const bySeg = new Map<number, JumpOnSegment[]>();\n for (const j of jumps) {\n const seg = segments[j.segIndex];\n if (!seg) {\n continue;\n }\n const segLen = Math.hypot(seg.b.x - seg.a.x, seg.b.y - seg.a.y);\n const list = bySeg.get(j.segIndex) ?? [];\n list.push({\n t: j.t,\n point: j.point,\n d: j.t * segLen,\n r: config.jumpRadius,\n });\n bySeg.set(j.segIndex, list);\n }\n\n const parts: string[] = [`M${pointToString(points[0])}`];\n // Running cursor along the current segment measured from seg.a.\n // Consumed at the front by the previous corner's cutLen (for rounded) and\n // after that by mid-segment jumps.\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n const segLen = Math.hypot(seg.b.x - seg.a.x, seg.b.y - seg.a.y);\n const ux = segLen === 0 ? 0 : (seg.b.x - seg.a.x) / segLen;\n const uy = segLen === 0 ? 0 : (seg.b.y - seg.a.y) / segLen;\n const sweep = getArcSweepFlag(seg);\n\n // How much of the front of this segment was consumed by the previous\n // corner's Q end-point (endX,endY). Default 0.\n let segStartConsumed = 0;\n if (rounded && i > 0) {\n const corner = computeRoundedCorner(\n points[i - 1],\n points[i],\n points[i + 1] ?? points[i],\n ROUNDED_CORNER_RADIUS\n );\n if (corner) {\n segStartConsumed = corner.cutLen;\n }\n }\n\n // Rounded: if there's a next corner ahead, we stop short of it by cutLen.\n let segEndStop = segLen;\n let upcomingCorner: RoundedCorner | null = null;\n if (rounded && i < segments.length - 1) {\n upcomingCorner = computeRoundedCorner(\n points[i],\n points[i + 1],\n points[i + 2] ?? points[i + 1],\n ROUNDED_CORNER_RADIUS\n );\n if (upcomingCorner) {\n segEndStop = segLen - upcomingCorner.cutLen;\n }\n }\n\n // Jumps clamped so they don't overlap corners at either end of the\n // segment or each other.\n const segJumps = [...(bySeg.get(i) ?? [])].sort((a, b) => a.t - b.t);\n for (const j of segJumps) {\n j.r = Math.min(j.r, j.d - segStartConsumed, segEndStop - j.d);\n }\n for (let k = 0; k < segJumps.length - 1; k++) {\n const gap = segJumps[k + 1].d - segJumps[k].d;\n if (segJumps[k].r + segJumps[k + 1].r > gap) {\n const half = gap / 2;\n segJumps[k].r = Math.min(segJumps[k].r, half);\n segJumps[k + 1].r = Math.min(segJumps[k + 1].r, half);\n }\n }\n\n for (const j of segJumps) {\n if (j.r < MIN_JUMP_RADIUS) {\n continue;\n }\n parts.push(...emitJump(j, ux, uy, sweep, config.jumpStyle));\n }\n\n // End of segment: either a straight L to seg.b (last segment or linear),\n // or a Q-corner into seg.b's neighborhood (rounded, middle).\n if (rounded && upcomingCorner) {\n parts.push(`L${fmt(upcomingCorner.startX)},${fmt(upcomingCorner.startY)}`);\n parts.push(\n `Q${fmt(upcomingCorner.ctrlX)},${fmt(upcomingCorner.ctrlY)} ${fmt(upcomingCorner.endX)},${fmt(upcomingCorner.endY)}`\n );\n } else {\n parts.push(`L${pointToString(seg.b)}`);\n }\n }\n\n return parts.join(' ');\n}\n\nfunction plainPath(points: Point[]): string {\n if (points.length === 0) {\n return '';\n }\n const parts = [`M${pointToString(points[0])}`];\n for (let i = 1; i < points.length; i++) {\n parts.push(`L${pointToString(points[i])}`);\n }\n return parts.join(' ');\n}\n\nexport function processEdgesWithJumps(\n edges: EdgeGeom[],\n config: LineJumpConfig\n): Map<string, string> {\n const result = new Map<string, string>();\n\n if (!config.enabled) {\n for (const edge of edges) {\n result.set(edge.id, plainPath(edge.points));\n }\n return result;\n }\n\n const crossings = findEdgeIntersections(edges);\n const jumpsByEdge = new Map<string, Crossing[]>();\n for (const c of crossings) {\n const list = jumpsByEdge.get(c.jumpEdgeId) ?? [];\n list.push(c);\n jumpsByEdge.set(c.jumpEdgeId, list);\n }\n\n for (const edge of edges) {\n const jumps = jumpsByEdge.get(edge.id);\n if (!jumps || jumps.length === 0) {\n result.set(edge.id, plainPath(edge.points));\n } else {\n result.set(edge.id, rewriteEdgePath(edge, jumps, config));\n }\n }\n\n return result;\n}\n\n/**\n * Returns true iff the SVG path `d` is a straight-line path \u2014 only `M`/`L`/`m`/`l`\n * move/line commands plus their numeric coordinates (digits, sign, decimal point,\n * scientific-notation `e`, and `,`/space separators). Curved paths are skipped by\n * the caller.\n */\nexport function isStraightPath(d: string): boolean {\n return /^[\\d\\s+,.LMelm-]*$/.test(d);\n}\n\n/**\n * Returns true iff the named curve produces orthogonal-friendly segments that\n * can be safely re-emitted with line jumps. Includes `'rounded'` even though\n * its rendered `d` contains `Q` corner-rounding commands \u2014 when an edge with\n * a jump is rewritten the corner rounding is dropped in exchange for visible\n * arc hops at crossings, which is the desired trade-off.\n */\nexport function curveSupportsLineHops(curve: string | undefined): boolean {\n if (!curve) {\n return true;\n }\n return (\n curve === 'linear' ||\n curve === 'rounded' ||\n curve === 'step' ||\n curve === 'stepBefore' ||\n curve === 'stepAfter'\n );\n}\n\n/**\n * Decodes the `data-points` attribute set by edges.js at render time. This\n * gives us the exact point list edges.js used to emit the rendered path \u2014\n * i.e. after node-boundary `intersect()` clipping and any orthogonalization,\n * but BEFORE `applyMarkerOffsetsToPoints`. Using these points guarantees the\n * rewrite's endpoints match the original rendered endpoints.\n */\nfunction decodeDataPoints(raw: string | null): Point[] | null {\n if (!raw) {\n return null;\n }\n try {\n const json = typeof atob === 'function' ? atob(raw) : Buffer.from(raw, 'base64').toString();\n const parsed = JSON.parse(json);\n if (!Array.isArray(parsed)) {\n return null;\n }\n const pts: Point[] = [];\n for (const p of parsed) {\n if (p && typeof p.x === 'number' && typeof p.y === 'number') {\n pts.push({ x: p.x, y: p.y });\n }\n }\n return pts.length >= 2 ? pts : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Patches the rendered SVG paths in `edgePathsGroup` for any edges that\n * cross. The true geometry is read from each path's `data-points` attribute\n * (written by edges.js at render time) so the rewrite's endpoints match\n * exactly what was originally rendered. Edges whose curve is a true\n * smoothing curve (`basis`, `monotoneX`, \u2026) are skipped.\n */\nexport function applyLineJumpsToSvg(\n edgePathsGroup: D3Selection<SVGGElement>,\n edges: EdgeGeom[],\n config: LineJumpConfig\n): void {\n if (!config.enabled) {\n return;\n }\n\n const groupNode = edgePathsGroup.node();\n if (!groupNode) {\n return;\n }\n\n // Build a metadata lookup so per-edge properties (curve, arrow types)\n // survive the DOM round-trip.\n const edgeMeta = new Map<string, EdgeGeom>();\n for (const e of edges) {\n edgeMeta.set(e.id, e);\n }\n\n // Collect geometry from each path's data-points, preferring that over the\n // incoming `edges[].points` which came from pre-render layout state.\n const renderedEdges: EdgeGeom[] = [];\n const pathById = new Map<string, Element>();\n for (const e of edges) {\n const escapedId = typeof CSS !== 'undefined' && CSS.escape ? CSS.escape(e.id) : e.id;\n const pathEl = groupNode.querySelector(`path[data-id=\"${escapedId}\"]`);\n if (!pathEl) {\n continue;\n }\n pathById.set(e.id, pathEl);\n const decoded = decodeDataPoints(pathEl.getAttribute('data-points'));\n const points = decoded ?? e.points;\n renderedEdges.push({ ...e, points });\n }\n\n const crossings = findEdgeIntersections(renderedEdges);\n if (crossings.length === 0) {\n return;\n }\n\n const jumpsByEdge = new Map<string, Crossing[]>();\n for (const c of crossings) {\n const list = jumpsByEdge.get(c.jumpEdgeId) ?? [];\n list.push(c);\n jumpsByEdge.set(c.jumpEdgeId, list);\n }\n\n for (const renderedEdge of renderedEdges) {\n const jumps = jumpsByEdge.get(renderedEdge.id);\n if (!jumps || jumps.length === 0) {\n continue;\n }\n const meta = edgeMeta.get(renderedEdge.id);\n const curveHint = meta?.curve;\n if (curveHint !== undefined && !curveSupportsLineHops(curveHint)) {\n continue;\n }\n\n const pathEl = pathById.get(renderedEdge.id);\n if (!pathEl) {\n continue;\n }\n\n if (curveHint === undefined) {\n const currentD = pathEl.getAttribute('d') ?? '';\n if (!isStraightPath(currentD)) {\n continue;\n }\n }\n\n // Read the ORIGINAL stroke-dasharray before rewriting so we can\n // recompute it against the new total length. The `neo` look emits:\n // stroke-dasharray: 0 <oValueS> <len - oValueS - oValueE> <oValueE>;\n // which hides the first oValueS and last oValueE pixels of the stroke\n // \u2014 this is what actually prevents the stroke from poking into the arrow\n // marker body. Our rewritten path has a different length, so without\n // updating the \"on\" portion the hidden tail ends up in the wrong place.\n const originalStyle = pathEl.getAttribute('style') ?? '';\n const dasharrayMatch = /stroke-dasharray\\s*:\\s*0\\s+([\\d.]+)\\s+[\\d.]+\\s+([\\d.]+)/.exec(\n originalStyle\n );\n const preservedOValueS = dasharrayMatch ? Number.parseFloat(dasharrayMatch[1]) : null;\n const preservedOValueE = dasharrayMatch ? Number.parseFloat(dasharrayMatch[2]) : null;\n\n const newD = rewriteEdgePath(renderedEdge, jumps, config);\n pathEl.setAttribute('d', newD);\n\n if (\n preservedOValueS !== null &&\n preservedOValueE !== null &&\n typeof (pathEl as SVGPathElement).getTotalLength === 'function'\n ) {\n const newLen = (pathEl as SVGPathElement).getTotalLength();\n const onLen = Math.max(0, newLen - preservedOValueS - preservedOValueE);\n const newDasharray = `0 ${preservedOValueS} ${onLen} ${preservedOValueE}`;\n const cleaned = originalStyle\n .replace(/stroke-dasharray\\s*:[^;]*;?/g, `stroke-dasharray: ${newDasharray};`)\n .replace(/;\\s*;+/g, ';');\n pathEl.setAttribute('style', cleaned);\n }\n }\n}\n", "import type { LayoutData } from '../../types.js';\nimport { positionNode } from '../../rendering-elements/nodes.js';\nimport type { D3Selection } from '../../../types.js';\nimport { insertCluster } from '../../rendering-elements/clusters.js';\nimport {\n edgeLabels,\n insertEdge,\n insertEdgeLabel,\n terminalLabels,\n} from '../../rendering-elements/edges.js';\nimport { applyLineJumpsToSvg } from '../../rendering-elements/lineJump.js';\nimport { log } from '../../../logger.js';\nimport { getSubGraphTitleMargins } from '../../../utils/subGraphTitleMargins.js';\nimport { getConfig } from '../../../config.js';\nimport utils from '../../../utils.js';\n\nexport async function adjustLayout(\n data4Layout: LayoutData,\n groups: {\n edgePaths: D3Selection<SVGGElement>;\n rootGroups: D3Selection<SVGGElement>;\n [key: string]: D3Selection<SVGGElement>;\n edgeLabels: D3Selection<SVGGElement>;\n }\n): Promise<void> {\n // Render clusters and position nodes; this also populates node.intersect on shapes.\n for (const node of data4Layout.nodes) {\n if (node.isGroup) {\n await insertCluster(groups.clusters, node);\n } else {\n positionNode(node);\n }\n }\n\n // Build a lookup so we can pass full node objects (with intersect) to insertEdge,\n // matching the behavior of the dagre-based pipeline.\n const nodeById = new Map<string, any>();\n for (const node of data4Layout.nodes) {\n if (node?.id) {\n nodeById.set(node.id, node);\n }\n }\n\n for (const edge of data4Layout.edges) {\n const startNode = edge.start ? (nodeById.get(edge.start) ?? {}) : {};\n const endNode = edge.end ? (nodeById.get(edge.end) ?? {}) : {};\n\n const paths = insertEdge(\n groups.edgePaths,\n { ...edge },\n {},\n data4Layout.type,\n startNode,\n endNode,\n data4Layout.diagramId\n );\n if (edge.label) {\n await insertEdgeLabel(groups.rootGroups, edge);\n }\n\n if (edge.label) {\n positionEdgeLabel(edge, paths);\n }\n }\n\n // Render-time post-processing: replace edge crossings with line hops.\n // Default: 'arc'. Set swimlane.lineHops = false to opt out.\n const lineHopsConfig = data4Layout.config?.swimlane?.lineHops;\n if (lineHopsConfig !== false) {\n const jumpStyle: 'arc' | 'gap' = lineHopsConfig === 'gap' ? 'gap' : 'arc';\n const edgeGeometries = data4Layout.edges\n .filter((e: any) => Array.isArray(e.points) && e.points.length >= 2)\n .map((e: any) => ({\n id: e.id,\n points: e.points,\n curve: e.curve,\n arrowTypeStart: e.arrowTypeStart,\n arrowTypeEnd: e.arrowTypeEnd,\n }));\n applyLineJumpsToSvg(groups.edgePaths, edgeGeometries, {\n enabled: true,\n jumpRadius: 6,\n jumpStyle,\n });\n }\n}\n\nfunction positionEdgeLabel(edge: any, paths: any) {\n const path = paths?.updatedPath ?? paths?.originalPath;\n const siteConfig = getConfig();\n const { subGraphTitleTotalMargin } = getSubGraphTitleMargins({\n flowchart: siteConfig.flowchart ?? {},\n });\n if (edge.label) {\n const el = edgeLabels.get(edge.id);\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils.calcLabelPosition(path);\n log.debug(\n 'Moving label ' + edge.label + ' from (',\n x,\n ',',\n y,\n ') to (',\n pos.x,\n ',',\n pos.y,\n ') abc88'\n );\n if (paths) {\n x = pos.x;\n y = pos.y;\n }\n }\n el.attr('transform', `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`);\n }\n\n if (edge?.startLabelLeft) {\n const el = terminalLabels.get(edge.id).startLeft;\n let x = edge?.x;\n let y = edge?.y;\n if (path) {\n const pos = utils.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, 'start_left', path);\n x = pos.x;\n y = pos.y;\n }\n el.attr('transform', `translate(${x}, ${y})`);\n }\n if (edge.startLabelRight) {\n const el = terminalLabels.get(edge.id).startRight;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils.calcTerminalLabelPosition(\n edge.arrowTypeStart ? 10 : 0,\n 'start_right',\n path\n );\n x = pos.x;\n y = pos.y;\n }\n el.attr('transform', `translate(${x}, ${y})`);\n }\n if (edge.endLabelLeft) {\n const el = terminalLabels.get(edge.id).endLeft;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, 'end_left', path);\n x = pos.x;\n y = pos.y;\n }\n el.attr('transform', `translate(${x}, ${y})`);\n }\n if (edge.endLabelRight) {\n const el = terminalLabels.get(edge.id).endRight;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, 'end_right', path);\n x = pos.x;\n y = pos.y;\n }\n el.attr('transform', `translate(${x}, ${y})`);\n }\n}\n", "import type {\n LayoutData,\n Node as MermaidNode,\n Edge as MermaidEdge,\n ClusterNode,\n} from '../../types.js';\n\nexport type Layout = LayoutData;\nexport type Node = MermaidNode;\nexport type NodeId = Node['id'];\nexport type EdgeId = MermaidEdge['id'];\n\nexport interface EdgeRef {\n id: EdgeId;\n src: NodeId;\n dst: NodeId;\n weight?: number;\n ref: MermaidEdge;\n}\n\nexport interface Graph {\n nodes: NodeId[];\n edges: EdgeRef[];\n layout: Layout;\n nodeById: Map<NodeId, Node>;\n}\n\nexport interface Layering {\n layers: NodeId[][];\n rankOf: Record<NodeId, number>;\n dummy?: Set<NodeId>;\n}\n\nexport interface OrderedLayers {\n layers: NodeId[][];\n}\n\nexport interface Coordinates {\n x: Record<NodeId, number>;\n y: Record<NodeId, number>;\n}\n\nexport type Edge = EdgeRef;\n\nexport const DEFAULT_SWIMLANE_ID = '__swimlane_default__';\n\nexport interface WriteBackOptions {\n layerGap?: number;\n nodeGap?: number;\n}\n\n// Captured swimlane fixtures use 21px as the stable single-line label height.\nconst TOP_LANE_TITLE_BAND_HEIGHT = 21;\nconst MIN_TOP_LANE_HORIZONTAL_PADDING = 20;\n\nfunction topLaneHorizontalPadding(lane: Node): number {\n return Math.max(lane.padding ?? MIN_TOP_LANE_HORIZONTAL_PADDING, MIN_TOP_LANE_HORIZONTAL_PADDING);\n}\n\nfunction assignTopLaneTitleRect(lane: Node): void {\n const { x, y, width, height } = lane;\n const contentTop = (lane as { swimlaneContentTop?: unknown }).swimlaneContentTop;\n if (\n typeof x !== 'number' ||\n typeof y !== 'number' ||\n typeof width !== 'number' ||\n typeof height !== 'number' ||\n typeof contentTop !== 'number' ||\n !Number.isFinite(x) ||\n !Number.isFinite(y) ||\n !Number.isFinite(width) ||\n !Number.isFinite(height) ||\n !Number.isFinite(contentTop) ||\n width <= 0 ||\n height <= 0\n ) {\n delete lane.groupTitleRect;\n return;\n }\n\n const top = y - height / 2;\n const headerBottom = Math.min(contentTop, y + height / 2);\n const titleHeight = Math.min(TOP_LANE_TITLE_BAND_HEIGHT, Math.max(0, headerBottom - top));\n const bottom = top + titleHeight;\n if (bottom <= top) {\n delete lane.groupTitleRect;\n return;\n }\n\n lane.groupTitleRect = {\n left: x - width / 2,\n right: x + width / 2,\n top,\n bottom,\n };\n}\n\nexport function prepareLayoutForSwimlanes(layout: LayoutData): void {\n const direction = (layout as any).direction;\n const nodes = (layout.nodes ??= []);\n for (const node of layout.nodes ?? []) {\n if (node.isGroup && !node.parentId) {\n node.shape = 'swimlane';\n if (direction) {\n (node as any).direction = direction;\n }\n }\n }\n\n const looseNodes = nodes.filter((node) => !node.isGroup && !node.parentId);\n if (looseNodes.length === 0) {\n return;\n }\n\n let defaultLane = nodes.find((node) => node.id === DEFAULT_SWIMLANE_ID);\n if (!defaultLane) {\n defaultLane = {\n id: DEFAULT_SWIMLANE_ID,\n label: '',\n isGroup: true,\n shape: 'swimlane',\n padding: 20,\n ...(direction ? { direction } : {}),\n } as ClusterNode;\n nodes.push(defaultLane);\n } else if (defaultLane.isGroup) {\n defaultLane.shape = 'swimlane';\n if (direction) {\n (defaultLane as any).direction = direction;\n }\n }\n\n for (const node of looseNodes) {\n node.parentId = DEFAULT_SWIMLANE_ID;\n }\n}\n\nexport function toGraphView(layout: LayoutData): Graph {\n const nodeById = new Map<NodeId, Node>();\n for (const n of layout.nodes ?? []) {\n nodeById.set(n.id, n);\n }\n\n const edges: EdgeRef[] = [];\n for (const e of layout.edges ?? []) {\n const src = typeof e.start === 'string' ? e.start : undefined;\n const dst = typeof e.end === 'string' ? e.end : undefined;\n if (!src || !dst) {\n continue;\n }\n // Exclude labelled originals from Sugiyama: their routing is carried by\n // the two layout-only virtual edges A\u2192label and label\u2192B, which create the\n // correct layer/ordering constraints. Including the original as well would\n // double-count rank pressure and inflate crossing penalties.\n if ((e as MermaidEdge & { labelNodeId?: string }).labelNodeId) {\n continue;\n }\n edges.push({ id: e.id, src, dst, ref: e });\n }\n\n const allNodes = layout.nodes ?? [];\n const groupNodes = allNodes.filter((n) => n.isGroup);\n const nonGroupNodes = allNodes.filter((n) => !n.isGroup);\n\n const nodesInGroupOrder = [...groupNodes].reverse();\n const nodes: NodeId[] = [...nodesInGroupOrder, ...nonGroupNodes].map((n) => n.id);\n return { nodes, edges, layout, nodeById };\n}\n\nexport function writeBackToLayoutData(\n g: Graph,\n ordered: OrderedLayers,\n coords: Coordinates,\n opts?: WriteBackOptions\n): void {\n const { layout } = g;\n const nodeMap = g.nodeById;\n const layerGap = opts?.layerGap ?? 100;\n const nodeGap = opts?.nodeGap ?? 40;\n\n let layerIndex = 0;\n for (const layer of ordered.layers) {\n let orderIndex = 0;\n for (const id of layer) {\n const node = nodeMap.get(id);\n if (!node) {\n orderIndex++;\n continue;\n }\n node.layer = layerIndex;\n node.order = orderIndex;\n const x = coords.x[id] ?? orderIndex * nodeGap;\n const y = coords.y[id] ?? layerIndex * layerGap;\n node.x = x;\n node.y = y;\n orderIndex++;\n }\n layerIndex++;\n }\n\n const allNodes = layout.nodes ?? [];\n const groupBounds = new Map<NodeId, { minX: number; maxX: number; minY: number; maxY: number }>();\n const topLevelGroups: Node[] = [];\n for (const group of allNodes) {\n if (!group?.isGroup) {\n continue;\n }\n if (!group.parentId) {\n topLevelGroups.push(group);\n }\n const children = allNodes.filter((n) => n.parentId === group.id);\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n for (const child of children) {\n const cx = child.x ?? coords.x[child.id];\n const cy = child.y ?? coords.y[child.id];\n const cw = child.width ?? 0;\n const ch = child.height ?? 0;\n if (cx != null && cy != null) {\n minX = Math.min(minX, cx - cw / 2);\n maxX = Math.max(maxX, cx + cw / 2);\n minY = Math.min(minY, cy - ch / 2);\n maxY = Math.max(maxY, cy + ch / 2);\n }\n }\n if (minX === Infinity || minY === Infinity) {\n group.x = group.x ?? 0;\n group.y = group.y ?? 0;\n group.width = group.width ?? 0;\n group.height = group.height ?? 0;\n } else {\n const pad = group.padding ?? 20;\n const horizontalPad = group.parentId ? pad : 2 * topLaneHorizontalPadding(group);\n const verticalPad = pad;\n const w = Math.max(0, maxX - minX) + horizontalPad;\n const h = Math.max(0, maxY - minY) + verticalPad;\n const cx = (minX + maxX) / 2;\n const cy = (minY + maxY) / 2;\n group.x = cx;\n group.y = cy;\n group.width = w;\n group.height = h;\n groupBounds.set(group.id, { minX, maxX, minY, maxY });\n }\n }\n\n if (topLevelGroups.length > 0 && groupBounds.size > 0) {\n let globalMinY = Infinity;\n let globalMaxY = -Infinity;\n let maxPad = 0;\n for (const lane of topLevelGroups) {\n const pad = lane.padding ?? 20;\n if (pad > maxPad) {\n maxPad = pad;\n }\n const b = groupBounds.get(lane.id);\n if (!b) {\n continue;\n }\n globalMinY = Math.min(globalMinY, b.minY);\n globalMaxY = Math.max(globalMaxY, b.maxY);\n }\n if (globalMinY !== Infinity && globalMaxY !== -Infinity) {\n const contentHeight = Math.max(0, globalMaxY - globalMinY);\n const minHeaderMargin = 36;\n const verticalMargin = Math.max(maxPad, minHeaderMargin);\n const laneHeight = contentHeight + 2 * verticalMargin;\n const centerY = (globalMinY + globalMaxY) / 2;\n for (const lane of topLevelGroups) {\n lane.y = centerY;\n lane.height = laneHeight;\n (lane as any).swimlaneContentTop = globalMinY;\n }\n\n const sortedLanes = [...topLevelGroups].sort((a, b) => {\n const ax = a.x ?? 0;\n const bx = b.x ?? 0;\n return ax - bx;\n });\n\n const laneIds: NodeId[] = [];\n const centers: number[] = [];\n const baseWidths: number[] = [];\n\n for (const lane of sortedLanes) {\n const b = groupBounds.get(lane.id);\n if (!b) {\n continue;\n }\n const contentWidth = Math.max(0, b.maxX - b.minX) + 2 * topLaneHorizontalPadding(lane);\n const cx = (b.minX + b.maxX) / 2;\n laneIds.push(lane.id);\n centers.push(cx);\n baseWidths.push(contentWidth);\n }\n\n const count = laneIds.length;\n if (count > 0) {\n const laneWidths = new Map<NodeId, number>();\n\n if (count === 1) {\n laneWidths.set(laneIds[0], baseWidths[0]);\n } else {\n const d: number[] = [];\n for (let i = 0; i < count - 1; i++) {\n d.push(centers[i + 1] - centers[i]);\n }\n\n const u: number[] = new Array(count);\n u[0] = 0;\n for (let i = 0; i < count - 1; i++) {\n u[i + 1] = 2 * d[i] - u[i];\n }\n\n let lowerBound = 0;\n let upperBound = Number.POSITIVE_INFINITY;\n for (let i = 0; i < count; i++) {\n const baseW = baseWidths[i];\n if (i % 2 === 0) {\n lowerBound = Math.max(lowerBound, baseW - u[i]);\n } else {\n upperBound = Math.min(upperBound, u[i] - baseW);\n }\n }\n\n let x = lowerBound;\n if (lowerBound <= upperBound) {\n x = (lowerBound + upperBound) / 2;\n } else {\n x = lowerBound;\n }\n\n for (let i = 0; i < count; i++) {\n const w = u[i] + (i % 2 === 0 ? x : -x);\n const finalWidth = Math.max(baseWidths[i], w);\n laneWidths.set(laneIds[i], finalWidth);\n }\n }\n\n for (const lane of topLevelGroups) {\n const w = laneWidths.get(lane.id);\n if (w != null) {\n lane.width = w;\n }\n assignTopLaneTitleRect(lane);\n }\n }\n }\n }\n}\n", "/**\n * Edge Label Nodes Transformation (label-as-waypoint variant)\n *\n * For each labelled edge, this transform creates an `edge-label-*` node that\n * participates in the Sugiyama layout (so the label text gets a deterministic\n * position in a lane). Unlike the older split-edge model, it leaves the\n * original labelled edge in place and stamps `labelNodeId` on it \u2014 the router\n * uses that stamp to thread the original edge's single polyline through the\n * label node's center.\n *\n * Two `isLayoutOnly` virtual edges (A\u2192label, label\u2192B) are appended to the\n * layout so that Sugiyama's layering and ordering honour the label's position\n * between source and target. They are never routed or rendered: the router and\n * renderer skip any edge flagged with `isLayoutOnly`.\n */\n\nimport type { LayoutData, Node, Edge, NonClusterNode } from '../../types.js';\nimport { log } from '../../../logger.js';\n\nconst EDGE_LABEL_LOG_PREFIX = '[EdgeLabelNodes]';\n\n/**\n * Transforms edges with labels into label nodes + layout-only virtual edges.\n *\n * For each edge with a label:\n * 1. Creates a label node with the label text.\n * 2. Assigns the label node to the source or target lane (cross-lane edges\n * prefer the target lane for tighter routing).\n * 3. Stamps `labelNodeId` on the original edge.\n * 4. Appends two `isLayoutOnly: true` virtual edges (A\u2192label, label\u2192B) so\n * Sugiyama places the label between source and target. The router skips\n * these; only the original edge is routed (threading through the label\n * node's center).\n *\n * @param data - The layout data to transform\n * @returns The transformed layout data with label nodes and virtual edges\n */\nexport function createEdgeLabelNodes(data: LayoutData): LayoutData {\n const nodesToAdd: NonClusterNode[] = [];\n const layoutOnlyEdges: Edge[] = [];\n\n const nodeById = new Map<string, Node>();\n for (const node of data.nodes) {\n nodeById.set(node.id, node);\n }\n\n for (const edge of data.edges) {\n if (!edge.label || edge.label.length === 0) {\n continue;\n }\n if ((edge as Edge & { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n // Guard against double-processing if the caller invokes us twice.\n if ((edge as Edge & { labelNodeId?: string }).labelNodeId) {\n continue;\n }\n\n const sourceNode = edge.start ? nodeById.get(edge.start) : undefined;\n const targetNode = edge.end ? nodeById.get(edge.end) : undefined;\n\n if (!sourceNode || !targetNode) {\n log.warn(EDGE_LABEL_LOG_PREFIX, `Edge ${edge.id} has missing source or target node`);\n continue;\n }\n\n const labelNodeId = `edge-label-${edge.start}-${edge.end}-${edge.id}`;\n\n // For cross-lane edges, assign to the target lane for better routing:\n // it keeps the label closer to where the edge is heading and avoids long\n // detours back to the source lane.\n const isCrossLane = sourceNode.parentId !== targetNode.parentId;\n const labelLane = isCrossLane ? targetNode.parentId : sourceNode.parentId;\n\n const labelNode: NonClusterNode = {\n id: labelNodeId,\n label: edge.label,\n edgeStart: edge.start ?? '',\n edgeEnd: edge.end ?? '',\n shape: 'labelRect',\n width: 0, // populated when rendered / applied from fixture\n height: 0,\n isEdgeLabel: true,\n isDummy: true,\n parentId: labelLane,\n isGroup: false,\n labelStyle: Array.isArray(edge.labelStyle) ? edge.labelStyle[0] : (edge.labelStyle ?? ''),\n ...(sourceNode.dir ? { dir: sourceNode.dir } : {}),\n };\n\n nodesToAdd.push(labelNode);\n\n // Stamp the original edge so the router can decompose routing through the\n // label's center when producing a single polyline.\n (edge as Edge & { labelNodeId?: string }).labelNodeId = labelNodeId;\n\n // Ownership of the label text moves to the label node. Clear the label\n // off the original edge so the edge renderer does not draw it a second\n // time alongside the label node's own text.\n edge.label = undefined;\n (edge as Edge & { text?: unknown }).text = undefined;\n\n // Layout-only virtual edges: Sugiyama uses these to place the label node\n // between source and target. They are not routed or rendered \u2014 consumers\n // must skip any edge with `isLayoutOnly: true`.\n const toLabelVirtual: Edge = {\n id: `${edge.id}-to-label`,\n start: edge.start,\n end: labelNodeId,\n type: 'normal',\n isLayoutOnly: true,\n } as unknown as Edge;\n const fromLabelVirtual: Edge = {\n id: `${edge.id}-from-label`,\n start: labelNodeId,\n end: edge.end,\n type: 'normal',\n isLayoutOnly: true,\n } as unknown as Edge;\n\n layoutOnlyEdges.push(toLabelVirtual, fromLabelVirtual);\n }\n\n const newNodes = [...data.nodes, ...nodesToAdd];\n const newEdges = [...data.edges, ...layoutOnlyEdges];\n\n return {\n ...data,\n nodes: newNodes,\n edges: newEdges,\n };\n}\n", "const EPS = 1e-3;\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport type RectSide = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface RectBounds {\n left: number;\n right: number;\n top: number;\n bottom: number;\n}\n\nexport interface RectEntry {\n id: string;\n rect: RectBounds;\n}\n\nexport interface NodeBoundsInfo extends RectEntry {\n cx: number;\n cy: number;\n}\n\nexport interface NodePairGeometry {\n srcId: string;\n dstId: string;\n srcInfo: NodeBoundsInfo;\n dstInfo: NodeBoundsInfo;\n collinearX: boolean;\n collinearY: boolean;\n}\n\nexport interface LayoutNodeRect extends RectBounds {\n nodeId: string;\n}\n\nexport interface ThreeSegmentRoute {\n kind: 'HVH' | 'VHV';\n p0: Point;\n p1: Point;\n p2: Point;\n p3: Point;\n}\n\nexport interface OrthogonalSegment {\n index: number;\n a: Point;\n b: Point;\n horizontal: boolean;\n vertical: boolean;\n}\n\ninterface EdgeSegmentInput {\n points?: Point[];\n isLayoutOnly?: boolean;\n}\n\ninterface NodeBoundsInput {\n id?: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n isGroup?: boolean;\n isEdgeLabel?: boolean;\n}\n\ninterface RectNodeInput {\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n}\n\ninterface EdgeEndpointInput {\n start?: string;\n end?: string;\n}\n\ninterface SimplifyPassResult {\n points: Point[];\n changed: boolean;\n}\n\nfunction measuredNodeRect(node: RectNodeInput) {\n const cx = node.x ?? 0;\n const cy = node.y ?? 0;\n const width = node.width ?? 0;\n const height = node.height ?? 0;\n return width > 0 && height > 0\n ? { cx, cy, rect: rectFromCenterSize(cx, cy, width, height) }\n : undefined;\n}\n\nfunction nodeBoundsInfoFor(node: NodeBoundsInput): NodeBoundsInfo | undefined {\n if (node.isGroup) {\n return undefined;\n }\n const measured = measuredNodeRect(node);\n if (!measured) {\n return undefined;\n }\n const id = String(node.id ?? '');\n return {\n id,\n cx: measured.cx,\n cy: measured.cy,\n rect: measured.rect,\n };\n}\n\nexport function samePoint(a: Point, b: Point, epsilon = EPS): boolean {\n return Math.abs(a.x - b.x) < epsilon && Math.abs(a.y - b.y) < epsilon;\n}\n\nexport function sameX(a: Point, b: Point, epsilon = EPS): boolean {\n return Math.abs(a.x - b.x) < epsilon;\n}\n\nexport function sameY(a: Point, b: Point, epsilon = EPS): boolean {\n return Math.abs(a.y - b.y) < epsilon;\n}\n\nexport function isHorizontalSegment(a: Point, b: Point, epsilon = EPS): boolean {\n return sameY(a, b, epsilon) && Math.abs(a.x - b.x) > epsilon;\n}\n\nexport function isVerticalSegment(a: Point, b: Point, epsilon = EPS): boolean {\n return sameX(a, b, epsilon) && Math.abs(a.y - b.y) > epsilon;\n}\n\nexport function overlapLength(a1: number, a2: number, b1: number, b2: number): number {\n return Math.max(\n 0,\n Math.min(Math.max(a1, a2), Math.max(b1, b2)) - Math.max(Math.min(a1, a2), Math.min(b1, b2))\n );\n}\n\nexport function sameAxisSegmentOverlapLength(\n a: OrthogonalSegment,\n b: OrthogonalSegment,\n epsilon = EPS\n): number {\n if (a.horizontal && b.horizontal && sameY(a.a, b.a, epsilon)) {\n return overlapLength(a.a.x, a.b.x, b.a.x, b.b.x);\n }\n if (a.vertical && b.vertical && sameX(a.a, b.a, epsilon)) {\n return overlapLength(a.a.y, a.b.y, b.a.y, b.b.y);\n }\n return 0;\n}\n\nexport function orthogonalSegmentsForPoints(points: Point[], epsilon = EPS): OrthogonalSegment[] {\n const result: OrthogonalSegment[] = [];\n for (let i = 0; i < points.length - 1; i++) {\n const a = points[i];\n const b = points[i + 1];\n const horizontal = isHorizontalSegment(a, b, epsilon);\n const vertical = isVerticalSegment(a, b, epsilon);\n if (horizontal || vertical) {\n result.push({ index: i, a, b, horizontal, vertical });\n }\n }\n return result;\n}\n\nexport function countOrthogonalBends(points: Point[], epsilon = EPS): number {\n const segments = orthogonalSegmentsForPoints(points, epsilon);\n let bends = 0;\n for (let i = 1; i < segments.length; i++) {\n if (segments[i - 1].horizontal !== segments[i].horizontal) {\n bends++;\n }\n }\n return bends;\n}\n\nexport function dedupeConsecutivePoints(points: Point[], epsilon = EPS): Point[] {\n const result: Point[] = [];\n for (const point of points) {\n const last = result.length > 0 ? result[result.length - 1] : undefined;\n if (!last || !samePoint(last, point, epsilon)) {\n result.push({ x: point.x, y: point.y });\n }\n }\n return result;\n}\n\nexport function classifyThreeSegmentRoute(\n points: Point[] | undefined,\n epsilon = EPS\n): ThreeSegmentRoute | undefined {\n if (!points || points.length !== 4) {\n return undefined;\n }\n const [p0, p1, p2, p3] = points;\n const isHVH =\n isHorizontalSegment(p0, p1, epsilon) &&\n isVerticalSegment(p1, p2, epsilon) &&\n isHorizontalSegment(p2, p3, epsilon);\n if (isHVH) {\n return { kind: 'HVH', p0, p1, p2, p3 };\n }\n const isVHV =\n isVerticalSegment(p0, p1, epsilon) &&\n isHorizontalSegment(p1, p2, epsilon) &&\n isVerticalSegment(p2, p3, epsilon);\n return isVHV ? { kind: 'VHV', p0, p1, p2, p3 } : undefined;\n}\n\nexport function segmentBoundsOverlapRect(\n a: Point,\n b: Point,\n rect: RectBounds,\n buffer = 0\n): boolean {\n const segMinX = Math.min(a.x, b.x);\n const segMaxX = Math.max(a.x, b.x);\n const segMinY = Math.min(a.y, b.y);\n const segMaxY = Math.max(a.y, b.y);\n return (\n segMaxX > rect.left - buffer &&\n segMinX < rect.right + buffer &&\n segMaxY > rect.top - buffer &&\n segMinY < rect.bottom + buffer\n );\n}\n\nexport function pointInsideRect(point: Point, rect: RectBounds, buffer = 0): boolean {\n return (\n point.x > rect.left + buffer &&\n point.x < rect.right - buffer &&\n point.y > rect.top + buffer &&\n point.y < rect.bottom - buffer\n );\n}\n\nexport function rectContainsRect(outer: RectBounds, inner: RectBounds): boolean {\n return (\n outer.left <= inner.left &&\n outer.right >= inner.right &&\n outer.top <= inner.top &&\n outer.bottom >= inner.bottom\n );\n}\n\nexport function rectsOverlap(a: RectBounds, b: RectBounds): boolean {\n return a.left < b.right && a.right > b.left && a.top < b.bottom && a.bottom > b.top;\n}\n\nexport function inflateRect(rect: RectBounds, margin: number): RectBounds {\n return {\n left: rect.left - margin,\n right: rect.right + margin,\n top: rect.top - margin,\n bottom: rect.bottom + margin,\n };\n}\n\nexport function rectFromCenterSize(\n cx: number,\n cy: number,\n width: number,\n height: number\n): RectBounds {\n return {\n left: cx - width / 2,\n right: cx + width / 2,\n top: cy - height / 2,\n bottom: cy + height / 2,\n };\n}\n\nexport function rectOfNodeBounds(node: RectNodeInput): RectBounds | undefined {\n return measuredNodeRect(node)?.rect;\n}\n\nexport function portForRectSide(\n node: { cx: number; cy: number; rect: RectBounds },\n side: RectSide\n): Point {\n switch (side) {\n case 'top':\n return { x: node.cx, y: node.rect.top };\n case 'bottom':\n return { x: node.cx, y: node.rect.bottom };\n case 'left':\n return { x: node.rect.left, y: node.cy };\n case 'right':\n return { x: node.rect.right, y: node.cy };\n }\n}\n\nexport function buildOrthogonalPortPath(\n src: Point,\n srcSide: RectSide,\n dst: Point,\n dstSide: RectSide,\n anchor: number,\n epsilon = EPS\n): Point[] | undefined {\n const srcH = srcSide === 'left' || srcSide === 'right';\n const dstH = dstSide === 'left' || dstSide === 'right';\n\n if (srcH && dstH) {\n const opposingDir =\n (srcSide === 'right' && dstSide === 'left' && src.x < dst.x) ||\n (srcSide === 'left' && dstSide === 'right' && src.x > dst.x);\n if (opposingDir) {\n if (sameY(src, dst, epsilon)) {\n return [src, dst];\n }\n const midX = (src.x + dst.x) / 2;\n return [src, { x: midX, y: src.y }, { x: midX, y: dst.y }, dst];\n }\n if (srcSide === dstSide) {\n if (sameY(src, dst, epsilon)) {\n return undefined;\n }\n const intX =\n srcSide === 'left' ? Math.min(src.x, dst.x) - anchor : Math.max(src.x, dst.x) + anchor;\n return [src, { x: intX, y: src.y }, { x: intX, y: dst.y }, dst];\n }\n return undefined;\n }\n\n if (!srcH && !dstH) {\n if (srcSide === dstSide) {\n if (sameX(src, dst, epsilon)) {\n return undefined;\n }\n const intY =\n srcSide === 'top' ? Math.min(src.y, dst.y) - anchor : Math.max(src.y, dst.y) + anchor;\n return [src, { x: src.x, y: intY }, { x: dst.x, y: intY }, dst];\n }\n const sameDir =\n (srcSide === 'bottom' && dstSide === 'top' && src.y < dst.y) ||\n (srcSide === 'top' && dstSide === 'bottom' && src.y > dst.y);\n if (!sameDir) {\n return undefined;\n }\n if (sameX(src, dst, epsilon)) {\n return [src, dst];\n }\n const midY = (src.y + dst.y) / 2;\n return [src, { x: src.x, y: midY }, { x: dst.x, y: midY }, dst];\n }\n\n if (srcH && !dstH) {\n const sameDirSrc =\n (srcSide === 'right' && dst.x > src.x) || (srcSide === 'left' && dst.x < src.x);\n const sameDirDst =\n (dstSide === 'top' && src.y < dst.y) || (dstSide === 'bottom' && src.y > dst.y);\n return sameDirSrc && sameDirDst ? [src, { x: dst.x, y: src.y }, dst] : undefined;\n }\n\n const sameDirSrc =\n (srcSide === 'bottom' && dst.y > src.y) || (srcSide === 'top' && dst.y < src.y);\n const sameDirDst =\n (dstSide === 'left' && src.x < dst.x) || (dstSide === 'right' && src.x > dst.x);\n return sameDirSrc && sameDirDst ? [src, { x: src.x, y: dst.y }, dst] : undefined;\n}\n\nexport function buildSameSideTrackPath(\n src: Point,\n side: RectSide,\n dst: Point,\n track: number\n): Point[] {\n return side === 'left' || side === 'right'\n ? [src, { x: track, y: src.y }, { x: track, y: dst.y }, dst]\n : [src, { x: src.x, y: track }, { x: dst.x, y: track }, dst];\n}\n\nexport function collectRealNodeBounds(nodes: Iterable<NodeBoundsInput>): {\n nodeInfoById: Map<string, NodeBoundsInfo>;\n realNodeRects: RectEntry[];\n} {\n const nodeInfoById = new Map<string, NodeBoundsInfo>();\n const realNodeRects: RectEntry[] = [];\n for (const node of nodes) {\n if (node.isEdgeLabel) {\n continue;\n }\n const info = nodeBoundsInfoFor(node);\n if (!info) {\n continue;\n }\n nodeInfoById.set(info.id, info);\n realNodeRects.push({ id: info.id, rect: info.rect });\n }\n return { nodeInfoById, realNodeRects };\n}\n\nexport function collectNodeRectEntries(nodes: Iterable<NodeBoundsInput>): {\n realNodeRects: RectEntry[];\n labelNodeRects: RectEntry[];\n} {\n const realNodeRects: RectEntry[] = [];\n const labelNodeRects: RectEntry[] = [];\n for (const node of nodes) {\n const info = nodeBoundsInfoFor(node);\n if (!info) {\n continue;\n }\n const entry = { id: info.id, rect: info.rect };\n if (node.isEdgeLabel) {\n labelNodeRects.push(entry);\n } else {\n realNodeRects.push(entry);\n }\n }\n return { realNodeRects, labelNodeRects };\n}\n\nexport function collectLayoutNodeRects(\n nodes: Iterable<NodeBoundsInput>,\n { includeEdgeLabels = true }: { includeEdgeLabels?: boolean } = {}\n): LayoutNodeRect[] {\n const result: LayoutNodeRect[] = [];\n for (const node of nodes) {\n if (node.isGroup || (!includeEdgeLabels && node.isEdgeLabel)) {\n continue;\n }\n const cx = node.x ?? 0;\n const cy = node.y ?? 0;\n const width = node.width ?? 0;\n const height = node.height ?? 0;\n result.push({\n nodeId: node.id!,\n ...rectFromCenterSize(cx, cy, width, height),\n });\n }\n return result;\n}\n\nexport function getNodePairGeometry(\n edge: EdgeEndpointInput,\n nodeInfoById: Map<string, NodeBoundsInfo>,\n epsilon = EPS\n): NodePairGeometry | undefined {\n const srcId = edge.start;\n const dstId = edge.end;\n if (!srcId || !dstId) {\n return undefined;\n }\n const srcInfo = nodeInfoById.get(srcId);\n const dstInfo = nodeInfoById.get(dstId);\n if (!srcInfo || !dstInfo) {\n return undefined;\n }\n return {\n srcId,\n dstId,\n srcInfo,\n dstInfo,\n collinearX: Math.abs(srcInfo.cx - dstInfo.cx) < epsilon,\n collinearY: Math.abs(srcInfo.cy - dstInfo.cy) < epsilon,\n };\n}\n\nexport function segmentHitsAnyRect(\n a: Point,\n b: Point,\n rects: RectEntry[],\n excludeIds: string[] = [],\n shrink = 0\n): boolean {\n for (const entry of rects) {\n if (excludeIds.includes(entry.id)) {\n continue;\n }\n if (segmentBoundsOverlapRect(a, b, entry.rect, -shrink)) {\n return true;\n }\n }\n return false;\n}\n\nexport function orthogonalSegmentsCross(\n a1: Point,\n b1: Point,\n a2: Point,\n b2: Point,\n epsilon = EPS,\n endpointTolerance = 1e-6\n): boolean {\n const s1H = sameY(a1, b1, epsilon);\n const s1V = sameX(a1, b1, epsilon);\n const s2H = sameY(a2, b2, epsilon);\n const s2V = sameX(a2, b2, epsilon);\n if ((s1H && s2H) || (s1V && s2V)) {\n return false;\n }\n if (!(s1H || s1V) || !(s2H || s2V)) {\n return false;\n }\n\n const horiz = s1H ? { a: a1, b: b1 } : { a: a2, b: b2 };\n const vert = s1V ? { a: a1, b: b1 } : { a: a2, b: b2 };\n const hY = horiz.a.y;\n const hX1 = Math.min(horiz.a.x, horiz.b.x);\n const hX2 = Math.max(horiz.a.x, horiz.b.x);\n const vX = vert.a.x;\n const vY1 = Math.min(vert.a.y, vert.b.y);\n const vY2 = Math.max(vert.a.y, vert.b.y);\n if (vX < hX1 || vX > hX2 || hY < vY1 || hY > vY2) {\n return false;\n }\n\n const matchesHorizEndpoint =\n (Math.abs(vX - horiz.a.x) < endpointTolerance &&\n Math.abs(hY - horiz.a.y) < endpointTolerance) ||\n (Math.abs(vX - horiz.b.x) < endpointTolerance && Math.abs(hY - horiz.b.y) < endpointTolerance);\n const matchesVertEndpoint =\n (Math.abs(vX - vert.a.x) < endpointTolerance && Math.abs(hY - vert.a.y) < endpointTolerance) ||\n (Math.abs(vX - vert.b.x) < endpointTolerance && Math.abs(hY - vert.b.y) < endpointTolerance);\n return !(matchesHorizEndpoint && matchesVertEndpoint);\n}\n\nexport function sameAxisSegmentsOverlap(\n a1: Point,\n b1: Point,\n a2: Point,\n b2: Point,\n epsilon = EPS\n): boolean {\n const s1H = sameY(a1, b1, epsilon);\n const s1V = sameX(a1, b1, epsilon);\n const s2H = sameY(a2, b2, epsilon);\n const s2V = sameX(a2, b2, epsilon);\n if (s1V && s2V && sameX(a1, a2, epsilon)) {\n return overlapLength(a1.y, b1.y, a2.y, b2.y) > epsilon;\n }\n if (s1H && s2H && sameY(a1, a2, epsilon)) {\n return overlapLength(a1.x, b1.x, a2.x, b2.x) > epsilon;\n }\n return false;\n}\n\nexport function segmentConflictsWithAnyEdge(\n a: Point,\n b: Point,\n edges: Iterable<EdgeSegmentInput>,\n excludeEdge?: EdgeSegmentInput,\n {\n epsilon = EPS,\n skipDegenerateOther = false,\n }: { epsilon?: number; skipDegenerateOther?: boolean } = {}\n): boolean {\n for (const other of edges) {\n if (other === excludeEdge || other.isLayoutOnly) {\n continue;\n }\n const points = other.points;\n if (!points || points.length < 2) {\n continue;\n }\n for (let i = 0; i < points.length - 1; i++) {\n const oa = points[i];\n const ob = points[i + 1];\n if (skipDegenerateOther && samePoint(oa, ob, epsilon)) {\n continue;\n }\n if (\n orthogonalSegmentsCross(a, b, oa, ob, epsilon) ||\n sameAxisSegmentsOverlap(a, b, oa, ob, epsilon)\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\nexport function orthogonalSegmentsStrictlyCross(\n a1: Point,\n b1: Point,\n a2: Point,\n b2: Point,\n epsilon = EPS\n): boolean {\n const aHoriz = sameY(a1, b1, epsilon);\n const aVert = sameX(a1, b1, epsilon);\n const bHoriz = sameY(a2, b2, epsilon);\n const bVert = sameX(a2, b2, epsilon);\n if (!((aHoriz && bVert) || (aVert && bHoriz))) {\n return false;\n }\n\n const horiz = aHoriz ? { a: a1, b: b1 } : { a: a2, b: b2 };\n const vert = aHoriz ? { a: a2, b: b2 } : { a: a1, b: b1 };\n const hY = horiz.a.y;\n const hXmin = Math.min(horiz.a.x, horiz.b.x);\n const hXmax = Math.max(horiz.a.x, horiz.b.x);\n const vX = vert.a.x;\n const vYmin = Math.min(vert.a.y, vert.b.y);\n const vYmax = Math.max(vert.a.y, vert.b.y);\n return (\n vX > hXmin + epsilon && vX < hXmax - epsilon && hY > vYmin + epsilon && hY < vYmax - epsilon\n );\n}\n\nfunction strictlyBetween(value: number, a: number, b: number): boolean {\n const lo = Math.min(a, b);\n const hi = Math.max(a, b);\n return value > lo + EPS && value < hi - EPS;\n}\n\nfunction isCollinearIntermediate(prev: Point, cur: Point, next: Point): boolean {\n if (sameX(prev, cur) && sameX(cur, next)) {\n return strictlyBetween(cur.y, prev.y, next.y);\n }\n\n if (sameY(prev, cur) && sameY(cur, next)) {\n return strictlyBetween(cur.x, prev.x, next.x);\n }\n\n return false;\n}\n\nfunction simplifyPolylineOnce(points: Point[]): SimplifyPassResult {\n let changed = false;\n const out: Point[] = [];\n\n for (let i = 0; i < points.length; i++) {\n const prev = out[out.length - 1];\n const cur = points[i];\n const next = i + 1 < points.length ? points[i + 1] : undefined;\n if (prev && next) {\n if (samePoint(prev, next)) {\n i++;\n changed = true;\n continue;\n }\n\n if (isCollinearIntermediate(prev, cur, next)) {\n changed = true;\n continue;\n }\n }\n out.push(cur);\n }\n\n return { points: out, changed };\n}\n\n// Inserts orthogonal L-bends and removes consecutive duplicate points.\nexport function orthogonalizePolyline(pts: Point[]): Point[] {\n const cleaned: Point[] = [pts[0]];\n for (let i = 1; i < pts.length; i++) {\n const prev = cleaned[cleaned.length - 1];\n const curr = pts[i];\n if (!sameX(prev, curr) && !sameY(prev, curr)) {\n const prevPrev = cleaned.length >= 2 ? cleaned[cleaned.length - 2] : undefined;\n const incomingVertical = prevPrev ? sameX(prevPrev, prev) : false;\n const corner = incomingVertical ? { x: prev.x, y: curr.y } : { x: curr.x, y: prev.y };\n cleaned.push(corner);\n }\n cleaned.push(curr);\n }\n const deduped: Point[] = [];\n for (const p of cleaned) {\n const last = deduped[deduped.length - 1];\n if (!last || !samePoint(last, p)) {\n deduped.push(p);\n }\n }\n return deduped;\n}\n\nexport function simplifyPolyline(pts: Point[]): Point[] {\n if (pts.length < 3) {\n return pts;\n }\n let work = [...pts];\n for (let guard = 0; guard < 32; guard++) {\n const result = simplifyPolylineOnce(work);\n work = result.points;\n if (!result.changed) {\n break;\n }\n }\n return work;\n}\n", "import {\n dedupeConsecutivePoints,\n orthogonalizePolyline,\n pointInsideRect,\n rectOfNodeBounds,\n samePoint,\n sameX,\n sameY,\n simplifyPolyline,\n} from './geometry.js';\nimport type { Point, RectBounds } from './geometry.js';\n\nconst EPS = 1e-3;\nconst INSIDE_EPS = 0.5;\nconst CORNER_CLEARANCE = 4;\n\ntype NodeRect = RectBounds;\n\ntype BorderSide = 'top' | 'bottom' | 'left' | 'right';\n\ninterface EndpointEdge {\n isLayoutOnly?: boolean;\n points?: Point[];\n start?: string;\n end?: string;\n}\n\nfunction endpointContextFor(edge: unknown, nodeByIdMap: Map<string, any>, minPoints: number) {\n const candidate = edge as EndpointEdge;\n if (candidate.isLayoutOnly || !candidate.points || candidate.points.length < minPoints) {\n return undefined;\n }\n const src = candidate.start ? nodeByIdMap.get(candidate.start) : undefined;\n const dst = candidate.end ? nodeByIdMap.get(candidate.end) : undefined;\n return {\n edge: candidate,\n points: candidate.points,\n srcRect: src ? rectOfNodeBounds(src) : undefined,\n dstRect: dst ? rectOfNodeBounds(dst) : undefined,\n };\n}\n\n// Given an axis-aligned segment from outside a rect to inside it, return the\n// point where the segment enters the rect boundary.\nfunction segmentEnterPoint(outside: Point, inside: Point, r: NodeRect): Point {\n if (sameY(outside, inside, EPS)) {\n const x = outside.x < r.left ? r.left : r.right;\n return { x, y: outside.y };\n }\n if (sameX(outside, inside, EPS)) {\n const y = outside.y < r.top ? r.top : r.bottom;\n return { x: outside.x, y };\n }\n return {\n x: Math.min(r.right, Math.max(r.left, outside.x)),\n y: Math.min(r.bottom, Math.max(r.top, outside.y)),\n };\n}\n\nfunction clipEndpoint(points: Point[], rect: NodeRect, atStart: boolean): Point[] {\n const step = atStart ? 1 : -1;\n let outsideIndex = atStart ? 0 : points.length - 1;\n while (\n outsideIndex >= 0 &&\n outsideIndex < points.length &&\n pointInsideRect(points[outsideIndex], rect, INSIDE_EPS)\n ) {\n outsideIndex += step;\n }\n if (outsideIndex < 0 || outsideIndex >= points.length) {\n return points;\n }\n\n const insideIndex = outsideIndex - step;\n if (insideIndex < 0 || insideIndex >= points.length) {\n return points;\n }\n\n const entry = segmentEnterPoint(points[outsideIndex], points[insideIndex], rect);\n return atStart\n ? [entry, ...points.slice(outsideIndex)]\n : [...points.slice(0, outsideIndex + 1), entry];\n}\n\nexport function clipEdgeEndpointsToNodeBoundaries(edges: unknown[], nodeByIdMap: Map<string, any>) {\n for (const edge of edges) {\n const context = endpointContextFor(edge, nodeByIdMap, 2);\n if (!context) {\n continue;\n }\n\n let next = [...context.points];\n if (context.srcRect) {\n next = clipEndpoint(next, context.srcRect, true);\n }\n if (context.dstRect) {\n next = clipEndpoint(next, context.dstRect, false);\n }\n next = simplifyPolyline(orthogonalizePolyline(next));\n next = clearStraightEndpointCornerConnections(next, context.srcRect, context.dstRect);\n context.edge.points = simplifyPolyline(orthogonalizePolyline(next));\n }\n}\n\nfunction snapEndpointToBoundary(\n inner: Point,\n endpoint: Point,\n r: NodeRect,\n useApproachSide = false\n): Point {\n if (sameY(inner, endpoint, EPS)) {\n if (endpoint.y < r.top - EPS || endpoint.y > r.bottom + EPS) {\n return endpoint;\n }\n if (useApproachSide) {\n if (inner.x < r.left - EPS) {\n return { x: r.left, y: inner.y };\n }\n if (inner.x > r.right + EPS) {\n return { x: r.right, y: inner.y };\n }\n }\n const toLeft = Math.abs(endpoint.x - r.left) <= Math.abs(endpoint.x - r.right);\n return { x: toLeft ? r.left : r.right, y: inner.y };\n }\n if (sameX(inner, endpoint, EPS)) {\n if (endpoint.x < r.left - EPS || endpoint.x > r.right + EPS) {\n return endpoint;\n }\n if (useApproachSide) {\n if (inner.y < r.top - EPS) {\n return { x: inner.x, y: r.top };\n }\n if (inner.y > r.bottom + EPS) {\n return { x: inner.x, y: r.bottom };\n }\n }\n const toTop = Math.abs(endpoint.y - r.top) <= Math.abs(endpoint.y - r.bottom);\n return { x: inner.x, y: toTop ? r.top : r.bottom };\n }\n return endpoint;\n}\n\nfunction firstDistinctAdjacent(\n points: Point[],\n endpointIndex: number,\n step: 1 | -1\n): Point | undefined {\n const endpoint = points[endpointIndex];\n for (let index = endpointIndex + step; index >= 0 && index < points.length; index += step) {\n const candidate = points[index];\n if (!samePoint(candidate, endpoint, EPS)) {\n return candidate;\n }\n }\n return points[endpointIndex + step];\n}\n\nfunction cornerClearanceRange(min: number, max: number): { lo: number; hi: number } {\n const lo = min + CORNER_CLEARANCE;\n const hi = max - CORNER_CLEARANCE;\n return lo <= hi ? { lo, hi } : { lo: (min + max) / 2, hi: (min + max) / 2 };\n}\n\nfunction clampToCornerClearance(value: number, min: number, max: number): number {\n const { lo, hi } = cornerClearanceRange(min, max);\n return Math.min(hi, Math.max(lo, value));\n}\n\nfunction intersectRanges(\n ranges: { lo: number; hi: number }[]\n): { lo: number; hi: number } | undefined {\n const lo = Math.max(...ranges.map((range) => range.lo));\n const hi = Math.min(...ranges.map((range) => range.hi));\n if (lo > hi) {\n return undefined;\n }\n return { lo, hi };\n}\n\nfunction clearanceRangeForSide(r: NodeRect, side: BorderSide): { lo: number; hi: number } {\n return side === 'left' || side === 'right'\n ? cornerClearanceRange(r.top, r.bottom)\n : cornerClearanceRange(r.left, r.right);\n}\n\nfunction terminalSideForSegment(\n endpoint: Point,\n adjacent: Point,\n r: NodeRect\n): BorderSide | undefined {\n const yWithin = endpoint.y >= r.top - EPS && endpoint.y <= r.bottom + EPS;\n const xWithin = endpoint.x >= r.left - EPS && endpoint.x <= r.right + EPS;\n if (sameY(endpoint, adjacent, EPS) && yWithin) {\n if (Math.abs(endpoint.x - r.left) < EPS) {\n return 'left';\n }\n if (Math.abs(endpoint.x - r.right) < EPS) {\n return 'right';\n }\n }\n if (sameX(endpoint, adjacent, EPS) && xWithin) {\n if (Math.abs(endpoint.y - r.top) < EPS) {\n return 'top';\n }\n if (Math.abs(endpoint.y - r.bottom) < EPS) {\n return 'bottom';\n }\n }\n return undefined;\n}\n\nfunction isHorizontalSide(side: BorderSide): boolean {\n return side === 'left' || side === 'right';\n}\n\nfunction straightClearanceRange(\n start: Point,\n end: Point,\n srcRect: NodeRect | undefined,\n dstRect: NodeRect | undefined,\n horizontal: boolean\n): { lo: number; hi: number } | undefined {\n const ranges: { lo: number; hi: number }[] = [];\n const srcSide = srcRect ? terminalSideForSegment(start, end, srcRect) : undefined;\n const dstSide = dstRect ? terminalSideForSegment(end, start, dstRect) : undefined;\n\n if (srcRect && srcSide && isHorizontalSide(srcSide) === horizontal) {\n ranges.push(clearanceRangeForSide(srcRect, srcSide));\n }\n if (dstRect && dstSide && isHorizontalSide(dstSide) === horizontal) {\n ranges.push(clearanceRangeForSide(dstRect, dstSide));\n }\n\n return ranges.length > 0 ? intersectRanges(ranges) : undefined;\n}\n\nfunction clearStraightEndpointCornerAxis(\n start: Point,\n end: Point,\n srcRect: NodeRect | undefined,\n dstRect: NodeRect | undefined,\n horizontal: boolean\n): Point[] | undefined {\n const range = straightClearanceRange(start, end, srcRect, dstRect, horizontal);\n if (!range) {\n return undefined;\n }\n\n const current = horizontal ? start.y : start.x;\n const next = Math.min(range.hi, Math.max(range.lo, current));\n if (Math.abs(next - current) < EPS) {\n return undefined;\n }\n\n return horizontal\n ? [\n { x: start.x, y: next },\n { x: end.x, y: next },\n ]\n : [\n { x: next, y: start.y },\n { x: next, y: end.y },\n ];\n}\n\nfunction clearStraightEndpointCornerConnections(\n points: Point[],\n srcRect?: NodeRect,\n dstRect?: NodeRect\n): Point[] {\n if (points.length !== 2) {\n return points;\n }\n\n const [start, end] = points;\n if (sameY(start, end, EPS)) {\n return clearStraightEndpointCornerAxis(start, end, srcRect, dstRect, true) ?? points;\n }\n\n if (sameX(start, end, EPS)) {\n return clearStraightEndpointCornerAxis(start, end, srcRect, dstRect, false) ?? points;\n }\n\n return points;\n}\n\nfunction cornerClearedEndpoint(endpoint: Point, r: NodeRect, side: BorderSide): Point {\n return isHorizontalSide(side)\n ? { x: endpoint.x, y: clampToCornerClearance(endpoint.y, r.top, r.bottom) }\n : { x: clampToCornerClearance(endpoint.x, r.left, r.right), y: endpoint.y };\n}\n\nfunction moveCollinearEndpointRun(\n points: Point[],\n endpointIndex: number,\n step: 1 | -1,\n endpoint: Point,\n adjusted: Point,\n horizontalTerminal: boolean\n): Point[] {\n const next = points.map((point) => ({ ...point }));\n for (let index = endpointIndex; index >= 0 && index < points.length; index += step) {\n const point = points[index];\n if (horizontalTerminal && !sameY(point, endpoint, EPS)) {\n break;\n }\n if (!horizontalTerminal && !sameX(point, endpoint, EPS)) {\n break;\n }\n if (horizontalTerminal) {\n next[index].y = adjusted.y;\n } else {\n next[index].x = adjusted.x;\n }\n }\n return next;\n}\n\nfunction clearEndpointCornerConnection(points: Point[], r: NodeRect, atStart: boolean): Point[] {\n if (points.length < 2) {\n return points;\n }\n\n const endpointIndex = atStart ? 0 : points.length - 1;\n const step = atStart ? 1 : -1;\n const endpoint = points[endpointIndex];\n const adjacent = firstDistinctAdjacent(points, endpointIndex, step);\n if (!adjacent) {\n return points;\n }\n\n const side = terminalSideForSegment(endpoint, adjacent, r);\n if (!side) {\n return points;\n }\n\n const horizontalTerminal = isHorizontalSide(side);\n const adjusted = cornerClearedEndpoint(endpoint, r, side);\n if (samePoint(endpoint, adjusted, EPS)) {\n return points;\n }\n\n return moveCollinearEndpointRun(\n points,\n endpointIndex,\n step,\n endpoint,\n adjusted,\n horizontalTerminal\n );\n}\n\nfunction borderSideForSegment(a: Point, b: Point, r: NodeRect): BorderSide | undefined {\n const xWithin = Math.min(a.x, b.x) >= r.left - EPS && Math.max(a.x, b.x) <= r.right + EPS;\n const yWithin = Math.min(a.y, b.y) >= r.top - EPS && Math.max(a.y, b.y) <= r.bottom + EPS;\n if (Math.abs(a.y - r.top) < EPS && Math.abs(b.y - r.top) < EPS && xWithin) {\n return 'top';\n }\n if (Math.abs(a.y - r.bottom) < EPS && Math.abs(b.y - r.bottom) < EPS && xWithin) {\n return 'bottom';\n }\n if (Math.abs(a.x - r.left) < EPS && Math.abs(b.x - r.left) < EPS && yWithin) {\n return 'left';\n }\n if (Math.abs(a.x - r.right) < EPS && Math.abs(b.x - r.right) < EPS && yWithin) {\n return 'right';\n }\n return undefined;\n}\n\nfunction leavesOutward(side: BorderSide, from: Point, to: Point, r: NodeRect): boolean {\n switch (side) {\n case 'top':\n return sameX(from, to, EPS) && to.y < r.top - EPS;\n case 'bottom':\n return sameX(from, to, EPS) && to.y > r.bottom + EPS;\n case 'left':\n return sameY(from, to, EPS) && to.x < r.left - EPS;\n case 'right':\n return sameY(from, to, EPS) && to.x > r.right + EPS;\n }\n}\n\nfunction collapseOwnBorderStub(points: Point[], r: NodeRect, atStart: boolean): Point[] {\n if (points.length < 3) {\n return points;\n }\n if (atStart) {\n const side = borderSideForSegment(points[0], points[1], r);\n if (side && leavesOutward(side, points[1], points[2], r)) {\n return points.slice(1);\n }\n return points;\n }\n\n const last = points.length - 1;\n const side = borderSideForSegment(points[last - 1], points[last], r);\n if (side && leavesOutward(side, points[last - 1], points[last - 2], r)) {\n return points.slice(0, last);\n }\n return points;\n}\n\nfunction snapAndCollapseEndpoints(\n points: Point[],\n srcRect?: NodeRect,\n dstRect?: NodeRect\n): Point[] {\n let next = points;\n if (srcRect) {\n const adjacent = firstDistinctAdjacent(next, 0, 1);\n if (adjacent) {\n const snapped = snapEndpointToBoundary(adjacent, next[0], srcRect);\n if (snapped !== next[0]) {\n next = [snapped, ...next.slice(1)];\n }\n }\n next = collapseOwnBorderStub(next, srcRect, true);\n }\n if (dstRect) {\n const last = next.length - 1;\n const adjacent = firstDistinctAdjacent(next, last, -1);\n if (adjacent) {\n const snapped = snapEndpointToBoundary(adjacent, next[last], dstRect, true);\n if (snapped !== next[last]) {\n next = [...next.slice(0, last), snapped];\n }\n }\n next = collapseOwnBorderStub(next, dstRect, false);\n }\n\n const straightCleared = clearStraightEndpointCornerConnections(next, srcRect, dstRect);\n if (straightCleared !== next || next.length === 2) {\n return straightCleared;\n }\n\n if (srcRect) {\n next = clearEndpointCornerConnection(next, srcRect, true);\n }\n if (dstRect) {\n next = clearEndpointCornerConnection(next, dstRect, false);\n }\n return next;\n}\n\nexport function prepareEdgeEndpointsForRenderer(edges: unknown[], nodeByIdMap: Map<string, any>) {\n for (const edge of edges) {\n const context = endpointContextFor(edge, nodeByIdMap, 2);\n if (!context) {\n continue;\n }\n\n const input = dedupeConsecutivePoints(context.points, EPS);\n const newPts = snapAndCollapseEndpoints(input, context.srcRect, context.dstRect);\n if (newPts.length < 3) {\n context.edge.points = newPts;\n continue;\n }\n const duplicated = [\n newPts[0],\n { ...newPts[0] },\n ...newPts.slice(1, -1),\n newPts[newPts.length - 1],\n { ...newPts[newPts.length - 1] },\n ];\n context.edge.points = duplicated;\n }\n}\n", "import type { LayoutData } from '../../../types.js';\n\ntype LayoutNode = NonNullable<LayoutData['nodes']>[number] & { swimlaneContentTop?: number };\ntype Direction = 'LR' | 'RL';\ntype Axis = 'x' | 'y';\n\nfunction buildNodeMap(nodes: LayoutNode[]): Map<string, LayoutNode> {\n return new Map(nodes.map((node) => [node.id, node]));\n}\n\nfunction resolveTopLevelGroupId(\n node: LayoutNode,\n nodeById: Map<string, LayoutNode>\n): string | null {\n let parentId = node.parentId;\n let topLevelGroupId: string | null = null;\n while (parentId) {\n const parent = nodeById.get(parentId);\n if (!parent?.isGroup) {\n break;\n }\n topLevelGroupId = parent.id;\n parentId = parent.parentId;\n }\n return topLevelGroupId;\n}\n\nfunction groupDepth(group: LayoutNode, nodeById: Map<string, LayoutNode>): number {\n let depth = 0;\n let parentId = group.parentId;\n while (parentId) {\n const parent = nodeById.get(parentId);\n if (!parent?.isGroup) {\n break;\n }\n depth++;\n parentId = parent.parentId;\n }\n return depth;\n}\n\nfunction boundsForChildren(\n children: LayoutNode[]\n): { minX: number; maxX: number; minY: number; maxY: number } | null {\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n for (const child of children) {\n const cx = child.x;\n const cy = child.y;\n if (typeof cx !== 'number' || typeof cy !== 'number') {\n continue;\n }\n const w = child.width ?? 0;\n const h = child.height ?? 0;\n minX = Math.min(minX, cx - w / 2);\n maxX = Math.max(maxX, cx + w / 2);\n minY = Math.min(minY, cy - h / 2);\n maxY = Math.max(maxY, cy + h / 2);\n }\n if (minX === Infinity || minY === Infinity) {\n return null;\n }\n return { minX, maxX, minY, maxY };\n}\n\nfunction applyGroupBounds(\n group: LayoutNode,\n bounds: NonNullable<ReturnType<typeof boundsForChildren>>\n) {\n const pad = group.padding ?? 20;\n group.x = (bounds.minX + bounds.maxX) / 2;\n group.y = (bounds.minY + bounds.maxY) / 2;\n group.width = Math.max(0, bounds.maxX - bounds.minX) + pad;\n group.height = Math.max(0, bounds.maxY - bounds.minY) + pad;\n}\n\nfunction recomputeNestedGroupBounds(nodes: LayoutNode[]): void {\n const nodeById = buildNodeMap(nodes);\n const groupsByDepth = nodes\n .filter((node) => node.isGroup && node.parentId)\n .sort((a, b) => groupDepth(b, nodeById) - groupDepth(a, nodeById));\n\n for (const group of groupsByDepth) {\n const children = nodes.filter((node) => node.parentId === group.id);\n const bounds = boundsForChildren(children);\n if (bounds) {\n applyGroupBounds(group, bounds);\n }\n }\n}\n\nfunction mirrorAxis(layout: LayoutData, axis: Axis): boolean {\n const nodes = (layout.nodes ?? []) as LayoutNode[];\n const edges = layout.edges ?? [];\n const contentNodes = nodes.filter((node) => !node.isGroup);\n let min = Infinity;\n let max = -Infinity;\n for (const node of contentNodes) {\n const value = node[axis];\n if (typeof value !== 'number') {\n continue;\n }\n min = Math.min(min, value);\n max = Math.max(max, value);\n }\n if (!Number.isFinite(min) || !Number.isFinite(max)) {\n return false;\n }\n const mirror = (value: number) => min + max - value;\n for (const node of nodes) {\n const value = node[axis];\n if (typeof value === 'number') {\n node[axis] = mirror(value);\n }\n const titleRect = node.groupTitleRect;\n if (titleRect) {\n node.groupTitleRect =\n axis === 'x'\n ? {\n ...titleRect,\n left: mirror(titleRect.right),\n right: mirror(titleRect.left),\n }\n : {\n ...titleRect,\n top: mirror(titleRect.bottom),\n bottom: mirror(titleRect.top),\n };\n }\n }\n for (const edge of edges) {\n for (const point of edge.points ?? []) {\n point[axis] = mirror(point[axis]);\n }\n }\n return true;\n}\n\nexport function applyBtDirectionTransform(layout: LayoutData): boolean {\n const nodes = (layout.nodes ?? []) as LayoutNode[];\n if (!nodes.some((node) => !node.isGroup)) {\n return true;\n }\n\n return mirrorAxis(layout, 'y');\n}\n\nexport function applyLrDirectionTransform(\n layout: LayoutData,\n direction: Direction = 'LR'\n): boolean {\n const nodes = (layout.nodes ?? []) as LayoutNode[];\n const edges = layout.edges ?? [];\n const contentNodes = nodes.filter((n) => !n.isGroup);\n\n let minX = Infinity;\n let minY = Infinity;\n for (const n of contentNodes) {\n const x0 = n.x ?? 0;\n const y0 = n.y ?? 0;\n if (x0 < minX) {\n minX = x0;\n }\n if (y0 < minY) {\n minY = y0;\n }\n }\n\n if (!Number.isFinite(minX) || !Number.isFinite(minY)) {\n return false;\n }\n\n const titleBandSize = 36;\n\n let totalWidth = 0;\n let totalHeight = 0;\n for (const n of contentNodes) {\n totalWidth += n.width ?? 0;\n totalHeight += n.height ?? 0;\n }\n const avgWidth = totalWidth / contentNodes.length;\n const avgHeight = totalHeight / contentNodes.length;\n const horizontalScaleFactor = avgHeight > 0 ? Math.max(1, avgWidth / avgHeight) : 1;\n\n for (const n of contentNodes) {\n const x0 = n.x ?? 0;\n const y0 = n.y ?? 0;\n const newX = (y0 - minY) * horizontalScaleFactor + titleBandSize;\n const newY = x0 - minX;\n\n n.x = newX;\n n.y = newY;\n }\n\n for (const e of edges) {\n if (!e.points) {\n continue;\n }\n for (const p of e.points) {\n const x0 = p.x;\n const y0 = p.y;\n const newX = (y0 - minY) * horizontalScaleFactor + titleBandSize;\n const newY = x0 - minX;\n p.x = newX;\n p.y = newY;\n }\n }\n\n recomputeNestedGroupBounds(nodes);\n\n const laneNodes = nodes.filter((n) => n.isGroup && !n.parentId);\n if (laneNodes.length === 0) {\n if (direction === 'RL') {\n mirrorAxis(layout, 'x');\n }\n return true;\n }\n\n const nodeById = buildNodeMap(nodes);\n const childrenByLane = new Map<string, LayoutNode[]>();\n\n for (const n of nodes) {\n if (n.isGroup) {\n continue;\n }\n const laneId = resolveTopLevelGroupId(n, nodeById);\n if (!laneId) {\n continue;\n }\n const bucket = childrenByLane.get(laneId) ?? [];\n bucket.push(n);\n childrenByLane.set(laneId, bucket);\n }\n\n let maxPad = 0;\n for (const lane of laneNodes) {\n const pad = lane.padding ?? 0;\n if (pad > maxPad) {\n maxPad = pad;\n }\n }\n\n const laneBounds: {\n lane: LayoutNode;\n contentTop: number;\n contentBottom: number;\n centerY: number;\n }[] = [];\n let globalMinXChild = Infinity;\n let globalMaxXChild = -Infinity;\n\n for (const lane of laneNodes) {\n const children = childrenByLane.get(lane.id) ?? [];\n const bounds = boundsForChildren(children);\n if (!bounds) {\n continue;\n }\n globalMinXChild = Math.min(globalMinXChild, bounds.minX);\n globalMaxXChild = Math.max(globalMaxXChild, bounds.maxX);\n\n laneBounds.push({\n lane,\n contentTop: bounds.minY,\n contentBottom: bounds.maxY,\n centerY: (bounds.minY + bounds.maxY) / 2,\n });\n }\n\n if (globalMinXChild === Infinity || globalMaxXChild === -Infinity) {\n return true;\n }\n\n const fullContentWidth = Math.max(0, globalMaxXChild - globalMinXChild);\n const horizontalMargin = Math.max(maxPad, 10);\n const bodyWidth = fullContentWidth + 2 * horizontalMargin;\n const laneWidth = titleBandSize + bodyWidth;\n const bodyCenter = (globalMinXChild + globalMaxXChild) / 2;\n const bodyLeft = bodyCenter - bodyWidth / 2;\n const laneLeft = bodyLeft - titleBandSize;\n const centerX = laneLeft + laneWidth / 2;\n const verticalMargin = Math.max(maxPad, titleBandSize);\n\n laneBounds.sort((a, b) => a.centerY - b.centerY);\n\n for (let i = 0; i < laneBounds.length; i++) {\n const curr = laneBounds[i];\n let laneTop: number;\n let laneBottom: number;\n\n if (i === 0) {\n laneTop = curr.contentTop - verticalMargin;\n } else {\n const prev = laneBounds[i - 1];\n laneTop = (prev.contentBottom + curr.contentTop) / 2;\n }\n\n if (i === laneBounds.length - 1) {\n laneBottom = curr.contentBottom + verticalMargin;\n } else {\n const next = laneBounds[i + 1];\n laneBottom = (curr.contentBottom + next.contentTop) / 2;\n }\n\n const laneHeight = Math.max(0, laneBottom - laneTop);\n const centerY = (laneTop + laneBottom) / 2;\n\n curr.lane.x = centerX;\n curr.lane.y = centerY;\n curr.lane.width = laneWidth;\n curr.lane.height = laneHeight;\n curr.lane.swimlaneContentTop = curr.contentTop;\n curr.lane.groupTitleRect = {\n left: laneLeft,\n right: laneLeft + titleBandSize,\n top: laneTop,\n bottom: laneBottom,\n };\n }\n\n if (direction === 'RL') {\n mirrorAxis(layout, 'x');\n }\n\n return true;\n}\n", "// cspell:ignore Battista Eades Eiglsperger Hegemann Kandinsky segs Siebenhaller Tamassia Tollis F\u00F6\u00DFmeier\nimport type { Edge, Node } from '../../../types.js';\nimport {\n classifyThreeSegmentRoute,\n collectRealNodeBounds,\n dedupeConsecutivePoints,\n getNodePairGeometry,\n samePoint,\n segmentConflictsWithAnyEdge,\n segmentHitsAnyRect,\n} from './geometry.js';\n\nconst EPS = 1e-6;\n// \u03B4_s \u2014 the Kandinsky port-spacing constant (F\u00F6\u00DFmeier\u2013Kaufmann 1995;\n// Siebenhaller dissertation \u00A76.1.2.2). When this pass places a second\n// edge on a face already occupied by a sibling centered at delta=0,\n// the canonical pairing is (0, \u00B1\u03B4_s) \u2014 full \u03B4_s separation between\n// port centers, not \u03B4_s/2. `straightenCollinearSiblingDetours` uses \u03B4_s/2\n// because that pass shifts BOTH members of a collinear pair\n// symmetrically (to \u00B1\u03B4_s/2, separation \u03B4_s); this pass shifts only\n// the single edge being swapped, so it must move the full \u03B4_s to\n// preserve the same canonical spacing.\nconst MIN_PORT_SPACING = 8;\nconst PORT_SHIFT = MIN_PORT_SPACING;\nconst TRY_DELTAS = [0, PORT_SHIFT, -PORT_SHIFT, 2 * PORT_SHIFT, -2 * PORT_SHIFT];\n\ninterface PointLite {\n x: number;\n y: number;\n}\n\n/**\n * Iter 17 \u2014 port-swap a 4-point H-V-H / V-H-V edge to a 3-point L-shape\n * when the current src port is \"straight-through\" (parallel to the\n * incoming edge) but a perpendicular src face permits a one-bend reach\n * to the existing dst port.\n *\n * Motivating case (user report 2026-04-16, 8-query-process-2.mmd):\n * L_A2_E_0 currently:\n * (A2.east=355.2, 0) \u2192 (gutter=402.3, 0)\n * \u2192 (402.3, 213.4) \u2192 (E.west=844.1, 213.4)\n * i.e. exits A2 on the east face (parallel to incoming A\u2192A2), bends\n * south, bends east \u2014 2 interior bends. The south face of A2 points\n * directly toward E's lane, so exiting south gives a 1-bend L-shape:\n * (A2.south=cx\u00B1\u03B4, 69.3) \u2192 (cx\u00B1\u03B4, 213.4) \u2192 (E.west=844.1, 213.4)\n * Saves one bend.\n *\n * Paper backing:\n * - Tamassia's bend-minimization flow (1987, and\n * Di Battista\u2013Eades\u2013Tamassia\u2013Tollis \u00A75): port/face assignment is a\n * free variable and the optimum switches faces whenever it saves a\n * bend.\n * - Kandinsky port distribution (F\u00F6\u00DFmeier\u2013Kaufmann 1995;\n * Siebenhaller dissertation \u00A72.3\u2013\u00A72.5): decision-diamond outgoing\n * edges favor distinct perpendicular faces.\n * - Siebenhaller \u00A73.3 \"Port Assignment\" + \u00A74.1 \"Bend optimization\":\n * local port-swap accepted iff (a) bends strictly decrease, (b) no\n * new crossings, (c) Kandinsky face-capacity preserved.\n * - Hegemann\u2013Wolff \u00A74.2 joint-feasibility (paper src `b65b3d45`):\n * the formal crossings + capacity guard set.\n *\n * Shape handled (src, dst NOT collinear):\n * H-V-H: p0 \u2192 p1 (horiz) \u2192 p2 (vert) \u2192 p3 (horiz);\n * src face E/W (parallel to seg01); swap to N/S.\n * V-H-V: p0 \u2192 p1 (vert) \u2192 p2 (horiz) \u2192 p3 (vert);\n * src face N/S (parallel to seg01); swap to E/W.\n *\n * Rewrite (H-V-H):\n * new_src_port = (src.cx + \u03B4, dst-below ? src.bottom : src.top)\n * new_polyline = [ new_src_port, (src.cx + \u03B4, p3.y), p3 ]\n * (V-H-V symmetric across axes.)\n *\n * Safety (the six guards from the iter-17 plan):\n * 1. Strict bend-count decrease \u2014 enforced by the 4-point \u2192 3-point\n * rewrite.\n * 2. No new edge-edge crossings \u2014 orthogonalSegmentsCross vs every other\n * non-self segment.\n * 3. No new edge-node collisions \u2014 segment-vs-node guard (both new segs,\n * excluding src for seg-1 and dst\n * for seg-2).\n * 4. Kandinsky face capacity \u2014 port-offset delta chosen from\n * 0, \u00B1PORT_SHIFT, \u00B12\u00B7PORT_SHIFT;\n * each candidate must lie strictly\n * within the src face span; the\n * collinear-axis overlap check\n * (shared axis + overlapping range)\n * rejects \u03B4 values that collide\n * with an existing sibling port.\n * 5. No label-rect overlap on new \u2014 re-done by anchorLabelsToPolyline\n * segments which runs after this pass.\n * 6. Monotonic on fixture suite \u2014 enforced externally by the DDLT\n * contract (no spec's totalBends or\n * crossings may increase).\n *\n * Distinct from `straightenCollinearSiblingDetours` (iter 12) which handles\n * the COLLINEAR case (4-point \u2192 2-point straight). This pass handles\n * the non-collinear case (4-point \u2192 3-point L). The two are disjoint\n * by the collinearX === collinearY guard: coRoute runs first and\n * converts collinear edges to 2-point straights which this pass then\n * skips by shape filter.\n *\n * Distinct from Eiglsperger bend-stretching (cited in iter 16\n * collapseShortTerminalStub): that pass requires the first and last\n * direction to be preserved; this pass explicitly CHANGES the first\n * direction \u2014 the whole point.\n */\nexport function portSwapToLShape(edges: Edge[], nodes: Node[]): void {\n const { nodeInfoById, realNodeRects } = collectRealNodeBounds(nodes);\n\n for (const edge of edges) {\n if (edge.isLayoutOnly) {\n continue;\n }\n const pts = edge.points;\n if (!pts || pts.length < 4) {\n continue;\n }\n\n // Dedupe consecutive identical points (raykov / endpoint-clip can\n // produce duplicates). We operate on the DEDUPED polyline but write\n // back without duplicates too \u2014 the rendering-handoff pass later\n // re-duplicates endpoints for the intersect-rect guard.\n const route = classifyThreeSegmentRoute(dedupeConsecutivePoints(pts, EPS), EPS);\n if (!route) {\n continue;\n }\n\n const { p3 } = route;\n const isHVH = route.kind === 'HVH';\n\n const nodePair = getNodePairGeometry(edge, nodeInfoById, EPS);\n if (!nodePair) {\n continue;\n }\n const { srcId, dstId, srcInfo, dstInfo, collinearX, collinearY } = nodePair;\n\n // Skip collinear src/dst \u2014 straightenCollinearSiblingDetours handles those.\n if (collinearX || collinearY) {\n continue;\n }\n\n // Build candidate new polyline.\n // H-V-H: swap src E/W face \u2192 N/S face. Preserve dst port (p3).\n // new p0 = (src.cx + \u03B4, dst-below ? src.bottom : src.top)\n // new p1 = (src.cx + \u03B4, p3.y)\n // new p2 = p3\n // V-H-V symmetric.\n let newPts: PointLite[] | undefined;\n const srcRect = srcInfo.rect;\n\n for (const delta of TRY_DELTAS) {\n let np0: PointLite;\n let np1: PointLite;\n let np2: PointLite;\n\n if (isHVH) {\n const dstBelow = dstInfo.cy > srcInfo.cy;\n const newSrcY = dstBelow ? srcRect.bottom : srcRect.top;\n const newSrcX = srcInfo.cx + delta;\n // Must lie strictly within src face span (exclusive of corners).\n if (newSrcX <= srcRect.left + EPS || newSrcX >= srcRect.right - EPS) {\n continue;\n }\n np0 = { x: newSrcX, y: newSrcY };\n np1 = { x: newSrcX, y: p3.y };\n np2 = { x: p3.x, y: p3.y };\n } else {\n // isVHV\n const dstEast = dstInfo.cx > srcInfo.cx;\n const newSrcX = dstEast ? srcRect.right : srcRect.left;\n const newSrcY = srcInfo.cy + delta;\n if (newSrcY <= srcRect.top + EPS || newSrcY >= srcRect.bottom - EPS) {\n continue;\n }\n np0 = { x: newSrcX, y: newSrcY };\n np1 = { x: p3.x, y: newSrcY };\n np2 = { x: p3.x, y: p3.y };\n }\n\n // Degenerate: if np1 === np2, the \"L\" collapses to a straight line.\n // Accept it (even better than a 1-bend L), but keep it as 2 pts.\n const firstSegDegenerate = samePoint(np0, np1, EPS);\n const secondSegDegenerate = samePoint(np1, np2, EPS);\n if (firstSegDegenerate && secondSegDegenerate) {\n continue;\n }\n\n // Guard 3: no edge-node collisions. Seg 1 may touch src; seg 2 may\n // touch dst. Excluding those ids from the hit check.\n if (!firstSegDegenerate && segmentHitsAnyRect(np0, np1, realNodeRects, [srcId], 1)) {\n continue;\n }\n if (!secondSegDegenerate && segmentHitsAnyRect(np1, np2, realNodeRects, [dstId], 1)) {\n continue;\n }\n\n // Guard 5: label overlap is checked by anchorLabelsToPolyline which\n // runs AFTER this pass and re-anchors each label onto its owning\n // edge's polyline (with along-segment parametric retry from iter\n // 14). At this pipeline stage labels still sit at stale Sugiyama\n // positions so a label-rect check here would reject against\n // positions that will imminently be moved. If anchorLabelsToPolyline\n // cannot find any legal anchor on the rewritten polyline,\n // validateLayout's label-on-edge-segment invariant will flag it at\n // DDLT level 1. Deliberately not checked here.\n\n // Guards 2 + 4: check every other edge's every segment for a\n // perpendicular crossing or a collinear-axis overlap with EITHER\n // of the new segments.\n const firstSegConflicts =\n !firstSegDegenerate &&\n segmentConflictsWithAnyEdge(np0, np1, edges, edge, {\n epsilon: EPS,\n skipDegenerateOther: true,\n });\n const secondSegConflicts =\n !secondSegDegenerate &&\n segmentConflictsWithAnyEdge(np1, np2, edges, edge, {\n epsilon: EPS,\n skipDegenerateOther: true,\n });\n if (firstSegConflicts || secondSegConflicts) {\n continue;\n }\n\n // All guards pass. Build the final polyline.\n if (firstSegDegenerate) {\n newPts = [np1, np2];\n } else if (secondSegDegenerate) {\n newPts = [np0, np1];\n } else {\n newPts = [np0, np1, np2];\n }\n break;\n }\n\n if (newPts) {\n edge.points = newPts;\n }\n }\n}\n", "// cspell:ignore Hegemann Wybrow penult\nimport {\n collectNodeRectEntries,\n dedupeConsecutivePoints,\n isHorizontalSegment,\n isVerticalSegment,\n orthogonalSegmentsStrictlyCross as segmentsCross,\n pointInsideRect,\n rectOfNodeBounds,\n sameX,\n sameY,\n segmentHitsAnyRect,\n} from './geometry.js';\nimport type { Point } from './geometry.js';\n\n/**\n * Iter 16 \u2014 collapse a short terminal stub at an edge's destination by\n * retargeting the destination face and dropping the corner. See the call-\n * site comment in `applySwimlaneDirectionTransform` for the user report and\n * paper backing (Siebenhaller `21f7ca55`; precedent in the retired\n * stale-port-offset straightener, Hegemann-Wolff `b65b3d45`).\n *\n * Shape handled:\n * ... \u2192 prev \u2192 penult \u2192 end\n * ~~~~~~~~~~~~~\n * penult perpendicular to last; `|end - penult| < MIN_STUB`.\n *\n * Rewrite:\n * ... \u2192 prev' \u2192 end'\n * where prev' keeps prev's \"far\" coordinate and adopts the destination's\n * face-center on the other axis, and end' is the destination face-center\n * on the approach axis (i.e. bottom/top when penult is vertical;\n * left/right when penult is horizontal \u2014 face chosen opposite to the\n * approach direction).\n *\n * Safety:\n * - Reject when the new prev'\u2192end' segment would enter any real-node\n * rect (excluding the dst itself), any label rect, or cross an\n * existing segment of a different edge (excluding its own segments).\n * - Reject when the new prev' lies inside the src node's rect.\n * - Only applied to the dst end; applying symmetrically on src\n * would need identical safety accounting and is out of scope here.\n */\nexport function collapseShortTerminalStub(edges: any[], nodeByIdMap: Map<string, any>): void {\n const MIN_STUB = 10;\n const EPS_LOCAL = 1e-3;\n const BUFFER = 2;\n\n type PointLite = Point;\n\n const { realNodeRects, labelNodeRects: labelRects } = collectNodeRectEntries(\n nodeByIdMap.values()\n );\n\n for (const edge of edges) {\n if ((edge as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const rawPts = (edge as { points?: PointLite[] }).points;\n if (!rawPts || rawPts.length < 4) {\n continue;\n }\n\n // Dedupe consecutive equal points so we measure the real last segment.\n const pts = dedupeConsecutivePoints(rawPts, EPS_LOCAL);\n if (pts.length < 4) {\n continue;\n }\n\n const nLast = pts.length - 1;\n const endPt = pts[nLast];\n const penultPt = pts[nLast - 1];\n const prevPt = pts[nLast - 2];\n\n // Last segment (penult \u2192 end): must be short.\n const lastDx = endPt.x - penultPt.x;\n const lastDy = endPt.y - penultPt.y;\n const lastLen = Math.hypot(lastDx, lastDy);\n if (lastLen >= MIN_STUB || lastLen < EPS_LOCAL) {\n continue;\n }\n\n // Penult segment (prev \u2192 penult): must be non-degenerate and\n // perpendicular to last.\n const penultDx = penultPt.x - prevPt.x;\n const penultDy = penultPt.y - prevPt.y;\n const penultLen = Math.hypot(penultDx, penultDy);\n if (penultLen < EPS_LOCAL) {\n continue;\n }\n\n const lastIsHoriz = isHorizontalSegment(penultPt, endPt, EPS_LOCAL);\n const lastIsVert = isVerticalSegment(penultPt, endPt, EPS_LOCAL);\n const penultIsHoriz = isHorizontalSegment(prevPt, penultPt, EPS_LOCAL);\n const penultIsVert = isVerticalSegment(prevPt, penultPt, EPS_LOCAL);\n if (!((lastIsHoriz && penultIsVert) || (lastIsVert && penultIsHoriz))) {\n continue;\n }\n\n const dstId = (edge as { end?: string }).end;\n const srcId = (edge as { start?: string }).start;\n const dst = dstId ? nodeByIdMap.get(dstId) : undefined;\n if (!dst) {\n continue;\n }\n const dstCx = (dst as { x?: number }).x ?? 0;\n const dstCy = (dst as { y?: number }).y ?? 0;\n const dstRect = rectOfNodeBounds(dst);\n if (!dstRect) {\n continue;\n }\n\n // Compute the new prev' and end'. The axis of approach is the\n // penult segment's axis; the new face is on the perpendicular to\n // the approach, opposite to the approach direction.\n let newPrev: { x: number; y: number };\n let newEnd: { x: number; y: number };\n if (penultIsVert) {\n // Vertical approach: penult goes up (penultDy<0) or down (penultDy>0).\n const approachFromBelow = penultDy < 0;\n newPrev = { x: dstCx, y: prevPt.y };\n newEnd = { x: dstCx, y: approachFromBelow ? dstRect.bottom : dstRect.top };\n } else {\n // Horizontal approach: penult goes right (penultDx>0) or left.\n const approachFromLeft = penultDx > 0;\n newPrev = { x: prevPt.x, y: dstCy };\n newEnd = { x: approachFromLeft ? dstRect.right : dstRect.left, y: dstCy };\n }\n\n // Reject if the new prev'\u2192end' vertical/horizontal segment would cross\n // any real-node rect (other than dst itself).\n if (segmentHitsAnyRect(newPrev, newEnd, realNodeRects, dstId ? [dstId] : [], -BUFFER)) {\n continue;\n }\n\n // Reject if the new approach segment would run through any label rect.\n if (segmentHitsAnyRect(newPrev, newEnd, labelRects, [], -BUFFER)) {\n continue;\n }\n\n // Reject if new prev' lies inside the src node's rect (pathological).\n if (srcId) {\n const src = nodeByIdMap.get(srcId);\n const srcRect = src ? rectOfNodeBounds(src) : undefined;\n if (srcRect && pointInsideRect(newPrev, srcRect, BUFFER)) {\n continue;\n }\n }\n\n // Also reject if the new prev'\u2192end' segment crosses any other edge's\n // existing segment (excluding our own segments we're about to replace).\n const ownSegmentKey = (a: PointLite, b: PointLite) =>\n `${a.x.toFixed(3)},${a.y.toFixed(3)}|${b.x.toFixed(3)},${b.y.toFixed(3)}`;\n const selfSegments = new Set<string>();\n for (let i = 0; i < pts.length - 1; i++) {\n selfSegments.add(ownSegmentKey(pts[i], pts[i + 1]));\n }\n\n const segmentCrossesOtherEdge = (from: PointLite, to: PointLite): boolean => {\n for (const other of edges) {\n if (other === edge) {\n continue;\n }\n if ((other as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const oPts = (other as { points?: PointLite[] }).points;\n if (!oPts || oPts.length < 2) {\n continue;\n }\n for (let i = 0; i < oPts.length - 1; i++) {\n const a = oPts[i];\n const b = oPts[i + 1];\n if (selfSegments.has(ownSegmentKey(a, b))) {\n continue;\n }\n if (segmentsCross(from, to, a, b, EPS_LOCAL)) {\n return true;\n }\n }\n }\n return false;\n };\n\n if (segmentCrossesOtherEdge(newPrev, newEnd)) {\n continue;\n }\n\n // Also: if the new prev' segment (from prev-before-prev to newPrev) is\n // degenerate or crosses anything, reject. The segment before the\n // original prev (pts[nLast-3] \u2192 prev) becomes (pts[nLast-3] \u2192 newPrev)\n // when we shift prev's axis.\n if (nLast - 3 >= 0) {\n const beforePrev = pts[nLast - 3];\n // The pre-existing segment was beforePrev \u2192 prev on the axis perpendicular\n // to penult. Shifting prev to newPrev preserves that axis alignment\n // (only the axis we're shifting changes). Re-check for obstacles on\n // the NEW extended segment.\n const endpointIds = [srcId, dstId].filter((id): id is string => Boolean(id));\n if (segmentHitsAnyRect(beforePrev, newPrev, realNodeRects, endpointIds, -BUFFER)) {\n continue;\n }\n if (segmentCrossesOtherEdge(beforePrev, newPrev)) {\n continue;\n }\n }\n\n // Build rewritten polyline: pts[0..nLast-3] + newPrev + newEnd.\n // This drops the original prev, penult, and end; replaces with newPrev\n // and newEnd (one fewer bend).\n const head = pts.slice(0, nLast - 2);\n const newPts = [...head, newPrev, newEnd];\n (edge as { points: PointLite[] }).points = newPts;\n\n // Re-anchor the edge's label (if any) onto the new polyline. The\n // original anchorLabelsToPolyline pass ran earlier in the pipeline\n // and placed the label against the old geometry; validateLayout\n // requires the polyline to pass through its label node. Place the\n // label at the midpoint of the longest segment of the new polyline\n // whose orientation matches the label's aspect.\n const labelId = (edge as { labelNodeId?: string }).labelNodeId;\n if (labelId) {\n const labelNode = nodeByIdMap.get(labelId);\n if (labelNode) {\n const lw = (labelNode as { width?: number }).width ?? 0;\n const lh = (labelNode as { height?: number }).height ?? 0;\n if (lw > 0 && lh > 0) {\n // Find longest segment \u2014 use its midpoint. Prefer axis-aligned\n // segments whose length >= the label's corresponding dim so\n // the label fits inside the segment's bounding run.\n let bestMidX: number | undefined;\n let bestMidY: number | undefined;\n let bestLen = -1;\n for (let i = 0; i < newPts.length - 1; i++) {\n const a = newPts[i];\n const b = newPts[i + 1];\n const segLen = Math.hypot(b.x - a.x, b.y - a.y);\n const isHoriz = sameY(a, b, EPS_LOCAL);\n const isVert = sameX(a, b, EPS_LOCAL);\n // Require axis-aligned and long enough to hold the label.\n const fits = (isHoriz && segLen >= lw + 2) || (isVert && segLen >= lh + 2);\n if (!fits) {\n continue;\n }\n if (segLen > bestLen) {\n bestLen = segLen;\n bestMidX = (a.x + b.x) / 2;\n bestMidY = (a.y + b.y) / 2;\n }\n }\n if (bestMidX !== undefined && bestMidY !== undefined) {\n (labelNode as { x: number }).x = bestMidX;\n (labelNode as { y: number }).y = bestMidY;\n }\n }\n }\n }\n }\n}\n", "// cspell:ignore Wybrow\n\nimport {\n collectNodeRectEntries,\n countOrthogonalBends,\n dedupeConsecutivePoints,\n isHorizontalSegment,\n isVerticalSegment,\n samePoint,\n sameX,\n sameY,\n buildOrthogonalPortPath,\n buildSameSideTrackPath,\n overlapLength,\n orthogonalSegmentsForPoints,\n orthogonalSegmentsStrictlyCross,\n portForRectSide,\n rectOfNodeBounds,\n sameAxisSegmentOverlapLength,\n segmentHitsAnyRect,\n simplifyPolyline,\n} from './geometry.js';\nimport type { OrthogonalSegment, Point, RectBounds, RectSide } from './geometry.js';\nimport type { Edge, Node } from '../../../types.js';\n\nconst EPS_LOCAL = 1e-3;\nconst MIN_SHARED = 8;\n\ntype PointLite = Point;\ntype RectLite = RectBounds;\ntype MaterializedEdge = Edge & { points?: PointLite[] };\ntype MaterializedNode = Node & { direction?: string };\ntype EdgeReplacementMap = Map<MaterializedEdge, PointLite[]>;\n\ntype SegmentLite = OrthogonalSegment;\n\nconst segmentsFor = orthogonalSegmentsForPoints;\n\nconst orthogonallyAligned = (a: PointLite, b: PointLite): boolean =>\n sameX(a, b, EPS_LOCAL) || sameY(a, b, EPS_LOCAL);\n\nexport function separateSharedRenderedTerminalLanes(\n edges: MaterializedEdge[],\n nodeByIdMap: Map<string, MaterializedNode>\n): void {\n const MIN_FACE_CLEARANCE = 16;\n const TRACK_SHIFT = 7;\n\n interface TerminalLane {\n edge: MaterializedEdge;\n edgeId: string;\n nodeId: string;\n atStart: boolean;\n orientation: 'H' | 'V';\n coord: number;\n min: number;\n max: number;\n boundary: PointLite;\n railEnd: PointLite;\n rect: RectLite;\n }\n\n const rectIntersect = (node: MaterializedNode, point: PointLite): PointLite => {\n const x = (node as { x?: number }).x ?? 0;\n const y = (node as { y?: number }).y ?? 0;\n const dx = point.x - x;\n const dy = point.y - y;\n let w = ((node as { width?: number }).width ?? 0) / 2;\n let h = ((node as { height?: number }).height ?? 0) / 2;\n\n if (Math.abs(dy) * w > Math.abs(dx) * h) {\n if (dy < 0) {\n h = -h;\n }\n return { x: x + (dy === 0 ? 0 : (h * dx) / dy), y: y + h };\n }\n\n if (dx < 0) {\n w = -w;\n }\n return { x: x + w, y: y + (dx === 0 ? 0 : (w * dy) / dx) };\n };\n\n const terminalLaneFor = (edge: MaterializedEdge, atStart: boolean): TerminalLane | undefined => {\n const points = dedupeConsecutivePoints((edge as { points?: PointLite[] }).points ?? []);\n if (points.length < 2) {\n return undefined;\n }\n\n const nodeId = atStart ? (edge as { start?: string }).start : (edge as { end?: string }).end;\n const node = nodeId ? nodeByIdMap.get(nodeId) : undefined;\n const rect = node ? rectOfNodeBounds(node) : undefined;\n if (!node || !nodeId || !rect) {\n return undefined;\n }\n\n const endpoint = atStart ? points[0] : points[points.length - 1];\n const adjacent = atStart ? points[1] : points[points.length - 2];\n const boundary = rectIntersect(node, endpoint);\n let railEnd = endpoint;\n if (orthogonallyAligned(adjacent, boundary)) {\n railEnd = adjacent;\n }\n\n if (sameX(boundary, railEnd, EPS_LOCAL)) {\n return {\n edge,\n edgeId: String((edge as { id?: string }).id ?? ''),\n nodeId,\n atStart,\n orientation: 'V',\n coord: boundary.x,\n min: Math.min(boundary.y, railEnd.y),\n max: Math.max(boundary.y, railEnd.y),\n boundary,\n railEnd,\n rect,\n };\n }\n if (sameY(boundary, railEnd, EPS_LOCAL)) {\n return {\n edge,\n edgeId: String((edge as { id?: string }).id ?? ''),\n nodeId,\n atStart,\n orientation: 'H',\n coord: boundary.y,\n min: Math.min(boundary.x, railEnd.x),\n max: Math.max(boundary.x, railEnd.x),\n boundary,\n railEnd,\n rect,\n };\n }\n return undefined;\n };\n\n const projectedOverlapLength = (a: TerminalLane, b: TerminalLane): number =>\n Math.max(0, Math.min(a.max, b.max) - Math.max(a.min, b.min));\n\n const sameTerminalFace = (a: TerminalLane, b: TerminalLane): boolean => {\n if (a.nodeId !== b.nodeId || a.orientation !== b.orientation) {\n return false;\n }\n\n if (a.orientation === 'H') {\n const aOnHorizontalFace =\n Math.abs(a.boundary.x - a.rect.left) < 1 || Math.abs(a.boundary.x - a.rect.right) < 1;\n return aOnHorizontalFace && sameX(a.boundary, b.boundary, 1);\n }\n\n const aOnVerticalFace =\n Math.abs(a.boundary.y - a.rect.top) < 1 || Math.abs(a.boundary.y - a.rect.bottom) < 1;\n return aOnVerticalFace && sameY(a.boundary, b.boundary, 1);\n };\n\n const exactTerminalLaneConflict = (a: TerminalLane, b: TerminalLane): boolean => {\n if (a.nodeId !== b.nodeId || a.orientation !== b.orientation) {\n return false;\n }\n\n const shared = projectedOverlapLength(a, b);\n return shared >= MIN_SHARED && Math.abs(a.coord - b.coord) < 0.5;\n };\n\n const nearTerminalLaneConflict = (a: TerminalLane, b: TerminalLane): boolean => {\n if (\n a.nodeId !== b.nodeId ||\n a.orientation !== b.orientation ||\n a.orientation !== 'H' ||\n a.atStart === b.atStart\n ) {\n return false;\n }\n\n const shared = projectedOverlapLength(a, b);\n if (shared < MIN_SHARED) {\n return false;\n }\n const faceSpan = a.rect.bottom - a.rect.top;\n if (shared < faceSpan || shared > 2 * faceSpan) {\n return false;\n }\n\n // Wybrow-style nudging keeps connector topology fixed while preserving\n // ordering constraints; rendered terminal tracks on the same object face\n // need the same treatment before endpoint duplication pins them in place.\n return sameTerminalFace(a, b) && Math.abs(a.coord - b.coord) < MIN_FACE_CLEARANCE;\n };\n\n const shiftedCandidate = (lane: TerminalLane, shift: number): PointLite[] | undefined => {\n const points = dedupeConsecutivePoints((lane.edge as { points?: PointLite[] }).points ?? []);\n if (points.length < 2) {\n return undefined;\n }\n\n const shiftedBoundary =\n lane.orientation === 'V'\n ? { x: lane.boundary.x + shift, y: lane.boundary.y }\n : { x: lane.boundary.x, y: lane.boundary.y + shift };\n const shiftedRailEnd =\n lane.orientation === 'V'\n ? { x: lane.railEnd.x + shift, y: lane.railEnd.y }\n : { x: lane.railEnd.x, y: lane.railEnd.y + shift };\n\n const boundaryStaysOnSameFace = (): boolean => {\n if (\n Math.abs(lane.boundary.y - lane.rect.top) < 1 ||\n Math.abs(lane.boundary.y - lane.rect.bottom) < 1\n ) {\n return (\n sameY(shiftedBoundary, lane.boundary, EPS_LOCAL) &&\n shiftedBoundary.x >= lane.rect.left + 1 &&\n shiftedBoundary.x <= lane.rect.right - 1\n );\n }\n\n if (\n Math.abs(lane.boundary.x - lane.rect.left) < 1 ||\n Math.abs(lane.boundary.x - lane.rect.right) < 1\n ) {\n return (\n sameX(shiftedBoundary, lane.boundary, EPS_LOCAL) &&\n shiftedBoundary.y >= lane.rect.top + 1 &&\n shiftedBoundary.y <= lane.rect.bottom - 1\n );\n }\n\n return false;\n };\n\n if (!boundaryStaysOnSameFace()) {\n return undefined;\n }\n\n if (lane.atStart) {\n const railEndIsAdjacent = points.length > 1 && samePoint(points[1], lane.railEnd, EPS_LOCAL);\n const rest = points.slice(railEndIsAdjacent ? 2 : 1);\n const next = rest[0];\n if (next && !orthogonallyAligned(next, shiftedRailEnd)) {\n return undefined;\n }\n return [shiftedBoundary, shiftedRailEnd, ...rest];\n }\n\n const railEndIsAdjacent =\n points.length > 1 && samePoint(points[points.length - 2], lane.railEnd, EPS_LOCAL);\n const before = points.slice(0, railEndIsAdjacent ? -2 : -1);\n const previous = before[before.length - 1];\n if (previous && !orthogonallyAligned(previous, shiftedRailEnd)) {\n return undefined;\n }\n return [...before, shiftedRailEnd, shiftedBoundary];\n };\n\n const laneIsStraightCollinearConnector = (lane: TerminalLane): boolean => {\n const edge = lane.edge as { points?: PointLite[]; start?: string; end?: string };\n const points = dedupeConsecutivePoints(edge.points ?? []);\n if (points.length !== 2) {\n return false;\n }\n const startId = edge.start;\n const endId = edge.end;\n const start = startId ? nodeByIdMap.get(startId) : undefined;\n const end = endId ? nodeByIdMap.get(endId) : undefined;\n if (!start || !end) {\n return false;\n }\n\n const startX = (start as { x?: number }).x ?? 0;\n const startY = (start as { y?: number }).y ?? 0;\n const endX = (end as { x?: number }).x ?? 0;\n const endY = (end as { y?: number }).y ?? 0;\n const [a, b] = points;\n\n return (\n (sameY(a, b, EPS_LOCAL) && Math.abs(startY - endY) < 1 && Math.abs(startX - endX) > 1) ||\n (sameX(a, b, EPS_LOCAL) && Math.abs(startX - endX) < 1 && Math.abs(startY - endY) > 1)\n );\n };\n\n const shifts = [\n -TRACK_SHIFT,\n TRACK_SHIFT,\n -2 * TRACK_SHIFT,\n 2 * TRACK_SHIFT,\n -3 * TRACK_SHIFT,\n 3 * TRACK_SHIFT,\n ];\n\n for (let iteration = 0; iteration < 8; iteration++) {\n const lanes = edges\n .filter((edge) => !(edge as { isLayoutOnly?: boolean }).isLayoutOnly)\n .flatMap((edge) => [terminalLaneFor(edge, true), terminalLaneFor(edge, false)])\n .filter((lane): lane is TerminalLane => Boolean(lane));\n\n let fixed = false;\n for (let i = 0; i < lanes.length && !fixed; i++) {\n for (let j = i + 1; j < lanes.length && !fixed; j++) {\n const first = lanes[i];\n const second = lanes[j];\n if (\n first.edge === second.edge ||\n !(exactTerminalLaneConflict(first, second) || nearTerminalLaneConflict(first, second))\n ) {\n continue;\n }\n\n const fixingNearConflict = !exactTerminalLaneConflict(first, second);\n const candidates = [first, second].sort((a, b) => {\n const aPreservesStraight = laneIsStraightCollinearConnector(a);\n const bPreservesStraight = laneIsStraightCollinearConnector(b);\n if (aPreservesStraight !== bPreservesStraight) {\n return Number(aPreservesStraight) - Number(bPreservesStraight);\n }\n return Number(!b.atStart) - Number(!a.atStart);\n });\n for (const lane of candidates) {\n for (const shift of shifts) {\n const candidate = shiftedCandidate(lane, shift);\n if (!candidate) {\n continue;\n }\n const nextLane = terminalLaneFor({ ...lane.edge, points: candidate }, lane.atStart);\n if (\n !nextLane ||\n lanes.some(\n (other) =>\n other.edge !== lane.edge &&\n (exactTerminalLaneConflict(nextLane, other) ||\n (fixingNearConflict && nearTerminalLaneConflict(nextLane, other)))\n )\n ) {\n continue;\n }\n\n (lane.edge as { points: PointLite[] }).points = candidate;\n fixed = true;\n break;\n }\n if (fixed) {\n break;\n }\n }\n }\n }\n\n if (!fixed) {\n return;\n }\n }\n}\n\nexport function collapseRedundantRectangularDoglegs(\n edges: MaterializedEdge[],\n nodeByIdMap: Map<string, MaterializedNode>\n): void {\n const BUFFER = 2;\n const MAX_ITERATIONS = 8;\n\n const { realNodeRects, labelNodeRects: labelRects } = collectNodeRectEntries(\n nodeByIdMap.values()\n );\n\n const candidateIsSafe = (edge: MaterializedEdge, candidate: PointLite[]): boolean => {\n const sourceId = (edge as { start?: string }).start;\n const targetId = (edge as { end?: string }).end;\n const candidateSegments = segmentsFor(candidate);\n if (candidateSegments.length !== candidate.length - 1) {\n return false;\n }\n\n const endpointIds = [sourceId, targetId].filter((id): id is string => Boolean(id));\n for (const segment of candidateSegments) {\n if (segmentHitsAnyRect(segment.a, segment.b, realNodeRects, endpointIds, -BUFFER)) {\n return false;\n }\n if (segmentHitsAnyRect(segment.a, segment.b, labelRects, [], -BUFFER)) {\n return false;\n }\n }\n\n for (const other of edges) {\n if (other === edge || (other as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const otherPoints = (other as { points?: PointLite[] }).points;\n if (!otherPoints || otherPoints.length < 2) {\n continue;\n }\n for (const candidateSegment of candidateSegments) {\n for (const otherSegment of segmentsFor(dedupeConsecutivePoints(otherPoints))) {\n if (sameAxisSegmentOverlapLength(candidateSegment, otherSegment, 0.5) >= MIN_SHARED) {\n return false;\n }\n if (\n orthogonalSegmentsStrictlyCross(\n candidateSegment.a,\n candidateSegment.b,\n otherSegment.a,\n otherSegment.b,\n EPS_LOCAL\n )\n ) {\n return false;\n }\n }\n }\n }\n\n return true;\n };\n\n const withoutDogleg = (points: PointLite[], i: number): PointLite[] | undefined => {\n if (i + 4 >= points.length) {\n return undefined;\n }\n const p0 = points[i];\n const p1 = points[i + 1];\n const p2 = points[i + 2];\n const p3 = points[i + 3];\n const p4 = points[i + 4];\n\n const terminalVerticalDogleg =\n isHorizontalSegment(p0, p1) &&\n isVerticalSegment(p1, p2) &&\n isHorizontalSegment(p2, p3) &&\n isVerticalSegment(p3, p4) &&\n sameX(p0, p3, EPS_LOCAL) &&\n sameX(p0, p4, EPS_LOCAL) &&\n sameX(p1, p2, EPS_LOCAL) &&\n (p1.x - p0.x) * (p3.x - p2.x) < 0;\n\n const terminalHorizontalDogleg =\n isVerticalSegment(p0, p1) &&\n isHorizontalSegment(p1, p2) &&\n isVerticalSegment(p2, p3) &&\n isHorizontalSegment(p3, p4) &&\n sameY(p0, p3, EPS_LOCAL) &&\n sameY(p0, p4, EPS_LOCAL) &&\n sameY(p1, p2, EPS_LOCAL) &&\n (p1.y - p0.y) * (p3.y - p2.y) < 0;\n\n if (terminalVerticalDogleg || terminalHorizontalDogleg) {\n return dedupeConsecutivePoints([...points.slice(0, i + 1), p4, ...points.slice(i + 5)]);\n }\n\n if (i + 5 >= points.length) {\n return undefined;\n }\n const p5 = points[i + 5];\n\n const verticalDogleg =\n isVerticalSegment(p0, p1) &&\n isHorizontalSegment(p1, p2) &&\n isVerticalSegment(p2, p3) &&\n isHorizontalSegment(p3, p4) &&\n isVerticalSegment(p4, p5) &&\n sameX(p0, p4, EPS_LOCAL) &&\n sameX(p0, p5, EPS_LOCAL) &&\n sameX(p2, p3, EPS_LOCAL) &&\n (p2.x - p1.x) * (p4.x - p3.x) < 0;\n\n const horizontalDogleg =\n isHorizontalSegment(p0, p1) &&\n isVerticalSegment(p1, p2) &&\n isHorizontalSegment(p2, p3) &&\n isVerticalSegment(p3, p4) &&\n isHorizontalSegment(p4, p5) &&\n sameY(p0, p4, EPS_LOCAL) &&\n sameY(p0, p5, EPS_LOCAL) &&\n sameY(p2, p3, EPS_LOCAL) &&\n (p2.y - p1.y) * (p4.y - p3.y) < 0;\n\n if (!verticalDogleg && !horizontalDogleg) {\n return undefined;\n }\n\n return dedupeConsecutivePoints([...points.slice(0, i + 1), p5, ...points.slice(i + 6)]);\n };\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n let fixed = false;\n for (const edge of edges) {\n if ((edge as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const points = dedupeConsecutivePoints((edge as { points?: PointLite[] }).points ?? []);\n for (let i = 0; i <= points.length - 5; i++) {\n const candidate = withoutDogleg(points, i);\n if (!candidate || !candidateIsSafe(edge, candidate)) {\n continue;\n }\n (edge as { points: PointLite[] }).points = candidate;\n fixed = true;\n break;\n }\n if (fixed) {\n break;\n }\n }\n if (!fixed) {\n return;\n }\n }\n}\n\nexport function liftObstacleHuggingSameSideRails(\n edges: MaterializedEdge[],\n nodeByIdMap: Map<string, MaterializedNode>\n): void {\n const BUFFER = 2;\n const CLEARANCE = 20;\n const MAX_ITERATIONS = 8;\n\n const { realNodeRects, labelNodeRects: labelRects } = collectNodeRectEntries(\n nodeByIdMap.values()\n );\n const visibleEdges = edges.filter((edge) => !(edge as { isLayoutOnly?: boolean }).isLayoutOnly);\n\n const pointsFor = (\n edge: MaterializedEdge,\n replacementEdge?: MaterializedEdge,\n replacement?: PointLite[]\n ): PointLite[] =>\n dedupeConsecutivePoints(\n edge === replacementEdge\n ? (replacement ?? [])\n : ((edge as { points?: PointLite[] }).points ?? [])\n );\n\n const strictCrossingCount = (\n replacementEdge?: MaterializedEdge,\n replacement?: PointLite[]\n ): number => {\n let count = 0;\n for (let i = 0; i < visibleEdges.length; i++) {\n const firstSegments = segmentsFor(pointsFor(visibleEdges[i], replacementEdge, replacement));\n for (let j = i + 1; j < visibleEdges.length; j++) {\n const secondSegments = segmentsFor(\n pointsFor(visibleEdges[j], replacementEdge, replacement)\n );\n for (const firstSegment of firstSegments) {\n for (const secondSegment of secondSegments) {\n if (\n orthogonalSegmentsStrictlyCross(\n firstSegment.a,\n firstSegment.b,\n secondSegment.a,\n secondSegment.b,\n EPS_LOCAL\n )\n ) {\n count++;\n }\n }\n }\n }\n }\n return count;\n };\n\n const middleRail = (\n points: PointLite[]\n ):\n | { index: number; horizontal: boolean; vertical: boolean; segment: SegmentLite }\n | undefined => {\n const segments = segmentsFor(points);\n if (segments.length !== 3) {\n return undefined;\n }\n const middle = segments[1];\n if (\n segments[0].horizontal === middle.horizontal ||\n segments[2].horizontal === middle.horizontal\n ) {\n return undefined;\n }\n return {\n index: middle.index,\n horizontal: middle.horizontal,\n vertical: middle.vertical,\n segment: middle,\n };\n };\n\n const blockingRectsFor = (edge: MaterializedEdge, rail: SegmentLite) => {\n const endpointIds = [(edge as { start?: string }).start, (edge as { end?: string }).end].filter(\n (id): id is string => Boolean(id)\n );\n return realNodeRects.filter((entry) => {\n if (endpointIds.includes(entry.id)) {\n return false;\n }\n const rect = entry.rect;\n if (rail.horizontal) {\n const xOverlap = overlapLength(rail.a.x, rail.b.x, rect.left, rect.right);\n return (\n xOverlap >= MIN_SHARED &&\n rail.a.y >= rect.top - BUFFER &&\n rail.a.y <= rect.bottom + BUFFER\n );\n }\n const yOverlap = overlapLength(rail.a.y, rail.b.y, rect.top, rect.bottom);\n return (\n yOverlap >= MIN_SHARED && rail.a.x >= rect.left - BUFFER && rail.a.x <= rect.right + BUFFER\n );\n });\n };\n\n const candidateByMovingRail = (\n points: PointLite[],\n rail: SegmentLite,\n coord: number\n ): PointLite[] | undefined => {\n const candidate = points.map((point) => ({ ...point }));\n if (rail.horizontal) {\n candidate[rail.index].y = coord;\n candidate[rail.index + 1].y = coord;\n } else if (rail.vertical) {\n candidate[rail.index].x = coord;\n candidate[rail.index + 1].x = coord;\n } else {\n return undefined;\n }\n const simplified = simplifyPolyline(dedupeConsecutivePoints(candidate));\n return segmentsFor(simplified).length === simplified.length - 1 ? simplified : undefined;\n };\n\n const candidateIsSafe = (\n edge: MaterializedEdge,\n candidate: PointLite[],\n currentCrossings: number\n ): boolean => {\n const endpointIds = [(edge as { start?: string }).start, (edge as { end?: string }).end].filter(\n (id): id is string => Boolean(id)\n );\n const candidateSegments = segmentsFor(candidate);\n if (candidateSegments.length !== candidate.length - 1) {\n return false;\n }\n\n for (const segment of candidateSegments) {\n if (segmentHitsAnyRect(segment.a, segment.b, realNodeRects, endpointIds, -BUFFER)) {\n return false;\n }\n if (segmentHitsAnyRect(segment.a, segment.b, labelRects, [], -BUFFER)) {\n return false;\n }\n }\n\n for (const other of visibleEdges) {\n if (other === edge) {\n continue;\n }\n for (const candidateSegment of candidateSegments) {\n for (const otherSegment of segmentsFor(pointsFor(other))) {\n if (sameAxisSegmentOverlapLength(candidateSegment, otherSegment, 0.5) >= MIN_SHARED) {\n return false;\n }\n }\n }\n }\n\n return strictCrossingCount(edge, candidate) <= currentCrossings;\n };\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n const currentCrossings = strictCrossingCount();\n let fixed = false;\n\n for (const edge of visibleEdges) {\n const points = pointsFor(edge);\n const rail = middleRail(points);\n if (!rail) {\n continue;\n }\n const blockers = blockingRectsFor(edge, rail.segment);\n if (blockers.length === 0) {\n continue;\n }\n\n const coords = rail.horizontal\n ? [\n Math.min(...blockers.map((entry) => entry.rect.top)) - CLEARANCE,\n Math.max(...blockers.map((entry) => entry.rect.bottom)) + CLEARANCE,\n ]\n : [\n Math.min(...blockers.map((entry) => entry.rect.left)) - CLEARANCE,\n Math.max(...blockers.map((entry) => entry.rect.right)) + CLEARANCE,\n ];\n\n for (const coord of coords) {\n const candidate = candidateByMovingRail(points, rail.segment, coord);\n if (!candidate || !candidateIsSafe(edge, candidate, currentCrossings)) {\n continue;\n }\n (edge as { points: PointLite[] }).points = candidate;\n fixed = true;\n break;\n }\n if (fixed) {\n break;\n }\n }\n\n if (!fixed) {\n return;\n }\n }\n}\n\nexport function liftTopLaneTitleBandsAboveRails(\n edges: MaterializedEdge[],\n nodeByIdMap: Map<string, MaterializedNode>\n): void {\n const CLEARANCE = 4;\n\n interface LaneTitle {\n node: MaterializedNode;\n rect: RectLite;\n }\n\n const validTitleRect = (node: MaterializedNode): RectLite | undefined => {\n const rect = (node as { groupTitleRect?: Partial<RectBounds> }).groupTitleRect;\n if (\n !rect ||\n typeof rect.left !== 'number' ||\n typeof rect.right !== 'number' ||\n typeof rect.top !== 'number' ||\n typeof rect.bottom !== 'number' ||\n !Number.isFinite(rect.left) ||\n !Number.isFinite(rect.right) ||\n !Number.isFinite(rect.top) ||\n !Number.isFinite(rect.bottom) ||\n rect.right <= rect.left ||\n rect.bottom <= rect.top\n ) {\n return undefined;\n }\n return { left: rect.left, right: rect.right, top: rect.top, bottom: rect.bottom };\n };\n\n const topLaneTitleFor = (node: MaterializedNode): LaneTitle | undefined => {\n if (!(node as { isGroup?: boolean }).isGroup || (node as { parentId?: unknown }).parentId) {\n return undefined;\n }\n const rawDirection = (node as { direction?: unknown }).direction;\n const direction = typeof rawDirection === 'string' ? rawDirection.toUpperCase() : '';\n if (direction === 'LR' || direction === 'RL' || direction === 'BT') {\n return undefined;\n }\n const rect = validTitleRect(node);\n const y = (node as { y?: number }).y;\n const height = (node as { height?: number }).height;\n if (\n !rect ||\n typeof y !== 'number' ||\n typeof height !== 'number' ||\n !Number.isFinite(y) ||\n !Number.isFinite(height) ||\n height <= 0\n ) {\n return undefined;\n }\n const titleWidth = rect.right - rect.left;\n const titleHeight = rect.bottom - rect.top;\n if (titleHeight <= 0 || titleWidth < titleHeight) {\n return undefined;\n }\n return { node, rect };\n };\n\n const horizontalSegmentIntersectsTitle = (segment: SegmentLite, rect: RectLite): boolean => {\n if (!segment.horizontal) {\n return false;\n }\n const y = segment.a.y;\n if (y <= rect.top + EPS_LOCAL || y >= rect.bottom - EPS_LOCAL) {\n return false;\n }\n return overlapLength(segment.a.x, segment.b.x, rect.left, rect.right) >= MIN_SHARED;\n };\n\n const lanes = [...nodeByIdMap.values()]\n .map(topLaneTitleFor)\n .filter((lane): lane is LaneTitle => Boolean(lane));\n if (lanes.length === 0) {\n return;\n }\n\n let topDelta = 0;\n for (const edge of edges) {\n if ((edge as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const points = dedupeConsecutivePoints((edge as { points?: PointLite[] }).points ?? []);\n for (const segment of segmentsFor(points)) {\n for (const lane of lanes) {\n if (!horizontalSegmentIntersectsTitle(segment, lane.rect)) {\n continue;\n }\n topDelta = Math.max(topDelta, lane.rect.bottom - segment.a.y + CLEARANCE);\n }\n }\n }\n\n if (topDelta <= EPS_LOCAL) {\n return;\n }\n\n for (const lane of lanes) {\n const y = (lane.node as { y?: number }).y;\n const height = (lane.node as { height?: number }).height;\n if (\n typeof y !== 'number' ||\n typeof height !== 'number' ||\n !Number.isFinite(y) ||\n !Number.isFinite(height) ||\n height <= 0\n ) {\n continue;\n }\n lane.node.y = y - topDelta / 2;\n lane.node.height = height + topDelta;\n lane.node.groupTitleRect = {\n ...lane.rect,\n top: lane.rect.top - topDelta,\n bottom: lane.rect.bottom - topDelta,\n };\n }\n}\n\nexport function shiftLeftLaneTitleBandsLeftOfRails(\n edges: MaterializedEdge[],\n nodeByIdMap: Map<string, MaterializedNode>\n): void {\n const CLEARANCE = 4;\n\n interface LaneTitle {\n node: MaterializedNode;\n rect: RectLite;\n }\n\n const validTitleRect = (node: MaterializedNode): RectLite | undefined => {\n const rect = (node as { groupTitleRect?: Partial<RectBounds> }).groupTitleRect;\n if (\n !rect ||\n typeof rect.left !== 'number' ||\n typeof rect.right !== 'number' ||\n typeof rect.top !== 'number' ||\n typeof rect.bottom !== 'number' ||\n !Number.isFinite(rect.left) ||\n !Number.isFinite(rect.right) ||\n !Number.isFinite(rect.top) ||\n !Number.isFinite(rect.bottom) ||\n rect.right <= rect.left ||\n rect.bottom <= rect.top\n ) {\n return undefined;\n }\n return { left: rect.left, right: rect.right, top: rect.top, bottom: rect.bottom };\n };\n\n const leftLaneTitleFor = (node: MaterializedNode): LaneTitle | undefined => {\n if (!(node as { isGroup?: boolean }).isGroup || (node as { parentId?: unknown }).parentId) {\n return undefined;\n }\n const rawDirection = (node as { direction?: unknown }).direction;\n if (rawDirection !== 'LR') {\n return undefined;\n }\n const rect = validTitleRect(node);\n const x = (node as { x?: number }).x;\n const width = (node as { width?: number }).width;\n if (\n !rect ||\n typeof x !== 'number' ||\n typeof width !== 'number' ||\n !Number.isFinite(x) ||\n !Number.isFinite(width) ||\n width <= 0\n ) {\n return undefined;\n }\n const titleWidth = rect.right - rect.left;\n const titleHeight = rect.bottom - rect.top;\n if (titleWidth <= 0 || titleHeight < titleWidth) {\n return undefined;\n }\n return { node, rect };\n };\n\n const verticalSegmentIntersectsTitle = (segment: SegmentLite, rect: RectLite): boolean => {\n if (!segment.vertical) {\n return false;\n }\n const x = segment.a.x;\n if (x <= rect.left + EPS_LOCAL || x >= rect.right - EPS_LOCAL) {\n return false;\n }\n return overlapLength(segment.a.y, segment.b.y, rect.top, rect.bottom) >= MIN_SHARED;\n };\n\n const horizontalSegmentIntersectsTitle = (segment: SegmentLite, rect: RectLite): boolean => {\n if (!segment.horizontal) {\n return false;\n }\n const y = segment.a.y;\n if (y <= rect.top + EPS_LOCAL || y >= rect.bottom - EPS_LOCAL) {\n return false;\n }\n return overlapLength(segment.a.x, segment.b.x, rect.left, rect.right) >= MIN_SHARED;\n };\n\n const lanes = [...nodeByIdMap.values()]\n .map(leftLaneTitleFor)\n .filter((lane): lane is LaneTitle => Boolean(lane));\n if (lanes.length === 0) {\n return;\n }\n\n let leftDelta = 0;\n for (const edge of edges) {\n if ((edge as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const points = dedupeConsecutivePoints((edge as { points?: PointLite[] }).points ?? []);\n for (const segment of segmentsFor(points)) {\n for (const lane of lanes) {\n if (verticalSegmentIntersectsTitle(segment, lane.rect)) {\n leftDelta = Math.max(leftDelta, lane.rect.right - segment.a.x + CLEARANCE);\n } else if (horizontalSegmentIntersectsTitle(segment, lane.rect)) {\n const segmentLeft = Math.min(segment.a.x, segment.b.x);\n leftDelta = Math.max(leftDelta, lane.rect.right - segmentLeft + CLEARANCE);\n }\n }\n }\n }\n\n if (leftDelta <= EPS_LOCAL) {\n return;\n }\n\n for (const lane of lanes) {\n const x = (lane.node as { x?: number }).x;\n const width = (lane.node as { width?: number }).width;\n if (\n typeof x !== 'number' ||\n typeof width !== 'number' ||\n !Number.isFinite(x) ||\n !Number.isFinite(width) ||\n width <= 0\n ) {\n continue;\n }\n lane.node.x = x - leftDelta / 2;\n lane.node.width = width + leftDelta;\n lane.node.groupTitleRect = {\n ...lane.rect,\n left: lane.rect.left - leftDelta,\n right: lane.rect.right - leftDelta,\n };\n }\n}\n\nexport function swapDestinationTerminalTailsToReduceCrossings(\n edges: MaterializedEdge[],\n nodeByIdMap: Map<string, MaterializedNode>\n): void {\n const BUFFER = 2;\n const MAX_ITERATIONS = 4;\n\n interface TerminalTail {\n tailStart: PointLite;\n terminal: PointLite;\n }\n\n const { realNodeRects } = collectNodeRectEntries(nodeByIdMap.values());\n const visibleEdges = edges.filter((edge) => !(edge as { isLayoutOnly?: boolean }).isLayoutOnly);\n\n const replacementPointsFor = (\n edge: MaterializedEdge,\n replacements: EdgeReplacementMap = new Map()\n ): PointLite[] =>\n dedupeConsecutivePoints(\n replacements.get(edge) ?? (edge as { points?: PointLite[] }).points ?? []\n );\n\n const crossingCount = (replacements: EdgeReplacementMap = new Map()): number => {\n let count = 0;\n for (let i = 0; i < visibleEdges.length; i++) {\n const firstSegments = segmentsFor(replacementPointsFor(visibleEdges[i], replacements));\n for (let j = i + 1; j < visibleEdges.length; j++) {\n const secondSegments = segmentsFor(replacementPointsFor(visibleEdges[j], replacements));\n for (const firstSegment of firstSegments) {\n for (const secondSegment of secondSegments) {\n if (\n orthogonalSegmentsStrictlyCross(\n firstSegment.a,\n firstSegment.b,\n secondSegment.a,\n secondSegment.b,\n EPS_LOCAL\n )\n ) {\n count++;\n }\n }\n }\n }\n }\n return count;\n };\n\n const totalBends = (replacements: EdgeReplacementMap = new Map()): number =>\n visibleEdges.reduce(\n (sum, edge) => sum + countOrthogonalBends(replacementPointsFor(edge, replacements)),\n 0\n );\n\n const terminalTailFor = (edge: MaterializedEdge): TerminalTail | undefined => {\n const points = replacementPointsFor(edge);\n if (points.length < 4) {\n return undefined;\n }\n const tailStart = points[points.length - 2];\n const terminal = points[points.length - 1];\n if (\n !isHorizontalSegment(tailStart, terminal, EPS_LOCAL) &&\n !isVerticalSegment(tailStart, terminal, EPS_LOCAL)\n ) {\n return undefined;\n }\n return { tailStart, terminal };\n };\n\n const candidateWithDestinationTail = (\n edge: MaterializedEdge,\n tail: TerminalTail\n ): PointLite[] | undefined => {\n const points = replacementPointsFor(edge);\n if (points.length < 3) {\n return undefined;\n }\n const start = points[0];\n const firstTurn = points[1];\n\n let connector: PointLite;\n if (isHorizontalSegment(start, firstTurn, EPS_LOCAL)) {\n connector = { x: firstTurn.x, y: tail.tailStart.y };\n } else if (isVerticalSegment(start, firstTurn, EPS_LOCAL)) {\n connector = { x: tail.tailStart.x, y: firstTurn.y };\n } else {\n return undefined;\n }\n\n const candidate = simplifyPolyline(\n dedupeConsecutivePoints([start, firstTurn, connector, tail.tailStart, tail.terminal])\n );\n return segmentsFor(candidate).length === candidate.length - 1 ? candidate : undefined;\n };\n\n const pathHasNodeHit = (edge: MaterializedEdge, path: PointLite[]): boolean => {\n const endpointIds = [(edge as { start?: string }).start, (edge as { end?: string }).end].filter(\n (id): id is string => Boolean(id)\n );\n for (const segment of segmentsFor(path)) {\n if (segmentHitsAnyRect(segment.a, segment.b, realNodeRects, endpointIds, -BUFFER)) {\n return true;\n }\n }\n return false;\n };\n\n const pathHasSharedTrack = (\n edge: MaterializedEdge,\n path: PointLite[],\n replacements: EdgeReplacementMap\n ): boolean => {\n for (const other of visibleEdges) {\n if (other === edge) {\n continue;\n }\n for (const candidateSegment of segmentsFor(path)) {\n for (const otherSegment of segmentsFor(replacementPointsFor(other, replacements))) {\n if (sameAxisSegmentOverlapLength(candidateSegment, otherSegment, 0.5) >= MIN_SHARED) {\n return true;\n }\n }\n }\n }\n return false;\n };\n\n const candidateIsSafe = (\n edge: MaterializedEdge,\n path: PointLite[],\n replacements: EdgeReplacementMap\n ): boolean => !pathHasNodeHit(edge, path) && !pathHasSharedTrack(edge, path, replacements);\n\n const edgesByDestination = (): Map<string, MaterializedEdge[]> => {\n const result = new Map<string, MaterializedEdge[]>();\n for (const edge of visibleEdges) {\n const dstId = (edge as { end?: string }).end;\n if (!dstId || !nodeByIdMap.has(dstId)) {\n continue;\n }\n const points = replacementPointsFor(edge);\n if (points.length < 4) {\n continue;\n }\n const bucket = result.get(dstId) ?? [];\n bucket.push(edge);\n result.set(dstId, bucket);\n }\n return result;\n };\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n const currentCrossings = crossingCount();\n if (currentCrossings === 0) {\n return;\n }\n const currentBends = totalBends();\n\n let bestReplacements: EdgeReplacementMap | undefined;\n let bestCrossings = currentCrossings;\n let bestBends = currentBends;\n\n for (const destinationEdges of edgesByDestination().values()) {\n for (let i = 0; i < destinationEdges.length; i++) {\n for (let j = i + 1; j < destinationEdges.length; j++) {\n const first = destinationEdges[i];\n const second = destinationEdges[j];\n const firstTail = terminalTailFor(first);\n const secondTail = terminalTailFor(second);\n if (!firstTail || !secondTail) {\n continue;\n }\n\n const firstCandidate = candidateWithDestinationTail(first, secondTail);\n const secondCandidate = candidateWithDestinationTail(second, firstTail);\n if (!firstCandidate || !secondCandidate) {\n continue;\n }\n\n const replacements = new Map<MaterializedEdge, PointLite[]>([\n [first, firstCandidate],\n [second, secondCandidate],\n ]);\n if (\n !candidateIsSafe(first, firstCandidate, replacements) ||\n !candidateIsSafe(second, secondCandidate, replacements)\n ) {\n continue;\n }\n\n const candidateCrossings = crossingCount(replacements);\n const candidateBends = totalBends(replacements);\n if (candidateCrossings >= currentCrossings) {\n continue;\n }\n if (\n candidateCrossings > bestCrossings ||\n (candidateCrossings === bestCrossings && candidateBends >= bestBends)\n ) {\n continue;\n }\n bestReplacements = replacements;\n bestCrossings = candidateCrossings;\n bestBends = candidateBends;\n }\n }\n }\n\n if (!bestReplacements) {\n return;\n }\n\n for (const [edge, points] of bestReplacements) {\n (edge as { points: PointLite[] }).points = points;\n }\n }\n}\n\n// Crossing cleanup sometimes requires reordering a small channel bundle as a\n// transaction: moving either rail alone is neutral or worse, while swapping the\n// shared external tracks removes crossings. Keep the search local and bounded,\n// but score it globally so crossing count stays the first acceptance criterion.\nexport function reassignCrossingExternalRailChannels(\n edges: MaterializedEdge[],\n nodeByIdMap: Map<string, MaterializedNode>\n): void {\n const BUFFER = 2;\n const RAIL_CHANNEL_GAP = 12;\n const MAX_ITERATIONS = 4;\n const MAX_EXHAUSTIVE_COMPONENT = 6;\n\n type RailAxis = 'horizontal' | 'vertical';\n\n interface ExternalRail {\n edge: MaterializedEdge;\n points: PointLite[];\n segmentIndex: number;\n axis: RailAxis;\n side: RectSide;\n coord: number;\n min: number;\n max: number;\n }\n\n const { realNodeRects, labelNodeRects: labelRects } = collectNodeRectEntries(\n nodeByIdMap.values()\n );\n const visibleEdges = edges.filter((edge) => !(edge as { isLayoutOnly?: boolean }).isLayoutOnly);\n\n const replacementPointsFor = (\n edge: MaterializedEdge,\n replacements: EdgeReplacementMap = new Map()\n ): PointLite[] =>\n dedupeConsecutivePoints(\n replacements.get(edge) ?? (edge as { points?: PointLite[] }).points ?? []\n );\n\n const strictCrossingCount = (replacements: EdgeReplacementMap = new Map()): number => {\n let count = 0;\n for (let i = 0; i < visibleEdges.length; i++) {\n const firstSegments = segmentsFor(replacementPointsFor(visibleEdges[i], replacements));\n for (let j = i + 1; j < visibleEdges.length; j++) {\n const secondSegments = segmentsFor(replacementPointsFor(visibleEdges[j], replacements));\n for (const firstSegment of firstSegments) {\n for (const secondSegment of secondSegments) {\n if (\n orthogonalSegmentsStrictlyCross(\n firstSegment.a,\n firstSegment.b,\n secondSegment.a,\n secondSegment.b,\n EPS_LOCAL\n )\n ) {\n count++;\n }\n }\n }\n }\n }\n return count;\n };\n\n const totalBends = (replacements: EdgeReplacementMap = new Map()): number =>\n visibleEdges.reduce(\n (sum, edge) => sum + countOrthogonalBends(replacementPointsFor(edge, replacements)),\n 0\n );\n\n const endpointRectsFor = (\n edge: MaterializedEdge\n ): { src: RectLite; dst: RectLite } | undefined => {\n const srcId = (edge as { start?: string }).start;\n const dstId = (edge as { end?: string }).end;\n const srcNode = srcId ? nodeByIdMap.get(srcId) : undefined;\n const dstNode = dstId ? nodeByIdMap.get(dstId) : undefined;\n const src = srcNode ? rectOfNodeBounds(srcNode) : undefined;\n const dst = dstNode ? rectOfNodeBounds(dstNode) : undefined;\n return src && dst ? { src, dst } : undefined;\n };\n\n const externalRailForSegment = (\n edge: MaterializedEdge,\n points: PointLite[],\n segment: SegmentLite\n ): ExternalRail | undefined => {\n if (segment.index <= 0 || segment.index + 1 >= points.length - 1) {\n return undefined;\n }\n\n const endpointRects = endpointRectsFor(edge);\n if (!endpointRects) {\n return undefined;\n }\n\n if (segment.vertical) {\n const coord = segment.a.x;\n const leftBound = Math.min(endpointRects.src.left, endpointRects.dst.left);\n const rightBound = Math.max(endpointRects.src.right, endpointRects.dst.right);\n const side: RectSide | undefined =\n coord < leftBound - EPS_LOCAL\n ? 'left'\n : coord > rightBound + EPS_LOCAL\n ? 'right'\n : undefined;\n if (!side) {\n return undefined;\n }\n return {\n edge,\n points,\n segmentIndex: segment.index,\n axis: 'vertical',\n side,\n coord,\n min: Math.min(segment.a.y, segment.b.y),\n max: Math.max(segment.a.y, segment.b.y),\n };\n }\n\n if (segment.horizontal) {\n const coord = segment.a.y;\n const topBound = Math.min(endpointRects.src.top, endpointRects.dst.top);\n const bottomBound = Math.max(endpointRects.src.bottom, endpointRects.dst.bottom);\n const side: RectSide | undefined =\n coord < topBound - EPS_LOCAL\n ? 'top'\n : coord > bottomBound + EPS_LOCAL\n ? 'bottom'\n : undefined;\n if (!side) {\n return undefined;\n }\n return {\n edge,\n points,\n segmentIndex: segment.index,\n axis: 'horizontal',\n side,\n coord,\n min: Math.min(segment.a.x, segment.b.x),\n max: Math.max(segment.a.x, segment.b.x),\n };\n }\n\n return undefined;\n };\n\n const collectExternalRails = (): ExternalRail[] => {\n const rails: ExternalRail[] = [];\n for (const edge of visibleEdges) {\n const points = replacementPointsFor(edge);\n for (const segment of segmentsFor(points)) {\n const rail = externalRailForSegment(edge, points, segment);\n if (rail) {\n rails.push(rail);\n }\n }\n }\n return rails;\n };\n\n const railsInteract = (a: ExternalRail, b: ExternalRail): boolean =>\n a.edge !== b.edge &&\n a.axis === b.axis &&\n a.side === b.side &&\n overlapLength(a.min, a.max, b.min, b.max) >= MIN_SHARED;\n\n const connectedComponents = (rails: ExternalRail[]): ExternalRail[][] => {\n const result: ExternalRail[][] = [];\n const seen = new Set<ExternalRail>();\n for (const rail of rails) {\n if (seen.has(rail)) {\n continue;\n }\n const queue = [rail];\n const component: ExternalRail[] = [];\n seen.add(rail);\n while (queue.length > 0) {\n const current = queue.pop()!;\n component.push(current);\n for (const next of rails) {\n if (!seen.has(next) && railsInteract(current, next)) {\n seen.add(next);\n queue.push(next);\n }\n }\n }\n if (component.length > 1) {\n result.push(component);\n }\n }\n return result;\n };\n\n const uniqueCoordsFor = (component: ExternalRail[]): number[] => {\n const coords: number[] = [];\n for (const rail of component) {\n if (!coords.some((coord) => Math.abs(coord - rail.coord) < EPS_LOCAL)) {\n coords.push(rail.coord);\n }\n }\n\n while (coords.length < component.length) {\n const min = Math.min(...coords);\n const max = Math.max(...coords);\n const side = component[0].side;\n coords.push(\n side === 'left' || side === 'top'\n ? min - RAIL_CHANNEL_GAP * (component.length - coords.length)\n : max + RAIL_CHANNEL_GAP * (component.length - coords.length)\n );\n }\n return coords;\n };\n\n const coordinateAssignmentsFor = (component: ExternalRail[]): number[][] => {\n const current = component.map((rail) => rail.coord);\n const coords = uniqueCoordsFor(component);\n const assignments: number[][] = [];\n\n if (component.length <= MAX_EXHAUSTIVE_COMPONENT) {\n const used = new Array(coords.length).fill(false);\n const next: number[] = [];\n const visit = () => {\n if (next.length === component.length) {\n if (next.some((coord, index) => Math.abs(coord - current[index]) >= EPS_LOCAL)) {\n assignments.push([...next]);\n }\n return;\n }\n for (const [i, coord] of coords.entries()) {\n if (used[i]) {\n continue;\n }\n used[i] = true;\n next.push(coord);\n visit();\n next.pop();\n used[i] = false;\n }\n };\n visit();\n return assignments;\n }\n\n for (let i = 0; i < current.length; i++) {\n for (let j = i + 1; j < current.length; j++) {\n const assignment = [...current];\n [assignment[i], assignment[j]] = [assignment[j], assignment[i]];\n assignments.push(assignment);\n }\n }\n return assignments;\n };\n\n const replacementsForAssignment = (\n component: ExternalRail[],\n assignment: number[]\n ): EdgeReplacementMap | undefined => {\n const draftByEdge = new Map<MaterializedEdge, PointLite[]>();\n for (const [i, rail] of component.entries()) {\n const coord = assignment[i];\n const points =\n draftByEdge.get(rail.edge) ?? rail.points.map((point) => ({ x: point.x, y: point.y }));\n if (rail.axis === 'vertical') {\n points[rail.segmentIndex].x = coord;\n points[rail.segmentIndex + 1].x = coord;\n } else {\n points[rail.segmentIndex].y = coord;\n points[rail.segmentIndex + 1].y = coord;\n }\n draftByEdge.set(rail.edge, points);\n }\n\n const replacements = new Map<MaterializedEdge, PointLite[]>();\n for (const [edge, points] of draftByEdge) {\n const simplified = simplifyPolyline(dedupeConsecutivePoints(points));\n if (segmentsFor(simplified).length !== simplified.length - 1) {\n return undefined;\n }\n replacements.set(edge, simplified);\n }\n return replacements;\n };\n\n const candidateIsSafe = (replacements: EdgeReplacementMap): boolean => {\n for (const [edge, points] of replacements) {\n const endpointIds = [\n (edge as { start?: string }).start,\n (edge as { end?: string }).end,\n ].filter((id): id is string => Boolean(id));\n for (const segment of segmentsFor(points)) {\n if (segmentHitsAnyRect(segment.a, segment.b, realNodeRects, endpointIds, -BUFFER)) {\n return false;\n }\n if (segmentHitsAnyRect(segment.a, segment.b, labelRects, [], -BUFFER)) {\n return false;\n }\n }\n }\n\n for (let i = 0; i < visibleEdges.length; i++) {\n const first = visibleEdges[i];\n const firstChanged = replacements.has(first);\n const firstSegments = segmentsFor(replacementPointsFor(first, replacements));\n for (let j = i + 1; j < visibleEdges.length; j++) {\n const second = visibleEdges[j];\n if (!firstChanged && !replacements.has(second)) {\n continue;\n }\n const secondSegments = segmentsFor(replacementPointsFor(second, replacements));\n for (const firstSegment of firstSegments) {\n for (const secondSegment of secondSegments) {\n if (sameAxisSegmentOverlapLength(firstSegment, secondSegment, 0.5) >= MIN_SHARED) {\n return false;\n }\n }\n }\n }\n }\n\n return true;\n };\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n const currentCrossings = strictCrossingCount();\n if (currentCrossings === 0) {\n return;\n }\n\n let bestReplacements: EdgeReplacementMap | undefined;\n let bestCrossings = currentCrossings;\n let bestBends = totalBends();\n let bestDisplacement = Number.POSITIVE_INFINITY;\n\n for (const component of connectedComponents(collectExternalRails())) {\n for (const assignment of coordinateAssignmentsFor(component)) {\n const replacements = replacementsForAssignment(component, assignment);\n if (!replacements || !candidateIsSafe(replacements)) {\n continue;\n }\n\n const candidateCrossings = strictCrossingCount(replacements);\n if (candidateCrossings >= currentCrossings) {\n continue;\n }\n const candidateBends = totalBends(replacements);\n const candidateDisplacement = component.reduce(\n (sum, rail, index) => sum + Math.abs(assignment[index] - rail.coord),\n 0\n );\n\n if (\n candidateCrossings > bestCrossings ||\n (candidateCrossings === bestCrossings &&\n (candidateBends > bestBends ||\n (candidateBends === bestBends && candidateDisplacement >= bestDisplacement)))\n ) {\n continue;\n }\n\n bestReplacements = replacements;\n bestCrossings = candidateCrossings;\n bestBends = candidateBends;\n bestDisplacement = candidateDisplacement;\n }\n }\n\n if (!bestReplacements) {\n return;\n }\n\n for (const [edge, points] of bestReplacements) {\n (edge as { points: PointLite[] }).points = points;\n }\n }\n}\n\nexport function shortcutRedundantOrthogonalJogs(\n edges: MaterializedEdge[],\n nodeByIdMap: Map<string, MaterializedNode>\n): void {\n const BUFFER = 2;\n const MAX_ITERATIONS = 8;\n\n const { realNodeRects, labelNodeRects: labelRects } = collectNodeRectEntries(\n nodeByIdMap.values()\n );\n const visibleEdges = edges.filter((edge) => !(edge as { isLayoutOnly?: boolean }).isLayoutOnly);\n\n const pointsFor = (\n edge: MaterializedEdge,\n replacementEdge?: MaterializedEdge,\n replacement?: PointLite[]\n ): PointLite[] =>\n dedupeConsecutivePoints(\n edge === replacementEdge\n ? (replacement ?? [])\n : ((edge as { points?: PointLite[] }).points ?? [])\n );\n\n const pathLength = (points: PointLite[]): number =>\n segmentsFor(points).reduce((sum, segment) => {\n const dx = segment.a.x - segment.b.x;\n const dy = segment.a.y - segment.b.y;\n return sum + Math.hypot(dx, dy);\n }, 0);\n\n const strictCrossingCount = (\n replacementEdge?: MaterializedEdge,\n replacement?: PointLite[]\n ): number => {\n let count = 0;\n for (let i = 0; i < visibleEdges.length; i++) {\n const firstSegments = segmentsFor(pointsFor(visibleEdges[i], replacementEdge, replacement));\n for (let j = i + 1; j < visibleEdges.length; j++) {\n const secondSegments = segmentsFor(\n pointsFor(visibleEdges[j], replacementEdge, replacement)\n );\n for (const firstSegment of firstSegments) {\n for (const secondSegment of secondSegments) {\n if (\n orthogonalSegmentsStrictlyCross(\n firstSegment.a,\n firstSegment.b,\n secondSegment.a,\n secondSegment.b,\n EPS_LOCAL\n )\n ) {\n count++;\n }\n }\n }\n }\n }\n return count;\n };\n\n const segmentRunsAlongRectBorder = (segment: SegmentLite, rect: RectLite): boolean => {\n if (segment.horizontal) {\n const y = segment.a.y;\n const onBorder = Math.abs(y - rect.top) < 1 || Math.abs(y - rect.bottom) < 1;\n return (\n onBorder && overlapLength(segment.a.x, segment.b.x, rect.left, rect.right) >= MIN_SHARED\n );\n }\n\n if (segment.vertical) {\n const x = segment.a.x;\n const onBorder = Math.abs(x - rect.left) < 1 || Math.abs(x - rect.right) < 1;\n return (\n onBorder && overlapLength(segment.a.y, segment.b.y, rect.top, rect.bottom) >= MIN_SHARED\n );\n }\n\n return false;\n };\n\n const endpointRectsFor = (edge: MaterializedEdge): RectLite[] => {\n const endpointIds = [(edge as { start?: string }).start, (edge as { end?: string }).end].filter(\n (id): id is string => Boolean(id)\n );\n const rects: RectLite[] = [];\n for (const id of endpointIds) {\n const node = nodeByIdMap.get(id);\n const rect = node ? rectOfNodeBounds(node) : undefined;\n if (rect) {\n rects.push(rect);\n }\n }\n return rects;\n };\n\n const shortcutCandidatesAt = (points: PointLite[], index: number): PointLite[][] => {\n if (index + 3 >= points.length) {\n return [];\n }\n\n const p0 = points[index];\n const p1 = points[index + 1];\n const p2 = points[index + 2];\n const p3 = points[index + 3];\n const isHVH =\n isHorizontalSegment(p0, p1, EPS_LOCAL) &&\n isVerticalSegment(p1, p2, EPS_LOCAL) &&\n isHorizontalSegment(p2, p3, EPS_LOCAL);\n const isVHV =\n isVerticalSegment(p0, p1, EPS_LOCAL) &&\n isHorizontalSegment(p1, p2, EPS_LOCAL) &&\n isVerticalSegment(p2, p3, EPS_LOCAL);\n if (!isHVH && !isVHV) {\n return [];\n }\n const outerSegmentsOppose = isHVH\n ? Math.sign(p1.x - p0.x) !== Math.sign(p3.x - p2.x)\n : Math.sign(p1.y - p0.y) !== Math.sign(p3.y - p2.y);\n if (!outerSegmentsOppose) {\n return [];\n }\n\n const corners =\n sameX(p0, p3, EPS_LOCAL) || sameY(p0, p3, EPS_LOCAL)\n ? []\n : [\n { x: p0.x, y: p3.y },\n { x: p3.x, y: p0.y },\n ];\n const rawCandidates =\n corners.length === 0\n ? [[...points.slice(0, index + 1), ...points.slice(index + 3)]]\n : corners.map((corner) => [\n ...points.slice(0, index + 1),\n corner,\n ...points.slice(index + 3),\n ]);\n\n const seen = new Set<string>();\n return rawCandidates\n .map((candidate) => simplifyPolyline(dedupeConsecutivePoints(candidate)))\n .filter((candidate) => {\n if (segmentsFor(candidate).length !== candidate.length - 1) {\n return false;\n }\n if (!candidate.some((point) => samePoint(point, p3, EPS_LOCAL))) {\n return false;\n }\n const key = candidate\n .map((point) => `${point.x.toFixed(3)},${point.y.toFixed(3)}`)\n .join('|');\n if (seen.has(key)) {\n return false;\n }\n seen.add(key);\n return true;\n });\n };\n\n const candidateIsSafe = (\n edge: MaterializedEdge,\n candidate: PointLite[],\n currentCrossings: number\n ): boolean => {\n const endpointIds = [(edge as { start?: string }).start, (edge as { end?: string }).end].filter(\n (id): id is string => Boolean(id)\n );\n const endpointRects = endpointRectsFor(edge);\n\n for (const segment of segmentsFor(candidate)) {\n if (segmentHitsAnyRect(segment.a, segment.b, realNodeRects, endpointIds, -BUFFER)) {\n return false;\n }\n if (segmentHitsAnyRect(segment.a, segment.b, labelRects, [], -BUFFER)) {\n return false;\n }\n if (endpointRects.some((rect) => segmentRunsAlongRectBorder(segment, rect))) {\n return false;\n }\n }\n\n for (const other of visibleEdges) {\n if (other === edge) {\n continue;\n }\n for (const candidateSegment of segmentsFor(candidate)) {\n for (const otherSegment of segmentsFor(pointsFor(other))) {\n if (sameAxisSegmentOverlapLength(candidateSegment, otherSegment, 0.5) >= MIN_SHARED) {\n return false;\n }\n }\n }\n }\n\n return strictCrossingCount(edge, candidate) <= currentCrossings;\n };\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n const currentCrossings = strictCrossingCount();\n let bestEdge: { points?: PointLite[] } | undefined;\n let bestPath: PointLite[] | undefined;\n let bestCrossings = currentCrossings;\n let bestBends = Number.POSITIVE_INFINITY;\n let bestLength = Number.POSITIVE_INFINITY;\n\n for (const edge of visibleEdges) {\n const currentPoints = pointsFor(edge);\n const currentBends = countOrthogonalBends(currentPoints, EPS_LOCAL);\n const currentLength = pathLength(currentPoints);\n for (let index = 0; index <= currentPoints.length - 4; index++) {\n for (const candidate of shortcutCandidatesAt(currentPoints, index)) {\n const candidateBends = countOrthogonalBends(candidate, EPS_LOCAL);\n const candidateLength = pathLength(candidate);\n const improvesShape =\n candidateBends < currentBends ||\n (candidateBends === currentBends && candidateLength < currentLength - EPS_LOCAL);\n if (!improvesShape || !candidateIsSafe(edge, candidate, currentCrossings)) {\n continue;\n }\n\n const candidateCrossings = strictCrossingCount(edge, candidate);\n if (\n candidateCrossings > bestCrossings ||\n (candidateCrossings === bestCrossings &&\n (candidateBends > bestBends ||\n (candidateBends === bestBends && candidateLength >= bestLength)))\n ) {\n continue;\n }\n\n bestEdge = edge;\n bestPath = candidate;\n bestCrossings = candidateCrossings;\n bestBends = candidateBends;\n bestLength = candidateLength;\n }\n }\n }\n\n if (!bestEdge || !bestPath) {\n return;\n }\n\n bestEdge.points = bestPath;\n }\n}\n\nexport function resolveRenderedOrthogonalCrossings(\n edges: MaterializedEdge[],\n nodeByIdMap: Map<string, MaterializedNode>\n): void {\n const ANCHOR = 20;\n const EXTRA_CHANNEL_COUNT = 2;\n const MAX_ITERATIONS = 4;\n const MAX_PAIR_CANDIDATES_PER_EDGE = 48;\n\n interface NodeInfo {\n id: string;\n cx: number;\n cy: number;\n rect: RectLite;\n }\n\n interface CrossingPair {\n first: MaterializedEdge;\n second: MaterializedEdge;\n count: number;\n }\n\n interface CrossingSnapshot {\n count: number;\n pairs: CrossingPair[];\n edgeSet: Set<MaterializedEdge>;\n edges: MaterializedEdge[];\n }\n\n interface PairCandidate {\n path: PointLite[];\n segments: SegmentLite[];\n sharedTrackConflicts: Set<MaterializedEdge>;\n totalBends: number;\n length: number;\n }\n\n interface PairOption {\n edge: MaterializedEdge;\n candidates: PairCandidate[];\n }\n\n interface PairReplacementScore {\n replacements: EdgeReplacementMap;\n crossings: number;\n bends: number;\n length: number;\n }\n\n interface PairScoringContext {\n current: CrossingSnapshot;\n currentBends: number;\n currentLength: number;\n baseBendsByEdge: Map<MaterializedEdge, number>;\n baseLengthByEdge: Map<MaterializedEdge, number>;\n baseSegments: Map<MaterializedEdge, SegmentLite[]>;\n }\n\n const realNodes: NodeInfo[] = [];\n for (const node of nodeByIdMap.values()) {\n if (\n (node as { isGroup?: boolean }).isGroup ||\n (node as { isEdgeLabel?: boolean }).isEdgeLabel\n ) {\n continue;\n }\n const cx = (node as { x?: number }).x ?? 0;\n const cy = (node as { y?: number }).y ?? 0;\n const rect = rectOfNodeBounds(node);\n if (!rect) {\n continue;\n }\n realNodes.push({\n id: String((node as { id?: string }).id ?? ''),\n cx,\n cy,\n rect,\n });\n }\n\n if (realNodes.length === 0) {\n return;\n }\n\n const nodeInfoById = new Map(realNodes.map((node) => [node.id, node]));\n const realNodeRects = realNodes.map((node) => ({ id: node.id, rect: node.rect }));\n const sides: RectSide[] = ['top', 'bottom', 'left', 'right'];\n const outsideTracks = {\n top: Math.min(...realNodes.map((node) => node.rect.top)) - ANCHOR,\n bottom: Math.max(...realNodes.map((node) => node.rect.bottom)) + ANCHOR,\n left: Math.min(...realNodes.map((node) => node.rect.left)) - ANCHOR,\n right: Math.max(...realNodes.map((node) => node.rect.right)) + ANCHOR,\n };\n\n const visibleEdges = edges.filter((edge) => !(edge as { isLayoutOnly?: boolean }).isLayoutOnly);\n const edgeIndex = new Map(visibleEdges.map((edge, index) => [edge, index]));\n\n const outwardTracksForSide = (side: RectSide): number[] => {\n const outward = side === 'left' || side === 'top' ? -1 : 1;\n const tracks: number[] = [];\n for (let channel = 0; channel <= EXTRA_CHANNEL_COUNT; channel++) {\n tracks.push(outsideTracks[side] + outward * ANCHOR * channel);\n }\n return tracks;\n };\n\n const replacementPointsFor = (\n edge: MaterializedEdge,\n replacements: EdgeReplacementMap = new Map()\n ): PointLite[] =>\n dedupeConsecutivePoints(\n replacements.get(edge) ?? (edge as { points?: PointLite[] }).points ?? []\n );\n\n const crossingCountBetweenSegments = (\n firstSegments: SegmentLite[],\n secondSegments: SegmentLite[]\n ): number => {\n let count = 0;\n for (const firstSegment of firstSegments) {\n for (const secondSegment of secondSegments) {\n if (\n orthogonalSegmentsStrictlyCross(\n firstSegment.a,\n firstSegment.b,\n secondSegment.a,\n secondSegment.b,\n EPS_LOCAL\n )\n ) {\n count++;\n }\n }\n }\n return count;\n };\n\n const crossingCountBetweenPaths = (first: PointLite[], second: PointLite[]): number =>\n crossingCountBetweenSegments(segmentsFor(first), segmentsFor(second));\n\n const crossingSnapshot = (replacements: EdgeReplacementMap = new Map()): CrossingSnapshot => {\n let count = 0;\n const pairs: CrossingPair[] = [];\n const edgeSet = new Set<MaterializedEdge>();\n const edgeOrder: MaterializedEdge[] = [];\n const addEdge = (edge: MaterializedEdge): void => {\n if (!edgeSet.has(edge)) {\n edgeSet.add(edge);\n edgeOrder.push(edge);\n }\n };\n\n for (let i = 0; i < visibleEdges.length; i++) {\n const first = visibleEdges[i];\n const firstPoints = replacementPointsFor(first, replacements);\n for (let j = i + 1; j < visibleEdges.length; j++) {\n const second = visibleEdges[j];\n const pairCount = crossingCountBetweenPaths(\n firstPoints,\n replacementPointsFor(second, replacements)\n );\n if (pairCount > 0) {\n count += pairCount;\n pairs.push({ first, second, count: pairCount });\n addEdge(first);\n addEdge(second);\n }\n }\n }\n\n edgeOrder.sort((a, b) => (edgeIndex.get(a) ?? 0) - (edgeIndex.get(b) ?? 0));\n return {\n count,\n pairs,\n edgeSet,\n edges: edgeOrder,\n };\n };\n\n const crossingCountWithReplacements = (\n current: CrossingSnapshot,\n replacements: EdgeReplacementMap\n ): number => {\n const changed = new Set(replacements.keys());\n if (changed.size === 0) {\n return current.count;\n }\n\n let currentAffected = 0;\n for (const pair of current.pairs) {\n if (changed.has(pair.first) || changed.has(pair.second)) {\n currentAffected += pair.count;\n }\n }\n\n let replacementAffected = 0;\n for (let i = 0; i < visibleEdges.length; i++) {\n const first = visibleEdges[i];\n const firstChanged = changed.has(first);\n const firstPoints = replacementPointsFor(first, replacements);\n for (let j = i + 1; j < visibleEdges.length; j++) {\n const second = visibleEdges[j];\n if (!firstChanged && !changed.has(second)) {\n continue;\n }\n replacementAffected += crossingCountBetweenPaths(\n firstPoints,\n replacementPointsFor(second, replacements)\n );\n }\n }\n\n return current.count - currentAffected + replacementAffected;\n };\n\n const crossingComponents = (snapshot: CrossingSnapshot): MaterializedEdge[][] => {\n const neighbors = new Map<MaterializedEdge, Set<MaterializedEdge>>();\n for (const pair of snapshot.pairs) {\n const firstNeighbors = neighbors.get(pair.first) ?? new Set<MaterializedEdge>();\n firstNeighbors.add(pair.second);\n neighbors.set(pair.first, firstNeighbors);\n\n const secondNeighbors = neighbors.get(pair.second) ?? new Set<MaterializedEdge>();\n secondNeighbors.add(pair.first);\n neighbors.set(pair.second, secondNeighbors);\n }\n\n const components: MaterializedEdge[][] = [];\n const seen = new Set<MaterializedEdge>();\n for (const edge of snapshot.edges) {\n if (seen.has(edge)) {\n continue;\n }\n const queue = [edge];\n const component: MaterializedEdge[] = [];\n seen.add(edge);\n while (queue.length > 0) {\n const current = queue.pop()!;\n component.push(current);\n for (const next of neighbors.get(current) ?? []) {\n if (!seen.has(next)) {\n seen.add(next);\n queue.push(next);\n }\n }\n }\n component.sort((a, b) => (edgeIndex.get(a) ?? 0) - (edgeIndex.get(b) ?? 0));\n if (component.length > 1) {\n components.push(component);\n }\n }\n\n return components;\n };\n\n const endpointIdsFor = (edge: MaterializedEdge): string[] =>\n [(edge as { start?: string }).start, (edge as { end?: string }).end].filter(\n (id): id is string => Boolean(id)\n );\n\n const pairSearchGroups = (snapshot: CrossingSnapshot): MaterializedEdge[][] => {\n const groups: MaterializedEdge[][] = [];\n for (const component of crossingComponents(snapshot)) {\n const componentSet = new Set(component);\n const componentEndpointIds = new Set(component.flatMap((edge) => endpointIdsFor(edge)));\n const group = [...component];\n for (const edge of visibleEdges) {\n if (componentSet.has(edge)) {\n continue;\n }\n if (endpointIdsFor(edge).some((id) => componentEndpointIds.has(id))) {\n group.push(edge);\n }\n }\n group.sort((a, b) => (edgeIndex.get(a) ?? 0) - (edgeIndex.get(b) ?? 0));\n groups.push(group);\n }\n return groups;\n };\n\n const crossingCountWithSingleReplacement = (\n current: CrossingSnapshot,\n edge: MaterializedEdge,\n replacement: PointLite[]\n ): number =>\n crossingCountWithReplacements(\n current,\n new Map<MaterializedEdge, PointLite[]>([[edge, replacement]])\n );\n\n const currentCrossingsByEdge = (current: CrossingSnapshot): Map<MaterializedEdge, number> => {\n const result = new Map<MaterializedEdge, number>();\n for (const pair of current.pairs) {\n result.set(pair.first, (result.get(pair.first) ?? 0) + pair.count);\n result.set(pair.second, (result.get(pair.second) ?? 0) + pair.count);\n }\n return result;\n };\n\n const pathLength = (points: PointLite[]): number =>\n points.slice(1).reduce((sum, point, index) => {\n const previous = points[index];\n return sum + Math.abs(point.x - previous.x) + Math.abs(point.y - previous.y);\n }, 0);\n\n const totalBends = (replacements: EdgeReplacementMap = new Map()): number =>\n visibleEdges.reduce(\n (sum, edge) => sum + countOrthogonalBends(replacementPointsFor(edge, replacements)),\n 0\n );\n\n const totalLength = (replacements: EdgeReplacementMap = new Map()): number =>\n visibleEdges.reduce(\n (sum, edge) => sum + pathLength(replacementPointsFor(edge, replacements)),\n 0\n );\n\n const pathHasSegmentConflict = (\n edge: MaterializedEdge,\n path: PointLite[],\n replacements: EdgeReplacementMap = new Map()\n ): boolean => {\n const pathSegments = segmentsFor(path);\n for (const other of visibleEdges) {\n if (other === edge) {\n continue;\n }\n for (const candidateSegment of pathSegments) {\n for (const otherSegment of segmentsFor(replacementPointsFor(other, replacements))) {\n if (sameAxisSegmentOverlapLength(candidateSegment, otherSegment, 0.5) >= MIN_SHARED) {\n return true;\n }\n }\n }\n }\n return false;\n };\n\n const pathHitsNode = (edge: MaterializedEdge, path: PointLite[]): boolean => {\n const endpointIds = [(edge as { start?: string }).start, (edge as { end?: string }).end].filter(\n (id): id is string => Boolean(id)\n );\n for (const segment of segmentsFor(path)) {\n if (segmentHitsAnyRect(segment.a, segment.b, realNodeRects, endpointIds, -2)) {\n return true;\n }\n }\n return false;\n };\n\n const pushOrthogonalCandidate = (candidates: PointLite[][], points: PointLite[]): void => {\n const candidate = simplifyPolyline(dedupeConsecutivePoints(points));\n if (segmentsFor(candidate).length === candidate.length - 1) {\n candidates.push(candidate);\n }\n };\n\n const sideIsHorizontal = (side: RectSide): boolean => side === 'left' || side === 'right';\n\n const localTrackForSameSide = (src: PointLite, side: RectSide, dst: PointLite): number => {\n switch (side) {\n case 'left':\n return Math.min(src.x, dst.x) - ANCHOR;\n case 'right':\n return Math.max(src.x, dst.x) + ANCHOR;\n case 'top':\n return Math.min(src.y, dst.y) - ANCHOR;\n case 'bottom':\n return Math.max(src.y, dst.y) + ANCHOR;\n }\n };\n\n const addSameSideCandidates = (\n candidates: PointLite[][],\n src: PointLite,\n srcSide: RectSide,\n dst: PointLite\n ): void => {\n const outward = srcSide === 'left' || srcSide === 'top' ? -1 : 1;\n const trackSeeds = [localTrackForSameSide(src, srcSide, dst), outsideTracks[srcSide]];\n for (const seed of trackSeeds) {\n for (let channel = 0; channel <= EXTRA_CHANNEL_COUNT; channel++) {\n pushOrthogonalCandidate(\n candidates,\n buildSameSideTrackPath(src, srcSide, dst, seed + outward * ANCHOR * channel)\n );\n }\n }\n };\n\n const addHorizontalToVerticalCandidates = (\n candidates: PointLite[][],\n src: PointLite,\n srcSide: RectSide,\n dst: PointLite,\n dstSide: RectSide\n ): void => {\n for (const xTrack of outwardTracksForSide(srcSide)) {\n for (const yTrack of outwardTracksForSide(dstSide)) {\n pushOrthogonalCandidate(candidates, [\n src,\n { x: xTrack, y: src.y },\n { x: xTrack, y: yTrack },\n { x: dst.x, y: yTrack },\n dst,\n ]);\n }\n }\n };\n\n const addVerticalToHorizontalCandidates = (\n candidates: PointLite[][],\n src: PointLite,\n srcSide: RectSide,\n dst: PointLite,\n dstSide: RectSide\n ): void => {\n for (const yTrack of outwardTracksForSide(srcSide)) {\n for (const xTrack of outwardTracksForSide(dstSide)) {\n pushOrthogonalCandidate(candidates, [\n src,\n { x: src.x, y: yTrack },\n { x: xTrack, y: yTrack },\n { x: xTrack, y: dst.y },\n dst,\n ]);\n }\n }\n };\n\n const addHorizontalPairCandidates = (\n candidates: PointLite[][],\n src: PointLite,\n srcSide: RectSide,\n dst: PointLite,\n dstSide: RectSide\n ): void => {\n const yTracks = [...outwardTracksForSide('top'), ...outwardTracksForSide('bottom')];\n for (const srcTrack of outwardTracksForSide(srcSide)) {\n for (const dstTrack of outwardTracksForSide(dstSide)) {\n for (const yTrack of yTracks) {\n pushOrthogonalCandidate(candidates, [\n src,\n { x: srcTrack, y: src.y },\n { x: srcTrack, y: yTrack },\n { x: dstTrack, y: yTrack },\n { x: dstTrack, y: dst.y },\n dst,\n ]);\n }\n }\n }\n };\n\n const addVerticalPairCandidates = (\n candidates: PointLite[][],\n src: PointLite,\n srcSide: RectSide,\n dst: PointLite,\n dstSide: RectSide\n ): void => {\n const xTracks = [...outwardTracksForSide('left'), ...outwardTracksForSide('right')];\n for (const srcTrack of outwardTracksForSide(srcSide)) {\n for (const dstTrack of outwardTracksForSide(dstSide)) {\n for (const xTrack of xTracks) {\n pushOrthogonalCandidate(candidates, [\n src,\n { x: src.x, y: srcTrack },\n { x: xTrack, y: srcTrack },\n { x: xTrack, y: dstTrack },\n { x: dst.x, y: dstTrack },\n dst,\n ]);\n }\n }\n }\n };\n\n const dedupeCandidatePaths = (candidates: PointLite[][]): PointLite[][] => {\n const seen = new Set<string>();\n return candidates\n .map((candidate) => dedupeConsecutivePoints(candidate))\n .filter((candidate) => {\n const key = candidate\n .map((point) => `${point.x.toFixed(3)},${point.y.toFixed(3)}`)\n .join('|');\n if (seen.has(key) || candidate.length < 2) {\n return false;\n }\n seen.add(key);\n return true;\n });\n };\n\n const buildCandidatesForSides = (\n src: PointLite,\n srcSide: RectSide,\n dst: PointLite,\n dstSide: RectSide\n ): PointLite[][] => {\n const candidates: PointLite[][] = [];\n const base = buildOrthogonalPortPath(src, srcSide, dst, dstSide, ANCHOR, EPS_LOCAL);\n if (base) {\n pushOrthogonalCandidate(candidates, base);\n }\n if (srcSide === dstSide) {\n addSameSideCandidates(candidates, src, srcSide, dst);\n }\n\n const srcHorizontal = sideIsHorizontal(srcSide);\n const dstHorizontal = sideIsHorizontal(dstSide);\n if (srcHorizontal && !dstHorizontal) {\n addHorizontalToVerticalCandidates(candidates, src, srcSide, dst, dstSide);\n } else if (!srcHorizontal && dstHorizontal) {\n addVerticalToHorizontalCandidates(candidates, src, srcSide, dst, dstSide);\n } else if (srcHorizontal) {\n addHorizontalPairCandidates(candidates, src, srcSide, dst, dstSide);\n } else {\n addVerticalPairCandidates(candidates, src, srcSide, dst, dstSide);\n }\n\n return dedupeCandidatePaths(candidates);\n };\n\n const addVerticalDepartureOuterTrackCandidates = (\n candidates: PointLite[][],\n first: PointLite,\n departure: PointLite,\n dstNode: NodeInfo\n ): void => {\n const externalXTracks = [...outwardTracksForSide('left'), ...outwardTracksForSide('right')];\n const externalYTracks = [...outwardTracksForSide('top'), ...outwardTracksForSide('bottom')];\n for (const side of sides) {\n const dst = portForRectSide(dstNode, side);\n const targetYTracks =\n side === 'top' || side === 'bottom' ? outwardTracksForSide(side) : externalYTracks;\n for (const track of externalXTracks) {\n pushOrthogonalCandidate(candidates, [\n first,\n departure,\n { x: track, y: departure.y },\n { x: track, y: dst.y },\n dst,\n ]);\n for (const targetTrack of targetYTracks) {\n pushOrthogonalCandidate(candidates, [\n first,\n departure,\n { x: track, y: departure.y },\n { x: track, y: targetTrack },\n { x: dst.x, y: targetTrack },\n dst,\n ]);\n }\n }\n }\n };\n\n const addHorizontalDepartureOuterTrackCandidates = (\n candidates: PointLite[][],\n first: PointLite,\n departure: PointLite,\n dstNode: NodeInfo\n ): void => {\n const externalXTracks = [...outwardTracksForSide('left'), ...outwardTracksForSide('right')];\n const externalYTracks = [...outwardTracksForSide('top'), ...outwardTracksForSide('bottom')];\n for (const side of sides) {\n const dst = portForRectSide(dstNode, side);\n const targetXTracks =\n side === 'left' || side === 'right' ? outwardTracksForSide(side) : externalXTracks;\n for (const track of externalYTracks) {\n pushOrthogonalCandidate(candidates, [\n first,\n departure,\n { x: departure.x, y: track },\n { x: dst.x, y: track },\n dst,\n ]);\n for (const targetTrack of targetXTracks) {\n pushOrthogonalCandidate(candidates, [\n first,\n departure,\n { x: departure.x, y: track },\n { x: targetTrack, y: track },\n { x: targetTrack, y: dst.y },\n dst,\n ]);\n }\n }\n }\n };\n\n const terminalPreservingOuterTrackCandidates = (edge: MaterializedEdge): PointLite[][] => {\n const srcId = (edge as { start?: string }).start;\n const dstId = (edge as { end?: string }).end;\n const dstNode = dstId ? nodeInfoById.get(dstId) : undefined;\n if (!srcId || !dstNode) {\n return [];\n }\n\n const points = dedupeConsecutivePoints((edge as { points?: PointLite[] }).points ?? []);\n if (points.length < 4) {\n return [];\n }\n\n const first = points[0];\n const departure = points[1];\n const candidates: PointLite[][] = [];\n if (isVerticalSegment(first, departure, EPS_LOCAL)) {\n addVerticalDepartureOuterTrackCandidates(candidates, first, departure, dstNode);\n } else if (isHorizontalSegment(first, departure, EPS_LOCAL)) {\n addHorizontalDepartureOuterTrackCandidates(candidates, first, departure, dstNode);\n }\n\n return candidates;\n };\n\n const candidatePathsFor = (edge: MaterializedEdge): PointLite[][] => {\n const srcId = (edge as { start?: string }).start;\n const dstId = (edge as { end?: string }).end;\n const srcNode = srcId ? nodeInfoById.get(srcId) : undefined;\n const dstNode = dstId ? nodeInfoById.get(dstId) : undefined;\n if (!srcNode || !dstNode) {\n return [];\n }\n\n const candidates: PointLite[][] = [];\n for (const srcSide of sides) {\n const srcPort = portForRectSide(srcNode, srcSide);\n for (const dstSide of sides) {\n candidates.push(\n ...buildCandidatesForSides(srcPort, srcSide, portForRectSide(dstNode, dstSide), dstSide)\n );\n }\n }\n candidates.push(...terminalPreservingOuterTrackCandidates(edge));\n return candidates;\n };\n\n const currentSegmentsByEdge = (): Map<MaterializedEdge, SegmentLite[]> =>\n new Map(visibleEdges.map((edge) => [edge, segmentsFor(replacementPointsFor(edge))] as const));\n\n const sharedTrackConflictsFor = (\n edge: MaterializedEdge,\n candidateSegments: SegmentLite[],\n baseSegments: Map<MaterializedEdge, SegmentLite[]>\n ): Set<MaterializedEdge> => {\n const conflicts = new Set<MaterializedEdge>();\n for (const other of visibleEdges) {\n if (other === edge) {\n continue;\n }\n const otherSegments = baseSegments.get(other) ?? segmentsFor(replacementPointsFor(other));\n if (\n candidateSegments.some((candidateSegment) =>\n otherSegments.some(\n (otherSegment) =>\n sameAxisSegmentOverlapLength(candidateSegment, otherSegment, 0.5) >= MIN_SHARED\n )\n )\n ) {\n conflicts.add(other);\n }\n }\n return conflicts;\n };\n\n const pairCandidatesFor = (\n edge: MaterializedEdge,\n current: CrossingSnapshot,\n baseSegments: Map<MaterializedEdge, SegmentLite[]>,\n crossingCountByEdge: Map<MaterializedEdge, number>\n ): PairCandidate[] => {\n const seen = new Set<string>();\n const candidates = candidatePathsFor(edge)\n .map((candidate) => simplifyPolyline(dedupeConsecutivePoints(candidate)))\n .filter((candidate) => {\n if (pathHitsNode(edge, candidate)) {\n return false;\n }\n const key = candidate\n .map((point) => `${point.x.toFixed(3)},${point.y.toFixed(3)}`)\n .join('|');\n if (seen.has(key) || candidate.length < 2) {\n return false;\n }\n seen.add(key);\n return true;\n })\n .map((candidate) => {\n const candidateSegments = segmentsFor(candidate);\n let replacementAffected = 0;\n for (const other of visibleEdges) {\n if (other === edge) {\n continue;\n }\n replacementAffected += crossingCountBetweenSegments(\n candidateSegments,\n baseSegments.get(other) ?? segmentsFor(replacementPointsFor(other))\n );\n }\n return {\n candidate,\n candidateSegments,\n crossings: current.count - (crossingCountByEdge.get(edge) ?? 0) + replacementAffected,\n bends: countOrthogonalBends(candidate, EPS_LOCAL),\n totalBends: countOrthogonalBends(candidate),\n length: pathLength(candidate),\n };\n })\n .filter(({ crossings }) => crossings <= current.count)\n .sort((a, b) => a.crossings - b.crossings || a.bends - b.bends || a.length - b.length);\n return candidates.slice(0, MAX_PAIR_CANDIDATES_PER_EDGE).map((candidate) => {\n return {\n path: candidate.candidate,\n segments: candidate.candidateSegments,\n sharedTrackConflicts: sharedTrackConflictsFor(\n edge,\n candidate.candidateSegments,\n baseSegments\n ),\n totalBends: candidate.totalBends,\n length: candidate.length,\n };\n });\n };\n\n const pairCrossingCount = (\n current: CrossingSnapshot,\n firstEdge: MaterializedEdge,\n firstCandidate: PairCandidate,\n secondEdge: MaterializedEdge,\n secondCandidate: PairCandidate,\n baseSegments: Map<MaterializedEdge, SegmentLite[]>\n ): number => {\n let currentAffected = 0;\n for (const pair of current.pairs) {\n if (\n pair.first === firstEdge ||\n pair.second === firstEdge ||\n pair.first === secondEdge ||\n pair.second === secondEdge\n ) {\n currentAffected += pair.count;\n }\n }\n\n let replacementAffected = crossingCountBetweenSegments(\n firstCandidate.segments,\n secondCandidate.segments\n );\n for (const other of visibleEdges) {\n if (other === firstEdge || other === secondEdge) {\n continue;\n }\n const otherSegments = baseSegments.get(other) ?? segmentsFor(replacementPointsFor(other));\n replacementAffected +=\n crossingCountBetweenSegments(firstCandidate.segments, otherSegments) +\n crossingCountBetweenSegments(secondCandidate.segments, otherSegments);\n }\n\n return current.count - currentAffected + replacementAffected;\n };\n\n const conflictsOnlyWith = (candidate: PairCandidate, edge: MaterializedEdge): boolean => {\n for (const conflict of candidate.sharedTrackConflicts) {\n if (conflict !== edge) {\n return false;\n }\n }\n return true;\n };\n\n const candidatesShareTrack = (\n firstCandidate: PairCandidate,\n secondCandidate: PairCandidate\n ): boolean =>\n firstCandidate.segments.some((firstSegment) =>\n secondCandidate.segments.some(\n (secondSegment) =>\n sameAxisSegmentOverlapLength(firstSegment, secondSegment, 0.5) >= MIN_SHARED\n )\n );\n\n const pairCandidatesAreCompatible = (\n first: PairOption,\n firstCandidate: PairCandidate,\n second: PairOption,\n secondCandidate: PairCandidate\n ): boolean =>\n conflictsOnlyWith(firstCandidate, second.edge) &&\n conflictsOnlyWith(secondCandidate, first.edge) &&\n !candidatesShareTrack(firstCandidate, secondCandidate);\n\n const scorePairReplacement = (\n context: PairScoringContext,\n first: PairOption,\n firstCandidate: PairCandidate,\n second: PairOption,\n secondCandidate: PairCandidate\n ): PairReplacementScore | undefined => {\n const crossings = pairCrossingCount(\n context.current,\n first.edge,\n firstCandidate,\n second.edge,\n secondCandidate,\n context.baseSegments\n );\n if (crossings >= context.current.count) {\n return undefined;\n }\n\n return {\n replacements: new Map<MaterializedEdge, PointLite[]>([\n [first.edge, firstCandidate.path],\n [second.edge, secondCandidate.path],\n ]),\n crossings,\n bends:\n context.currentBends -\n (context.baseBendsByEdge.get(first.edge) ?? 0) -\n (context.baseBendsByEdge.get(second.edge) ?? 0) +\n firstCandidate.totalBends +\n secondCandidate.totalBends,\n length:\n context.currentLength -\n (context.baseLengthByEdge.get(first.edge) ?? 0) -\n (context.baseLengthByEdge.get(second.edge) ?? 0) +\n firstCandidate.length +\n secondCandidate.length,\n };\n };\n\n const pairScoreIsBetter = (\n candidate: PairReplacementScore,\n best: PairReplacementScore\n ): boolean =>\n candidate.crossings < best.crossings ||\n (candidate.crossings === best.crossings &&\n (candidate.bends < best.bends ||\n (candidate.bends === best.bends && candidate.length < best.length)));\n\n const bestScoreForOptionPair = (\n context: PairScoringContext,\n first: PairOption,\n second: PairOption,\n best: PairReplacementScore\n ): PairReplacementScore => {\n let pairBest = best;\n for (const firstCandidate of first.candidates) {\n for (const secondCandidate of second.candidates) {\n if (!pairCandidatesAreCompatible(first, firstCandidate, second, secondCandidate)) {\n continue;\n }\n const score = scorePairReplacement(context, first, firstCandidate, second, secondCandidate);\n if (score && pairScoreIsBetter(score, pairBest)) {\n pairBest = score;\n }\n }\n }\n return pairBest;\n };\n\n const bestPairedReplacement = (current: CrossingSnapshot): EdgeReplacementMap | undefined => {\n const currentBends = totalBends();\n const currentLength = totalLength();\n const baseSegments = currentSegmentsByEdge();\n const crossingCountByEdge = currentCrossingsByEdge(current);\n const baseBendsByEdge = new Map(\n visibleEdges.map((edge) => [edge, countOrthogonalBends(replacementPointsFor(edge))] as const)\n );\n const baseLengthByEdge = new Map(\n visibleEdges.map((edge) => [edge, pathLength(replacementPointsFor(edge))] as const)\n );\n const optionsByEdge = new Map<MaterializedEdge, PairOption>();\n const groups = pairSearchGroups(current);\n for (const group of groups) {\n for (const edge of group) {\n if (optionsByEdge.has(edge)) {\n continue;\n }\n const candidates = pairCandidatesFor(edge, current, baseSegments, crossingCountByEdge);\n if (candidates.length > 0) {\n optionsByEdge.set(edge, { edge, candidates });\n }\n }\n }\n\n let best: PairReplacementScore = {\n replacements: new Map(),\n crossings: current.count,\n bends: currentBends,\n length: currentLength,\n };\n const scoringContext: PairScoringContext = {\n current,\n currentBends,\n currentLength,\n baseBendsByEdge,\n baseLengthByEdge,\n baseSegments,\n };\n\n for (const group of groups) {\n const crossingEdgeSet = new Set(group.filter((edge) => current.edgeSet.has(edge)));\n const options = group\n .map((edge) => optionsByEdge.get(edge))\n .filter((option): option is PairOption => Boolean(option));\n for (let i = 0; i < options.length; i++) {\n const first = options[i];\n for (let j = i + 1; j < options.length; j++) {\n const second = options[j];\n if (!crossingEdgeSet.has(first.edge) && !crossingEdgeSet.has(second.edge)) {\n continue;\n }\n best = bestScoreForOptionPair(scoringContext, first, second, best);\n }\n }\n }\n\n return best.replacements.size > 0 ? best.replacements : undefined;\n };\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n const current = crossingSnapshot();\n const currentCrossings = current.count;\n if (currentCrossings === 0) {\n return;\n }\n\n let bestEdge: { points?: PointLite[] } | undefined;\n let bestPath: PointLite[] | undefined;\n let bestCrossings = currentCrossings;\n let bestBends = Number.POSITIVE_INFINITY;\n\n for (const edge of current.edges) {\n const currentEdgeBends = countOrthogonalBends(replacementPointsFor(edge), EPS_LOCAL);\n for (const candidate of candidatePathsFor(edge)) {\n const candidateHitsNode = pathHitsNode(edge, candidate);\n const candidateHasSegmentConflict =\n !candidateHitsNode && pathHasSegmentConflict(edge, candidate);\n const candidateCrossings = crossingCountWithSingleReplacement(current, edge, candidate);\n const candidateBends = countOrthogonalBends(candidate, EPS_LOCAL);\n if (candidateHitsNode || candidateHasSegmentConflict) {\n continue;\n }\n const improvesCurrentEdge =\n candidateCrossings < currentCrossings ||\n (candidateCrossings === currentCrossings && candidateBends < currentEdgeBends);\n if (!improvesCurrentEdge) {\n continue;\n }\n if (\n candidateCrossings > bestCrossings ||\n (candidateCrossings === bestCrossings && candidateBends >= bestBends)\n ) {\n continue;\n }\n bestEdge = edge;\n bestPath = candidate;\n bestCrossings = candidateCrossings;\n bestBends = candidateBends;\n }\n }\n\n if (bestEdge && bestPath) {\n bestEdge.points = bestPath;\n continue;\n }\n\n const pairedReplacement = bestPairedReplacement(current);\n if (!pairedReplacement) {\n return;\n }\n for (const [edge, points] of pairedReplacement) {\n (edge as { points: PointLite[] }).points = points;\n }\n }\n}\n", "// cspell:ignore Hegemann Wybrow\n\nimport type { NodeBoundsInfo } from './geometry.js';\nimport {\n buildOrthogonalPortPath,\n buildSameSideTrackPath,\n collectRealNodeBounds,\n countOrthogonalBends,\n orthogonalSegmentsCross,\n orthogonalSegmentsForPoints,\n portForRectSide,\n sameAxisSegmentOverlapLength,\n segmentHitsAnyRect,\n} from './geometry.js';\nimport type { RectSide } from './geometry.js';\n\nconst EPS = 1e-3;\nconst MIN_SHARED = 8;\n\nexport function simplifyDetouredEdges(edges: any[], nodes: any[]): void {\n const { nodeInfoById, realNodeRects } = collectRealNodeBounds(nodes);\n\n const sides: RectSide[] = ['top', 'bottom', 'left', 'right'];\n\n // Anchor offset for port exit. Each port's first/last segment must\n // extend in the port's perpendicular direction by at least this many\n // units before turning, so (a) the port-direction check in\n // validateLayout is satisfied and (b) the segment does not hug the\n // node's boundary. Matches raykov's ANCHOR_OFFSET.\n const ANCHOR = 20;\n\n const outsideTracks = {\n top: Math.min(...realNodeRects.map((node) => node.rect.top)) - ANCHOR,\n bottom: Math.max(...realNodeRects.map((node) => node.rect.bottom)) + ANCHOR,\n left: Math.min(...realNodeRects.map((node) => node.rect.left)) - ANCHOR,\n right: Math.max(...realNodeRects.map((node) => node.rect.right)) + ANCHOR,\n };\n\n const buildOrthogonalPathCandidates = (\n src: { x: number; y: number },\n srcSide: RectSide,\n dst: { x: number; y: number },\n dstSide: RectSide\n ): { x: number; y: number }[][] => {\n const paths: { x: number; y: number }[][] = [];\n const base = buildOrthogonalPortPath(src, srcSide, dst, dstSide, ANCHOR, EPS);\n if (base) {\n paths.push(base);\n }\n\n // Crossing-reduction extension of the same-side detour rule above:\n // when the local \"just outside these two ports\" track still crosses\n // an existing connector, also try the corresponding global outer\n // channel. This mirrors Wybrow-style post-route nudging/ordering:\n // preserve the port pair and topology class, but move the maximal\n // middle segment into an uncongested alley if safety checks accept it.\n if (srcSide === dstSide) {\n paths.push(buildSameSideTrackPath(src, srcSide, dst, outsideTracks[srcSide]));\n }\n\n return paths;\n };\n\n const pathHitsNode = (pts: { x: number; y: number }[], excludeIds: string[]): boolean => {\n for (let i = 0; i < pts.length - 1; i++) {\n const a = pts[i];\n const b = pts[i + 1];\n if (segmentHitsAnyRect(a, b, realNodeRects, excludeIds, 1)) {\n return true;\n }\n }\n return false;\n };\n\n const pathConflictCount = (\n path: { x: number; y: number }[],\n currentEdge: any,\n includeIncidentEdges = false\n ): number => {\n let conflicts = 0;\n const pathSegments = orthogonalSegmentsForPoints(path, EPS);\n const currentStart = (currentEdge as { start?: string }).start;\n const currentEnd = (currentEdge as { end?: string }).end;\n for (const other of edges) {\n if (other === currentEdge || (other as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const otherStart = (other as { start?: string }).start;\n const otherEnd = (other as { end?: string }).end;\n if (\n !includeIncidentEdges &&\n currentStart &&\n currentEnd &&\n (otherStart === currentStart ||\n otherStart === currentEnd ||\n otherEnd === currentStart ||\n otherEnd === currentEnd)\n ) {\n continue;\n }\n const otherPts = (other as { points?: { x: number; y: number }[] }).points;\n if (!otherPts || otherPts.length < 2) {\n continue;\n }\n for (const pathSegment of pathSegments) {\n for (const otherSegment of orthogonalSegmentsForPoints(otherPts, EPS)) {\n if (\n orthogonalSegmentsCross(\n pathSegment.a,\n pathSegment.b,\n otherSegment.a,\n otherSegment.b,\n EPS,\n EPS\n )\n ) {\n conflicts++;\n continue;\n }\n if (sameAxisSegmentOverlapLength(pathSegment, otherSegment, EPS) >= MIN_SHARED) {\n conflicts++;\n }\n }\n }\n }\n return conflicts;\n };\n\n const BEND_THRESHOLD = 4;\n\n // Collect which node faces are already claimed by other edges so the\n // rewrite loop below can reject a candidate port pair whose face is\n // contested. This realizes Hegemann-Wolff's bend-or-end global\n // feasibility rule (src d30cdbe1): two edges claiming the same node\n // face must be feasibility-checked as a set, never accepted as a\n // sequential patch.\n //\n // Iter 9 defect: raykov routed L_D_E_0 around H with 4 bends and\n // L_E_F_0 cleanly at E.top in parallel; this pass then rewrote\n // L_D_E_0 to the 2-bend (D.top, E.top) L-shape because it only\n // checked against real-node obstacles and was blind to the E.top\n // claim L_E_F_0 had already made.\n //\n // Note the face-detection uses `nearestSideOfRect` which picks\n // whichever of the 4 rect edges the point is closest to. The\n // polyline endpoints at this point in the pipeline are ALREADY\n // transformed to TB coordinates but the final endpoint-clip pass\n // (which snaps each endpoint onto the actual rect boundary) runs\n // LATER, so the raw attach points may sit a few units inside the\n // node rect. Nearest-side works regardless of whether the point is\n // on, just outside, or a few units inside the rect.\n const nearestSideOfRect = (pt: { x: number; y: number }, info: NodeBoundsInfo): RectSide => {\n const dTop = Math.abs(pt.y - info.rect.top);\n const dBottom = Math.abs(pt.y - info.rect.bottom);\n const dLeft = Math.abs(pt.x - info.rect.left);\n const dRight = Math.abs(pt.x - info.rect.right);\n let best: RectSide = 'top';\n let bestDist = dTop;\n if (dBottom < bestDist) {\n best = 'bottom';\n bestDist = dBottom;\n }\n if (dLeft < bestDist) {\n best = 'left';\n bestDist = dLeft;\n }\n if (dRight < bestDist) {\n best = 'right';\n bestDist = dRight;\n }\n return best;\n };\n\n interface FaceClaim {\n side: RectSide;\n edgeId: string;\n }\n const faceClaims = new Map<string, FaceClaim[]>();\n const addFaceClaim = (nodeId: string, side: RectSide, edgeId: string) => {\n const claims = faceClaims.get(nodeId) ?? [];\n claims.push({ side, edgeId });\n faceClaims.set(nodeId, claims);\n };\n for (const e of edges) {\n if ((e as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const pts = (e as { points?: { x: number; y: number }[] }).points ?? [];\n if (pts.length < 1) {\n continue;\n }\n const eId = (e as { id?: string }).id ?? '';\n const startId = (e as { start?: string }).start;\n const endId = (e as { end?: string }).end;\n if (startId) {\n const info = nodeInfoById.get(startId);\n if (info) {\n addFaceClaim(startId, nearestSideOfRect(pts[0], info), eId);\n }\n }\n if (endId) {\n const info = nodeInfoById.get(endId);\n if (info) {\n addFaceClaim(endId, nearestSideOfRect(pts[pts.length - 1], info), eId);\n }\n }\n }\n\n const faceIsClaimed = (nodeId: string, side: RectSide, ignoreEdgeId: string): boolean => {\n return (\n faceClaims.get(nodeId)?.some((c) => c.edgeId !== ignoreEdgeId && c.side === side) ?? false\n );\n };\n\n for (const edge of edges) {\n if (edge.isLayoutOnly) {\n continue;\n }\n const pts = edge.points as { x: number; y: number }[] | undefined;\n if (!pts || pts.length < 2) {\n continue;\n }\n const currentBends = countOrthogonalBends(pts, EPS);\n if (currentBends < BEND_THRESHOLD) {\n continue;\n }\n const srcId = edge.start as string | undefined;\n const dstId = edge.end as string | undefined;\n if (!srcId || !dstId) {\n continue;\n }\n const srcInfo = nodeInfoById.get(srcId);\n const dstInfo = nodeInfoById.get(dstId);\n if (!srcInfo || !dstInfo) {\n continue;\n }\n const edgeId = (edge as { id?: string }).id ?? '';\n const currentCrossingConflicts = pathConflictCount(pts, edge, true);\n const currentNonIncidentConflicts = pathConflictCount(pts, edge);\n\n let bestPath: { x: number; y: number }[] | undefined;\n let bestCrossingConflicts = currentCrossingConflicts;\n let bestBends = currentBends;\n\n for (const srcSide of sides) {\n if (faceIsClaimed(srcId, srcSide, edgeId)) {\n continue;\n }\n const srcPort = portForRectSide(srcInfo, srcSide);\n for (const dstSide of sides) {\n if (faceIsClaimed(dstId, dstSide, edgeId)) {\n continue;\n }\n const dstPort = portForRectSide(dstInfo, dstSide);\n for (const path of buildOrthogonalPathCandidates(srcPort, srcSide, dstPort, dstSide)) {\n if (pathHitsNode(path, [srcId, dstId])) {\n continue;\n }\n\n const pathBends = countOrthogonalBends(path, EPS);\n if (currentCrossingConflicts > 0) {\n const pathCrossingConflicts = pathConflictCount(path, edge, true);\n if (\n pathCrossingConflicts > bestCrossingConflicts ||\n (pathCrossingConflicts === bestCrossingConflicts && pathBends >= bestBends)\n ) {\n continue;\n }\n bestCrossingConflicts = pathCrossingConflicts;\n bestBends = pathBends;\n bestPath = path;\n continue;\n }\n\n if (pathConflictCount(path, edge) > currentNonIncidentConflicts) {\n continue;\n }\n if (pathBends < bestBends) {\n bestBends = pathBends;\n bestPath = path;\n }\n }\n }\n }\n\n if (bestPath) {\n (edge as { points: { x: number; y: number }[] }).points = bestPath;\n // Refresh face claims for this edge so downstream iterations\n // see the new attach sides. The loop mutates edges in place;\n // stale claims would let two edges both commit to the same face.\n const refreshSrc = faceClaims.get(srcId);\n if (refreshSrc) {\n faceClaims.set(\n srcId,\n refreshSrc.filter((c) => c.edgeId !== edgeId)\n );\n }\n const refreshDst = faceClaims.get(dstId);\n if (refreshDst) {\n faceClaims.set(\n dstId,\n refreshDst.filter((c) => c.edgeId !== edgeId)\n );\n }\n addFaceClaim(srcId, nearestSideOfRect(bestPath[0], srcInfo), edgeId);\n addFaceClaim(dstId, nearestSideOfRect(bestPath[bestPath.length - 1], dstInfo), edgeId);\n }\n }\n}\n", "// cspell:ignore Helmers Wybrow\nimport type { Edge, Node } from '../../../types.js';\nimport {\n dedupeConsecutivePoints,\n inflateRect,\n rectContainsRect,\n rectFromCenterSize,\n rectOfNodeBounds,\n rectsOverlap,\n segmentBoundsOverlapRect,\n} from './geometry.js';\nimport type { RectBounds } from './geometry.js';\n\nconst EPS = 1e-3;\nconst MARKER_CLEARANCE_LENGTH = 10;\nconst MARKER_CLEARANCE_HALF_WIDTH = 7;\n\nfunction markerClearanceRectFor(\n pts: { x: number; y: number }[],\n atStart: boolean\n): RectBounds | undefined {\n const terminalIndex = atStart ? 0 : pts.length - 1;\n const step = atStart ? 1 : -1;\n const tip = pts[terminalIndex];\n const inner = pts[terminalIndex + step];\n if (!tip || !inner) {\n return undefined;\n }\n\n const dx = inner.x - tip.x;\n const dy = inner.y - tip.y;\n const len = Math.abs(dx) + Math.abs(dy);\n if (len < EPS) {\n return undefined;\n }\n\n if (Math.abs(dy) <= EPS) {\n const x2 = tip.x + Math.sign(dx) * MARKER_CLEARANCE_LENGTH;\n return {\n left: Math.min(tip.x, x2),\n right: Math.max(tip.x, x2),\n top: tip.y - MARKER_CLEARANCE_HALF_WIDTH,\n bottom: tip.y + MARKER_CLEARANCE_HALF_WIDTH,\n };\n }\n\n if (Math.abs(dx) <= EPS) {\n const y2 = tip.y + Math.sign(dy) * MARKER_CLEARANCE_LENGTH;\n return {\n left: tip.x - MARKER_CLEARANCE_HALF_WIDTH,\n right: tip.x + MARKER_CLEARANCE_HALF_WIDTH,\n top: Math.min(tip.y, y2),\n bottom: Math.max(tip.y, y2),\n };\n }\n\n return {\n left: Math.min(tip.x, inner.x),\n right: Math.max(tip.x, inner.x),\n top: Math.min(tip.y, inner.y),\n bottom: Math.max(tip.y, inner.y),\n };\n}\n\nfunction normalizeRect(rect: RectBounds): RectBounds {\n return {\n left: Math.min(rect.left, rect.right),\n right: Math.max(rect.left, rect.right),\n top: Math.min(rect.top, rect.bottom),\n bottom: Math.max(rect.top, rect.bottom),\n };\n}\n\nfunction labelOverlapsOwnMarker(rect: RectBounds, pts: { x: number; y: number }[]): boolean {\n const visiblePts = dedupeConsecutivePoints(pts);\n const startMarker = markerClearanceRectFor(visiblePts, true);\n const endMarker = markerClearanceRectFor(visiblePts, false);\n return [startMarker, endMarker].some(\n (marker) => marker && rectsOverlap(rect, normalizeRect(marker))\n );\n}\n\nexport function anchorLabelsToPolyline(edges: Edge[], nodeByIdMap: Map<string, Node>): void {\n // Build a set of foreign polylines once for overlap checks. Labelled\n // originals that haven't been anchored yet are still included \u2014 their\n // polylines exist, even if their labels haven't moved.\n type RectLite = RectBounds;\n interface SegmentLite {\n edgeId: string;\n p1: { x: number; y: number };\n p2: { x: number; y: number };\n }\n const allEdgeSegments: SegmentLite[] = [];\n for (const other of edges) {\n if (other.isLayoutOnly) {\n continue;\n }\n const pts = other.points;\n if (!pts || pts.length < 2) {\n continue;\n }\n for (let i = 0; i < pts.length - 1; i++) {\n allEdgeSegments.push({ edgeId: other.id, p1: pts[i], p2: pts[i + 1] });\n }\n }\n\n const foreignNodeRects: { nodeId: string; rect: RectLite }[] = [];\n // Collect top-level lane groups so we can re-assign a label's parentId to\n // whichever lane geometrically contains its anchored position. Without\n // this, labels whose anchor crosses a lane boundary are reported as\n // node-overlap violations against sibling lane groups.\n const laneGroups: { id: string; rect: RectLite }[] = [];\n for (const n of nodeByIdMap.values()) {\n const isGroup = n.isGroup;\n const parentId = n.parentId;\n if (isGroup && !parentId) {\n const rect = rectOfNodeBounds(n);\n if (rect) {\n laneGroups.push({\n id: n.id,\n rect,\n });\n }\n continue;\n }\n if (isGroup) {\n continue;\n }\n if (n.isEdgeLabel) {\n continue;\n }\n const rect = rectOfNodeBounds(n);\n if (!rect) {\n continue;\n }\n foreignNodeRects.push({\n nodeId: n.id,\n rect,\n });\n }\n\n // Inflation margin for foreign-edge / foreign-node proximity. The layout\n // validator's `edge-border-hugging` check fires when a polyline runs\n // within ~2u of a label's visual border (EPS_BORDER). Inflate the label\n // rect we test by a little more than that when rejecting candidates, so\n // no chosen placement will trigger the hug check. 3u preserves the buffer\n // used by the old pre-label detour pass.\n const LABEL_PLACEMENT_BUFFER = 3;\n const LABEL_LANE_MARGIN = 1;\n // Mermaid's point marker occupies roughly 10u at the edge endpoint; keep\n // labels a little farther away so the arrowhead remains visually readable.\n const LABEL_ENDPOINT_CLEARANCE = 12;\n\n const labelOverlapsForeignNode = (labelId: string, rect: RectLite): boolean => {\n const buffered = inflateRect(rect, LABEL_PLACEMENT_BUFFER);\n for (const { nodeId, rect: nr } of foreignNodeRects) {\n if (nodeId === labelId) {\n continue;\n }\n if (rectsOverlap(buffered, nr)) {\n return true;\n }\n }\n return false;\n };\n\n const labelOverlapsForeignEdge = (edgeId: string, rect: RectLite): boolean => {\n const buffered = inflateRect(rect, LABEL_PLACEMENT_BUFFER);\n for (const s of allEdgeSegments) {\n if (s.edgeId === edgeId) {\n continue;\n }\n if (segmentBoundsOverlapRect(s.p1, s.p2, buffered)) {\n return true;\n }\n }\n return false;\n };\n\n const labelOverlapsAnything = (labelId: string, edgeId: string, rect: RectLite): boolean =>\n labelOverlapsForeignNode(labelId, rect) || labelOverlapsForeignEdge(edgeId, rect);\n\n const placedLabelRects: { labelId: string; rect: RectLite }[] = [];\n\n const findContainingLane = (rect: RectLite): string | undefined => {\n for (const { id, rect: laneRect } of laneGroups) {\n if (rectContainsRect(laneRect, rect)) {\n return id;\n }\n }\n return undefined;\n };\n\n const overlapsPlacedLabel = (labelId: string, rect: RectLite): boolean =>\n placedLabelRects.some(\n (placed) => placed.labelId !== labelId && rectsOverlap(rect, placed.rect)\n );\n\n interface SegmentCandidate {\n idx: number;\n length: number;\n orientation: 'horizontal' | 'vertical';\n midX: number;\n midY: number;\n }\n\n for (const edge of edges) {\n if (edge.isLayoutOnly) {\n continue;\n }\n const labelId = edge.labelNodeId;\n if (!labelId) {\n continue;\n }\n const labelNode = nodeByIdMap.get(labelId);\n if (!labelNode) {\n continue;\n }\n const pts = edge.points;\n if (!pts || pts.length < 2) {\n continue;\n }\n const lw = labelNode.width ?? 0;\n const lh = labelNode.height ?? 0;\n if (lw <= 0 || lh <= 0) {\n continue;\n }\n\n // Collect every non-zero segment with orientation.\n const segments: SegmentCandidate[] = [];\n for (let i = 0; i < pts.length - 1; i++) {\n const a = pts[i];\n const b = pts[i + 1];\n const dx = Math.abs(a.x - b.x);\n const dy = Math.abs(a.y - b.y);\n if (dx < EPS && dy < EPS) {\n continue;\n }\n if (dx >= EPS && dy >= EPS) {\n continue; // non-orthogonal \u2014 should not happen post-orthogonalize\n }\n segments.push({\n idx: i,\n length: dx + dy,\n orientation: dx >= EPS ? 'horizontal' : 'vertical',\n midX: (a.x + b.x) / 2,\n midY: (a.y + b.y) / 2,\n });\n }\n\n if (segments.length === 0) {\n continue;\n }\n\n // \u00A7118: middle segments only (exclude first and last). Fall back to\n // any segment if the polyline has fewer than 3 segments (the paper is\n // silent on degenerate cases \u2014 Mermaid calibration).\n const middleSegments =\n segments.length >= 3\n ? segments.filter((s) => s.idx > 0 && s.idx < segments.length - 1)\n : segments;\n const poolBase = middleSegments.length > 0 ? middleSegments : segments;\n\n // Label long axis: horizontal if wider than tall, else vertical. The\n // label is drawn horizontally inside its bbox regardless, so the long\n // axis only drives preference, not hard filtering.\n const labelLongAxis: 'horizontal' | 'vertical' = lw >= lh ? 'horizontal' : 'vertical';\n\n // Candidate ranking: (a) length >= labelExtent + 2, (b) orientation\n // matching label long axis preferred, (c) longest tie-break.\n const rankSegments = (pool: SegmentCandidate[]): SegmentCandidate[] => {\n return [...pool].sort((a, b) => {\n const aLongAxis = a.orientation === labelLongAxis;\n const bLongAxis = b.orientation === labelLongAxis;\n if (aLongAxis !== bLongAxis) {\n return aLongAxis ? -1 : 1;\n }\n const aFits = a.length >= (a.orientation === 'horizontal' ? lw : lh) + 2;\n const bFits = b.length >= (b.orientation === 'horizontal' ? lw : lh) + 2;\n if (aFits !== bFits) {\n return aFits ? -1 : 1;\n }\n return b.length - a.length;\n });\n };\n\n // Try the middle-segment pool first (\u00A7118), then expand to include\n // every orthogonal segment if the middle-only pool yields no\n // lane-containing, overlap-free candidate. The \"any segment\" expansion\n // is a Mermaid-specific adaptation for cross-lane edges whose only\n // middle segment is the vertical lane-crossing leg (which by\n // construction straddles a lane boundary and cannot host the label).\n //\n // Per-segment, if the midpoint (t=0.5) collides with a foreign edge\n // or label, walk along the segment at additional parametric positions\n // t \u2208 {0.25, 0.75, 0.15, 0.85, 0.1, 0.9} before moving on. Helmers diss.pdf\n // \u00A7118 requires \"one of e's middle segments\" but is silent on the\n // exact anchor position along that segment, so along-segment shift is\n // consistent with the paper (Mermaid adaptation). Paper-adjacent to\n // Wybrow-Marriott alley-midpoint centering (src `e8804c93`), which\n // picks the placement with widest clearance to foreign geometry.\n const firstVisibleSegment = segments[0];\n const lastVisibleSegment = segments[segments.length - 1];\n const ALONG_SEGMENT_TS = [0.5, 0.25, 0.75, 0.05, 0.95, 0.15, 0.85, 0.1, 0.9];\n const anchorAtT = (seg: SegmentCandidate, t: number): { midX: number; midY: number } => {\n const a = pts[seg.idx];\n const b = pts[seg.idx + 1];\n return {\n midX: a.x + (b.x - a.x) * t,\n midY: a.y + (b.y - a.y) * t,\n };\n };\n const clamp = (value: number, min: number, max: number): number =>\n Math.min(max, Math.max(min, value));\n const pointInsideRectInclusive = (\n point: { midX: number; midY: number },\n rect: RectLite\n ): boolean =>\n point.midX >= rect.left - EPS &&\n point.midX <= rect.right + EPS &&\n point.midY >= rect.top - EPS &&\n point.midY <= rect.bottom + EPS;\n const placementForAnchor = (anchor: {\n midX: number;\n midY: number;\n }): { laneId: string; anchor: { midX: number; midY: number }; rect: RectLite } | undefined => {\n const centeredRect = rectFromCenterSize(anchor.midX, anchor.midY, lw, lh);\n const centeredLane = findContainingLane(centeredRect);\n if (centeredLane) {\n return { laneId: centeredLane, anchor, rect: centeredRect };\n }\n\n // If the segment is close to a lane border, keep the label box inside\n // the lane while requiring the original segment point to remain inside\n // that box. The validator then sees the edge passing through the label.\n const containingLane = laneGroups.find(({ rect }) => pointInsideRectInclusive(anchor, rect));\n if (!containingLane) {\n return undefined;\n }\n\n const minX = containingLane.rect.left + lw / 2 + LABEL_LANE_MARGIN;\n const maxX = containingLane.rect.right - lw / 2 - LABEL_LANE_MARGIN;\n const minY = containingLane.rect.top + lh / 2 + LABEL_LANE_MARGIN;\n const maxY = containingLane.rect.bottom - lh / 2 - LABEL_LANE_MARGIN;\n if (minX > maxX || minY > maxY) {\n return undefined;\n }\n\n const clampedAnchor = {\n midX: clamp(anchor.midX, minX, maxX),\n midY: clamp(anchor.midY, minY, maxY),\n };\n const clampedRect = rectFromCenterSize(clampedAnchor.midX, clampedAnchor.midY, lw, lh);\n return pointInsideRectInclusive(anchor, clampedRect)\n ? { laneId: containingLane.id, anchor: clampedAnchor, rect: clampedRect }\n : undefined;\n };\n const distanceAlongSegment = (\n seg: SegmentCandidate,\n anchor: { midX: number; midY: number },\n endpoint: { x: number; y: number }\n ): number =>\n seg.orientation === 'horizontal'\n ? Math.abs(anchor.midX - endpoint.x)\n : Math.abs(anchor.midY - endpoint.y);\n const labelClearsTerminalEndpoints = (\n seg: SegmentCandidate,\n anchor: { midX: number; midY: number }\n ): boolean => {\n const labelHalfExtent = seg.orientation === 'horizontal' ? lw / 2 : lh / 2;\n const requiredDistance = labelHalfExtent + LABEL_ENDPOINT_CLEARANCE;\n if (seg === firstVisibleSegment) {\n const start = pts[seg.idx];\n if (distanceAlongSegment(seg, anchor, start) + EPS < requiredDistance) {\n return false;\n }\n }\n if (seg === lastVisibleSegment) {\n const end = pts[seg.idx + 1];\n if (distanceAlongSegment(seg, anchor, end) + EPS < requiredDistance) {\n return false;\n }\n }\n return true;\n };\n const tryPool = (\n pool: SegmentCandidate[]\n ): { laneId: string; anchor: { midX: number; midY: number } } | undefined => {\n const rankedPool = rankSegments(pool);\n for (const seg of rankedPool) {\n for (const t of ALONG_SEGMENT_TS) {\n const anchor = anchorAtT(seg, t);\n if (!labelClearsTerminalEndpoints(seg, anchor)) {\n continue;\n }\n const placement = placementForAnchor(anchor);\n if (!placement) {\n continue;\n }\n if (labelOverlapsOwnMarker(placement.rect, pts)) {\n continue;\n }\n if (overlapsPlacedLabel(labelId, placement.rect)) {\n continue;\n }\n if (!labelOverlapsAnything(labelId, edge.id, placement.rect)) {\n return { laneId: placement.laneId, anchor: placement.anchor };\n }\n }\n }\n return undefined;\n };\n\n const findLaneContainingFallback = (\n pool: SegmentCandidate[],\n requireEndpointClearance: boolean,\n allowForeignEdgeOverlap = false\n ): { laneId: string; anchor: { midX: number; midY: number } } | undefined => {\n const rankedPool = rankSegments(pool);\n for (const seg of rankedPool) {\n const anchor = { midX: seg.midX, midY: seg.midY };\n if (requireEndpointClearance && !labelClearsTerminalEndpoints(seg, anchor)) {\n continue;\n }\n const placement = placementForAnchor(anchor);\n if (\n placement &&\n !labelOverlapsOwnMarker(placement.rect, pts) &&\n !overlapsPlacedLabel(labelId, placement.rect) &&\n !labelOverlapsForeignNode(labelId, placement.rect) &&\n (allowForeignEdgeOverlap || !labelOverlapsForeignEdge(edge.id, placement.rect))\n ) {\n return { laneId: placement.laneId, anchor: placement.anchor };\n }\n }\n return undefined;\n };\n\n const chosen =\n tryPool(poolBase) ??\n (poolBase.length < segments.length ? tryPool(segments) : undefined) ??\n findLaneContainingFallback(segments, true) ??\n findLaneContainingFallback(segments, false) ??\n findLaneContainingFallback(segments, false, true);\n\n if (chosen) {\n labelNode.x = chosen.anchor.midX;\n labelNode.y = chosen.anchor.midY;\n labelNode.parentId = chosen.laneId;\n const chosenRect = rectFromCenterSize(chosen.anchor.midX, chosen.anchor.midY, lw, lh);\n const priorIdx = placedLabelRects.findIndex((placed) => placed.labelId === labelId);\n if (priorIdx >= 0) {\n placedLabelRects[priorIdx] = { labelId, rect: chosenRect };\n } else {\n placedLabelRects.push({ labelId, rect: chosenRect });\n }\n }\n }\n}\n", "// cspell:ignore Hegemann Kandinsky Siebenhaller\nimport type { Edge, Node } from '../../../types.js';\nimport {\n classifyThreeSegmentRoute,\n collectRealNodeBounds,\n getNodePairGeometry,\n segmentConflictsWithAnyEdge,\n segmentHitsAnyRect,\n} from './geometry.js';\n\nconst EPS = 1e-6;\nconst MIN_PORT_SPACING = 8;\nconst PORT_SHIFT = MIN_PORT_SPACING / 2;\nconst LABEL_CLEARANCE_BUFFER = 3;\n\ninterface PointLite {\n x: number;\n y: number;\n}\n\ninterface LabelDim {\n w: number;\n h: number;\n}\n\nfunction pairKey(a: string, b: string): string {\n return a < b ? `${a}::${b}` : `${b}::${a}`;\n}\n\n/**\n * Iter 12 \u2014 co-route sibling straight-line rescue.\n *\n * Fires only on the narrow \"4-point U-detour around a collinear blocker\n * where the obvious straight line is geometrically clear\" shape. For each\n * eligible edge, shifts the source and destination attach points by\n * MIN_PORT_SPACING/2 along the shared face and replaces the polyline\n * with a 2-point straight line. The shift direction is chosen by trying\n * both +delta and -delta and picking whichever doesn't introduce a new\n * edge crossing or leave the node's face span.\n *\n * Paper backing: Hegemann & Wolff \"On the smoothing of orthogonal\n * connector layouts\" (NotebookLM src b65b3d45) \u00A74.2 / Fig. 11 \u2014\n * joint-feasibility via port distribution rather than face exclusion.\n * Mermaid-specific narrowing: we only rescue the exact 4-point shape to\n * minimize blast radius.\n */\nexport function straightenCollinearSiblingDetours(edges: Edge[], nodes: Node[]): void {\n const { nodeInfoById, realNodeRects } = collectRealNodeBounds(nodes);\n // Side table of label-node dimensions so we can grow the rescue delta\n // far enough to clear a label sitting on the sibling line.\n const labelDimById = new Map<string, LabelDim>();\n for (const n of nodes) {\n const id = n.id;\n if (n.isGroup) {\n continue;\n }\n if (n.isEdgeLabel) {\n labelDimById.set(id, {\n w: n.width ?? 0,\n h: n.height ?? 0,\n });\n continue;\n }\n }\n\n // For a given (this-edge, axis) pair, find the largest label half-extent\n // among any edge sharing the same node pair (anti-parallel siblings) plus\n // this edge's own label. Used to grow the rescue shift past the label so\n // anchorLabelsToPolyline can place the label clear of the sibling.\n const labelClearanceFor = (\n thisEdge: Edge,\n thisSrcId: string,\n thisDstId: string,\n axis: 'x' | 'y'\n ): number => {\n const targetPair = pairKey(thisSrcId, thisDstId);\n let maxHalf = 0;\n const consider = (labelId: string | undefined) => {\n if (!labelId) {\n return;\n }\n const dim = labelDimById.get(labelId);\n if (!dim) {\n return;\n }\n const half = axis === 'x' ? dim.w / 2 : dim.h / 2;\n if (half > maxHalf) {\n maxHalf = half;\n }\n };\n consider(thisEdge.labelNodeId);\n for (const other of edges) {\n if (other === thisEdge) {\n continue;\n }\n if (other.isLayoutOnly) {\n continue;\n }\n const oSrc = other.start;\n const oDst = other.end;\n if (!oSrc || !oDst) {\n continue;\n }\n if (pairKey(oSrc, oDst) !== targetPair) {\n continue;\n }\n consider(other.labelNodeId);\n }\n return maxHalf > 0 ? maxHalf + LABEL_CLEARANCE_BUFFER : 0;\n };\n\n for (const edge of edges) {\n if (edge.isLayoutOnly) {\n continue;\n }\n const pts = edge.points;\n if (!classifyThreeSegmentRoute(pts, EPS)) {\n continue;\n }\n\n const nodePair = getNodePairGeometry(edge, nodeInfoById, EPS);\n if (!nodePair) {\n continue;\n }\n const { srcId, dstId, srcInfo, dstInfo, collinearX, collinearY } = nodePair;\n if (collinearX === collinearY) {\n continue;\n }\n\n let targetSrc: PointLite;\n let targetDst: PointLite;\n if (collinearX) {\n const dstBelow = dstInfo.cy > srcInfo.cy;\n targetSrc = { x: srcInfo.cx, y: dstBelow ? srcInfo.rect.bottom : srcInfo.rect.top };\n targetDst = { x: dstInfo.cx, y: dstBelow ? dstInfo.rect.top : dstInfo.rect.bottom };\n } else {\n const dstEast = dstInfo.cx > srcInfo.cx;\n targetSrc = { x: dstEast ? srcInfo.rect.right : srcInfo.rect.left, y: srcInfo.cy };\n targetDst = { x: dstEast ? dstInfo.rect.left : dstInfo.rect.right, y: dstInfo.cy };\n }\n\n if (segmentHitsAnyRect(targetSrc, targetDst, realNodeRects, [srcId, dstId], 1)) {\n continue;\n }\n\n // The rescue moves the line perpendicular to its own direction: a\n // horizontal rescued line shifts in y (so the label HEIGHT determines\n // clearance), a vertical one shifts in x (label WIDTH). collinearX\n // means the rescued line is vertical (nodes share a column).\n //\n // When the edge (or an anti-parallel sibling) carries a label, the\n // small PORT_SHIFT would leave the rescued straight inside the label's\n // bbox \u2014 the label would visually overlap this line. We grow the\n // shift to clear the label rect. If the wider shift won't fit on the\n // node face, the bounds check below rejects it and we fall through\n // without rescuing, which keeps the original 4-point detour \u2014 also\n // correct, since the detour routes far away from the label.\n const shiftAxis: 'x' | 'y' = collinearX ? 'x' : 'y';\n const labelShift = labelClearanceFor(edge, srcId, dstId, shiftAxis);\n const effectiveShift = labelShift > PORT_SHIFT ? labelShift : PORT_SHIFT;\n const deltas = [0, effectiveShift, -effectiveShift];\n for (const delta of deltas) {\n const shiftedSrc = { ...targetSrc };\n const shiftedDst = { ...targetDst };\n if (collinearX) {\n shiftedSrc.x += delta;\n shiftedDst.x += delta;\n if (shiftedSrc.x <= srcInfo.rect.left || shiftedSrc.x >= srcInfo.rect.right) {\n continue;\n }\n if (shiftedDst.x <= dstInfo.rect.left || shiftedDst.x >= dstInfo.rect.right) {\n continue;\n }\n } else {\n shiftedSrc.y += delta;\n shiftedDst.y += delta;\n if (shiftedSrc.y <= srcInfo.rect.top || shiftedSrc.y >= srcInfo.rect.bottom) {\n continue;\n }\n if (shiftedDst.y <= dstInfo.rect.top || shiftedDst.y >= dstInfo.rect.bottom) {\n continue;\n }\n }\n\n if (segmentHitsAnyRect(shiftedSrc, shiftedDst, realNodeRects, [srcId, dstId], 1)) {\n continue;\n }\n\n if (segmentConflictsWithAnyEdge(shiftedSrc, shiftedDst, edges, edge, { epsilon: EPS })) {\n continue;\n }\n\n edge.points = [shiftedSrc, shiftedDst];\n break;\n }\n }\n}\n", "import type { Edge, Node } from '../../../types.js';\nimport {\n collectNodeRectEntries,\n dedupeConsecutivePoints,\n overlapLength,\n orthogonalSegmentsForPoints,\n orthogonalSegmentsStrictlyCross,\n rectOfNodeBounds,\n segmentHitsAnyRect,\n} from './geometry.js';\nimport type { OrthogonalSegment, Point } from './geometry.js';\n\nexport function nudgeSharedInteriorSubpaths(edges: Edge[], nodeByIdMap: Map<string, Node>): void {\n const EPS_LOCAL = 1e-3;\n const MIN_SHARED = 8;\n const TRACK_SHIFT = 7;\n const MIN_TRACK_GAP = TRACK_SHIFT;\n const SOURCE_DETOUR_STUB = 20;\n const BUFFER = 2;\n const MAX_ITERATIONS = 12;\n\n type PointLite = Point;\n\n interface SegmentLite extends OrthogonalSegment {\n edge: Edge;\n interior: boolean;\n }\n\n const { realNodeRects, labelNodeRects: labelRects } = collectNodeRectEntries(\n nodeByIdMap.values()\n );\n\n const segmentsFor = (edge: Edge, points: PointLite[]): SegmentLite[] => {\n return orthogonalSegmentsForPoints(points, EPS_LOCAL).map((segment) => ({\n ...segment,\n edge,\n interior: segment.index >= 1 && segment.index <= points.length - 3,\n }));\n };\n\n const allSegments = (): SegmentLite[] => {\n const result: SegmentLite[] = [];\n for (const edge of edges) {\n if (edge.isLayoutOnly) {\n continue;\n }\n const points = edge.points;\n if (!points || points.length < 2) {\n continue;\n }\n result.push(...segmentsFor(edge, dedupeConsecutivePoints(points)));\n }\n return result;\n };\n\n const hasCrowdedParallelTrack = (a: SegmentLite, b: SegmentLite): boolean => {\n if (a.horizontal && b.horizontal) {\n return (\n overlapLength(a.a.x, a.b.x, b.a.x, b.b.x) >= MIN_SHARED &&\n Math.abs(a.a.y - b.a.y) < MIN_TRACK_GAP\n );\n }\n if (a.vertical && b.vertical) {\n return (\n overlapLength(a.a.y, a.b.y, b.a.y, b.b.y) >= MIN_SHARED &&\n Math.abs(a.a.x - b.a.x) < MIN_TRACK_GAP\n );\n }\n return false;\n };\n\n const candidateIsSafe = (edge: Edge, candidate: PointLite[]): boolean => {\n const sourceId = edge.start;\n const targetId = edge.end;\n const candidateSegments = segmentsFor(edge, candidate);\n if (candidateSegments.length !== candidate.length - 1) {\n return false;\n }\n\n const endpointIds = [sourceId, targetId].filter((id): id is string => Boolean(id));\n const ownLabelIds = edge.labelNodeId ? [edge.labelNodeId] : [];\n for (const segment of candidateSegments) {\n if (segmentHitsAnyRect(segment.a, segment.b, realNodeRects, endpointIds, -BUFFER)) {\n return false;\n }\n if (segmentHitsAnyRect(segment.a, segment.b, labelRects, ownLabelIds, -BUFFER)) {\n return false;\n }\n }\n\n for (const other of edges) {\n if (other === edge || other.isLayoutOnly) {\n continue;\n }\n const otherPoints = other.points;\n if (!otherPoints || otherPoints.length < 2) {\n continue;\n }\n for (const candidateSegment of candidateSegments) {\n for (const otherSegment of segmentsFor(other, dedupeConsecutivePoints(otherPoints))) {\n if (hasCrowdedParallelTrack(candidateSegment, otherSegment)) {\n return false;\n }\n if (\n orthogonalSegmentsStrictlyCross(\n candidateSegment.a,\n candidateSegment.b,\n otherSegment.a,\n otherSegment.b,\n EPS_LOCAL\n )\n ) {\n return false;\n }\n }\n }\n }\n\n return true;\n };\n\n const shiftedCandidate = (segment: SegmentLite, shift: number): PointLite[] | undefined => {\n const points = dedupeConsecutivePoints(segment.edge.points ?? []);\n if (points.length < 4 || segment.index >= points.length - 1) {\n return undefined;\n }\n const candidate = points.map((p) => ({ ...p }));\n if (segment.horizontal) {\n candidate[segment.index].y += shift;\n candidate[segment.index + 1].y += shift;\n } else if (segment.vertical) {\n candidate[segment.index].x += shift;\n candidate[segment.index + 1].x += shift;\n } else {\n return undefined;\n }\n return segmentsFor(segment.edge, candidate).length === candidate.length - 1\n ? candidate\n : undefined;\n };\n\n type NodeRect = NonNullable<ReturnType<typeof rectOfNodeBounds>>;\n\n interface SourceDetourContext {\n sourceCenter: Point;\n targetCenter: Point;\n sourceRect: NodeRect;\n tail: PointLite[];\n }\n\n const nodeCenter = (node: Node, rect: NodeRect): Point => ({\n x: node.x ?? (rect.left + rect.right) / 2,\n y: node.y ?? (rect.top + rect.bottom) / 2,\n });\n\n const sourceDetourContextFor = (segment: SegmentLite): SourceDetourContext | undefined => {\n const edge = segment.edge;\n const points = dedupeConsecutivePoints(edge.points ?? []);\n if (points.length !== 4 || segment.index !== 1) {\n return undefined;\n }\n\n const sourceNode = edge.start ? nodeByIdMap.get(edge.start) : undefined;\n const targetNode = edge.end ? nodeByIdMap.get(edge.end) : undefined;\n const sourceRect = sourceNode ? rectOfNodeBounds(sourceNode) : undefined;\n const targetRect = targetNode ? rectOfNodeBounds(targetNode) : undefined;\n const tail = points.slice(segment.index + 2);\n if (!sourceNode || !targetNode || !sourceRect || !targetRect || tail.length === 0) {\n return undefined;\n }\n\n return {\n sourceCenter: nodeCenter(sourceNode, sourceRect),\n targetCenter: nodeCenter(targetNode, targetRect),\n sourceRect,\n tail,\n };\n };\n\n const verticalSourceDetour = (\n segment: SegmentLite,\n shift: number,\n sourceCenter: Point,\n targetCenter: Point,\n sourceRect: NodeRect,\n tail: PointLite[]\n ): PointLite[] | undefined => {\n const targetBelow = targetCenter.y >= sourceCenter.y;\n const sourcePortY = targetBelow ? sourceRect.bottom : sourceRect.top;\n const stubY = sourcePortY + (targetBelow ? SOURCE_DETOUR_STUB : -SOURCE_DETOUR_STUB);\n if (\n (targetBelow && segment.b.y <= stubY + EPS_LOCAL) ||\n (!targetBelow && segment.b.y >= stubY - EPS_LOCAL)\n ) {\n return undefined;\n }\n\n const railX = segment.a.x + shift;\n return dedupeConsecutivePoints(\n [\n { x: sourceCenter.x, y: sourcePortY },\n { x: sourceCenter.x, y: stubY },\n { x: railX, y: stubY },\n { x: railX, y: segment.b.y },\n ...tail,\n ],\n EPS_LOCAL\n );\n };\n\n const horizontalSourceDetour = (\n segment: SegmentLite,\n shift: number,\n sourceCenter: Point,\n targetCenter: Point,\n sourceRect: NodeRect,\n tail: PointLite[]\n ): PointLite[] | undefined => {\n const targetRight = targetCenter.x >= sourceCenter.x;\n const sourcePortX = targetRight ? sourceRect.right : sourceRect.left;\n const stubX = sourcePortX + (targetRight ? SOURCE_DETOUR_STUB : -SOURCE_DETOUR_STUB);\n if (\n (targetRight && segment.b.x <= stubX + EPS_LOCAL) ||\n (!targetRight && segment.b.x >= stubX - EPS_LOCAL)\n ) {\n return undefined;\n }\n\n const railY = segment.a.y + shift;\n return dedupeConsecutivePoints(\n [\n { x: sourcePortX, y: sourceCenter.y },\n { x: stubX, y: sourceCenter.y },\n { x: stubX, y: railY },\n { x: segment.b.x, y: railY },\n ...tail,\n ],\n EPS_LOCAL\n );\n };\n\n const sourceDetourCandidate = (segment: SegmentLite, shift: number): PointLite[] | undefined => {\n const context = sourceDetourContextFor(segment);\n if (!context) {\n return undefined;\n }\n\n if (segment.vertical) {\n return verticalSourceDetour(\n segment,\n shift,\n context.sourceCenter,\n context.targetCenter,\n context.sourceRect,\n context.tail\n );\n }\n if (segment.horizontal) {\n return horizontalSourceDetour(\n segment,\n shift,\n context.sourceCenter,\n context.targetCenter,\n context.sourceRect,\n context.tail\n );\n }\n\n return undefined;\n };\n\n const shifts = [\n -TRACK_SHIFT,\n TRACK_SHIFT,\n -2 * TRACK_SHIFT,\n 2 * TRACK_SHIFT,\n -3 * TRACK_SHIFT,\n 3 * TRACK_SHIFT,\n ];\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {\n const segments = allSegments();\n let fixed = false;\n\n for (let i = 0; i < segments.length && !fixed; i++) {\n for (let j = i + 1; j < segments.length && !fixed; j++) {\n const first = segments[i];\n const second = segments[j];\n if (first.edge === second.edge || !hasCrowdedParallelTrack(first, second)) {\n continue;\n }\n\n const candidates = [first, second].filter((segment) => segment.interior);\n for (const segment of candidates) {\n for (const shift of shifts) {\n const direct = shiftedCandidate(segment, shift);\n if (direct && candidateIsSafe(segment.edge, direct)) {\n segment.edge.points = direct;\n fixed = true;\n break;\n }\n\n const detoured = sourceDetourCandidate(segment, shift);\n if (detoured && candidateIsSafe(segment.edge, detoured)) {\n segment.edge.points = detoured;\n fixed = true;\n break;\n }\n }\n if (fixed) {\n break;\n }\n }\n }\n }\n\n if (!fixed) {\n return;\n }\n }\n}\n", "import type { LayoutData } from '../../../types.js';\nimport { log } from '../../../../logger.js';\nimport { collectLayoutNodeRects, segmentBoundsOverlapRect } from './geometry.js';\n\nexport interface ValidationIssue {\n type: 'edge-node-overlap' | 'edge-edge-crossing';\n edgeId: string;\n /** Second edge ID (for crossings) or node ID (for overlaps) */\n targetId: string;\n detail: string;\n}\n\n/**\n * Checks if two line segments intersect.\n * Uses the CCW (counter-clockwise) orientation test.\n * Returns true only for proper intersections: touching endpoints\n * or collinear segments return false.\n */\nfunction segmentsIntersect(\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n p3: { x: number; y: number },\n p4: { x: number; y: number }\n): boolean {\n const d1x = p2.x - p1.x;\n const d1y = p2.y - p1.y;\n const d2x = p4.x - p3.x;\n const d2y = p4.y - p3.y;\n\n const cross = d1x * d2y - d1y * d2x;\n if (Math.abs(cross) < 1e-10) {\n return false; // parallel or collinear\n }\n\n const dx = p3.x - p1.x;\n const dy = p3.y - p1.y;\n const t = (dx * d2y - dy * d2x) / cross;\n const u = (dx * d1y - dy * d1x) / cross;\n\n // Strict interior intersection to avoid false positives at shared nodes.\n const eps = 0.01;\n return t > eps && t < 1 - eps && u > eps && u < 1 - eps;\n}\n\n/**\n * Final validation pass: scans the completed layout for remaining quality\n * issues. Does not attempt fixes, just logs warnings so developers can\n * identify problems during debugging.\n *\n * Checks:\n * 1. Edge segments that still pass through non-endpoint nodes\n * 2. Edge segments that cross other edge segments\n */\nexport function validateSwimlanesLayout(layout: LayoutData): ValidationIssue[] {\n const nodes = layout.nodes ?? [];\n const edges = (layout.edges ?? []) as any[];\n const issues: ValidationIssue[] = [];\n\n if (!edges.length || !nodes.length) {\n return issues;\n }\n\n const nodeRects = collectLayoutNodeRects(nodes);\n\n const epsilon = 1; // tighter than the fix pass: catch marginal overlaps\n const edgeSegments: {\n edgeId: string;\n start: string;\n end: string;\n p1: { x: number; y: number };\n p2: { x: number; y: number };\n }[] = [];\n\n for (const edge of edges) {\n if (edge.isLayoutOnly) {\n continue;\n }\n const points = edge.points as { x: number; y: number }[] | undefined;\n if (!points || points.length < 2) {\n continue;\n }\n const edgeStart = edge.start as string | undefined;\n const edgeEnd = edge.end as string | undefined;\n const ownLabelId = edge.labelNodeId as string | undefined;\n const edgeId = (edge.id as string) ?? `${edgeStart}->${edgeEnd}`;\n\n for (const rect of nodeRects) {\n if (rect.nodeId === edgeStart || rect.nodeId === edgeEnd) {\n continue;\n }\n if (ownLabelId && rect.nodeId === ownLabelId) {\n continue;\n }\n for (let i = 0; i < points.length - 1; i++) {\n if (segmentBoundsOverlapRect(points[i], points[i + 1], rect, -epsilon)) {\n issues.push({\n type: 'edge-node-overlap',\n edgeId,\n targetId: rect.nodeId,\n detail: `segment ${i} passes through node \"${rect.nodeId}\"`,\n });\n break;\n }\n }\n }\n\n for (let i = 0; i < points.length - 1; i++) {\n edgeSegments.push({\n edgeId,\n start: edgeStart!,\n end: edgeEnd!,\n p1: points[i],\n p2: points[i + 1],\n });\n }\n }\n\n const crossingPairs = new Set<string>();\n for (let i = 0; i < edgeSegments.length; i++) {\n for (let j = i + 1; j < edgeSegments.length; j++) {\n const a = edgeSegments[i];\n const b = edgeSegments[j];\n if (a.edgeId === b.edgeId) {\n continue;\n }\n\n if (a.start === b.start || a.start === b.end || a.end === b.start || a.end === b.end) {\n continue;\n }\n\n if (segmentsIntersect(a.p1, a.p2, b.p1, b.p2)) {\n const pairKey = a.edgeId < b.edgeId ? `${a.edgeId}|${b.edgeId}` : `${b.edgeId}|${a.edgeId}`;\n if (!crossingPairs.has(pairKey)) {\n crossingPairs.add(pairKey);\n issues.push({\n type: 'edge-edge-crossing',\n edgeId: a.edgeId,\n targetId: b.edgeId,\n detail: `edges \"${a.edgeId}\" and \"${b.edgeId}\" cross`,\n });\n }\n }\n }\n }\n\n if (issues.length > 0) {\n const overlaps = issues.filter((i) => i.type === 'edge-node-overlap').length;\n const crossings = issues.filter((i) => i.type === 'edge-edge-crossing').length;\n log.warn(\n `[SWIMLANE_VALIDATE] ${issues.length} issue(s) detected: ` +\n `${overlaps} edge-node overlap(s), ${crossings} edge crossing(s)`\n );\n for (const issue of issues) {\n log.warn(`[SWIMLANE_VALIDATE] ${issue.type}: ${issue.detail}`);\n }\n }\n\n return issues;\n}\n", "// cspell:ignore raykov Wybrow\nimport type { LayoutData } from '../../types.js';\nimport {\n clipEdgeEndpointsToNodeBoundaries,\n prepareEdgeEndpointsForRenderer,\n} from './direction/endpointClip.js';\nimport { orthogonalizePolyline, simplifyPolyline } from './direction/geometry.js';\nimport { applyBtDirectionTransform, applyLrDirectionTransform } from './direction/lrTransform.js';\nimport { portSwapToLShape } from './direction/portSwap.js';\nimport { collapseShortTerminalStub } from './direction/terminalStub.js';\nimport {\n collapseRedundantRectangularDoglegs,\n liftObstacleHuggingSameSideRails,\n liftTopLaneTitleBandsAboveRails,\n reassignCrossingExternalRailChannels,\n resolveRenderedOrthogonalCrossings,\n separateSharedRenderedTerminalLanes,\n shiftLeftLaneTitleBandsLeftOfRails,\n shortcutRedundantOrthogonalJogs,\n swapDestinationTerminalTailsToReduceCrossings,\n} from './direction/materializedGeometry.js';\nimport { simplifyDetouredEdges } from './direction/detourSimplification.js';\nimport { anchorLabelsToPolyline } from './direction/labelAnchoring.js';\nimport { straightenCollinearSiblingDetours } from './direction/siblingSharedFaceRouting.js';\nimport { nudgeSharedInteriorSubpaths } from './direction/sharedTrackNudging.js';\nexport { validateSwimlanesLayout } from './direction/validation.js';\n\n/** Applies direction transforms and post-routing cleanup to a swimlane layout. */\nexport function postProcessSwimlaneLayout(layout: LayoutData, direction?: string): void {\n const nodes = layout.nodes ?? [];\n const edges = layout.edges ?? [];\n const contentNodes = nodes.filter((n) => !n.isGroup);\n\n // TB is the canonical orientation. LR/RL rotate rank progression onto X;\n // BT mirrors the canonical Y progression. Cleanup passes below operate in\n // whichever coordinate system this step leaves behind.\n if (\n (direction === 'LR' || direction === 'RL') &&\n contentNodes.length > 0 &&\n !applyLrDirectionTransform(layout, direction)\n ) {\n return;\n }\n\n if (direction === 'BT' && contentNodes.length > 0 && !applyBtDirectionTransform(layout)) {\n return;\n }\n\n for (const edge of edges) {\n if ((edge as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const pts = (edge as { points?: { x: number; y: number }[] }).points;\n if (!pts || pts.length < 2) {\n continue;\n }\n (edge as { points: { x: number; y: number }[] }).points = simplifyPolyline(\n orthogonalizePolyline(pts)\n );\n }\n\n simplifyDetouredEdges(edges as any[], nodes);\n\n // Prefer shorter sibling routes when a local port shift keeps them clear.\n straightenCollinearSiblingDetours(edges as any[], nodes);\n\n // Swap a source port only when it produces a clear L-shape with fewer bends.\n portSwapToLShape(edges as any[], nodes);\n\n const nodeByIdMap = new Map<string, any>();\n for (const n of nodes) {\n nodeByIdMap.set(String(n.id), n);\n }\n // Initial label anchoring against the routed polylines. The cleanup passes\n // below (nudging, terminal-lane splits, crossing resolution) can still reshape\n // these polylines, so labels are re-anchored once more at the end.\n anchorLabelsToPolyline(edges, nodeByIdMap);\n\n clipEdgeEndpointsToNodeBoundaries(edges, nodeByIdMap);\n\n // Retarget short terminal stubs that are hidden by endpoint clipping.\n collapseShortTerminalStub(edges, nodeByIdMap);\n\n // Wybrow-style shared-track nudge. The router may legitimately bundle\n // connectors onto the same rail, but before rendering those coincident\n // middle rails must be separated into nearby parallel tracks. This pass\n // keeps endpoint stubs pinned and only offsets interior H/V segments whose\n // same-axis span overlaps another edge.\n nudgeSharedInteriorSubpaths(edges, nodeByIdMap);\n\n // Materialized-render terminal lane split. The raw layout can still look\n // valid while the renderer's endpoint clipping creates coincident first/last\n // stubs on a shared node face. Split those visible terminal rails before the\n // endpoint-duplication handoff pins them.\n separateSharedRenderedTerminalLanes(edges, nodeByIdMap);\n\n // Once terminal lanes have been separated, some earlier same-track detours\n // become unnecessary. Remove only provably redundant rectangular doglegs;\n // safety checks preserve obstacle clearance and the newly split lanes.\n collapseRedundantRectangularDoglegs(edges, nodeByIdMap);\n\n // Same-side rails can be routed just inside a taller intervening node's\n // border. Lift those rails outside the blocker before crossing cleanup.\n liftObstacleHuggingSameSideRails(edges, nodeByIdMap);\n\n // Some shared-destination crossings only improve when two terminal ports\n // exchange places together. Try that bounded transaction before falling back\n // to whole-edge reroutes.\n swapDestinationTerminalTailsToReduceCrossings(edges, nodeByIdMap);\n\n const finalizeRenderedEdges = (): void => {\n resolveRenderedOrthogonalCrossings(edges, nodeByIdMap);\n reassignCrossingExternalRailChannels(edges, nodeByIdMap);\n shortcutRedundantOrthogonalJogs(edges, nodeByIdMap);\n anchorLabelsToPolyline(edges, nodeByIdMap);\n prepareEdgeEndpointsForRenderer(edges, nodeByIdMap);\n liftObstacleHuggingSameSideRails(edges, nodeByIdMap);\n anchorLabelsToPolyline(edges, nodeByIdMap);\n prepareEdgeEndpointsForRenderer(edges, nodeByIdMap);\n };\n\n // Wybrow-style crossing cleanup for the materialized render geometry. This\n // pass only activates when strict H/V crossings remain after the lower-level\n // nudging passes. It tries bounded port-pair and outer-channel candidates,\n // preserving obstacle clearance and accepting only candidates that reduce the\n // rendered crossing count or shorten an equally crossing route.\n finalizeRenderedEdges();\n\n // Renderer endpoint preparation materializes the visible endpoint geometry.\n // Run the shared-track pass once more on that visible shape, then refresh\n // labels and endpoint handoff. `prepareEdgeEndpointsForRenderer` is\n // idempotent, so unchanged edges do not accumulate duplicate endpoints.\n nudgeSharedInteriorSubpaths(edges, nodeByIdMap);\n\n // Endpoint preparation materializes the renderer-facing terminal stubs. In\n // long return-edge cases those stubs can reveal a crossing that was not\n // present in the pre-materialized route, so run the bounded cleanup once\n // more and then re-prepare the endpoints it reshaped.\n finalizeRenderedEdges();\n\n // Swimlane title bands are visual headers, not routing obstacles. After all\n // edge geometry is final, move the aligned title bands out of any clear rail\n // that still crosses the title section.\n liftTopLaneTitleBandsAboveRails(edges, nodeByIdMap);\n shiftLeftLaneTitleBandsLeftOfRails(edges, nodeByIdMap);\n // Moving one aligned title band can expose a second title/rail interaction\n // after the group bounds settle. The passes are idempotent, so one bounded\n // repeat keeps headers out of late crossing-cleanup routes without rerouting\n // the edges again.\n liftTopLaneTitleBandsAboveRails(edges, nodeByIdMap);\n shiftLeftLaneTitleBandsLeftOfRails(edges, nodeByIdMap);\n}\n", "import type { Graph, EdgeRef, NodeId } from './helpers.js';\n// cspell:ignore acyclicity topo indeg preds succs\n\n// Normalize/validate a Graph view; ensure nodeById exists and edges refer to known nodes\nexport function normalizeGraph(g: Graph): Graph {\n const nodeById = new Map(g.nodeById);\n // Filter edges with unknown endpoints and de-duplicate by id+endpoints\n const seen = new Set<string>();\n const edges: EdgeRef[] = [];\n for (const e of g.edges) {\n if (!nodeById.has(e.src) || !nodeById.has(e.dst)) {\n continue;\n }\n const key = `${e.id}:${e.src}->${e.dst}`;\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n edges.push(e);\n }\n const nodes = [...nodeById.keys()];\n return { nodes, edges, layout: g.layout, nodeById };\n}\n\n// Return incoming edges for v\nexport function incoming(g: Graph, v: NodeId): EdgeRef[] {\n return g.edges.filter((e) => e.dst === v);\n}\n\n// Return outgoing edges for v\nexport function outgoing(g: Graph, v: NodeId): EdgeRef[] {\n return g.edges.filter((e) => e.src === v);\n}\n\nexport function buildSuccessorMap(g: Graph): Map<NodeId, NodeId[]> {\n const succs = new Map<NodeId, NodeId[]>();\n for (const v of g.nodes) {\n succs.set(v, []);\n }\n for (const e of g.edges) {\n succs.get(e.src)!.push(e.dst);\n }\n return succs;\n}\n\nexport function buildSortedSuccessorMap(g: Graph): Map<NodeId, NodeId[]> {\n const succs = buildSuccessorMap(g);\n for (const successors of succs.values()) {\n successors.sort((a, b) => a.localeCompare(b));\n }\n return succs;\n}\n\nexport function buildInDegreeMap(g: Graph): Map<NodeId, number> {\n const indeg = new Map<NodeId, number>();\n for (const v of g.nodes) {\n indeg.set(v, 0);\n }\n for (const e of g.edges) {\n indeg.set(e.dst, (indeg.get(e.dst) ?? 0) + 1);\n }\n return indeg;\n}\n\nexport function sortedZeroInDegreeNodes(indeg: Map<NodeId, number>): NodeId[] {\n return [...indeg.entries()]\n .filter(([, degree]) => degree === 0)\n .map(([id]) => id)\n .sort((a, b) => a.localeCompare(b));\n}\n\nexport function buildPredecessorSuccessorMaps(\n g: Graph,\n includeEdge: (edge: EdgeRef) => boolean = () => true\n): { preds: Map<NodeId, NodeId[]>; succs: Map<NodeId, NodeId[]> } {\n const preds = new Map<NodeId, NodeId[]>();\n const succs = new Map<NodeId, NodeId[]>();\n for (const v of g.nodes) {\n preds.set(v, []);\n succs.set(v, []);\n }\n for (const e of g.edges) {\n if (!includeEdge(e)) {\n continue;\n }\n succs.get(e.src)!.push(e.dst);\n preds.get(e.dst)!.push(e.src);\n }\n return { preds, succs };\n}\n\nexport function buildLayersFromRanks(\n g: Graph,\n order: NodeId[],\n rankOf: Record<NodeId, number>,\n opts?: { skipGroups?: boolean }\n): NodeId[][] {\n let maxRank = 0;\n for (const v of g.nodes) {\n if (opts?.skipGroups && g.nodeById.get(v)?.isGroup) {\n continue;\n }\n maxRank = Math.max(maxRank, rankOf[v] ?? 0);\n }\n\n const layers: NodeId[][] = Array.from({ length: maxRank + 1 }, () => []);\n for (const v of order) {\n if (opts?.skipGroups && g.nodeById.get(v)?.isGroup) {\n continue;\n }\n layers[Math.max(0, rankOf[v] ?? 0)].push(v);\n }\n return layers;\n}\n\n// Detect acyclicity via DFS (white/gray/black sets)\nexport function isAcyclic(g: Graph): boolean {\n const color: Record<NodeId, 0 | 1 | 2> = Object.create(null);\n for (const v of g.nodes) {\n color[v] = 0; // 0 white, 1 gray, 2 black\n }\n\n const adj = buildSuccessorMap(g);\n\n const dfs = (u: NodeId): boolean => {\n color[u] = 1; // gray\n for (const v of adj.get(u) ?? []) {\n if (color[v] === 0 && !dfs(v)) {\n return false;\n }\n if (color[v] === 1) {\n // back-edge\n return false;\n }\n }\n color[u] = 2; // black\n return true;\n };\n\n for (const v of g.nodes) {\n if (color[v] === 0 && !dfs(v)) {\n return false;\n }\n }\n return true;\n}\n\n// Topological sort (Kahn). Returns null if cycles exist.\nexport function topoSortIfAcyclic(g: Graph): NodeId[] | null {\n const indeg = buildInDegreeMap(g);\n const queue = sortedZeroInDegreeNodes(indeg);\n const order: NodeId[] = [];\n const adj = buildSortedSuccessorMap(g);\n\n while (queue.length) {\n const u = queue.shift()!;\n order.push(u);\n for (const v of adj.get(u) ?? []) {\n indeg.set(v, (indeg.get(v) ?? 0) - 1);\n if ((indeg.get(v) ?? 0) === 0) {\n // insert keeping sorted order for determinism\n let i = 0;\n while (i < queue.length && queue[i] < v) {\n i++;\n }\n queue.splice(i, 0, v);\n }\n }\n }\n\n return order.length === g.nodes.length ? order : null;\n}\n\n/**\n * Build an index map from node IDs to their positions in a layer.\n * This is used for efficient lookups during crossing minimization.\n */\nexport function buildLayerIndex(layer: NodeId[]): Map<NodeId, number> {\n const m = new Map<NodeId, number>();\n let index = 0;\n for (const id of layer) {\n m.set(id, index);\n index++;\n }\n return m;\n}\n\nexport function countInversions(values: number[]): number {\n const tmp = new Array<number>(values.length);\n const count = (left: number, right: number): number => {\n if (right - left <= 1) {\n return 0;\n }\n const mid = (left + right) >> 1;\n let inversions = count(left, mid) + count(mid, right);\n let i = left;\n let j = mid;\n let k = left;\n while (i < mid || j < right) {\n if (j >= right || (i < mid && values[i] <= values[j])) {\n tmp[k++] = values[i++];\n } else {\n tmp[k++] = values[j++];\n inversions += mid - i;\n }\n }\n for (let t = left; t < right; t++) {\n values[t] = tmp[t];\n }\n return inversions;\n };\n return count(0, values.length);\n}\n", "import type { Graph, Edge, EdgeRef, NodeId } from './helpers.js';\nimport { normalizeGraph } from './phase0.helpers.js';\n// cspell:ignore Graphviz acyc Eades\n\nexport interface CycleRemovalResult {\n acyclic: Graph;\n reversed: Edge[]; // edges that were reversed (original orientation)\n}\n\n// Deterministic DFS-based cycle removal (similar to Graphviz dot back-edge marking)\nexport function removeCycles_DFS(g: Graph): CycleRemovalResult {\n const gn = normalizeGraph(g);\n\n // Build adjacency with deterministic order\n const adj = new Map<NodeId, EdgeRef[]>();\n for (const v of gn.nodes) {\n adj.set(v, []);\n }\n for (const e of gn.edges) {\n adj.get(e.src)!.push(e);\n }\n for (const arr of adj.values()) {\n arr.sort((a, b) => (a.dst === b.dst ? a.id.localeCompare(b.id) : a.dst.localeCompare(b.dst)));\n }\n\n const color: Record<NodeId, 0 | 1 | 2> = Object.create(null);\n for (const v of gn.nodes) {\n color[v] = 0; // 0 white, 1 gray, 2 black\n }\n\n const reversed: EdgeRef[] = [];\n\n const dfs = (u: NodeId) => {\n color[u] = 1;\n for (const e of adj.get(u) ?? []) {\n const v = e.dst;\n if (color[v] === 0) {\n dfs(v);\n } else if (color[v] === 1) {\n // back-edge u->v; mark for reversal\n reversed.push(e);\n }\n }\n color[u] = 2;\n };\n\n // Visit in deterministic order\n const nodesSorted = [...gn.nodes].sort((a, b) => a.localeCompare(b));\n for (const v of nodesSorted) {\n if (color[v] === 0) {\n dfs(v);\n }\n }\n\n // Build acyclic edge set by reversing all marked edges\n const toReverse = new Set<string>(reversed.map((e) => `${e.id}:${e.src}->${e.dst}`));\n const acycEdges: EdgeRef[] = gn.edges.map((e) =>\n toReverse.has(`${e.id}:${e.src}->${e.dst}`)\n ? { id: e.id, src: e.dst, dst: e.src, weight: e.weight, ref: e.ref }\n : e\n );\n\n const acyclic: Graph = {\n nodes: [...gn.nodes],\n edges: acycEdges,\n layout: gn.layout,\n nodeById: new Map(gn.nodeById),\n };\n return { acyclic, reversed };\n}\n", "import type { Graph, NodeId } from './helpers.js';\n\n/**\n * Options controlling how layers are assigned in the Sugiyama pipeline.\n */\nexport interface LayeringOptions {\n /** If true, a node with exactly one incoming edge inherits its predecessor's layer. */\n compactSingleInput?: boolean;\n /** If true, ignore edges from other lanes when calculating layer positions. */\n ignoreCrossLaneEdges?: boolean;\n /** If true, try to lift nodes to reduce crossings between layers. */\n optimizeRanksByCrossings?: boolean;\n /** Diagram direction, used by lane-aware rank heuristics with direction-specific failure modes. */\n direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n/**\n * Computes the \"top lane\" (outermost group container) for each node.\n *\n * Returns a map from node id -\\> lane id (top-level group) or null if the node\n * does not belong to any lane.\n */\nexport function buildTopLaneMap(g: Graph): Map<NodeId, string | null> {\n const cache = new Map<NodeId, string | null>();\n\n const resolve = (id: NodeId): string | null => {\n if (cache.has(id)) {\n return cache.get(id)!;\n }\n const node = g.nodeById.get(id) as any;\n if (!node) {\n cache.set(id, null);\n return null;\n }\n const parentId = node.parentId as NodeId | undefined;\n if (!parentId) {\n cache.set(id, null);\n return null;\n }\n const parentLane = resolve(parentId);\n const lane = parentLane ?? parentId;\n cache.set(id, lane);\n return lane;\n };\n\n for (const id of g.nodes) {\n resolve(id);\n }\n return cache;\n}\n\nexport function createTopLaneResolver(g: Graph): (id: NodeId) => string | null {\n const topLaneMap = buildTopLaneMap(g);\n return (id: NodeId): string | null => topLaneMap.get(id) ?? null;\n}\n\nexport function buildTopLaneOrder(g: Graph): string[] {\n const lanes: string[] = [];\n for (const node of g.layout.nodes ?? []) {\n if (node.isGroup && !node.parentId) {\n lanes.push(node.id);\n }\n }\n return [...new Set(lanes)].reverse();\n}\n\nexport function resolveTopLaneOrder(g: Graph, preferredOrder?: string[]): string[] {\n const sourceOrder = buildTopLaneOrder(g);\n if (!preferredOrder || preferredOrder.length === 0) {\n return sourceOrder;\n }\n\n const sourceLaneIds = new Set(sourceOrder);\n const seen = new Set<string>();\n const resolved: string[] = [];\n for (const laneId of preferredOrder) {\n if (!sourceLaneIds.has(laneId) || seen.has(laneId)) {\n continue;\n }\n seen.add(laneId);\n resolved.push(laneId);\n }\n for (const laneId of sourceOrder) {\n if (seen.has(laneId)) {\n continue;\n }\n resolved.push(laneId);\n }\n return resolved;\n}\n", "/**\n * Configuration constants for the Swimlanes layout algorithm.\n * Centralizes all magic numbers and default values for maintainability.\n */\n\n/**\n * Edge routing and spacing constants\n */\nexport const EDGE_ROUTING = {\n /** Spacing between parallel edges in the same corridor (px) */\n EDGE_GAP: 12,\n\n /** Horizontal offset from lane boundary to corridor center (px) */\n LANE_MARGIN: 20,\n} as const;\n\n/**\n * Numerical precision constants\n */\nexport const PRECISION = {\n /** Epsilon for floating-point comparisons */\n EPSILON: 1e-6,\n} as const;\n\n/**\n * Layer assignment constants\n */\nexport const LAYERING = {\n /** Default number of iterations for gravity-based layering */\n GRAVITY_ITERATIONS: 8,\n\n /** Maximum number of passes for crossing-based rank optimization */\n MAX_CROSSING_OPTIMIZATION_PASSES: 4,\n\n /** Whether to compact single-input nodes by default */\n DEFAULT_COMPACT_SINGLE_INPUT: true,\n} as const;\n\n/**\n * Coordinate assignment constants\n */\nexport const COORDINATES = {\n /** Default vertical gap between layers (px) */\n DEFAULT_LAYER_GAP: 100,\n\n /** Default horizontal gap between nodes (px) */\n DEFAULT_NODE_GAP: 40,\n} as const;\n", "import type { Graph, NodeId } from './helpers.js';\nimport {\n buildPredecessorSuccessorMaps,\n normalizeGraph,\n topoSortIfAcyclic,\n} from './phase0.helpers.js';\n// cspell:ignore preorder postorder preds topo\n\nexport interface DrivingTreeBlock {\n id: number;\n nodes: NodeId[];\n edges: [NodeId, NodeId][];\n}\n\nexport interface DrivingTree {\n parent: Map<NodeId, NodeId | null>;\n children: Map<NodeId, NodeId[]>;\n roots: NodeId[];\n componentOf: Map<NodeId, number>;\n blocks: DrivingTreeBlock[];\n nodeBlocks: Map<NodeId, number[]>;\n adjacency: Map<NodeId, NodeId[]>;\n preorder: NodeId[];\n postorder: NodeId[];\n topologicalOrder: NodeId[];\n}\n\nexport interface DrivingTreeBuildOptions {\n rankHint?: Record<NodeId, number>;\n laneOf?: (id: NodeId) => string | null;\n}\n\n// Build the spanning forest and traversal metadata used by tree ordering.\nexport function buildDrivingTree(graph: Graph, opts?: DrivingTreeBuildOptions): DrivingTree {\n const g = normalizeGraph(graph);\n const laneOf = opts?.laneOf ?? (() => null);\n const rankHint = opts?.rankHint;\n\n const { preds } = buildPredecessorSuccessorMaps(g);\n for (const arr of preds.values()) {\n arr.sort((a, b) => a.localeCompare(b));\n }\n\n const topoOrder = topoSortIfAcyclic(g) ?? [...g.nodes].sort((a, b) => a.localeCompare(b));\n const topoIndex = new Map<NodeId, number>();\n for (const [idx, id] of topoOrder.entries()) {\n topoIndex.set(id, idx);\n }\n\n const parent = new Map<NodeId, NodeId | null>();\n const children = new Map<NodeId, NodeId[]>();\n for (const node of g.nodes) {\n children.set(node, []);\n }\n\n for (const node of topoOrder) {\n const candidates = (preds.get(node) ?? []).filter((p) => parent.has(p));\n if (candidates.length > 0) {\n const chosen = chooseParent(node, candidates, {\n laneOf,\n rankHint,\n topoIndex,\n });\n parent.set(node, chosen);\n children.get(chosen)!.push(node);\n } else if (!parent.has(node)) {\n parent.set(node, null);\n }\n }\n\n for (const node of g.nodes) {\n if (!parent.has(node)) {\n parent.set(node, null);\n }\n }\n\n const rootSet = new Set<NodeId>();\n for (const node of g.nodes) {\n if ((parent.get(node) ?? null) === null) {\n rootSet.add(node);\n }\n }\n const roots = [...rootSet].sort((a, b) => {\n const ta = topoIndex.get(a) ?? 0;\n const tb = topoIndex.get(b) ?? 0;\n if (ta === tb) {\n return a.localeCompare(b);\n }\n return ta - tb;\n });\n\n const adjacency = buildAdjacency(g);\n const adjacencyList = new Map<NodeId, NodeId[]>();\n for (const [node, set] of adjacency.entries()) {\n adjacencyList.set(\n node,\n [...set].sort((a, b) => a.localeCompare(b))\n );\n }\n\n const componentOf = assignComponents(adjacencyList);\n const blocks = computeBlocks(adjacencyList);\n const nodeBlocks = new Map<NodeId, number[]>();\n for (const node of g.nodes) {\n nodeBlocks.set(node, []);\n }\n for (const block of blocks) {\n for (const node of block.nodes) {\n const list = nodeBlocks.get(node);\n if (list) {\n list.push(block.id);\n } else {\n nodeBlocks.set(node, [block.id]);\n }\n }\n }\n\n const preorder: NodeId[] = [];\n const postorder: NodeId[] = [];\n const seen = new Set<NodeId>();\n\n const walk = (node: NodeId) => {\n if (seen.has(node)) {\n return;\n }\n seen.add(node);\n preorder.push(node);\n for (const child of children.get(node) ?? []) {\n walk(child);\n }\n postorder.push(node);\n };\n\n for (const root of roots) {\n walk(root);\n }\n for (const node of topoOrder) {\n walk(node);\n }\n\n return {\n parent,\n children,\n roots,\n componentOf,\n blocks,\n nodeBlocks,\n adjacency: adjacencyList,\n preorder,\n postorder,\n topologicalOrder: topoOrder,\n };\n}\n\ninterface ParentSelectionContext {\n laneOf: (id: NodeId) => string | null;\n rankHint?: Record<NodeId, number>;\n topoIndex: Map<NodeId, number>;\n}\n\nfunction chooseParent(node: NodeId, candidates: NodeId[], ctx: ParentSelectionContext): NodeId {\n const laneNode = ctx.laneOf(node);\n const sorted = [...candidates].sort((a, b) => {\n const laneA = ctx.laneOf(a);\n const laneB = ctx.laneOf(b);\n const sameLaneA = laneA != null && laneA === laneNode;\n const sameLaneB = laneB != null && laneB === laneNode;\n if (sameLaneA !== sameLaneB) {\n return sameLaneA ? -1 : 1;\n }\n\n const rankA = ctx.rankHint?.[a];\n const rankB = ctx.rankHint?.[b];\n if (rankA != null && rankB != null && rankA !== rankB) {\n return rankB - rankA;\n }\n\n const idxA = ctx.topoIndex.get(a) ?? 0;\n const idxB = ctx.topoIndex.get(b) ?? 0;\n if (idxA !== idxB) {\n return idxA - idxB;\n }\n\n return a.localeCompare(b);\n });\n return sorted[0];\n}\n\nfunction buildAdjacency(g: Graph): Map<NodeId, Set<NodeId>> {\n const adjacency = new Map<NodeId, Set<NodeId>>();\n for (const node of g.nodes) {\n adjacency.set(node, new Set<NodeId>());\n }\n for (const e of g.edges) {\n adjacency.get(e.src)!.add(e.dst);\n adjacency.get(e.dst)!.add(e.src);\n }\n return adjacency;\n}\n\nfunction assignComponents(adjacency: Map<NodeId, NodeId[]>): Map<NodeId, number> {\n const componentOf = new Map<NodeId, number>();\n let componentId = 0;\n for (const node of adjacency.keys()) {\n if (componentOf.has(node)) {\n continue;\n }\n const stack: NodeId[] = [node];\n while (stack.length > 0) {\n const cur = stack.pop()!;\n if (componentOf.has(cur)) {\n continue;\n }\n componentOf.set(cur, componentId);\n for (const next of adjacency.get(cur) ?? []) {\n if (!componentOf.has(next)) {\n stack.push(next);\n }\n }\n }\n componentId++;\n }\n return componentOf;\n}\n\nfunction computeBlocks(adjacency: Map<NodeId, NodeId[]>): DrivingTreeBlock[] {\n const discovery = new Map<NodeId, number>();\n const low = new Map<NodeId, number>();\n const edgeStack: [NodeId, NodeId][] = [];\n const blocks: DrivingTreeBlock[] = [];\n let time = 0;\n\n const visit = (node: NodeId, parent: NodeId | null) => {\n discovery.set(node, ++time);\n low.set(node, time);\n\n for (const next of adjacency.get(node) ?? []) {\n if (next === parent) {\n continue;\n }\n if (!discovery.has(next)) {\n edgeStack.push([node, next]);\n visit(next, node);\n low.set(node, Math.min(low.get(node) ?? time, low.get(next) ?? time));\n if ((low.get(next) ?? 0) >= (discovery.get(node) ?? 0)) {\n blocks.push(popBlock(node, next, edgeStack, blocks.length));\n }\n } else if ((discovery.get(next) ?? 0) < (discovery.get(node) ?? 0)) {\n edgeStack.push([node, next]);\n low.set(node, Math.min(low.get(node) ?? time, discovery.get(next) ?? time));\n }\n }\n };\n\n for (const node of adjacency.keys()) {\n if (!discovery.has(node)) {\n visit(node, null);\n }\n }\n\n return blocks;\n}\n\nfunction popBlock(u: NodeId, v: NodeId, stack: [NodeId, NodeId][], id: number): DrivingTreeBlock {\n const edges: [NodeId, NodeId][] = [];\n const nodes = new Set<NodeId>();\n while (stack.length > 0) {\n const edge = stack.pop()!;\n edges.push(edge);\n nodes.add(edge[0]);\n nodes.add(edge[1]);\n if ((edge[0] === u && edge[1] === v) || (edge[0] === v && edge[1] === u)) {\n break;\n }\n }\n return { id, edges, nodes: [...nodes] };\n}\n", "import type { Graph, NodeId } from './helpers.js';\nimport type { DrivingTree } from './driving-tree.js';\n\n/**\n * Computes crossing counts for each parent/child pair in the driving tree.\n *\n * Uses a binary-lifting LCA over the driving tree and counts, for every edge,\n * how many layers it spans below the LCA. These per-layer counts are then\n * accumulated to obtain, for each parent -\\> child edge in the tree, an\n * approximate \"subtree crossing\" score used when ordering children.\n */\nexport function computeSubtreeCrossCounts(\n g: Graph,\n rankOf: Record<NodeId, number>,\n tree: DrivingTree\n): Map<NodeId, Map<NodeId, number>> {\n const nodes = [...g.nodes];\n const indexOf = new Map<NodeId, number>();\n for (const [i, node] of nodes.entries()) {\n indexOf.set(node, i);\n }\n const n = nodes.length;\n\n const parentIdx = new Array<number>(n).fill(-1);\n const depth = new Array<number>(n).fill(0);\n\n const queue: NodeId[] = [];\n const seen = new Set<NodeId>();\n\n // Seed BFS from roots\n for (const node of nodes) {\n const parentId = tree.parent.get(node) ?? null;\n const idx = indexOf.get(node);\n if (idx == null) {\n continue;\n }\n if (parentId == null) {\n parentIdx[idx] = -1;\n depth[idx] = 0;\n if (!seen.has(node)) {\n seen.add(node);\n queue.push(node);\n }\n }\n }\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const currentIdx = indexOf.get(current);\n if (currentIdx == null) {\n continue;\n }\n const childList = tree.children.get(current) ?? [];\n for (const child of childList) {\n if (seen.has(child)) {\n continue;\n }\n const childIdx = indexOf.get(child);\n if (childIdx == null) {\n continue;\n }\n parentIdx[childIdx] = currentIdx;\n depth[childIdx] = depth[currentIdx] + 1;\n seen.add(child);\n queue.push(child);\n }\n }\n\n // Ensure all nodes are represented even if disconnected in the tree\n for (const node of nodes) {\n if (seen.has(node)) {\n continue;\n }\n const idx = indexOf.get(node);\n if (idx == null) {\n continue;\n }\n parentIdx[idx] = -1;\n depth[idx] = 0;\n seen.add(node);\n }\n\n const maxLog = Math.max(1, Math.ceil(Math.log2(Math.max(1, n))) + 1);\n const up: number[][] = Array.from({ length: maxLog }, () => new Array<number>(n).fill(-1));\n for (let i = 0; i < n; i++) {\n up[0][i] = parentIdx[i];\n }\n for (let k = 1; k < maxLog; k++) {\n for (let i = 0; i < n; i++) {\n const prev = up[k - 1][i];\n up[k][i] = prev === -1 ? -1 : up[k - 1][prev];\n }\n }\n\n const lcaIndex = (aIdx: number, bIdx: number): number => {\n if (aIdx === -1 || bIdx === -1) {\n return -1;\n }\n if (depth[aIdx] < depth[bIdx]) {\n [aIdx, bIdx] = [bIdx, aIdx];\n }\n const diff = depth[aIdx] - depth[bIdx];\n for (let k = 0; k < maxLog; k++) {\n if ((diff >> k) & 1) {\n aIdx = up[k][aIdx];\n if (aIdx === -1) {\n return -1;\n }\n }\n }\n if (aIdx === bIdx) {\n return aIdx;\n }\n for (let k = maxLog - 1; k >= 0; k--) {\n const upA = up[k][aIdx];\n const upB = up[k][bIdx];\n if (upA === -1 || upB === -1) {\n continue;\n }\n if (upA !== upB) {\n aIdx = upA;\n bIdx = upB;\n }\n }\n return up[0][aIdx];\n };\n\n const ownCounts = Array.from({ length: n }, () => new Map<number, number>());\n\n // Count, for each LCA, how many edges pass through each layer below it.\n for (const edge of g.edges) {\n let src = edge.src;\n let dst = edge.dst;\n let ru = rankOf[src];\n let rv = rankOf[dst];\n if (ru == null || rv == null) {\n continue;\n }\n if (ru > rv) {\n [src, dst] = [dst, src];\n [ru, rv] = [rv, ru];\n }\n if (ru == null || rv == null || ru === rv) {\n continue;\n }\n const upperIdx = indexOf.get(src);\n const lowerIdx = indexOf.get(dst);\n if (upperIdx == null || lowerIdx == null) {\n continue;\n }\n const lca = lcaIndex(upperIdx, lowerIdx);\n if (lca === -1) {\n continue;\n }\n const bucket = ownCounts[lca];\n for (let layer = ru; layer < rv; layer++) {\n bucket.set(layer, (bucket.get(layer) ?? 0) + 1);\n }\n }\n\n const crossCounts = new Map<NodeId, Map<NodeId, number>>();\n\n const mergeInto = (target: Map<number, number>, source: Map<number, number>) => {\n if (source.size === 0) {\n return;\n }\n for (const [layer, value] of source) {\n target.set(layer, (target.get(layer) ?? 0) + value);\n }\n };\n\n const visited = new Set<NodeId>();\n const dfs = (node: NodeId): Map<number, number> => {\n const idx = indexOf.get(node);\n visited.add(node);\n const base = idx == null ? undefined : ownCounts[idx];\n const accumulator = base ? new Map<number, number>(base) : new Map<number, number>();\n const childList = tree.children.get(node) ?? [];\n for (const child of childList) {\n const childMap = dfs(child);\n const parentLayer = rankOf[node];\n if (parentLayer != null) {\n let map = crossCounts.get(node);\n if (!map) {\n map = new Map<NodeId, number>();\n crossCounts.set(node, map);\n }\n let value = childMap.get(parentLayer) ?? 0;\n const childLayer = rankOf[child];\n if (childLayer != null && childLayer > parentLayer) {\n value += 1;\n }\n map.set(child, value);\n }\n mergeInto(accumulator, childMap);\n }\n return accumulator;\n };\n\n for (const root of tree.roots) {\n if (!visited.has(root)) {\n dfs(root);\n }\n }\n for (const node of nodes) {\n if (!visited.has(node)) {\n dfs(node);\n }\n }\n\n return crossCounts;\n}\n", "import type { NodeId } from './helpers.js';\n\n// cspell:ignore multitree\n/**\n * Utilities shared by the multitree-based layer ordering logic.\n */\nexport function annotateMinimumLayers(\n nodes: NodeId[],\n children: Map<NodeId, NodeId[]>,\n rankOf: Record<NodeId, number>\n): Map<NodeId, number> {\n const minLayer = new Map<NodeId, number>();\n\n const annotate = (node: NodeId) => {\n let minL = rankOf[node] ?? 0;\n const childList = [...(children.get(node) ?? [])];\n childList.sort(compareByRankThenId(rankOf));\n for (const child of childList) {\n annotate(child);\n const childMin = minLayer.get(child);\n if (childMin != null) {\n minL = Math.min(minL, childMin);\n }\n }\n minLayer.set(node, minL);\n };\n\n for (const node of nodes) {\n annotate(node);\n }\n\n return minLayer;\n}\n\nexport function compareByRankThenId(rankOf: Record<NodeId, number>) {\n return (a: NodeId, b: NodeId) => {\n const ra = rankOf[a] ?? 0;\n const rb = rankOf[b] ?? 0;\n return ra === rb ? a.localeCompare(b) : ra - rb;\n };\n}\n\n/**\n * Emits nodes into layers in tree traversal order, using the provided\n * orderChildren function to determine the order of children.\n */\nexport function emitNodesInTreeOrder(\n roots: NodeId[],\n allNodes: NodeId[],\n rankOf: Record<NodeId, number>,\n orderChildren: (node: NodeId) => NodeId[]\n): NodeId[][] {\n let maxRank = 0;\n for (const node of allNodes) {\n const r = rankOf[node] ?? 0;\n if (r > maxRank) {\n maxRank = r;\n }\n }\n\n const layers: NodeId[][] = Array.from({ length: maxRank + 1 }, () => []);\n const emitted = new Set<NodeId>();\n\n const emit = (node: NodeId) => {\n if (emitted.has(node)) {\n return;\n }\n emitted.add(node);\n const layer = rankOf[node] ?? 0;\n if (!layers[layer]) {\n layers[layer] = [];\n }\n layers[layer].push(node);\n for (const child of orderChildren(node)) {\n emit(child);\n }\n };\n\n for (const root of roots) {\n emit(root);\n }\n\n // Fallback for isolated nodes (if any were not connected through spanning forest)\n for (const node of allNodes) {\n if (!emitted.has(node)) {\n const layer = rankOf[node] ?? 0;\n if (!layers[layer]) {\n layers[layer] = [];\n }\n layers[layer].push(node);\n emitted.add(node);\n }\n }\n\n return layers;\n}\n\n/**\n * Removes duplicate nodes from each layer while preserving order.\n */\nexport function deduplicateLayers(layers: NodeId[][]): NodeId[][] {\n const result: NodeId[][] = [];\n for (const layer of layers) {\n const seen = new Set<NodeId>();\n const deduped: NodeId[] = [];\n for (const id of layer) {\n if (seen.has(id)) {\n continue;\n }\n seen.add(id);\n deduped.push(id);\n }\n result.push(deduped);\n }\n return result;\n}\n", "import type { Graph, NodeId } from './helpers.js';\nimport { buildDrivingTree } from './driving-tree.js';\nimport { computeSubtreeCrossCounts } from './phase2.crossCounts.js';\nimport {\n annotateMinimumLayers,\n compareByRankThenId,\n emitNodesInTreeOrder,\n deduplicateLayers,\n} from './phase2.multitree.core.js';\n\n// cspell:ignore multitree Multitree\n\n/**\n * Creates a function that orders children by crossing counts and minimum layers.\n * Children in future layers are ordered by their minimum layer, while children\n * in the current layer are ordered by crossing counts.\n */\nfunction createChildOrderer(\n children: Map<NodeId, NodeId[]>,\n rankOf: Record<NodeId, number>,\n crossCounts: Map<NodeId, Map<NodeId, number>>,\n minLayer: Map<NodeId, number>\n): (node: NodeId) => NodeId[] {\n return (node: NodeId): NodeId[] => {\n const raw = children.get(node) ?? [];\n if (raw.length === 0) {\n return [];\n }\n const layer = rankOf[node] ?? 0;\n const future: { child: NodeId; min: number }[] = [];\n const present: NodeId[] = [];\n const crossMap = crossCounts.get(node);\n\n for (const child of raw) {\n const minL = minLayer.get(child) ?? layer;\n if (minL > layer) {\n future.push({ child, min: minL });\n } else {\n present.push(child);\n }\n }\n\n future.sort((a, b) => {\n if (a.min === b.min) {\n return a.child.localeCompare(b.child);\n }\n return a.min - b.min;\n });\n\n present.sort((a, b) => {\n const ca = crossMap?.get(a) ?? 0;\n const cb = crossMap?.get(b) ?? 0;\n if (ca !== cb) {\n return ca - cb;\n }\n const ma = minLayer.get(a) ?? layer;\n const mb = minLayer.get(b) ?? layer;\n if (ma !== mb) {\n return ma - mb;\n }\n return a.localeCompare(b);\n });\n\n return [...future.map((item) => item.child), ...present];\n };\n}\n\n/**\n * Builds a layering (array of layers) by traversing the driving tree in a\n * multitree order that tries to minimize crossings.\n */\nexport function buildMultitreeLayerOrder(\n g: Graph,\n rankOf: Record<NodeId, number>,\n laneOf: (id: NodeId) => string | null\n): NodeId[][] {\n const tree = buildDrivingTree(g, {\n rankHint: rankOf,\n laneOf,\n });\n const { children, roots } = tree;\n\n // Ensure all nodes have a children entry\n for (const node of g.nodes) {\n if (!children.has(node)) {\n children.set(node, []);\n }\n }\n\n const crossCounts = computeSubtreeCrossCounts(g, rankOf, tree);\n\n const rootsSorted = [...roots].sort(compareByRankThenId(rankOf));\n\n // Annotate each node with the minimum layer in its subtree\n const minLayer = annotateMinimumLayers(rootsSorted, children, rankOf);\n\n // Create a function to order children by crossing counts\n const orderChildren = createChildOrderer(children, rankOf, crossCounts, minLayer);\n\n // Emit nodes in tree order\n let layers = emitNodesInTreeOrder(rootsSorted, g.nodes, rankOf, orderChildren);\n\n // Deduplicate each layer\n layers = deduplicateLayers(layers);\n\n return layers;\n}\n", "import type { Graph, NodeId, EdgeRef } from './helpers.js';\nimport {\n buildLayerIndex,\n buildPredecessorSuccessorMaps,\n countInversions,\n} from './phase0.helpers.js';\nimport { LAYERING } from './config.js';\nimport { createTopLaneResolver } from './phase2.options.js';\nimport { buildMultitreeLayerOrder } from './phase2.multitree.order.js';\n// cspell:ignore acyclicity preds\n\nfunction countCrossingsBetweenAdjacent(upper: NodeId[], lower: NodeId[], edges: EdgeRef[]): number {\n const upperSet = new Set(upper);\n const lowerSet = new Set(lower);\n const li = buildLayerIndex(lower);\n const vs: number[] = [];\n for (const e of edges) {\n if (upperSet.has(e.src) && lowerSet.has(e.dst)) {\n vs.push(li.get(e.dst)!);\n }\n }\n return countInversions(vs);\n}\n\nfunction totalCrossings(\n layers: NodeId[][],\n edges: EdgeRef[],\n rankOf: Record<NodeId, number>\n): number {\n const expanded: EdgeRef[] = [];\n for (const e of edges) {\n const ru = rankOf[e.src];\n const rv = rankOf[e.dst];\n if (ru == null || rv == null || ru === rv) {\n continue;\n }\n let upper = e.src;\n let lower = e.dst;\n let rUpper = ru;\n let rLower = rv;\n if (ru > rv) {\n upper = e.dst;\n lower = e.src;\n rUpper = rv;\n rLower = ru;\n }\n for (let L = rUpper; L < rLower; L++) {\n expanded.push({ id: `${e.id}@${L}`, src: upper, dst: lower, ref: e.ref });\n }\n }\n let sum = 0;\n for (let i = 0; i + 1 < layers.length; i++) {\n sum += countCrossingsBetweenAdjacent(layers[i], layers[i + 1], expanded);\n }\n return sum;\n}\n\n/**\n * Greedy local search that tries to lift nodes to reduce crossings while\n * preserving acyclicity (rank(v) \u0003e= rank(u)+1 for every edge u-\\>v).\n */\nexport function optimizeRanksByCrossings(\n g: Graph,\n initialRank: Record<NodeId, number>\n): Record<NodeId, number> {\n const rankOf: Record<NodeId, number> = { ...initialRank } as any;\n const { preds } = buildPredecessorSuccessorMaps(g);\n\n const laneOf = createTopLaneResolver(g);\n\n const layers = buildMultitreeLayerOrder(g, rankOf, laneOf);\n let best = totalCrossings(layers, g.edges, rankOf);\n const maxPasses = LAYERING.MAX_CROSSING_OPTIMIZATION_PASSES;\n for (let pass = 0; pass < maxPasses; pass++) {\n let changed = false;\n const nodesByRank = [...g.nodes].sort((a, b) => (rankOf[b] ?? 0) - (rankOf[a] ?? 0));\n for (const v of nodesByRank) {\n const r = rankOf[v] ?? 0;\n if (r === 0) {\n continue;\n }\n let lb = 0;\n for (const u of preds.get(v) ?? []) {\n lb = Math.max(lb, (rankOf[u] ?? 0) + 1);\n }\n if (lb >= r) {\n continue;\n }\n const old = r;\n rankOf[v] = lb;\n const trialLayers = buildMultitreeLayerOrder(g, rankOf, laneOf);\n const score = totalCrossings(trialLayers, g.edges, rankOf);\n if (score < best) {\n best = score;\n changed = true;\n } else {\n rankOf[v] = old;\n }\n }\n if (!changed) {\n break;\n }\n }\n return rankOf;\n}\n", "import type { Graph, NodeId } from './helpers.js';\nimport { createTopLaneResolver } from './phase2.options.js';\n\n/**\n * Heuristic to push nodes with only cross-lane outgoing edges downward so\n * that same-lane successors have room to appear above them.\n */\nexport function adjustCrossLaneSources(g: Graph, rankOf: Record<NodeId, number>): void {\n const topLaneOf = createTopLaneResolver(g);\n\n const nodesByRank = [...g.nodes].sort(\n (a, b) => (rankOf[a] ?? 0) - (rankOf[b] ?? 0) || a.localeCompare(b)\n );\n for (const v of nodesByRank) {\n const laneV = topLaneOf(v);\n if (!laneV) {\n continue;\n }\n const outEdges = g.edges.filter((e) => e.src === v);\n if (outEdges.length === 0) {\n continue;\n }\n let hasSameLaneSucc = false;\n let crossLaneCount = 0;\n for (const e of outEdges) {\n const laneDst = topLaneOf(e.dst);\n if (laneDst == null || laneDst === laneV) {\n hasSameLaneSucc = true;\n } else {\n crossLaneCount++;\n }\n }\n if (crossLaneCount === 0 || hasSameLaneSucc) {\n continue;\n }\n\n let crossLaneIncoming = 0;\n let hasSameLanePred = false;\n for (const e of g.edges) {\n if (e.dst !== v) {\n continue;\n }\n const laneSrc = topLaneOf(e.src);\n if (!laneSrc) {\n continue;\n }\n if (laneSrc === laneV) {\n hasSameLanePred = true;\n } else {\n crossLaneIncoming++;\n }\n }\n if (crossLaneIncoming > 0 || !hasSameLanePred) {\n continue;\n }\n const current = rankOf[v] ?? 0;\n const target = current + crossLaneCount;\n // Ensure we still respect predecessor constraints\n let lb = 0;\n for (const e of g.edges) {\n if (e.dst === v) {\n lb = Math.max(lb, (rankOf[e.src] ?? 0) + 1);\n }\n }\n const newRank = Math.max(current, lb, target);\n if (newRank !== current) {\n rankOf[v] = newRank;\n }\n }\n}\n", "import type { Graph, Layering, NodeId } from './helpers.js';\nimport { incoming, topoSortIfAcyclic, normalizeGraph } from './phase0.helpers.js';\nimport type { LayeringOptions } from './phase2.options.js';\nimport { createTopLaneResolver } from './phase2.options.js';\nimport { optimizeRanksByCrossings } from './phase2.crossOptimization.js';\nimport { adjustCrossLaneSources } from './phase2.crossLaneAdjust.js';\nimport { buildMultitreeLayerOrder } from './phase2.multitree.order.js';\n\n/**\n * Classic longest-path layering with optional compaction and lane awareness.\n */\nexport function assignLayers_LongestPath(gAcyclic: Graph, opts?: LayeringOptions): Layering {\n const g = normalizeGraph(gAcyclic);\n const order = topoSortIfAcyclic(g) ?? [...g.nodes].sort();\n const compact = opts?.compactSingleInput ?? false;\n\n const topLaneOf = createTopLaneResolver(g);\n\n let rankOf: Record<NodeId, number> = Object.create(null);\n for (const v of order) {\n const incAll = incoming(g, v);\n const inc = opts?.ignoreCrossLaneEdges\n ? incAll.filter((e) => {\n const laneSrc = topLaneOf(e.src);\n const laneDst = topLaneOf(v);\n if (!laneSrc || !laneDst) {\n return true;\n }\n return laneSrc === laneDst;\n })\n : incAll;\n if (inc.length === 0) {\n rankOf[v] = 0;\n } else if (compact && inc.length === 1) {\n const u = inc[0].src;\n // Only compact if predecessor is in a different lane than v\n const laneU = topLaneOf(u);\n const laneV = topLaneOf(v);\n if (laneU !== laneV) {\n rankOf[v] = rankOf[u] ?? 0;\n } else {\n rankOf[v] = (rankOf[u] ?? 0) + 1;\n }\n } else {\n let mx = -Infinity;\n for (const e of inc) {\n mx = Math.max(mx, (rankOf[e.src] ?? 0) + 1);\n }\n rankOf[v] = mx === -Infinity ? 0 : mx;\n }\n }\n\n // Optional: revisit ranks using a greedy crossing reduction respecting precedence constraints\n if (opts?.optimizeRanksByCrossings ?? false) {\n rankOf = optimizeRanksByCrossings(g, rankOf);\n }\n\n if (opts?.ignoreCrossLaneEdges) {\n adjustCrossLaneSources(g, rankOf);\n }\n\n const layers = buildMultitreeLayerOrder(g, rankOf, topLaneOf);\n\n return { layers, rankOf, dummy: new Set<NodeId>() };\n}\n", "import type { Graph, Layering, NodeId } from './helpers.js';\nimport {\n buildLayersFromRanks,\n buildPredecessorSuccessorMaps,\n topoSortIfAcyclic,\n normalizeGraph,\n} from './phase0.helpers.js';\nimport type { LayeringOptions } from './phase2.options.js';\nimport { createTopLaneResolver } from './phase2.options.js';\nimport { LAYERING } from './config.js';\nimport { assignLayers_LongestPath } from './phase2.longestPath.js';\n\n// cspell:ignore acyclicity preds succs\n\n/**\n * Gravity-based layering algorithm that minimizes edge lengths while maintaining acyclicity.\n */\nexport function assignLayers_Gravity(gAcyclic: Graph, opts?: LayeringOptions): Layering {\n const g = normalizeGraph(gAcyclic);\n // Initial ranks from longest path (gives feasible lower bounds)\n const base = assignLayers_LongestPath(g, {\n compactSingleInput: opts?.compactSingleInput,\n ignoreCrossLaneEdges: opts?.ignoreCrossLaneEdges,\n optimizeRanksByCrossings: opts?.optimizeRanksByCrossings,\n });\n const rankOf: Record<NodeId, number> = { ...base.rankOf } as any;\n\n const topLaneOf = createTopLaneResolver(g);\n\n const { preds, succs } = buildPredecessorSuccessorMaps(g, (e) => {\n if (opts?.ignoreCrossLaneEdges) {\n const laneSrc = topLaneOf(e.src);\n const laneDst = topLaneOf(e.dst);\n if (laneSrc && laneDst && laneSrc !== laneDst) {\n return false;\n }\n }\n return true;\n });\n\n const order = topoSortIfAcyclic(g) ?? [...g.nodes];\n const revOrder = [...order].reverse();\n\n const clampFeasible = (v: NodeId, desired: number): number => {\n // Lower bound from predecessors: max(rank[u] + 1)\n let lb = 0;\n for (const u of preds.get(v) ?? []) {\n lb = Math.max(lb, (rankOf[u] ?? 0) + 1);\n }\n // Upper bound from successors: min(rank[w] - 1)\n let ub = Number.POSITIVE_INFINITY;\n const s = succs.get(v) ?? [];\n if (s.length > 0) {\n ub = Math.min(...s.map((w) => (rankOf[w] ?? 0) - 1));\n }\n if (!Number.isFinite(ub)) {\n ub = Math.max(lb, desired);\n }\n return Math.min(Math.max(desired, lb), ub);\n };\n\n // Iterative relaxation\n const iters = LAYERING.GRAVITY_ITERATIONS;\n const relaxOrder = (nodeOrder: NodeId[]): boolean => {\n let changed = false;\n for (const v of nodeOrder) {\n const ps = preds.get(v) ?? [];\n const ss = succs.get(v) ?? [];\n if (ps.length === 0 && ss.length === 0) {\n continue;\n }\n const predAvg =\n ps.length > 0\n ? ps.reduce((a, u) => a + (rankOf[u] ?? 0) + 1, 0) / ps.length\n : (rankOf[v] ?? 0);\n const succAvg =\n ss.length > 0\n ? ss.reduce((a, w) => a + (rankOf[w] ?? 0) - 1, 0) / ss.length\n : (rankOf[v] ?? 0);\n const desired = Math.round((predAvg + succAvg) / 2);\n const clamped = clampFeasible(v, desired);\n if (clamped !== rankOf[v]) {\n rankOf[v] = clamped;\n changed = true;\n }\n }\n return changed;\n };\n\n for (let it = 0; it < iters; it++) {\n const forwardChanged = relaxOrder(order);\n // backward pass helps propagate upper bounds\n const backwardChanged = relaxOrder(revOrder);\n if (!forwardChanged && !backwardChanged) {\n break;\n }\n }\n\n // Final feasibility fix-ups (ensure r(v) >= r(u)+1)\n for (const v of order) {\n let lb = 0;\n for (const u of preds.get(v) ?? []) {\n lb = Math.max(lb, (rankOf[u] ?? 0) + 1);\n }\n if ((rankOf[v] ?? 0) < lb) {\n rankOf[v] = lb;\n }\n }\n for (const v of revOrder) {\n const s = succs.get(v) ?? [];\n if (s.length > 0) {\n const ub = Math.min(...s.map((w) => (rankOf[w] ?? 0) - 1));\n if ((rankOf[v] ?? 0) > ub) {\n rankOf[v] = ub;\n }\n }\n }\n\n const layers = buildLayersFromRanks(g, order, rankOf);\n\n return { layers, rankOf, dummy: new Set<NodeId>() };\n}\n", "import type { Graph, Layering, NodeId } from './helpers.js';\nimport {\n buildInDegreeMap,\n buildLayersFromRanks,\n buildSortedSuccessorMap,\n incoming,\n normalizeGraph,\n sortedZeroInDegreeNodes,\n topoSortIfAcyclic,\n} from './phase0.helpers.js';\nimport type { LayeringOptions } from './phase2.options.js';\nimport { createTopLaneResolver } from './phase2.options.js';\n\n// cspell:ignore indeg preds topo\n\nfunction topoSortByGenerationIfAcyclic(g: Graph): NodeId[] | null {\n const indeg = buildInDegreeMap(g);\n const adj = buildSortedSuccessorMap(g);\n let frontier = sortedZeroInDegreeNodes(indeg);\n const order: NodeId[] = [];\n\n while (frontier.length > 0) {\n const nextFrontier: NodeId[] = [];\n for (const u of frontier) {\n order.push(u);\n for (const v of adj.get(u) ?? []) {\n indeg.set(v, (indeg.get(v) ?? 0) - 1);\n if ((indeg.get(v) ?? 0) === 0) {\n nextFrontier.push(v);\n }\n }\n }\n frontier = nextFrontier.sort((a, b) => a.localeCompare(b));\n }\n\n return order.length === g.nodes.length ? order : null;\n}\n\n// Lane-aware compact layering: one node per (layer, lane); inter-lane edges can stay on same layer\nexport function assignLayers_LaneAwareCompact(gAcyclic: Graph, opts?: LayeringOptions): Layering {\n const g = normalizeGraph(gAcyclic);\n const order =\n opts?.direction === 'LR'\n ? (topoSortByGenerationIfAcyclic(g) ?? [...g.nodes].sort())\n : (topoSortIfAcyclic(g) ?? [...g.nodes].sort());\n\n // Determine a lane id for each node: top-level parent id, or fall back to node id if none\n const topLaneOf = createTopLaneResolver(g);\n const laneOf = (id: NodeId): string => topLaneOf(id) ?? id;\n\n const rankOf: Record<NodeId, number> = Object.create(null);\n const nextFree = new Map<string, number>();\n\n // Helper: edge weight w(u,v) = 1 if same lane else 0, when ignoring cross-lane constraints;\n // otherwise 1 for all edges.\n const edgeWeight = (u: NodeId, v: NodeId): number => {\n const ignoreCrossLane = opts?.ignoreCrossLaneEdges ?? true;\n if (ignoreCrossLane) {\n return laneOf(u) === laneOf(v) ? 1 : 0;\n }\n return 1;\n };\n\n for (const v of order) {\n const node = g.nodeById.get(v) as any;\n if (node?.isGroup) {\n continue;\n } // do not assign ranks/capacity to lane/group containers\n const preds = incoming(g, v);\n let base = 0;\n if (preds.length > 0) {\n for (const e of preds) {\n const u = e.src;\n const ru = rankOf[u] ?? 0;\n base = Math.max(base, ru + edgeWeight(u, v));\n }\n }\n const lane = laneOf(v);\n const nf = nextFree.get(lane) ?? 0;\n const L = Math.max(base, nf);\n rankOf[v] = L;\n nextFree.set(lane, L + 1);\n }\n\n const layers = buildLayersFromRanks(g, order, rankOf, { skipGroups: true });\n\n return { layers, rankOf, dummy: new Set<NodeId>() };\n}\n", "import type { Graph, Layering, Node, NodeId, EdgeRef } from './helpers.js';\nimport { normalizeGraph } from './phase0.helpers.js';\n\nexport function makeProperLayering(\n layering: Layering,\n gAcyclic: Graph\n): { layering: Layering; graphWithDummies: Graph } {\n const g = normalizeGraph(gAcyclic);\n const { rankOf } = layering;\n const layers = layering.layers.map((l) => [...l]);\n const dummy = new Set<NodeId>(layering.dummy ? [...layering.dummy] : []);\n\n // Helper to create a dummy node at layer L\n let dummySeq = 0;\n const nodeById = new Map(g.nodeById);\n const addDummyAt = (L: number): NodeId => {\n const id: NodeId = `placeholder-${dummySeq++}`;\n const dn: Node = { id, isGroup: false, isDummy: true, width: 0, height: 0 } as any;\n nodeById.set(id, dn);\n dummy.add(id);\n // Ensure layers[L] exists\n while (layers.length <= L) {\n layers.push([]);\n }\n layers[L].push(id);\n (rankOf as any)[id] = L;\n return id;\n };\n\n // Sort edges deterministically to stabilize dummy creation order\n const edgesSorted = [...g.edges].sort((a, b) =>\n a.id === b.id\n ? a.src === b.src\n ? a.dst.localeCompare(b.dst)\n : a.src.localeCompare(b.src)\n : a.id.localeCompare(b.id)\n );\n\n const newEdges: EdgeRef[] = [];\n for (const e of edgesSorted) {\n const rU = rankOf[e.src] ?? 0;\n const rV = rankOf[e.dst] ?? 0;\n if (rV - rU <= 1) {\n newEdges.push(e);\n continue;\n }\n // Need to insert dummies on intermediate layers rU+1..rV-1\n let prev = e.src;\n for (let L = rU + 1, k = 0; L < rV; L++, k++) {\n const d = addDummyAt(L);\n // chain prev -> d\n newEdges.push({ id: `${e.id}#${k}`, src: prev, dst: d, weight: e.weight, ref: e.ref });\n prev = d;\n }\n // last dummy (or src if no dummies) -> dst\n const lastIndex = rV - rU - 2; // -2 because we added k from 0..(rV-rU-2)\n newEdges.push({\n id: `${e.id}#${Math.max(lastIndex + 1, 0)}`,\n src: prev,\n dst: e.dst,\n weight: e.weight,\n ref: e.ref,\n });\n }\n\n // Build new nodes list (preserve original order, then dummies by creation order)\n const nodes = [...g.nodes, ...[...dummy].filter((id) => !g.nodes.includes(id))];\n const graphWithDummies: Graph = { nodes, edges: newEdges, layout: g.layout, nodeById };\n\n return { layering: { layers, rankOf, dummy }, graphWithDummies };\n}\n", "import type { Graph, Layering, OrderedLayers, NodeId, Edge } from './helpers.js';\nimport { buildLayerIndex, countInversions } from './phase0.helpers.js';\nimport { createTopLaneResolver, resolveTopLaneOrder } from './phase2.options.js';\n\ntype SweepDirection = 'down' | 'up';\n\nfunction median(values: number[]): number {\n const n = values.length;\n if (n === 0) {\n return Number.POSITIVE_INFINITY;\n }\n const a = [...values].sort((x, y) => x - y);\n if (n % 2 === 1) {\n return a[(n - 1) / 2];\n }\n return 0.5 * (a[n / 2 - 1] + a[n / 2]);\n}\n\nfunction barycenter(values: number[]): number {\n if (values.length === 0) {\n return Number.POSITIVE_INFINITY;\n }\n const s = values.reduce((acc, v) => acc + v, 0);\n return s / values.length;\n}\n\nfunction neighborPositionsFor(\n targetNodes: NodeId[],\n fixedIndex: Map<NodeId, number>,\n edges: Edge[],\n direction: SweepDirection\n): Map<NodeId, number[]> {\n const neighborPositions = new Map<NodeId, number[]>();\n for (const v of targetNodes) {\n neighborPositions.set(v, []);\n }\n for (const e of edges) {\n if (direction === 'down') {\n if (fixedIndex.has(e.src) && neighborPositions.has(e.dst)) {\n neighborPositions.get(e.dst)!.push(fixedIndex.get(e.src)!);\n }\n } else if (fixedIndex.has(e.dst) && neighborPositions.has(e.src)) {\n neighborPositions.get(e.src)!.push(fixedIndex.get(e.dst)!);\n }\n }\n return neighborPositions;\n}\n\nfunction currentOrderTieBreak(\n a: NodeId,\n b: NodeId,\n currentLayerIndex: Map<NodeId, number>\n): number {\n const ia = currentLayerIndex.get(a) ?? 0;\n const ib = currentLayerIndex.get(b) ?? 0;\n return ia !== ib ? ia - ib : a.localeCompare(b);\n}\n\nfunction countCrossingsBetweenAdjacent(upper: NodeId[], lower: NodeId[], edges: Edge[]): number {\n // Filter edges between these two layers\n const upperSet = new Set(upper);\n const lowerSet = new Set(lower);\n const upperIndex = buildLayerIndex(upper);\n const lowerIndex = buildLayerIndex(lower);\n const pairs: { u: number; v: number }[] = [];\n for (const e of edges) {\n if (upperSet.has(e.src) && lowerSet.has(e.dst)) {\n pairs.push({ u: upperIndex.get(e.src)!, v: lowerIndex.get(e.dst)! });\n }\n }\n // Sort by u, count inversions in v\n pairs.sort((a, b) => (a.u === b.u ? a.v - b.v : a.u - b.u));\n const vs = pairs.map((p) => p.v);\n return countInversions(vs);\n}\n\nexport function totalCrossings(layers: NodeId[][], edges: Edge[]): number {\n let sum = 0;\n for (let i = 0; i + 1 < layers.length; i++) {\n sum += countCrossingsBetweenAdjacent(layers[i], layers[i + 1], edges);\n }\n return sum;\n}\n\n/**\n * Sort a subset of nodes by their median score relative to a fixed layer.\n * This is the core sorting logic extracted for reuse per-lane.\n */\nfunction sortByHeuristic(\n nodes: NodeId[],\n neighborPositions: Map<NodeId, number[]>,\n currentLayerIndex: Map<NodeId, number>\n): NodeId[] {\n return [...nodes].sort((a, b) => {\n const sa = median(neighborPositions.get(a) ?? []);\n const sb = median(neighborPositions.get(b) ?? []);\n if (sa === sb) {\n return currentOrderTieBreak(a, b, currentLayerIndex);\n }\n if (!isFinite(sa)) {\n return 1;\n }\n if (!isFinite(sb)) {\n return -1;\n }\n return sa - sb;\n });\n}\n\nfunction reorderLayer(\n fixedLayer: NodeId[],\n targetLayer: NodeId[],\n edges: Edge[],\n direction: SweepDirection,\n topLaneOf?: (id: NodeId) => string | null,\n laneOrder?: string[]\n): NodeId[] {\n const fixedIndex = buildLayerIndex(fixedLayer);\n const currIndex = buildLayerIndex(targetLayer);\n const neighborPositions = neighborPositionsFor(targetLayer, fixedIndex, edges, direction);\n\n // If no lane info, fall back to flat reorder (original behavior)\n if (!topLaneOf || !laneOrder || laneOrder.length === 0) {\n return sortByHeuristic(targetLayer, neighborPositions, currIndex);\n }\n\n // Partition target layer nodes by lane\n const byLane = new Map<string | null, NodeId[]>();\n for (const id of targetLayer) {\n const lane = topLaneOf(id);\n const arr = byLane.get(lane) ?? [];\n arr.push(id);\n byLane.set(lane, arr);\n }\n\n // Reorder nodes within each lane independently\n const result: NodeId[] = [];\n\n // First, place lane-grouped nodes in lane order\n for (const lane of laneOrder) {\n const nodesInLane = byLane.get(lane);\n if (!nodesInLane || nodesInLane.length === 0) {\n continue;\n }\n const sorted = sortByHeuristic(nodesInLane, neighborPositions, currIndex);\n result.push(...sorted);\n }\n\n // Then, handle null-lane nodes (long-edge dummies without a parent).\n // Compute their barycenter and insert them adjacent to the lane whose\n // center position is closest to their barycenter.\n const nullNodes = byLane.get(null);\n if (nullNodes && nullNodes.length > 0) {\n // Sort null-lane nodes by their barycenter across the full layer\n const sorted = sortByHeuristic(nullNodes, neighborPositions, currIndex);\n\n // For each null-lane node, find the best insertion position\n // based on its connections to nodes already in the result\n for (const nid of sorted) {\n // Compute the barycenter position of this node's neighbors in the fixed layer\n const bc = barycenter(neighborPositions.get(nid) ?? []);\n\n // Find the best insertion point: scan result and insert where the\n // node's barycenter fits relative to its neighbors\n let bestIdx = result.length; // default: append at end\n if (isFinite(bc)) {\n // Find insertion point by comparing barycenter against positions of\n // nodes already placed. Insert before the first node whose fixed-layer\n // neighbor position is greater than this node's barycenter.\n for (const [i, rid] of result.entries()) {\n const rBc = barycenter(neighborPositions.get(rid) ?? []);\n if (bc < rBc) {\n bestIdx = i;\n break;\n }\n }\n }\n result.splice(bestIdx, 0, nid);\n }\n }\n\n return result;\n}\n\nfunction transposeImprove(\n upper: NodeId[],\n current: NodeId[],\n edges: Edge[],\n next?: NodeId[],\n topLaneOf?: (id: NodeId) => string | null\n): NodeId[] {\n const best = [...current];\n const upperSet = new Set(upper);\n const layerSet = new Set(current);\n const nextSet = next ? new Set(next) : null;\n\n const edgesIn = edges.filter((e) => upperSet.has(e.src) && layerSet.has(e.dst));\n const edgesOut = nextSet\n ? edges.filter((e) => layerSet.has(e.src) && nextSet.has(e.dst))\n : undefined;\n\n const crossingScore = (order: NodeId[]): number => {\n let score = countCrossingsBetweenAdjacent(upper, order, edgesIn);\n if (edgesOut && next) {\n score += countCrossingsBetweenAdjacent(order, next, edgesOut);\n }\n return score;\n };\n\n // Precompute lane membership for same-lane check\n const laneOf = topLaneOf ? new Map<NodeId, string | null>() : null;\n if (topLaneOf && laneOf) {\n for (const id of current) {\n laneOf.set(id, topLaneOf(id));\n }\n }\n\n let improved = true;\n let bestScore = crossingScore(best);\n while (improved) {\n improved = false;\n for (let i = 0; i + 1 < best.length; i++) {\n // Only swap nodes in the same lane (or both null-lane)\n if (laneOf) {\n const laneA = laneOf.get(best[i]);\n const laneB = laneOf.get(best[i + 1]);\n if (laneA !== laneB) {\n continue; // never swap across lane boundaries\n }\n }\n\n const prev = bestScore;\n [best[i], best[i + 1]] = [best[i + 1], best[i]];\n const nextScore = crossingScore(best);\n if (nextScore < prev) {\n bestScore = nextScore;\n improved = true;\n } else {\n [best[i], best[i + 1]] = [best[i + 1], best[i]];\n }\n }\n }\n return best;\n}\n\n// Sugiyama phase 3: lane-aware median sweeps plus adjacent transpose improvements.\nexport interface OrderOptions {\n laneOrder?: string[];\n}\n\nexport function orderLayers(\n layering: Layering,\n gWithDummies: Graph,\n opts?: OrderOptions\n): OrderedLayers {\n // Start with deterministic initial order per layer (preserve given order)\n const layers = layering.layers.map((l) => [...l]);\n const edges = gWithDummies.edges;\n\n // Compute lane order for lane-aware crossing minimization (Siebenhaller Lemma 4.4)\n const topLaneOf = createTopLaneResolver(gWithDummies);\n const laneOrder = resolveTopLaneOrder(gWithDummies, opts?.laneOrder);\n\n // Perform top-down / bottom-up sweeps\n for (let s = 0; s < 3; s++) {\n // Top-down: reorder layer i based on neighbors in layer i-1\n for (let i = 1; i < layers.length; i++) {\n layers[i] = reorderLayer(layers[i - 1], layers[i], edges, 'down', topLaneOf, laneOrder);\n layers[i] = transposeImprove(layers[i - 1], layers[i], edges, layers[i + 1], topLaneOf);\n }\n // Bottom-up: reorder layer i based on neighbors in layer i+1\n for (let i = layers.length - 2; i >= 0; i--) {\n layers[i] = reorderLayer(layers[i + 1], layers[i], edges, 'up', topLaneOf, laneOrder);\n layers[i] = transposeImprove(layers[i + 1], layers[i], edges, layers[i - 1], topLaneOf);\n }\n }\n\n return { layers };\n}\n", "import type { Graph, OrderedLayers, Coordinates, NodeId, EdgeRef } from './helpers.js';\nimport { COORDINATES } from './config.js';\nimport { createTopLaneResolver, resolveTopLaneOrder } from './phase2.options.js';\n\nexport interface CoordOptions {\n layerGap?: number; // vertical distance between layers\n nodeGap?: number; // horizontal gap between siblings inside a lane\n laneGap?: number; // horizontal gap between lanes (clusters)\n direction?: 'TB' | 'LR' | 'BT' | 'RL'; // layout direction for proper spacing\n laneOrder?: string[];\n}\n\nexport function assignCoordinates(\n ordered: OrderedLayers,\n gWithDummies: Graph,\n opts?: CoordOptions\n): Coordinates {\n const layerGap = opts?.layerGap ?? COORDINATES.DEFAULT_LAYER_GAP;\n const nodeGap = opts?.nodeGap ?? COORDINATES.DEFAULT_NODE_GAP;\n const laneGap = opts?.laneGap ?? nodeGap * 2;\n const direction = opts?.direction ?? 'TB';\n const isHorizontal = direction === 'LR' || direction === 'RL';\n\n const layers = ordered.layers;\n\n const x: Record<NodeId, number> = Object.create(null);\n const y: Record<NodeId, number> = Object.create(null);\n\n const getNode = (id: NodeId) => gWithDummies.nodeById.get(id) as any;\n const getWidth = (id: NodeId) => getNode(id)?.width ?? 0;\n const getHeight = (id: NodeId) => getNode(id)?.height ?? 0;\n const topLaneOf = createTopLaneResolver(gWithDummies);\n const laneOrderGlobal = resolveTopLaneOrder(gWithDummies, opts?.laneOrder);\n\n const layerHeights: number[] = layers.map((layer) =>\n layer.reduce((m, v) => Math.max(m, getHeight(v)), 0)\n );\n\n // LR/RL transforms turn width into horizontal span, so widen layer gaps up front.\n const extraLayerGaps: number[] = [];\n if (isHorizontal) {\n for (let i = 0; i + 1 < layers.length; i++) {\n const thisLayerMaxWidth = layers[i].reduce((m, v) => Math.max(m, getWidth(v)), 0);\n const nextLayerMaxWidth = layers[i + 1].reduce((m, v) => Math.max(m, getWidth(v)), 0);\n const thisLayerMaxHeight = layerHeights[i];\n const nextLayerMaxHeight = layerHeights[i + 1];\n\n const normalSpacing = thisLayerMaxHeight / 2 + nextLayerMaxHeight / 2;\n const requiredSpacing = (thisLayerMaxWidth + nextLayerMaxWidth) / 2;\n const extraNeeded = Math.max(0, requiredSpacing - normalSpacing - layerGap);\n extraLayerGaps.push(extraNeeded);\n }\n }\n\n const lanesUsedSet = new Set<string | null>();\n for (const layer of layers) {\n for (const id of layer) {\n lanesUsedSet.add(topLaneOf(id));\n }\n }\n const hasNullLane = lanesUsedSet.has(null);\n const lanesUsed = laneOrderGlobal.filter((L) => lanesUsedSet.has(L));\n const laneOrderColumns: (string | null)[] = [...(hasNullLane ? [null] : []), ...lanesUsed];\n\n const laneWidth: Record<string, number> = Object.create(null);\n for (const L of lanesUsed) {\n laneWidth[L] = 0;\n }\n if (hasNullLane) {\n (laneWidth as any).null = 0 as any;\n }\n for (const layer of layers) {\n const perLane: Record<string, string[]> = Object.create(null);\n const nullIds: string[] = [];\n for (const id of layer) {\n const L = topLaneOf(id);\n if (L === null) {\n nullIds.push(id);\n } else {\n (perLane[L] ||= []).push(id);\n }\n }\n for (const [L, ids] of Object.entries(perLane)) {\n const total =\n ids.reduce((s, id) => s + getWidth(id), 0) + nodeGap * Math.max(0, ids.length - 1);\n laneWidth[L] = Math.max(laneWidth[L] ?? 0, total);\n }\n if (hasNullLane && nullIds.length) {\n const totalNull =\n nullIds.reduce((s, id) => s + getWidth(id), 0) + nodeGap * Math.max(0, nullIds.length - 1);\n (laneWidth as any).null = Math.max((laneWidth as any).null ?? 0, totalNull) as any;\n }\n }\n\n const centerX = new Map<string | null, number>();\n {\n const widths = laneOrderColumns.map(\n (L) => (L === null ? ((laneWidth as any).null as number) : laneWidth[L]) ?? 0\n );\n const totalW =\n widths.reduce((a, b) => a + b, 0) + laneGap * Math.max(0, laneOrderColumns.length - 1);\n let cursor = -totalW / 2;\n for (let i = 0; i < laneOrderColumns.length; i++) {\n const L = laneOrderColumns[i];\n const w = widths[i] ?? 0;\n const cx = cursor + w / 2;\n centerX.set(L, cx);\n cursor += w;\n if (i < laneOrderColumns.length - 1) {\n cursor += laneGap;\n }\n }\n }\n\n let yOffset = 0;\n for (const [li, layer] of layers.entries()) {\n const layerH = layerHeights[li] ?? 0;\n\n const byLane = new Map<string | null, NodeId[]>();\n for (const id of layer) {\n const laneId = topLaneOf(id);\n const arr = byLane.get(laneId) ?? [];\n arr.push(id);\n byLane.set(laneId, arr);\n }\n\n for (const L of laneOrderColumns) {\n const nodesInLane = byLane.get(L) ?? [];\n if (nodesInLane.length === 0) {\n continue;\n }\n const cx = centerX.get(L)!;\n if (nodesInLane.length === 1) {\n const id = nodesInLane[0];\n x[id] = cx;\n y[id] = yOffset + layerH / 2;\n } else {\n // Preserve phase 3 order while spreading nodes around the lane center.\n const widths = nodesInLane.map((id) => getWidth(id));\n const total = widths.reduce((a, b) => a + b, 0) + nodeGap * (nodesInLane.length - 1);\n let start = cx - total / 2;\n for (const [i, id] of nodesInLane.entries()) {\n const w = widths[i];\n x[id] = start + w / 2;\n y[id] = yOffset + layerH / 2;\n start += w + nodeGap;\n }\n }\n }\n\n const extraGap = extraLayerGaps[li] ?? 0;\n yOffset += layerH + layerGap + extraGap;\n }\n\n // Align dummy chains for each original edge: set dummy x to midpoint between src and dst.\n const byRef = new Map<string, EdgeRef[]>();\n for (const e of gWithDummies.edges) {\n const rid = e.ref.id;\n if (!byRef.has(rid)) {\n byRef.set(rid, []);\n }\n byRef.get(rid)!.push(e);\n }\n for (const [, chainEdges] of byRef) {\n if (chainEdges.length === 0) {\n continue;\n }\n const ref = chainEdges[0].ref;\n const src = ref.start!;\n const dst = ref.end!;\n if (src == null || dst == null) {\n continue;\n }\n const midX = Math.round(((x[src] ?? 0) + (x[dst] ?? 0)) / 2);\n const involved = new Set<NodeId>();\n for (const e of chainEdges) {\n involved.add(e.src);\n involved.add(e.dst);\n }\n for (const vid of involved) {\n if (vid === src || vid === dst) {\n continue;\n }\n const node = gWithDummies.nodeById.get(vid) as any;\n if (node?.isDummy) {\n x[vid] = midX;\n }\n }\n }\n\n return { x, y };\n}\n", "import type { Graph } from './helpers.js';\nimport { buildTopLaneOrder, createTopLaneResolver } from './phase2.options.js';\n\nexport const AUTOMATIC_LANE_ORDERING_RESTARTS = 8;\n\nexport interface WeightedLaneEdge {\n a: string;\n b: string;\n weight: number;\n}\n\ninterface CandidateOrder {\n order: string[];\n cost: number;\n sourceDistance: number;\n}\n\nfunction hashString(input: string): number {\n let hash = 2166136261;\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n}\n\nfunction mulberry32(seed: number): () => number {\n let state = seed >>> 0;\n return () => {\n state += 0x6d2b79f5;\n let t = state;\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\nfunction deterministicShuffle(order: string[], seed: number): string[] {\n const shuffled = [...order];\n const random = mulberry32(seed);\n for (let i = shuffled.length - 1; i > 0; i--) {\n const j = Math.floor(random() * (i + 1));\n [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];\n }\n return shuffled;\n}\n\nfunction sourceDistance(order: string[], sourceIndex: Map<string, number>): number {\n let distance = 0;\n for (const [index, laneId] of order.entries()) {\n distance += Math.abs(index - (sourceIndex.get(laneId) ?? index));\n }\n return distance;\n}\n\nexport function laneArrangementCost(order: string[], weights: WeightedLaneEdge[]): number {\n const position = new Map<string, number>();\n for (const [index, laneId] of order.entries()) {\n position.set(laneId, index);\n }\n\n let cost = 0;\n for (const { a, b, weight } of weights) {\n const ai = position.get(a);\n const bi = position.get(b);\n if (ai == null || bi == null) {\n continue;\n }\n cost += weight * Math.abs(ai - bi);\n }\n return cost;\n}\n\nexport function buildWeightedLaneEdges(g: Graph): WeightedLaneEdge[] {\n const sourceOrder = buildTopLaneOrder(g);\n if (sourceOrder.length < 2) {\n return [];\n }\n\n const sourceIndex = new Map(sourceOrder.map((laneId, index) => [laneId, index]));\n const topLaneOf = createTopLaneResolver(g);\n const weights = new Map<string, WeightedLaneEdge>();\n\n for (const edge of g.layout.edges ?? []) {\n if ((edge as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n const src = typeof edge.start === 'string' ? edge.start : undefined;\n const dst = typeof edge.end === 'string' ? edge.end : undefined;\n if (!src || !dst || !g.nodeById.has(src) || !g.nodeById.has(dst)) {\n continue;\n }\n\n const laneA = topLaneOf(src);\n const laneB = topLaneOf(dst);\n if (!laneA || !laneB || laneA === laneB) {\n continue;\n }\n\n const ia = sourceIndex.get(laneA);\n const ib = sourceIndex.get(laneB);\n if (ia == null || ib == null) {\n continue;\n }\n\n const [a, b] = ia <= ib ? [laneA, laneB] : [laneB, laneA];\n const key = `${a}\\0${b}`;\n const existing = weights.get(key);\n if (existing) {\n existing.weight++;\n } else {\n weights.set(key, { a, b, weight: 1 });\n }\n }\n\n return [...weights.values()];\n}\n\nfunction greedySwitch(\n startOrder: string[],\n weights: WeightedLaneEdge[],\n sourceIndex: Map<string, number>\n): CandidateOrder {\n const order = [...startOrder];\n let cost = laneArrangementCost(order, weights);\n let changed = true;\n let sweeps = 0;\n const maxSweeps = Math.max(1, order.length);\n\n while (changed && sweeps < maxSweeps) {\n changed = false;\n sweeps++;\n for (let i = 0; i + 1 < order.length; i++) {\n [order[i], order[i + 1]] = [order[i + 1], order[i]];\n const nextCost = laneArrangementCost(order, weights);\n if (nextCost < cost) {\n cost = nextCost;\n changed = true;\n } else {\n [order[i], order[i + 1]] = [order[i + 1], order[i]];\n }\n }\n }\n\n return {\n order,\n cost,\n sourceDistance: sourceDistance(order, sourceIndex),\n };\n}\n\nfunction isBetterCandidate(candidate: CandidateOrder, best: CandidateOrder): boolean {\n if (candidate.cost !== best.cost) {\n return candidate.cost < best.cost;\n }\n return candidate.sourceDistance < best.sourceDistance;\n}\n\nfunction seedForRestart(\n sourceOrder: string[],\n weights: WeightedLaneEdge[],\n restartIndex: number\n): number {\n const weightSignature = [...weights]\n .sort((a, b) => (a.a === b.a ? a.b.localeCompare(b.b) : a.a.localeCompare(b.a)))\n .map(({ a, b, weight }) => `${a}:${b}:${weight}`)\n .join('|');\n return hashString(`${sourceOrder.join('|')}#${weightSignature}#${restartIndex}`);\n}\n\nexport function optimizeTopLaneOrder(g: Graph, opts: { restarts?: number } = {}): string[] {\n const sourceOrder = buildTopLaneOrder(g);\n if (sourceOrder.length < 2) {\n return sourceOrder;\n }\n\n const weights = buildWeightedLaneEdges(g);\n if (weights.length === 0) {\n return sourceOrder;\n }\n\n const sourceIndex = new Map(sourceOrder.map((laneId, index) => [laneId, index]));\n let best = greedySwitch(sourceOrder, weights, sourceIndex);\n const restarts = Math.max(0, opts.restarts ?? AUTOMATIC_LANE_ORDERING_RESTARTS);\n\n for (let i = 0; i < restarts; i++) {\n const seed = seedForRestart(sourceOrder, weights, i);\n const start = deterministicShuffle(sourceOrder, seed);\n const candidate = greedySwitch(start, weights, sourceIndex);\n if (isBetterCandidate(candidate, best)) {\n best = candidate;\n }\n }\n\n return best.order;\n}\n", "import type { Graph, Layering, OrderedLayers, Coordinates, Edge } from './helpers.js';\nimport { normalizeGraph } from './phase0.helpers.js';\nimport { removeCycles_DFS } from './phase1.cycles.js';\n\nimport { assignLayers_Gravity } from './phase2.gravity.js';\nimport { assignLayers_LaneAwareCompact } from './phase2.laneAwareCompact.js';\nimport { makeProperLayering } from './phase2.dummies.js';\nimport { orderLayers } from './phase3.ordering.js';\nimport { assignCoordinates } from './phase4.coordinates.js';\nimport { LAYERING } from './config.js';\nimport { AUTOMATIC_LANE_ORDERING_RESTARTS, optimizeTopLaneOrder } from './laneOrdering.js';\n\nexport interface LayoutOptions {\n // Layering\n compactSingleInput?: boolean; // default true for compact swimlanes\n ignoreCrossLaneEdges?: boolean;\n optimizeRanksByCrossings?: boolean;\n automaticLaneOrdering?: boolean;\n // Coordinates\n layerGap?: number;\n nodeGap?: number;\n // Direction (for proper spacing calculation)\n direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\nexport interface LayoutResult {\n acyclic: Graph;\n reversed: Edge[];\n layering: Layering;\n ordered: OrderedLayers;\n coordinates: Coordinates;\n}\n\nexport function sugiyamaLayout(g: Graph, opts?: LayoutOptions): LayoutResult {\n const ignoreCrossLaneEdges = opts?.ignoreCrossLaneEdges ?? true;\n const optimizeRanksByCrossings = opts?.optimizeRanksByCrossings ?? true;\n const g0 = normalizeGraph(g);\n const laneOrder = opts?.automaticLaneOrdering\n ? optimizeTopLaneOrder(g0, { restarts: AUTOMATIC_LANE_ORDERING_RESTARTS })\n : undefined;\n\n // Phase 1: cycle removal\n const cycleRes = removeCycles_DFS(g0);\n const gAcyclic = cycleRes.acyclic;\n\n // Phase 2: layering\n const layering = ignoreCrossLaneEdges\n ? assignLayers_LaneAwareCompact(gAcyclic, {\n compactSingleInput: opts?.compactSingleInput ?? LAYERING.DEFAULT_COMPACT_SINGLE_INPUT,\n ignoreCrossLaneEdges: true,\n direction: opts?.direction,\n })\n : assignLayers_Gravity(gAcyclic, {\n compactSingleInput: opts?.compactSingleInput ?? LAYERING.DEFAULT_COMPACT_SINGLE_INPUT,\n ignoreCrossLaneEdges: false,\n optimizeRanksByCrossings,\n });\n const { layering: properLayering, graphWithDummies } = makeProperLayering(layering, gAcyclic);\n // Phase 3: ordering\n const ordered = orderLayers(properLayering, graphWithDummies, { laneOrder });\n\n // Phase 4: coordinates\n const coordinates = assignCoordinates(ordered, graphWithDummies, {\n layerGap: opts?.layerGap,\n nodeGap: opts?.nodeGap,\n direction: opts?.direction,\n laneOrder,\n });\n\n return {\n acyclic: gAcyclic,\n reversed: cycleRes.reversed,\n layering: properLayering,\n ordered,\n coordinates,\n };\n}\n", "// cspell:ignore raykov Raykov Wybrow Marriott Stuckey\n\n/**\n * Orthogonal edge router for the swimlanes layout.\n *\n * Each edge is routed as an axis-aligned (Manhattan) polyline between ports on\n * the node borders, with port distribution and nudging to reduce overlaps and\n * crossings. The approach follows the orthogonal-connector-routing literature \u2014\n * notably Wybrow, Marriott & Stuckey, \"Orthogonal Connector Routing\" (the\n * libavoid family). \"Raykov\" in the comments and tests is the informal name this\n * implementation was developed under, not an external dependency.\n */\n\nimport type { LayoutData, Node as MermaidNode } from '../../../types.js';\nimport { PRECISION } from '../config.js';\n\nconst EPS = PRECISION.EPSILON;\n\nconst NODE_PADDING = 8;\nconst HORIZONTAL_PIPE_MARGIN = 15;\nconst VERTICAL_PIPE_MARGIN = 15;\nconst ROUTING_MARGIN = 25;\nconst ANCHOR_OFFSET = 20;\nconst TRACK_SPACING = 10;\n\n// ---------------------------------------------------------------------------\n// Type Definitions for Orthogonal Router\n// ---------------------------------------------------------------------------\n\ninterface Point {\n x: number;\n y: number;\n}\n\ntype OrthogonalSide = 'top' | 'bottom' | 'left' | 'right';\n\ninterface LaneInfo {\n id: string;\n}\n\ntype Orientation = 'horizontal' | 'vertical';\n\ninterface Pipe {\n id: string;\n orientation: Orientation;\n coord: number; // y for horizontal, x for vertical\n spanMin: number;\n spanMax: number;\n tracks: Track[];\n}\n\ninterface Track {\n index: number;\n coord: number; // actual x/y of this track\n segments: SegmentRef[]; // references to segments belonging to this track\n}\n\ninterface SegmentRef {\n edgeIndex: number;\n segmentIndex: number;\n from: number; // min coord along axis\n to: number; // max coord along axis\n}\n\ninterface RoutedSegment {\n edgeIndex: number;\n segmentIndex: number;\n orientation: Orientation;\n pipe: Pipe;\n trackIndex: number;\n from: number;\n to: number;\n}\n\ninterface RoutedLine {\n orient: Orientation;\n coord: number;\n from: number;\n to: number;\n}\n\nfunction chooseOrthogonalSide(\n node: MermaidNode,\n target: Point,\n fallback: OrthogonalSide\n): OrthogonalSide {\n const cx = node.x ?? 0;\n const cy = node.y ?? 0;\n const dx = target.x - cx;\n const dy = target.y - cy;\n const absDx = Math.abs(dx);\n const absDy = Math.abs(dy);\n\n if (absDx < EPS && absDy < EPS) {\n return fallback;\n }\n\n const verticalBias = 3.0;\n if (absDy > EPS && absDy * verticalBias >= absDx) {\n return dy > 0 ? 'bottom' : 'top';\n }\n if (absDx > EPS) {\n return dx > 0 ? 'right' : 'left';\n }\n return fallback;\n}\n\nfunction sharedLineEndpointCoord(line: RoutedLine, nextLine: RoutedLine): number {\n return Math.abs(line.to - nextLine.from) < EPS || Math.abs(line.to - nextLine.to) < EPS\n ? line.to\n : line.from;\n}\n\nfunction pointOnLine(line: RoutedLine, along: number): Point {\n return line.orient === 'vertical' ? { x: line.coord, y: along } : { x: along, y: line.coord };\n}\n\n// ---------------------------------------------------------------------------\n// Orthogonal Router Implementation\n// ---------------------------------------------------------------------------\n\nexport function routeEdgesOrthogonal(data: LayoutData, direction?: string): LayoutData {\n const nodes = data.nodes ?? [];\n const originalEdges = data.edges ?? [];\n\n // Build a local \"routing view\" of the edge list:\n // - Skip `isLayoutOnly` virtual edges \u2014 they exist only for Sugiyama layering\n // (the A\u2192label, label\u2192B pair lets Sugiyama rank through labels) and must\n // never be routed or rendered.\n // - All other edges (including labelled originals) pass through unchanged.\n // Strategy 1 (late-insertion / diss.pdf \u00A7118): labelled edges are routed\n // as single unbroken A\u2192B polylines with labels invisible to routing.\n // Labels are then anchored post-routing onto a middle segment of the\n // resulting polyline via postProcessing.ts's `anchorLabelsToPolyline` pass.\n // No shadow-split, no L-bend bridge, no per-edge label obstacle exclusion.\n interface InternalRoutingEdge {\n id: string;\n start?: string;\n end?: string;\n points?: Point[];\n __originalEdge?: (typeof originalEdges)[number];\n [key: string]: unknown;\n }\n const edges: InternalRoutingEdge[] = [];\n for (const oe of originalEdges) {\n if ((oe as { isLayoutOnly?: boolean }).isLayoutOnly) {\n continue;\n }\n edges.push({\n ...(oe as unknown as Record<string, unknown>),\n __originalEdge: oe,\n } as InternalRoutingEdge);\n }\n\n const nodeById = new Map<string, MermaidNode>();\n const laneByNodeId = new Map<string, LaneInfo>();\n const pipes: Pipe[] = [];\n const isLR = direction === 'LR';\n\n // 1. Initialize Helpers & Lookups\n for (const n of nodes) {\n nodeById.set(n.id, n);\n }\n\n // Identify Lanes (Top-level groups)\n const topLevelGroups = nodes.filter((n) => n.isGroup && !n.parentId);\n for (const group of topLevelGroups) {\n const lane: LaneInfo = { id: group.id };\n\n // Assign this lane to all descendants\n const assignLane = (n: MermaidNode) => {\n laneByNodeId.set(n.id, lane);\n nodes.filter((child) => child.parentId === n.id).forEach(assignLane);\n };\n assignLane(group);\n }\n // Also build obstacle rects for non-group nodes, tracking which node each belongs to.\n //\n // Strategy 1 (late-insertion / diss.pdf \u00A7118): edge-label nodes are NOT\n // obstacles during routing. Labels are placed post-routing onto an\n // existing polyline segment via `anchorLabelsToPolyline` in postProcessing.ts.\n // Foreign edges never route around labels, so there is no \"foreign edge\n // routed around old label position, label later moved\" inconsistency.\n interface ObstacleRect {\n nodeId: string;\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n // For LR direction, we need to know the \"visual\" extent after transform\n // TB x becomes LR y, so the visual Y extent should use height, not width\n visualXHalfExtent: number;\n }\n const obstacles: ObstacleRect[] = nodes\n .filter((n) => !n.isGroup && !(n as { isEdgeLabel?: boolean }).isEdgeLabel)\n .map((n) => {\n const w = n.width ?? 10;\n const h = n.height ?? 10;\n const x = n.x ?? 0;\n const y = n.y ?? 0;\n // Inflate by configured padding\n const padding = NODE_PADDING;\n\n return {\n nodeId: n.id,\n minX: x - w / 2 - padding,\n maxX: x + w / 2 + padding,\n minY: y - h / 2 - padding,\n maxY: y + h / 2 + padding,\n // For LR: TB x becomes LR y, so visual Y extent should be based on height\n visualXHalfExtent: isLR ? h / 2 + padding : w / 2 + padding,\n };\n });\n\n // Helper to find or create pipe\n const getOrAddPipe = (\n orientation: Orientation,\n coord: number,\n spanMin: number,\n spanMax: number\n ): Pipe => {\n let pipe = pipes.find((p) => p.orientation === orientation && Math.abs(p.coord - coord) < 1);\n if (!pipe) {\n pipe = {\n id: `pipe-${orientation}-${coord.toFixed(0)}`,\n orientation,\n coord,\n spanMin,\n spanMax,\n tracks: [],\n };\n pipes.push(pipe);\n }\n // Extend span\n pipe.spanMin = Math.min(pipe.spanMin, spanMin);\n pipe.spanMax = Math.max(pipe.spanMax, spanMax);\n return pipe;\n };\n\n // Direct port-for-side helper. Used by Step 6.2's sibling side-split\n // reassignment so the main routing loop can honor a side that does\n // not match `getOrthogonalPort`'s natural choice.\n const portForSide = (node: MermaidNode, side: OrthogonalSide): Point => {\n const w = node.width ?? 10;\n const h = node.height ?? 10;\n const cx = node.x ?? 0;\n const cy = node.y ?? 0;\n switch (side) {\n case 'top':\n return { x: cx, y: cy - h / 2 };\n case 'bottom':\n return { x: cx, y: cy + h / 2 };\n case 'left':\n return { x: cx - w / 2, y: cy };\n case 'right':\n return { x: cx + w / 2, y: cy };\n }\n };\n\n /**\n * Get orthogonal port point - returns the CENTER of a cardinal side (left/right/top/bottom).\n * This ensures the edge starts/ends with a purely horizontal or vertical segment.\n *\n * @param node - The node to get the port from\n * @param target - The target point (used to determine which side)\n * @param isSource - Whether this is the source node (affects side selection for same-row/column cases)\n */\n const getOrthogonalPort = (node: MermaidNode, target: Point, isSource: boolean): Point =>\n portForSide(node, chooseOrthogonalSide(node, target, isSource ? 'bottom' : 'top'));\n\n // Global list of all routed segments for crossing reduction\n const allRoutedSegments: RoutedSegment[] = [];\n const edgeSegmentIndices: number[][] = []; // edgeIndex -> [routedSegmentIndex, ...]\n // Centered straight-line fast-path edges should keep their pipe coord.\n const straightIntraLaneEdges = new Set<number>();\n const CROSSING_PENALTY = 1000;\n\n const crossingPenalty = (edgeIdx: number, from: Point, to: Point): number => {\n if (allRoutedSegments.length === 0) {\n return 0;\n }\n const isHorizontal = Math.abs(from.y - to.y) < EPS;\n const isVertical = Math.abs(from.x - to.x) < EPS;\n if (!isHorizontal && !isVertical) {\n return 0;\n }\n\n let penalties = 0;\n if (isHorizontal) {\n const y = from.y;\n const minX = Math.min(from.x, to.x) - EPS;\n const maxX = Math.max(from.x, to.x) + EPS;\n if (maxX <= minX) {\n return 0;\n }\n for (const seg of allRoutedSegments) {\n if (seg.edgeIndex === edgeIdx || seg.orientation !== 'vertical') {\n continue;\n }\n if (seg.pipe.coord < minX || seg.pipe.coord > maxX) {\n continue;\n }\n if (seg.from - EPS <= y && seg.to + EPS >= y) {\n penalties += CROSSING_PENALTY;\n }\n }\n } else if (isVertical) {\n const x = from.x;\n const minY = Math.min(from.y, to.y) - EPS;\n const maxY = Math.max(from.y, to.y) + EPS;\n if (maxY <= minY) {\n return 0;\n }\n for (const seg of allRoutedSegments) {\n if (seg.edgeIndex === edgeIdx || seg.orientation !== 'horizontal') {\n continue;\n }\n if (seg.pipe.coord < minY || seg.pipe.coord > maxY) {\n continue;\n }\n if (seg.from - EPS <= x && seg.to + EPS >= x) {\n penalties += CROSSING_PENALTY;\n }\n }\n }\n return penalties;\n };\n\n // -----------------------------------------------------------------------\n // Phase 1: Initial Routing\n // -----------------------------------------------------------------------\n const routingOrder = edges\n .map((edge, idx) => {\n if (!edge.start || !edge.end) {\n return { idx, crossLane: 0, dx: 0, dy: 0 };\n }\n const srcNode = nodeById.get(edge.start);\n const dstNode = nodeById.get(edge.end);\n const srcLane = laneByNodeId.get(edge.start);\n const dstLane = laneByNodeId.get(edge.end);\n const crossLane = srcLane && dstLane && srcLane.id !== dstLane.id ? 1 : 0;\n const dx = srcNode && dstNode ? Math.abs((dstNode.x ?? 0) - (srcNode.x ?? 0)) : 0;\n const dy = srcNode && dstNode ? Math.abs((dstNode.y ?? 0) - (srcNode.y ?? 0)) : 0;\n return { idx, crossLane, dx, dy };\n })\n .sort((a, b) => {\n // Route cross-lane edges FIRST so they claim their preferred straight\n // path before flexible intra-lane detours can block them. Intra-lane\n // edges then adapt via the backward-looking CROSSING_PENALTY \u2014 a\n // cheap U-detour around an obstacle is strictly better than a\n // sequential-A* pathology where the cross-lane edge gets forced\n // through a crossing it can no longer avoid.\n // Paper backing: Walk on the Wild Side (LIPIcs.GD.2025.35) \u2014 bend-\n // minimization dominates crossing-minimization when crossings are\n // orthogonal; Wybrow et al. Orthogonal Connector Routing \u2014 crossing\n // penalty is only effective against already-routed edges.\n if (a.crossLane !== b.crossLane) {\n return b.crossLane - a.crossLane;\n }\n // Shorter edges first \u2014 they need less room to maneuver\n const aDist = a.dx + a.dy;\n const bDist = b.dx + b.dy;\n if (Math.abs(aDist - bDist) > 1) {\n return aDist - bDist;\n }\n return a.idx - b.idx;\n })\n .map((entry) => entry.idx);\n\n // Helper to check if a segment is blocked by any obstacle.\n // excludeStart and excludeEnd are node IDs to exclude from obstacle checking.\n const isSegmentBlocked = (p1: Point, p2: Point, excludeStart?: string, excludeEnd?: string) => {\n const segMinX = Math.min(p1.x, p2.x);\n const segMaxX = Math.max(p1.x, p2.x);\n const segMinY = Math.min(p1.y, p2.y);\n const segMaxY = Math.max(p1.y, p2.y);\n\n const blockingObs = obstacles.find((obs) => {\n if (excludeStart && obs.nodeId === excludeStart) {\n return false;\n }\n if (excludeEnd && obs.nodeId === excludeEnd) {\n return false;\n }\n if (Math.abs(p1.x - p2.x) > EPS) {\n // Horizontal segment\n return obs.minY < p1.y && obs.maxY > p1.y && obs.maxX > segMinX && obs.minX < segMaxX;\n } else {\n // Vertical segment\n return obs.minX < p1.x && obs.maxX > p1.x && obs.maxY > segMinY && obs.minY < segMaxY;\n }\n });\n\n return !!blockingObs;\n };\n\n // ---- Step 6: Port pre-assignment ----\n // When multiple edges connect to the same side of a node, distribute their\n // ports across that side and order them by source/target coordinate to\n // prevent crossings at the node boundary.\n //\n // Key: \"nodeId:side:role\" where side is 'top'|'bottom'|'left'|'right'\n // and role is 'src' (edge leaves this node) or 'dst' (edge arrives here).\n // Value: list of { edgeIdx, oppositeCoord } sorted by oppositeCoord.\n const portGroups = new Map<string, { edgeIdx: number; oppositeCoord: number }[]>();\n const incidentEdgeTotals = new Map<string, number>();\n for (const edge of edges) {\n if (!edge.start || !edge.end || edge.start === edge.end) {\n continue;\n }\n incidentEdgeTotals.set(edge.start, (incidentEdgeTotals.get(edge.start) ?? 0) + 1);\n incidentEdgeTotals.set(edge.end, (incidentEdgeTotals.get(edge.end) ?? 0) + 1);\n }\n\n // First pass: determine which side each edge connects to on each node\n const determineSide = (node: MermaidNode, target: Point): OrthogonalSide =>\n chooseOrthogonalSide(node, target, 'bottom');\n\n // ----- Step 6.1: compute initial sides for every edge ---------------\n //\n // We run determineSide up-front for both endpoints of every edge so the\n // sibling side-splitting pass (6.2) can see the full picture before the\n // port-group build (6.3) locks each edge into a side.\n type SideT = 'top' | 'bottom' | 'left' | 'right';\n interface EdgeSideInfo {\n edgeIdx: number;\n srcId: string;\n dstId: string;\n srcSide: SideT;\n dstSide: SideT;\n absDx: number;\n absDy: number;\n dxSign: number;\n dySign: number;\n }\n const sideInfoByIdx = new Map<number, EdgeSideInfo>();\n for (const [i, e] of edges.entries()) {\n if (!e.start || !e.end || e.start === e.end) {\n continue;\n }\n if (e.points && e.points.length > 0) {\n continue;\n }\n const src = nodeById.get(e.start);\n const dst = nodeById.get(e.end);\n if (!src || !dst) {\n continue;\n }\n const dx = (dst.x ?? 0) - (src.x ?? 0);\n const dy = (dst.y ?? 0) - (src.y ?? 0);\n sideInfoByIdx.set(i, {\n edgeIdx: i,\n srcId: e.start,\n dstId: e.end,\n srcSide: determineSide(src, { x: dst.x ?? 0, y: dst.y ?? 0 }),\n dstSide: determineSide(dst, { x: src.x ?? 0, y: src.y ?? 0 }),\n absDx: Math.abs(dx),\n absDy: Math.abs(dy),\n dxSign: Math.sign(dx),\n dySign: Math.sign(dy),\n });\n }\n\n // ----- Step 6.2: sibling side-splitting (diss.pdf \u00A76.1.2.2) ---------\n //\n // Paper-backed \u03B4_s load-balancing rule: when two or more edges leave a\n // source node from the same side, reassign the ones with the *weaker*\n // preference-strength to their secondary side, naturally distributing\n // them across multiple sides of the node. Preference-strength combines\n // source and destination side-load (the paper sums \u03B4_s over both\n // endpoints). With edge-id tiebreak for determinism when 3+ edges tie.\n //\n // Sequencing note (critical, per Algorithm Expert review): this pass\n // MUST run before the port-group build (6.3), anchor computation\n // (Step 7), and any later port-sensitive post-processing. Changing a side\n // later would corrupt E_{v,s} membership without updating downstream sort keys.\n //\n // \"Preference strength\" = the dy/dx ratio (for vertically-preferred\n // edges) or dx/dy ratio (for horizontally-preferred) \u2014 higher ratio\n // means more dominant in the current side's axis.\n const preferenceStrength = (info: EdgeSideInfo): number => {\n if (info.srcSide === 'top' || info.srcSide === 'bottom') {\n return info.absDx === 0 ? Infinity : info.absDy / info.absDx;\n }\n return info.absDy === 0 ? Infinity : info.absDx / info.absDy;\n };\n const secondarySide = (info: EdgeSideInfo): SideT => {\n if (info.srcSide === 'top' || info.srcSide === 'bottom') {\n return info.dxSign >= 0 ? 'right' : 'left';\n }\n return info.dySign >= 0 ? 'bottom' : 'top';\n };\n\n // Group by (src, srcSide) so we can detect 2+ edges sharing a side.\n const sourceSideGroups = new Map<string, EdgeSideInfo[]>();\n for (const info of sideInfoByIdx.values()) {\n const key = `${info.srcId}:${info.srcSide}`;\n if (!sourceSideGroups.has(key)) {\n sourceSideGroups.set(key, []);\n }\n sourceSideGroups.get(key)!.push(info);\n }\n\n // Running side-load counters for every (nodeId, side) to implement\n // \u03B4_s. Bumped every time an edge is committed to a side as its src or\n // dst. The paper's rule compares (\u03B4_src + \u03B4_dst) across candidate\n // routes; we use this counter to tiebreak between primary and\n // secondary sides when the strength-sort leaves two candidates equally\n // attractive.\n const sideLoad = new Map<string, number>();\n const loadKey = (nodeId: string, side: SideT): string => `${nodeId}:${side}`;\n for (const info of sideInfoByIdx.values()) {\n sideLoad.set(\n loadKey(info.srcId, info.srcSide),\n (sideLoad.get(loadKey(info.srcId, info.srcSide)) ?? 0) + 1\n );\n sideLoad.set(\n loadKey(info.dstId, info.dstSide),\n (sideLoad.get(loadKey(info.dstId, info.dstSide)) ?? 0) + 1\n );\n }\n\n for (const group of sourceSideGroups.values()) {\n if (group.length < 2) {\n continue;\n }\n // Sort by preference strength DESCENDING \u2014 strongest first.\n // The strongest sibling keeps its preferred side; each subsequent\n // (weaker) sibling is considered for reassignment to its secondary\n // side. Tiebreak on edgeIdx for deterministic 3+-sibling cases.\n //\n // Paper-backed rationale (diss.pdf \u00A76.1.2.2): when multiple edges\n // contend for the same side, preserving the strongest preference\n // minimizes the aggregate cost of deviation. The \u03B4_s counter\n // breaks ties and prevents ping-ponging when secondary sides are\n // already loaded.\n group.sort((a, b) => {\n const sa = preferenceStrength(a);\n const sb = preferenceStrength(b);\n if (Math.abs(sa - sb) > 1e-9) {\n return sb - sa;\n }\n return a.edgeIdx - b.edgeIdx;\n });\n // Each sibling except the first (strongest) is considered for\n // reassignment to its secondary side, bumping \u03B4_s counters as we go.\n for (let g = 1; g < group.length; g++) {\n const info = group[g];\n const secondary = secondarySide(info);\n const primaryLoad = sideLoad.get(loadKey(info.srcId, info.srcSide)) ?? 0;\n const secondaryLoad = sideLoad.get(loadKey(info.srcId, secondary)) ?? 0;\n // Only move to the secondary side if it's strictly less loaded\n // than the primary (avoids ping-ponging when both sides are\n // equally crowded \u2014 the paper's \u03B4_s rule picks whichever sum is\n // smaller, and equal sums default to the original assignment).\n if (secondaryLoad >= primaryLoad) {\n continue;\n }\n // Update counters and the side assignment.\n sideLoad.set(loadKey(info.srcId, info.srcSide), primaryLoad - 1);\n sideLoad.set(loadKey(info.srcId, secondary), secondaryLoad + 1);\n info.srcSide = secondary;\n }\n }\n\n // ----- Step 6.2b: bimodal in/out de-collision for diamond nodes -----\n //\n // Paper backing: the BIMODAL drawing constraint (Eiglsperger, \"Orthogonal\n // Graph Drawing with Constraints\" \u00A73.1): a vertex's incoming and outgoing\n // edges should occupy separate, non-intersecting intervals of its circular\n // edge order \u2014 in practice, distinct sides. Step 6.2 only load-balances\n // same-role siblings (multiple out-edges from one side), so an out-edge can\n // still land on the very side an in-edge already uses. On a diamond each\n // side collapses to a single pin at the vertex (6.3 gives diamonds only a\n // 0.3\u00B7side port span), so an in-edge and an out-edge sharing a side resolve\n // to the SAME pin \u2014 the detached-stub \"shared projected port\" defect\n // (validateLayout: edge-shared-projected-port). Move the out-edge to its\n // free secondary side to restore bimodality. Scoped to diamonds so\n // rectangles \u2014 whose long sides hold multiple distinct pins \u2014 are untouched.\n const isDiamondNode = (node: MermaidNode | undefined): boolean => {\n const shape = (node as { shape?: string } | undefined)?.shape;\n return shape === 'question' || shape === 'diamond';\n };\n const inSidesByNode = new Map<string, Set<SideT>>();\n for (const info of sideInfoByIdx.values()) {\n if (!inSidesByNode.has(info.dstId)) {\n inSidesByNode.set(info.dstId, new Set());\n }\n inSidesByNode.get(info.dstId)!.add(info.dstSide);\n }\n for (const info of sideInfoByIdx.values()) {\n if (!isDiamondNode(nodeById.get(info.srcId))) {\n continue;\n }\n const inSides = inSidesByNode.get(info.srcId);\n if (!inSides?.has(info.srcSide)) {\n continue; // no in-edge shares this out-edge's side \u2192 no bimodal clash\n }\n const secondary = secondarySide(info);\n // Only move to a side that no in-edge uses and that carries no committed\n // load \u2014 keeps the change surgical and never creates a new collision.\n if (inSides.has(secondary) || (sideLoad.get(loadKey(info.srcId, secondary)) ?? 0) > 0) {\n continue;\n }\n const primaryLoad = sideLoad.get(loadKey(info.srcId, info.srcSide)) ?? 0;\n sideLoad.set(loadKey(info.srcId, info.srcSide), Math.max(0, primaryLoad - 1));\n sideLoad.set(loadKey(info.srcId, secondary), 1);\n info.srcSide = secondary;\n }\n\n // ----- Step 6.3: port-group build (uses possibly-reassigned sides) --\n for (const info of sideInfoByIdx.values()) {\n const { edgeIdx: i, srcId, dstId, srcSide, dstSide } = info;\n const src = nodeById.get(srcId)!;\n const dst = nodeById.get(dstId)!;\n\n const srcKey = `${srcId}:${srcSide}:src`;\n const dstCoord = srcSide === 'top' || srcSide === 'bottom' ? (dst.x ?? 0) : (dst.y ?? 0);\n if (!portGroups.has(srcKey)) {\n portGroups.set(srcKey, []);\n }\n portGroups.get(srcKey)!.push({ edgeIdx: i, oppositeCoord: dstCoord });\n\n const dstKey = `${dstId}:${dstSide}:dst`;\n const srcCoord = dstSide === 'top' || dstSide === 'bottom' ? (src.x ?? 0) : (src.y ?? 0);\n if (!portGroups.has(dstKey)) {\n portGroups.set(dstKey, []);\n }\n portGroups.get(dstKey)!.push({ edgeIdx: i, oppositeCoord: srcCoord });\n }\n\n // Now compute port offsets for each group with 2+ edges\n // Key: \"edgeIdx:src\" or \"edgeIdx:dst\" \u2192 port offset from center\n const portOffsets = new Map<string, number>();\n const MIN_PORT_SPACING = 8; // minimum pixels between adjacent ports\n\n for (const [key, group] of portGroups) {\n if (group.length < 2) {\n continue;\n }\n // Sort by opposite coordinate (ascending)\n group.sort((a, b) => a.oppositeCoord - b.oppositeCoord);\n\n // Parse node ID and side from key\n const parts = key.split(':');\n const nodeId = parts.slice(0, -2).join(':'); // handle IDs with colons\n const side = parts[parts.length - 2];\n const role = parts[parts.length - 1]; // 'src' or 'dst'\n const node = nodeById.get(nodeId);\n if (!node) {\n continue;\n }\n\n // Determine available span along the side.\n // For diamond/rhombus shapes, the effective port area on pointy sides is\n // much smaller than the bounding box \u2014 use a fraction of the side length.\n const isVerticalSide = side === 'left' || side === 'right';\n const sideLength = isVerticalSide ? (node.height ?? 10) : (node.width ?? 10);\n const shape = (node as { shape?: string }).shape;\n const isDiamond = shape === 'question' || shape === 'diamond';\n const effectiveLength = isDiamond ? sideLength * 0.3 : sideLength;\n const MAX_PORT_SPACING = 20; // cap spacing to avoid large detours\n\n // Distribute ports evenly, clamped by MIN and MAX\n const spacing = Math.min(\n MAX_PORT_SPACING,\n Math.max(MIN_PORT_SPACING, effectiveLength / (group.length + 1))\n );\n const totalSpan = spacing * (group.length - 1);\n const startOffset = -totalSpan / 2;\n\n for (const [j, element] of group.entries()) {\n const offset = startOffset + j * spacing;\n const offsetKey = `${element.edgeIdx}:${role}`;\n portOffsets.set(offsetKey, offset);\n }\n }\n\n const edgeHasLabelNode = (edgeIdx: number): boolean =>\n Boolean((edges[edgeIdx] as { labelNodeId?: string } | undefined)?.labelNodeId);\n\n const faceHasLabelNode = (nodeId: string | undefined, side: SideT): boolean => {\n if (!nodeId) {\n return false;\n }\n return (\n (portGroups.get(`${nodeId}:${side}:src`) ?? []).some(({ edgeIdx }) =>\n edgeHasLabelNode(edgeIdx)\n ) ||\n (portGroups.get(`${nodeId}:${side}:dst`) ?? []).some(({ edgeIdx }) =>\n edgeHasLabelNode(edgeIdx)\n )\n );\n };\n\n // Helper to apply port offset to a base center port\n const applyPortOffset = (\n basePort: Point,\n side: 'top' | 'bottom' | 'left' | 'right',\n offset: number\n ): Point => {\n if (side === 'top' || side === 'bottom') {\n // Offset along X axis\n return { x: basePort.x + offset, y: basePort.y };\n } else {\n // Offset along Y axis\n return { x: basePort.x, y: basePort.y + offset };\n }\n };\n\n const portsForEdge = (edgeIndex: number, src: MermaidNode, dst: MermaidNode) => {\n const sideInfo = sideInfoByIdx.get(edgeIndex);\n const srcTarget = { x: dst.x ?? 0, y: dst.y ?? 0 };\n const dstTarget = { x: src.x ?? 0, y: src.y ?? 0 };\n const srcSide = sideInfo?.srcSide ?? determineSide(src, srcTarget);\n const dstSide = sideInfo?.dstSide ?? determineSide(dst, dstTarget);\n let pSrcPort = sideInfo\n ? portForSide(src, sideInfo.srcSide)\n : getOrthogonalPort(src, srcTarget, true);\n let pDstPort = sideInfo\n ? portForSide(dst, sideInfo.dstSide)\n : getOrthogonalPort(dst, dstTarget, false);\n\n const srcOffset = portOffsets.get(`${edgeIndex}:src`);\n const dstOffset = portOffsets.get(`${edgeIndex}:dst`);\n if (srcOffset !== undefined) {\n pSrcPort = applyPortOffset(pSrcPort, srcSide, srcOffset);\n }\n if (dstOffset !== undefined) {\n pDstPort = applyPortOffset(pDstPort, dstSide, dstOffset);\n }\n return { pSrcPort, pDstPort, srcSide, dstSide };\n };\n\n for (const i of routingOrder) {\n const e = edges[i];\n edgeSegmentIndices[i] = [];\n\n if (!e.start || !e.end) {\n continue;\n }\n if (e.points && e.points.length > 0) {\n continue;\n }\n // Skip self-loops\n if (e.start === e.end) {\n continue;\n }\n\n const src = nodeById.get(e.start);\n const dst = nodeById.get(e.end);\n if (!src || !dst) {\n continue;\n }\n\n // 2. Compute Ports. Use the side assignment from Step 6.2 (sibling\n // side-split) so that a reassigned edge exits from its secondary\n // cardinal side instead of `getOrthogonalPort`'s natural choice.\n const {\n pSrcPort,\n pDstPort,\n srcSide: srcPortSide,\n dstSide: dstPortSide,\n } = portsForEdge(i, src, dst);\n\n // 3. Compute Anchors\n const pSrcAnchor: Point = { ...pSrcPort };\n const pDstAnchor: Point = { ...pDstPort };\n\n // Adjust anchors based on port direction\n // For orthogonal routing, anchors should extend in the same direction as the port\n // (i.e., if port is on bottom, anchor should be below the port)\n\n // Determine if ports are vertical (top/bottom) or horizontal (left/right).\n // Prefer the side from Step 6.2 so that a reassigned sibling gets its\n // anchor extended on the correct axis.\n const srcPortIsVertical = srcPortSide === 'top' || srcPortSide === 'bottom';\n const dstPortIsVertical = dstPortSide === 'top' || dstPortSide === 'bottom';\n\n // Source Anchor - extend from port in the appropriate direction\n if (srcPortIsVertical) {\n // Port is on top or bottom - extend vertically\n const isBottom = pSrcPort.y > (src.y ?? 0);\n pSrcAnchor.y = isBottom ? pSrcPort.y + ANCHOR_OFFSET : pSrcPort.y - ANCHOR_OFFSET;\n } else {\n // Port is on left or right - extend horizontally\n const isRight = pSrcPort.x > (src.x ?? 0);\n pSrcAnchor.x = isRight ? pSrcPort.x + ANCHOR_OFFSET : pSrcPort.x - ANCHOR_OFFSET;\n }\n\n // Target Anchor - extend from port in the appropriate direction\n if (dstPortIsVertical) {\n // Port is on top or bottom - extend vertically\n const isBottom = pDstPort.y > (dst.y ?? 0);\n pDstAnchor.y = isBottom ? pDstPort.y + ANCHOR_OFFSET : pDstPort.y - ANCHOR_OFFSET;\n } else {\n // Port is on left or right - extend horizontally\n const isRight = pDstPort.x > (dst.x ?? 0);\n pDstAnchor.x = isRight ? pDstPort.x + ANCHOR_OFFSET : pDstPort.x - ANCHOR_OFFSET;\n }\n\n // Helper to check if a point is inside any obstacle (excluding src/dst nodes)\n const isPointInObstacle = (\n pt: Point,\n excludeNodeIds: string[]\n ): { inside: boolean; obstacle?: (typeof obstacles)[0] } => {\n for (const obs of obstacles) {\n if (excludeNodeIds.includes(obs.nodeId)) {\n continue;\n }\n if (pt.x > obs.minX && pt.x < obs.maxX && pt.y > obs.minY && pt.y < obs.maxY) {\n return { inside: true, obstacle: obs };\n }\n }\n return { inside: false };\n };\n\n const obstacleDetour = (\n port: Point,\n node: MermaidNode,\n opposite: MermaidNode,\n obs: (typeof obstacles)[0],\n portIsVertical: boolean\n ): { x: number; y: number; leavesPositiveSide: boolean } => {\n if (portIsVertical) {\n const leavesPositiveSide = port.y > (node.y ?? 0);\n const goRight = (opposite.x ?? 0) >= port.x;\n return {\n x: goRight ? obs.maxX + HORIZONTAL_PIPE_MARGIN : obs.minX - HORIZONTAL_PIPE_MARGIN,\n y: leavesPositiveSide ? obs.maxY + VERTICAL_PIPE_MARGIN : obs.minY - VERTICAL_PIPE_MARGIN,\n leavesPositiveSide,\n };\n }\n\n const leavesPositiveSide = port.x > (node.x ?? 0);\n const goDown = (opposite.y ?? 0) >= port.y;\n return {\n x: leavesPositiveSide\n ? obs.maxX + HORIZONTAL_PIPE_MARGIN\n : obs.minX - HORIZONTAL_PIPE_MARGIN,\n y: goDown ? obs.maxY + VERTICAL_PIPE_MARGIN : obs.minY - VERTICAL_PIPE_MARGIN,\n leavesPositiveSide,\n };\n };\n\n // Push source anchor out if it's inside an obstacle\n // This happens when the node below the source is too close\n // When pushed, we also compute waypoints to route around the obstacle\n //\n // CRITICAL: The waypoints must be structured so that the FIRST point after the port\n // is in the orthogonal direction (same x for vertical port, same y for horizontal port).\n // This is because insertEdge calls tail.intersect(firstInnerPoint), and if firstInnerPoint\n // is not aligned orthogonally, it will produce a diagonal intersection instead of the\n // orthogonal port we computed.\n let srcHandleWaypoints: Point[] = [];\n const endpointIds = [e.start, e.end];\n const srcCheck = isPointInObstacle(pSrcAnchor, endpointIds);\n if (srcCheck.inside && srcCheck.obstacle) {\n const obs = srcCheck.obstacle;\n if (srcPortIsVertical) {\n // Vertical port (top/bottom) - need to route around the obstacle horizontally\n const detour = obstacleDetour(pSrcPort, src, dst, obs, true);\n\n pSrcAnchor.x = detour.x;\n pSrcAnchor.y = detour.y;\n\n // Strategy: go sideways FIRST to clear the obstacle's x-range, then go down.\n // But we need the FIRST point after port to be orthogonal for insertEdge.\n //\n // Compute a small orthogonal step in the gap between the source node and obstacle:\n // - For bottom port going down: step to just before the obstacle's top\n // - This creates an orthogonal segment that insertEdge will preserve\n const gapY = detour.leavesPositiveSide\n ? Math.min(obs.minY - 2, pSrcPort.y + ANCHOR_OFFSET) // Just before obstacle\n : Math.max(obs.maxY + 2, pSrcPort.y - ANCHOR_OFFSET); // Just after obstacle\n\n // Waypoints:\n // 1. Small orthogonal step (same X, slightly toward obstacle) - for insertEdge\n // 2. Horizontal detour to clear obstacle's X range\n // 3. Vertical to clearance Y (past obstacle)\n srcHandleWaypoints = [\n { x: pSrcPort.x, y: gapY }, // Orthogonal step in the gap\n { x: detour.x, y: gapY }, // Horizontal detour\n { x: detour.x, y: detour.y }, // Down past obstacle\n ];\n } else {\n // Horizontal port (left/right) - route around vertically\n const detour = obstacleDetour(pSrcPort, src, dst, obs, false);\n\n const gapX = detour.leavesPositiveSide\n ? Math.min(obs.minX - 2, pSrcPort.x + ANCHOR_OFFSET)\n : Math.max(obs.maxX + 2, pSrcPort.x - ANCHOR_OFFSET);\n\n pSrcAnchor.x = detour.x;\n pSrcAnchor.y = detour.y;\n\n srcHandleWaypoints = [\n { x: gapX, y: pSrcPort.y }, // Orthogonal step in the gap\n { x: gapX, y: detour.y }, // Vertical detour\n { x: detour.x, y: detour.y }, // Horizontal past obstacle\n ];\n }\n }\n\n // Push destination anchor out if it's inside an obstacle\n // Same logic as source: ensure orthogonal waypoints for proper intersection\n let dstHandleWaypoints: Point[] = [];\n const dstCheck = isPointInObstacle(pDstAnchor, endpointIds);\n if (dstCheck.inside && dstCheck.obstacle) {\n const obs = dstCheck.obstacle;\n if (dstPortIsVertical) {\n const detour = obstacleDetour(pDstPort, dst, src, obs, true);\n\n pDstAnchor.x = detour.x;\n pDstAnchor.y = detour.y;\n\n // Waypoints: from anchor -> sideways -> orthogonally to port\n // The LAST waypoint before port MUST have same X as port for orthogonal intersection\n dstHandleWaypoints = [\n { x: detour.x, y: detour.y }, // From anchor position\n { x: pDstPort.x, y: detour.y }, // Go sideways to port's X\n // Then orthogonally to port\n ];\n } else {\n const detour = obstacleDetour(pDstPort, dst, src, obs, false);\n\n pDstAnchor.x = detour.x;\n pDstAnchor.y = detour.y;\n\n dstHandleWaypoints = [\n { x: detour.x, y: detour.y }, // From anchor position\n { x: detour.x, y: pDstPort.y }, // Go vertically to port's Y\n ];\n }\n }\n\n // ----- Centered straight-line fast path (Kandinsky \u00A72, diss.pdf 0fb2d84f) --\n //\n // When the two port sides face each other and the anchor-to-anchor\n // segment is already axis-aligned (both at the same x or the same y),\n // emit the straight port-to-port polyline directly if no foreign\n // obstacle blocks it. This realizes the Kandinsky centered-straight-\n // line invariant: *straight-line edges are centered at the\n // corresponding vertex side* \u2014 the ports already sit at the face\n // centers returned by `portForSide`, so there is nothing to compute.\n //\n // This generalized path captures the same optimisation for any edge\n // whose face-center ports are aligned, regardless of label semantics.\n //\n // Conditions:\n // 1. No obstacle-avoidance waypoints were injected (pSrcAnchor /\n // pDstAnchor stayed at their face-center extensions).\n // 2. The anchors share one coordinate axis within the pipe margin.\n // 3. The edge is not part of a distributed port group (port offsets\n // would shift the face-center port and break centering).\n // 4. Either the endpoint faces are uncontested, or every contested\n // endpoint is a degree-2 chain node. The latter is allowed so a\n // genuinely collinear connector keeps the Kandinsky centered-\n // straight invariant; the rendered terminal-lane splitter can then\n // move the other incident lane instead of introducing a bend here.\n // Higher-degree nodes still fall back to normal track assignment,\n // because preserving one center port there can force short near-node\n // bands on another incident edge.\n // 5. The port-to-port direct segment is obstacle-free.\n //\n // When these hold, set e.points directly and skip the rest of the\n // routing loop body. Phase 2/3 (track assignment, point emission)\n // both skip edges with empty `edgeSegmentIndices[i]`, so the\n // straight polyline survives unchanged to the final output.\n //\n // For aligned-column back-edges (e.g. L_J_E_0 in 7-car-sales-constr\n // where J and E share TB x=392), the transform maps the LR-straight\n // horizontal to a TB-straight vertical, and the final endpoint clip\n // pass in postProcessing.ts snaps each endpoint to the facing side\n // center (J.top-center, E.bottom-center) \u2014 resolving the\n // `edge-corner-connection` pathology where the prior 5-point U-detour\n // landed endpoints 0.67\u20133u from a node corner.\n if (srcHandleWaypoints.length === 0 && dstHandleWaypoints.length === 0) {\n const hpMargin = HORIZONTAL_PIPE_MARGIN;\n const anchorsSameX = Math.abs(pSrcAnchor.x - pDstAnchor.x) < hpMargin;\n const anchorsSameY = Math.abs(pSrcAnchor.y - pDstAnchor.y) < hpMargin;\n const hasPortOffset =\n portOffsets.get(`${i}:src`) !== undefined || portOffsets.get(`${i}:dst`) !== undefined;\n // Count total edges (any role) attaching at each facing side.\n // >1 means the face is contested \u2014 skip the fast path so the\n // normal track-assignment logic can spread attach points.\n const srcFaceTotal =\n (portGroups.get(`${e.start ?? ''}:${srcPortSide}:src`)?.length ?? 0) +\n (portGroups.get(`${e.start ?? ''}:${srcPortSide}:dst`)?.length ?? 0);\n const dstFaceTotal =\n (portGroups.get(`${e.end ?? ''}:${dstPortSide}:src`)?.length ?? 0) +\n (portGroups.get(`${e.end ?? ''}:${dstPortSide}:dst`)?.length ?? 0);\n const faceContested = srcFaceTotal > 1 || dstFaceTotal > 1;\n const srcIncidentTotal = incidentEdgeTotals.get(e.start ?? '') ?? 0;\n const dstIncidentTotal = incidentEdgeTotals.get(e.end ?? '') ?? 0;\n const contestedFaceHasLabel =\n (srcFaceTotal > 1 && faceHasLabelNode(e.start, srcPortSide)) ||\n (dstFaceTotal > 1 && faceHasLabelNode(e.end, dstPortSide));\n const srcContestAllowsCenteredStraight = srcFaceTotal <= 1 || srcIncidentTotal <= 2;\n const dstContestAllowsCenteredStraight = dstFaceTotal <= 1 || dstIncidentTotal <= 2;\n const canPreserveSimpleContestedStraight =\n faceContested &&\n !contestedFaceHasLabel &&\n srcContestAllowsCenteredStraight &&\n dstContestAllowsCenteredStraight;\n if (\n (anchorsSameX || anchorsSameY) &&\n !hasPortOffset &&\n (!faceContested || canPreserveSimpleContestedStraight)\n ) {\n const directBlocked = isSegmentBlocked(pSrcPort, pDstPort, e.start, e.end);\n if (!directBlocked) {\n // Emit the canonical `port \u2192 anchor \u2192 anchor \u2192 port` 4-point\n // shape. Because all four points are collinear along the\n // shared axis, postProcessing.ts's `simplifyPolyline` collapses it\n // to a clean 2-point straight line downstream, and the\n // endpoint-clip pass snaps the port endpoints onto the\n // facing node side centers. Keeping the 4-point form here\n // preserves the long-standing raykov contract that a\n // straight-line edge's `e.points` includes the anchor\n // extensions, which several unit tests pin.\n e.points = [{ ...pSrcPort }, { ...pSrcAnchor }, { ...pDstAnchor }, { ...pDstPort }];\n straightIntraLaneEdges.add(i);\n // Register the fast-path's full port\u2192port line as a routed\n // segment so later A* searches can see it via crossingPenalty.\n // Without this, iter 8's fast path is invisible to the\n // CROSSING_PENALTY check in the A* loop and later intra-lane\n // detours (e.g. L_D_E_0 detouring around a shared-column node)\n // pick crossings they should be able to avoid. We intentionally\n // do NOT add this index to edgeSegmentIndices[i] \u2014 phase 2/3\n // track-assignment must keep skipping fast-path edges so their\n // centered straight shape is preserved.\n const fastPathOrientation: Orientation = anchorsSameY ? 'horizontal' : 'vertical';\n const fastPathCoord = anchorsSameY ? pSrcPort.y : pSrcPort.x;\n const fastPathFrom = anchorsSameY\n ? Math.min(pSrcPort.x, pDstPort.x)\n : Math.min(pSrcPort.y, pDstPort.y);\n const fastPathTo = anchorsSameY\n ? Math.max(pSrcPort.x, pDstPort.x)\n : Math.max(pSrcPort.y, pDstPort.y);\n const fastPathPipe: Pipe = {\n id: `fast-path-${fastPathOrientation}-${fastPathCoord.toFixed(0)}-${i}`,\n orientation: fastPathOrientation,\n coord: fastPathCoord,\n spanMin: fastPathFrom,\n spanMax: fastPathTo,\n tracks: [],\n };\n allRoutedSegments.push({\n edgeIndex: i,\n segmentIndex: 0,\n orientation: fastPathOrientation,\n pipe: fastPathPipe,\n trackIndex: 0,\n from: fastPathFrom,\n to: fastPathTo,\n });\n continue;\n }\n }\n }\n\n // Snap anchors to nearest pipe (create lazily).\n const srcPipe = getOrAddPipe('vertical', pSrcAnchor.x, pSrcAnchor.y, pSrcAnchor.y);\n pSrcAnchor.x = srcPipe.coord;\n const dstPipe = getOrAddPipe('vertical', pDstAnchor.x, pDstAnchor.y, pDstAnchor.y);\n pDstAnchor.x = dstPipe.coord;\n\n // 4. Build Visibility Graph & Pathfinding\n // Bounding box - start with anchor points\n let bbMinX = Math.min(pSrcAnchor.x, pDstAnchor.x) - 50;\n let bbMaxX = Math.max(pSrcAnchor.x, pDstAnchor.x) + 50;\n let bbMinY = Math.min(pSrcAnchor.y, pDstAnchor.y) - 50;\n let bbMaxY = Math.max(pSrcAnchor.y, pDstAnchor.y) + 50;\n\n // Expand bounding box to include detour routes around any obstacles that block the direct path\n for (const obs of obstacles) {\n // Check if obstacle is in the way (overlaps with the direct path corridor)\n const pathMinX = Math.min(pSrcAnchor.x, pDstAnchor.x);\n const pathMaxX = Math.max(pSrcAnchor.x, pDstAnchor.x);\n const pathMinY = Math.min(pSrcAnchor.y, pDstAnchor.y);\n const pathMaxY = Math.max(pSrcAnchor.y, pDstAnchor.y);\n\n const obsBlocksPath =\n obs.minX < pathMaxX && obs.maxX > pathMinX && obs.minY < pathMaxY && obs.maxY > pathMinY;\n\n if (obsBlocksPath) {\n // Expand bbox to include space for routing around this obstacle\n bbMinX = Math.min(bbMinX, obs.minX - ROUTING_MARGIN);\n bbMaxX = Math.max(bbMaxX, obs.maxX + ROUTING_MARGIN);\n bbMinY = Math.min(bbMinY, obs.minY - ROUTING_MARGIN);\n bbMaxY = Math.max(bbMaxY, obs.maxY + ROUTING_MARGIN);\n }\n }\n\n // Add pipe grid lines around obstacles\n for (const obs of obstacles) {\n // Check if obstacle is relevant to this edge's bounding box\n if (obs.maxX < bbMinX || obs.minX > bbMaxX || obs.maxY < bbMinY || obs.minY > bbMaxY) {\n continue;\n }\n // Add horizontal pipes around obstacle - ONLY at safe zone positions (with margins)\n // Do NOT create pipes at exact boundaries - that allows edges to hug nodes\n const hMargin = HORIZONTAL_PIPE_MARGIN;\n getOrAddPipe('horizontal', obs.minY - hMargin, bbMinX, bbMaxX); // Above obstacle (safe zone)\n getOrAddPipe('horizontal', obs.maxY + hMargin, bbMinX, bbMaxX); // Below obstacle (safe zone)\n\n // Add vertical pipes around obstacle - ONLY at safe zone positions (with margins)\n const vMargin = VERTICAL_PIPE_MARGIN;\n getOrAddPipe('vertical', obs.minX - vMargin, bbMinY, bbMaxY); // Left of obstacle (safe zone)\n getOrAddPipe('vertical', obs.maxX + vMargin, bbMinY, bbMaxY); // Right of obstacle (safe zone)\n }\n\n // Ensure start/end horizontal pipes exist\n getOrAddPipe('horizontal', pSrcAnchor.y, bbMinX, bbMaxX);\n getOrAddPipe('horizontal', pDstAnchor.y, bbMinX, bbMaxX);\n\n // Collect relevant pipes\n const hPipes = pipes.filter(\n (p) => p.orientation === 'horizontal' && p.coord >= bbMinY && p.coord <= bbMaxY\n );\n const vPipes = pipes.filter(\n (p) => p.orientation === 'vertical' && p.coord >= bbMinX && p.coord <= bbMaxX\n );\n\n // Vertices: All intersections of hPipes and vPipes\n // We run A* on these vertices.\n\n const getKey = (x: number, y: number) => `${x.toFixed(1)},${y.toFixed(1)}`;\n const startKey = getKey(pSrcAnchor.x, pSrcAnchor.y);\n const endKey = getKey(pDstAnchor.x, pDstAnchor.y);\n\n // A* Data Structures\n const gScore = new Map<string, number>();\n const cameFrom = new Map<string, Point>();\n // Track the direction we arrived at each node from: 'h' = horizontal, 'v' = vertical, 'n' = start (none)\n const arrivalDir = new Map<string, 'h' | 'v' | 'n'>();\n const openSet = new Set<string>();\n const openList: { key: string; f: number; pt: Point }[] = [];\n\n gScore.set(startKey, 0);\n arrivalDir.set(startKey, 'n'); // start has no arrival direction\n openList.push({\n key: startKey,\n f: Math.hypot(pDstAnchor.x - pSrcAnchor.x, pDstAnchor.y - pSrcAnchor.y),\n pt: pSrcAnchor,\n });\n openSet.add(startKey);\n\n let foundPath: Point[] = [];\n\n // Helper to check if a segment is blocked for this edge (excluding src/dst)\n const checkSegmentBlocked = (p1: Point, p2: Point): boolean => {\n return isSegmentBlocked(p1, p2, e.start, e.end);\n };\n\n // Try direct L-shaped paths first (much simpler than A*)\n // Option 1: Go horizontal first, then vertical\n const cornerHV: Point = { x: pDstAnchor.x, y: pSrcAnchor.y };\n const seg1HV_blocked = checkSegmentBlocked(pSrcAnchor, cornerHV);\n const seg2HV_blocked = checkSegmentBlocked(cornerHV, pDstAnchor);\n const pathHV_blocked = seg1HV_blocked || seg2HV_blocked;\n\n // Option 2: Go vertical first, then horizontal\n const cornerVH: Point = { x: pSrcAnchor.x, y: pDstAnchor.y };\n const seg1VH_blocked = checkSegmentBlocked(pSrcAnchor, cornerVH);\n const seg2VH_blocked = checkSegmentBlocked(cornerVH, pDstAnchor);\n const pathVH_blocked = seg1VH_blocked || seg2VH_blocked;\n\n if (!pathHV_blocked) {\n // Use horizontal-first L-path\n if (\n Math.abs(pSrcAnchor.y - pDstAnchor.y) < EPS ||\n Math.abs(pSrcAnchor.x - pDstAnchor.x) < EPS\n ) {\n // Same Y or same X - straight line (corner would be a duplicate point)\n foundPath = [pSrcAnchor, pDstAnchor];\n } else {\n foundPath = [pSrcAnchor, cornerHV, pDstAnchor];\n }\n } else if (!pathVH_blocked) {\n // Use vertical-first L-path\n if (Math.abs(pSrcAnchor.x - pDstAnchor.x) < EPS) {\n // Same X - straight vertical line\n foundPath = [pSrcAnchor, pDstAnchor];\n } else {\n foundPath = [pSrcAnchor, cornerVH, pDstAnchor];\n }\n }\n\n // If no direct path found, use A* (existing logic)\n if (foundPath.length === 0) {\n while (openList.length > 0) {\n openList.sort((a, b) => a.f - b.f);\n const current = openList.shift()!;\n openSet.delete(current.key);\n\n if (current.key === endKey) {\n // Reconstruct path\n let currKey = endKey;\n let currPt = pDstAnchor;\n foundPath = [currPt];\n while (cameFrom.has(currKey)) {\n const prev = cameFrom.get(currKey)!;\n foundPath.unshift(prev);\n currPt = prev;\n currKey = getKey(prev.x, prev.y);\n }\n break;\n }\n\n // Neighbors: move along current horizontal pipe or current vertical pipe\n const cx = current.pt.x;\n const cy = current.pt.y;\n\n // Find adjacent vPipes to cx\n const sortedVPipes = vPipes.sort((a, b) => a.coord - b.coord);\n const vIdx = sortedVPipes.findIndex((p) => Math.abs(p.coord - cx) < 1);\n\n const hPipesSorted = hPipes.sort((a, b) => a.coord - b.coord);\n const hIdx = hPipesSorted.findIndex((p) => Math.abs(p.coord - cy) < 1);\n\n const neighbors: Point[] = [];\n\n // Add horizontal neighbors (along hPipe at cy)\n if (vIdx > 0) {\n neighbors.push({ x: sortedVPipes[vIdx - 1].coord, y: cy });\n }\n if (vIdx >= 0 && vIdx < sortedVPipes.length - 1) {\n neighbors.push({ x: sortedVPipes[vIdx + 1].coord, y: cy });\n }\n\n // Add vertical neighbors (along vPipe at cx)\n if (hIdx > 0) {\n neighbors.push({ x: cx, y: hPipesSorted[hIdx - 1].coord });\n }\n if (hIdx >= 0 && hIdx < hPipesSorted.length - 1) {\n neighbors.push({ x: cx, y: hPipesSorted[hIdx + 1].coord });\n }\n\n for (const neighbor of neighbors) {\n // Check obstacles - exclude source and destination nodes so edge can reach them\n const minX = Math.min(cx, neighbor.x);\n const maxX = Math.max(cx, neighbor.x);\n const minY = Math.min(cy, neighbor.y);\n const maxY = Math.max(cy, neighbor.y);\n\n const blocked = obstacles.some((obs) => {\n // Don't block on source or destination nodes - the edge needs to reach them\n if (obs.nodeId === e.start || obs.nodeId === e.end) {\n return false;\n }\n if (minX !== maxX) {\n // Horizontal\n return obs.minY < cy && obs.maxY > cy && obs.maxX > minX && obs.minX < maxX;\n } else {\n // Vertical\n return obs.minX < cx && obs.maxX > cx && obs.maxY > minY && obs.minY < maxY;\n }\n });\n\n if (blocked) {\n continue;\n }\n\n const nKey = getKey(neighbor.x, neighbor.y);\n const dist = Math.abs(neighbor.x - cx) + Math.abs(neighbor.y - cy);\n const penalty = crossingPenalty(i, current.pt, neighbor);\n\n // Directional penalty: STRONGLY discourage going OPPOSITE to the destination direction\n // This prevents paths that go UP when destination is below, etc.\n let dirPenalty = 0;\n const destDx = pDstAnchor.x - pSrcAnchor.x;\n const destDy = pDstAnchor.y - pSrcAnchor.y;\n const moveDx = neighbor.x - cx;\n const moveDy = neighbor.y - cy;\n\n // If destination is below (destDy > 0) and we're moving up (moveDy < 0), penalize HEAVILY\n // If destination is above (destDy < 0) and we're moving down (moveDy > 0), penalize HEAVILY\n // Penalty must be higher than crossing penalty (typically 1000 per crossing) to prevent\n // A* from preferring wrong-direction paths that avoid crossings\n if ((destDy > 10 && moveDy < -5) || (destDy < -10 && moveDy > 5)) {\n dirPenalty = Math.abs(moveDy) * 100; // VERY strong penalty - must exceed crossing penalties\n }\n // Similarly for horizontal\n if ((destDx > 10 && moveDx < -5) || (destDx < -10 && moveDx > 5)) {\n dirPenalty += Math.abs(moveDx) * 50; // Strong penalty for going wrong horizontal direction\n }\n\n // Bend penalty: penalize direction changes to prefer straighter paths with fewer bends\n // This helps produce cleaner routes that don't zig-zag unnecessarily\n let bendPenalty = 0;\n const currentDir = arrivalDir.get(current.key) ?? 'n';\n const moveDir: 'h' | 'v' = Math.abs(moveDx) > EPS ? 'h' : 'v';\n // If we're changing direction (and not at start), add a penalty\n if (currentDir !== 'n' && currentDir !== moveDir) {\n bendPenalty = 50; // Moderate penalty for each bend/turn\n }\n\n const stepCost = dist + penalty + dirPenalty + bendPenalty;\n const tentativeG = (gScore.get(current.key) ?? Infinity) + stepCost;\n const h = Math.abs(pDstAnchor.x - neighbor.x) + Math.abs(pDstAnchor.y - neighbor.y);\n\n if (tentativeG < (gScore.get(nKey) ?? Infinity)) {\n cameFrom.set(nKey, current.pt);\n gScore.set(nKey, tentativeG);\n arrivalDir.set(nKey, moveDir); // Track how we arrived at this node\n if (!openSet.has(nKey)) {\n openList.push({ key: nKey, f: tentativeG + h, pt: neighbor });\n openSet.add(nKey);\n } else {\n const idx = openList.findIndex((x) => x.key === nKey);\n if (idx !== -1) {\n openList[idx].f = tentativeG + h;\n }\n }\n }\n }\n }\n } // end if (foundPath.length === 0) - A* block\n\n if (foundPath.length === 0) {\n foundPath = [pSrcAnchor, { x: pSrcAnchor.x, y: pDstAnchor.y }, pDstAnchor];\n }\n\n // Path simplification: Find the minimum x-extent and y-extent needed to route around obstacles\n // Then reconstruct the path using only those extents\n\n if (foundPath.length > 4) {\n const start = foundPath[0];\n const end = foundPath[foundPath.length - 1];\n\n // Find the extreme x and y values in the path (excluding start/end)\n // These represent how far we had to go to clear obstacles\n let minX = Math.min(start.x, end.x);\n let maxX = Math.max(start.x, end.x);\n let minY = Math.min(start.y, end.y);\n let maxY = Math.max(start.y, end.y);\n\n for (const pt of foundPath) {\n minX = Math.min(minX, pt.x);\n maxX = Math.max(maxX, pt.x);\n minY = Math.min(minY, pt.y);\n maxY = Math.max(maxY, pt.y);\n }\n\n // Determine if we need to route left or right (or both)\n const wentRight = maxX > Math.max(start.x, end.x);\n const wentLeft = minX < Math.min(start.x, end.x);\n\n // For LR direction: recalculate detour X using visual extent\n // TB x becomes LR y after transform, so the visual extent should be based on height, not width\n if (isLR) {\n const margin = VERTICAL_PIPE_MARGIN;\n // Find obstacles that block the direct vertical path (caused us to detour)\n // An obstacle blocks the path if its x-range contains the path's x and its y-range overlaps with the path's y-range\n if (wentRight) {\n const pathX = Math.max(start.x, end.x);\n const pathMinY = Math.min(start.y, end.y);\n const pathMaxY = Math.max(start.y, end.y);\n const detourObstacles = obstacles.filter(\n (obs) =>\n obs.minX < pathX &&\n obs.maxX > pathX && // obstacle's x-range contains the path x\n obs.minY < pathMaxY &&\n obs.maxY > pathMinY // obstacle's y-range overlaps with path y-range\n );\n if (detourObstacles.length > 0) {\n // Find the obstacle that needs the maximum detour based on visual extent\n let visualMaxX = Math.max(start.x, end.x);\n for (const obs of detourObstacles) {\n const obsCenterX = (obs.minX + obs.maxX) / 2;\n // Skip obstacles without valid visualXHalfExtent (e.g., edge labels added later)\n if (obs.visualXHalfExtent === undefined || isNaN(obs.visualXHalfExtent)) {\n continue;\n }\n const visualRight = obsCenterX + obs.visualXHalfExtent + margin;\n visualMaxX = Math.max(visualMaxX, visualRight);\n }\n\n // Use visual maxX - this may be smaller than the original maxX\n // because we want to route closer to obstacles based on their visual extent (height in LR mode)\n if (!isNaN(visualMaxX)) {\n maxX = visualMaxX;\n }\n }\n }\n // Find obstacles that caused the left detour\n if (wentLeft) {\n const detourObstacles = obstacles.filter(\n (obs) =>\n obs.minX < Math.min(start.x, end.x) + margin && // obstacle extends past the direct path\n obs.minY < Math.max(start.y, end.y) &&\n obs.maxY > Math.min(start.y, end.y) // obstacle is in Y range\n );\n if (detourObstacles.length > 0) {\n // Find the obstacle that needs the minimum detour based on visual extent\n let visualMinX = Math.min(start.x, end.x);\n for (const obs of detourObstacles) {\n const obsCenterX = (obs.minX + obs.maxX) / 2;\n const visualLeft = obsCenterX - obs.visualXHalfExtent - margin;\n visualMinX = Math.min(visualMinX, visualLeft);\n }\n minX = visualMinX;\n }\n }\n }\n\n // Find the best Y for the horizontal return segment (closest to obstacles, not destination)\n // This creates cleaner routing that hugs obstacles instead of going all the way to destination\n const findBestReturnY = (detourX: number): number => {\n const goingDown = end.y > start.y;\n // Find obstacles that we're routing around (between start and end, blocking direct path)\n const relevantObs = obstacles.filter((obs) => {\n const obsInXRange =\n Math.min(start.x, end.x) < obs.maxX && Math.max(start.x, end.x) > obs.minX;\n const obsInYRange =\n Math.min(start.y, end.y) < obs.maxY && Math.max(start.y, end.y) > obs.minY;\n return obsInXRange && obsInYRange;\n });\n\n // For LR we care most about obstacles that actually intersect the chosen detour\n // column (detourX). Obstacles that are between start/end but off to the side\n // should not force the detour to go unnecessarily deep vertically.\n let filteredObs = relevantObs;\n if (isLR && relevantObs.length > 0) {\n const obsAtDetourX = relevantObs.filter(\n (obs) => obs.minX < detourX && obs.maxX > detourX\n );\n if (obsAtDetourX.length > 0) {\n filteredObs = obsAtDetourX;\n }\n }\n\n if (filteredObs.length === 0) {\n return end.y;\n }\n\n // Find the obstacle edge closest to destination in the direction we're going\n const margin = HORIZONTAL_PIPE_MARGIN;\n if (goingDown) {\n // Going down: find the bottom of the lowest obstacle we need to clear\n const lowestObsBottom = Math.max(...filteredObs.map((obs) => obs.maxY));\n const bestY = lowestObsBottom + margin;\n // Only use if it's closer than end.y and doesn't overshoot\n if (bestY < end.y - EPS) {\n return bestY;\n }\n } else {\n // Going up: find the top of the highest obstacle we need to clear\n const highestObsTop = Math.min(...filteredObs.map((obs) => obs.minY));\n const bestY = highestObsTop - margin;\n // Only use if it's closer than end.y and doesn't overshoot\n if (bestY > end.y + EPS) {\n return bestY;\n }\n }\n return end.y;\n };\n\n // Try to construct a minimal path using only the extreme coordinates\n // For a U-shaped detour going right: start -> (maxX, start.y) -> (maxX, bestY) -> (end.x, bestY) -> end\n // For a U-shaped detour going left: start -> (minX, start.y) -> (minX, bestY) -> (end.x, bestY) -> end\n const trySimplifyWithDetourX = (detourX: number): Point[] | null => {\n const bestY = findBestReturnY(detourX);\n const corner1: Point = { x: detourX, y: start.y };\n const corner2: Point = { x: detourX, y: bestY };\n const corner3: Point = { x: end.x, y: bestY };\n const seg1Blocked = checkSegmentBlocked(start, corner1);\n const seg2Blocked = checkSegmentBlocked(corner1, corner2);\n const seg3Blocked = checkSegmentBlocked(corner2, corner3);\n const seg4Blocked = bestY !== end.y ? checkSegmentBlocked(corner3, end) : false;\n\n if (!seg1Blocked && !seg2Blocked && !seg3Blocked && !seg4Blocked) {\n if (Math.abs(bestY - end.y) < EPS) {\n return [start, corner1, corner2, end];\n }\n return [start, corner1, corner2, corner3, end];\n }\n return null;\n };\n\n const simplified =\n wentRight && !wentLeft\n ? trySimplifyWithDetourX(maxX)\n : wentLeft && !wentRight\n ? trySimplifyWithDetourX(minX)\n : null;\n\n if (simplified) {\n foundPath = simplified;\n }\n }\n\n // 5. Collapse collinear and generate segments\n // Include handle waypoints for routing around obstacles at source/destination\n const fullPoints = [\n pSrcPort,\n ...srcHandleWaypoints,\n ...foundPath,\n ...dstHandleWaypoints.reverse(), // Reverse because they're stored anchor->waypoint->port\n pDstPort,\n ];\n\n // Post-process: Remove \"hooks\" or \"overshoots\" at the end\n // If the path goes A -> B -> C, and A-B-C are collinear, and B is \"beyond\" C, truncate B.\n // This happens if pDstAnchor (B) is on the node boundary but pDstPort (C) is slightly outside (margin).\n if (fullPoints.length >= 3) {\n const C = fullPoints[fullPoints.length - 1];\n const B = fullPoints[fullPoints.length - 2];\n const A = fullPoints[fullPoints.length - 3];\n\n // Check collinearity (Horizontal or Vertical)\n const isHoriz = Math.abs(A.y - B.y) < EPS && Math.abs(B.y - C.y) < EPS;\n const isVert = Math.abs(A.x - B.x) < EPS && Math.abs(B.x - C.x) < EPS;\n\n if (isHoriz) {\n // Check if C is between A and B (i.e., B overshot C)\n // dist(A, B) > dist(A, C) and direction is same?\n // Or simply: B is further from A than C is, in the same direction.\n // Signs: (B-A) and (C-A) have same sign. |B-A| > |C-A|.\n const signAB = Math.sign(B.x - A.x);\n const signAC = Math.sign(C.x - A.x);\n if (signAB !== 0 && signAB === signAC && Math.abs(B.x - A.x) > Math.abs(C.x - A.x)) {\n // B is an overshoot. Remove B.\n // fullPoints = [..., A, C]\n fullPoints.splice(-2, 1);\n }\n } else if (isVert) {\n const signAB = Math.sign(B.y - A.y);\n const signAC = Math.sign(C.y - A.y);\n if (signAB !== 0 && signAB === signAC && Math.abs(B.y - A.y) > Math.abs(C.y - A.y)) {\n fullPoints.splice(-2, 1);\n }\n }\n }\n\n const simplified: Point[] = [fullPoints[0]];\n for (let k = 1; k < fullPoints.length - 1; k++) {\n // Preserve the Anchor point (k=1) to satisfy strict testing requirements expecting 4 points for Z/U shapes\n if (k === 1) {\n simplified.push(fullPoints[k]);\n continue;\n }\n const prev = simplified[simplified.length - 1];\n const curr = fullPoints[k];\n const next = fullPoints[k + 1];\n\n // Check collinearity carefully - direction matters?\n // If direction reverses, we should NOT skip.\n // Horizontal: y is same.\n if (Math.abs(prev.y - curr.y) < EPS && Math.abs(curr.y - next.y) < EPS) {\n // Check direction reversal\n const dir1 = curr.x > prev.x;\n const dir2 = next.x > curr.x;\n if (dir1 !== dir2) {\n simplified.push(curr);\n continue;\n }\n // Same direction, can skip\n continue;\n }\n // Vertical: x is same\n if (Math.abs(prev.x - curr.x) < EPS && Math.abs(curr.x - next.x) < EPS) {\n const dir1 = curr.y > prev.y;\n const dir2 = next.y > curr.y;\n if (dir1 !== dir2) {\n simplified.push(curr);\n continue;\n }\n continue;\n }\n\n simplified.push(curr);\n }\n simplified.push(fullPoints[fullPoints.length - 1]);\n\n // Create Segments\n for (let k = 0; k < simplified.length - 1; k++) {\n const p1 = simplified[k];\n const p2 = simplified[k + 1];\n const orientation: Orientation = Math.abs(p1.x - p2.x) < EPS ? 'vertical' : 'horizontal';\n const coord = orientation === 'vertical' ? p1.x : p1.y;\n const from = orientation === 'vertical' ? Math.min(p1.y, p2.y) : Math.min(p1.x, p2.x);\n const to = orientation === 'vertical' ? Math.max(p1.y, p2.y) : Math.max(p1.x, p2.x);\n\n const pipe = getOrAddPipe(orientation, coord, from, to);\n\n const rSeg: RoutedSegment = {\n edgeIndex: i,\n segmentIndex: k,\n orientation,\n pipe,\n trackIndex: 0, // Initial track\n from,\n to,\n };\n\n allRoutedSegments.push(rSeg);\n edgeSegmentIndices[i].push(allRoutedSegments.length - 1);\n\n if (!pipe.tracks[0]) {\n pipe.tracks[0] = { index: 0, coord: pipe.coord, segments: [] };\n }\n pipe.tracks[0].segments.push({\n edgeIndex: i,\n segmentIndex: k,\n from,\n to,\n });\n }\n }\n\n // -----------------------------------------------------------------------\n // Phase 2: Crossing Reduction\n // -----------------------------------------------------------------------\n\n const segmentsOverlap = (s1: { from: number; to: number }, s2: { from: number; to: number }) => {\n // Overlap if intervals intersect.\n // [a, b] and [c, d] overlap if a < d and c < b.\n // from/to are sorted (min/max).\n return s1.from < s2.to && s2.from < s1.to;\n };\n\n const trySwapSegmentsAcrossTracks = (\n s1: RoutedSegment,\n s2: RoutedSegment,\n t1: Track,\n t2: Track\n ): boolean => {\n const canS1GoT2 = !t2.segments.some(\n (r) =>\n (r.edgeIndex !== s2.edgeIndex || r.segmentIndex !== s2.segmentIndex) &&\n segmentsOverlap(r, s1)\n );\n const canS2GoT1 = !t1.segments.some(\n (r) =>\n (r.edgeIndex !== s1.edgeIndex || r.segmentIndex !== s1.segmentIndex) &&\n segmentsOverlap(r, s2)\n );\n\n if (canS1GoT2 && canS2GoT1) {\n s1.trackIndex = t2.index;\n s2.trackIndex = t1.index;\n t1.segments = [\n ...t1.segments.filter(\n (r) => r.edgeIndex !== s1.edgeIndex || r.segmentIndex !== s1.segmentIndex\n ),\n {\n edgeIndex: s2.edgeIndex,\n segmentIndex: s2.segmentIndex,\n from: s2.from,\n to: s2.to,\n },\n ];\n t2.segments = [\n ...t2.segments.filter(\n (r) => r.edgeIndex !== s2.edgeIndex || r.segmentIndex !== s2.segmentIndex\n ),\n {\n edgeIndex: s1.edgeIndex,\n segmentIndex: s1.segmentIndex,\n from: s1.from,\n to: s1.to,\n },\n ];\n return true;\n }\n return false;\n };\n\n const createNewTrack = (pipe: Pipe): number => {\n const idx = pipe.tracks.length;\n pipe.tracks[idx] = { index: idx, coord: pipe.coord, segments: [] };\n return idx;\n };\n\n const moveSegmentToTrack = (seg: RoutedSegment, trackIdx: number) => {\n const oldTrack = seg.pipe.tracks[seg.trackIndex];\n oldTrack.segments = oldTrack.segments.filter(\n (r) => r.edgeIndex !== seg.edgeIndex || r.segmentIndex !== seg.segmentIndex\n );\n seg.trackIndex = trackIdx;\n const newTrack = seg.pipe.tracks[trackIdx];\n newTrack.segments.push({\n edgeIndex: seg.edgeIndex,\n segmentIndex: seg.segmentIndex,\n from: seg.from,\n to: seg.to,\n });\n };\n\n const moveSegmentChainToTrack = (seg: RoutedSegment, trackIdx: number) => {\n // Move ALL segments of this edge that are on the same pipe, not just consecutive ones\n const indices = edgeSegmentIndices[seg.edgeIndex];\n for (const idx of indices) {\n const s = allRoutedSegments[idx];\n if (s.pipe === seg.pipe) {\n moveSegmentToTrack(s, trackIdx);\n }\n }\n };\n\n const getAdjacentSegmentsAlongEdge = (seg: RoutedSegment) => {\n const indices = edgeSegmentIndices[seg.edgeIndex];\n const idxInList = indices.indexOf(allRoutedSegments.indexOf(seg));\n const adj: RoutedSegment[] = [];\n if (idxInList > 0) {\n adj.push(allRoutedSegments[indices[idxInList - 1]]);\n }\n if (idxInList < indices.length - 1) {\n adj.push(allRoutedSegments[indices[idxInList + 1]]);\n }\n return adj;\n };\n\n const haveAnyCrossing = (segA: RoutedSegment, segB: RoutedSegment) => {\n if (segA.orientation === segB.orientation) {\n return false;\n }\n const h = segA.orientation === 'horizontal' ? segA : segB;\n const v = segA.orientation === 'horizontal' ? segB : segA;\n return (\n v.pipe.coord > h.from && v.pipe.coord < h.to && h.pipe.coord > v.from && h.pipe.coord < v.to\n );\n };\n\n const findAvailableTrack = (pipe: Pipe, seg: RoutedSegment): number => {\n for (const track of pipe.tracks) {\n const overlap = track.segments.some(\n (r) =>\n (r.edgeIndex !== seg.edgeIndex || r.segmentIndex !== seg.segmentIndex) &&\n segmentsOverlap(r, seg)\n );\n if (!overlap) {\n return track.index;\n }\n }\n return -1;\n };\n\n const segmentsConflict = (s1: RoutedSegment, s2: RoutedSegment): boolean => {\n if (s1.trackIndex === s2.trackIndex) {\n return segmentsOverlap(s1, s2);\n }\n\n const adj1 = getAdjacentSegmentsAlongEdge(s1);\n const adj2 = getAdjacentSegmentsAlongEdge(s2);\n return adj1.some((a1) => adj2.some((a2) => haveAnyCrossing(a1, a2)));\n };\n\n const resolveTrackConflict = (\n s1: RoutedSegment,\n s2: RoutedSegment,\n move: (seg: RoutedSegment, trackIdx: number) => void\n ) => {\n if (\n trySwapSegmentsAcrossTracks(\n s1,\n s2,\n s1.pipe.tracks[s1.trackIndex],\n s2.pipe.tracks[s2.trackIndex]\n )\n ) {\n return;\n }\n\n const avail = findAvailableTrack(s1.pipe, s2);\n move(s2, avail !== -1 ? avail : createNewTrack(s1.pipe));\n };\n\n const resolveHandleConflicts = (handles: RoutedSegment[]): number => {\n let crossings = 0;\n for (let i = 0; i < handles.length; i++) {\n for (let j = i + 1; j < handles.length; j++) {\n const h1 = handles[i];\n const h2 = handles[j];\n if (h1.pipe !== h2.pipe) {\n continue;\n }\n\n if (segmentsConflict(h1, h2)) {\n crossings++;\n resolveTrackConflict(h1, h2, moveSegmentChainToTrack);\n }\n }\n }\n return crossings;\n };\n\n interface DestInfo {\n dest: number;\n deviation: number;\n base: number;\n delta: number;\n }\n const destInfoCache = new Map<number, DestInfo>();\n const getDestInfo = (edgeIdx: number): DestInfo => {\n if (destInfoCache.has(edgeIdx)) {\n return destInfoCache.get(edgeIdx)!;\n }\n const indices = edgeSegmentIndices[edgeIdx];\n if (indices.length === 0) {\n const info = { dest: 0, deviation: 0, base: 0, delta: 0 };\n destInfoCache.set(edgeIdx, info);\n return info;\n }\n const firstSeg = allRoutedSegments[indices[0]];\n const base = firstSeg.pipe.coord;\n let dest = base;\n for (let idx = 1; idx < indices.length; idx++) {\n const seg = allRoutedSegments[indices[idx]];\n if (seg.orientation === 'horizontal') {\n const candidateA = seg.from;\n const candidateB = seg.to;\n dest = Math.abs(candidateA - base) > Math.abs(candidateB - base) ? candidateA : candidateB;\n break;\n }\n }\n const deviation = Math.abs(dest - base);\n const info = { dest, deviation, base, delta: dest - base };\n destInfoCache.set(edgeIdx, info);\n return info;\n };\n\n const fixSourceHandleCrossings = (): number => {\n let crossings = 0;\n const edgesBySource = new Map<string, number[]>();\n for (const [i, e] of edges.entries()) {\n if (edgeSegmentIndices[i].length === 0) {\n continue;\n }\n if (!e.start) {\n continue;\n }\n if (!edgesBySource.has(e.start)) {\n edgesBySource.set(e.start, []);\n }\n edgesBySource.get(e.start)!.push(i);\n }\n\n const getEdgeDistance = (edgeIdx: number) => {\n const edge = edges[edgeIdx];\n if (!edge.start || !edge.end) {\n return 0;\n }\n const srcNode = nodeById.get(edge.start);\n const dstNode = nodeById.get(edge.end);\n if (!srcNode || !dstNode) {\n return 0;\n }\n const dx = (dstNode.x ?? 0) - (srcNode.x ?? 0);\n const dy = (dstNode.y ?? 0) - (srcNode.y ?? 0);\n return Math.abs(dx) + Math.abs(dy);\n };\n\n for (const grp of edgesBySource.values()) {\n // Sort by continuity: prefer edges that continue straight from previous segment\n grp.sort((a, b) => {\n // 0. Destination-aware ordering: keep near-center edges on the center track.\n const infoA = getDestInfo(a);\n const infoB = getDestInfo(b);\n if (Math.abs(infoA.deviation - infoB.deviation) > 1) {\n return infoA.deviation - infoB.deviation;\n }\n if (Math.abs(infoA.dest - infoB.dest) > 1) {\n return infoA.dest - infoB.dest;\n }\n\n // 0. Prefer longer spans (edges that travel further should keep straighter paths)\n const distA = getEdgeDistance(a);\n const distB = getEdgeDistance(b);\n if (Math.abs(distA - distB) > 1) {\n return distB - distA;\n }\n\n // 1. Segment Count: Prefer simpler paths (fewer segments usually means more direct)\n const lenA = edgeSegmentIndices[a].length;\n const lenB = edgeSegmentIndices[b].length;\n if (lenA !== lenB) {\n return lenA - lenB;\n }\n\n // 2. Length Check for single-segment edges: Prefer shorter edges to stay centered\n if (lenA === 1) {\n const idxA = edgeSegmentIndices[a][0];\n const idxB = edgeSegmentIndices[b][0];\n // Ensure indices exist\n if (allRoutedSegments[idxA] && allRoutedSegments[idxB]) {\n const segA = allRoutedSegments[idxA];\n const segB = allRoutedSegments[idxB];\n const distA = Math.abs(segA.to - segA.from);\n const distB = Math.abs(segB.to - segB.from);\n if (Math.abs(distA - distB) > 1) {\n // Shorter distance (closer destination) should come first to get center track\n return distA - distB;\n }\n }\n }\n\n return 0;\n });\n\n const handles = grp.map((ei) => allRoutedSegments[edgeSegmentIndices[ei][0]]);\n crossings += resolveHandleConflicts(handles);\n }\n return crossings;\n };\n\n const fixTargetHandleCrossings = (): number => {\n let crossings = 0;\n const edgesByTarget = new Map<string, number[]>();\n for (const [i, e] of edges.entries()) {\n const indices = edgeSegmentIndices[i];\n if (indices.length === 0) {\n continue;\n }\n if (!e.end) {\n continue;\n }\n if (!edgesByTarget.has(e.end)) {\n edgesByTarget.set(e.end, []);\n }\n edgesByTarget.get(e.end)!.push(i);\n }\n\n for (const grp of edgesByTarget.values()) {\n // Sort by continuity: prefer edges that align with their previous segment\n grp.sort((a, b) => {\n const getDist = (edgeIdx: number) => {\n const indices = edgeSegmentIndices[edgeIdx];\n if (indices.length < 2) {\n return 0;\n }\n // Shorter perpendicular connector means better target-handle alignment.\n const prev = allRoutedSegments[indices[indices.length - 2]];\n return Math.abs(prev.to - prev.from);\n };\n\n const scoreA = getDist(a);\n const scoreB = getDist(b);\n if (Math.abs(scoreA - scoreB) > 0.1) {\n return scoreA - scoreB; // Ascending length (shorter first)\n }\n return a - b; // Stable fallback\n });\n\n const handles = grp.map(\n (ei) => allRoutedSegments[edgeSegmentIndices[ei][edgeSegmentIndices[ei].length - 1]]\n );\n crossings += resolveHandleConflicts(handles);\n }\n return crossings;\n };\n\n const fixPipeCrossings = (): number => {\n let crossings = 0;\n for (const pipe of pipes) {\n // Collect all segments in pipe\n const pipeSegments: RoutedSegment[] = [];\n for (const t of pipe.tracks) {\n for (const ref of t.segments) {\n // Find the actual RoutedSegment object\n const idx = edgeSegmentIndices[ref.edgeIndex].find(\n (ix) => allRoutedSegments[ix].segmentIndex === ref.segmentIndex\n );\n if (idx !== undefined) {\n pipeSegments.push(allRoutedSegments[idx]);\n }\n }\n }\n\n // if (pipeSegments.length > 0 && pipe.orientation === 'vertical' && Math.abs(pipe.coord - (-19.5)) < 0.1) {}\n\n pipeSegments.sort((a, b) => a.edgeIndex - b.edgeIndex || a.segmentIndex - b.segmentIndex);\n\n for (let i = 0; i < pipeSegments.length; i++) {\n for (let j = i + 1; j < pipeSegments.length; j++) {\n const s1 = pipeSegments[i];\n const s2 = pipeSegments[j];\n\n if (segmentsConflict(s1, s2)) {\n crossings++;\n resolveTrackConflict(s1, s2, moveSegmentToTrack);\n }\n }\n }\n }\n return crossings;\n };\n\n // Main Reduction Loop\n let iterations = 0;\n const MAX_ITER = 10;\n while (iterations < MAX_ITER) {\n let changed = 0;\n changed += fixSourceHandleCrossings();\n changed += fixTargetHandleCrossings();\n changed += fixPipeCrossings();\n if (changed === 0) {\n break;\n }\n iterations++;\n }\n\n // -----------------------------------------------------------------------\n // Phase 3: Rebuild Geometry\n // -----------------------------------------------------------------------\n const segmentCoords = new Map<string, number>(); // `${edgeIndex}-${segmentIndex}` -> coord\n\n for (const pipe of pipes) {\n // Identify clusters of connected segments (interval graph)\n interface SegmentInfo {\n edgeIndex: number;\n segmentIndex: number;\n trackIndex: number;\n from: number;\n to: number;\n }\n\n const segments: SegmentInfo[] = [];\n pipe.tracks.forEach((t) => {\n t.segments.forEach((s) => {\n segments.push({\n edgeIndex: s.edgeIndex,\n segmentIndex: s.segmentIndex,\n trackIndex: t.index,\n from: s.from,\n to: s.to,\n });\n });\n });\n\n segments.sort((a, b) => a.from - b.from);\n\n const clusters: SegmentInfo[][] = [];\n if (segments.length > 0) {\n let currentCluster: SegmentInfo[] = [segments[0]];\n let clusterEnd = segments[0].to;\n\n for (let k = 1; k < segments.length; k++) {\n const s = segments[k];\n if (s.from < clusterEnd) {\n currentCluster.push(s);\n clusterEnd = Math.max(clusterEnd, s.to);\n } else {\n clusters.push(currentCluster);\n currentCluster = [s];\n clusterEnd = s.to;\n }\n }\n clusters.push(currentCluster);\n }\n\n // Assign local coordinates for each cluster\n for (const cluster of clusters) {\n const usedTracks = new Set<number>();\n cluster.forEach((s) => usedTracks.add(s.trackIndex));\n const trackScores = new Map<number, number>();\n cluster.forEach((s) => {\n const info = getDestInfo(s.edgeIndex);\n trackScores.set(s.trackIndex, (trackScores.get(s.trackIndex) ?? 0) + info.delta);\n });\n\n const leftTracks = [...usedTracks].filter((t) => (trackScores.get(t) ?? 0) < -1);\n const rightTracks = [...usedTracks].filter((t) => (trackScores.get(t) ?? 0) > 1);\n const neutralTracks = [...usedTracks].filter((t) => Math.abs(trackScores.get(t) ?? 0) <= 1);\n\n leftTracks.sort((a, b) => (trackScores.get(b) ?? 0) - (trackScores.get(a) ?? 0));\n rightTracks.sort((a, b) => (trackScores.get(a) ?? 0) - (trackScores.get(b) ?? 0));\n\n const assignCoord = (trackIndex: number, coord: number) => {\n cluster\n .filter((s) => s.trackIndex === trackIndex)\n .forEach((s) => {\n // Straight intra-lane edges keep pipe coord \u2014 don't spread them\n const effectiveCoord = straightIntraLaneEdges.has(s.edgeIndex) ? pipe.coord : coord;\n segmentCoords.set(`${s.edgeIndex}-${s.segmentIndex}`, effectiveCoord);\n });\n };\n\n let leftCount = 0;\n for (const trackIndex of leftTracks) {\n leftCount++;\n assignCoord(trackIndex, pipe.coord - leftCount * TRACK_SPACING);\n }\n\n if (neutralTracks.length === 0 && usedTracks.size > 0) {\n // If no neutral track, make the closest-to-center track neutral\n const bestTrack = [...usedTracks].sort(\n (a, b) => Math.abs(trackScores.get(a) ?? 0) - Math.abs(trackScores.get(b) ?? 0)\n )[0];\n const leftIdx = leftTracks.indexOf(bestTrack);\n if (leftIdx !== -1) {\n leftTracks.splice(leftIdx, 1);\n }\n const rightIdx = rightTracks.indexOf(bestTrack);\n if (rightIdx !== -1) {\n rightTracks.splice(rightIdx, 1);\n }\n neutralTracks.push(bestTrack);\n }\n\n let neutralAssigned = 0;\n for (const trackIndex of neutralTracks) {\n if (neutralAssigned === 0) {\n assignCoord(trackIndex, pipe.coord);\n } else {\n const dir = neutralAssigned % 2 === 1 ? 1 : -1;\n const magnitude = Math.ceil(neutralAssigned / 2);\n assignCoord(trackIndex, pipe.coord + dir * magnitude * TRACK_SPACING * 0.5);\n }\n neutralAssigned++;\n }\n\n let rightCount = 0;\n for (const trackIndex of rightTracks) {\n rightCount++;\n assignCoord(trackIndex, pipe.coord + rightCount * TRACK_SPACING);\n }\n }\n }\n\n // Strategy 1: no sibling to-label fan-out nudge is needed because\n // `-to-label` synthetic edges no longer exist; labelled originals route\n // as single A\u2192B edges and share track assignment with every other edge.\n\n for (const [i, e] of edges.entries()) {\n const indices = edgeSegmentIndices[i] ?? [];\n if (indices.length === 0) {\n continue;\n }\n\n const newPoints: Point[] = [];\n\n // Recompute ports, honoring Step 6.2's side assignment.\n const src = nodeById.get(e.start!)!;\n const dst = nodeById.get(e.end!)!;\n const { pSrcPort, pDstPort } = portsForEdge(i, src, dst);\n\n const lines: RoutedLine[] = indices.map((idx) => {\n const s = allRoutedSegments[idx];\n // const track = s.pipe.tracks[s.trackIndex];\n const coord = segmentCoords.get(`${s.edgeIndex}-${s.segmentIndex}`) ?? s.pipe.coord;\n return {\n orient: s.orientation,\n coord: coord,\n from: s.from,\n to: s.to,\n };\n });\n\n newPoints.push(pSrcPort);\n\n for (let k = 0; k < lines.length; k++) {\n const line = lines[k];\n const prevPt = newPoints[newPoints.length - 1];\n const prevAlong = line.orient === 'vertical' ? prevPt.y : prevPt.x;\n const prevTrackCoord = line.orient === 'vertical' ? prevPt.x : prevPt.y;\n const nextLine = lines[k + 1];\n const hasNextLine = k < lines.length - 1;\n\n if (Math.abs(prevTrackCoord - line.coord) > EPS) {\n newPoints.push(pointOnLine(line, prevAlong));\n }\n\n if (hasNextLine && nextLine.orient === line.orient) {\n if (Math.abs(line.coord - nextLine.coord) > EPS) {\n const junction =\n line.orient === 'vertical'\n ? (prevAlong + nextLine.from) / 2\n : sharedLineEndpointCoord(line, nextLine);\n newPoints.push(pointOnLine(line, junction), pointOnLine(nextLine, junction));\n } else if (k === 0 || k === lines.length - 2) {\n newPoints.push(pointOnLine(line, sharedLineEndpointCoord(line, nextLine)));\n }\n } else if (hasNextLine) {\n newPoints.push(pointOnLine(line, nextLine.coord));\n } else {\n const endAlong =\n Math.abs(line.from - prevAlong) < Math.abs(line.to - prevAlong) ? line.to : line.from;\n newPoints.push(pointOnLine(line, endAlong));\n }\n }\n\n // Ensure we end at pDstPort to protect the last anchor from being eaten by the renderer's intersection logic\n const last = newPoints[newPoints.length - 1];\n if (Math.abs(last.x - pDstPort.x) > EPS || Math.abs(last.y - pDstPort.y) > EPS) {\n newPoints.push(pDstPort);\n }\n\n const filtered: Point[] = [];\n if (newPoints.length > 0) {\n filtered.push(newPoints[0]);\n }\n for (let k = 1; k < newPoints.length; k++) {\n const p = newPoints[k];\n const prev = filtered[filtered.length - 1];\n if (Math.abs(p.x - prev.x) > EPS || Math.abs(p.y - prev.y) > EPS) {\n filtered.push(p);\n }\n }\n\n e.points = filtered;\n }\n\n // Strategy 1: no shadow concatenation / L-bend bridge. Each labelled\n // original now routes as a single unbroken A\u2192B polyline, so we simply\n // copy the routing view's polyline back onto the original edge.\n for (const re of edges) {\n const orig = re.__originalEdge as { points?: Point[] } | undefined;\n if (orig && re.points) {\n orig.points = re.points;\n }\n }\n\n // Strip `isLayoutOnly` virtual edges from the layout. They have served their\n // purpose by giving Sugiyama layering constraints through label nodes and\n // must not reach rendering, validation, or scoring.\n data.edges = (data.edges ?? []).filter((e) => !(e as { isLayoutOnly?: boolean }).isLayoutOnly);\n\n // Snap edge endpoints onto the rectangular boundary of their src / dst\n // nodes. Raykov's internal port-and-anchor logic leaves the polyline\n // terminating near the anchor offset (inside the node body); the renderer\n // normally clips to the node boundary via `tail.intersect()`, but the\n // validator sees the raw polyline points. Snapping here guarantees the\n // first and last points sit on the boundary regardless of downstream\n // rendering, and preserves the last/first segment's orientation.\n const nodeBoundaryClamp = (p: Point, node: MermaidNode): Point => {\n const cx = node.x ?? 0;\n const cy = node.y ?? 0;\n const w = node.width ?? 0;\n const h = node.height ?? 0;\n if (w <= 0 || h <= 0) {\n return p;\n }\n const left = cx - w / 2;\n const right = cx + w / 2;\n const top = cy - h / 2;\n const bottom = cy + h / 2;\n // Already outside the rect: leave alone.\n if (p.x < left || p.x > right || p.y < top || p.y > bottom) {\n return p;\n }\n // Inside (or on) the rect: project onto the nearest edge. Ties pick the\n // side closest to the node center in the orthogonal axis, which keeps\n // the snap consistent across similarly-positioned edges.\n const dLeft = p.x - left;\n const dRight = right - p.x;\n const dTop = p.y - top;\n const dBottom = bottom - p.y;\n const minD = Math.min(dLeft, dRight, dTop, dBottom);\n if (minD === dLeft) {\n return { x: left, y: p.y };\n }\n if (minD === dRight) {\n return { x: right, y: p.y };\n }\n if (minD === dTop) {\n return { x: p.x, y: top };\n }\n return { x: p.x, y: bottom };\n };\n\n for (const edge of data.edges) {\n const pts = (edge as { points?: Point[] }).points;\n if (!pts || pts.length < 2) {\n continue;\n }\n const srcId = (edge as { start?: string }).start;\n const dstId = (edge as { end?: string }).end;\n const src = srcId ? nodeById.get(srcId) : undefined;\n const dst = dstId ? nodeById.get(dstId) : undefined;\n if (src) {\n pts[0] = nodeBoundaryClamp(pts[0], src);\n }\n if (dst) {\n pts[pts.length - 1] = nodeBoundaryClamp(pts[pts.length - 1], dst);\n }\n }\n\n return data;\n}\n", "import type { LayoutData } from '../../types.js';\nimport { postProcessSwimlaneLayout, validateSwimlanesLayout } from './postProcessing.js';\nimport { toGraphView, writeBackToLayoutData } from './helpers.js';\nimport { sugiyamaLayout } from './pipeline.js';\nimport { routeEdgesOrthogonal } from './orthogonalRouter/router.js';\n\nexport type SwimlaneDirection = 'TB' | 'LR' | 'BT' | 'RL';\n\nfunction getSwimlaneDirection(data4Layout: LayoutData): SwimlaneDirection {\n return ((data4Layout as LayoutData & { direction?: string }).direction ??\n 'TB') as SwimlaneDirection;\n}\n\n/**\n * Pure swimlane layout core shared by browser rendering and DDLT.\n *\n * The browser measures DOM nodes before this runs; DDLT injects captured sizes\n * before calling the same function.\n */\nexport function runSwimlaneLayoutCore(data4Layout: LayoutData): SwimlaneDirection {\n const g = toGraphView(data4Layout);\n const nodeGap = data4Layout.config.flowchart?.nodeSpacing ?? 40;\n const layerGap = data4Layout.config.flowchart?.rankSpacing ?? 100;\n const ignoreCrossLaneEdges = data4Layout.config.swimlane?.ignoreCrossLaneEdges ?? true;\n const optimizeRanksByCrossings = data4Layout.config.swimlane?.optimizeRanksByCrossings ?? true;\n const automaticLaneOrdering = data4Layout.config.swimlane?.automaticLaneOrdering ?? false;\n const direction = getSwimlaneDirection(data4Layout);\n\n const { ordered, coordinates } = sugiyamaLayout(g, {\n nodeGap,\n layerGap,\n ignoreCrossLaneEdges,\n optimizeRanksByCrossings,\n automaticLaneOrdering,\n direction,\n });\n writeBackToLayoutData(g, ordered, coordinates, { nodeGap, layerGap });\n\n // The layout phases above position nodes only; they do not emit edge routing.\n // Reset any edge points carried on the input so routeEdgesOrthogonal below is\n // the single source of truth for swimlane edge geometry.\n for (const edge of data4Layout.edges ?? []) {\n delete edge.points;\n }\n routeEdgesOrthogonal(data4Layout, direction);\n\n for (const edge of data4Layout.edges ?? []) {\n if (!edge.curve || edge.curve === 'basis') {\n edge.curve = 'rounded';\n }\n }\n\n postProcessSwimlaneLayout(data4Layout, direction);\n\n validateSwimlanesLayout(data4Layout);\n\n return direction;\n}\n", "import type { SVG } from '../../../mermaid.js';\nimport type { D3Selection } from '../../../types.js';\nimport { createGraphWithElements } from '../../createGraph.js';\nimport insertMarkers from '../../rendering-elements/markers.js';\nimport { clear as clearGraphlib } from '../dagre/mermaid-graphlib.js';\nimport { clear as clearNodes } from '../../rendering-elements/nodes.js';\nimport { clear as clearClusters } from '../../rendering-elements/clusters.js';\nimport { clear as clearEdges } from '../../rendering-elements/edges.js';\nimport type { LayoutData } from '../../types.js';\nimport { adjustLayout } from './adjustLayout.js';\nimport { prepareLayoutForSwimlanes } from './helpers.js';\nimport { createEdgeLabelNodes } from './edgeLabelNodes.js';\nimport { runSwimlaneLayoutCore } from './layoutCore.js';\n\nexport async function render(data4Layout: LayoutData, svg: SVG) {\n const element = svg.select('g') as unknown as D3Selection<SVGElement>;\n insertMarkers(element, data4Layout.markers, data4Layout.type, data4Layout.diagramId);\n clearNodes();\n clearEdges();\n clearClusters();\n clearGraphlib();\n\n prepareLayoutForSwimlanes(data4Layout);\n\n const transformedData = createEdgeLabelNodes(data4Layout);\n data4Layout.nodes = transformedData.nodes;\n data4Layout.edges = transformedData.edges;\n\n const { groups } = await createGraphWithElements(element, data4Layout);\n\n runSwimlaneLayoutCore(data4Layout);\n\n await adjustLayout(data4Layout, groups);\n}\n"],
"mappings": "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",
"names": ["getConfig", "edgeLabels", "sameDirSrc", "sameDirDst", "EPS", "side", "EPS", "EPS_LOCAL", "railEndIsAdjacent", "EPS", "MIN_SHARED", "EPS", "rect", "EPS", "MIN_PORT_SPACING", "PORT_SHIFT", "EPS_LOCAL", "MIN_SHARED", "segmentsFor", "pairKey", "countCrossingsBetweenAdjacent", "countCrossingsBetweenAdjacent", "optimizeRanksByCrossings", "EPS", "MIN_PORT_SPACING", "leavesPositiveSide", "simplified", "info", "distA", "distB", "optimizeRanksByCrossings", "clear"]
}