@nodius/layouting 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +253 -0
- package/dist/index.d.mts +176 -0
- package/dist/index.d.ts +176 -0
- package/dist/index.js +1115 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1086 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/graph.ts","../src/algorithms/cycle-breaking.ts","../src/algorithms/layer-assignment.ts","../src/algorithms/crossing-minimization.ts","../src/algorithms/coordinate-assignment.ts","../src/algorithms/edge-routing.ts","../src/layout.ts","../src/incremental.ts"],"sourcesContent":["export { layout } from './layout';\nexport { IncrementalLayout } from './incremental';\nexport { countAllCrossings } from './algorithms/crossing-minimization';\n\nexport type {\n HandleSide,\n HandleType,\n LayoutDirection,\n Point,\n HandleInput,\n NodeInput,\n EdgeInput,\n LayoutInput,\n LayoutOptions,\n HandleOutput,\n NodeOutput,\n EdgeOutput,\n LayoutResult,\n} from './types';\n","/** Position on a node where a handle can be placed */\nexport type HandleSide = 'top' | 'right' | 'bottom' | 'left';\n\n/** Handle type - input receives connections, output sends connections */\nexport type HandleType = 'input' | 'output';\n\n/** Layout direction */\nexport type LayoutDirection = 'TB' | 'LR' | 'BT' | 'RL';\n\n/** A 2D point */\nexport interface Point {\n x: number;\n y: number;\n}\n\n/** Handle definition on a node */\nexport interface HandleInput {\n id: string;\n type: HandleType;\n position: HandleSide;\n /** Position along the side (0 = start, 1 = end). Default: 0.5 */\n offset?: number;\n}\n\n/** Node input definition */\nexport interface NodeInput {\n id: string;\n width: number;\n height: number;\n handles: HandleInput[];\n}\n\n/** Edge input definition */\nexport interface EdgeInput {\n id: string;\n from: string;\n to: string;\n fromHandle: string;\n toHandle: string;\n}\n\n/** Complete layout input */\nexport interface LayoutInput {\n nodes: NodeInput[];\n edges: EdgeInput[];\n}\n\n/** Layout configuration options */\nexport interface LayoutOptions {\n /** Layout direction. Default: 'TB' */\n direction?: LayoutDirection;\n /** Minimum spacing between nodes in the same layer. Default: 40 */\n nodeSpacing?: number;\n /** Minimum spacing between layers. Default: 60 */\n layerSpacing?: number;\n /** Number of iterations for crossing minimization. Default: 24 */\n crossingMinimizationIterations?: number;\n /** Number of iterations for coordinate optimization. Default: 8 */\n coordinateOptimizationIterations?: number;\n /** Margin for edge routing (distance from node before turning). Default: 20 */\n edgeMargin?: number;\n}\n\n/** Resolved options with all defaults applied */\nexport interface ResolvedOptions {\n direction: LayoutDirection;\n nodeSpacing: number;\n layerSpacing: number;\n crossingMinimizationIterations: number;\n coordinateOptimizationIterations: number;\n edgeMargin: number;\n}\n\nexport function resolveOptions(options?: LayoutOptions): ResolvedOptions {\n return {\n direction: options?.direction ?? 'TB',\n nodeSpacing: options?.nodeSpacing ?? 40,\n layerSpacing: options?.layerSpacing ?? 60,\n crossingMinimizationIterations: options?.crossingMinimizationIterations ?? 24,\n coordinateOptimizationIterations: options?.coordinateOptimizationIterations ?? 8,\n edgeMargin: options?.edgeMargin ?? 20,\n };\n}\n\n/** Positioned handle in the output */\nexport interface HandleOutput {\n id: string;\n type: HandleType;\n position: HandleSide;\n x: number;\n y: number;\n}\n\n/** Positioned node in the output */\nexport interface NodeOutput {\n id: string;\n x: number;\n y: number;\n width: number;\n height: number;\n handles: HandleOutput[];\n}\n\n/** Routed edge in the output */\nexport interface EdgeOutput {\n id: string;\n from: string;\n to: string;\n fromHandle: string;\n toHandle: string;\n points: Point[];\n}\n\n/** Complete layout result */\nexport interface LayoutResult {\n nodes: NodeOutput[];\n edges: EdgeOutput[];\n}\n","import { HandleInput, HandleSide, NodeInput, EdgeInput, Point } from './types';\n\nexport interface InternalNode {\n id: string;\n width: number;\n height: number;\n handles: HandleInput[];\n isDummy: boolean;\n layer: number;\n order: number;\n x: number;\n y: number;\n}\n\nexport interface InternalEdge {\n id: string;\n from: string;\n to: string;\n fromHandle: string;\n toHandle: string;\n reversed: boolean;\n originalId: string;\n}\n\nexport class Graph {\n nodes: Map<string, InternalNode> = new Map();\n edges: Map<string, InternalEdge> = new Map();\n outEdges: Map<string, Set<string>> = new Map();\n inEdges: Map<string, Set<string>> = new Map();\n\n addNode(node: InternalNode): void {\n this.nodes.set(node.id, node);\n if (!this.outEdges.has(node.id)) this.outEdges.set(node.id, new Set());\n if (!this.inEdges.has(node.id)) this.inEdges.set(node.id, new Set());\n }\n\n addEdge(edge: InternalEdge): void {\n this.edges.set(edge.id, edge);\n if (!this.outEdges.has(edge.from)) this.outEdges.set(edge.from, new Set());\n if (!this.inEdges.has(edge.to)) this.inEdges.set(edge.to, new Set());\n this.outEdges.get(edge.from)!.add(edge.id);\n this.inEdges.get(edge.to)!.add(edge.id);\n }\n\n removeEdge(edgeId: string): void {\n const edge = this.edges.get(edgeId);\n if (!edge) return;\n this.outEdges.get(edge.from)?.delete(edgeId);\n this.inEdges.get(edge.to)?.delete(edgeId);\n this.edges.delete(edgeId);\n }\n\n removeNode(nodeId: string): void {\n const outEdgeIds = [...(this.outEdges.get(nodeId) || [])];\n const inEdgeIds = [...(this.inEdges.get(nodeId) || [])];\n for (const eid of outEdgeIds) this.removeEdge(eid);\n for (const eid of inEdgeIds) this.removeEdge(eid);\n this.nodes.delete(nodeId);\n this.outEdges.delete(nodeId);\n this.inEdges.delete(nodeId);\n }\n\n predecessors(nodeId: string): string[] {\n const result: string[] = [];\n const inEdgeIds = this.inEdges.get(nodeId);\n if (inEdgeIds) {\n for (const eid of inEdgeIds) {\n const edge = this.edges.get(eid);\n if (edge) result.push(edge.from);\n }\n }\n return result;\n }\n\n successors(nodeId: string): string[] {\n const result: string[] = [];\n const outEdgeIds = this.outEdges.get(nodeId);\n if (outEdgeIds) {\n for (const eid of outEdgeIds) {\n const edge = this.edges.get(eid);\n if (edge) result.push(edge.to);\n }\n }\n return result;\n }\n}\n\nexport function buildGraph(nodes: NodeInput[], edges: EdgeInput[]): Graph {\n const graph = new Graph();\n\n for (const node of nodes) {\n graph.addNode({\n id: node.id,\n width: node.width,\n height: node.height,\n handles: node.handles.map(h => ({ ...h, offset: h.offset ?? 0.5 })),\n isDummy: false,\n layer: -1,\n order: -1,\n x: 0,\n y: 0,\n });\n }\n\n for (const edge of edges) {\n graph.addEdge({\n id: edge.id,\n from: edge.from,\n to: edge.to,\n fromHandle: edge.fromHandle,\n toHandle: edge.toHandle,\n reversed: false,\n originalId: edge.id,\n });\n }\n\n return graph;\n}\n\n/** Compute the absolute position of a handle on a positioned node */\nexport function getHandlePosition(node: InternalNode, handleId: string): Point {\n const handle = node.handles.find(h => h.id === handleId);\n if (!handle) {\n return { x: node.x + node.width / 2, y: node.y + node.height / 2 };\n }\n\n const offset = handle.offset ?? 0.5;\n\n switch (handle.position) {\n case 'top':\n return { x: node.x + offset * node.width, y: node.y };\n case 'bottom':\n return { x: node.x + offset * node.width, y: node.y + node.height };\n case 'left':\n return { x: node.x, y: node.y + offset * node.height };\n case 'right':\n return { x: node.x + node.width, y: node.y + offset * node.height };\n }\n}\n\n/** Get the direction vector for exiting/entering a handle */\nexport function getHandleDirection(side: HandleSide): Point {\n switch (side) {\n case 'top': return { x: 0, y: -1 };\n case 'bottom': return { x: 0, y: 1 };\n case 'left': return { x: -1, y: 0 };\n case 'right': return { x: 1, y: 0 };\n }\n}\n","import { Graph } from '../graph';\n\n/**\n * Break cycles in the graph using DFS-based back edge detection.\n * Reverses back edges to make the graph a DAG.\n * Returns the set of reversed edge IDs.\n */\nexport function breakCycles(graph: Graph): Set<string> {\n const WHITE = 0, GRAY = 1, BLACK = 2;\n const state = new Map<string, number>();\n const reversed = new Set<string>();\n\n for (const nodeId of graph.nodes.keys()) {\n state.set(nodeId, WHITE);\n }\n\n // Process nodes with more outgoing than incoming edges first\n const nodeIds = [...graph.nodes.keys()].sort((a, b) => {\n const aDiff = (graph.outEdges.get(a)?.size || 0) - (graph.inEdges.get(a)?.size || 0);\n const bDiff = (graph.outEdges.get(b)?.size || 0) - (graph.inEdges.get(b)?.size || 0);\n return bDiff - aDiff;\n });\n\n function dfs(nodeId: string): void {\n state.set(nodeId, GRAY);\n\n const outEdgeIds = graph.outEdges.get(nodeId);\n if (outEdgeIds) {\n for (const edgeId of outEdgeIds) {\n const edge = graph.edges.get(edgeId);\n if (!edge) continue;\n\n const targetState = state.get(edge.to);\n if (targetState === GRAY) {\n reversed.add(edgeId);\n } else if (targetState === WHITE) {\n dfs(edge.to);\n }\n }\n }\n\n state.set(nodeId, BLACK);\n }\n\n for (const nodeId of nodeIds) {\n if (state.get(nodeId) === WHITE) {\n dfs(nodeId);\n }\n }\n\n // Reverse the back edges in the graph\n for (const edgeId of reversed) {\n const edge = graph.edges.get(edgeId);\n if (!edge) continue;\n\n graph.removeEdge(edgeId);\n graph.addEdge({\n ...edge,\n from: edge.to,\n to: edge.from,\n fromHandle: edge.toHandle,\n toHandle: edge.fromHandle,\n reversed: !edge.reversed,\n });\n }\n\n return reversed;\n}\n","import { Graph } from '../graph';\n\n/**\n * Assign layers to nodes using the longest path algorithm.\n * Source nodes (no predecessors) get layer 0.\n * Each node's layer = max(predecessors' layers) + 1.\n */\nexport function assignLayers(graph: Graph): string[][] {\n const layers = new Map<string, number>();\n const visiting = new Set<string>();\n\n function computeLayer(nodeId: string): number {\n if (layers.has(nodeId)) return layers.get(nodeId)!;\n if (visiting.has(nodeId)) return 0;\n\n visiting.add(nodeId);\n\n const preds = graph.predecessors(nodeId);\n let maxPredLayer = -1;\n\n for (const pred of preds) {\n maxPredLayer = Math.max(maxPredLayer, computeLayer(pred));\n }\n\n const layer = maxPredLayer + 1;\n layers.set(nodeId, layer);\n\n const node = graph.nodes.get(nodeId);\n if (node) node.layer = layer;\n\n visiting.delete(nodeId);\n return layer;\n }\n\n for (const nodeId of graph.nodes.keys()) {\n computeLayer(nodeId);\n }\n\n // Build layers array\n let maxLayer = 0;\n for (const layer of layers.values()) {\n maxLayer = Math.max(maxLayer, layer);\n }\n\n const layersArray: string[][] = Array.from({ length: maxLayer + 1 }, () => []);\n for (const [nodeId, layer] of layers) {\n layersArray[layer].push(nodeId);\n }\n\n return layersArray;\n}\n\n/**\n * Insert dummy nodes for edges that span multiple layers.\n * Returns updated layers array.\n */\nexport function insertDummyNodes(graph: Graph, layers: string[][]): string[][] {\n let dummyCounter = 0;\n const edgesToProcess = [...graph.edges.values()];\n\n for (const edge of edgesToProcess) {\n const fromNode = graph.nodes.get(edge.from);\n const toNode = graph.nodes.get(edge.to);\n if (!fromNode || !toNode) continue;\n\n const fromLayer = fromNode.layer;\n const toLayer = toNode.layer;\n const span = toLayer - fromLayer;\n\n if (span <= 1) continue;\n\n // Remove original edge\n graph.removeEdge(edge.id);\n\n // Create chain of dummy nodes and edges\n let prevNodeId = edge.from;\n let prevHandleId = edge.fromHandle;\n\n for (let l = fromLayer + 1; l < toLayer; l++) {\n const dummyId = `__dummy_${dummyCounter++}`;\n\n graph.addNode({\n id: dummyId,\n width: 0,\n height: 0,\n handles: [\n { id: 'in', type: 'input', position: 'top', offset: 0.5 },\n { id: 'out', type: 'output', position: 'bottom', offset: 0.5 },\n ],\n isDummy: true,\n layer: l,\n order: -1,\n x: 0,\n y: 0,\n });\n\n layers[l].push(dummyId);\n\n graph.addEdge({\n id: `__dedge_${dummyCounter}_${l}_in`,\n from: prevNodeId,\n to: dummyId,\n fromHandle: prevHandleId,\n toHandle: 'in',\n reversed: edge.reversed,\n originalId: edge.originalId,\n });\n\n prevNodeId = dummyId;\n prevHandleId = 'out';\n }\n\n // Final edge to target\n graph.addEdge({\n id: `__dedge_${dummyCounter}_final`,\n from: prevNodeId,\n to: edge.to,\n fromHandle: prevHandleId,\n toHandle: edge.toHandle,\n reversed: edge.reversed,\n originalId: edge.originalId,\n });\n }\n\n return layers;\n}\n","import { Graph } from '../graph';\n\n/**\n * Minimize edge crossings using barycenter heuristic with transpose improvement.\n */\nexport function minimizeCrossings(\n graph: Graph,\n layers: string[][],\n iterations: number\n): string[][] {\n if (layers.length <= 1) return layers;\n\n const totalNodes = layers.reduce((s, l) => s + l.length, 0);\n\n // Adaptive: reduce iterations for large graphs\n const effectiveIter = totalNodes > 500\n ? Math.min(iterations, 6)\n : totalNodes > 200\n ? Math.min(iterations, 12)\n : iterations;\n\n // Skip transpose for very large layers\n const skipTranspose = totalNodes > 800;\n\n // Initialize node orders\n for (let l = 0; l < layers.length; l++) {\n for (let i = 0; i < layers[l].length; i++) {\n const node = graph.nodes.get(layers[l][i]);\n if (node) node.order = i;\n }\n }\n\n let bestLayers = layers.map(l => [...l]);\n let bestCrossings = countAllCrossings(graph, layers);\n let noImprovementCount = 0;\n\n for (let iter = 0; iter < effectiveIter; iter++) {\n // Down sweep\n for (let l = 1; l < layers.length; l++) {\n orderByBarycenter(graph, layers, l, 'up');\n }\n\n // Up sweep\n for (let l = layers.length - 2; l >= 0; l--) {\n orderByBarycenter(graph, layers, l, 'down');\n }\n\n // Transpose improvement\n if (!skipTranspose) {\n for (let l = 0; l < layers.length; l++) {\n if (layers[l].length <= 100) {\n transposeImprove(graph, layers, l);\n }\n }\n }\n\n const crossings = countAllCrossings(graph, layers);\n if (crossings < bestCrossings) {\n bestCrossings = crossings;\n bestLayers = layers.map(l => [...l]);\n noImprovementCount = 0;\n } else {\n noImprovementCount++;\n }\n\n if (crossings === 0 || noImprovementCount >= 3) break;\n }\n\n // Restore best ordering\n for (let l = 0; l < layers.length; l++) {\n layers[l] = bestLayers[l];\n for (let i = 0; i < layers[l].length; i++) {\n const node = graph.nodes.get(layers[l][i]);\n if (node) node.order = i;\n }\n }\n\n return layers;\n}\n\nfunction orderByBarycenter(\n graph: Graph,\n layers: string[][],\n layerIndex: number,\n direction: 'up' | 'down'\n): void {\n const layer = layers[layerIndex];\n const adjLayerIndex = direction === 'up' ? layerIndex - 1 : layerIndex + 1;\n\n if (adjLayerIndex < 0 || adjLayerIndex >= layers.length) return;\n\n // Build position lookup for adjacent layer using node.order\n const adjLayerSet = new Set(layers[adjLayerIndex]);\n\n const barycenters = new Map<string, number>();\n\n for (let i = 0; i < layer.length; i++) {\n const nodeId = layer[i];\n\n // Get neighbor positions directly using node.order\n let sum = 0;\n let count = 0;\n\n if (direction === 'up') {\n const inEdgeIds = graph.inEdges.get(nodeId);\n if (inEdgeIds) {\n for (const eid of inEdgeIds) {\n const edge = graph.edges.get(eid);\n if (edge && adjLayerSet.has(edge.from)) {\n const neighbor = graph.nodes.get(edge.from);\n if (neighbor) {\n sum += neighbor.order;\n count++;\n }\n }\n }\n }\n } else {\n const outEdgeIds = graph.outEdges.get(nodeId);\n if (outEdgeIds) {\n for (const eid of outEdgeIds) {\n const edge = graph.edges.get(eid);\n if (edge && adjLayerSet.has(edge.to)) {\n const neighbor = graph.nodes.get(edge.to);\n if (neighbor) {\n sum += neighbor.order;\n count++;\n }\n }\n }\n }\n }\n\n barycenters.set(nodeId, count > 0 ? sum / count : i);\n }\n\n layer.sort((a, b) => barycenters.get(a)! - barycenters.get(b)!);\n\n for (let i = 0; i < layer.length; i++) {\n const node = graph.nodes.get(layer[i]);\n if (node) node.order = i;\n }\n}\n\nfunction transposeImprove(graph: Graph, layers: string[][], layerIndex: number): void {\n const layer = layers[layerIndex];\n if (layer.length <= 1) return;\n\n let improved = true;\n let passes = 0;\n\n while (improved && passes < 2) {\n improved = false;\n passes++;\n for (let i = 0; i < layer.length - 1; i++) {\n const nodeA = layer[i];\n const nodeB = layer[i + 1];\n\n const crossingsBefore = countPairCrossings(graph, layers, layerIndex, nodeA, nodeB);\n\n // Swap in-place\n layer[i] = nodeB;\n layer[i + 1] = nodeA;\n const nA = graph.nodes.get(nodeA);\n const nB = graph.nodes.get(nodeB);\n if (nA) nA.order = i + 1;\n if (nB) nB.order = i;\n\n const crossingsAfter = countPairCrossings(graph, layers, layerIndex, nodeB, nodeA);\n\n if (crossingsAfter < crossingsBefore) {\n improved = true;\n } else {\n // Revert\n layer[i] = nodeA;\n layer[i + 1] = nodeB;\n if (nA) nA.order = i;\n if (nB) nB.order = i + 1;\n }\n }\n }\n}\n\n/**\n * Count crossings involving a specific pair of adjacent nodes using node.order directly.\n */\nfunction countPairCrossings(\n graph: Graph,\n layers: string[][],\n layerIndex: number,\n nodeA: string,\n nodeB: string\n): number {\n let crossings = 0;\n\n // Check with upper layer\n if (layerIndex > 0) {\n const upperLayer = new Set(layers[layerIndex - 1]);\n\n const predsA: number[] = [];\n const predsB: number[] = [];\n\n const inA = graph.inEdges.get(nodeA);\n if (inA) {\n for (const eid of inA) {\n const edge = graph.edges.get(eid);\n if (edge && upperLayer.has(edge.from)) {\n const n = graph.nodes.get(edge.from);\n if (n) predsA.push(n.order);\n }\n }\n }\n\n const inB = graph.inEdges.get(nodeB);\n if (inB) {\n for (const eid of inB) {\n const edge = graph.edges.get(eid);\n if (edge && upperLayer.has(edge.from)) {\n const n = graph.nodes.get(edge.from);\n if (n) predsB.push(n.order);\n }\n }\n }\n\n for (const pA of predsA) {\n for (const pB of predsB) {\n if (pA > pB) crossings++;\n }\n }\n }\n\n // Check with lower layer\n if (layerIndex < layers.length - 1) {\n const lowerLayer = new Set(layers[layerIndex + 1]);\n\n const succsA: number[] = [];\n const succsB: number[] = [];\n\n const outA = graph.outEdges.get(nodeA);\n if (outA) {\n for (const eid of outA) {\n const edge = graph.edges.get(eid);\n if (edge && lowerLayer.has(edge.to)) {\n const n = graph.nodes.get(edge.to);\n if (n) succsA.push(n.order);\n }\n }\n }\n\n const outB = graph.outEdges.get(nodeB);\n if (outB) {\n for (const eid of outB) {\n const edge = graph.edges.get(eid);\n if (edge && lowerLayer.has(edge.to)) {\n const n = graph.nodes.get(edge.to);\n if (n) succsB.push(n.order);\n }\n }\n }\n\n for (const sA of succsA) {\n for (const sB of succsB) {\n if (sA > sB) crossings++;\n }\n }\n }\n\n return crossings;\n}\n\nexport function countAllCrossings(graph: Graph, layers: string[][]): number {\n let total = 0;\n for (let l = 0; l < layers.length - 1; l++) {\n total += countLayerCrossings(graph, layers[l], layers[l + 1]);\n }\n return total;\n}\n\n/**\n * Count crossings between two adjacent layers using merge-sort based\n * inversion counting. O(E log V) instead of O(E^2).\n */\nfunction countLayerCrossings(\n graph: Graph,\n upperLayer: string[],\n lowerLayer: string[]\n): number {\n const lowerPos = new Map<string, number>();\n lowerLayer.forEach((id, pos) => lowerPos.set(id, pos));\n\n // Collect edge endpoint pairs sorted by upper position\n const edgePairs: [number, number][] = [];\n for (let uPos = 0; uPos < upperLayer.length; uPos++) {\n const nodeId = upperLayer[uPos];\n const outEdgeIds = graph.outEdges.get(nodeId);\n if (!outEdgeIds) continue;\n for (const eid of outEdgeIds) {\n const edge = graph.edges.get(eid);\n if (!edge) continue;\n const lp = lowerPos.get(edge.to);\n if (lp !== undefined) {\n edgePairs.push([uPos, lp]);\n }\n }\n }\n\n if (edgePairs.length <= 1) return 0;\n\n // Sort by upper position, then by lower\n edgePairs.sort((a, b) => a[0] - b[0] || a[1] - b[1]);\n\n // Count inversions in the lower positions\n const lowerPositions = edgePairs.map(e => e[1]);\n return mergeSortCount(lowerPositions);\n}\n\nfunction mergeSortCount(arr: number[]): number {\n if (arr.length <= 1) return 0;\n\n const mid = arr.length >> 1;\n const left = arr.slice(0, mid);\n const right = arr.slice(mid);\n\n let count = mergeSortCount(left) + mergeSortCount(right);\n\n let i = 0, j = 0, k = 0;\n while (i < left.length && j < right.length) {\n if (left[i] <= right[j]) {\n arr[k++] = left[i++];\n } else {\n count += left.length - i;\n arr[k++] = right[j++];\n }\n }\n\n while (i < left.length) arr[k++] = left[i++];\n while (j < right.length) arr[k++] = right[j++];\n\n return count;\n}\n","import { Graph } from '../graph';\nimport { LayoutDirection, ResolvedOptions } from '../types';\n\n/**\n * Assign x,y coordinates to all nodes using a median-based iterative approach.\n */\nexport function assignCoordinates(\n graph: Graph,\n layers: string[][],\n options: ResolvedOptions\n): void {\n const isHorizontal = options.direction === 'LR' || options.direction === 'RL';\n const isReversed = options.direction === 'BT' || options.direction === 'RL';\n\n assignRankPositions(graph, layers, options, isHorizontal, isReversed);\n assignOrderPositions(graph, layers, options, isHorizontal);\n optimizePositions(graph, layers, options, isHorizontal);\n}\n\n/**\n * Assign positions along the rank axis (y for TB/BT, x for LR/RL).\n */\nfunction assignRankPositions(\n graph: Graph,\n layers: string[][],\n options: ResolvedOptions,\n isHorizontal: boolean,\n isReversed: boolean\n): void {\n // Compute layer sizes (max node size in rank direction)\n const layerSizes: number[] = [];\n for (const layer of layers) {\n let maxSize = 0;\n for (const nodeId of layer) {\n const node = graph.nodes.get(nodeId)!;\n const size = isHorizontal ? node.width : node.height;\n maxSize = Math.max(maxSize, size);\n }\n layerSizes.push(maxSize);\n }\n\n // Compute cumulative positions\n const layerPositions: number[] = [];\n let pos = 0;\n for (let l = 0; l < layers.length; l++) {\n layerPositions.push(pos);\n pos += layerSizes[l] + options.layerSpacing;\n }\n\n // If reversed, flip positions\n if (isReversed) {\n const totalSize = pos - options.layerSpacing;\n for (let l = 0; l < layerPositions.length; l++) {\n layerPositions[l] = totalSize - layerPositions[l] - layerSizes[l];\n }\n }\n\n // Assign positions\n for (let l = 0; l < layers.length; l++) {\n for (const nodeId of layers[l]) {\n const node = graph.nodes.get(nodeId)!;\n const nodeSize = isHorizontal ? node.width : node.height;\n const offset = (layerSizes[l] - nodeSize) / 2;\n\n if (isHorizontal) {\n node.x = layerPositions[l] + offset;\n } else {\n node.y = layerPositions[l] + offset;\n }\n }\n }\n}\n\n/**\n * Assign positions along the order axis (x for TB/BT, y for LR/RL).\n * Initial even spacing, centered.\n */\nfunction assignOrderPositions(\n graph: Graph,\n layers: string[][],\n options: ResolvedOptions,\n isHorizontal: boolean\n): void {\n for (const layer of layers) {\n let pos = 0;\n\n for (const nodeId of layer) {\n const node = graph.nodes.get(nodeId)!;\n const size = isHorizontal ? node.height : node.width;\n\n if (isHorizontal) {\n node.y = pos;\n } else {\n node.x = pos;\n }\n\n pos += size + options.nodeSpacing;\n }\n\n // Center the layer\n const totalSize = pos - options.nodeSpacing;\n const centerOffset = -totalSize / 2;\n\n for (const nodeId of layer) {\n const node = graph.nodes.get(nodeId)!;\n if (isHorizontal) {\n node.y += centerOffset;\n } else {\n node.x += centerOffset;\n }\n }\n }\n}\n\n/**\n * Iteratively optimize positions by aligning nodes with their connected neighbors.\n */\nfunction optimizePositions(\n graph: Graph,\n layers: string[][],\n options: ResolvedOptions,\n isHorizontal: boolean\n): void {\n for (let iter = 0; iter < options.coordinateOptimizationIterations; iter++) {\n // Down sweep\n for (let l = 0; l < layers.length; l++) {\n optimizeLayer(graph, layers[l], options, isHorizontal);\n }\n\n // Up sweep\n for (let l = layers.length - 1; l >= 0; l--) {\n optimizeLayer(graph, layers[l], options, isHorizontal);\n }\n }\n\n centerAllLayers(graph, layers, isHorizontal);\n}\n\nfunction optimizeLayer(\n graph: Graph,\n layer: string[],\n options: ResolvedOptions,\n isHorizontal: boolean\n): void {\n if (layer.length === 0) return;\n\n // Compute desired positions\n const desired = new Map<string, number>();\n\n for (const nodeId of layer) {\n const node = graph.nodes.get(nodeId)!;\n const connected = [...graph.predecessors(nodeId), ...graph.successors(nodeId)];\n\n if (connected.length === 0) {\n desired.set(nodeId, getOrderPos(node, isHorizontal));\n continue;\n }\n\n // Median of connected nodes' center positions\n const positions = connected\n .map(cId => {\n const c = graph.nodes.get(cId)!;\n return getOrderPos(c, isHorizontal) + getOrderSize(c, isHorizontal) / 2;\n })\n .sort((a, b) => a - b);\n\n const nodeSize = getOrderSize(node, isHorizontal);\n const median = positions.length % 2 === 0\n ? (positions[positions.length / 2 - 1] + positions[positions.length / 2]) / 2\n : positions[Math.floor(positions.length / 2)];\n\n desired.set(nodeId, median - nodeSize / 2);\n }\n\n // Forward pass: apply desired positions with spacing constraints\n for (let i = 0; i < layer.length; i++) {\n const nodeId = layer[i];\n const node = graph.nodes.get(nodeId)!;\n let desiredPos = desired.get(nodeId)!;\n\n if (i > 0) {\n const prevId = layer[i - 1];\n const prev = graph.nodes.get(prevId)!;\n const prevEnd = getOrderPos(prev, isHorizontal) + getOrderSize(prev, isHorizontal);\n desiredPos = Math.max(desiredPos, prevEnd + options.nodeSpacing);\n }\n\n setOrderPos(node, isHorizontal, desiredPos);\n }\n\n // Backward pass: fix overlaps from right\n for (let i = layer.length - 2; i >= 0; i--) {\n const nodeId = layer[i];\n const node = graph.nodes.get(nodeId)!;\n const nextId = layer[i + 1];\n const next = graph.nodes.get(nextId)!;\n\n const nodeEnd = getOrderPos(node, isHorizontal) + getOrderSize(node, isHorizontal);\n const nextStart = getOrderPos(next, isHorizontal);\n\n if (nodeEnd + options.nodeSpacing > nextStart) {\n setOrderPos(node, isHorizontal, nextStart - options.nodeSpacing - getOrderSize(node, isHorizontal));\n }\n }\n}\n\nfunction centerAllLayers(\n graph: Graph,\n layers: string[][],\n isHorizontal: boolean\n): void {\n if (layers.length === 0) return;\n\n // Find global bounds\n let globalMin = Infinity;\n let globalMax = -Infinity;\n\n for (const layer of layers) {\n for (const nodeId of layer) {\n const node = graph.nodes.get(nodeId)!;\n const pos = getOrderPos(node, isHorizontal);\n const size = getOrderSize(node, isHorizontal);\n globalMin = Math.min(globalMin, pos);\n globalMax = Math.max(globalMax, pos + size);\n }\n }\n\n // Shift everything so the layout starts at 0\n const offset = -globalMin;\n for (const layer of layers) {\n for (const nodeId of layer) {\n const node = graph.nodes.get(nodeId)!;\n setOrderPos(node, isHorizontal, getOrderPos(node, isHorizontal) + offset);\n }\n }\n\n // Also shift rank positions to start at 0\n let rankMin = Infinity;\n for (const layer of layers) {\n for (const nodeId of layer) {\n const node = graph.nodes.get(nodeId)!;\n const pos = isHorizontal ? node.x : node.y;\n rankMin = Math.min(rankMin, pos);\n }\n }\n\n if (rankMin !== 0) {\n for (const layer of layers) {\n for (const nodeId of layer) {\n const node = graph.nodes.get(nodeId)!;\n if (isHorizontal) {\n node.x -= rankMin;\n } else {\n node.y -= rankMin;\n }\n }\n }\n }\n}\n\nfunction getOrderPos(node: { x: number; y: number }, isHorizontal: boolean): number {\n return isHorizontal ? node.y : node.x;\n}\n\nfunction setOrderPos(node: { x: number; y: number }, isHorizontal: boolean, value: number): void {\n if (isHorizontal) {\n node.y = value;\n } else {\n node.x = value;\n }\n}\n\nfunction getOrderSize(node: { width: number; height: number }, isHorizontal: boolean): number {\n return isHorizontal ? node.height : node.width;\n}\n","import { Graph, getHandlePosition, getHandleDirection } from '../graph';\nimport { Point, HandleSide, LayoutDirection } from '../types';\n\nexport interface RoutedEdge {\n id: string;\n from: string;\n to: string;\n fromHandle: string;\n toHandle: string;\n points: Point[];\n}\n\n/**\n * Route all edges with orthogonal paths.\n * Reconstructs original edges from dummy node chains.\n */\nexport function routeEdges(\n graph: Graph,\n direction: LayoutDirection,\n edgeMargin: number\n): RoutedEdge[] {\n const chains = collectEdgeChains(graph);\n const routes: RoutedEdge[] = [];\n\n for (const chain of chains) {\n routes.push(routeChain(graph, chain, direction, edgeMargin));\n }\n\n return routes;\n}\n\ninterface EdgeChain {\n originalId: string;\n from: string;\n to: string;\n fromHandle: string;\n toHandle: string;\n dummyNodes: string[];\n reversed: boolean;\n}\n\nfunction collectEdgeChains(graph: Graph): EdgeChain[] {\n const chains: EdgeChain[] = [];\n const visited = new Set<string>();\n\n for (const [edgeId, edge] of graph.edges) {\n if (visited.has(edgeId)) continue;\n\n const fromNode = graph.nodes.get(edge.from);\n if (!fromNode || fromNode.isDummy) continue;\n\n const dummyNodes: string[] = [];\n let currentEdge = edge;\n visited.add(edgeId);\n\n // Follow through dummy nodes\n while (true) {\n const toNode = graph.nodes.get(currentEdge.to);\n if (!toNode || !toNode.isDummy) break;\n\n dummyNodes.push(currentEdge.to);\n\n const outEdgeIds = graph.outEdges.get(currentEdge.to);\n if (!outEdgeIds || outEdgeIds.size === 0) break;\n\n // Find the edge with matching originalId\n let nextEdge = null;\n for (const eid of outEdgeIds) {\n const e = graph.edges.get(eid);\n if (e && e.originalId === edge.originalId) {\n nextEdge = e;\n visited.add(eid);\n break;\n }\n }\n\n if (!nextEdge) {\n // Fallback: take any outgoing edge\n const eid = outEdgeIds.values().next().value;\n if (!eid) break;\n nextEdge = graph.edges.get(eid);\n if (!nextEdge) break;\n visited.add(eid);\n }\n\n currentEdge = nextEdge;\n }\n\n chains.push({\n originalId: edge.originalId,\n from: edge.from,\n to: currentEdge.to,\n fromHandle: edge.fromHandle,\n toHandle: currentEdge.toHandle,\n dummyNodes,\n reversed: edge.reversed,\n });\n }\n\n return chains;\n}\n\nfunction routeChain(\n graph: Graph,\n chain: EdgeChain,\n direction: LayoutDirection,\n margin: number\n): RoutedEdge {\n const fromNode = graph.nodes.get(chain.from)!;\n const toNode = graph.nodes.get(chain.to)!;\n\n // Determine actual from/to based on reversal\n const actualFrom = chain.reversed ? chain.to : chain.from;\n const actualTo = chain.reversed ? chain.from : chain.to;\n const actualFromHandle = chain.reversed ? chain.toHandle : chain.fromHandle;\n const actualToHandle = chain.reversed ? chain.fromHandle : chain.toHandle;\n\n const sourceNode = chain.reversed ? toNode : fromNode;\n const targetNode = chain.reversed ? fromNode : toNode;\n\n const sourcePos = getHandlePosition(sourceNode, actualFromHandle);\n const targetPos = getHandlePosition(targetNode, actualToHandle);\n\n const sourceHandle = sourceNode.handles.find(h => h.id === actualFromHandle);\n const targetHandle = targetNode.handles.find(h => h.id === actualToHandle);\n\n const sourceSide = sourceHandle?.position || getDefaultSourceSide(direction);\n const targetSide = targetHandle?.position || getDefaultTargetSide(direction);\n\n // Build waypoints\n const rawPoints: Point[] = [];\n\n // Source handle\n rawPoints.push(sourcePos);\n\n // Exit point\n const exitDir = getHandleDirection(sourceSide);\n rawPoints.push({\n x: sourcePos.x + exitDir.x * margin,\n y: sourcePos.y + exitDir.y * margin,\n });\n\n // Dummy node positions (in correct order based on reversal)\n const dummies = chain.reversed ? [...chain.dummyNodes].reverse() : chain.dummyNodes;\n for (const dummyId of dummies) {\n const dummy = graph.nodes.get(dummyId)!;\n rawPoints.push({ x: dummy.x, y: dummy.y });\n }\n\n // Entry point\n const entryDir = getHandleDirection(targetSide);\n rawPoints.push({\n x: targetPos.x + entryDir.x * margin,\n y: targetPos.y + entryDir.y * margin,\n });\n\n // Target handle\n rawPoints.push(targetPos);\n\n // Make orthogonal\n const points = makeOrthogonal(rawPoints, direction);\n\n return {\n id: chain.originalId,\n from: actualFrom,\n to: actualTo,\n fromHandle: actualFromHandle,\n toHandle: actualToHandle,\n points,\n };\n}\n\n/**\n * Insert bends to make the path orthogonal (only horizontal/vertical segments).\n */\nfunction makeOrthogonal(points: Point[], direction: LayoutDirection): Point[] {\n if (points.length < 2) return points;\n\n const result: Point[] = [points[0]];\n const isVerticalFlow = direction === 'TB' || direction === 'BT';\n\n for (let i = 1; i < points.length; i++) {\n const prev = result[result.length - 1];\n const curr = points[i];\n\n const dx = Math.abs(prev.x - curr.x);\n const dy = Math.abs(prev.y - curr.y);\n\n // If already aligned, just add the point\n if (dx < 0.01 || dy < 0.01) {\n result.push(curr);\n continue;\n }\n\n // Need a bend\n if (isVerticalFlow) {\n // Prefer vertical-then-horizontal routing\n const midY = (prev.y + curr.y) / 2;\n result.push({ x: prev.x, y: midY });\n result.push({ x: curr.x, y: midY });\n } else {\n // Prefer horizontal-then-vertical routing\n const midX = (prev.x + curr.x) / 2;\n result.push({ x: midX, y: prev.y });\n result.push({ x: midX, y: curr.y });\n }\n\n result.push(curr);\n }\n\n return cleanupPoints(result);\n}\n\n/**\n * Remove redundant collinear points.\n */\nfunction cleanupPoints(points: Point[]): Point[] {\n if (points.length <= 2) return points;\n\n const result: Point[] = [points[0]];\n\n for (let i = 1; i < points.length - 1; i++) {\n const prev = result[result.length - 1];\n const curr = points[i];\n const next = points[i + 1];\n\n // Skip if collinear\n const sameX = Math.abs(prev.x - curr.x) < 0.01 && Math.abs(curr.x - next.x) < 0.01;\n const sameY = Math.abs(prev.y - curr.y) < 0.01 && Math.abs(curr.y - next.y) < 0.01;\n\n if (!sameX && !sameY) {\n result.push(curr);\n } else if (sameX || sameY) {\n // Collinear - skip this point\n continue;\n } else {\n result.push(curr);\n }\n }\n\n result.push(points[points.length - 1]);\n return result;\n}\n\nfunction getDefaultSourceSide(direction: LayoutDirection): HandleSide {\n switch (direction) {\n case 'TB': return 'bottom';\n case 'BT': return 'top';\n case 'LR': return 'right';\n case 'RL': return 'left';\n }\n}\n\nfunction getDefaultTargetSide(direction: LayoutDirection): HandleSide {\n switch (direction) {\n case 'TB': return 'top';\n case 'BT': return 'bottom';\n case 'LR': return 'left';\n case 'RL': return 'right';\n }\n}\n","import { LayoutInput, LayoutOptions, LayoutResult, NodeOutput, EdgeOutput, HandleOutput, resolveOptions, ResolvedOptions } from './types';\nimport { Graph, buildGraph, getHandlePosition } from './graph';\nimport { breakCycles } from './algorithms/cycle-breaking';\nimport { assignLayers, insertDummyNodes } from './algorithms/layer-assignment';\nimport { minimizeCrossings } from './algorithms/crossing-minimization';\nimport { assignCoordinates } from './algorithms/coordinate-assignment';\nimport { routeEdges } from './algorithms/edge-routing';\n\n/**\n * Compute a complete layout for the given graph.\n * This is the main entry point for one-shot layout computation.\n */\nexport function layout(input: LayoutInput, options?: LayoutOptions): LayoutResult {\n const resolved = resolveOptions(options);\n const graph = buildGraph(input.nodes, input.edges);\n return computeLayout(graph, resolved);\n}\n\n/**\n * Internal layout computation on an already-built graph.\n */\nexport function computeLayout(graph: Graph, options: ResolvedOptions): LayoutResult {\n if (graph.nodes.size === 0) {\n return { nodes: [], edges: [] };\n }\n\n // Phase 1: Break cycles\n breakCycles(graph);\n\n // Phase 2: Assign layers\n let layers = assignLayers(graph);\n\n // Phase 3: Insert dummy nodes for long edges\n layers = insertDummyNodes(graph, layers);\n\n // Phase 4: Minimize crossings\n layers = minimizeCrossings(graph, layers, options.crossingMinimizationIterations);\n\n // Phase 5: Assign coordinates\n assignCoordinates(graph, layers, options);\n\n // Phase 6: Route edges\n const routedEdges = routeEdges(graph, options.direction, options.edgeMargin);\n\n // Build output (exclude dummy nodes)\n return buildResult(graph, routedEdges);\n}\n\nfunction buildResult(graph: Graph, routedEdges: { id: string; from: string; to: string; fromHandle: string; toHandle: string; points: { x: number; y: number }[] }[]): LayoutResult {\n const nodes: NodeOutput[] = [];\n const edges: EdgeOutput[] = [];\n\n for (const [, node] of graph.nodes) {\n if (node.isDummy) continue;\n\n const handles: HandleOutput[] = node.handles.map(h => {\n const pos = getHandlePosition(node, h.id);\n return {\n id: h.id,\n type: h.type,\n position: h.position,\n x: pos.x,\n y: pos.y,\n };\n });\n\n nodes.push({\n id: node.id,\n x: node.x,\n y: node.y,\n width: node.width,\n height: node.height,\n handles,\n });\n }\n\n for (const route of routedEdges) {\n edges.push({\n id: route.id,\n from: route.from,\n to: route.to,\n fromHandle: route.fromHandle,\n toHandle: route.toHandle,\n points: route.points,\n });\n }\n\n return { nodes, edges };\n}\n","import { LayoutInput, LayoutOptions, LayoutResult, NodeInput, EdgeInput, resolveOptions, ResolvedOptions } from './types';\nimport { Graph, buildGraph, getHandlePosition } from './graph';\nimport { breakCycles } from './algorithms/cycle-breaking';\nimport { assignLayers, insertDummyNodes } from './algorithms/layer-assignment';\nimport { minimizeCrossings } from './algorithms/crossing-minimization';\nimport { assignCoordinates } from './algorithms/coordinate-assignment';\nimport { routeEdges } from './algorithms/edge-routing';\nimport { computeLayout } from './layout';\n\n/**\n * Incremental layout engine.\n * Maintains layout state and supports adding/removing nodes\n * without full recomputation.\n */\nexport class IncrementalLayout {\n private options: ResolvedOptions;\n private inputNodes: Map<string, NodeInput> = new Map();\n private inputEdges: Map<string, EdgeInput> = new Map();\n private lastResult: LayoutResult | null = null;\n private nodePositions: Map<string, { x: number; y: number }> = new Map();\n\n constructor(options?: LayoutOptions) {\n this.options = resolveOptions(options);\n }\n\n /**\n * Set the full graph and compute a complete layout.\n */\n setGraph(input: LayoutInput): LayoutResult {\n this.inputNodes.clear();\n this.inputEdges.clear();\n\n for (const node of input.nodes) {\n this.inputNodes.set(node.id, node);\n }\n for (const edge of input.edges) {\n this.inputEdges.set(edge.id, edge);\n }\n\n return this.recompute();\n }\n\n /**\n * Add nodes and edges incrementally.\n * Attempts to minimize layout changes for existing nodes.\n */\n addNodes(nodes: NodeInput[], edges?: EdgeInput[]): LayoutResult {\n for (const node of nodes) {\n this.inputNodes.set(node.id, node);\n }\n if (edges) {\n for (const edge of edges) {\n this.inputEdges.set(edge.id, edge);\n }\n }\n\n return this.recomputeIncremental(\n new Set(nodes.map(n => n.id)),\n new Set(edges?.map(e => e.id) || [])\n );\n }\n\n /**\n * Remove nodes (and their connected edges) from the layout.\n */\n removeNodes(nodeIds: string[]): LayoutResult {\n const removedSet = new Set(nodeIds);\n\n for (const id of nodeIds) {\n this.inputNodes.delete(id);\n }\n\n // Remove edges connected to removed nodes\n for (const [edgeId, edge] of this.inputEdges) {\n if (removedSet.has(edge.from) || removedSet.has(edge.to)) {\n this.inputEdges.delete(edgeId);\n }\n }\n\n // Remove from position cache\n for (const id of nodeIds) {\n this.nodePositions.delete(id);\n }\n\n return this.recompute();\n }\n\n /**\n * Add edges between existing nodes.\n */\n addEdges(edges: EdgeInput[]): LayoutResult {\n for (const edge of edges) {\n this.inputEdges.set(edge.id, edge);\n }\n return this.recomputeIncremental(\n new Set<string>(),\n new Set(edges.map(e => e.id))\n );\n }\n\n /**\n * Remove edges from the layout.\n */\n removeEdges(edgeIds: string[]): LayoutResult {\n for (const id of edgeIds) {\n this.inputEdges.delete(id);\n }\n return this.recompute();\n }\n\n /**\n * Get the current layout result.\n */\n getResult(): LayoutResult | null {\n return this.lastResult;\n }\n\n private recompute(): LayoutResult {\n const input: LayoutInput = {\n nodes: [...this.inputNodes.values()],\n edges: [...this.inputEdges.values()],\n };\n\n const graph = buildGraph(input.nodes, input.edges);\n this.lastResult = computeLayout(graph, this.options);\n\n // Cache positions for future incremental updates\n this.cachePositions();\n\n return this.lastResult;\n }\n\n private recomputeIncremental(\n newNodeIds: Set<string>,\n newEdgeIds: Set<string>\n ): LayoutResult {\n const input: LayoutInput = {\n nodes: [...this.inputNodes.values()],\n edges: [...this.inputEdges.values()],\n };\n\n const graph = buildGraph(input.nodes, input.edges);\n\n // Phase 1: Break cycles\n breakCycles(graph);\n\n // Phase 2: Assign layers\n let layers = assignLayers(graph);\n\n // Phase 3: Insert dummy nodes\n layers = insertDummyNodes(graph, layers);\n\n // Phase 4: Minimize crossings (full, but starting from hints)\n layers = minimizeCrossings(graph, layers, this.options.crossingMinimizationIterations);\n\n // Phase 5: Assign coordinates\n assignCoordinates(graph, layers, this.options);\n\n // Phase 6: Apply position stability for existing nodes\n this.applyStability(graph, newNodeIds);\n\n // Phase 7: Route edges\n const routedEdges = routeEdges(graph, this.options.direction, this.options.edgeMargin);\n\n // Build result\n this.lastResult = this.buildResult(graph, routedEdges);\n this.cachePositions();\n\n return this.lastResult;\n }\n\n /**\n * Apply stability: blend new positions with old positions for existing nodes.\n * This reduces visual disruption when adding new nodes.\n */\n private applyStability(graph: Graph, newNodeIds: Set<string>): void {\n if (this.nodePositions.size === 0) return;\n\n const STABILITY_WEIGHT = 0.3; // 30% old position, 70% new\n\n for (const [nodeId, node] of graph.nodes) {\n if (node.isDummy || newNodeIds.has(nodeId)) continue;\n\n const oldPos = this.nodePositions.get(nodeId);\n if (!oldPos) continue;\n\n // Blend positions\n node.x = node.x * (1 - STABILITY_WEIGHT) + oldPos.x * STABILITY_WEIGHT;\n node.y = node.y * (1 - STABILITY_WEIGHT) + oldPos.y * STABILITY_WEIGHT;\n }\n }\n\n private cachePositions(): void {\n if (!this.lastResult) return;\n this.nodePositions.clear();\n for (const node of this.lastResult.nodes) {\n this.nodePositions.set(node.id, { x: node.x, y: node.y });\n }\n }\n\n private buildResult(\n graph: Graph,\n routedEdges: { id: string; from: string; to: string; fromHandle: string; toHandle: string; points: { x: number; y: number }[] }[]\n ): LayoutResult {\n const nodes: LayoutResult['nodes'] = [];\n const edges: LayoutResult['edges'] = [];\n\n for (const [, node] of graph.nodes) {\n if (node.isDummy) continue;\n\n const handles = node.handles.map(h => {\n const pos = getHandlePosition(node, h.id);\n return {\n id: h.id,\n type: h.type,\n position: h.position,\n x: pos.x,\n y: pos.y,\n };\n });\n\n nodes.push({\n id: node.id,\n x: node.x,\n y: node.y,\n width: node.width,\n height: node.height,\n handles,\n });\n }\n\n for (const route of routedEdges) {\n edges.push({\n id: route.id,\n from: route.from,\n to: route.to,\n fromHandle: route.fromHandle,\n toHandle: route.toHandle,\n points: route.points,\n });\n }\n\n return { nodes, edges };\n }\n}\n"],"mappings":"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","names":[]}
|