@pixerate/editor 0.19.0 → 0.21.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/README.md +95 -4
- package/dist/agent/index.cjs +625 -2
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +286 -2
- package/dist/agent/index.d.ts +286 -2
- package/dist/agent/index.js +624 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/canvas/index.cjs +1240 -22
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +515 -3
- package/dist/canvas/index.d.ts +515 -3
- package/dist/canvas/index.js +1219 -1
- package/dist/canvas/index.js.map +1 -1
- package/dist/chunk-3TYMNULT.js +1367 -0
- package/dist/chunk-3TYMNULT.js.map +1 -0
- package/dist/chunk-4QPLEUL2.cjs +4480 -0
- package/dist/chunk-4QPLEUL2.cjs.map +1 -0
- package/dist/chunk-4SUNJZWB.cjs +553 -0
- package/dist/chunk-4SUNJZWB.cjs.map +1 -0
- package/dist/chunk-A7DKIA72.js +2657 -0
- package/dist/chunk-A7DKIA72.js.map +1 -0
- package/dist/chunk-AXV2ZW34.cjs +118 -0
- package/dist/chunk-AXV2ZW34.cjs.map +1 -0
- package/dist/chunk-B2ZRLN4S.js +118 -0
- package/dist/chunk-B2ZRLN4S.js.map +1 -0
- package/dist/chunk-CYFJCKC4.js +4480 -0
- package/dist/chunk-CYFJCKC4.js.map +1 -0
- package/dist/chunk-GVW4P7BG.js +2706 -0
- package/dist/chunk-GVW4P7BG.js.map +1 -0
- package/dist/chunk-JACER6TE.cjs +1 -0
- package/dist/chunk-JACER6TE.cjs.map +1 -0
- package/dist/chunk-JYRIOFEN.cjs +2657 -0
- package/dist/chunk-JYRIOFEN.cjs.map +1 -0
- package/dist/chunk-KYRZDWM4.js +299 -0
- package/dist/chunk-KYRZDWM4.js.map +1 -0
- package/dist/chunk-LA7PEGU3.cjs +299 -0
- package/dist/chunk-LA7PEGU3.cjs.map +1 -0
- package/dist/chunk-N7FG6CBO.js +1 -0
- package/dist/chunk-N7FG6CBO.js.map +1 -0
- package/dist/chunk-OYXSKQFR.js +553 -0
- package/dist/chunk-OYXSKQFR.js.map +1 -0
- package/dist/chunk-TVRC4KVT.cjs +1367 -0
- package/dist/chunk-TVRC4KVT.cjs.map +1 -0
- package/dist/chunk-U6NDQFOK.cjs +2706 -0
- package/dist/chunk-U6NDQFOK.cjs.map +1 -0
- package/dist/controller-OUdxPY-X.d.cts +754 -0
- package/dist/controller-OUdxPY-X.d.ts +754 -0
- package/dist/extensions/index.cjs +144 -3
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +9 -144
- package/dist/extensions/index.d.ts +9 -144
- package/dist/extensions/index.js +145 -4
- package/dist/grammar/index.cjs +31 -3
- package/dist/grammar/index.cjs.map +1 -1
- package/dist/grammar/index.d.cts +239 -19
- package/dist/grammar/index.d.ts +239 -19
- package/dist/grammar/index.js +31 -3
- package/dist/history/index.d.cts +2 -41
- package/dist/history/index.d.ts +2 -41
- package/dist/index-Ng1pG7JE.d.ts +899 -0
- package/dist/index-k3mFbPx_.d.cts +899 -0
- package/dist/index.cjs +457 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +99 -12
- package/dist/index.d.ts +99 -12
- package/dist/index.js +457 -20
- package/dist/index.js.map +1 -1
- package/dist/registry-iAHbqkYt.d.cts +128 -0
- package/dist/registry-iAHbqkYt.d.ts +128 -0
- package/dist/serializers/index.cjs +26 -3
- package/dist/serializers/index.cjs.map +1 -1
- package/dist/serializers/index.d.cts +119 -6
- package/dist/serializers/index.d.ts +119 -6
- package/dist/serializers/index.js +24 -1
- package/dist/spreadsheet/index.cjs +122 -2
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.d.cts +371 -313
- package/dist/spreadsheet/index.d.ts +371 -313
- package/dist/spreadsheet/index.js +127 -7
- package/dist/tokens-CyLZmIei.d.cts +76 -0
- package/dist/tokens-CyLZmIei.d.ts +76 -0
- package/dist/track-changes-G8JcWB8b.d.cts +306 -0
- package/dist/track-changes-G8JcWB8b.d.ts +306 -0
- package/dist/types-BZgcDsC5.d.cts +42 -0
- package/dist/types-BZgcDsC5.d.ts +42 -0
- package/dist/{types-JV3S8VeR.d.cts → types-DMe0vFB1.d.cts} +1 -1
- package/dist/{types-JV3S8VeR.d.ts → types-DMe0vFB1.d.ts} +1 -1
- package/package.json +11 -4
- package/dist/chunk-7FWEWE6T.js +0 -1888
- package/dist/chunk-7FWEWE6T.js.map +0 -1
- package/dist/chunk-AIZUKWTL.js +0 -1715
- package/dist/chunk-AIZUKWTL.js.map +0 -1
- package/dist/chunk-GLSIZKOX.js +0 -17
- package/dist/chunk-GLSIZKOX.js.map +0 -1
- package/dist/chunk-LDES3EOS.cjs +0 -1888
- package/dist/chunk-LDES3EOS.cjs.map +0 -1
- package/dist/chunk-LLUAKTLW.cjs +0 -532
- package/dist/chunk-LLUAKTLW.cjs.map +0 -1
- package/dist/chunk-MPPXH7U5.cjs +0 -336
- package/dist/chunk-MPPXH7U5.cjs.map +0 -1
- package/dist/chunk-O7LOPQMH.js +0 -336
- package/dist/chunk-O7LOPQMH.js.map +0 -1
- package/dist/chunk-QGVMBCT5.js +0 -532
- package/dist/chunk-QGVMBCT5.js.map +0 -1
- package/dist/chunk-SEDR75VH.cjs +0 -17
- package/dist/chunk-SEDR75VH.cjs.map +0 -1
- package/dist/chunk-YQCI4CCN.cjs +0 -1715
- package/dist/chunk-YQCI4CCN.cjs.map +0 -1
- package/dist/mention-Dcevh3ff.d.cts +0 -32
- package/dist/mention-Dcevh3ff.d.ts +0 -32
- package/dist/tokens-7kRTEtPb.d.cts +0 -39
- package/dist/tokens-7kRTEtPb.d.ts +0 -39
package/dist/canvas/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/canvas/clock.ts","../../src/canvas/trajectory.ts","../../src/canvas/displacement.ts","../../src/canvas/clipboard.ts","../../src/canvas/view.ts","../../src/canvas/streaming.ts"],"sourcesContent":["/**\n * The time source that canvas animations and agent performances play on.\n *\n * Defaults to `realClock` (requestAnimationFrame and setTimeout).\n * A `ManualClock` moves only when told to via `advance(ms)` or `tick(fps)`,\n * enabling deterministic frame-by-frame stepping for testing, video generation,\n * or headless server environments.\n */\n\nexport interface Clock {\n\t/** Current time in milliseconds. */\n\tnow(): number;\n\t/** Resolves on the next animation frame. */\n\tframe(): Promise<void>;\n\t/** Resolves after `ms` milliseconds of this clock's time. */\n\tsleep(ms: number): Promise<void>;\n\t/**\n\t * Whether the clock follows wall time. Live clocks stop or degrade when the\n\t * tab is in the background (browsers pause animation frames), so transitions\n\t * can commit immediately rather than leaving operations hanging.\n\t */\n\treadonly live: boolean;\n}\n\n/** Whether the browser tab is hidden (where RAF pauses). */\nexport const pageHidden = (): boolean =>\n\ttypeof document !== 'undefined' && document.hidden;\n\n/** Real-time clock using requestAnimationFrame and setTimeout. */\nexport const realClock: Clock = {\n\tlive: true,\n\tnow: () => (typeof performance !== 'undefined' ? performance.now() : Date.now()),\n\tframe: () =>\n\t\tnew Promise<void>((resolve) => {\n\t\t\tif (typeof requestAnimationFrame === 'function' && !pageHidden()) {\n\t\t\t\trequestAnimationFrame(() => resolve());\n\t\t\t} else {\n\t\t\t\tsetTimeout(resolve, 16);\n\t\t\t}\n\t\t}),\n\tsleep: (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, Math.max(0, ms)))\n};\n\nconst settle = () => new Promise<void>((resolve) => setTimeout(resolve, 0));\n\n/**\n * A deterministic clock that only moves forward when `advance` or `tick` is called.\n * Allows step-by-step frame testing and video rendering without waiting for real time.\n */\nexport class ManualClock implements Clock {\n\treadonly live = false;\n\tprivate time: number;\n\tprivate frames: (() => void)[] = [];\n\tprivate sleepers: { at: number; seq: number; resolve: () => void }[] = [];\n\tprivate seq = 0;\n\n\tconstructor(start = 0) {\n\t\tthis.time = start;\n\t}\n\n\tpublic now(): number {\n\t\treturn this.time;\n\t}\n\n\tpublic frame(): Promise<void> {\n\t\treturn new Promise<void>((resolve) => this.frames.push(resolve));\n\t}\n\n\tpublic sleep(ms: number): Promise<void> {\n\t\treturn new Promise<void>((resolve) =>\n\t\t\tthis.sleepers.push({\n\t\t\t\tat: this.time + Math.max(0, ms),\n\t\t\t\tseq: this.seq++,\n\t\t\t\tresolve\n\t\t\t})\n\t\t);\n\t}\n\n\t/** Whether any frames or sleep timers are currently pending. */\n\tpublic get pending(): boolean {\n\t\treturn this.frames.length > 0 || this.sleepers.length > 0;\n\t}\n\n\t/** Advances time by `ms`, resolving due sleep timers in order, followed by queued frames. */\n\tpublic async advance(ms: number): Promise<void> {\n\t\tconst end = this.time + Math.max(0, ms);\n\t\tawait settle();\n\n\t\twhile (true) {\n\t\t\tlet next: (typeof this.sleepers)[number] | undefined;\n\t\t\tfor (const s of this.sleepers) {\n\t\t\t\tif (s.at <= end && (!next || s.at < next.at || (s.at === next.at && s.seq < next.seq))) {\n\t\t\t\t\tnext = s;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!next) break;\n\n\t\t\tthis.sleepers.splice(this.sleepers.indexOf(next), 1);\n\t\t\tthis.time = Math.max(this.time, next.at);\n\t\t\tnext.resolve();\n\t\t\tawait settle();\n\t\t}\n\n\t\tthis.time = end;\n\t\tconst dueFrames = this.frames.splice(0, this.frames.length);\n\t\tfor (const resolveFrame of dueFrames) {\n\t\t\tresolveFrame();\n\t\t}\n\t\tawait settle();\n\t}\n\n\t/** Convenience method to advance by 1 frame at a given fps (default: 60fps = 16.67ms). */\n\tpublic async tick(fps = 60): Promise<void> {\n\t\tawait this.advance(Math.round(1000 / fps));\n\t}\n}\n","import type {\n\tCanvasNode,\n\tCanvasNodeStyle,\n\tFanOutTrajectoryOptions,\n\tNodeTransition,\n\tTrajectoryFunction,\n\tTrajectoryPoint,\n\tXYPosition\n} from './types.js';\n\n/**\n * Standard cubic ease-out function (pure math, framework-agnostic).\n */\nexport const defaultEasing = (t: number): number => --t * t * t + 1;\n\n/**\n * Standard linear trajectory: straight line interpolation with linear scale & opacity progression.\n */\nexport const linearTrajectory: TrajectoryFunction = (\n\torigin: XYPosition,\n\ttarget: XYPosition,\n\tprogress: number\n): TrajectoryPoint => {\n\treturn {\n\t\tposition: {\n\t\t\tx: origin.x + (target.x - origin.x) * progress,\n\t\t\ty: origin.y + (target.y - origin.y) * progress\n\t\t},\n\t\tscale: progress,\n\t\topacity: Math.min(1, progress * 1.5)\n\t};\n};\n\n/**\n * Linear position trajectory: pure position interpolation without altering scale or opacity.\n */\nexport const linearPositionTrajectory: TrajectoryFunction = (\n\torigin: XYPosition,\n\ttarget: XYPosition,\n\tprogress: number\n): TrajectoryPoint => {\n\treturn {\n\t\tposition: {\n\t\t\tx: origin.x + (target.x - origin.x) * progress,\n\t\t\ty: origin.y + (target.y - origin.y) * progress\n\t\t}\n\t};\n};\n\n/**\n * Creates a fan-out trajectory where nodes arc outward from origin to target.\n */\nexport function createFanOutTrajectory(options: FanOutTrajectoryOptions = {}): TrajectoryFunction {\n\tconst {\n\t\tcurvature = 0.4,\n\t\tstartScale = 0,\n\t\tendScale = 1,\n\t\tstartOpacity = 0,\n\t\tendOpacity = 1\n\t} = options;\n\n\treturn (\n\t\torigin: XYPosition,\n\t\ttarget: XYPosition,\n\t\tprogress: number,\n\t\tindex: number,\n\t\ttotal: number\n\t): TrajectoryPoint => {\n\t\tconst dx = target.x - origin.x;\n\t\tconst dy = target.y - origin.y;\n\n\t\t// Normalized index from -1 (top) to +1 (bottom)\n\t\tconst normIndex = total > 1 ? (index - (total - 1) / 2) / ((total - 1) / 2) : 0;\n\n\t\t// Perpendicular control point offset to create smooth fan arc\n\t\tconst midX = origin.x + dx * 0.4;\n\t\tconst midY = origin.y + dy * 0.1 - normIndex * Math.abs(dx) * 0.15 * curvature;\n\n\t\t// Quadratic Bezier interpolation: B(t) = (1-t)^2 * P0 + 2(1-t)t * P1 + t^2 * P2\n\t\tconst t = progress;\n\t\tconst oneMinusT = 1 - t;\n\n\t\tconst x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * midX + t * t * target.x;\n\t\tconst y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * midY + t * t * target.y;\n\n\t\tconst scale = startScale + (endScale - startScale) * progress;\n\t\tconst opacity = startOpacity + (endOpacity - startOpacity) * progress;\n\n\t\treturn {\n\t\t\tposition: { x, y },\n\t\t\tscale,\n\t\t\topacity\n\t\t};\n\t};\n}\n\n/**\n * Creates a custom quadratic Bezier trajectory with a specified control point resolver.\n */\nexport function createBezierTrajectory(\n\tgetControlPoint: (origin: XYPosition, target: XYPosition) => XYPosition\n): TrajectoryFunction {\n\treturn (origin: XYPosition, target: XYPosition, progress: number): TrajectoryPoint => {\n\t\tconst cp = getControlPoint(origin, target);\n\t\tconst t = progress;\n\t\tconst oneMinusT = 1 - t;\n\n\t\tconst x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * cp.x + t * t * target.x;\n\t\tconst y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * cp.y + t * t * target.y;\n\n\t\treturn {\n\t\t\tposition: { x, y },\n\t\t\tscale: progress,\n\t\t\topacity: progress\n\t\t};\n\t};\n}\n\nimport { realClock, type Clock } from './clock.js';\n\n/**\n * Returns a copy of `style` with its opacity set to `opacity`.\n *\n * Supports both CSS strings (`\"color: red; opacity: 0.5;\"`, used by SvelteFlow)\n * and style objects (`{ color: 'red', opacity: 0.5 }`, used by React Flow / xyflow).\n * When `style` is empty, `emptyFormat` decides which representation is produced.\n * Never mutates the input.\n */\nexport function withStyleOpacity(\n\tstyle: CanvasNodeStyle | undefined | null,\n\topacity: number,\n\temptyFormat: 'string' | 'object' = 'string'\n): CanvasNodeStyle {\n\tif (style !== null && typeof style === 'object') {\n\t\treturn { ...style, opacity };\n\t}\n\tif (typeof style === 'string' && style.trim() !== '') {\n\t\tconst rest = style\n\t\t\t.replace(/(^|;)\\s*opacity\\s*:\\s*[^;]*;?/gi, '$1')\n\t\t\t.trim()\n\t\t\t.replace(/;+\\s*$/, '')\n\t\t\t.trim();\n\t\treturn `${rest ? rest + '; ' : ''}opacity: ${opacity};`;\n\t}\n\treturn emptyFormat === 'object' ? { opacity } : `opacity: ${opacity};`;\n}\n\nexport interface MultiNodeTransitionOptions<TNode extends CanvasNode = CanvasNode> {\n\tdefaultDuration?: number;\n\tdefaultEasing?: (t: number) => number;\n\tclock?: Clock;\n\t/**\n\t * Style representation to create for nodes that have no `style` yet when an opacity\n\t * is applied. Defaults to `'string'` (SvelteFlow); pass `'object'` for React Flow.\n\t * Existing styles always keep their representation.\n\t */\n\tstyleFormat?: 'string' | 'object';\n\t/**\n\t * Called on every frame with updated copies of the transitioning nodes, in the same\n\t * order as the `transitions` array. Input nodes are never mutated.\n\t */\n\tonUpdate?: (nodes: TNode[]) => void;\n\t/** Called once all transitions finished, with the final node copies. */\n\tonComplete?: (nodes: TNode[]) => void;\n}\n\n/**\n * Coordinates and animates multiple node transitions simultaneously.\n *\n * The input nodes are treated as immutable: every frame produces updated copies\n * (position, `data.scale` / `data.opacity`, and `style` opacity) which are handed to\n * `onUpdate` and finally `onComplete`. Merge them into your node state by `id`.\n */\nexport function runMultiNodeTransition<TNode extends CanvasNode = CanvasNode>(\n\ttransitions: NodeTransition<TNode>[],\n\toptions: MultiNodeTransitionOptions<TNode> = {}\n): () => void {\n\tif (transitions.length === 0) {\n\t\toptions.onComplete?.([]);\n\t\treturn () => {};\n\t}\n\n\tconst {\n\t\tdefaultDuration = 400,\n\t\tdefaultEasing: easingFunc = defaultEasing,\n\t\tclock = realClock,\n\t\tstyleFormat = 'string',\n\t\tonUpdate,\n\t\tonComplete\n\t} = options;\n\n\tlet isCancelled = false;\n\tconst startTime = clock.now();\n\n\tconst items = transitions.map((tr, i) => ({\n\t\t...tr,\n\t\tindex: tr.index ?? i,\n\t\ttotal: tr.total ?? transitions.length,\n\t\tduration: tr.duration ?? defaultDuration,\n\t\teasing: tr.easing ?? easingFunc,\n\t\tdelay: tr.delay ?? 0,\n\t\ttrajectory: tr.trajectory ?? linearTrajectory\n\t}));\n\n\t// Latest copy of every node; starts out as the untouched inputs.\n\tconst current: TNode[] = items.map((item) => item.node);\n\n\tfunction frame() {\n\t\tif (isCancelled) return;\n\n\t\tconst now = clock.now();\n\t\tlet allCompleted = true;\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst item = items[i];\n\t\t\tconst elapsed = now - (startTime + item.delay);\n\n\t\t\tif (elapsed < 0) {\n\t\t\t\tallCompleted = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Guard zero duration and division by zero (referenced in GOTCHAS.md)\n\t\t\tconst rawProgress = item.duration <= 0 ? 1 : Math.min(elapsed / item.duration, 1);\n\t\t\tconst progress = item.duration <= 0 ? 1 : item.easing(rawProgress);\n\n\t\t\tconst point = item.trajectory(item.from, item.to, progress, item.index, item.total);\n\n\t\t\tconst next: TNode = { ...item.node, position: { ...point.position } };\n\n\t\t\tif (point.scale !== undefined || point.opacity !== undefined) {\n\t\t\t\tconst data: Record<string, any> = { ...(item.node.data ?? {}) };\n\t\t\t\tif (point.scale !== undefined) {\n\t\t\t\t\tdata.scale = point.scale;\n\t\t\t\t}\n\t\t\t\tif (point.opacity !== undefined) {\n\t\t\t\t\tdata.opacity = point.opacity;\n\t\t\t\t\t(next as CanvasNode).style = withStyleOpacity(item.node.style, point.opacity, styleFormat);\n\t\t\t\t}\n\t\t\t\t(next as CanvasNode).data = data;\n\t\t\t}\n\n\t\t\tcurrent[i] = next;\n\n\t\t\tif (rawProgress < 1) {\n\t\t\t\tallCompleted = false;\n\t\t\t}\n\t\t}\n\n\t\tonUpdate?.(current.slice());\n\n\t\tif (!allCompleted) {\n\t\t\tclock.frame().then(frame);\n\t\t} else {\n\t\t\tonComplete?.(current.slice());\n\t\t}\n\t}\n\n\tframe();\n\n\treturn () => {\n\t\tisCancelled = true;\n\t};\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n\tCanvasEdge,\n\tCanvasNode,\n\tDirectionalDisplacementOptions,\n\tRect,\n\tReflowDisplacementOptions,\n\tXYPosition\n} from './types.js';\n\n/**\n * Calculates a bounding rectangle for a set of nodes if not provided by getNodesBounds.\n */\nexport function computeNodesBoundingBox<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\tdefaultWidth = 200,\n\tdefaultHeight = 60\n): Rect {\n\tif (nodes.length === 0) {\n\t\treturn { x: 0, y: 0, width: 0, height: 0 };\n\t}\n\n\tlet minX = Infinity;\n\tlet minY = Infinity;\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const node of nodes) {\n\t\tconst width = node.measured?.width ?? (node as any).width ?? defaultWidth;\n\t\tconst height = node.measured?.height ?? (node as any).height ?? defaultHeight;\n\n\t\tminX = Math.min(minX, node.position.x);\n\t\tminY = Math.min(minY, node.position.y);\n\t\tmaxX = Math.max(maxX, node.position.x + width);\n\t\tmaxY = Math.max(maxY, node.position.y + height);\n\t}\n\n\treturn {\n\t\tx: minX,\n\t\ty: minY,\n\t\twidth: maxX - minX,\n\t\theight: maxY - minY\n\t};\n}\n\n/**\n * Pure directional displacement calculation.\n * Shifts downstream or surrounding nodes along an axis to clear space for newly inserted child nodes.\n */\nexport function calculateDirectionalDisplacement<TNode extends CanvasNode = CanvasNode>(params: {\n\texistingNodes: TNode[];\n\toriginNode: TNode;\n\tchildNodes: TNode[];\n\tgetNodesBounds?: (nodes: TNode[]) => Rect;\n\toptions?: DirectionalDisplacementOptions;\n}): Map<string, XYPosition> {\n\tconst {\n\t\texistingNodes,\n\t\toriginNode,\n\t\tchildNodes,\n\t\tgetNodesBounds,\n\t\toptions = {}\n\t} = params;\n\n\tconst {\n\t\tdirection = 'right',\n\t\tgap = 40,\n\t\tspreadSiblingLanes = false,\n\t\tsiblingTolerance = 50,\n\t\tminY\n\t} = options;\n\n\tconst displacedMap = new Map<string, XYPosition>();\n\tif (childNodes.length === 0 || existingNodes.length === 0) {\n\t\treturn displacedMap;\n\t}\n\n\tconst childBounds = getNodesBounds\n\t\t? getNodesBounds(childNodes)\n\t\t: computeNodesBoundingBox(childNodes);\n\n\tconst originWidth = originNode.measured?.width ?? (originNode as any).width ?? 200;\n\tconst originHeight = originNode.measured?.height ?? (originNode as any).height ?? 60;\n\n\t// The delta space required along primary axis\n\tconst deltaPrimary =\n\t\tdirection === 'right' || direction === 'left'\n\t\t\t? childBounds.width + gap\n\t\t\t: childBounds.height + gap;\n\n\t// Vertical displacement parameters: upward and downward row clearance\n\tconst deltaUp = Math.max(0, originNode.position.y - childBounds.y + gap);\n\tconst deltaDown = Math.max(\n\t\t0,\n\t\tchildBounds.y + childBounds.height - (originNode.position.y + originHeight) + gap\n\t);\n\n\t// Both above and below displace equally so the row expands symmetrically\n\tconst equalDelta = Math.max(deltaUp, deltaDown);\n\n\tfor (const node of existingNodes) {\n\t\tif (node.id === originNode.id) continue;\n\n\t\tconst isSiblingRow =\n\t\t\tMath.abs(node.position.y - originNode.position.y) < siblingTolerance;\n\n\t\tswitch (direction) {\n\t\t\tcase 'right': {\n\t\t\t\tif (node.position.x > originNode.position.x) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x + deltaPrimary,\n\t\t\t\t\t\ty: node.position.y\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'left': {\n\t\t\t\tif (node.position.x < originNode.position.x) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x - deltaPrimary,\n\t\t\t\t\t\ty: node.position.y\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'down': {\n\t\t\t\tif (node.position.y > originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y + deltaPrimary\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'up': {\n\t\t\t\tif (node.position.y < originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y - deltaPrimary\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'vertical': {\n\t\t\t\tif (isSiblingRow) break;\n\n\t\t\t\tif (node.position.y < originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y - equalDelta\n\t\t\t\t\t});\n\t\t\t\t} else if (node.position.y > originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y + equalDelta\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sibling lane spreading to avoid overlap among child nodes\n\tif (spreadSiblingLanes && (direction === 'right' || direction === 'left')) {\n\t\tfor (const [nodeId, pos] of displacedMap.entries()) {\n\t\t\tconst node = existingNodes.find((n) => n.id === nodeId);\n\t\t\tif (node && Math.abs(node.position.y - originNode.position.y) < siblingTolerance) {\n\t\t\t\tconst isAbove = node.position.y < originNode.position.y;\n\t\t\t\tdisplacedMap.set(nodeId, {\n\t\t\t\t\tx: pos.x,\n\t\t\t\t\ty: pos.y + (isAbove ? -deltaUp : deltaDown)\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Floor constraint\n\tif (minY !== undefined) {\n\t\tfor (const [nodeId, pos] of displacedMap.entries()) {\n\t\t\tif (pos.y < minY) {\n\t\t\t\tdisplacedMap.set(nodeId, { x: pos.x, y: minY });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn displacedMap;\n}\n\n/**\n * Calculates Dagre reflow displacement preserving the position of an anchor node.\n */\nexport function calculateDagreReflowDisplacement<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(params: {\n\tcurrentNodes: TNode[];\n\tcurrentEdges: TEdge[];\n\tfutureNodes: TNode[];\n\tfutureEdges: TEdge[];\n\toptions: ReflowDisplacementOptions;\n\tgetNodesBounds?: (nodes: TNode[]) => Rect;\n}): Map<string, XYPosition> {\n\tconst {\n\t\tcurrentNodes,\n\t\tfutureNodes,\n\t\tfutureEdges,\n\t\toptions\n\t} = params;\n\n\tconst {\n\t\tanchorNodeId,\n\t\tdirection = 'LR',\n\t\tranksep = 100,\n\t\tnodesep = 25,\n\t\tdefaultNodeWidth = 200,\n\t\tdefaultNodeHeight = 60\n\t} = options;\n\n\tconst anchorNode = currentNodes.find((n) => n.id === anchorNodeId);\n\tif (!anchorNode) return new Map();\n\n\tconst g = new dagre.graphlib.Graph();\n\tg.setDefaultEdgeLabel(() => ({}));\n\tg.setGraph({ rankdir: direction, ranksep, nodesep });\n\n\tconst nodeIds = new Set(futureNodes.map((n) => n.id));\n\n\tfutureNodes.forEach((node) => {\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\t\tg.setNode(node.id, { width: nodeWidth, height: nodeHeight });\n\t});\n\n\tfutureEdges.forEach((edge) => {\n\t\tif (nodeIds.has(edge.source) && nodeIds.has(edge.target)) {\n\t\t\tg.setEdge(edge.source, edge.target);\n\t\t}\n\t});\n\n\tdagre.layout(g);\n\n\tconst anchorLayoutPos = g.node(anchorNodeId);\n\tif (!anchorLayoutPos) return new Map();\n\n\tconst anchorWidth = anchorNode.measured?.width ?? (anchorNode as any).width ?? defaultNodeWidth;\n\tconst anchorHeight = anchorNode.measured?.height ?? (anchorNode as any).height ?? defaultNodeHeight;\n\n\tconst anchorLayoutUpperLeft = {\n\t\tx: anchorLayoutPos.x - anchorWidth / 2,\n\t\ty: anchorLayoutPos.y - anchorHeight / 2\n\t};\n\n\tconst deltaX = anchorNode.position.x - anchorLayoutUpperLeft.x;\n\tconst deltaY = anchorNode.position.y - anchorLayoutUpperLeft.y;\n\n\tconst displacementMap = new Map<string, XYPosition>();\n\n\tcurrentNodes.forEach((node) => {\n\t\tif (node.id === anchorNodeId) return;\n\n\t\tconst layoutNode = g.node(node.id);\n\t\tif (!layoutNode) return;\n\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\n\t\tconst upperLeftX = layoutNode.x - nodeWidth / 2 + deltaX;\n\t\tconst upperLeftY = layoutNode.y - nodeHeight / 2 + deltaY;\n\n\t\tif (\n\t\t\tMath.abs(upperLeftX - node.position.x) > 1 ||\n\t\t\tMath.abs(upperLeftY - node.position.y) > 1\n\t\t) {\n\t\t\tdisplacementMap.set(node.id, { x: upperLeftX, y: upperLeftY });\n\t\t}\n\t});\n\n\treturn displacementMap;\n}\n","import type {\n\tCanvasClipboardPayload,\n\tCanvasEdge,\n\tCanvasNode,\n\tXYPosition\n} from './types.js';\n\n/**\n * Checks if an event originated from a text input, textarea, contenteditable element, or rich editor.\n */\nexport function isEventFromTextInput(event: Event | { target: EventTarget | null }): boolean {\n\tconst target = (event as any).target as HTMLElement | null;\n\tif (!target) return false;\n\tif (\n\t\ttarget.tagName === 'INPUT' ||\n\t\ttarget.tagName === 'TEXTAREA' ||\n\t\ttarget.tagName === 'SELECT' ||\n\t\ttarget.isContentEditable ||\n\t\ttarget.closest?.('[contenteditable=\"true\"]') ||\n\t\ttarget.closest?.('.ProseMirror')\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Validates that an object conforms to minimal CanvasNode shape:\n * a string `id` and a `position` whose `x` / `y` are finite numbers.\n */\nexport function isValidCanvasNode(obj: unknown): obj is CanvasNode {\n\tif (typeof obj !== 'object' || obj === null) return false;\n\tconst candidate = obj as { id?: unknown; position?: unknown };\n\tif (typeof candidate.id !== 'string') return false;\n\tconst position = candidate.position as { x?: unknown; y?: unknown } | null | undefined;\n\treturn (\n\t\ttypeof position === 'object' &&\n\t\tposition !== null &&\n\t\ttypeof position.x === 'number' &&\n\t\tNumber.isFinite(position.x) &&\n\t\ttypeof position.y === 'number' &&\n\t\tNumber.isFinite(position.y)\n\t);\n}\n\n/**\n * Validates that an object conforms to minimal CanvasEdge shape (string `id`, `source`, `target`).\n */\nexport function isValidCanvasEdge(obj: unknown): obj is CanvasEdge {\n\tif (typeof obj !== 'object' || obj === null) return false;\n\tconst candidate = obj as { id?: unknown; source?: unknown; target?: unknown };\n\treturn (\n\t\ttypeof candidate.id === 'string' &&\n\t\ttypeof candidate.source === 'string' &&\n\t\ttypeof candidate.target === 'string'\n\t);\n}\n\n/**\n * Checks if a string is a valid HTTP/HTTPS URL.\n */\nexport function isValidUrl(url: string): boolean {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\treturn parsed.protocol === 'http:' || parsed.protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Serializes nodes and optional edges into clipboard JSON payload.\n */\nexport function serializeCanvasNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(nodes: TNode[], edges?: TEdge[]): string {\n\tconst payload: CanvasClipboardPayload<TNode, TEdge> = {\n\t\tversion: 1,\n\t\tnodes,\n\t\tedges\n\t};\n\treturn JSON.stringify(payload);\n}\n\n/**\n * Parses raw JSON string into a CanvasClipboardPayload if valid.\n */\nexport function parseCanvasClipboardData<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(raw: string): CanvasClipboardPayload<TNode, TEdge> | null {\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\tif (\n\t\t\ttypeof parsed === 'object' &&\n\t\t\tparsed !== null &&\n\t\t\tArray.isArray(parsed.nodes) &&\n\t\t\tparsed.nodes.length > 0 &&\n\t\t\tparsed.nodes.every(isValidCanvasNode)\n\t\t) {\n\t\t\t// Untrusted input: drop malformed edges instead of crashing downstream consumers.\n\t\t\tconst edges = Array.isArray(parsed.edges)\n\t\t\t\t? (parsed.edges as unknown[]).filter(isValidCanvasEdge)\n\t\t\t\t: undefined;\n\t\t\treturn { ...parsed, edges } as CanvasClipboardPayload<TNode, TEdge>;\n\t\t}\n\t} catch {\n\t\t// Not JSON or invalid payload\n\t}\n\treturn null;\n}\n\n/**\n * Generates unique new IDs for pasted nodes and updates edge references accordingly.\n *\n * - Nodes without a valid id / finite numeric position are skipped.\n * - `parentId` (and legacy `parentNode`) references to other pasted nodes are remapped to\n * the new IDs; such children keep their parent-relative position (no extra offset).\n * References to parents outside the pasted set are left unchanged.\n * - Edges are kept only when both endpoints were pasted; a non-array `edges` is ignored.\n */\nexport function remapPastedNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[] | null | undefined = [],\n\toffset: XYPosition = { x: 30, y: 30 },\n\tidGenerator: () => string = () => `node-${Math.random().toString(36).substring(2, 9)}`\n): { nodes: TNode[]; edges: TEdge[] } {\n\tconst validNodes = (Array.isArray(nodes) ? nodes : []).filter(isValidCanvasNode) as TNode[];\n\tconst validEdges = (Array.isArray(edges) ? edges : []).filter(isValidCanvasEdge) as TEdge[];\n\n\tconst dx = Number.isFinite(offset?.x) ? offset.x : 0;\n\tconst dy = Number.isFinite(offset?.y) ? offset.y : 0;\n\n\tconst idMap = new Map<string, string>();\n\tfor (const node of validNodes) {\n\t\tidMap.set(node.id, idGenerator());\n\t}\n\n\tconst newNodes = validNodes.map((node) => {\n\t\tconst next: CanvasNode = {\n\t\t\t...node,\n\t\t\tid: idMap.get(node.id)!,\n\t\t\tposition: {\n\t\t\t\tx: node.position.x + dx,\n\t\t\t\ty: node.position.y + dy\n\t\t\t},\n\t\t\tselected: true\n\t\t};\n\n\t\tlet parentRemapped = false;\n\t\tfor (const key of ['parentId', 'parentNode'] as const) {\n\t\t\tconst parent = (node as CanvasNode)[key];\n\t\t\tif (typeof parent === 'string' && idMap.has(parent)) {\n\t\t\t\tnext[key] = idMap.get(parent)!;\n\t\t\t\tparentRemapped = true;\n\t\t\t}\n\t\t}\n\t\tif (parentRemapped) {\n\t\t\t// Position is relative to the (also pasted, also offset) parent.\n\t\t\tnext.position = { x: node.position.x, y: node.position.y };\n\t\t}\n\n\t\treturn next as TNode;\n\t});\n\n\tconst newEdges = validEdges\n\t\t.filter((e) => idMap.has(e.source) && idMap.has(e.target))\n\t\t.map((edge) => ({\n\t\t\t...edge,\n\t\t\tid: `edge-${Math.random().toString(36).substring(2, 9)}`,\n\t\t\tsource: idMap.get(edge.source)!,\n\t\t\ttarget: idMap.get(edge.target)!,\n\t\t\tselected: false\n\t\t}));\n\n\treturn { nodes: newNodes, edges: newEdges };\n}\n\n/**\n * Repositions nodes so their bounding box origin matches the given target position.\n */\nexport function repositionNodesTo<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\ttargetOrigin: XYPosition\n): TNode[] {\n\tif (nodes.length === 0) return [];\n\tconst minX = Math.min(...nodes.map((n) => n.position.x));\n\tconst minY = Math.min(...nodes.map((n) => n.position.y));\n\tconst deltaX = targetOrigin.x - minX;\n\tconst deltaY = targetOrigin.y - minY;\n\n\treturn nodes.map((n) => ({\n\t\t...n,\n\t\tposition: {\n\t\t\tx: n.position.x + deltaX,\n\t\t\ty: n.position.y + deltaY\n\t\t}\n\t}));\n}\n","import type { CanvasEdge, CanvasNode, Rect } from './types.js';\n\nexport interface CanvasHeightOptions {\n\t/** Smallest height returned (default 320). */\n\tmin?: number;\n\t/** Largest height returned; taller content is scaled/zoomed (default 560). */\n\tmax?: number;\n\t/** Extra padding around the content (default 48). */\n\tpadding?: number;\n}\n\nfunction clampHeight(contentHeight: number, options: CanvasHeightOptions = {}): number {\n\tconst { min = 320, max = 560, padding = 48 } = options;\n\treturn Math.round(Math.min(max, Math.max(min, contentHeight + padding)));\n}\n\n/**\n * Calculates the bounding box extent of all positioned nodes, or `null` for an empty graph.\n */\nexport function layoutBounds<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[]\n): Rect | null {\n\tif (nodes.length === 0) return null;\n\n\tlet minX = Infinity;\n\tlet minY = Infinity;\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const node of nodes) {\n\t\tconst x = node.position.x;\n\t\tconst y = node.position.y;\n\t\tconst width = node.width ?? 180;\n\t\tconst height = node.height ?? 80;\n\n\t\tminX = Math.min(minX, x);\n\t\tminY = Math.min(minY, y);\n\t\tmaxX = Math.max(maxX, x + width);\n\t\tmaxY = Math.max(maxY, y + height);\n\t}\n\n\tif (minX === Infinity) return null;\n\treturn { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/**\n * Returns a clamped container height that fits the layout at 1:1 scale without overflow.\n */\nexport function canvasHeight<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\toptions?: CanvasHeightOptions\n): number {\n\treturn clampHeight(layoutBounds(nodes)?.height ?? 0, options);\n}\n\nconst DEFAULT_RANK_HEIGHT = 80 + 72; // Average node height + default rank separation\nconst NODES_PER_RANK = 2;\n\n/**\n * Estimates the container height to reserve before layout calculation finishes,\n * based on node and edge counts alone. Prevents layout shift (CLS).\n */\nexport function estimateCanvasHeight<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[],\n\toptions?: CanvasHeightOptions\n): number {\n\tconst ranks = Math.max(1, Math.ceil(nodes.length / NODES_PER_RANK));\n\treturn clampHeight(ranks * DEFAULT_RANK_HEIGHT, options);\n}\n\nfunction mix(a: number, b: number, t: number): number {\n\treturn a + (b - a) * t;\n}\n\n/**\n * Interpolates node positions and sizes between two layouts partway at progress `t` (0 = from, 1 = to).\n * Nodes present in both interpolate smoothly; nodes newly added in `to` snap to target.\n */\nexport function blendLayout<TNode extends CanvasNode = CanvasNode>(\n\tfrom: TNode[],\n\tto: TNode[],\n\tt: number\n): TNode[] {\n\tif (t >= 1) return to;\n\n\tconst fromMap = new Map<string, TNode>(from.map((n) => [n.id, n]));\n\n\treturn to.map((target) => {\n\t\tconst origin = fromMap.get(target.id);\n\t\tif (!origin) return target;\n\n\t\treturn {\n\t\t\t...target,\n\t\t\tposition: {\n\t\t\t\tx: mix(origin.position.x, target.position.x, t),\n\t\t\t\ty: mix(origin.position.y, target.position.y, t)\n\t\t\t},\n\t\t\twidth:\n\t\t\t\torigin.width !== undefined && target.width !== undefined\n\t\t\t\t\t? mix(origin.width, target.width, t)\n\t\t\t\t\t: target.width,\n\t\t\theight:\n\t\t\t\torigin.height !== undefined && target.height !== undefined\n\t\t\t\t\t? mix(origin.height, target.height, t)\n\t\t\t\t\t: target.height\n\t\t};\n\t});\n}\n\n/**\n * Filters out nodes that are not touched by any edge.\n *\n * During LLM streaming, nodes often arrive a chunk or token before the edge\n * that connects them. Displaying them immediately causes them to be placed as root\n * nodes only to jump into their correct position once the edge arrives.\n * Hiding orphan nodes during active streaming keeps the layout calm and jitter-free.\n */\nexport function connectedOnly<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[]\n): TNode[] {\n\tif (edges.length === 0) return nodes;\n\n\tconst linkedNodeIds = new Set<string>();\n\tfor (const edge of edges) {\n\t\tlinkedNodeIds.add(edge.source);\n\t\tlinkedNodeIds.add(edge.target);\n\t}\n\n\tconst filtered = nodes.filter((node) => linkedNodeIds.has(node.id));\n\t// If filtering would remove everything, return the original nodes\n\treturn filtered.length > 0 ? filtered : nodes;\n}\n","import { realClock, type Clock } from './clock.js';\nimport { ensureLayout } from './layout.js';\nimport { linearPositionTrajectory, runMultiNodeTransition } from './trajectory.js';\nimport type { CanvasEdge, CanvasNode, IncrementalLayoutOptions, NodeTransition, XYPosition } from './types.js';\nimport { connectedOnly } from './view.js';\n\nexport interface StreamingLayoutManagerOptions {\n\tthrottleMs?: number;\n\tglideDurationMs?: number;\n\tconnectedOnly?: boolean;\n\tclock?: Clock;\n\tlayoutOptions?: IncrementalLayoutOptions;\n\tonLayoutUpdated?: (positions: Map<string, XYPosition>) => void;\n}\n\n/**\n * Manages throttled incremental layout recalculation and smooth tweened node gliding\n * during active streaming (e.g. LLM streaming or graph generation).\n *\n * - `pushStreamUpdate` is a true throttle (leading + trailing edge): the first update\n * lays out immediately, further updates within `throttleMs` are coalesced and the\n * latest one is laid out when the window closes. Layouts therefore keep running at\n * most once per `throttleMs` while a stream is active, instead of being postponed\n * until the stream goes quiet.\n * - Every layout is computed from the graph (respecting `layoutOptions.storedPositions`\n * as pinned/manual coordinates) and each known node glides from its *current*\n * position (the `currentPositions` argument) to its newly computed position.\n */\nexport class StreamingLayoutManager<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n> {\n\tprivate throttleMs: number;\n\tprivate glideDurationMs: number;\n\tprivate connectedOnly: boolean;\n\tprivate clock: Clock;\n\tprivate layoutOptions: IncrementalLayoutOptions;\n\tprivate onLayoutUpdated?: (positions: Map<string, XYPosition>) => void;\n\n\tprivate pendingTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate pendingArgs: [TNode[], TEdge[], Map<string, XYPosition>] | null = null;\n\tprivate activeTransitionCancel: (() => void) | null = null;\n\tprivate targetPositions = new Map<string, XYPosition>();\n\tprivate livePositions = new Map<string, XYPosition>();\n\n\tconstructor(options: StreamingLayoutManagerOptions = {}) {\n\t\tthis.throttleMs = options.throttleMs ?? 200;\n\t\tthis.glideDurationMs = options.glideDurationMs ?? 300;\n\t\tthis.connectedOnly = options.connectedOnly ?? false;\n\t\tthis.clock = options.clock ?? realClock;\n\t\tthis.layoutOptions = options.layoutOptions ?? { direction: 'LR' };\n\t\tthis.onLayoutUpdated = options.onLayoutUpdated;\n\t}\n\n\t/**\n\t * Feed incoming nodes and edges into the streaming manager.\n\t * Throttles rapid streaming bursts (leading + trailing edge) and triggers smooth layout gliding.\n\t */\n\tpublic pushStreamUpdate(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tif (this.pendingTimer !== null) {\n\t\t\t// Inside the throttle window: remember the latest update for the trailing edge.\n\t\t\tthis.pendingArgs = [nodes, edges, currentPositions];\n\t\t\treturn;\n\t\t}\n\n\t\t// Leading edge: lay out immediately and open a throttle window.\n\t\tthis.recalculateAndGlide(nodes, edges, currentPositions);\n\t\tthis.startWindow();\n\t}\n\n\tprivate startWindow(): void {\n\t\tthis.pendingTimer = setTimeout(() => {\n\t\t\tthis.pendingTimer = null;\n\t\t\tconst args = this.pendingArgs;\n\t\t\tthis.pendingArgs = null;\n\t\t\tif (args) {\n\t\t\t\t// Trailing edge: lay out the latest coalesced update and keep throttling.\n\t\t\t\tthis.recalculateAndGlide(...args);\n\t\t\t\tthis.startWindow();\n\t\t\t}\n\t\t}, Math.max(0, this.throttleMs));\n\t}\n\n\t/**\n\t * Forces immediate calculation and cancels pending throttled timers.\n\t */\n\tpublic flush(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tthis.clearPending();\n\t\tthis.recalculateAndGlide(nodes, edges, currentPositions);\n\t}\n\n\t/**\n\t * Latest computed layout targets (the positions nodes are gliding towards).\n\t */\n\tpublic getTargetPositions(): Map<string, XYPosition> {\n\t\treturn new Map(this.targetPositions);\n\t}\n\n\tprivate clearPending(): void {\n\t\tif (this.pendingTimer !== null) {\n\t\t\tclearTimeout(this.pendingTimer);\n\t\t\tthis.pendingTimer = null;\n\t\t}\n\t\tthis.pendingArgs = null;\n\t}\n\n\tprivate recalculateAndGlide(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tconst targetNodes = this.connectedOnly ? connectedOnly(nodes, edges) : nodes;\n\t\tif (targetNodes.length === 0) return;\n\n\t\t// Where nodes are right now: the caller's view, overridden by any glide still in\n\t\t// flight (the caller may not have applied the latest animated frame yet).\n\t\tconst startPositions = new Map<string, XYPosition>(currentPositions);\n\t\tif (this.activeTransitionCancel) {\n\t\t\tfor (const [id, pos] of this.livePositions) {\n\t\t\t\tstartPositions.set(id, pos);\n\t\t\t}\n\t\t\tthis.activeTransitionCancel();\n\t\t\tthis.activeTransitionCancel = null;\n\t\t}\n\n\t\t// Compute fresh layout targets. Only explicitly stored (pinned/manual) positions\n\t\t// are preserved; current positions are the glide *origin*, not the destination.\n\t\tconst layouted = ensureLayout(targetNodes, edges, this.layoutOptions);\n\n\t\tconst nextPositions = new Map<string, XYPosition>();\n\t\tconst transitions: NodeTransition<TNode>[] = [];\n\n\t\tfor (const node of layouted) {\n\t\t\tconst target = { ...node.position };\n\t\t\tnextPositions.set(node.id, target);\n\n\t\t\tconst current = startPositions.get(node.id);\n\t\t\tif (!current) continue; // brand-new node: appears directly at its target\n\n\t\t\tconst distance = Math.hypot(target.x - current.x, target.y - current.y);\n\t\t\tif (distance > 2) {\n\t\t\t\ttransitions.push({\n\t\t\t\t\tnode: { ...node, position: { ...current } },\n\t\t\t\t\tfrom: current,\n\t\t\t\t\tto: target,\n\t\t\t\t\ttrajectory: linearPositionTrajectory,\n\t\t\t\t\tduration: this.glideDurationMs\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.targetPositions = nextPositions;\n\n\t\tif (transitions.length === 0) {\n\t\t\tthis.livePositions = new Map(nextPositions);\n\t\t\tthis.onLayoutUpdated?.(nextPositions);\n\t\t\treturn;\n\t\t}\n\n\t\tconst live = new Map<string, XYPosition>(nextPositions);\n\t\tfor (const trans of transitions) {\n\t\t\tlive.set(trans.node.id, { ...trans.from });\n\t\t}\n\t\tthis.livePositions = live;\n\n\t\tlet finished = false;\n\t\tconst cancel = runMultiNodeTransition(transitions, {\n\t\t\tclock: this.clock,\n\t\t\tonUpdate: (updated) => {\n\t\t\t\tconst frame = new Map<string, XYPosition>(this.livePositions);\n\t\t\t\tfor (const node of updated) {\n\t\t\t\t\tframe.set(node.id, { ...node.position });\n\t\t\t\t}\n\t\t\t\tthis.livePositions = frame;\n\t\t\t\tthis.onLayoutUpdated?.(frame);\n\t\t\t},\n\t\t\tonComplete: () => {\n\t\t\t\tfinished = true;\n\t\t\t\tthis.activeTransitionCancel = null;\n\t\t\t\tthis.livePositions = new Map(nextPositions);\n\t\t\t\tthis.onLayoutUpdated?.(nextPositions);\n\t\t\t}\n\t\t});\n\t\t// A zero-duration glide completes synchronously; don't keep a stale canceller.\n\t\tthis.activeTransitionCancel = finished ? null : cancel;\n\t}\n\n\tpublic destroy(): void {\n\t\tthis.clearPending();\n\t\tif (this.activeTransitionCancel) {\n\t\t\tthis.activeTransitionCancel();\n\t\t\tthis.activeTransitionCancel = null;\n\t\t}\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/canvas/clock.ts","../../src/canvas/trajectory.ts","../../src/canvas/displacement.ts","../../src/canvas/clipboard.ts","../../src/canvas/view.ts","../../src/canvas/streaming.ts","../../src/canvas/arrange.ts","../../src/canvas/guides.ts","../../src/canvas/connectors.ts","../../src/canvas/scenes.ts","../../src/canvas/arrangeShortcuts.ts","../../src/canvas/arrangeController.ts"],"sourcesContent":["/**\n * The time source that canvas animations and agent performances play on.\n *\n * Defaults to `realClock` (requestAnimationFrame and setTimeout).\n * A `ManualClock` moves only when told to via `advance(ms)` or `tick(fps)`,\n * enabling deterministic frame-by-frame stepping for testing, video generation,\n * or headless server environments.\n */\n\nexport interface Clock {\n\t/** Current time in milliseconds. */\n\tnow(): number;\n\t/** Resolves on the next animation frame. */\n\tframe(): Promise<void>;\n\t/** Resolves after `ms` milliseconds of this clock's time. */\n\tsleep(ms: number): Promise<void>;\n\t/**\n\t * Whether the clock follows wall time. Live clocks stop or degrade when the\n\t * tab is in the background (browsers pause animation frames), so transitions\n\t * can commit immediately rather than leaving operations hanging.\n\t */\n\treadonly live: boolean;\n}\n\n/** Whether the browser tab is hidden (where RAF pauses). */\nexport const pageHidden = (): boolean =>\n\ttypeof document !== 'undefined' && document.hidden;\n\n/** Real-time clock using requestAnimationFrame and setTimeout. */\nexport const realClock: Clock = {\n\tlive: true,\n\tnow: () => (typeof performance !== 'undefined' ? performance.now() : Date.now()),\n\tframe: () =>\n\t\tnew Promise<void>((resolve) => {\n\t\t\tif (typeof requestAnimationFrame === 'function' && !pageHidden()) {\n\t\t\t\trequestAnimationFrame(() => resolve());\n\t\t\t} else {\n\t\t\t\tsetTimeout(resolve, 16);\n\t\t\t}\n\t\t}),\n\tsleep: (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, Math.max(0, ms)))\n};\n\nconst settle = () => new Promise<void>((resolve) => setTimeout(resolve, 0));\n\n/**\n * A deterministic clock that only moves forward when `advance` or `tick` is called.\n * Allows step-by-step frame testing and video rendering without waiting for real time.\n */\nexport class ManualClock implements Clock {\n\treadonly live = false;\n\tprivate time: number;\n\tprivate frames: (() => void)[] = [];\n\tprivate sleepers: { at: number; seq: number; resolve: () => void }[] = [];\n\tprivate seq = 0;\n\n\tconstructor(start = 0) {\n\t\tthis.time = start;\n\t}\n\n\tpublic now(): number {\n\t\treturn this.time;\n\t}\n\n\tpublic frame(): Promise<void> {\n\t\treturn new Promise<void>((resolve) => this.frames.push(resolve));\n\t}\n\n\tpublic sleep(ms: number): Promise<void> {\n\t\treturn new Promise<void>((resolve) =>\n\t\t\tthis.sleepers.push({\n\t\t\t\tat: this.time + Math.max(0, ms),\n\t\t\t\tseq: this.seq++,\n\t\t\t\tresolve\n\t\t\t})\n\t\t);\n\t}\n\n\t/** Whether any frames or sleep timers are currently pending. */\n\tpublic get pending(): boolean {\n\t\treturn this.frames.length > 0 || this.sleepers.length > 0;\n\t}\n\n\t/** Advances time by `ms`, resolving due sleep timers in order, followed by queued frames. */\n\tpublic async advance(ms: number): Promise<void> {\n\t\tconst end = this.time + Math.max(0, ms);\n\t\tawait settle();\n\n\t\twhile (true) {\n\t\t\tlet next: (typeof this.sleepers)[number] | undefined;\n\t\t\tfor (const s of this.sleepers) {\n\t\t\t\tif (s.at <= end && (!next || s.at < next.at || (s.at === next.at && s.seq < next.seq))) {\n\t\t\t\t\tnext = s;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!next) break;\n\n\t\t\tthis.sleepers.splice(this.sleepers.indexOf(next), 1);\n\t\t\tthis.time = Math.max(this.time, next.at);\n\t\t\tnext.resolve();\n\t\t\tawait settle();\n\t\t}\n\n\t\tthis.time = end;\n\t\tconst dueFrames = this.frames.splice(0, this.frames.length);\n\t\tfor (const resolveFrame of dueFrames) {\n\t\t\tresolveFrame();\n\t\t}\n\t\tawait settle();\n\t}\n\n\t/** Convenience method to advance by 1 frame at a given fps (default: 60fps = 16.67ms). */\n\tpublic async tick(fps = 60): Promise<void> {\n\t\tawait this.advance(Math.round(1000 / fps));\n\t}\n}\n","import type {\n\tCanvasNode,\n\tCanvasNodeStyle,\n\tFanOutTrajectoryOptions,\n\tNodeTransition,\n\tTrajectoryFunction,\n\tTrajectoryPoint,\n\tXYPosition\n} from './types.js';\n\n/**\n * Standard cubic ease-out function (pure math, framework-agnostic).\n */\nexport const defaultEasing = (t: number): number => --t * t * t + 1;\n\n/**\n * Standard linear trajectory: straight line interpolation with linear scale & opacity progression.\n */\nexport const linearTrajectory: TrajectoryFunction = (\n\torigin: XYPosition,\n\ttarget: XYPosition,\n\tprogress: number\n): TrajectoryPoint => {\n\treturn {\n\t\tposition: {\n\t\t\tx: origin.x + (target.x - origin.x) * progress,\n\t\t\ty: origin.y + (target.y - origin.y) * progress\n\t\t},\n\t\tscale: progress,\n\t\topacity: Math.min(1, progress * 1.5)\n\t};\n};\n\n/**\n * Linear position trajectory: pure position interpolation without altering scale or opacity.\n */\nexport const linearPositionTrajectory: TrajectoryFunction = (\n\torigin: XYPosition,\n\ttarget: XYPosition,\n\tprogress: number\n): TrajectoryPoint => {\n\treturn {\n\t\tposition: {\n\t\t\tx: origin.x + (target.x - origin.x) * progress,\n\t\t\ty: origin.y + (target.y - origin.y) * progress\n\t\t}\n\t};\n};\n\n/**\n * Creates a fan-out trajectory where nodes arc outward from origin to target.\n */\nexport function createFanOutTrajectory(options: FanOutTrajectoryOptions = {}): TrajectoryFunction {\n\tconst {\n\t\tcurvature = 0.4,\n\t\tstartScale = 0,\n\t\tendScale = 1,\n\t\tstartOpacity = 0,\n\t\tendOpacity = 1\n\t} = options;\n\n\treturn (\n\t\torigin: XYPosition,\n\t\ttarget: XYPosition,\n\t\tprogress: number,\n\t\tindex: number,\n\t\ttotal: number\n\t): TrajectoryPoint => {\n\t\tconst dx = target.x - origin.x;\n\t\tconst dy = target.y - origin.y;\n\n\t\t// Normalized index from -1 (top) to +1 (bottom)\n\t\tconst normIndex = total > 1 ? (index - (total - 1) / 2) / ((total - 1) / 2) : 0;\n\n\t\t// Perpendicular control point offset to create smooth fan arc\n\t\tconst midX = origin.x + dx * 0.4;\n\t\tconst midY = origin.y + dy * 0.1 - normIndex * Math.abs(dx) * 0.15 * curvature;\n\n\t\t// Quadratic Bezier interpolation: B(t) = (1-t)^2 * P0 + 2(1-t)t * P1 + t^2 * P2\n\t\tconst t = progress;\n\t\tconst oneMinusT = 1 - t;\n\n\t\tconst x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * midX + t * t * target.x;\n\t\tconst y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * midY + t * t * target.y;\n\n\t\tconst scale = startScale + (endScale - startScale) * progress;\n\t\tconst opacity = startOpacity + (endOpacity - startOpacity) * progress;\n\n\t\treturn {\n\t\t\tposition: { x, y },\n\t\t\tscale,\n\t\t\topacity\n\t\t};\n\t};\n}\n\n/**\n * Creates a custom quadratic Bezier trajectory with a specified control point resolver.\n */\nexport function createBezierTrajectory(\n\tgetControlPoint: (origin: XYPosition, target: XYPosition) => XYPosition\n): TrajectoryFunction {\n\treturn (origin: XYPosition, target: XYPosition, progress: number): TrajectoryPoint => {\n\t\tconst cp = getControlPoint(origin, target);\n\t\tconst t = progress;\n\t\tconst oneMinusT = 1 - t;\n\n\t\tconst x = oneMinusT * oneMinusT * origin.x + 2 * oneMinusT * t * cp.x + t * t * target.x;\n\t\tconst y = oneMinusT * oneMinusT * origin.y + 2 * oneMinusT * t * cp.y + t * t * target.y;\n\n\t\treturn {\n\t\t\tposition: { x, y },\n\t\t\tscale: progress,\n\t\t\topacity: progress\n\t\t};\n\t};\n}\n\nimport { realClock, type Clock } from './clock.js';\n\n/**\n * Returns a copy of `style` with its opacity set to `opacity`.\n *\n * Supports both CSS strings (`\"color: red; opacity: 0.5;\"`, used by SvelteFlow)\n * and style objects (`{ color: 'red', opacity: 0.5 }`, used by React Flow / xyflow).\n * When `style` is empty, `emptyFormat` decides which representation is produced.\n * Never mutates the input.\n */\nexport function withStyleOpacity(\n\tstyle: CanvasNodeStyle | undefined | null,\n\topacity: number,\n\temptyFormat: 'string' | 'object' = 'string'\n): CanvasNodeStyle {\n\tif (style !== null && typeof style === 'object') {\n\t\treturn { ...style, opacity };\n\t}\n\tif (typeof style === 'string' && style.trim() !== '') {\n\t\tconst rest = style\n\t\t\t.replace(/(^|;)\\s*opacity\\s*:\\s*[^;]*;?/gi, '$1')\n\t\t\t.trim()\n\t\t\t.replace(/;+\\s*$/, '')\n\t\t\t.trim();\n\t\treturn `${rest ? rest + '; ' : ''}opacity: ${opacity};`;\n\t}\n\treturn emptyFormat === 'object' ? { opacity } : `opacity: ${opacity};`;\n}\n\nexport interface MultiNodeTransitionOptions<TNode extends CanvasNode = CanvasNode> {\n\tdefaultDuration?: number;\n\tdefaultEasing?: (t: number) => number;\n\tclock?: Clock;\n\t/**\n\t * Style representation to create for nodes that have no `style` yet when an opacity\n\t * is applied. Defaults to `'string'` (SvelteFlow); pass `'object'` for React Flow.\n\t * Existing styles always keep their representation.\n\t */\n\tstyleFormat?: 'string' | 'object';\n\t/**\n\t * Called on every frame with updated copies of the transitioning nodes, in the same\n\t * order as the `transitions` array. Input nodes are never mutated.\n\t */\n\tonUpdate?: (nodes: TNode[]) => void;\n\t/** Called once all transitions finished, with the final node copies. */\n\tonComplete?: (nodes: TNode[]) => void;\n}\n\n/**\n * Coordinates and animates multiple node transitions simultaneously.\n *\n * The input nodes are treated as immutable: every frame produces updated copies\n * (position, `data.scale` / `data.opacity`, and `style` opacity) which are handed to\n * `onUpdate` and finally `onComplete`. Merge them into your node state by `id`.\n */\nexport function runMultiNodeTransition<TNode extends CanvasNode = CanvasNode>(\n\ttransitions: NodeTransition<TNode>[],\n\toptions: MultiNodeTransitionOptions<TNode> = {}\n): () => void {\n\tif (transitions.length === 0) {\n\t\toptions.onComplete?.([]);\n\t\treturn () => {};\n\t}\n\n\tconst {\n\t\tdefaultDuration = 400,\n\t\tdefaultEasing: easingFunc = defaultEasing,\n\t\tclock = realClock,\n\t\tstyleFormat = 'string',\n\t\tonUpdate,\n\t\tonComplete\n\t} = options;\n\n\tlet isCancelled = false;\n\tconst startTime = clock.now();\n\n\tconst items = transitions.map((tr, i) => ({\n\t\t...tr,\n\t\tindex: tr.index ?? i,\n\t\ttotal: tr.total ?? transitions.length,\n\t\tduration: tr.duration ?? defaultDuration,\n\t\teasing: tr.easing ?? easingFunc,\n\t\tdelay: tr.delay ?? 0,\n\t\ttrajectory: tr.trajectory ?? linearTrajectory\n\t}));\n\n\t// Latest copy of every node; starts out as the untouched inputs.\n\tconst current: TNode[] = items.map((item) => item.node);\n\n\tfunction frame() {\n\t\tif (isCancelled) return;\n\n\t\tconst now = clock.now();\n\t\tlet allCompleted = true;\n\n\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\tconst item = items[i];\n\t\t\tconst elapsed = now - (startTime + item.delay);\n\n\t\t\tif (elapsed < 0) {\n\t\t\t\tallCompleted = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Guard zero duration and division by zero (referenced in GOTCHAS.md)\n\t\t\tconst rawProgress = item.duration <= 0 ? 1 : Math.min(elapsed / item.duration, 1);\n\t\t\tconst progress = item.duration <= 0 ? 1 : item.easing(rawProgress);\n\n\t\t\tconst point = item.trajectory(item.from, item.to, progress, item.index, item.total);\n\n\t\t\tconst next: TNode = { ...item.node, position: { ...point.position } };\n\n\t\t\tif (point.scale !== undefined || point.opacity !== undefined) {\n\t\t\t\tconst data: Record<string, any> = { ...(item.node.data ?? {}) };\n\t\t\t\tif (point.scale !== undefined) {\n\t\t\t\t\tdata.scale = point.scale;\n\t\t\t\t}\n\t\t\t\tif (point.opacity !== undefined) {\n\t\t\t\t\tdata.opacity = point.opacity;\n\t\t\t\t\t(next as CanvasNode).style = withStyleOpacity(item.node.style, point.opacity, styleFormat);\n\t\t\t\t}\n\t\t\t\t(next as CanvasNode).data = data;\n\t\t\t}\n\n\t\t\tcurrent[i] = next;\n\n\t\t\tif (rawProgress < 1) {\n\t\t\t\tallCompleted = false;\n\t\t\t}\n\t\t}\n\n\t\tonUpdate?.(current.slice());\n\n\t\tif (!allCompleted) {\n\t\t\tclock.frame().then(frame);\n\t\t} else {\n\t\t\tonComplete?.(current.slice());\n\t\t}\n\t}\n\n\tframe();\n\n\treturn () => {\n\t\tisCancelled = true;\n\t};\n}\n","import dagre from '@dagrejs/dagre';\nimport type {\n\tCanvasEdge,\n\tCanvasNode,\n\tDirectionalDisplacementOptions,\n\tRect,\n\tReflowDisplacementOptions,\n\tXYPosition\n} from './types.js';\n\n/**\n * Calculates a bounding rectangle for a set of nodes if not provided by getNodesBounds.\n */\nexport function computeNodesBoundingBox<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\tdefaultWidth = 200,\n\tdefaultHeight = 60\n): Rect {\n\tif (nodes.length === 0) {\n\t\treturn { x: 0, y: 0, width: 0, height: 0 };\n\t}\n\n\tlet minX = Infinity;\n\tlet minY = Infinity;\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const node of nodes) {\n\t\tconst width = node.measured?.width ?? (node as any).width ?? defaultWidth;\n\t\tconst height = node.measured?.height ?? (node as any).height ?? defaultHeight;\n\n\t\tminX = Math.min(minX, node.position.x);\n\t\tminY = Math.min(minY, node.position.y);\n\t\tmaxX = Math.max(maxX, node.position.x + width);\n\t\tmaxY = Math.max(maxY, node.position.y + height);\n\t}\n\n\treturn {\n\t\tx: minX,\n\t\ty: minY,\n\t\twidth: maxX - minX,\n\t\theight: maxY - minY\n\t};\n}\n\n/**\n * Pure directional displacement calculation.\n * Shifts downstream or surrounding nodes along an axis to clear space for newly inserted child nodes.\n */\nexport function calculateDirectionalDisplacement<TNode extends CanvasNode = CanvasNode>(params: {\n\texistingNodes: TNode[];\n\toriginNode: TNode;\n\tchildNodes: TNode[];\n\tgetNodesBounds?: (nodes: TNode[]) => Rect;\n\toptions?: DirectionalDisplacementOptions;\n}): Map<string, XYPosition> {\n\tconst {\n\t\texistingNodes,\n\t\toriginNode,\n\t\tchildNodes,\n\t\tgetNodesBounds,\n\t\toptions = {}\n\t} = params;\n\n\tconst {\n\t\tdirection = 'right',\n\t\tgap = 40,\n\t\tspreadSiblingLanes = false,\n\t\tsiblingTolerance = 50,\n\t\tminY\n\t} = options;\n\n\tconst displacedMap = new Map<string, XYPosition>();\n\tif (childNodes.length === 0 || existingNodes.length === 0) {\n\t\treturn displacedMap;\n\t}\n\n\tconst childBounds = getNodesBounds\n\t\t? getNodesBounds(childNodes)\n\t\t: computeNodesBoundingBox(childNodes);\n\n\tconst originWidth = originNode.measured?.width ?? (originNode as any).width ?? 200;\n\tconst originHeight = originNode.measured?.height ?? (originNode as any).height ?? 60;\n\n\t// The delta space required along primary axis\n\tconst deltaPrimary =\n\t\tdirection === 'right' || direction === 'left'\n\t\t\t? childBounds.width + gap\n\t\t\t: childBounds.height + gap;\n\n\t// Vertical displacement parameters: upward and downward row clearance\n\tconst deltaUp = Math.max(0, originNode.position.y - childBounds.y + gap);\n\tconst deltaDown = Math.max(\n\t\t0,\n\t\tchildBounds.y + childBounds.height - (originNode.position.y + originHeight) + gap\n\t);\n\n\t// Both above and below displace equally so the row expands symmetrically\n\tconst equalDelta = Math.max(deltaUp, deltaDown);\n\n\tfor (const node of existingNodes) {\n\t\tif (node.id === originNode.id) continue;\n\n\t\tconst isSiblingRow =\n\t\t\tMath.abs(node.position.y - originNode.position.y) < siblingTolerance;\n\n\t\tswitch (direction) {\n\t\t\tcase 'right': {\n\t\t\t\tif (node.position.x > originNode.position.x) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x + deltaPrimary,\n\t\t\t\t\t\ty: node.position.y\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'left': {\n\t\t\t\tif (node.position.x < originNode.position.x) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x - deltaPrimary,\n\t\t\t\t\t\ty: node.position.y\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'down': {\n\t\t\t\tif (node.position.y > originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y + deltaPrimary\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'up': {\n\t\t\t\tif (node.position.y < originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y - deltaPrimary\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'vertical': {\n\t\t\t\tif (isSiblingRow) break;\n\n\t\t\t\tif (node.position.y < originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y - equalDelta\n\t\t\t\t\t});\n\t\t\t\t} else if (node.position.y > originNode.position.y) {\n\t\t\t\t\tdisplacedMap.set(node.id, {\n\t\t\t\t\t\tx: node.position.x,\n\t\t\t\t\t\ty: node.position.y + equalDelta\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Sibling lane spreading to avoid overlap among child nodes\n\tif (spreadSiblingLanes && (direction === 'right' || direction === 'left')) {\n\t\tfor (const [nodeId, pos] of displacedMap.entries()) {\n\t\t\tconst node = existingNodes.find((n) => n.id === nodeId);\n\t\t\tif (node && Math.abs(node.position.y - originNode.position.y) < siblingTolerance) {\n\t\t\t\tconst isAbove = node.position.y < originNode.position.y;\n\t\t\t\tdisplacedMap.set(nodeId, {\n\t\t\t\t\tx: pos.x,\n\t\t\t\t\ty: pos.y + (isAbove ? -deltaUp : deltaDown)\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Floor constraint\n\tif (minY !== undefined) {\n\t\tfor (const [nodeId, pos] of displacedMap.entries()) {\n\t\t\tif (pos.y < minY) {\n\t\t\t\tdisplacedMap.set(nodeId, { x: pos.x, y: minY });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn displacedMap;\n}\n\n/**\n * Calculates Dagre reflow displacement preserving the position of an anchor node.\n */\nexport function calculateDagreReflowDisplacement<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(params: {\n\tcurrentNodes: TNode[];\n\tcurrentEdges: TEdge[];\n\tfutureNodes: TNode[];\n\tfutureEdges: TEdge[];\n\toptions: ReflowDisplacementOptions;\n\tgetNodesBounds?: (nodes: TNode[]) => Rect;\n}): Map<string, XYPosition> {\n\tconst {\n\t\tcurrentNodes,\n\t\tfutureNodes,\n\t\tfutureEdges,\n\t\toptions\n\t} = params;\n\n\tconst {\n\t\tanchorNodeId,\n\t\tdirection = 'LR',\n\t\tranksep = 100,\n\t\tnodesep = 25,\n\t\tdefaultNodeWidth = 200,\n\t\tdefaultNodeHeight = 60\n\t} = options;\n\n\tconst anchorNode = currentNodes.find((n) => n.id === anchorNodeId);\n\tif (!anchorNode) return new Map();\n\n\tconst g = new dagre.graphlib.Graph();\n\tg.setDefaultEdgeLabel(() => ({}));\n\tg.setGraph({ rankdir: direction, ranksep, nodesep });\n\n\tconst nodeIds = new Set(futureNodes.map((n) => n.id));\n\n\tfutureNodes.forEach((node) => {\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\t\tg.setNode(node.id, { width: nodeWidth, height: nodeHeight });\n\t});\n\n\tfutureEdges.forEach((edge) => {\n\t\tif (nodeIds.has(edge.source) && nodeIds.has(edge.target)) {\n\t\t\tg.setEdge(edge.source, edge.target);\n\t\t}\n\t});\n\n\tdagre.layout(g);\n\n\tconst anchorLayoutPos = g.node(anchorNodeId);\n\tif (!anchorLayoutPos) return new Map();\n\n\tconst anchorWidth = anchorNode.measured?.width ?? (anchorNode as any).width ?? defaultNodeWidth;\n\tconst anchorHeight = anchorNode.measured?.height ?? (anchorNode as any).height ?? defaultNodeHeight;\n\n\tconst anchorLayoutUpperLeft = {\n\t\tx: anchorLayoutPos.x - anchorWidth / 2,\n\t\ty: anchorLayoutPos.y - anchorHeight / 2\n\t};\n\n\tconst deltaX = anchorNode.position.x - anchorLayoutUpperLeft.x;\n\tconst deltaY = anchorNode.position.y - anchorLayoutUpperLeft.y;\n\n\tconst displacementMap = new Map<string, XYPosition>();\n\n\tcurrentNodes.forEach((node) => {\n\t\tif (node.id === anchorNodeId) return;\n\n\t\tconst layoutNode = g.node(node.id);\n\t\tif (!layoutNode) return;\n\n\t\tconst nodeWidth = node.measured?.width ?? (node as any).width ?? defaultNodeWidth;\n\t\tconst nodeHeight = node.measured?.height ?? (node as any).height ?? defaultNodeHeight;\n\n\t\tconst upperLeftX = layoutNode.x - nodeWidth / 2 + deltaX;\n\t\tconst upperLeftY = layoutNode.y - nodeHeight / 2 + deltaY;\n\n\t\tif (\n\t\t\tMath.abs(upperLeftX - node.position.x) > 1 ||\n\t\t\tMath.abs(upperLeftY - node.position.y) > 1\n\t\t) {\n\t\t\tdisplacementMap.set(node.id, { x: upperLeftX, y: upperLeftY });\n\t\t}\n\t});\n\n\treturn displacementMap;\n}\n","import type {\n\tCanvasClipboardPayload,\n\tCanvasEdge,\n\tCanvasNode,\n\tXYPosition\n} from './types.js';\n\n/**\n * Checks if an event originated from a text input, textarea, contenteditable element, or rich editor.\n */\nexport function isEventFromTextInput(event: Event | { target: EventTarget | null }): boolean {\n\tconst target = (event as any).target as HTMLElement | null;\n\tif (!target) return false;\n\tif (\n\t\ttarget.tagName === 'INPUT' ||\n\t\ttarget.tagName === 'TEXTAREA' ||\n\t\ttarget.tagName === 'SELECT' ||\n\t\ttarget.isContentEditable ||\n\t\ttarget.closest?.('[contenteditable=\"true\"]') ||\n\t\ttarget.closest?.('.ProseMirror')\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/**\n * Validates that an object conforms to minimal CanvasNode shape:\n * a string `id` and a `position` whose `x` / `y` are finite numbers.\n */\nexport function isValidCanvasNode(obj: unknown): obj is CanvasNode {\n\tif (typeof obj !== 'object' || obj === null) return false;\n\tconst candidate = obj as { id?: unknown; position?: unknown };\n\tif (typeof candidate.id !== 'string') return false;\n\tconst position = candidate.position as { x?: unknown; y?: unknown } | null | undefined;\n\treturn (\n\t\ttypeof position === 'object' &&\n\t\tposition !== null &&\n\t\ttypeof position.x === 'number' &&\n\t\tNumber.isFinite(position.x) &&\n\t\ttypeof position.y === 'number' &&\n\t\tNumber.isFinite(position.y)\n\t);\n}\n\n/**\n * Validates that an object conforms to minimal CanvasEdge shape (string `id`, `source`, `target`).\n */\nexport function isValidCanvasEdge(obj: unknown): obj is CanvasEdge {\n\tif (typeof obj !== 'object' || obj === null) return false;\n\tconst candidate = obj as { id?: unknown; source?: unknown; target?: unknown };\n\treturn (\n\t\ttypeof candidate.id === 'string' &&\n\t\ttypeof candidate.source === 'string' &&\n\t\ttypeof candidate.target === 'string'\n\t);\n}\n\n/**\n * Checks if a string is a valid HTTP/HTTPS URL.\n */\nexport function isValidUrl(url: string): boolean {\n\ttry {\n\t\tconst parsed = new URL(url);\n\t\treturn parsed.protocol === 'http:' || parsed.protocol === 'https:';\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Serializes nodes and optional edges into clipboard JSON payload.\n */\nexport function serializeCanvasNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(nodes: TNode[], edges?: TEdge[]): string {\n\tconst payload: CanvasClipboardPayload<TNode, TEdge> = {\n\t\tversion: 1,\n\t\tnodes,\n\t\tedges\n\t};\n\treturn JSON.stringify(payload);\n}\n\n/**\n * Parses raw JSON string into a CanvasClipboardPayload if valid.\n */\nexport function parseCanvasClipboardData<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(raw: string): CanvasClipboardPayload<TNode, TEdge> | null {\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\tif (\n\t\t\ttypeof parsed === 'object' &&\n\t\t\tparsed !== null &&\n\t\t\tArray.isArray(parsed.nodes) &&\n\t\t\tparsed.nodes.length > 0 &&\n\t\t\tparsed.nodes.every(isValidCanvasNode)\n\t\t) {\n\t\t\t// Untrusted input: drop malformed edges instead of crashing downstream consumers.\n\t\t\tconst edges = Array.isArray(parsed.edges)\n\t\t\t\t? (parsed.edges as unknown[]).filter(isValidCanvasEdge)\n\t\t\t\t: undefined;\n\t\t\treturn { ...parsed, edges } as CanvasClipboardPayload<TNode, TEdge>;\n\t\t}\n\t} catch {\n\t\t// Not JSON or invalid payload\n\t}\n\treturn null;\n}\n\n/**\n * Generates unique new IDs for pasted nodes and updates edge references accordingly.\n *\n * - Nodes without a valid id / finite numeric position are skipped.\n * - `parentId` (and legacy `parentNode`) references to other pasted nodes are remapped to\n * the new IDs; such children keep their parent-relative position (no extra offset).\n * References to parents outside the pasted set are left unchanged.\n * - Edges are kept only when both endpoints were pasted; a non-array `edges` is ignored.\n */\nexport function remapPastedNodes<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[] | null | undefined = [],\n\toffset: XYPosition = { x: 30, y: 30 },\n\tidGenerator: () => string = () => `node-${Math.random().toString(36).substring(2, 9)}`\n): { nodes: TNode[]; edges: TEdge[] } {\n\tconst validNodes = (Array.isArray(nodes) ? nodes : []).filter(isValidCanvasNode) as TNode[];\n\tconst validEdges = (Array.isArray(edges) ? edges : []).filter(isValidCanvasEdge) as TEdge[];\n\n\tconst dx = Number.isFinite(offset?.x) ? offset.x : 0;\n\tconst dy = Number.isFinite(offset?.y) ? offset.y : 0;\n\n\tconst idMap = new Map<string, string>();\n\tfor (const node of validNodes) {\n\t\tidMap.set(node.id, idGenerator());\n\t}\n\n\tconst newNodes = validNodes.map((node) => {\n\t\tconst next: CanvasNode = {\n\t\t\t...node,\n\t\t\tid: idMap.get(node.id)!,\n\t\t\tposition: {\n\t\t\t\tx: node.position.x + dx,\n\t\t\t\ty: node.position.y + dy\n\t\t\t},\n\t\t\tselected: true\n\t\t};\n\n\t\tlet parentRemapped = false;\n\t\tfor (const key of ['parentId', 'parentNode'] as const) {\n\t\t\tconst parent = (node as CanvasNode)[key];\n\t\t\tif (typeof parent === 'string' && idMap.has(parent)) {\n\t\t\t\tnext[key] = idMap.get(parent)!;\n\t\t\t\tparentRemapped = true;\n\t\t\t}\n\t\t}\n\t\tif (parentRemapped) {\n\t\t\t// Position is relative to the (also pasted, also offset) parent.\n\t\t\tnext.position = { x: node.position.x, y: node.position.y };\n\t\t}\n\n\t\treturn next as TNode;\n\t});\n\n\tconst newEdges = validEdges\n\t\t.filter((e) => idMap.has(e.source) && idMap.has(e.target))\n\t\t.map((edge) => ({\n\t\t\t...edge,\n\t\t\tid: `edge-${Math.random().toString(36).substring(2, 9)}`,\n\t\t\tsource: idMap.get(edge.source)!,\n\t\t\ttarget: idMap.get(edge.target)!,\n\t\t\tselected: false\n\t\t}));\n\n\treturn { nodes: newNodes, edges: newEdges };\n}\n\n/**\n * Repositions nodes so their bounding box origin matches the given target position.\n */\nexport function repositionNodesTo<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\ttargetOrigin: XYPosition\n): TNode[] {\n\tif (nodes.length === 0) return [];\n\tconst minX = Math.min(...nodes.map((n) => n.position.x));\n\tconst minY = Math.min(...nodes.map((n) => n.position.y));\n\tconst deltaX = targetOrigin.x - minX;\n\tconst deltaY = targetOrigin.y - minY;\n\n\treturn nodes.map((n) => ({\n\t\t...n,\n\t\tposition: {\n\t\t\tx: n.position.x + deltaX,\n\t\t\ty: n.position.y + deltaY\n\t\t}\n\t}));\n}\n","import type { CanvasEdge, CanvasNode, Rect } from './types.js';\n\nexport interface CanvasHeightOptions {\n\t/** Smallest height returned (default 320). */\n\tmin?: number;\n\t/** Largest height returned; taller content is scaled/zoomed (default 560). */\n\tmax?: number;\n\t/** Extra padding around the content (default 48). */\n\tpadding?: number;\n}\n\nfunction clampHeight(contentHeight: number, options: CanvasHeightOptions = {}): number {\n\tconst { min = 320, max = 560, padding = 48 } = options;\n\treturn Math.round(Math.min(max, Math.max(min, contentHeight + padding)));\n}\n\n/**\n * Calculates the bounding box extent of all positioned nodes, or `null` for an empty graph.\n */\nexport function layoutBounds<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[]\n): Rect | null {\n\tif (nodes.length === 0) return null;\n\n\tlet minX = Infinity;\n\tlet minY = Infinity;\n\tlet maxX = -Infinity;\n\tlet maxY = -Infinity;\n\n\tfor (const node of nodes) {\n\t\tconst x = node.position.x;\n\t\tconst y = node.position.y;\n\t\tconst width = node.width ?? 180;\n\t\tconst height = node.height ?? 80;\n\n\t\tminX = Math.min(minX, x);\n\t\tminY = Math.min(minY, y);\n\t\tmaxX = Math.max(maxX, x + width);\n\t\tmaxY = Math.max(maxY, y + height);\n\t}\n\n\tif (minX === Infinity) return null;\n\treturn { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/**\n * Returns a clamped container height that fits the layout at 1:1 scale without overflow.\n */\nexport function canvasHeight<TNode extends CanvasNode = CanvasNode>(\n\tnodes: TNode[],\n\toptions?: CanvasHeightOptions\n): number {\n\treturn clampHeight(layoutBounds(nodes)?.height ?? 0, options);\n}\n\nconst DEFAULT_RANK_HEIGHT = 80 + 72; // Average node height + default rank separation\nconst NODES_PER_RANK = 2;\n\n/**\n * Estimates the container height to reserve before layout calculation finishes,\n * based on node and edge counts alone. Prevents layout shift (CLS).\n */\nexport function estimateCanvasHeight<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[],\n\toptions?: CanvasHeightOptions\n): number {\n\tconst ranks = Math.max(1, Math.ceil(nodes.length / NODES_PER_RANK));\n\treturn clampHeight(ranks * DEFAULT_RANK_HEIGHT, options);\n}\n\nfunction mix(a: number, b: number, t: number): number {\n\treturn a + (b - a) * t;\n}\n\n/**\n * Interpolates node positions and sizes between two layouts partway at progress `t` (0 = from, 1 = to).\n * Nodes present in both interpolate smoothly; nodes newly added in `to` snap to target.\n */\nexport function blendLayout<TNode extends CanvasNode = CanvasNode>(\n\tfrom: TNode[],\n\tto: TNode[],\n\tt: number\n): TNode[] {\n\tif (t >= 1) return to;\n\n\tconst fromMap = new Map<string, TNode>(from.map((n) => [n.id, n]));\n\n\treturn to.map((target) => {\n\t\tconst origin = fromMap.get(target.id);\n\t\tif (!origin) return target;\n\n\t\treturn {\n\t\t\t...target,\n\t\t\tposition: {\n\t\t\t\tx: mix(origin.position.x, target.position.x, t),\n\t\t\t\ty: mix(origin.position.y, target.position.y, t)\n\t\t\t},\n\t\t\twidth:\n\t\t\t\torigin.width !== undefined && target.width !== undefined\n\t\t\t\t\t? mix(origin.width, target.width, t)\n\t\t\t\t\t: target.width,\n\t\t\theight:\n\t\t\t\torigin.height !== undefined && target.height !== undefined\n\t\t\t\t\t? mix(origin.height, target.height, t)\n\t\t\t\t\t: target.height\n\t\t};\n\t});\n}\n\n/**\n * Filters out nodes that are not touched by any edge.\n *\n * During LLM streaming, nodes often arrive a chunk or token before the edge\n * that connects them. Displaying them immediately causes them to be placed as root\n * nodes only to jump into their correct position once the edge arrives.\n * Hiding orphan nodes during active streaming keeps the layout calm and jitter-free.\n */\nexport function connectedOnly<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n>(\n\tnodes: TNode[],\n\tedges: TEdge[]\n): TNode[] {\n\tif (edges.length === 0) return nodes;\n\n\tconst linkedNodeIds = new Set<string>();\n\tfor (const edge of edges) {\n\t\tlinkedNodeIds.add(edge.source);\n\t\tlinkedNodeIds.add(edge.target);\n\t}\n\n\tconst filtered = nodes.filter((node) => linkedNodeIds.has(node.id));\n\t// If filtering would remove everything, return the original nodes\n\treturn filtered.length > 0 ? filtered : nodes;\n}\n","import { realClock, type Clock } from './clock.js';\nimport { ensureLayout } from './layout.js';\nimport { linearPositionTrajectory, runMultiNodeTransition } from './trajectory.js';\nimport type { CanvasEdge, CanvasNode, IncrementalLayoutOptions, NodeTransition, XYPosition } from './types.js';\nimport { connectedOnly } from './view.js';\n\nexport interface StreamingLayoutManagerOptions {\n\tthrottleMs?: number;\n\tglideDurationMs?: number;\n\tconnectedOnly?: boolean;\n\tclock?: Clock;\n\tlayoutOptions?: IncrementalLayoutOptions;\n\tonLayoutUpdated?: (positions: Map<string, XYPosition>) => void;\n}\n\n/**\n * Manages throttled incremental layout recalculation and smooth tweened node gliding\n * during active streaming (e.g. LLM streaming or graph generation).\n *\n * - `pushStreamUpdate` is a true throttle (leading + trailing edge): the first update\n * lays out immediately, further updates within `throttleMs` are coalesced and the\n * latest one is laid out when the window closes. Layouts therefore keep running at\n * most once per `throttleMs` while a stream is active, instead of being postponed\n * until the stream goes quiet.\n * - Every layout is computed from the graph (respecting `layoutOptions.storedPositions`\n * as pinned/manual coordinates) and each known node glides from its *current*\n * position (the `currentPositions` argument) to its newly computed position.\n */\nexport class StreamingLayoutManager<\n\tTNode extends CanvasNode = CanvasNode,\n\tTEdge extends CanvasEdge = CanvasEdge\n> {\n\tprivate throttleMs: number;\n\tprivate glideDurationMs: number;\n\tprivate connectedOnly: boolean;\n\tprivate clock: Clock;\n\tprivate layoutOptions: IncrementalLayoutOptions;\n\tprivate onLayoutUpdated?: (positions: Map<string, XYPosition>) => void;\n\n\tprivate pendingTimer: ReturnType<typeof setTimeout> | null = null;\n\tprivate pendingArgs: [TNode[], TEdge[], Map<string, XYPosition>] | null = null;\n\tprivate activeTransitionCancel: (() => void) | null = null;\n\tprivate targetPositions = new Map<string, XYPosition>();\n\tprivate livePositions = new Map<string, XYPosition>();\n\n\tconstructor(options: StreamingLayoutManagerOptions = {}) {\n\t\tthis.throttleMs = options.throttleMs ?? 200;\n\t\tthis.glideDurationMs = options.glideDurationMs ?? 300;\n\t\tthis.connectedOnly = options.connectedOnly ?? false;\n\t\tthis.clock = options.clock ?? realClock;\n\t\tthis.layoutOptions = options.layoutOptions ?? { direction: 'LR' };\n\t\tthis.onLayoutUpdated = options.onLayoutUpdated;\n\t}\n\n\t/**\n\t * Feed incoming nodes and edges into the streaming manager.\n\t * Throttles rapid streaming bursts (leading + trailing edge) and triggers smooth layout gliding.\n\t */\n\tpublic pushStreamUpdate(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tif (this.pendingTimer !== null) {\n\t\t\t// Inside the throttle window: remember the latest update for the trailing edge.\n\t\t\tthis.pendingArgs = [nodes, edges, currentPositions];\n\t\t\treturn;\n\t\t}\n\n\t\t// Leading edge: lay out immediately and open a throttle window.\n\t\tthis.recalculateAndGlide(nodes, edges, currentPositions);\n\t\tthis.startWindow();\n\t}\n\n\tprivate startWindow(): void {\n\t\tthis.pendingTimer = setTimeout(() => {\n\t\t\tthis.pendingTimer = null;\n\t\t\tconst args = this.pendingArgs;\n\t\t\tthis.pendingArgs = null;\n\t\t\tif (args) {\n\t\t\t\t// Trailing edge: lay out the latest coalesced update and keep throttling.\n\t\t\t\tthis.recalculateAndGlide(...args);\n\t\t\t\tthis.startWindow();\n\t\t\t}\n\t\t}, Math.max(0, this.throttleMs));\n\t}\n\n\t/**\n\t * Forces immediate calculation and cancels pending throttled timers.\n\t */\n\tpublic flush(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tthis.clearPending();\n\t\tthis.recalculateAndGlide(nodes, edges, currentPositions);\n\t}\n\n\t/**\n\t * Latest computed layout targets (the positions nodes are gliding towards).\n\t */\n\tpublic getTargetPositions(): Map<string, XYPosition> {\n\t\treturn new Map(this.targetPositions);\n\t}\n\n\tprivate clearPending(): void {\n\t\tif (this.pendingTimer !== null) {\n\t\t\tclearTimeout(this.pendingTimer);\n\t\t\tthis.pendingTimer = null;\n\t\t}\n\t\tthis.pendingArgs = null;\n\t}\n\n\tprivate recalculateAndGlide(\n\t\tnodes: TNode[],\n\t\tedges: TEdge[],\n\t\tcurrentPositions: Map<string, XYPosition>\n\t): void {\n\t\tconst targetNodes = this.connectedOnly ? connectedOnly(nodes, edges) : nodes;\n\t\tif (targetNodes.length === 0) return;\n\n\t\t// Where nodes are right now: the caller's view, overridden by any glide still in\n\t\t// flight (the caller may not have applied the latest animated frame yet).\n\t\tconst startPositions = new Map<string, XYPosition>(currentPositions);\n\t\tif (this.activeTransitionCancel) {\n\t\t\tfor (const [id, pos] of this.livePositions) {\n\t\t\t\tstartPositions.set(id, pos);\n\t\t\t}\n\t\t\tthis.activeTransitionCancel();\n\t\t\tthis.activeTransitionCancel = null;\n\t\t}\n\n\t\t// Compute fresh layout targets. Only explicitly stored (pinned/manual) positions\n\t\t// are preserved; current positions are the glide *origin*, not the destination.\n\t\tconst layouted = ensureLayout(targetNodes, edges, this.layoutOptions);\n\n\t\tconst nextPositions = new Map<string, XYPosition>();\n\t\tconst transitions: NodeTransition<TNode>[] = [];\n\n\t\tfor (const node of layouted) {\n\t\t\tconst target = { ...node.position };\n\t\t\tnextPositions.set(node.id, target);\n\n\t\t\tconst current = startPositions.get(node.id);\n\t\t\tif (!current) continue; // brand-new node: appears directly at its target\n\n\t\t\tconst distance = Math.hypot(target.x - current.x, target.y - current.y);\n\t\t\tif (distance > 2) {\n\t\t\t\ttransitions.push({\n\t\t\t\t\tnode: { ...node, position: { ...current } },\n\t\t\t\t\tfrom: current,\n\t\t\t\t\tto: target,\n\t\t\t\t\ttrajectory: linearPositionTrajectory,\n\t\t\t\t\tduration: this.glideDurationMs\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.targetPositions = nextPositions;\n\n\t\tif (transitions.length === 0) {\n\t\t\tthis.livePositions = new Map(nextPositions);\n\t\t\tthis.onLayoutUpdated?.(nextPositions);\n\t\t\treturn;\n\t\t}\n\n\t\tconst live = new Map<string, XYPosition>(nextPositions);\n\t\tfor (const trans of transitions) {\n\t\t\tlive.set(trans.node.id, { ...trans.from });\n\t\t}\n\t\tthis.livePositions = live;\n\n\t\tlet finished = false;\n\t\tconst cancel = runMultiNodeTransition(transitions, {\n\t\t\tclock: this.clock,\n\t\t\tonUpdate: (updated) => {\n\t\t\t\tconst frame = new Map<string, XYPosition>(this.livePositions);\n\t\t\t\tfor (const node of updated) {\n\t\t\t\t\tframe.set(node.id, { ...node.position });\n\t\t\t\t}\n\t\t\t\tthis.livePositions = frame;\n\t\t\t\tthis.onLayoutUpdated?.(frame);\n\t\t\t},\n\t\t\tonComplete: () => {\n\t\t\t\tfinished = true;\n\t\t\t\tthis.activeTransitionCancel = null;\n\t\t\t\tthis.livePositions = new Map(nextPositions);\n\t\t\t\tthis.onLayoutUpdated?.(nextPositions);\n\t\t\t}\n\t\t});\n\t\t// A zero-duration glide completes synchronously; don't keep a stale canceller.\n\t\tthis.activeTransitionCancel = finished ? null : cancel;\n\t}\n\n\tpublic destroy(): void {\n\t\tthis.clearPending();\n\t\tif (this.activeTransitionCancel) {\n\t\t\tthis.activeTransitionCancel();\n\t\t\tthis.activeTransitionCancel = null;\n\t\t}\n\t}\n}\n","import { boundsOf, estimateNodeSize } from './layout.js';\nimport type { CanvasNode, CanvasNodeStyle, Rect, XYPosition } from './types.js';\n\n/**\n * Edge (or centre line) used by `alignNodes`.\n * `center` aligns horizontal centres (a vertical line); `middle` aligns vertical centres.\n */\nexport type AlignEdge = 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom';\n\n/** Axis used by `distributeNodes`. `both` distributes horizontally and vertically. */\nexport type DistributeAxis = 'horizontal' | 'vertical' | 'both';\n\n/**\n * `gaps` leaves equal space between neighbouring nodes, `centres` spaces their centres equally.\n */\nexport type DistributeMode = 'gaps' | 'centres';\n\n/** Dimension(s) copied by `matchSize`. */\nexport type SizeDimension = 'width' | 'height' | 'both';\n\n/**\n * Partial node change produced by the arrange helpers. `position` is in the node's own\n * coordinate space (relative to its `parentId` parent when it has one).\n */\nexport interface CanvasNodeUpdate {\n\tid: string;\n\tposition?: XYPosition;\n\twidth?: number;\n\theight?: number;\n\tzIndex?: number;\n}\n\nexport interface NodeRectOptions {\n\t/** Width used when a node has no measured, explicit or style size and estimation is off. */\n\tdefaultWidth?: number;\n\t/** Height used when a node has no measured, explicit or style size and estimation is off. */\n\tdefaultHeight?: number;\n\t/** Estimate unmeasured node sizes from their label via `estimateNodeSize` (default `true`). */\n\testimate?: boolean;\n}\n\n/** Data key marking a node as locked. See `lockNodes`. */\nexport const LOCKED_DATA_KEY = 'locked';\n/** Data key holding the interaction flags a node had before it was locked. */\nexport const LOCKED_PREVIOUS_FLAGS_KEY = 'lockedPrevious';\n\nfunction parsePx(value: unknown): number | undefined {\n\tif (typeof value === 'number' && Number.isFinite(value)) return value;\n\tif (typeof value === 'string') {\n\t\tconst match = /^\\s*(-?\\d+(?:\\.\\d+)?)(px)?\\s*$/i.exec(value);\n\t\tif (match) return Number(match[1]);\n\t}\n\treturn undefined;\n}\n\n/**\n * Reads a pixel `width` / `height` from a node style, which may be a CSS string (SvelteFlow)\n * or a style object (React Flow). Non-pixel values (`%`, `auto`, ...) are ignored.\n */\nexport function readStyleSize(style: CanvasNodeStyle | undefined | null): {\n\twidth?: number;\n\theight?: number;\n} {\n\tif (!style) return {};\n\tif (typeof style === 'object') {\n\t\treturn { width: parsePx(style.width), height: parsePx(style.height) };\n\t}\n\tconst read = (prop: string) => {\n\t\tconst match = new RegExp(`(?:^|;)\\\\s*${prop}\\\\s*:\\\\s*([^;]+)`, 'i').exec(style);\n\t\treturn match ? parsePx(match[1]) : undefined;\n\t};\n\treturn { width: read('width'), height: read('height') };\n}\n\n/**\n * Returns `style` with its pixel `width` / `height` replaced, keeping its representation\n * (string or object). Only dimensions already present in the style are rewritten, because\n * xyflow applies the node's own `width` / `height` props otherwise.\n */\nexport function withStyleSize(\n\tstyle: CanvasNodeStyle | undefined | null,\n\tsize: { width?: number; height?: number }\n): CanvasNodeStyle | undefined {\n\tif (!style) return style ?? undefined;\n\tif (typeof style === 'object') {\n\t\tconst next: Record<string, any> = { ...style };\n\t\tif (size.width !== undefined && 'width' in next) next.width = size.width;\n\t\tif (size.height !== undefined && 'height' in next) next.height = size.height;\n\t\treturn next;\n\t}\n\tlet next = style;\n\tfor (const prop of ['width', 'height'] as const) {\n\t\tconst value = size[prop];\n\t\tif (value === undefined) continue;\n\t\tnext = next.replace(\n\t\t\tnew RegExp(`((?:^|;)\\\\s*${prop}\\\\s*:\\\\s*)[^;]+`, 'i'),\n\t\t\t`$1${value}px`\n\t\t);\n\t}\n\treturn next;\n}\n\n/**\n * Resolves a node's size: measured DOM size, then explicit `width` / `height`, then a pixel\n * size in `style`, then a label-based estimate (or the defaults when `estimate` is `false`).\n */\nexport function getNodeSize(\n\tnode: CanvasNode,\n\toptions: NodeRectOptions = {}\n): { width: number; height: number } {\n\tconst styleSize = readStyleSize(node.style);\n\tlet width = node.measured?.width ?? node.width ?? styleSize.width;\n\tlet height = node.measured?.height ?? node.height ?? styleSize.height;\n\tif (width === undefined || height === undefined) {\n\t\tconst fallback =\n\t\t\toptions.estimate === false\n\t\t\t\t? { width: options.defaultWidth ?? 200, height: options.defaultHeight ?? 60 }\n\t\t\t\t: estimateNodeSize(node, options.defaultWidth, options.defaultHeight);\n\t\twidth ??= fallback.width;\n\t\theight ??= fallback.height;\n\t}\n\treturn { width, height };\n}\n\n/**\n * Absolute (flow-space) position of a node, following its `parentId` chain.\n * Cycles and missing parents are tolerated.\n */\nexport function getAbsolutePosition(\n\tnode: CanvasNode,\n\tlookup: ReadonlyMap<string, CanvasNode>\n): XYPosition {\n\tlet x = node.position.x;\n\tlet y = node.position.y;\n\tconst seen = new Set<string>([node.id]);\n\tlet parentId = node.parentId;\n\twhile (parentId && !seen.has(parentId)) {\n\t\tconst parent = lookup.get(parentId);\n\t\tif (!parent) break;\n\t\tseen.add(parentId);\n\t\tx += parent.position.x;\n\t\ty += parent.position.y;\n\t\tparentId = parent.parentId;\n\t}\n\treturn { x, y };\n}\n\n/** Builds an id lookup for a node array. */\nexport function createNodeLookup<TNode extends CanvasNode>(nodes: TNode[]): Map<string, TNode> {\n\treturn new Map(nodes.map((n) => [n.id, n]));\n}\n\n/** Absolute flow-space rectangle of a node. */\nexport function getNodeRect(\n\tnode: CanvasNode,\n\tlookup?: ReadonlyMap<string, CanvasNode>,\n\toptions?: NodeRectOptions\n): Rect {\n\tconst { x, y } = node.parentId && lookup ? getAbsolutePosition(node, lookup) : node.position;\n\treturn { x, y, ...getNodeSize(node, options) };\n}\n\n/**\n * Whether a node has been locked with `lockNodes`.\n */\nexport function isLocked(node: CanvasNode | undefined | null): boolean {\n\treturn node?.data?.[LOCKED_DATA_KEY] === true;\n}\n\n/**\n * Locks nodes: marks `data.locked = true` and sets `draggable: false` and `deletable: false`\n * so both SvelteFlow and React Flow stop dragging and deleting them. Nodes stay `selectable`\n * so they can be unlocked again. The previous flags are kept in `data.lockedPrevious` and\n * restored by `unlockNodes`. Returns a new array; untouched nodes keep their identity.\n */\nexport function lockNodes<TNode extends CanvasNode>(nodes: TNode[], ids: Iterable<string>): TNode[] {\n\tconst idSet = new Set(ids);\n\treturn nodes.map((node) => {\n\t\tif (!idSet.has(node.id) || isLocked(node)) return node;\n\t\tconst previous: Record<string, boolean> = {};\n\t\tif (node.draggable !== undefined) previous.draggable = node.draggable;\n\t\tif (node.deletable !== undefined) previous.deletable = node.deletable;\n\t\treturn {\n\t\t\t...node,\n\t\t\tdraggable: false,\n\t\t\tdeletable: false,\n\t\t\tdata: { ...node.data, [LOCKED_DATA_KEY]: true, [LOCKED_PREVIOUS_FLAGS_KEY]: previous }\n\t\t};\n\t});\n}\n\n/**\n * Reverses `lockNodes`, restoring the `draggable` / `deletable` flags the node had before.\n */\nexport function unlockNodes<TNode extends CanvasNode>(nodes: TNode[], ids: Iterable<string>): TNode[] {\n\tconst idSet = new Set(ids);\n\treturn nodes.map((node) => {\n\t\tif (!idSet.has(node.id) || !isLocked(node)) return node;\n\t\tconst {\n\t\t\t[LOCKED_DATA_KEY]: _locked,\n\t\t\t[LOCKED_PREVIOUS_FLAGS_KEY]: previous = {},\n\t\t\t...data\n\t\t} = node.data as Record<string, any>;\n\t\tconst next = { ...node, data } as TNode;\n\t\tdelete next.draggable;\n\t\tdelete next.deletable;\n\t\tif (previous.draggable !== undefined) next.draggable = previous.draggable;\n\t\tif (previous.deletable !== undefined) next.deletable = previous.deletable;\n\t\treturn next;\n\t});\n}\n\n/** Locks the given nodes if any of them is unlocked, otherwise unlocks them all. */\nexport function toggleLockNodes<TNode extends CanvasNode>(nodes: TNode[], ids: Iterable<string>): TNode[] {\n\tconst idSet = new Set(ids);\n\tconst anyUnlocked = nodes.some((n) => idSet.has(n.id) && !isLocked(n));\n\treturn anyUnlocked ? lockNodes(nodes, idSet) : unlockNodes(nodes, idSet);\n}\n\ninterface Item {\n\tnode: CanvasNode;\n\trect: Rect;\n\tlocked: boolean;\n}\n\nfunction collect(nodes: CanvasNode[], ids: Iterable<string>, options?: NodeRectOptions) {\n\tconst lookup = createNodeLookup(nodes);\n\tconst items: Item[] = [];\n\tconst seen = new Set<string>();\n\tfor (const id of ids) {\n\t\tconst node = lookup.get(id);\n\t\tif (!node || seen.has(id)) continue;\n\t\tseen.add(id);\n\t\titems.push({ node, rect: getNodeRect(node, lookup, options), locked: isLocked(node) });\n\t}\n\treturn { lookup, items };\n}\n\n/**\n * Converts absolute target positions into node-relative `position` updates. When a parent\n * moves in the same operation, children are made relative to the parent's new position.\n */\nfunction toPositionUpdates(\n\tlookup: Map<string, CanvasNode>,\n\ttargets: Map<string, XYPosition>\n): CanvasNodeUpdate[] {\n\tconst updates: CanvasNodeUpdate[] = [];\n\tfor (const [id, abs] of targets) {\n\t\tconst node = lookup.get(id)!;\n\t\tlet position = abs;\n\t\tif (node.parentId && lookup.has(node.parentId)) {\n\t\t\tconst parent = lookup.get(node.parentId)!;\n\t\t\tconst parentAbs = targets.get(parent.id) ?? getAbsolutePosition(parent, lookup);\n\t\t\tposition = { x: abs.x - parentAbs.x, y: abs.y - parentAbs.y };\n\t\t}\n\t\tif (position.x !== node.position.x || position.y !== node.position.y) {\n\t\t\tupdates.push({ id, position });\n\t\t}\n\t}\n\treturn updates;\n}\n\nexport interface AlignNodesOptions extends NodeRectOptions {\n\t/**\n\t * What to align to: the selection bounding box (default) or a fixed rectangle.\n\t * Locked nodes never move but still count towards the selection bounds, so they act as anchors.\n\t */\n\tto?: 'selection' | Rect;\n}\n\n/**\n * Aligns nodes to a shared edge or centre line of their bounding box (Freeform's\n * Align Left / Center / Right / Top / Middle / Bottom). Needs at least two nodes unless\n * `options.to` is a rectangle. Locked nodes are not moved.\n */\nexport function alignNodes(\n\tnodes: CanvasNode[],\n\tids: Iterable<string>,\n\tedge: AlignEdge,\n\toptions: AlignNodesOptions = {}\n): CanvasNodeUpdate[] {\n\tconst { lookup, items } = collect(nodes, ids, options);\n\tconst fixed = typeof options.to === 'object' ? options.to : null;\n\tif (items.length === 0 || (!fixed && items.length < 2)) return [];\n\tconst bounds = fixed ?? boundsOf(items.map((i) => i.rect))!;\n\n\tconst targets = new Map<string, XYPosition>();\n\tfor (const { node, rect, locked } of items) {\n\t\tif (locked) continue;\n\t\tlet { x, y } = rect;\n\t\tswitch (edge) {\n\t\t\tcase 'left':\n\t\t\t\tx = bounds.x;\n\t\t\t\tbreak;\n\t\t\tcase 'center':\n\t\t\t\tx = bounds.x + bounds.width / 2 - rect.width / 2;\n\t\t\t\tbreak;\n\t\t\tcase 'right':\n\t\t\t\tx = bounds.x + bounds.width - rect.width;\n\t\t\t\tbreak;\n\t\t\tcase 'top':\n\t\t\t\ty = bounds.y;\n\t\t\t\tbreak;\n\t\t\tcase 'middle':\n\t\t\t\ty = bounds.y + bounds.height / 2 - rect.height / 2;\n\t\t\t\tbreak;\n\t\t\tcase 'bottom':\n\t\t\t\ty = bounds.y + bounds.height - rect.height;\n\t\t\t\tbreak;\n\t\t}\n\t\ttargets.set(node.id, { x, y });\n\t}\n\treturn toPositionUpdates(lookup, targets);\n}\n\nexport interface DistributeNodesOptions extends NodeRectOptions {\n\t/** Explicit gap between neighbours for `gaps` mode. Default: spread evenly between the outer nodes. */\n\tgap?: number;\n}\n\nfunction distributeAxis(\n\titems: Item[],\n\thorizontal: boolean,\n\tmode: DistributeMode,\n\tgapOverride: number | undefined,\n\ttargets: Map<string, XYPosition>\n) {\n\tconst start = (r: Rect) => (horizontal ? r.x : r.y);\n\tconst size = (r: Rect) => (horizontal ? r.width : r.height);\n\tconst sorted = [...items].sort(\n\t\t(a, b) => start(a.rect) + size(a.rect) / 2 - (start(b.rect) + size(b.rect) / 2)\n\t);\n\tconst first = sorted[0].rect;\n\tconst last = sorted[sorted.length - 1].rect;\n\tconst n = sorted.length;\n\tconst set = (item: Item, value: number) => {\n\t\tif (item.locked) return;\n\t\tconst current = targets.get(item.node.id) ?? { x: item.rect.x, y: item.rect.y };\n\t\ttargets.set(item.node.id, horizontal ? { ...current, x: value } : { ...current, y: value });\n\t};\n\n\tif (mode === 'centres') {\n\t\tconst c0 = start(first) + size(first) / 2;\n\t\tconst c1 = start(last) + size(last) / 2;\n\t\tconst step = (c1 - c0) / (n - 1);\n\t\tsorted.forEach((item, i) => set(item, c0 + step * i - size(item.rect) / 2));\n\t\treturn;\n\t}\n\n\tconst span = start(last) + size(last) - start(first);\n\tconst total = sorted.reduce((sum, item) => sum + size(item.rect), 0);\n\tconst gap = gapOverride ?? (span - total) / (n - 1);\n\tlet cursor = start(first);\n\tfor (const item of sorted) {\n\t\tset(item, cursor);\n\t\tcursor += size(item.rect) + gap;\n\t}\n}\n\n/**\n * Distributes nodes along an axis (Freeform's Distribute Horizontally / Vertically / Evenly).\n * The outermost nodes stay put and the others are spaced with equal gaps (`gaps`, default)\n * or equally spaced centres (`centres`). Needs at least three nodes (two with an explicit\n * `gap`). Locked nodes keep their place in the order but are not moved.\n */\nexport function distributeNodes(\n\tnodes: CanvasNode[],\n\tids: Iterable<string>,\n\taxis: DistributeAxis,\n\tmode: DistributeMode = 'gaps',\n\toptions: DistributeNodesOptions = {}\n): CanvasNodeUpdate[] {\n\tconst { lookup, items } = collect(nodes, ids, options);\n\tconst minimum = options.gap !== undefined && mode === 'gaps' ? 2 : 3;\n\tif (items.length < minimum) return [];\n\tconst targets = new Map<string, XYPosition>();\n\tif (axis !== 'vertical') distributeAxis(items, true, mode, options.gap, targets);\n\tif (axis !== 'horizontal') distributeAxis(items, false, mode, options.gap, targets);\n\treturn toPositionUpdates(lookup, targets);\n}\n\nexport interface MatchSizeOptions extends NodeRectOptions {\n\t/**\n\t * Size source: the `largest` (default) or `smallest` node, the `first` id given,\n\t * or a specific node id.\n\t */\n\treference?: 'largest' | 'smallest' | 'first' | { id: string };\n\t/** Keep each node's centre in place instead of its top-left corner (default `false`). */\n\tkeepCentre?: boolean;\n}\n\n/**\n * Makes nodes the same width, height or both (Freeform's Make Same Size). Returns size\n * updates (plus position updates with `keepCentre`). Locked nodes are not resized but can\n * be the reference.\n */\nexport function matchSize(\n\tnodes: CanvasNode[],\n\tids: Iterable<string>,\n\tdimension: SizeDimension,\n\toptions: MatchSizeOptions = {}\n): CanvasNodeUpdate[] {\n\tconst { items } = collect(nodes, ids, options);\n\tif (items.length < 2) return [];\n\tconst reference = options.reference ?? 'largest';\n\n\tconst pick = (dim: 'width' | 'height'): number => {\n\t\tif (typeof reference === 'object') {\n\t\t\tconst item = items.find((i) => i.node.id === reference.id);\n\t\t\tif (item) return item.rect[dim];\n\t\t}\n\t\tif (reference === 'first') return items[0].rect[dim];\n\t\tconst values = items.map((i) => i.rect[dim]);\n\t\treturn reference === 'smallest' ? Math.min(...values) : Math.max(...values);\n\t};\n\tconst width = dimension !== 'height' ? pick('width') : undefined;\n\tconst height = dimension !== 'width' ? pick('height') : undefined;\n\n\tconst updates: CanvasNodeUpdate[] = [];\n\tfor (const { node, rect, locked } of items) {\n\t\tif (locked) continue;\n\t\tconst update: CanvasNodeUpdate = { id: node.id };\n\t\tif (width !== undefined && width !== rect.width) update.width = width;\n\t\tif (height !== undefined && height !== rect.height) update.height = height;\n\t\tif (update.width === undefined && update.height === undefined) continue;\n\t\tif (options.keepCentre) {\n\t\t\tupdate.position = {\n\t\t\t\tx: node.position.x - ((update.width ?? rect.width) - rect.width) / 2,\n\t\t\t\ty: node.position.y - ((update.height ?? rect.height) - rect.height) / 2\n\t\t\t};\n\t\t}\n\t\tupdates.push(update);\n\t}\n\treturn updates;\n}\n\n/** Z-order operation. */\nexport type ZOrderOperation = 'bringForward' | 'sendBackward' | 'bringToFront' | 'sendToBack';\n\n/**\n * Restacks nodes (Bring Forward / Send Backward / Bring to Front / Send to Back).\n *\n * Both SvelteFlow and React Flow stack nodes by `zIndex` (missing = 0) and, for equal\n * `zIndex`, by array order. This computes that effective order for the siblings that share\n * the targets' parent, applies the operation, and returns `zIndex` updates assigning each\n * sibling its new rank. The array order is left alone, because xyflow requires parents to\n * precede their children. Locked nodes are not restacked. \"Forward\" moves past the next\n * sibling the node overlaps, falling back to the next sibling when nothing overlaps.\n */\nexport function reorderNodes(\n\tnodes: CanvasNode[],\n\tids: Iterable<string>,\n\toperation: ZOrderOperation,\n\toptions: NodeRectOptions = {}\n): CanvasNodeUpdate[] {\n\tconst lookup = createNodeLookup(nodes);\n\tconst targetIds = new Set(\n\t\t[...ids].filter((id) => lookup.has(id) && !isLocked(lookup.get(id)))\n\t);\n\tif (targetIds.size === 0) return [];\n\n\t// Restack each sibling group (nodes sharing a parent) independently.\n\tconst groups = new Map<string, CanvasNode[]>();\n\tfor (const node of nodes) {\n\t\tconst key = node.parentId ?? '';\n\t\tif (!groups.has(key)) groups.set(key, []);\n\t\tgroups.get(key)!.push(node);\n\t}\n\n\tconst updates: CanvasNodeUpdate[] = [];\n\tfor (const siblings of groups.values()) {\n\t\tif (!siblings.some((n) => targetIds.has(n.id))) continue;\n\t\tconst order = siblings\n\t\t\t.map((node, index) => ({ node, index, z: typeof node.zIndex === 'number' ? node.zIndex : 0 }))\n\t\t\t.sort((a, b) => a.z - b.z || a.index - b.index)\n\t\t\t.map((entry) => entry.node);\n\t\tconst isTarget = (n: CanvasNode) => targetIds.has(n.id);\n\t\tlet next: CanvasNode[];\n\n\t\tif (operation === 'bringToFront') {\n\t\t\tnext = [...order.filter((n) => !isTarget(n)), ...order.filter(isTarget)];\n\t\t} else if (operation === 'sendToBack') {\n\t\t\tnext = [...order.filter(isTarget), ...order.filter((n) => !isTarget(n))];\n\t\t} else {\n\t\t\tnext = [...order];\n\t\t\tconst forward = operation === 'bringForward';\n\t\t\tconst rects = new Map(next.map((n) => [n.id, getNodeRect(n, lookup, options)]));\n\t\t\tconst intersects = (a: Rect, b: Rect) =>\n\t\t\t\ta.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y;\n\t\t\t// Walk from the end we are moving towards so adjacent targets keep their relative order.\n\t\t\tconst indices = next.map((_, i) => i);\n\t\t\tif (forward) indices.reverse();\n\t\t\tfor (const i of indices) {\n\t\t\t\tconst node = next[i];\n\t\t\t\tif (!isTarget(node)) continue;\n\t\t\t\tconst step = forward ? 1 : -1;\n\t\t\t\tlet j = i + step;\n\t\t\t\tlet swapWith = -1;\n\t\t\t\tlet firstNonTarget = -1;\n\t\t\t\twhile (j >= 0 && j < next.length) {\n\t\t\t\t\tif (!isTarget(next[j])) {\n\t\t\t\t\t\tif (firstNonTarget === -1) firstNonTarget = j;\n\t\t\t\t\t\tif (intersects(rects.get(node.id)!, rects.get(next[j].id)!)) {\n\t\t\t\t\t\t\tswapWith = j;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tj += step;\n\t\t\t\t}\n\t\t\t\tif (swapWith === -1) swapWith = firstNonTarget;\n\t\t\t\tif (swapWith === -1) continue;\n\t\t\t\tnext.splice(i, 1);\n\t\t\t\tnext.splice(swapWith, 0, node);\n\t\t\t}\n\t\t}\n\n\t\tif (next.every((node, i) => node === order[i])) continue;\n\t\tnext.forEach((node, rank) => {\n\t\t\tconst current = typeof node.zIndex === 'number' ? node.zIndex : 0;\n\t\t\tif (current !== rank) updates.push({ id: node.id, zIndex: rank });\n\t\t});\n\t}\n\treturn updates;\n}\n\n/**\n * Applies `CanvasNodeUpdate`s to a node array, returning a new array. Unchanged nodes keep\n * their identity. Size updates set `width` / `height` and rewrite pixel sizes already present\n * in `style` (string or object). An existing `measured` size is updated too, so geometry\n * helpers see the new size before xyflow re-measures the node.\n */\nexport function applyNodeUpdates<TNode extends CanvasNode>(\n\tnodes: TNode[],\n\tupdates: CanvasNodeUpdate[]\n): TNode[] {\n\tif (updates.length === 0) return nodes;\n\tconst byId = new Map<string, CanvasNodeUpdate>();\n\tfor (const update of updates) {\n\t\tbyId.set(update.id, { ...byId.get(update.id), ...update });\n\t}\n\treturn nodes.map((node) => {\n\t\tconst update = byId.get(node.id);\n\t\tif (!update) return node;\n\t\tconst next = { ...node } as TNode;\n\t\tif (update.position) next.position = { ...update.position };\n\t\tif (update.zIndex !== undefined) (next as CanvasNode).zIndex = update.zIndex;\n\t\tif (update.width !== undefined || update.height !== undefined) {\n\t\t\tif (update.width !== undefined) next.width = update.width;\n\t\t\tif (update.height !== undefined) next.height = update.height;\n\t\t\tif (node.style) next.style = withStyleSize(node.style, update);\n\t\t\tif (node.measured) {\n\t\t\t\tnext.measured = {\n\t\t\t\t\t...node.measured,\n\t\t\t\t\t...(update.width !== undefined ? { width: update.width } : {}),\n\t\t\t\t\t...(update.height !== undefined ? { height: update.height } : {})\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn next;\n\t});\n}\n\n/**\n * Inverse of a set of updates against the current nodes, for undo. Restores the previous\n * position / size / zIndex of every node an update touches.\n */\nexport function invertNodeUpdates(\n\tnodes: CanvasNode[],\n\tupdates: CanvasNodeUpdate[]\n): CanvasNodeUpdate[] {\n\tconst lookup = createNodeLookup(nodes);\n\tconst inverse: CanvasNodeUpdate[] = [];\n\tfor (const update of updates) {\n\t\tconst node = lookup.get(update.id);\n\t\tif (!node) continue;\n\t\tconst back: CanvasNodeUpdate = { id: node.id };\n\t\tif (update.position) back.position = { ...node.position };\n\t\tif (update.zIndex !== undefined) back.zIndex = typeof node.zIndex === 'number' ? node.zIndex : 0;\n\t\tif (update.width !== undefined || update.height !== undefined) {\n\t\t\tconst size = getNodeSize(node);\n\t\t\tif (update.width !== undefined) back.width = size.width;\n\t\t\tif (update.height !== undefined) back.height = size.height;\n\t\t}\n\t\tinverse.push(back);\n\t}\n\treturn inverse;\n}\n","import { boundsOf } from './layout.js';\nimport { createNodeLookup, getNodeRect, type CanvasNodeUpdate, type NodeRectOptions } from './arrange.js';\nimport type { CanvasNode, Rect, XYPosition } from './types.js';\n\n/**\n * A guide line to render while dragging, in flow coordinates.\n * `edge` and `centre` guides are alignment lines; `spacing` guides mark equal gaps.\n */\nexport interface GuideLine {\n\torientation: 'vertical' | 'horizontal';\n\tkind: 'edge' | 'centre' | 'spacing';\n\tx1: number;\n\ty1: number;\n\tx2: number;\n\ty2: number;\n}\n\nexport interface SnapGuidesOptions {\n\t/** Current viewport zoom; the threshold is in screen pixels and divided by it (default 1). */\n\tzoom?: number;\n\t/** Snap distance in screen pixels (default 6). */\n\tthreshold?: number;\n\t/** Snap edges to other shapes' edges (default `true`). */\n\tedges?: boolean;\n\t/** Snap centres to other shapes' centres (default `true`). */\n\tcentres?: boolean;\n\t/** Snap to equal spacing between neighbouring shapes in the same row / column (default `true`). */\n\tspacing?: boolean;\n}\n\nexport interface SnapResult {\n\t/** Snapped top-left of the moving rectangle. */\n\tposition: XYPosition;\n\t/** Offset applied to the input rectangle (`position - rect`). */\n\toffset: XYPosition;\n\t/** Guide segments to draw for the snap that was applied. */\n\tguides: GuideLine[];\n\tsnappedX: boolean;\n\tsnappedY: boolean;\n}\n\ninterface AxisEntries {\n\tvalues: Float64Array;\n\trects: Rect[];\n}\n\nfunction buildAxis(entries: { value: number; rect: Rect }[]): AxisEntries {\n\tentries.sort((a, b) => a.value - b.value);\n\treturn {\n\t\tvalues: Float64Array.from(entries.map((e) => e.value)),\n\t\trects: entries.map((e) => e.rect)\n\t};\n}\n\n/** First index whose value is >= `v`. */\nfunction lowerBound(values: Float64Array, v: number): number {\n\tlet lo = 0;\n\tlet hi = values.length;\n\twhile (lo < hi) {\n\t\tconst mid = (lo + hi) >>> 1;\n\t\tif (values[mid] < v) lo = mid + 1;\n\t\telse hi = mid;\n\t}\n\treturn lo;\n}\n\n/**\n * Pre-sorted snap targets for a set of static rectangles. Build it once when a drag starts\n * and reuse it on every pointer move; each query is a binary search, so snapping stays\n * cheap with hundreds or thousands of shapes.\n */\nexport interface GuideIndex {\n\trects: Rect[];\n\tedgeX: AxisEntries;\n\tcentreX: AxisEntries;\n\tedgeY: AxisEntries;\n\tcentreY: AxisEntries;\n}\n\n/** Builds a `GuideIndex` from the rectangles the moving shape may snap to. */\nexport function createGuideIndex(rects: Rect[]): GuideIndex {\n\tconst edgeX: { value: number; rect: Rect }[] = [];\n\tconst centreX: { value: number; rect: Rect }[] = [];\n\tconst edgeY: { value: number; rect: Rect }[] = [];\n\tconst centreY: { value: number; rect: Rect }[] = [];\n\tfor (const rect of rects) {\n\t\tedgeX.push({ value: rect.x, rect }, { value: rect.x + rect.width, rect });\n\t\tcentreX.push({ value: rect.x + rect.width / 2, rect });\n\t\tedgeY.push({ value: rect.y, rect }, { value: rect.y + rect.height, rect });\n\t\tcentreY.push({ value: rect.y + rect.height / 2, rect });\n\t}\n\treturn {\n\t\trects,\n\t\tedgeX: buildAxis(edgeX),\n\t\tcentreX: buildAxis(centreX),\n\t\tedgeY: buildAxis(edgeY),\n\t\tcentreY: buildAxis(centreY)\n\t};\n}\n\n/** Nearest indexed value within `tolerance` of `v`, as a signed delta, or `null`. */\nfunction nearest(axis: AxisEntries, v: number, tolerance: number): number | null {\n\tconst { values } = axis;\n\tlet best: number | null = null;\n\tfor (let i = lowerBound(values, v - tolerance); i < values.length && values[i] <= v + tolerance; i++) {\n\t\tconst delta = values[i] - v;\n\t\tif (best === null || Math.abs(delta) < Math.abs(best)) best = delta;\n\t}\n\treturn best;\n}\n\n/** Rectangles whose indexed value equals `v` (within `eps`). */\nfunction matches(axis: AxisEntries, v: number, eps: number): Rect[] {\n\tconst { values, rects } = axis;\n\tconst out: Rect[] = [];\n\tfor (let i = lowerBound(values, v - eps); i < values.length && values[i] <= v + eps; i++) {\n\t\tout.push(rects[i]);\n\t}\n\treturn out;\n}\n\ninterface SpacingCandidate {\n\tdelta: number;\n\tguides: GuideLine[];\n}\n\n/**\n * Equal-spacing candidates along one axis. Looks at shapes in the same row (horizontal) or\n * column (vertical) as the moving rectangle and proposes: centring between the nearest\n * neighbours, or repeating the gap a neighbour has to its own neighbour.\n */\nfunction spacingCandidate(\n\trects: Rect[],\n\tmoving: Rect,\n\thorizontal: boolean,\n\ttolerance: number\n): SpacingCandidate | null {\n\tconst start = (r: Rect) => (horizontal ? r.x : r.y);\n\tconst end = (r: Rect) => (horizontal ? r.x + r.width : r.y + r.height);\n\tconst crossStart = (r: Rect) => (horizontal ? r.y : r.x);\n\tconst crossEnd = (r: Rect) => (horizontal ? r.y + r.height : r.x + r.width);\n\tconst size = end(moving) - start(moving);\n\tconst inLane = (r: Rect, lane: Rect) => crossStart(r) < crossEnd(lane) && crossEnd(r) > crossStart(lane);\n\n\tconst lane = rects.filter((r) => inLane(r, moving));\n\tif (lane.length === 0) return null;\n\n\tlet before: Rect | null = null;\n\tlet after: Rect | null = null;\n\tfor (const r of lane) {\n\t\tif (end(r) <= start(moving) + tolerance && (!before || end(r) > end(before))) before = r;\n\t\tif (start(r) >= end(moving) - tolerance && (!after || start(r) < start(after))) after = r;\n\t}\n\n\tconst neighbourOf = (r: Rect, forward: boolean): Rect | null => {\n\t\tlet best: Rect | null = null;\n\t\tfor (const other of lane) {\n\t\t\tif (other === r || !inLane(other, r)) continue;\n\t\t\tif (forward ? start(other) >= end(r) : end(other) <= start(r)) {\n\t\t\t\tif (!best || (forward ? start(other) < start(best) : end(other) > end(best))) best = other;\n\t\t\t}\n\t\t}\n\t\treturn best;\n\t};\n\n\tconst crossMid = (a: Rect, b: Rect) =>\n\t\t(Math.max(crossStart(a), crossStart(b)) + Math.min(crossEnd(a), crossEnd(b))) / 2;\n\tconst segment = (from: number, to: number, cross: number): GuideLine =>\n\t\thorizontal\n\t\t\t? { orientation: 'horizontal', kind: 'spacing', x1: from, y1: cross, x2: to, y2: cross }\n\t\t\t: { orientation: 'vertical', kind: 'spacing', x1: cross, y1: from, x2: cross, y2: to };\n\n\tconst candidates: { pos: number; guides: (pos: number) => GuideLine[] }[] = [];\n\tif (before && after) {\n\t\tconst b = before;\n\t\tconst a = after;\n\t\tconst pos = (end(b) + start(a) - size) / 2;\n\t\tif (pos >= end(b)) {\n\t\t\tcandidates.push({\n\t\t\t\tpos,\n\t\t\t\tguides: (p) => [\n\t\t\t\t\tsegment(end(b), p, crossMid(b, moving)),\n\t\t\t\t\tsegment(p + size, start(a), crossMid(a, moving))\n\t\t\t\t]\n\t\t\t});\n\t\t}\n\t}\n\tif (before) {\n\t\tconst b = before;\n\t\tconst prev = neighbourOf(b, false);\n\t\tif (prev) {\n\t\t\tconst gap = start(b) - end(prev);\n\t\t\tcandidates.push({\n\t\t\t\tpos: end(b) + gap,\n\t\t\t\tguides: (p) => [segment(end(prev), start(b), crossMid(prev, b)), segment(end(b), p, crossMid(b, moving))]\n\t\t\t});\n\t\t}\n\t}\n\tif (after) {\n\t\tconst a = after;\n\t\tconst next = neighbourOf(a, true);\n\t\tif (next) {\n\t\t\tconst gap = start(next) - end(a);\n\t\t\tcandidates.push({\n\t\t\t\tpos: start(a) - gap - size,\n\t\t\t\tguides: (p) => [segment(p + size, start(a), crossMid(a, moving)), segment(end(a), start(next), crossMid(a, next))]\n\t\t\t});\n\t\t}\n\t}\n\n\tlet best: SpacingCandidate | null = null;\n\tfor (const c of candidates) {\n\t\tconst delta = c.pos - start(moving);\n\t\tif (Math.abs(delta) <= tolerance && (!best || Math.abs(delta) < Math.abs(best.delta))) {\n\t\t\tbest = { delta, guides: c.guides(c.pos) };\n\t\t}\n\t}\n\treturn best;\n}\n\n/**\n * Computes smart-guide snapping for a moving rectangle (a dragged node or a selection's\n * bounding box) against other shapes. Edges snap to edges and centres to centres within\n * `threshold` screen pixels (converted to flow units via `zoom`). Each axis snaps\n * independently to its nearest candidate. Returns the snapped position and the guides to draw.\n */\nexport function computeSnapGuides(\n\tmoving: Rect,\n\ttargets: Rect[] | GuideIndex,\n\toptions: SnapGuidesOptions = {}\n): SnapResult {\n\tconst index = Array.isArray(targets) ? createGuideIndex(targets) : targets;\n\tconst zoom = options.zoom && options.zoom > 0 ? options.zoom : 1;\n\tconst tolerance = (options.threshold ?? 6) / zoom;\n\tconst useEdges = options.edges !== false;\n\tconst useCentres = options.centres !== false;\n\tconst useSpacing = options.spacing !== false;\n\tconst eps = 0.5 / zoom;\n\n\tconst snapAxis = (horizontal: boolean) => {\n\t\tconst start = horizontal ? moving.x : moving.y;\n\t\tconst size = horizontal ? moving.width : moving.height;\n\t\tconst edgeAxis = horizontal ? index.edgeX : index.edgeY;\n\t\tconst centreAxis = horizontal ? index.centreX : index.centreY;\n\t\tlet delta: number | null = null;\n\t\tconst consider = (d: number | null) => {\n\t\t\tif (d !== null && (delta === null || Math.abs(d) < Math.abs(delta))) delta = d;\n\t\t};\n\t\tif (useEdges) {\n\t\t\tconsider(nearest(edgeAxis, start, tolerance));\n\t\t\tconsider(nearest(edgeAxis, start + size, tolerance));\n\t\t}\n\t\tif (useCentres) consider(nearest(centreAxis, start + size / 2, tolerance));\n\t\tconst spacing = useSpacing ? spacingCandidate(index.rects, moving, horizontal, tolerance) : null;\n\t\tif (spacing && (delta === null || Math.abs(spacing.delta) < Math.abs(delta) - eps)) {\n\t\t\treturn { delta: spacing.delta, spacing };\n\t\t}\n\t\treturn { delta: delta as number | null, spacing: null };\n\t};\n\n\tconst sx = snapAxis(true);\n\tconst sy = snapAxis(false);\n\tconst dx = sx.delta ?? 0;\n\tconst dy = sy.delta ?? 0;\n\tconst snapped: Rect = { x: moving.x + dx, y: moving.y + dy, width: moving.width, height: moving.height };\n\tconst guides: GuideLine[] = [];\n\n\tconst alignmentGuides = (horizontal: boolean) => {\n\t\tconst start = horizontal ? snapped.x : snapped.y;\n\t\tconst size = horizontal ? snapped.width : snapped.height;\n\t\tconst lines: { value: number; kind: 'edge' | 'centre'; axis: AxisEntries }[] = [];\n\t\tif (useEdges) {\n\t\t\tconst axis = horizontal ? index.edgeX : index.edgeY;\n\t\t\tlines.push({ value: start, kind: 'edge', axis }, { value: start + size, kind: 'edge', axis });\n\t\t}\n\t\tif (useCentres) {\n\t\t\tlines.push({ value: start + size / 2, kind: 'centre', axis: horizontal ? index.centreX : index.centreY });\n\t\t}\n\t\tfor (const line of lines) {\n\t\t\tconst aligned = matches(line.axis, line.value, eps);\n\t\t\tif (aligned.length === 0) continue;\n\t\t\tconst span = boundsOf([snapped, ...aligned])!;\n\t\t\tguides.push(\n\t\t\t\thorizontal\n\t\t\t\t\t? { orientation: 'vertical', kind: line.kind, x1: line.value, y1: span.y, x2: line.value, y2: span.y + span.height }\n\t\t\t\t\t: { orientation: 'horizontal', kind: line.kind, x1: span.x, y1: line.value, x2: span.x + span.width, y2: line.value }\n\t\t\t);\n\t\t}\n\t};\n\n\tif (sx.delta !== null) {\n\t\tif (sx.spacing) guides.push(...shiftGuides(sx.spacing.guides, 0, dy));\n\t\telse alignmentGuides(true);\n\t}\n\tif (sy.delta !== null) {\n\t\tif (sy.spacing) guides.push(...shiftGuides(sy.spacing.guides, dx, 0));\n\t\telse alignmentGuides(false);\n\t}\n\n\treturn {\n\t\tposition: { x: snapped.x, y: snapped.y },\n\t\toffset: { x: dx, y: dy },\n\t\tguides,\n\t\tsnappedX: sx.delta !== null,\n\t\tsnappedY: sy.delta !== null\n\t};\n}\n\n/** Spacing guides are computed before the other axis snaps; shift their cross coordinate to match. */\nfunction shiftGuides(guides: GuideLine[], dx: number, dy: number): GuideLine[] {\n\treturn guides.map((g) =>\n\t\tg.orientation === 'horizontal'\n\t\t\t? { ...g, y1: g.y1 + dy, y2: g.y2 + dy }\n\t\t\t: { ...g, x1: g.x1 + dx, x2: g.x2 + dx }\n\t);\n}\n\n/** Ids of the given nodes plus every descendant (children move with their parent). */\nexport function collectDescendantIds(nodes: CanvasNode[], ids: Iterable<string>): Set<string> {\n\tconst result = new Set(ids);\n\tlet grew = true;\n\twhile (grew) {\n\t\tgrew = false;\n\t\tfor (const node of nodes) {\n\t\t\tif (node.parentId && result.has(node.parentId) && !result.has(node.id)) {\n\t\t\t\tresult.add(node.id);\n\t\t\t\tgrew = true;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n}\n\n/**\n * Builds a `GuideIndex` of every node except the dragged ones and their descendants.\n * Call once at drag start and pass it to `snapNodeDrag` on every move.\n */\nexport function createNodeGuideIndex(\n\tnodes: CanvasNode[],\n\tdraggingIds: Iterable<string>,\n\toptions: NodeRectOptions & { filter?: (node: CanvasNode) => boolean } = {}\n): GuideIndex {\n\tconst exclude = collectDescendantIds(nodes, draggingIds);\n\tconst lookup = createNodeLookup(nodes);\n\tconst rects: Rect[] = [];\n\tfor (const node of nodes) {\n\t\tif (exclude.has(node.id) || node.hidden === true) continue;\n\t\tif (options.filter && !options.filter(node)) continue;\n\t\trects.push(getNodeRect(node, lookup, options));\n\t}\n\treturn createGuideIndex(rects);\n}\n\nexport interface SnapNodeDragOptions extends SnapGuidesOptions, NodeRectOptions {\n\t/** Index from `createNodeGuideIndex`, reused across drag frames. Built on demand when omitted. */\n\tindex?: GuideIndex;\n}\n\nexport interface SnapNodeDragResult extends SnapResult {\n\t/** Position updates moving every dragged node by `offset` (node-relative coordinates). */\n\tupdates: CanvasNodeUpdate[];\n}\n\n/**\n * Snaps a drag of one or more nodes. The dragged nodes' bounding box is snapped against all\n * other nodes; the resulting offset is applied to each dragged node. Dragged nodes whose\n * parent is also dragged are skipped, because they move with the parent.\n */\nexport function snapNodeDrag(\n\tnodes: CanvasNode[],\n\tdraggingIds: Iterable<string>,\n\toptions: SnapNodeDragOptions = {}\n): SnapNodeDragResult {\n\tconst ids = new Set(draggingIds);\n\tconst lookup = createNodeLookup(nodes);\n\tconst dragged = [...ids].map((id) => lookup.get(id)).filter((n): n is CanvasNode => !!n);\n\tconst empty: SnapNodeDragResult = {\n\t\tposition: { x: 0, y: 0 },\n\t\toffset: { x: 0, y: 0 },\n\t\tguides: [],\n\t\tsnappedX: false,\n\t\tsnappedY: false,\n\t\tupdates: []\n\t};\n\tif (dragged.length === 0) return empty;\n\n\tconst bounds = boundsOf(dragged.map((n) => getNodeRect(n, lookup, options)))!;\n\tconst index = options.index ?? createNodeGuideIndex(nodes, ids, options);\n\tconst result = computeSnapGuides(bounds, index, options);\n\tconst { x: dx, y: dy } = result.offset;\n\tconst updates: CanvasNodeUpdate[] = [];\n\tif (dx !== 0 || dy !== 0) {\n\t\tfor (const node of dragged) {\n\t\t\tif (node.parentId && ids.has(node.parentId)) continue;\n\t\t\tupdates.push({ id: node.id, position: { x: node.position.x + dx, y: node.position.y + dy } });\n\t\t}\n\t}\n\treturn { ...result, updates };\n}\n","import { centre } from './layout.js';\nimport type { Position, Rect, Side, XYPosition } from './types.js';\n\n/**\n * Connection line styles supported by both SvelteFlow and React Flow\n * (`connectionLineType` / edge `type`).\n */\nexport type CanvasConnectionLineType = 'default' | 'straight' | 'step' | 'smoothstep' | 'simplebezier';\n\nexport const CONNECTION_LINE_TYPES: readonly CanvasConnectionLineType[] = [\n\t'default',\n\t'straight',\n\t'step',\n\t'smoothstep',\n\t'simplebezier'\n];\n\n/** Maps a handle `Position` to the placement `Side` vocabulary used by `placeBeside`. */\nexport function positionToSide(position: Position): Side {\n\tswitch (position) {\n\t\tcase 'top':\n\t\t\treturn 'above';\n\t\tcase 'bottom':\n\t\t\treturn 'below';\n\t\tdefault:\n\t\t\treturn position;\n\t}\n}\n\n/** Maps a placement `Side` to the handle `Position` vocabulary used by xyflow. */\nexport function sideToPosition(side: Side): Position {\n\tswitch (side) {\n\t\tcase 'above':\n\t\t\treturn 'top';\n\t\tcase 'below':\n\t\t\treturn 'bottom';\n\t\tdefault:\n\t\t\treturn side;\n\t}\n}\n\n/** The handle position facing the other way. */\nexport function oppositePosition(position: Position): Position {\n\tswitch (position) {\n\t\tcase 'top':\n\t\t\treturn 'bottom';\n\t\tcase 'bottom':\n\t\t\treturn 'top';\n\t\tcase 'left':\n\t\t\treturn 'right';\n\t\tdefault:\n\t\t\treturn 'left';\n\t}\n}\n\n/** Midpoint of a rectangle's side, where a centred handle sits. */\nexport function handlePoint(rect: Rect, position: Position): XYPosition {\n\tswitch (position) {\n\t\tcase 'top':\n\t\t\treturn { x: rect.x + rect.width / 2, y: rect.y };\n\t\tcase 'bottom':\n\t\t\treturn { x: rect.x + rect.width / 2, y: rect.y + rect.height };\n\t\tcase 'left':\n\t\t\treturn { x: rect.x, y: rect.y + rect.height / 2 };\n\t\tdefault:\n\t\t\treturn { x: rect.x + rect.width, y: rect.y + rect.height / 2 };\n\t}\n}\n\nexport interface ConnectorSnapTarget {\n\tid: string;\n\trect: Rect;\n\t/** Sides that can accept a connection (default: all four). */\n\tpositions?: Position[];\n}\n\nexport interface ConnectorSnapOptions {\n\t/** Viewport zoom; `radius` is in screen pixels and divided by it (default 1). */\n\tzoom?: number;\n\t/** How far outside a shape the pointer may be and still attach, in screen pixels (default 24). */\n\tradius?: number;\n\t/** Node ids that cannot be attached to, e.g. the connection's source node. */\n\texcludeIds?: Iterable<string>;\n\t/**\n\t * `handle` snaps to the side's midpoint (a centred handle, default). `edge` snaps to the\n\t * closest point along that side, for floating edges.\n\t */\n\tmode?: 'handle' | 'edge';\n}\n\nexport interface ConnectorSnap {\n\tnodeId: string;\n\tposition: Position;\n\tside: Side;\n\t/** Attachment point in flow coordinates. */\n\tpoint: XYPosition;\n\t/** Distance from the pointer to `point`, in flow units. */\n\tdistance: number;\n}\n\n/**\n * Finds the shape side a connection line should attach to for a pointer (flow coordinates).\n * Shapes the pointer is inside win over shapes it is merely near; among those, the closest\n * allowed side wins. Returns `null` when nothing is within `radius`.\n */\nexport function findConnectorSnap(\n\tpointer: XYPosition,\n\ttargets: ConnectorSnapTarget[],\n\toptions: ConnectorSnapOptions = {}\n): ConnectorSnap | null {\n\tconst zoom = options.zoom && options.zoom > 0 ? options.zoom : 1;\n\tconst radius = (options.radius ?? 24) / zoom;\n\tconst exclude = new Set(options.excludeIds ?? []);\n\tconst all: Position[] = ['top', 'right', 'bottom', 'left'];\n\n\tlet best: (ConnectorSnap & { inside: boolean; rank: number }) | null = null;\n\tfor (const target of targets) {\n\t\tif (exclude.has(target.id)) continue;\n\t\tconst { rect } = target;\n\t\t// Cheap rejection: pointer outside the rect grown by the radius.\n\t\tif (\n\t\t\tpointer.x < rect.x - radius ||\n\t\t\tpointer.x > rect.x + rect.width + radius ||\n\t\t\tpointer.y < rect.y - radius ||\n\t\t\tpointer.y > rect.y + rect.height + radius\n\t\t) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst inside =\n\t\t\tpointer.x >= rect.x &&\n\t\t\tpointer.x <= rect.x + rect.width &&\n\t\t\tpointer.y >= rect.y &&\n\t\t\tpointer.y <= rect.y + rect.height;\n\n\t\tfor (const position of target.positions ?? all) {\n\t\t\tconst point =\n\t\t\t\toptions.mode === 'edge' ? closestPointOnSide(rect, position, pointer) : handlePoint(rect, position);\n\t\t\t// Rank sides by distance from the pointer to the side line, so a pointer near the\n\t\t\t// middle of a wide shape attaches to the side it is closest to.\n\t\t\tconst sidePoint = closestPointOnSide(rect, position, pointer);\n\t\t\tconst rank = Math.hypot(pointer.x - sidePoint.x, pointer.y - sidePoint.y);\n\t\t\tconst distance = Math.hypot(pointer.x - point.x, pointer.y - point.y);\n\t\t\tif (!inside && rank > radius) continue;\n\t\t\tconst better =\n\t\t\t\t!best ||\n\t\t\t\t(inside && !best.inside) ||\n\t\t\t\t(inside === best.inside && rank < best.rank);\n\t\t\tif (better) {\n\t\t\t\tbest = { nodeId: target.id, position, side: positionToSide(position), point, distance, inside, rank };\n\t\t\t}\n\t\t}\n\t}\n\tif (!best) return null;\n\tconst { inside: _inside, rank: _rank, ...snap } = best;\n\treturn snap;\n}\n\nfunction closestPointOnSide(rect: Rect, position: Position, p: XYPosition): XYPosition {\n\tconst clampX = Math.min(rect.x + rect.width, Math.max(rect.x, p.x));\n\tconst clampY = Math.min(rect.y + rect.height, Math.max(rect.y, p.y));\n\tswitch (position) {\n\t\tcase 'top':\n\t\t\treturn { x: clampX, y: rect.y };\n\t\tcase 'bottom':\n\t\t\treturn { x: clampX, y: rect.y + rect.height };\n\t\tcase 'left':\n\t\t\treturn { x: rect.x, y: clampY };\n\t\tdefault:\n\t\t\treturn { x: rect.x + rect.width, y: clampY };\n\t}\n}\n\n/**\n * Picks the facing sides for a connection between two shapes, the way Freeform attaches\n * connection lines: along the axis with the larger centre offset.\n */\nexport function nearestHandlePositions(\n\tsource: Rect,\n\ttarget: Rect\n): { source: Position; target: Position } {\n\tconst a = centre(source);\n\tconst b = centre(target);\n\tconst dx = b.x - a.x;\n\tconst dy = b.y - a.y;\n\tif (Math.abs(dx) >= Math.abs(dy)) {\n\t\treturn dx >= 0 ? { source: 'right', target: 'left' } : { source: 'left', target: 'right' };\n\t}\n\treturn dy >= 0 ? { source: 'bottom', target: 'top' } : { source: 'top', target: 'bottom' };\n}\n","import { boundsOf } from './layout.js';\nimport { createNodeLookup, getNodeRect, type NodeRectOptions } from './arrange.js';\nimport type { CanvasNode, Rect } from './types.js';\n\n/**\n * Viewport transform in xyflow's convention: `screen = flow * zoom + (x, y)`.\n */\nexport interface CanvasViewport {\n\tx: number;\n\ty: number;\n\tzoom: number;\n}\n\n/**\n * A named, saved view of the canvas (Freeform \"Scenes\").\n */\nexport interface CanvasScene {\n\tid: string;\n\tname: string;\n\tviewport: CanvasViewport;\n\t/** Optional nodes the scene is about, e.g. to re-fit the scene after they move. */\n\tnodeIds?: string[];\n}\n\nexport interface CanvasScenesState {\n\tscenes: readonly CanvasScene[];\n\t/** Id of the scene last shown, or `null`. */\n\tcurrentId: string | null;\n\t/** Index of the current scene, or `-1`. */\n\tcurrentIndex: number;\n}\n\nexport interface CanvasScenesOptions {\n\tinitialScenes?: CanvasScene[];\n\t/** Id generator for new scenes (default: `crypto.randomUUID` with a counter fallback). */\n\tcreateId?: () => string;\n\t/** Whether `next` / `previous` wrap around at the ends (default `false`). */\n\twrap?: boolean;\n\tonChange?: (state: CanvasScenesState) => void;\n}\n\nexport interface SerializedCanvasScenes {\n\tversion: 1;\n\tscenes: CanvasScene[];\n}\n\nlet fallbackCounter = 0;\nfunction defaultId(): string {\n\tif (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n\t\treturn crypto.randomUUID();\n\t}\n\tfallbackCounter += 1;\n\treturn `scene-${Date.now().toString(36)}-${fallbackCounter}`;\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n\treturn typeof value === 'number' && Number.isFinite(value);\n}\n\n/** Validates the shape of a scene. */\nexport function isValidCanvasScene(value: unknown): value is CanvasScene {\n\tif (typeof value !== 'object' || value === null) return false;\n\tconst scene = value as Record<string, any>;\n\tconst vp = scene.viewport;\n\treturn (\n\t\ttypeof scene.id === 'string' &&\n\t\ttypeof scene.name === 'string' &&\n\t\ttypeof vp === 'object' &&\n\t\tvp !== null &&\n\t\tisFiniteNumber(vp.x) &&\n\t\tisFiniteNumber(vp.y) &&\n\t\tisFiniteNumber(vp.zoom) &&\n\t\tvp.zoom > 0 &&\n\t\t(scene.nodeIds === undefined ||\n\t\t\t(Array.isArray(scene.nodeIds) && scene.nodeIds.every((id: unknown) => typeof id === 'string')))\n\t);\n}\n\nfunction cloneScene(scene: CanvasScene): CanvasScene {\n\tconst copy: CanvasScene = {\n\t\tid: scene.id,\n\t\tname: scene.name,\n\t\tviewport: { x: scene.viewport.x, y: scene.viewport.y, zoom: scene.viewport.zoom }\n\t};\n\tif (scene.nodeIds) copy.nodeIds = [...scene.nodeIds];\n\treturn copy;\n}\n\n/**\n * Parses serialized scenes (a JSON string, a `{ version, scenes }` object or a bare array).\n * Invalid entries and duplicate ids are dropped.\n */\nexport function parseCanvasScenes(input: string | unknown): CanvasScene[] {\n\tlet value: unknown = input;\n\tif (typeof input === 'string') {\n\t\ttry {\n\t\t\tvalue = JSON.parse(input);\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}\n\tconst list = Array.isArray(value)\n\t\t? value\n\t\t: typeof value === 'object' && value !== null && Array.isArray((value as any).scenes)\n\t\t\t? (value as any).scenes\n\t\t\t: [];\n\tconst seen = new Set<string>();\n\tconst scenes: CanvasScene[] = [];\n\tfor (const entry of list) {\n\t\tif (!isValidCanvasScene(entry) || seen.has(entry.id)) continue;\n\t\tseen.add(entry.id);\n\t\tscenes.push(cloneScene(entry));\n\t}\n\treturn scenes;\n}\n\n/**\n * Headless, framework-agnostic store of named viewports. Snapshots returned by `getState()`\n * are cached and only replaced on change, so it can back React's `useSyncExternalStore`.\n */\nexport class CanvasScenesStore {\n\tprivate scenes: CanvasScene[];\n\tprivate currentId: string | null = null;\n\tprivate cached: CanvasScenesState;\n\tprivate listeners = new Set<(state: CanvasScenesState) => void>();\n\tprivate readonly createId: () => string;\n\tprivate readonly onChange?: (state: CanvasScenesState) => void;\n\twrap: boolean;\n\n\tconstructor(options: CanvasScenesOptions = {}) {\n\t\tthis.scenes = parseCanvasScenes(options.initialScenes ?? []);\n\t\tthis.createId = options.createId ?? defaultId;\n\t\tthis.wrap = options.wrap ?? false;\n\t\tthis.onChange = options.onChange;\n\t\tthis.cached = this.snapshot();\n\t}\n\n\tprivate snapshot(): CanvasScenesState {\n\t\tconst currentIndex = this.currentId ? this.scenes.findIndex((s) => s.id === this.currentId) : -1;\n\t\treturn {\n\t\t\tscenes: this.scenes,\n\t\t\tcurrentId: currentIndex === -1 ? null : this.currentId,\n\t\t\tcurrentIndex\n\t\t};\n\t}\n\n\tprivate commit(scenes: CanvasScene[] = this.scenes) {\n\t\tthis.scenes = scenes;\n\t\tif (this.currentId && !scenes.some((s) => s.id === this.currentId)) this.currentId = null;\n\t\tthis.cached = this.snapshot();\n\t\tthis.onChange?.(this.cached);\n\t\tfor (const listener of this.listeners) listener(this.cached);\n\t}\n\n\tgetState(): CanvasScenesState {\n\t\treturn this.cached;\n\t}\n\n\tgetScene(id: string): CanvasScene | undefined {\n\t\treturn this.scenes.find((s) => s.id === id);\n\t}\n\n\tsubscribe(listener: (state: CanvasScenesState) => void): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\t/** First unused \"Scene N\" name. */\n\tnextDefaultName(): string {\n\t\tconst names = new Set(this.scenes.map((s) => s.name));\n\t\tlet n = this.scenes.length + 1;\n\t\twhile (names.has(`Scene ${n}`)) n += 1;\n\t\treturn `Scene ${n}`;\n\t}\n\n\t/**\n\t * Adds a scene (appended, or inserted at `index`) and makes it current.\n\t */\n\tadd(input: { viewport: CanvasViewport; name?: string; nodeIds?: string[]; id?: string }, index?: number): CanvasScene {\n\t\tconst scene = cloneScene({\n\t\t\tid: input.id && !this.getScene(input.id) ? input.id : this.createId(),\n\t\t\tname: input.name?.trim() || this.nextDefaultName(),\n\t\t\tviewport: input.viewport,\n\t\t\tnodeIds: input.nodeIds\n\t\t});\n\t\tif (!isValidCanvasScene(scene)) throw new Error('[CanvasScenesStore] Invalid scene viewport.');\n\t\tconst scenes = [...this.scenes];\n\t\tconst at = index === undefined ? scenes.length : Math.max(0, Math.min(scenes.length, index));\n\t\tscenes.splice(at, 0, scene);\n\t\tthis.currentId = scene.id;\n\t\tthis.commit(scenes);\n\t\treturn scene;\n\t}\n\n\t/** Patches a scene's name, viewport or node ids. Returns the updated scene. */\n\tupdate(id: string, patch: Partial<Omit<CanvasScene, 'id'>>): CanvasScene | undefined {\n\t\tconst index = this.scenes.findIndex((s) => s.id === id);\n\t\tif (index === -1) return undefined;\n\t\tconst current = this.scenes[index];\n\t\tconst next = cloneScene({\n\t\t\t...current,\n\t\t\t...patch,\n\t\t\tname: patch.name !== undefined ? patch.name.trim() || current.name : current.name,\n\t\t\tviewport: patch.viewport ?? current.viewport,\n\t\t\tid\n\t\t});\n\t\tif (!isValidCanvasScene(next)) throw new Error('[CanvasScenesStore] Invalid scene viewport.');\n\t\tconst scenes = [...this.scenes];\n\t\tscenes[index] = next;\n\t\tthis.commit(scenes);\n\t\treturn next;\n\t}\n\n\trename(id: string, name: string): CanvasScene | undefined {\n\t\treturn this.update(id, { name });\n\t}\n\n\t/** Moves a scene to `toIndex` (clamped). */\n\tmove(id: string, toIndex: number): void {\n\t\tconst from = this.scenes.findIndex((s) => s.id === id);\n\t\tif (from === -1) return;\n\t\tconst to = Math.max(0, Math.min(this.scenes.length - 1, Math.trunc(toIndex)));\n\t\tif (from === to) return;\n\t\tconst scenes = [...this.scenes];\n\t\tconst [scene] = scenes.splice(from, 1);\n\t\tscenes.splice(to, 0, scene);\n\t\tthis.commit(scenes);\n\t}\n\n\t/** Reorders scenes to match `ids`; unknown ids are ignored and missing scenes keep their relative order at the end. */\n\treorder(ids: string[]): void {\n\t\tconst byId = new Map(this.scenes.map((s) => [s.id, s]));\n\t\tconst ordered: CanvasScene[] = [];\n\t\tfor (const id of ids) {\n\t\t\tconst scene = byId.get(id);\n\t\t\tif (scene) {\n\t\t\t\tordered.push(scene);\n\t\t\t\tbyId.delete(id);\n\t\t\t}\n\t\t}\n\t\tthis.commit([...ordered, ...this.scenes.filter((s) => byId.has(s.id))]);\n\t}\n\n\tremove(id: string): void {\n\t\tif (!this.getScene(id)) return;\n\t\tthis.commit(this.scenes.filter((s) => s.id !== id));\n\t}\n\n\tclear(): void {\n\t\tthis.currentId = null;\n\t\tthis.commit([]);\n\t}\n\n\t/** Marks a scene as current and returns it. */\n\tgoTo(id: string): CanvasScene | undefined {\n\t\tconst scene = this.getScene(id);\n\t\tif (!scene) return undefined;\n\t\tif (this.currentId !== id) {\n\t\t\tthis.currentId = id;\n\t\t\tthis.commit();\n\t\t}\n\t\treturn scene;\n\t}\n\n\tprivate step(direction: 1 | -1): CanvasScene | undefined {\n\t\tconst count = this.scenes.length;\n\t\tif (count === 0) return undefined;\n\t\tconst index = this.cached.currentIndex;\n\t\tlet next: number;\n\t\tif (index === -1) next = direction === 1 ? 0 : count - 1;\n\t\telse next = index + direction;\n\t\tif (next < 0 || next >= count) {\n\t\t\tif (!this.wrap) return undefined;\n\t\t\tnext = (next + count) % count;\n\t\t}\n\t\treturn this.goTo(this.scenes[next].id);\n\t}\n\n\t/** Shows the next scene. Returns `undefined` at the end unless `wrap` is on. */\n\tnext(): CanvasScene | undefined {\n\t\treturn this.step(1);\n\t}\n\n\t/** Shows the previous scene. Returns `undefined` at the start unless `wrap` is on. */\n\tprevious(): CanvasScene | undefined {\n\t\treturn this.step(-1);\n\t}\n\n\ttoJSON(): SerializedCanvasScenes {\n\t\treturn { version: 1, scenes: this.scenes.map(cloneScene) };\n\t}\n\n\tserialize(): string {\n\t\treturn JSON.stringify(this.toJSON());\n\t}\n\n\t/** Replaces all scenes from serialized data (see `parseCanvasScenes`). */\n\tload(input: string | unknown): void {\n\t\tthis.currentId = null;\n\t\tthis.commit(parseCanvasScenes(input));\n\t}\n}\n\nexport function createCanvasScenesStore(options?: CanvasScenesOptions): CanvasScenesStore {\n\treturn new CanvasScenesStore(options);\n}\n\nexport interface FitViewportOptions {\n\t/** Padding around the content as a fraction of the content size per side (default 0.1, like xyflow). */\n\tpadding?: number;\n\tminZoom?: number;\n\tmaxZoom?: number;\n}\n\n/**\n * Viewport that fits `rect` into a container of `size`, centred (xyflow `fitView` maths).\n */\nexport function fitViewportToRect(\n\trect: Rect,\n\tsize: { width: number; height: number },\n\toptions: FitViewportOptions = {}\n): CanvasViewport {\n\tconst { padding = 0.1, minZoom = 0.1, maxZoom = 2 } = options;\n\tconst paddedWidth = Math.max(rect.width * (1 + padding * 2), 1);\n\tconst paddedHeight = Math.max(rect.height * (1 + padding * 2), 1);\n\tconst raw = Math.min(size.width / paddedWidth, size.height / paddedHeight);\n\tconst zoom = Math.min(maxZoom, Math.max(minZoom, raw));\n\tconst cx = rect.x + rect.width / 2;\n\tconst cy = rect.y + rect.height / 2;\n\treturn { x: size.width / 2 - cx * zoom, y: size.height / 2 - cy * zoom, zoom };\n}\n\n/**\n * Viewport that fits the given nodes (all nodes when `ids` is omitted), or `null` when none match.\n */\nexport function fitViewportToNodes(\n\tnodes: CanvasNode[],\n\tsize: { width: number; height: number },\n\tids?: Iterable<string>,\n\toptions: FitViewportOptions & NodeRectOptions = {}\n): CanvasViewport | null {\n\tconst lookup = createNodeLookup(nodes);\n\tconst wanted = ids ? new Set(ids) : null;\n\tconst rects = nodes\n\t\t.filter((n) => (wanted ? wanted.has(n.id) : true))\n\t\t.map((n) => getNodeRect(n, lookup, options));\n\tconst bounds = boundsOf(rects);\n\treturn bounds ? fitViewportToRect(bounds, size, options) : null;\n}\n","import { isEventFromTextInput } from './clipboard.js';\n\n/**\n * Canvas arrangement actions that have keyboard shortcuts.\n */\nexport type CanvasArrangeAction =\n\t| 'alignLeft'\n\t| 'alignCenter'\n\t| 'alignRight'\n\t| 'alignTop'\n\t| 'alignMiddle'\n\t| 'alignBottom'\n\t| 'distributeHorizontal'\n\t| 'distributeVertical'\n\t| 'lock'\n\t| 'unlock'\n\t| 'bringForward'\n\t| 'sendBackward'\n\t| 'bringToFront'\n\t| 'sendToBack'\n\t| 'nextScene'\n\t| 'previousScene';\n\nexport interface ArrangeShortcutBinding {\n\taction: CanvasArrangeAction;\n\t/** `KeyboardEvent.code` (layout- and Option-independent, e.g. `KeyA`, `BracketRight`). */\n\tcode: string;\n\tmod?: boolean;\n\talt?: boolean;\n\tshift?: boolean;\n\t/** Human readable label, e.g. for menus. `Mod` is ⌘ on macOS and Ctrl elsewhere. */\n\tlabel: string;\n}\n\n/**\n * Default bindings. Align/distribute follow Figma (Option/Alt + letter), layer order follows\n * the common `Mod+]` / `Mod+[` convention, lock follows Keynote/Freeform (`Mod+L`,\n * `Mod+Alt+L` to unlock) and scenes step with PageDown / PageUp.\n */\nexport const DEFAULT_ARRANGE_SHORTCUTS: readonly ArrangeShortcutBinding[] = [\n\t{ action: 'alignLeft', code: 'KeyA', alt: true, label: 'Alt+A' },\n\t{ action: 'alignCenter', code: 'KeyH', alt: true, label: 'Alt+H' },\n\t{ action: 'alignRight', code: 'KeyD', alt: true, label: 'Alt+D' },\n\t{ action: 'alignTop', code: 'KeyW', alt: true, label: 'Alt+W' },\n\t{ action: 'alignMiddle', code: 'KeyV', alt: true, label: 'Alt+V' },\n\t{ action: 'alignBottom', code: 'KeyS', alt: true, label: 'Alt+S' },\n\t{ action: 'distributeHorizontal', code: 'KeyH', alt: true, shift: true, label: 'Alt+Shift+H' },\n\t{ action: 'distributeVertical', code: 'KeyV', alt: true, shift: true, label: 'Alt+Shift+V' },\n\t{ action: 'lock', code: 'KeyL', mod: true, label: 'Mod+L' },\n\t{ action: 'unlock', code: 'KeyL', mod: true, alt: true, label: 'Mod+Alt+L' },\n\t{ action: 'bringForward', code: 'BracketRight', mod: true, label: 'Mod+]' },\n\t{ action: 'sendBackward', code: 'BracketLeft', mod: true, label: 'Mod+[' },\n\t{ action: 'bringToFront', code: 'BracketRight', mod: true, alt: true, label: 'Mod+Alt+]' },\n\t{ action: 'sendToBack', code: 'BracketLeft', mod: true, alt: true, label: 'Mod+Alt+[' },\n\t{ action: 'nextScene', code: 'PageDown', label: 'PageDown' },\n\t{ action: 'previousScene', code: 'PageUp', label: 'PageUp' }\n];\n\nconst KEY_TO_CODE: Record<string, string> = {\n\t']': 'BracketRight',\n\t'[': 'BracketLeft',\n\tPageDown: 'PageDown',\n\tPageUp: 'PageUp'\n};\n\nfunction eventCode(event: KeyboardEvent): string {\n\tif (event.code) return event.code;\n\t// Synthetic events (and some test environments) omit `code`; derive it from `key`.\n\tif (KEY_TO_CODE[event.key]) return KEY_TO_CODE[event.key];\n\tif (/^[a-z]$/i.test(event.key)) return `Key${event.key.toUpperCase()}`;\n\treturn event.key;\n}\n\n/**\n * Resolves a keydown event to an arrange action, or `null`. Events from text inputs,\n * textareas, selects, contenteditable and ProseMirror are ignored (see `isEventFromTextInput`).\n * `Mod` is ⌘ or Ctrl.\n */\nexport function matchArrangeShortcut(\n\tevent: KeyboardEvent,\n\tbindings: readonly ArrangeShortcutBinding[] = DEFAULT_ARRANGE_SHORTCUTS\n): CanvasArrangeAction | null {\n\tif (isEventFromTextInput(event)) return null;\n\tconst code = eventCode(event);\n\tconst mod = event.metaKey || event.ctrlKey;\n\tfor (const binding of bindings) {\n\t\tif (\n\t\t\tbinding.code === code &&\n\t\t\t!!binding.mod === mod &&\n\t\t\t!!binding.alt === event.altKey &&\n\t\t\t!!binding.shift === event.shiftKey\n\t\t) {\n\t\t\treturn binding.action;\n\t\t}\n\t}\n\treturn null;\n}\n","import type { Command } from '../history/types.js';\nimport {\n\talignNodes,\n\tapplyNodeUpdates,\n\tdistributeNodes,\n\tinvertNodeUpdates,\n\tisLocked,\n\tlockNodes,\n\tmatchSize,\n\treorderNodes,\n\tunlockNodes,\n\ttype AlignEdge,\n\ttype AlignNodesOptions,\n\ttype CanvasNodeUpdate,\n\ttype DistributeAxis,\n\ttype DistributeMode,\n\ttype DistributeNodesOptions,\n\ttype MatchSizeOptions,\n\ttype NodeRectOptions,\n\ttype SizeDimension,\n\ttype ZOrderOperation\n} from './arrange.js';\nimport type { CanvasArrangeAction } from './arrangeShortcuts.js';\nimport {\n\tcreateNodeGuideIndex,\n\tsnapNodeDrag,\n\ttype GuideIndex,\n\ttype GuideLine,\n\ttype SnapGuidesOptions,\n\ttype SnapNodeDragResult\n} from './guides.js';\nimport type { CanvasNode, XYPosition } from './types.js';\n\n/** Minimal history surface (`HistoryManager` satisfies it). */\nexport interface ArrangeHistoryTarget {\n\texecute(command: Command): void;\n}\n\nexport interface CanvasArrangeControllerOptions<TNode extends CanvasNode = CanvasNode> {\n\tgetNodes: () => TNode[];\n\tsetNodes: (nodes: TNode[]) => void;\n\t/** Ids acted on when a method is called without ids (default: nodes with `selected: true`). */\n\tgetSelectedIds?: () => string[];\n\t/** When set, every arrange action is recorded as one undoable command. */\n\thistory?: ArrangeHistoryTarget;\n\t/** Current zoom, used to convert the guide threshold from screen pixels (default 1). */\n\tgetZoom?: () => number;\n\t/** Smart-guide options (threshold in screen px, edges / centres / spacing toggles). */\n\tguides?: Omit<SnapGuidesOptions, 'zoom'>;\n\t/** Turns drag snapping off while keeping the arrange actions (default `true`). */\n\tsnapping?: boolean;\n\t/** Size resolution for unmeasured nodes. */\n\trectOptions?: NodeRectOptions;\n\t/** Called whenever the guide segments change (set while dragging, cleared on drop). */\n\tonGuidesChange?: (guides: GuideLine[]) => void;\n}\n\n/** A React Flow / SvelteFlow style node change; only `position` changes are inspected. */\nexport interface PositionChangeLike {\n\ttype: string;\n\tid: string;\n\tposition?: XYPosition;\n\tdragging?: boolean;\n\t[key: string]: any;\n}\n\n/**\n * Framework-agnostic arrange controller shared by the Svelte rune and the React hook:\n * align / distribute / match size / lock / z-order actions on the selection (optionally\n * undoable through a `HistoryManager`) and smart-guide snapping during drags.\n */\nexport function createCanvasArrangeController<TNode extends CanvasNode = CanvasNode>(\n\toptions: CanvasArrangeControllerOptions<TNode>\n) {\n\tlet guides: GuideLine[] = [];\n\tlet dragIndex: GuideIndex | null = null;\n\tlet dragKey = '';\n\n\tconst selectedIds = (ids?: Iterable<string>) =>\n\t\tids ? [...ids] : options.getSelectedIds?.() ?? options.getNodes().filter((n) => n.selected).map((n) => n.id);\n\n\tconst setGuides = (next: GuideLine[]) => {\n\t\tif (next.length === 0 && guides.length === 0) return;\n\t\tguides = next;\n\t\toptions.onGuidesChange?.(guides);\n\t};\n\n\t/** Applies updates as one (optionally undoable) step. Returns the updates. */\n\tfunction apply(name: string, updates: CanvasNodeUpdate[]): CanvasNodeUpdate[] {\n\t\tif (updates.length === 0) return updates;\n\t\tconst inverse = invertNodeUpdates(options.getNodes(), updates);\n\t\tconst run = (u: CanvasNodeUpdate[]) => options.setNodes(applyNodeUpdates(options.getNodes(), u));\n\t\tif (options.history) {\n\t\t\toptions.history.execute({ name, execute: () => run(updates), undo: () => run(inverse) });\n\t\t} else {\n\t\t\trun(updates);\n\t\t}\n\t\treturn updates;\n\t}\n\n\tfunction setLocked(name: string, ids: string[], locked: boolean): string[] {\n\t\tconst nodes = options.getNodes();\n\t\tconst set = new Set(ids);\n\t\tconst changed = nodes.filter((n) => set.has(n.id) && isLocked(n) !== locked).map((n) => n.id);\n\t\tif (changed.length === 0) return changed;\n\t\tconst lock = () => options.setNodes(lockNodes(options.getNodes(), changed));\n\t\tconst unlock = () => options.setNodes(unlockNodes(options.getNodes(), changed));\n\t\tif (options.history) {\n\t\t\toptions.history.execute({ name, execute: locked ? lock : unlock, undo: locked ? unlock : lock });\n\t\t} else if (locked) lock();\n\t\telse unlock();\n\t\treturn changed;\n\t}\n\n\tconst rect = () => options.rectOptions ?? {};\n\n\tconst controller = {\n\t\tget guides() {\n\t\t\treturn guides;\n\t\t},\n\t\tapply,\n\t\talign(edge: AlignEdge, ids?: Iterable<string>, alignOptions: AlignNodesOptions = {}) {\n\t\t\treturn apply(`Align ${edge}`, alignNodes(options.getNodes(), selectedIds(ids), edge, { ...rect(), ...alignOptions }));\n\t\t},\n\t\tdistribute(\n\t\t\taxis: DistributeAxis,\n\t\t\tmode: DistributeMode = 'gaps',\n\t\t\tids?: Iterable<string>,\n\t\t\tdistributeOptions: DistributeNodesOptions = {}\n\t\t) {\n\t\t\treturn apply(\n\t\t\t\t`Distribute ${axis}`,\n\t\t\t\tdistributeNodes(options.getNodes(), selectedIds(ids), axis, mode, { ...rect(), ...distributeOptions })\n\t\t\t);\n\t\t},\n\t\tmatchSize(dimension: SizeDimension, ids?: Iterable<string>, sizeOptions: MatchSizeOptions = {}) {\n\t\t\treturn apply(\n\t\t\t\t'Make Same Size',\n\t\t\t\tmatchSize(options.getNodes(), selectedIds(ids), dimension, { ...rect(), ...sizeOptions })\n\t\t\t);\n\t\t},\n\t\treorder(operation: ZOrderOperation, ids?: Iterable<string>) {\n\t\t\treturn apply(operation, reorderNodes(options.getNodes(), selectedIds(ids), operation, rect()));\n\t\t},\n\t\tbringForward: (ids?: Iterable<string>) => controller.reorder('bringForward', ids),\n\t\tsendBackward: (ids?: Iterable<string>) => controller.reorder('sendBackward', ids),\n\t\tbringToFront: (ids?: Iterable<string>) => controller.reorder('bringToFront', ids),\n\t\tsendToBack: (ids?: Iterable<string>) => controller.reorder('sendToBack', ids),\n\t\tlock: (ids?: Iterable<string>) => setLocked('Lock', selectedIds(ids), true),\n\t\tunlock: (ids?: Iterable<string>) => setLocked('Unlock', selectedIds(ids), false),\n\t\ttoggleLock(ids?: Iterable<string>) {\n\t\t\tconst list = selectedIds(ids);\n\t\t\tconst set = new Set(list);\n\t\t\tconst anyUnlocked = options.getNodes().some((n) => set.has(n.id) && !isLocked(n));\n\t\t\treturn anyUnlocked ? controller.lock(list) : controller.unlock(list);\n\t\t},\n\t\tisLocked: (id: string) => isLocked(options.getNodes().find((n) => n.id === id)),\n\n\t\t/**\n\t\t * Runs a shortcut action. Scene actions are not handled here (see the scenes store);\n\t\t * returns `false` for them and for unknown actions.\n\t\t */\n\t\trunAction(action: CanvasArrangeAction): boolean {\n\t\t\tswitch (action) {\n\t\t\t\tcase 'alignLeft': controller.align('left'); return true;\n\t\t\t\tcase 'alignCenter': controller.align('center'); return true;\n\t\t\t\tcase 'alignRight': controller.align('right'); return true;\n\t\t\t\tcase 'alignTop': controller.align('top'); return true;\n\t\t\t\tcase 'alignMiddle': controller.align('middle'); return true;\n\t\t\t\tcase 'alignBottom': controller.align('bottom'); return true;\n\t\t\t\tcase 'distributeHorizontal': controller.distribute('horizontal'); return true;\n\t\t\t\tcase 'distributeVertical': controller.distribute('vertical'); return true;\n\t\t\t\tcase 'lock': controller.lock(); return true;\n\t\t\t\tcase 'unlock': controller.unlock(); return true;\n\t\t\t\tcase 'bringForward': controller.bringForward(); return true;\n\t\t\t\tcase 'sendBackward': controller.sendBackward(); return true;\n\t\t\t\tcase 'bringToFront': controller.bringToFront(); return true;\n\t\t\t\tcase 'sendToBack': controller.sendToBack(); return true;\n\t\t\t\tdefault: return false;\n\t\t\t}\n\t\t},\n\n\t\t/** Caches the snap targets for a drag. Optional: `drag` builds them lazily. */\n\t\tbeginDrag(ids?: Iterable<string>) {\n\t\t\tconst list = selectedIds(ids);\n\t\t\tdragKey = list.slice().sort().join('\\u0000');\n\t\t\tdragIndex = createNodeGuideIndex(options.getNodes(), list, rect());\n\t\t},\n\n\t\t/**\n\t\t * Snaps the dragged nodes (as currently positioned in `getNodes()`) to the other\n\t\t * nodes, writes the snapped positions back through `setNodes` (not recorded in\n\t\t * history) and updates `guides`.\n\t\t */\n\t\tdrag(ids?: Iterable<string>): SnapNodeDragResult | null {\n\t\t\tif (options.snapping === false) return null;\n\t\t\tconst list = selectedIds(ids);\n\t\t\tconst key = list.slice().sort().join('\\u0000');\n\t\t\tif (!dragIndex || key !== dragKey) controller.beginDrag(list);\n\t\t\tconst result = snapNodeDrag(options.getNodes(), list, {\n\t\t\t\t...rect(),\n\t\t\t\t...options.guides,\n\t\t\t\tzoom: options.getZoom?.() ?? 1,\n\t\t\t\tindex: dragIndex!\n\t\t\t});\n\t\t\tif (result.updates.length > 0) {\n\t\t\t\toptions.setNodes(applyNodeUpdates(options.getNodes(), result.updates));\n\t\t\t}\n\t\t\tsetGuides(result.guides);\n\t\t\treturn result;\n\t\t},\n\n\t\t/**\n\t\t * React Flow style: adjusts dragging `position` changes in an `onNodesChange` batch so\n\t\t * the dragged nodes snap, and updates `guides`. Returns the (possibly new) changes array.\n\t\t * A batch without a dragging position change ends the drag and clears the guides.\n\t\t */\n\t\tsnapPositionChanges<TChange extends PositionChangeLike>(changes: TChange[]): TChange[] {\n\t\t\tconst dragging = changes.filter((c) => c.type === 'position' && c.position && c.dragging);\n\t\t\tif (dragging.length === 0) {\n\t\t\t\tif (changes.some((c) => c.type === 'position' && c.dragging === false)) controller.endDrag();\n\t\t\t\treturn changes;\n\t\t\t}\n\t\t\tif (options.snapping === false) return changes;\n\t\t\tconst ids = dragging.map((c) => c.id);\n\t\t\tconst key = ids.slice().sort().join('\\u0000');\n\t\t\tif (!dragIndex || key !== dragKey) controller.beginDrag(ids);\n\t\t\tconst proposed = new Map(dragging.map((c) => [c.id, c.position!]));\n\t\t\tconst nodes = options.getNodes().map((n) => (proposed.has(n.id) ? { ...n, position: proposed.get(n.id)! } : n));\n\t\t\tconst result = snapNodeDrag(nodes, ids, {\n\t\t\t\t...rect(),\n\t\t\t\t...options.guides,\n\t\t\t\tzoom: options.getZoom?.() ?? 1,\n\t\t\t\tindex: dragIndex!\n\t\t\t});\n\t\t\tsetGuides(result.guides);\n\t\t\tconst { x: dx, y: dy } = result.offset;\n\t\t\tif (dx === 0 && dy === 0) return changes;\n\t\t\t// Children of a dragged parent move with it; only shift top-level dragged nodes.\n\t\t\tconst parents = new Map(nodes.map((n) => [n.id, n.parentId]));\n\t\t\tconst shift = new Set(ids.filter((id) => !proposed.has(parents.get(id) ?? '')));\n\t\t\treturn changes.map((c) =>\n\t\t\t\tc.type === 'position' && c.position && c.dragging && shift.has(c.id)\n\t\t\t\t\t? { ...c, position: { x: c.position.x + dx, y: c.position.y + dy } }\n\t\t\t\t\t: c\n\t\t\t);\n\t\t},\n\n\t\t/** Clears guides and the cached snap targets. */\n\t\tendDrag() {\n\t\t\tdragIndex = null;\n\t\t\tdragKey = '';\n\t\t\tsetGuides([]);\n\t\t}\n\t};\n\treturn controller;\n}\n\nexport type CanvasArrangeController<TNode extends CanvasNode = CanvasNode> = ReturnType<\n\ttypeof createCanvasArrangeController<TNode>\n>;\n"],"mappings":"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","names":["next","lane","best"]}
|