@invana/graph 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/store/AdjacencyIndex.ts","../src/store/FrameFlushScheduler.ts","../src/store/PendingEdges.ts","../src/store/GraphStore.ts","../src/layer/types.ts","../src/layer/GraphLayer.ts","../src/layer/MiniMapLayer.ts","../src/history/GraphHistory.ts","../src/clipboard/GraphClipboard.ts","../src/behaviours/HoverActivateBehaviour.ts","../src/behaviours/ModifierTracker.ts","../src/behaviours/ClickSelectBehaviour.ts","../src/behaviours/ClickInspectBehaviour.ts","../src/behaviours/BrushSelectBehaviour.ts","../src/behaviours/LassoSelectBehaviour.ts","../src/behaviours/DragNodeBehaviour.ts","../src/behaviours/ContextMenuBehaviour.ts","../src/behaviours/CreateNodeBehaviour.ts","../src/behaviours/DrawEdgeBehaviour.ts","../src/behaviours/EraseBehaviour.ts","../src/behaviours/CollapseExpandBehaviour.ts","../src/behaviours/NodeResizeBehaviour.ts","../src/behaviours/LabelCollisionBehaviour.ts","../src/behaviours/LabelResolutionLODBehaviour.ts","../src/behaviours/NodeSizeLODBehaviour.ts","../src/behaviours/EdgeSizeLODBehaviour.ts","../src/behaviours/ParallelEdgeBehaviour.ts","../src/behaviours/DegreeSizeBehaviour.ts","../src/behaviours/ResponsiveThemeBehaviour.ts"],"names":["EventEmitter","resolveOptions","Behaviour","Container","Graphics","DRAG_THRESHOLD","ElementSizeLODBehaviour"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * `AdjacencyIndex` — per-slot `Int32Array` lists of edge slot indices.\n *\n * One instance tracks one direction (out or in) of every node's incident\n * edges. The graph store keeps two: `outAdj` (edges where the node is the\n * source) and `inAdj` (edges where the node is the target).\n *\n * Layout:\n *\n * ```\n * slot u → Int32Array of length deg(u), filled with edge slot indices\n * slot v → Int32Array of length deg(v), filled with edge slot indices\n * ...\n * ```\n *\n * Each per-slot array grows geometrically and uses **swap-pop** removal to\n * keep insert / remove at O(1) amortized.\n *\n * Why per-slot `Int32Array`s instead of a single shared CSR-style buffer:\n * realtime mutations dominate this workload. CSR would be faster to iterate\n * but rebuild-on-insert kills the streaming case. Per-slot typed arrays give\n * dynamic O(1) insert + remove with `subarray` views for zero-allocation\n * iteration of live entries.\n *\n * @internal — not exported from `@invana/graph`. Used only inside `GraphStore`.\n */\nexport class AdjacencyIndex {\n /** Per-slot edge-slot lists. `buckets[u]` may be `undefined` for empty slots. */\n private buckets: (Int32Array | undefined)[] = [];\n\n /** Live entry count per slot. Parallels `buckets`. */\n private degrees: Int32Array;\n\n /** Initial per-bucket capacity. Doubles geometrically on overflow. */\n private static readonly INITIAL_BUCKET_CAPACITY = 4;\n\n constructor(initialNodeCapacity = 256) {\n this.degrees = new Int32Array(initialNodeCapacity);\n }\n\n /**\n * Ensure the degree array is large enough to address slot `slot`. Mirrors\n * the geometric growth pattern of `ColumnStore`.\n */\n ensureCapacity(slot: number): void {\n if (slot < this.degrees.length) return;\n let next = this.degrees.length || 1;\n while (next <= slot) next *= 2;\n const grown = new Int32Array(next);\n grown.set(this.degrees);\n this.degrees = grown;\n }\n\n /** Degree of `slot`. Zero if the slot has no edges or is unallocated. */\n degree(slot: number): number {\n return slot < this.degrees.length ? this.degrees[slot]! : 0;\n }\n\n /**\n * Append `edgeSlot` to slot `slot`'s adjacency. Allocates / grows the\n * per-slot `Int32Array` as needed.\n */\n add(slot: number, edgeSlot: number): void {\n this.ensureCapacity(slot);\n let bucket = this.buckets[slot];\n const deg = this.degrees[slot]!;\n if (!bucket) {\n bucket = new Int32Array(AdjacencyIndex.INITIAL_BUCKET_CAPACITY);\n this.buckets[slot] = bucket;\n } else if (deg >= bucket.length) {\n const grown = new Int32Array(bucket.length * 2);\n grown.set(bucket);\n this.buckets[slot] = grown;\n bucket = grown;\n }\n bucket[deg] = edgeSlot;\n this.degrees[slot] = deg + 1;\n }\n\n /**\n * Remove `edgeSlot` from slot `slot`'s adjacency via swap-pop. O(deg(slot))\n * in the worst case to scan for the entry, O(1) to remove. No-op if absent.\n *\n * Returns `true` if the entry was found and removed.\n */\n remove(slot: number, edgeSlot: number): boolean {\n if (slot >= this.degrees.length) return false;\n const bucket = this.buckets[slot];\n const deg = this.degrees[slot]!;\n if (!bucket || deg === 0) return false;\n for (let i = 0; i < deg; i++) {\n if (bucket[i] === edgeSlot) {\n const last = deg - 1;\n if (i !== last) bucket[i] = bucket[last]!;\n this.degrees[slot] = last;\n return true;\n }\n }\n return false;\n }\n\n /**\n * Return a zero-allocation view of slot `slot`'s adjacency. Length is\n * `degree(slot)`. The returned subarray shares memory with the underlying\n * bucket — do **not** mutate it.\n *\n * Stable across reads only until the next `add` / `remove` against this\n * slot (which may grow or swap-pop the bucket).\n */\n view(slot: number): Int32Array {\n if (slot >= this.degrees.length) return EMPTY_VIEW;\n const bucket = this.buckets[slot];\n const deg = this.degrees[slot]!;\n if (!bucket || deg === 0) return EMPTY_VIEW;\n return bucket.subarray(0, deg);\n }\n\n /** Clear all per-slot data (e.g. on `store.clear()`). Capacity preserved. */\n clearAll(): void {\n this.buckets.length = 0;\n this.degrees.fill(0);\n }\n\n /** Reset a single slot (e.g. on `removeNode`). */\n clearSlot(slot: number): void {\n if (slot >= this.degrees.length) return;\n this.buckets[slot] = undefined;\n this.degrees[slot] = 0;\n }\n}\n\n/** Shared empty view returned for zero-degree slots. */\nconst EMPTY_VIEW = new Int32Array(0);\n","/**\n * `FrameFlushScheduler` — RAF-aligned flush coordination for streaming feeds.\n *\n * In `GraphStore` `flushMode: 'frame'`, every mutation calls `request()`. The\n * first call within a frame schedules a `requestAnimationFrame(flush)`;\n * subsequent calls are no-ops until the flush fires. The flush callback runs\n * the supplied flush function once and resets state.\n *\n * Falls back to `queueMicrotask` (or `setTimeout(0)`) outside the browser so\n * tests can drive the scheduler without a real RAF loop. Tests can also call\n * `flushNow()` to bypass scheduling and run the pending flush synchronously.\n *\n * @internal — not exported from `@invana/graph`. Used only inside `GraphStore`.\n */\n\ntype FlushFn = () => void;\n\n/** Detection of `requestAnimationFrame` in non-browser environments. */\nconst hasRAF =\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as { requestAnimationFrame?: unknown }).requestAnimationFrame === 'function';\n\nexport class FrameFlushScheduler {\n private readonly flushFn: FlushFn;\n private scheduled = false;\n /** Monotonic frame counter, incremented on each flush. */\n private _frame = 0;\n\n constructor(flushFn: FlushFn) {\n this.flushFn = flushFn;\n }\n\n /**\n * Current frame counter. Bumps after each flush. Used by `PendingEdges` for\n * TTL accounting.\n */\n get frame(): number {\n return this._frame;\n }\n\n /**\n * Ask for a flush on the next animation frame. Idempotent within a frame.\n */\n request(): void {\n if (this.scheduled) return;\n this.scheduled = true;\n const fire = this.fire.bind(this);\n if (hasRAF) {\n (globalThis as { requestAnimationFrame: (cb: () => void) => number }).requestAnimationFrame(\n fire,\n );\n } else {\n // Fallback for node / vitest — microtask is good enough to coalesce\n // synchronous bursts, and tests can call `flushNow()` to be explicit.\n queueMicrotask(fire);\n }\n }\n\n /**\n * Run any pending flush synchronously. No-op if nothing was scheduled.\n * Used by `GraphStore.flush()` and by tests that need deterministic timing.\n */\n flushNow(): void {\n if (!this.scheduled) return;\n this.fire();\n }\n\n /** Drop any pending flush without firing it (used on `clear()`). */\n cancel(): void {\n this.scheduled = false;\n }\n\n private fire(): void {\n if (!this.scheduled) return;\n this.scheduled = false;\n this._frame++;\n this.flushFn();\n }\n}\n","/**\n * `PendingEdges` — buffer for edges whose source or target node hasn't yet\n * arrived. Used only when `GraphStoreOptions.unknownEndpoint === 'buffer'`.\n *\n * Keyed by missing-endpoint id. An edge missing both endpoints is registered\n * under both ids. When a node arrives, all edges keyed by that id are\n * candidates for admission — those whose other endpoint is already present\n * are admitted; others stay until their second endpoint arrives.\n *\n * Each edge carries its arrival-frame counter for TTL eviction.\n *\n * @internal — not exported from `@invana/graph`. Used only inside `GraphStore`.\n */\nimport type { GraphEdge } from './types';\n\n/** Pending entry — the edge plus its arrival frame for TTL. */\ninterface PendingEntry {\n edge: GraphEdge;\n /** Frame counter when the edge was first parked. */\n parkedAtFrame: number;\n /**\n * The waitingFor sets this entry is registered in. Lets us remove the entry\n * from all of them in O(owners) time on admission, instead of scanning every\n * set in the waitingFor map (which would be O(N) per admit with N total\n * pending endpoints — quadratic for streaming workloads).\n */\n ownerSets: Set<Set<PendingEntry>>;\n}\n\nexport class PendingEdges {\n /** missing-id → set of pending entries waiting on it. */\n private readonly waitingFor: Map<string, Set<PendingEntry>> = new Map();\n\n /** edge id → entry (so duplicate `addEdge` calls update one entry). */\n private readonly byEdgeId: Map<string, PendingEntry> = new Map();\n\n /** Number of pending edges (not entries — an edge missing both endpoints counts once). */\n size(): number {\n return this.byEdgeId.size;\n }\n\n /**\n * Park `edge`, registering it under each of the missing endpoint ids.\n * Replaces a prior pending entry for the same edge id if any.\n */\n park(edge: GraphEdge, missingIds: readonly string[], frame: number): void {\n const existing = this.byEdgeId.get(edge.id);\n if (existing) this.unpark(edge.id);\n const entry: PendingEntry = { edge, parkedAtFrame: frame, ownerSets: new Set() };\n this.byEdgeId.set(edge.id, entry);\n for (const id of missingIds) {\n let set = this.waitingFor.get(id);\n if (!set) {\n set = new Set();\n this.waitingFor.set(id, set);\n }\n set.add(entry);\n entry.ownerSets.add(set);\n }\n }\n\n /**\n * Take every pending edge that was waiting on `id`. Caller decides which\n * are now admissible (an edge missing both endpoints will be returned when\n * the first endpoint arrives but should be re-parked under the second).\n */\n takeWaitingFor(id: string): GraphEdge[] {\n const set = this.waitingFor.get(id);\n if (!set || set.size === 0) return [];\n const entries: PendingEntry[] = [];\n for (const entry of set) {\n entries.push(entry);\n this.byEdgeId.delete(entry.edge.id);\n }\n this.waitingFor.delete(id);\n // For each entry, remove it from every *other* waitingFor set it owned\n // (we just deleted this one). O(owners) per entry — owners is 1 or 2.\n for (const entry of entries) {\n for (const otherSet of entry.ownerSets) {\n if (otherSet !== set) otherSet.delete(entry);\n }\n entry.ownerSets.clear();\n }\n return entries.map((e) => e.edge);\n }\n\n /** Remove a pending edge entirely (e.g. on `unpark` after admission). */\n unpark(edgeId: string): void {\n const entry = this.byEdgeId.get(edgeId);\n if (!entry) return;\n this.byEdgeId.delete(edgeId);\n for (const set of entry.ownerSets) set.delete(entry);\n entry.ownerSets.clear();\n }\n\n /** True iff `edgeId` is currently parked. */\n has(edgeId: string): boolean {\n return this.byEdgeId.has(edgeId);\n }\n\n /**\n * Yield all edges that were parked more than `ttl` frames before `currentFrame`.\n * Caller is expected to call `unpark` on each before emitting `edge:orphaned`.\n */\n *expired(currentFrame: number, ttl: number): IterableIterator<GraphEdge> {\n if (!Number.isFinite(ttl)) return;\n const cutoff = currentFrame - ttl;\n for (const entry of this.byEdgeId.values()) {\n if (entry.parkedAtFrame <= cutoff) yield entry.edge;\n }\n }\n\n /** Wipe all state. */\n clear(): void {\n this.waitingFor.clear();\n this.byEdgeId.clear();\n }\n}\n","/**\n * `GraphStore` — the domain primitive for `@invana/graph`.\n *\n * Composes two `ColumnStore`s (from `@invana/canvas`) for hot fields plus\n * `Map<id, payload>` for cold fields. Adjacency uses per-slot `Int32Array`\n * indices via {@link AdjacencyIndex}. Streaming feeds get RAF-coalesced\n * flushing via {@link FrameFlushScheduler} and out-of-order edge handling\n * via {@link PendingEdges}.\n *\n * See `apps/docs/graph/data-model.md` for the user-facing description and\n * `apps/docs/graph/store-plan.md` for the implementation rationale.\n */\n\nimport { ColumnStore, SourceEmitter } from '@invana/canvas';\nimport type { CanvasEventBus } from '@invana/canvas';\n\nimport { AdjacencyIndex } from './AdjacencyIndex';\nimport { FrameFlushScheduler } from './FrameFlushScheduler';\nimport { PendingEdges } from './PendingEdges';\nimport type {\n EdgeDirection,\n GraphEdge,\n GraphNode,\n GraphStoreEventMap,\n GraphStoreOptions,\n Vec2,\n} from './types';\n\n/** Bit layout for the `flags` column on the node ColumnStore. */\nconst FLAG_PINNED = 1 << 0;\nconst FLAG_TOMBSTONE = 1 << 1;\n\n/** Node hot-field schema. */\nconst NODE_SCHEMA = {\n x: 'f32',\n y: 'f32',\n flags: 'u8',\n} as const;\n\n/** Edge hot-field schema. Stores source/target node *slot* indices for O(1) lookup. */\nconst EDGE_SCHEMA = {\n srcSlot: 'i32',\n dstSlot: 'i32',\n flags: 'u8',\n} as const;\n\n/** Mutable counters accumulated between flushes. */\ninterface FlushCounters {\n addedNodes: number;\n updatedNodes: number;\n removedNodes: number;\n addedEdges: number;\n updatedEdges: number;\n removedEdges: number;\n}\n\nfunction emptyCounters(): FlushCounters {\n return {\n addedNodes: 0,\n updatedNodes: 0,\n removedNodes: 0,\n addedEdges: 0,\n updatedEdges: 0,\n removedEdges: 0,\n };\n}\n\nexport class GraphStore {\n // ─── Options ────────────────────────────────────────────────────────────\n private readonly flushMode: 'sync' | 'frame';\n private readonly unknownEndpoint: 'throw' | 'buffer' | 'drop';\n private readonly pendingEdgeTTL: number;\n\n // ─── Hot storage (typed arrays via ColumnStore) ─────────────────────────\n private readonly nodeCols: ColumnStore<typeof NODE_SCHEMA>;\n private readonly edgeCols: ColumnStore<typeof EDGE_SCHEMA>;\n\n // ─── Cold storage (Map<id, payload>) ────────────────────────────────────\n private readonly nodeMap: Map<string, GraphNode> = new Map();\n private readonly edgeMap: Map<string, GraphEdge> = new Map();\n private readonly childrenIndex: Map<string, Set<string>> = new Map();\n\n // ─── Interaction state (presence compartment) ───────────────────────────\n // The *runtime* active-state sets — hover / selected / highlighted toggled by\n // behaviours and UI. Kept SEPARATE from the cold `states[]` field, which is\n // the *document* (data-driven) active-state list. The two compartments are\n // independent: runtime toggles never touch `states[]`, and a data-feed\n // `updateNode({ states })` never touches these sets (so a feed update can't\n // wipe a live hover/selection). The renderer reads the **union** of both via\n // {@link nodeStatesOf}. See `store-owns-state-plan.md` § 0 / § 5.\n private readonly nodeRuntimeStates: Map<string, Set<string>> = new Map();\n private readonly edgeRuntimeStates: Map<string, Set<string>> = new Map();\n\n // ─── Indices ────────────────────────────────────────────────────────────\n private readonly outAdj = new AdjacencyIndex();\n private readonly inAdj = new AdjacencyIndex();\n private readonly pending = new PendingEdges();\n\n // ─── Reactivity ─────────────────────────────────────────────────────────\n /**\n * Public event bus. Subscribe via `store.events.on('node:add', ...)`.\n *\n * A `SourceEmitter` (`{ kind: 'store' }`): once the owning layer calls\n * {@link bindBus} on mount, every emit also publishes a `CanvasEvent` envelope\n * to the canvas tap channel, so telemetry sees all store mutations\n * (`store-owns-state-plan.md` § 6).\n */\n readonly events: SourceEmitter<GraphStoreEventMap>;\n\n /** Per-flush counters. Reset on `flush()`. */\n private counters = emptyCounters();\n\n /** Pending dedup-ed event payloads to fire on the next flush. */\n private pendingNodeAdds: Set<string> = new Set();\n private pendingNodeUpdates: Map<string, Partial<GraphNode>> = new Map();\n private pendingNodeRemoves: Set<string> = new Set();\n private pendingEdgeAdds: Set<string> = new Set();\n private pendingEdgeUpdates: Map<string, Partial<GraphEdge>> = new Map();\n private pendingEdgeRemoves: Set<string> = new Set();\n private pendingEdgeOrphans: Set<string> = new Set();\n /**\n * Pending runtime-state toggles, keyed by `\"<id>\\u0000<name>\"` so repeated\n * toggles of the same (id, name) within a flush window collapse to one event.\n * The emitted `on` is read from live set membership at flush time, so an\n * add+remove in the same frame nets out correctly.\n */\n private pendingNodeStates: Map<string, { id: string; name: string; actor?: string }> = new Map();\n private pendingEdgeStates: Map<string, { id: string; name: string; actor?: string }> = new Map();\n\n /** Depth of nested `batch()` calls. Flushes only on outermost exit. */\n private batchDepth = 0;\n private flushScheduler: FrameFlushScheduler | null = null;\n\n /** Monotonic version counter. Bumps on every mutation including silent. */\n private _version = 0;\n\n /**\n * Monotonic flush counter. Bumps on every `doFlush` regardless of which\n * code path triggered the flush. Used by `PendingEdges` TTL accounting.\n */\n private _frame = 0;\n\n // ────────────────────────────────────────────────────────────────────────\n\n constructor(opts: GraphStoreOptions = {}) {\n this.flushMode = opts.flushMode ?? 'sync';\n this.unknownEndpoint = opts.unknownEndpoint ?? 'throw';\n this.pendingEdgeTTL = opts.pendingEdgeTTL ?? Infinity;\n const initialCapacity = opts.initialCapacity ?? 256;\n\n this.events = new SourceEmitter<GraphStoreEventMap>({\n kind: 'store',\n id: opts.id ?? 'graph-store',\n });\n\n this.nodeCols = new ColumnStore(NODE_SCHEMA, { initialCapacity });\n this.edgeCols = new ColumnStore(EDGE_SCHEMA, { initialCapacity });\n\n if (this.flushMode === 'frame') {\n this.flushScheduler = new FrameFlushScheduler(() => this.doFlush());\n }\n }\n\n /**\n * Attach (or detach with `undefined`) the canvas event bus this store's\n * events forward to. Called by the owning `GraphLayer` on mount/unmount so\n * store mutations reach the telemetry tap channel (§ 6). Local\n * `store.events.on(...)` subscribers work with or without a bus.\n */\n bindBus(bus: CanvasEventBus | undefined): void {\n this.events.setBus(bus);\n }\n\n // ─── Public read accessors ──────────────────────────────────────────────\n\n /** Monotonic counter. Bumps on every mutation including silent position writes. */\n get version(): number {\n return this._version;\n }\n\n /** Number of live (non-tombstoned) nodes. */\n nodeCount(): number {\n return this.nodeMap.size;\n }\n\n /** Number of live (non-tombstoned) edges. */\n edgeCount(): number {\n return this.edgeMap.size;\n }\n\n hasNode(id: string): boolean {\n return this.nodeMap.has(id);\n }\n\n hasEdge(id: string): boolean {\n return this.edgeMap.has(id);\n }\n\n getNode<D = unknown>(id: string): GraphNode<D> | undefined {\n const cold = this.nodeMap.get(id);\n if (!cold) return undefined;\n const pos = this.readPosition(id);\n const node: GraphNode<D> = { ...(cold as GraphNode<D>) };\n if (pos) node.position = pos;\n node.pinned = this.isPinned(id);\n return node;\n }\n\n getEdge<D = unknown>(id: string): GraphEdge<D> | undefined {\n const cold = this.edgeMap.get(id);\n return cold ? ({ ...cold } as GraphEdge<D>) : undefined;\n }\n\n *nodes(): IterableIterator<GraphNode> {\n for (const id of this.nodeMap.keys()) {\n const node = this.getNode(id);\n if (node) yield node;\n }\n }\n\n *edges(): IterableIterator<GraphEdge> {\n for (const cold of this.edgeMap.values()) yield { ...cold };\n }\n\n // ─── Adjacency ──────────────────────────────────────────────────────────\n\n outDegree(nodeId: string): number {\n const slot = this.nodeCols.slot(nodeId);\n if (slot === undefined) return 0;\n return this.outAdj.degree(slot);\n }\n\n inDegree(nodeId: string): number {\n const slot = this.nodeCols.slot(nodeId);\n if (slot === undefined) return 0;\n return this.inAdj.degree(slot);\n }\n\n /**\n * Yield edges incident to `nodeId` in the requested direction.\n * `'out'` — edges where `nodeId` is the source.\n * `'in'` — edges where `nodeId` is the target.\n * `'both'` — out then in.\n */\n *edgesOf(nodeId: string, dir: EdgeDirection = 'both'): IterableIterator<GraphEdge> {\n const slot = this.nodeCols.slot(nodeId);\n if (slot === undefined) return;\n if (dir === 'out' || dir === 'both') {\n const view = this.outAdj.view(slot);\n for (let i = 0; i < view.length; i++) {\n const edgeId = this.edgeCols.idAt(view[i]!);\n if (edgeId !== undefined) {\n const cold = this.edgeMap.get(edgeId);\n if (cold) yield { ...cold };\n }\n }\n }\n if (dir === 'in' || dir === 'both') {\n const view = this.inAdj.view(slot);\n for (let i = 0; i < view.length; i++) {\n const edgeId = this.edgeCols.idAt(view[i]!);\n if (edgeId !== undefined) {\n const cold = this.edgeMap.get(edgeId);\n if (cold) yield { ...cold };\n }\n }\n }\n }\n\n /** Yield neighbor node ids in the requested direction. */\n *neighborsOf(nodeId: string, dir: EdgeDirection = 'both'): IterableIterator<string> {\n const slot = this.nodeCols.slot(nodeId);\n if (slot === undefined) return;\n const srcCol = this.edgeCols.column('srcSlot');\n const dstCol = this.edgeCols.column('dstSlot');\n if (dir === 'out' || dir === 'both') {\n const view = this.outAdj.view(slot);\n for (let i = 0; i < view.length; i++) {\n const otherSlot = dstCol[view[i]!]!;\n const otherId = this.nodeCols.idAt(otherSlot);\n if (otherId !== undefined) yield otherId;\n }\n }\n if (dir === 'in' || dir === 'both') {\n const view = this.inAdj.view(slot);\n for (let i = 0; i < view.length; i++) {\n const otherSlot = srcCol[view[i]!]!;\n const otherId = this.nodeCols.idAt(otherSlot);\n if (otherId !== undefined) yield otherId;\n }\n }\n }\n\n // ─── Hierarchy ──────────────────────────────────────────────────────────\n\n parentOf(id: string): string | undefined {\n return this.nodeMap.get(id)?.parentId;\n }\n\n *childrenOf(parentId: string): IterableIterator<string> {\n const set = this.childrenIndex.get(parentId);\n if (!set) return;\n for (const childId of set) yield childId;\n }\n\n *descendantsOf(id: string): IterableIterator<string> {\n const stack: string[] = [];\n const initial = this.childrenIndex.get(id);\n if (initial) for (const c of initial) stack.push(c);\n while (stack.length > 0) {\n const next = stack.pop()!;\n yield next;\n const kids = this.childrenIndex.get(next);\n if (kids) for (const c of kids) stack.push(c);\n }\n }\n\n *ancestorsOf(id: string): IterableIterator<string> {\n let cursor = this.parentOf(id);\n while (cursor !== undefined) {\n yield cursor;\n cursor = this.parentOf(cursor);\n }\n }\n\n // ─── Positions ──────────────────────────────────────────────────────────\n\n getPosition(id: string): Vec2 | undefined {\n return this.readPosition(id);\n }\n\n /**\n * Set a single node's position.\n *\n * Default fires `node:update`. `opts.silent: true` skips the event and just\n * bumps `version` — use for layout sim ticks at 60fps.\n */\n setPosition(id: string, pos: Vec2, opts?: { silent?: boolean }): void {\n const slot = this.nodeCols.slot(id);\n if (slot === undefined) return;\n const xCol = this.nodeCols.column('x');\n const yCol = this.nodeCols.column('y');\n xCol[slot] = pos.x;\n yCol[slot] = pos.y;\n this.nodeCols.touch();\n this._version++;\n if (!opts?.silent) {\n this.enqueueNodeUpdate(id, { position: { x: pos.x, y: pos.y } });\n this.scheduleFlushIfNeeded();\n }\n }\n\n /**\n * Set many positions in a single tight loop.\n *\n * `xy` is packed `[x0, y0, x1, y1, ...]` (length must equal `ids.length * 2`).\n * `opts.silent: true` skips events — sim-tick fastpath. Otherwise emits one\n * deduped `node:update` per id.\n */\n setPositionsBulk(ids: readonly string[], xy: Float32Array, opts?: { silent?: boolean }): void {\n if (xy.length !== ids.length * 2) {\n throw new Error(\n `GraphStore.setPositionsBulk: xy.length=${xy.length} must equal ids.length*2=${ids.length * 2}`,\n );\n }\n const xCol = this.nodeCols.column('x');\n const yCol = this.nodeCols.column('y');\n const silent = !!opts?.silent;\n for (let i = 0; i < ids.length; i++) {\n const slot = this.nodeCols.slot(ids[i]!);\n if (slot === undefined) continue;\n const x = xy[i * 2]!;\n const y = xy[i * 2 + 1]!;\n xCol[slot] = x;\n yCol[slot] = y;\n if (!silent) {\n this.enqueueNodeUpdate(ids[i]!, { position: { x, y } });\n }\n }\n this.nodeCols.touch();\n this._version++;\n if (!silent) this.scheduleFlushIfNeeded();\n }\n\n setPinned(id: string, pinned: boolean): void {\n const slot = this.nodeCols.slot(id);\n if (slot === undefined) return;\n const flagsCol = this.nodeCols.column('flags');\n const prev = flagsCol[slot]!;\n const next = pinned ? prev | FLAG_PINNED : prev & ~FLAG_PINNED;\n if (next === prev) return;\n flagsCol[slot] = next;\n this.nodeCols.touch();\n this._version++;\n this.enqueueNodeUpdate(id, { pinned });\n this.scheduleFlushIfNeeded();\n }\n\n isPinned(id: string): boolean {\n const slot = this.nodeCols.slot(id);\n if (slot === undefined) return false;\n return (this.nodeCols.column('flags')[slot]! & FLAG_PINNED) !== 0;\n }\n\n *pinnedIds(): IterableIterator<string> {\n const flagsCol = this.nodeCols.column('flags');\n for (const id of this.nodeMap.keys()) {\n const slot = this.nodeCols.slot(id);\n if (slot === undefined) continue;\n if ((flagsCol[slot]! & FLAG_PINNED) !== 0) yield id;\n }\n }\n\n // ─── CRUD: nodes ────────────────────────────────────────────────────────\n\n /** Strict add — throws on duplicate. */\n addNode<D>(node: GraphNode<D>): void {\n if (this.nodeMap.has(node.id)) {\n throw new Error(`GraphStore.addNode: duplicate id \"${node.id}\"`);\n }\n this.installNode(node);\n this.scheduleFlushIfNeeded();\n }\n\n /** Add-or-merge. Streaming-friendly path. */\n upsertNode<D>(node: GraphNode<D>): void {\n if (this.nodeMap.has(node.id)) {\n this.updateNode(node.id, node as Partial<GraphNode<D>>);\n return;\n }\n this.installNode(node);\n this.scheduleFlushIfNeeded();\n }\n\n updateNode<D>(id: string, patch: Partial<GraphNode<D>>): void {\n const cold = this.nodeMap.get(id);\n if (!cold) return;\n const slot = this.nodeCols.slot(id)!;\n\n // Re-parenting validation + index maintenance.\n if ('parentId' in patch && patch.parentId !== cold.parentId) {\n if (patch.parentId !== undefined) {\n if (patch.parentId === id) {\n throw new Error(`GraphStore.updateNode: parentId cycle (self-parent) on \"${id}\"`);\n }\n if (this.wouldCreateCycle(id, patch.parentId)) {\n throw new Error(\n `GraphStore.updateNode: parentId cycle — \"${patch.parentId}\" is a descendant of \"${id}\"`,\n );\n }\n }\n if (cold.parentId !== undefined) {\n this.childrenIndex.get(cold.parentId)?.delete(id);\n }\n if (patch.parentId !== undefined) {\n let set = this.childrenIndex.get(patch.parentId);\n if (!set) {\n set = new Set();\n this.childrenIndex.set(patch.parentId, set);\n }\n set.add(id);\n }\n cold.parentId = patch.parentId;\n }\n\n if ('data' in patch) cold.data = patch.data;\n\n if ('states' in patch) cold.states = patch.states ?? undefined;\n if ('state' in patch) cold.state = patch.state;\n if ('type' in patch) cold.type = patch.type;\n if ('style' in patch) cold.style = patch.style;\n\n if ('position' in patch && patch.position !== undefined) {\n this.nodeCols.column('x')[slot] = patch.position.x;\n this.nodeCols.column('y')[slot] = patch.position.y;\n }\n\n if ('pinned' in patch && patch.pinned !== undefined) {\n const flagsCol = this.nodeCols.column('flags');\n const prev = flagsCol[slot]!;\n flagsCol[slot] = patch.pinned ? prev | FLAG_PINNED : prev & ~FLAG_PINNED;\n }\n\n this.nodeCols.touch();\n this._version++;\n this.enqueueNodeUpdate(id, patch as Partial<GraphNode>);\n this.scheduleFlushIfNeeded();\n }\n\n /**\n * Remove a node. Cascades by default — removes all incident edges first.\n * `cascade: false` throws if any incident edges still exist.\n */\n removeNode(id: string, opts?: { cascade?: boolean }): void {\n const cold = this.nodeMap.get(id);\n if (!cold) return;\n const slot = this.nodeCols.slot(id)!;\n const cascade = opts?.cascade ?? true;\n\n const outView = this.outAdj.view(slot);\n const inView = this.inAdj.view(slot);\n if (!cascade && (outView.length > 0 || inView.length > 0)) {\n throw new Error(\n `GraphStore.removeNode: \"${id}\" still has ${outView.length + inView.length} incident edges (pass { cascade: true })`,\n );\n }\n\n // Snapshot edge ids to remove since `removeEdge` mutates the adjacency views.\n const incidentEdgeIds: string[] = [];\n for (let i = 0; i < outView.length; i++) {\n const eid = this.edgeCols.idAt(outView[i]!);\n if (eid !== undefined) incidentEdgeIds.push(eid);\n }\n for (let i = 0; i < inView.length; i++) {\n const eid = this.edgeCols.idAt(inView[i]!);\n if (eid !== undefined) incidentEdgeIds.push(eid);\n }\n for (const eid of incidentEdgeIds) this.removeEdge(eid);\n\n // Remove from parent index + clear childrenIndex bucket if present.\n if (cold.parentId !== undefined) {\n this.childrenIndex.get(cold.parentId)?.delete(id);\n }\n // Reparent direct children of this node to `undefined` (logical orphan).\n // Cheaper than recursive removal; caller decides what to do with orphans.\n const myChildren = this.childrenIndex.get(id);\n if (myChildren) {\n for (const childId of myChildren) {\n const childCold = this.nodeMap.get(childId);\n if (childCold) childCold.parentId = undefined;\n }\n this.childrenIndex.delete(id);\n }\n\n // Mark tombstone in the ColumnStore but keep the slot occupied so slot\n // indices stay stable until `compact()`.\n const flagsCol = this.nodeCols.column('flags');\n flagsCol[slot] = flagsCol[slot]! | FLAG_TOMBSTONE;\n this.outAdj.clearSlot(slot);\n this.inAdj.clearSlot(slot);\n\n // Remove from cold storage and id→slot map (so slot is no longer\n // discoverable by id, but the ColumnStore slot is preserved).\n this.nodeMap.delete(id);\n this.nodeCols.remove(id);\n this.nodeRuntimeStates.delete(id);\n\n this.nodeCols.touch();\n this._version++;\n this.enqueueNodeRemove(id);\n this.scheduleFlushIfNeeded();\n\n // If anything was waiting for this id to arrive, those edges are now\n // orphaned for this admission attempt — drop them.\n if (this.unknownEndpoint === 'buffer') {\n const wereWaiting = this.pending.takeWaitingFor(id);\n for (const e of wereWaiting) {\n if (this.pending.has(e.id)) this.pending.unpark(e.id);\n this.enqueueEdgeOrphan(e.id);\n }\n }\n }\n\n // ─── CRUD: edges ────────────────────────────────────────────────────────\n\n addEdge<D>(edge: GraphEdge<D>): void {\n if (this.edgeMap.has(edge.id)) {\n throw new Error(`GraphStore.addEdge: duplicate id \"${edge.id}\"`);\n }\n const srcSlot = this.nodeCols.slot(edge.source);\n const dstSlot = this.nodeCols.slot(edge.target);\n if (srcSlot === undefined || dstSlot === undefined) {\n this.handleUnknownEndpoint(edge, srcSlot === undefined, dstSlot === undefined);\n return;\n }\n this.installEdge(edge, srcSlot, dstSlot);\n this.scheduleFlushIfNeeded();\n }\n\n upsertEdge<D>(edge: GraphEdge<D>): void {\n if (this.edgeMap.has(edge.id)) {\n this.updateEdge(edge.id, edge as Partial<GraphEdge<D>>);\n return;\n }\n // Defer to addEdge so unknownEndpoint policy applies uniformly.\n this.addEdge(edge);\n }\n\n updateEdge<D>(id: string, patch: Partial<GraphEdge<D>>): void {\n const cold = this.edgeMap.get(id);\n if (!cold) return;\n const slot = this.edgeCols.slot(id)!;\n\n if ('source' in patch || 'target' in patch) {\n const nextSource = (patch.source ?? cold.source) as string;\n const nextTarget = (patch.target ?? cold.target) as string;\n const nextSrcSlot = this.nodeCols.slot(nextSource);\n const nextDstSlot = this.nodeCols.slot(nextTarget);\n if (nextSrcSlot === undefined || nextDstSlot === undefined) {\n throw new Error(\n `GraphStore.updateEdge: re-pointing edge \"${id}\" to unknown endpoint \"${nextSrcSlot === undefined ? nextSource : nextTarget}\"`,\n );\n }\n // Rewire adjacency: remove from old, add to new.\n const oldSrcSlot = this.nodeCols.slot(cold.source)!;\n const oldDstSlot = this.nodeCols.slot(cold.target)!;\n this.outAdj.remove(oldSrcSlot, slot);\n this.inAdj.remove(oldDstSlot, slot);\n this.outAdj.add(nextSrcSlot, slot);\n this.inAdj.add(nextDstSlot, slot);\n this.edgeCols.column('srcSlot')[slot] = nextSrcSlot;\n this.edgeCols.column('dstSlot')[slot] = nextDstSlot;\n cold.source = nextSource;\n cold.target = nextTarget;\n }\n\n if ('type' in patch) cold.type = patch.type;\n if ('data' in patch) cold.data = patch.data;\n if ('states' in patch) cold.states = patch.states ?? undefined;\n if ('state' in patch) cold.state = patch.state;\n if ('style' in patch) cold.style = patch.style;\n\n this.edgeCols.touch();\n this._version++;\n this.enqueueEdgeUpdate(id, patch as Partial<GraphEdge>);\n this.scheduleFlushIfNeeded();\n }\n\n /**\n * Reverse an edge's direction — swap its `source` and `target`. No-op if the\n * edge doesn't exist. Routes through {@link updateEdge}, so adjacency indexes\n * are rewired and an `edge:update` is enqueued like any other re-pointing.\n */\n reverseEdge(id: string): void {\n const cold = this.edgeMap.get(id);\n if (!cold) return;\n this.updateEdge(id, { source: cold.target, target: cold.source });\n }\n\n removeEdge(id: string): void {\n const cold = this.edgeMap.get(id);\n if (!cold) return;\n const slot = this.edgeCols.slot(id)!;\n const srcSlot = this.nodeCols.slot(cold.source);\n const dstSlot = this.nodeCols.slot(cold.target);\n if (srcSlot !== undefined) this.outAdj.remove(srcSlot, slot);\n if (dstSlot !== undefined) this.inAdj.remove(dstSlot, slot);\n const flagsCol = this.edgeCols.column('flags');\n flagsCol[slot] = flagsCol[slot]! | FLAG_TOMBSTONE;\n this.edgeCols.touch();\n this.edgeMap.delete(id);\n this.edgeCols.remove(id);\n this._version++;\n this.edgeRuntimeStates.delete(id);\n this.enqueueEdgeRemove(id);\n this.scheduleFlushIfNeeded();\n }\n\n // ─── Interaction state (presence compartment) ───────────────────────────\n //\n // These mutate the *runtime* (presence) compartment only — hover / selected /\n // highlighted / lineage, toggled by behaviours and UI. They are kept separate\n // from the document `states[]` field (feed-owned, changed via `updateNode`);\n // see the field declarations and `store-owns-state-plan.md` § 0 / § 5. Reads\n // ({@link nodeStatesOf} / {@link hasNodeState} / {@link nodesWithState}) report\n // the **union** of both compartments — the effective active-state set the\n // renderer applies. Multi-item callers should wrap writes in {@link batch} so\n // the N toggles coalesce into a single flush (§ 2.5).\n\n /**\n * Add a runtime (presence) state to a node. Idempotent — re-adding an already\n * active state is a no-op (no event). No-op if the node id is unknown.\n *\n * @param id Node id.\n * @param name State name (e.g. `'selected'`, `'highlighted'`, `'lineage'`).\n * @param _opts Reserved for collaboration — `actor` will tag the change with\n * its originating user once presence replication lands (§ 5). Unused today.\n */\n addNodeState(id: string, name: string, _opts?: { actor?: string }): void {\n if (!this.nodeMap.has(id)) return;\n let set = this.nodeRuntimeStates.get(id);\n if (set?.has(name)) return;\n if (!set) {\n set = new Set();\n this.nodeRuntimeStates.set(id, set);\n }\n set.add(name);\n this._version++;\n this.enqueueNodeState(id, name, _opts?.actor);\n this.scheduleFlushIfNeeded();\n }\n\n /**\n * Remove a runtime (presence) state from a node. No-op if the state isn't\n * currently active (no event) or the node is unknown.\n */\n removeNodeState(id: string, name: string, _opts?: { actor?: string }): void {\n const set = this.nodeRuntimeStates.get(id);\n if (!set?.has(name)) return;\n set.delete(name);\n if (set.size === 0) this.nodeRuntimeStates.delete(id);\n this._version++;\n this.enqueueNodeState(id, name, _opts?.actor);\n this.scheduleFlushIfNeeded();\n }\n\n /**\n * Toggle a runtime (presence) state on a node — `on ? addNodeState :\n * removeNodeState`. Convenience for callers (e.g. hover) that compute the\n * desired membership as a boolean. Default `on = true`.\n */\n setNodeState(id: string, name: string, on = true, opts?: { actor?: string }): void {\n if (on) this.addNodeState(id, name, opts);\n else this.removeNodeState(id, name, opts);\n }\n\n /** Toggle a runtime (presence) state on an edge. See {@link setNodeState}. */\n setEdgeState(id: string, name: string, on = true, opts?: { actor?: string }): void {\n if (on) this.addEdgeState(id, name, opts);\n else this.removeEdgeState(id, name, opts);\n }\n\n /**\n * Strip a runtime (presence) state from every node that carries it, in one\n * pass — e.g. clearing a transient `'selected'` / `'lineage'` set. Touches the\n * presence compartment only; a document state of the same name in `states[]`\n * is unaffected (change those via {@link updateNode}).\n */\n clearNodeState(name: string): void {\n let changed = false;\n for (const [id, set] of this.nodeRuntimeStates) {\n if (set.delete(name)) {\n changed = true;\n this.enqueueNodeState(id, name);\n if (set.size === 0) this.nodeRuntimeStates.delete(id);\n }\n }\n if (changed) {\n this._version++;\n this.scheduleFlushIfNeeded();\n }\n }\n\n /** Add a runtime (presence) state to an edge. See {@link addNodeState}. */\n addEdgeState(id: string, name: string, _opts?: { actor?: string }): void {\n if (!this.edgeMap.has(id)) return;\n let set = this.edgeRuntimeStates.get(id);\n if (set?.has(name)) return;\n if (!set) {\n set = new Set();\n this.edgeRuntimeStates.set(id, set);\n }\n set.add(name);\n this._version++;\n this.enqueueEdgeState(id, name, _opts?.actor);\n this.scheduleFlushIfNeeded();\n }\n\n /** Remove a runtime (presence) state from an edge. See {@link removeNodeState}. */\n removeEdgeState(id: string, name: string, _opts?: { actor?: string }): void {\n const set = this.edgeRuntimeStates.get(id);\n if (!set?.has(name)) return;\n set.delete(name);\n if (set.size === 0) this.edgeRuntimeStates.delete(id);\n this._version++;\n this.enqueueEdgeState(id, name, _opts?.actor);\n this.scheduleFlushIfNeeded();\n }\n\n /** Strip a runtime (presence) state from every edge. See {@link clearNodeState}. */\n clearEdgeState(name: string): void {\n let changed = false;\n for (const [id, set] of this.edgeRuntimeStates) {\n if (set.delete(name)) {\n changed = true;\n this.enqueueEdgeState(id, name);\n if (set.size === 0) this.edgeRuntimeStates.delete(id);\n }\n }\n if (changed) {\n this._version++;\n this.scheduleFlushIfNeeded();\n }\n }\n\n /**\n * Effective active states of a node — the **union** of its document `states[]`\n * (feed-owned) and its runtime presence set. This is what the renderer iterates\n * to apply state overlays. Returns a fresh array; empty if the node is unknown\n * or carries no states.\n */\n nodeStatesOf(id: string): readonly string[] {\n const doc = this.nodeMap.get(id)?.states;\n const runtime = this.nodeRuntimeStates.get(id);\n if (!runtime || runtime.size === 0) return doc ? [...doc] : [];\n if (!doc || doc.length === 0) return [...runtime];\n const out = new Set<string>(doc);\n for (const name of runtime) out.add(name);\n return [...out];\n }\n\n /** Effective active states of an edge — union of document + presence. */\n edgeStatesOf(id: string): readonly string[] {\n const doc = this.edgeMap.get(id)?.states;\n const runtime = this.edgeRuntimeStates.get(id);\n if (!runtime || runtime.size === 0) return doc ? [...doc] : [];\n if (!doc || doc.length === 0) return [...runtime];\n const out = new Set<string>(doc);\n for (const name of runtime) out.add(name);\n return [...out];\n }\n\n /** True iff `name` is in a node's effective (document ∪ presence) state set. */\n hasNodeState(id: string, name: string): boolean {\n if (this.nodeRuntimeStates.get(id)?.has(name)) return true;\n return this.nodeMap.get(id)?.states?.includes(name) ?? false;\n }\n\n /** True iff `name` is in an edge's effective (document ∪ presence) state set. */\n hasEdgeState(id: string, name: string): boolean {\n if (this.edgeRuntimeStates.get(id)?.has(name)) return true;\n return this.edgeMap.get(id)?.states?.includes(name) ?? false;\n }\n\n /**\n * Ids of every node whose effective (document ∪ presence) state set contains\n * `name`. Scans live nodes; useful for snapshots / iteration.\n */\n *nodesWithState(name: string): IterableIterator<string> {\n for (const id of this.nodeMap.keys()) {\n if (this.nodeRuntimeStates.get(id)?.has(name)) {\n yield id;\n continue;\n }\n if (this.nodeMap.get(id)?.states?.includes(name)) yield id;\n }\n }\n\n /** Edge sibling of {@link nodesWithState}. */\n *edgesWithState(name: string): IterableIterator<string> {\n for (const [id, cold] of this.edgeMap) {\n if (this.edgeRuntimeStates.get(id)?.has(name) || cold.states?.includes(name)) {\n yield id;\n }\n }\n }\n\n // ─── Bulk operations ────────────────────────────────────────────────────\n\n addNodesBulk(nodes: readonly GraphNode[]): void {\n this.batch(() => {\n for (const n of nodes) this.addNode(n);\n });\n }\n\n addEdgesBulk(edges: readonly GraphEdge[]): void {\n this.batch(() => {\n for (const e of edges) this.addEdge(e);\n });\n }\n\n /**\n * Append nodes + edges in one batch — non-destructive (does NOT clear).\n * Convenience for streaming feeds that push a fresh chunk of items as\n * they arrive. Subscribers see a single `flush`.\n *\n * Differs from `GraphLayer.setData`, which clears the store first.\n */\n addData(data: { nodes?: readonly GraphNode[]; edges?: readonly GraphEdge[] }): void {\n this.batch(() => {\n if (data.nodes && data.nodes.length > 0) {\n for (const n of data.nodes) this.addNode(n);\n }\n if (data.edges && data.edges.length > 0) {\n for (const e of data.edges) this.addEdge(e);\n }\n });\n }\n\n /**\n * Apply a streaming delta in a single batch. Order within the batch:\n * 1. `removed.edgeIds` — removed first so node removals can't cascade\n * them again (no-op double removal is harmless, but explicit is cleaner).\n * 2. `removed.nodeIds` — cascade-removes incident edges per `removeNode`'s\n * default `cascade: true`.\n * 3. `added.nodes` — `upsertNode` (idempotent; safe to re-send).\n * 4. `added.edges` — `upsertEdge`.\n * 5. `updated.nodes` — partial patches via `updateNode`.\n * 6. `updated.edges` — partial patches via `updateEdge`.\n *\n * Use `upsertNode` / `upsertEdge` for the `added` lists so a feed that\n * re-sends an existing id (common in pub-sub) merges rather than throwing.\n * If you have hard-add semantics, use `addData` instead.\n *\n * Subscribers see one `flush` regardless of how many items were touched.\n */\n applyDelta(delta: {\n added?: { nodes?: readonly GraphNode[]; edges?: readonly GraphEdge[] };\n updated?: {\n nodes?: ReadonlyArray<{ id: string; patch: Partial<GraphNode> }>;\n edges?: ReadonlyArray<{ id: string; patch: Partial<GraphEdge> }>;\n };\n removed?: { nodeIds?: readonly string[]; edgeIds?: readonly string[] };\n }): void {\n this.batch(() => {\n const removedEdgeIds = delta.removed?.edgeIds;\n if (removedEdgeIds) {\n for (const id of removedEdgeIds) {\n if (this.hasEdge(id)) this.removeEdge(id);\n }\n }\n const removedNodeIds = delta.removed?.nodeIds;\n if (removedNodeIds) {\n for (const id of removedNodeIds) {\n if (this.hasNode(id)) this.removeNode(id);\n }\n }\n const addedNodes = delta.added?.nodes;\n if (addedNodes) {\n for (const n of addedNodes) this.upsertNode(n);\n }\n const addedEdges = delta.added?.edges;\n if (addedEdges) {\n for (const e of addedEdges) this.upsertEdge(e);\n }\n const updatedNodes = delta.updated?.nodes;\n if (updatedNodes) {\n for (const u of updatedNodes) {\n if (this.hasNode(u.id)) this.updateNode(u.id, u.patch);\n }\n }\n const updatedEdges = delta.updated?.edges;\n if (updatedEdges) {\n for (const u of updatedEdges) {\n if (this.hasEdge(u.id)) this.updateEdge(u.id, u.patch);\n }\n }\n });\n }\n\n // ─── Reactivity ─────────────────────────────────────────────────────────\n\n /**\n * Coalesce all mutations inside `fn` into a single flush. Nested `batch`\n * calls flush only on the outermost exit.\n */\n batch<T>(fn: () => T): T {\n this.batchDepth++;\n try {\n return fn();\n } finally {\n this.batchDepth--;\n if (this.batchDepth === 0) {\n this.scheduleFlushIfNeeded();\n if (this.flushMode === 'sync') this.doFlush();\n }\n }\n }\n\n /**\n * Drain any pending events. Cancels the RAF-scheduled flush (frame mode).\n * In sync mode this still works — handy for forcing the TTL eviction sweep\n * even if no mutation has happened since the last flush.\n */\n flush(): void {\n this.flushScheduler?.cancel();\n this.doFlush();\n }\n\n /** Wipe all data. Cancels any pending flush. */\n clear(): void {\n this.nodeMap.clear();\n this.edgeMap.clear();\n this.nodeRuntimeStates.clear();\n this.edgeRuntimeStates.clear();\n this.childrenIndex.clear();\n this.outAdj.clearAll();\n this.inAdj.clearAll();\n this.pending.clear();\n this.nodeCols.clear();\n this.edgeCols.clear();\n this.pendingNodeAdds.clear();\n this.pendingNodeUpdates.clear();\n this.pendingNodeRemoves.clear();\n this.pendingEdgeAdds.clear();\n this.pendingEdgeUpdates.clear();\n this.pendingEdgeRemoves.clear();\n this.pendingEdgeOrphans.clear();\n this.pendingNodeStates.clear();\n this.pendingEdgeStates.clear();\n this.counters = emptyCounters();\n this.flushScheduler?.cancel();\n this._version++;\n }\n\n /**\n * Reclaim tombstoned slots. Invalidates any external code that cached\n * slot indices. Renderer batch buffers etc. must invalidate first.\n */\n compact(): void {\n // Snapshot hot fields keyed by id BEFORE clearing the ColumnStores —\n // position + pinned-flag live only in the hot columns, not in the cold\n // maps, so we'd lose them if we cleared first.\n const xCol = this.nodeCols.column('x');\n const yCol = this.nodeCols.column('y');\n const flagsCol = this.nodeCols.column('flags');\n const nodeSnapshot = new Map<string, { x: number; y: number; flags: number }>();\n for (const id of this.nodeMap.keys()) {\n const slot = this.nodeCols.slot(id);\n if (slot === undefined) continue;\n nodeSnapshot.set(id, {\n x: xCol[slot]!,\n y: yCol[slot]!,\n flags: flagsCol[slot]! & ~FLAG_TOMBSTONE, // strip tombstone bit on rebuild\n });\n }\n\n this.nodeCols.clear();\n this.edgeCols.clear();\n this.outAdj.clearAll();\n this.inAdj.clearAll();\n\n for (const id of this.nodeMap.keys()) {\n const snap = nodeSnapshot.get(id) ?? { x: 0, y: 0, flags: 0 };\n const slot = this.nodeCols.add(id, snap);\n this.outAdj.ensureCapacity(slot);\n this.inAdj.ensureCapacity(slot);\n }\n for (const [id, edge] of this.edgeMap) {\n const srcSlot = this.nodeCols.slot(edge.source);\n const dstSlot = this.nodeCols.slot(edge.target);\n if (srcSlot === undefined || dstSlot === undefined) continue;\n const slot = this.edgeCols.add(id, { srcSlot, dstSlot, flags: 0 });\n this.outAdj.add(srcSlot, slot);\n this.inAdj.add(dstSlot, slot);\n }\n this._version++;\n }\n\n // ─── Internals ──────────────────────────────────────────────────────────\n\n private installNode(node: GraphNode): void {\n if (node.parentId !== undefined) {\n if (node.parentId === node.id) {\n throw new Error(`GraphStore: parentId cycle (self-parent) on \"${node.id}\"`);\n }\n // Note: cycle check vs descendants only matters on update; on add the\n // node has no descendants yet so self-parent is the only case.\n }\n\n const slot = this.nodeCols.add(node.id, {\n x: node.position?.x ?? 0,\n y: node.position?.y ?? 0,\n flags: node.pinned ? FLAG_PINNED : 0,\n });\n this.outAdj.ensureCapacity(slot);\n this.inAdj.ensureCapacity(slot);\n\n // Cold payload stored without `position` / `pinned` — those live in columns.\n const cold: GraphNode = { id: node.id };\n if (node.data !== undefined) cold.data = node.data;\n if (node.parentId !== undefined) cold.parentId = node.parentId;\n if (node.states !== undefined) cold.states = node.states;\n if (node.state !== undefined) cold.state = node.state;\n if (node.type !== undefined) cold.type = node.type;\n if (node.style !== undefined) cold.style = node.style;\n this.nodeMap.set(node.id, cold);\n\n if (node.parentId !== undefined) {\n let set = this.childrenIndex.get(node.parentId);\n if (!set) {\n set = new Set();\n this.childrenIndex.set(node.parentId, set);\n }\n set.add(node.id);\n }\n\n this._version++;\n this.enqueueNodeAdd(node.id);\n\n // If anything was waiting for this id, try to admit it now.\n if (this.unknownEndpoint === 'buffer') {\n const candidates = this.pending.takeWaitingFor(node.id);\n for (const edge of candidates) this.tryAdmitPending(edge);\n }\n }\n\n private installEdge(edge: GraphEdge, srcSlot: number, dstSlot: number): void {\n const slot = this.edgeCols.add(edge.id, { srcSlot, dstSlot, flags: 0 });\n this.outAdj.add(srcSlot, slot);\n this.inAdj.add(dstSlot, slot);\n\n const cold: GraphEdge = { id: edge.id, source: edge.source, target: edge.target };\n if (edge.type !== undefined) cold.type = edge.type;\n if (edge.data !== undefined) cold.data = edge.data;\n if (edge.states !== undefined) cold.states = edge.states;\n if (edge.state !== undefined) cold.state = edge.state;\n if (edge.style !== undefined) cold.style = edge.style;\n this.edgeMap.set(edge.id, cold);\n\n this._version++;\n this.enqueueEdgeAdd(edge.id);\n }\n\n private handleUnknownEndpoint(edge: GraphEdge, srcMissing: boolean, dstMissing: boolean): void {\n switch (this.unknownEndpoint) {\n case 'throw': {\n const missing = srcMissing ? edge.source : edge.target;\n throw new Error(`GraphStore.addEdge: unknown endpoint \"${missing}\" on edge \"${edge.id}\"`);\n }\n case 'drop':\n return;\n case 'buffer': {\n const missingIds: string[] = [];\n if (srcMissing) missingIds.push(edge.source);\n if (dstMissing) missingIds.push(edge.target);\n this.pending.park(edge, missingIds, this._frame);\n // Schedule a flush so the TTL sweep runs on the next flush even if no\n // other mutation happens.\n this.scheduleFlushIfNeeded();\n return;\n }\n }\n }\n\n private tryAdmitPending(edge: GraphEdge): void {\n const srcSlot = this.nodeCols.slot(edge.source);\n const dstSlot = this.nodeCols.slot(edge.target);\n if (srcSlot === undefined || dstSlot === undefined) {\n // Still missing the other endpoint — re-park under that id.\n const missingIds: string[] = [];\n if (srcSlot === undefined) missingIds.push(edge.source);\n if (dstSlot === undefined) missingIds.push(edge.target);\n this.pending.park(edge, missingIds, this._frame);\n return;\n }\n if (this.edgeMap.has(edge.id)) return; // already admitted via direct path\n this.installEdge(edge, srcSlot, dstSlot);\n }\n\n /** True iff `candidateAncestor` is already a descendant of `id`. */\n private wouldCreateCycle(id: string, candidateAncestor: string): boolean {\n for (const desc of this.descendantsOf(id)) {\n if (desc === candidateAncestor) return true;\n }\n return false;\n }\n\n private readPosition(id: string): Vec2 | undefined {\n const slot = this.nodeCols.slot(id);\n if (slot === undefined) return undefined;\n const x = this.nodeCols.column('x')[slot]!;\n const y = this.nodeCols.column('y')[slot]!;\n return { x, y };\n }\n\n // Event queue management — dedups within a flush window.\n\n private enqueueNodeAdd(id: string): void {\n // If the node was removed earlier in the same batch and now re-added,\n // collapse: the net effect is a single 'add' (no remove fires).\n if (this.pendingNodeRemoves.delete(id)) {\n // remove counter cancelled\n this.counters.removedNodes = Math.max(0, this.counters.removedNodes - 1);\n }\n this.pendingNodeAdds.add(id);\n this.pendingNodeUpdates.delete(id);\n this.counters.addedNodes++;\n }\n\n private enqueueNodeUpdate(id: string, patch: Partial<GraphNode>): void {\n if (this.pendingNodeAdds.has(id)) return; // the add carries the latest state\n if (this.pendingNodeRemoves.has(id)) return; // removed — ignore late updates\n const existing = this.pendingNodeUpdates.get(id);\n if (existing) {\n Object.assign(existing, patch);\n } else {\n this.pendingNodeUpdates.set(id, { ...patch });\n this.counters.updatedNodes++;\n }\n }\n\n private enqueueNodeRemove(id: string): void {\n if (this.pendingNodeAdds.delete(id)) {\n // Added and removed in the same batch — net zero. Counters retreat.\n this.counters.addedNodes = Math.max(0, this.counters.addedNodes - 1);\n this.pendingNodeUpdates.delete(id);\n return;\n }\n this.pendingNodeUpdates.delete(id);\n this.pendingNodeRemoves.add(id);\n this.counters.removedNodes++;\n }\n\n private enqueueEdgeAdd(id: string): void {\n if (this.pendingEdgeRemoves.delete(id)) {\n this.counters.removedEdges = Math.max(0, this.counters.removedEdges - 1);\n }\n this.pendingEdgeAdds.add(id);\n this.pendingEdgeUpdates.delete(id);\n this.counters.addedEdges++;\n }\n\n private enqueueEdgeUpdate(id: string, patch: Partial<GraphEdge>): void {\n if (this.pendingEdgeAdds.has(id)) return;\n if (this.pendingEdgeRemoves.has(id)) return;\n const existing = this.pendingEdgeUpdates.get(id);\n if (existing) {\n Object.assign(existing, patch);\n } else {\n this.pendingEdgeUpdates.set(id, { ...patch });\n this.counters.updatedEdges++;\n }\n }\n\n private enqueueEdgeRemove(id: string): void {\n if (this.pendingEdgeAdds.delete(id)) {\n this.counters.addedEdges = Math.max(0, this.counters.addedEdges - 1);\n this.pendingEdgeUpdates.delete(id);\n return;\n }\n this.pendingEdgeUpdates.delete(id);\n this.pendingEdgeRemoves.add(id);\n this.counters.removedEdges++;\n }\n\n private enqueueEdgeOrphan(id: string): void {\n this.pendingEdgeOrphans.add(id);\n }\n\n /** Queue a node runtime-state change, deduped per `(id, name)` per flush. */\n private enqueueNodeState(id: string, name: string, actor?: string): void {\n this.pendingNodeStates.set(`${id}\\u0000${name}`, { id, name, actor });\n }\n\n /** Queue an edge runtime-state change, deduped per `(id, name)` per flush. */\n private enqueueEdgeState(id: string, name: string, actor?: string): void {\n this.pendingEdgeStates.set(`${id}\\u0000${name}`, { id, name, actor });\n }\n\n private scheduleFlushIfNeeded(): void {\n if (this.batchDepth > 0) return;\n if (this.flushMode === 'frame') {\n this.flushScheduler?.request();\n return;\n }\n this.doFlush();\n }\n\n private doFlush(): void {\n this._frame++;\n\n // Expire stale pending edges (TTL eviction) before flushing.\n if (this.unknownEndpoint === 'buffer' && Number.isFinite(this.pendingEdgeTTL)) {\n const stale: string[] = [];\n for (const e of this.pending.expired(this._frame, this.pendingEdgeTTL)) stale.push(e.id);\n for (const eid of stale) {\n this.pending.unpark(eid);\n this.pendingEdgeOrphans.add(eid);\n }\n }\n\n // Snapshot then clear queues so listener-induced mutations rebuild the\n // next batch cleanly.\n const nodeAdds = this.pendingNodeAdds;\n const nodeUpdates = this.pendingNodeUpdates;\n const nodeRemoves = this.pendingNodeRemoves;\n const edgeAdds = this.pendingEdgeAdds;\n const edgeUpdates = this.pendingEdgeUpdates;\n const edgeRemoves = this.pendingEdgeRemoves;\n const edgeOrphans = this.pendingEdgeOrphans;\n const nodeStates = this.pendingNodeStates;\n const edgeStates = this.pendingEdgeStates;\n const counters = this.counters;\n this.pendingNodeAdds = new Set();\n this.pendingNodeUpdates = new Map();\n this.pendingNodeRemoves = new Set();\n this.pendingEdgeAdds = new Set();\n this.pendingEdgeUpdates = new Map();\n this.pendingEdgeRemoves = new Set();\n this.pendingEdgeOrphans = new Set();\n this.pendingNodeStates = new Map();\n this.pendingEdgeStates = new Map();\n this.counters = emptyCounters();\n\n if (\n nodeAdds.size === 0 &&\n nodeUpdates.size === 0 &&\n nodeRemoves.size === 0 &&\n edgeAdds.size === 0 &&\n edgeUpdates.size === 0 &&\n edgeRemoves.size === 0 &&\n edgeOrphans.size === 0 &&\n nodeStates.size === 0 &&\n edgeStates.size === 0\n ) {\n return;\n }\n\n for (const id of nodeAdds) this.events.emit('node:add', { nodeId: id });\n for (const [id, patch] of nodeUpdates) this.events.emit('node:update', { nodeId: id, patch });\n for (const id of nodeRemoves) this.events.emit('node:remove', { nodeId: id });\n for (const id of edgeAdds) this.events.emit('edge:add', { edgeId: id });\n for (const [id, patch] of edgeUpdates) this.events.emit('edge:update', { edgeId: id, patch });\n for (const id of edgeRemoves) this.events.emit('edge:remove', { edgeId: id });\n for (const id of edgeOrphans) this.events.emit('edge:orphaned', { edgeId: id });\n // Runtime-state toggles — `on` read from live membership so an add+remove in\n // the same flush window nets out correctly. Document `states[]` changes ride\n // the `node:update` above, not these.\n for (const { id, name, actor } of nodeStates.values()) {\n this.events.emit('node:state', {\n nodeId: id,\n name,\n on: this.nodeRuntimeStates.get(id)?.has(name) ?? false,\n actor,\n });\n }\n for (const { id, name, actor } of edgeStates.values()) {\n this.events.emit('edge:state', {\n edgeId: id,\n name,\n on: this.edgeRuntimeStates.get(id)?.has(name) ?? false,\n actor,\n });\n }\n this.events.emit('flush', counters);\n }\n\n}\n\n// Slot-stability note: `ColumnStore.remove` pushes the slot onto its internal\n// free-slot stack, so the next `add` will reuse it. That means GraphStore slot\n// indices are stable until the next `add` after a `remove`. The tombstone\n// flag bit lets external code detect a recycled slot if it cached one before\n// removal. `compact()` rebuilds both ColumnStores from cold storage, which\n// fully reclaims any orphaned capacity. If profiling later shows that slot\n// recycling causes problems for the GraphLayer renderer, the right fix is to\n// add a `disableRecycling` option to ColumnStore upstream — not to hack\n// around it here.\n","/**\n * `GraphLayer` public types — option shapes and per-node/per-edge render-spec\n * hints that map domain data to primitive specs.\n */\nimport type {\n ShapeLabelStyle,\n ConnectorLabelStyle,\n ShapeFill,\n ShapeLabelPlacement,\n ConnectorLabelPlacement,\n InsetAnchor,\n} from '@invana/canvas';\nimport type { Point } from '@invana/canvas/primitives';\nimport type {\n RingDecorationStyle,\n GlowDecorationStyle,\n PulseRingDecorationStyle,\n MarchingAntsDecorationStyle,\n LiquidFillDecorationStyle,\n RingConnectorDecorationStyle,\n GlowConnectorDecorationStyle,\n MarchingAntsConnectorDecorationStyle,\n RippleConnectorDecorationStyle,\n FlyMarkerConnectorDecorationStyle,\n FlowParticlesConnectorDecorationStyle,\n RevealConnectorDecorationStyle,\n ToggleDecorationStyle,\n TogglePlacement,\n ResizeHandleDecorationStyle,\n SelectionFrameDecorationStyle,\n} from '@invana/canvas/primitives';\nimport type { GraphEdge, GraphNode } from '../store/types';\n\n/**\n * A field value that's either a static value or a function that derives the\n * value from the host item (node / edge / raw data).\n *\n * Used on every field of `NodeStyle` / `EdgeStyle` (via `ResolvableNodeStyle`\n * / `ResolvableEdgeStyle`) so callers can supply per-item-derived styling\n * on the layer template (`options.node.style`) or per-instance input\n * (`NodeInput.style`) without spreading hints into every node's `data`.\n *\n * Resolved per render (layer-level) or once at insert (per-input). Keep\n * resolvers cheap and pure — they may run per frame. Recursive returns\n * (a function returning another function) are not unwrapped — return the\n * final value.\n *\n * @example\n * ```ts\n * node: {\n * style: {\n * bgFill: (n) => groupColors[(n.data as Group).group % groupColors.length],\n * shape: (n) => ({ kind: 'circle', radius: 12 + Math.sqrt((n.data as N).degree ?? 1) * 4 }),\n * labelText: (n) => (n.data as N).name,\n * },\n * }\n * ```\n */\nexport type Resolvable<T, I> = T | ((input: I) => T);\n\n/** Convenience alias for id-resolvers; `D` is the raw data type on input. */\nexport type ResolvableId<D> = string | ((data: D) => string);\n\n/**\n * Unwrap a {@link Resolvable} field for `input`. Static values pass through\n * untouched; function values are invoked once with `input` and their return\n * is used. Functions returning further functions are NOT unwrapped — return\n * the final value.\n */\nexport function resolveField<T, I>(\n v: Resolvable<T, I> | undefined,\n input: I,\n): T | undefined {\n return typeof v === 'function' ? (v as (i: I) => T)(input) : v;\n}\n\n/** Path-style shortcut for an edge. Maps to the canvas router + pathStyle pair. */\nexport type EdgePathType =\n | 'straight'\n | 'bezier'\n | 'quadratic'\n | 'bump-radial'\n | 'bump-horizontal'\n | 'step-radial'\n | 'orth'\n | 'manhattan'\n | 'rounded'\n | 'smooth'\n | 'bundle'\n // Self-loop variants — use when `source === target`. Path geometry is\n // generated from `pathStyleOpts` (angle, radius/stubLength, width/gap)\n // anchored at the host node; the anchor/router pair is degenerate for a\n // self-edge so these styles ignore the polyline beyond its first point.\n | 'loop-curve'\n | 'loop-polyline';\n\n/**\n * Endpoint anchor.\n *\n * - `'boundary'` (default) — trim the endpoint at the node's outline along\n * the line from the other endpoint. Visually the edge stops at the node\n * boundary; works with arrows and connector decorations cleanly.\n * - `'center'` — leave the endpoint at the node's centre. The edge passes\n * through the node visually; rely on z-order (nodes drawn on top) to make\n * it look like the edge terminates at the boundary. Pick this for radial\n * layouts so polar pathStyles (e.g. `bump-radial`) compute their tangent\n * from the true node-centre angle rather than the trimmed cut point.\n * - `'perpendicular'` — exit / enter perpendicular to the host edge of a\n * rect-like node. Reserved for box-shaped nodes.\n * - `'edge-port'` — attach to a specific point on one face of the node's\n * bounding box, picked by `{ side, offset }` on the per-endpoint\n * `sourceAnchorOpts` / `targetAnchorOpts`. Used by the Sankey layout to\n * stack ribbons along the right face of source and left face of target.\n *\n * Widened to `string` so anchors registered at runtime (e.g. domain-specific\n * port anchors) can be referenced by name.\n */\nexport type EdgeAnchor = 'boundary' | 'center' | 'perpendicular' | 'edge-port' | (string & {});\n\n/** Initial-load shape passed to `graphLayer.setData(data)`. */\nexport interface GraphData {\n nodes: GraphNode[];\n edges: GraphEdge[];\n}\n\n/**\n/**\n * Canonical interaction-state names with sensible defaults baked into the\n * GraphLayer's resolver. State styling lives on the layer-level\n * {@link NodeOption.state} / per-node {@link NodeData.state} catalogue —\n * `default` is intentionally absent (it's the absence of any active state,\n * not a state itself).\n *\n * The state-config map is open-keyed: consumers can declare additional\n * named states (e.g. `'pinned'`, `'flagged'`, `'error'`, `'focused'`)\n * directly on `options.node.state` / `node.state` with the same shape —\n * they compose via the same merge rules. The canonical set below is\n * deliberately small; reach for it only when the named driver applies.\n *\n * ### Driver → state map\n *\n * Each canonical state has a distinct *driver* (what causes the state to\n * be written) and *lifetime* (when it clears). The visual treatments\n * overlap (most are stroke rings of various colours), but the semantics\n * do not — a single node can carry several states simultaneously (e.g.\n * `selected + hover`) and a behaviour should only write the states it\n * owns.\n *\n * | State | Driver | Lifetime | Cardinality |\n * | ------------- | ----------------------------------------- | --------------------------------- | ----------------- |\n * | `hovered` | Mouse / touch pointer-over | Transient — clears on pointer-out | ≤ 1 per layer |\n * | `selected` | Click / lasso / brush — user's chosen set | Sticky until explicitly cleared | 0–N per layer |\n * | `highlighted` | 1-hop neighbours of the hovered / selected | Transient — clears with the driver | 0–N per layer |\n * | `dimmed` | Complement of the focal-emphasis set | Transient — clears with the driver | 0–N per layer |\n * | `disabled` | Data flag — \"not interactive\" | Sticky — owned by the data feed | 0–N per layer |\n *\n * ### Sticky chosen set — `selected`\n *\n * `selected` is the click / lasso / brush state — what the user *chose*.\n * Persists until explicitly deselected. **Multi-select doesn't need its\n * own state**: it's just the same `selected` state applied to every\n * member of `selectedIds: Set<string>`. One node selected → one ring;\n * ten nodes selected → ten rings.\n *\n * `selected` can co-exist with `hovered` — clicking a node doesn't stop\n * it from being hovered.\n *\n * ### Focal-emphasis flow — `highlighted` + `dimmed`\n *\n * Written together by a focal-emphasis behaviour (typically driven by\n * hover or selection). When the user hovers / selects a node:\n * - its 1-hop neighbours go `highlighted` — *supporting cast*,\n * - everyone else goes `dimmed` — *pushed back so the focal set pops*.\n *\n * Both clear together when emphasis ends. Drop the pair if the product\n * never needs the \"fade everyone except the focal subgraph\" interaction.\n *\n * ### Data-driven — `disabled`\n *\n * Sticky and owned by the data feed (not by an interaction behaviour).\n * `disabled` is \"this node isn't interactive — don't let the user pick\n * it\". Visually overlaps `dimmed` but they're semantically distinct:\n * - `dimmed` says *\"you're focusing elsewhere\"* (transient, behaviour).\n * - `disabled` says *\"you can't interact with me\"* (sticky, data).\n * Conflating them would couple interaction code to data code — keep them\n * separate even if the visual treatment is similar.\n */\nexport type CanonicalStateName =\n /** Mouse / touch pointer is over the node. Transient; one node at a time. */\n | 'hovered'\n /** User's chosen set (click / lasso / brush). Sticky; many at a time. Multi-select is just this state applied to each member of the selection. */\n | 'selected'\n /** 1-hop neighbour of the hovered / selected focal — \"supporting cast\". Transient; cleared with the focal. */\n | 'highlighted'\n /** Complement of the focal-emphasis set — pushed back so `selected` + `highlighted` pop. Transient. NOT `disabled` — that's a data flag. */\n | 'dimmed'\n /** Data flag: \"not interactive\". Sticky; owned by the data feed. Visually similar to `dimmed` but semantically distinct (data, not interaction). */\n | 'disabled';\n\n// ───────────────────────────────────────────────────────────────────────────\n// v3 — G6-aligned types (NodeData / NodeInput / NodeOption + edge mirror)\n// See `data-types-instances.md` + `data-types-implementation-plan.md`.\n// ───────────────────────────────────────────────────────────────────────────\n\n// ─── NodeShapeOptions (structural geometry, per-shape options) ─────────────\n\n/** Rect-shape option. `cornerRadius` is optional; everything else required. */\nexport interface RectShapeOption {\n readonly kind: 'rect';\n readonly width: number;\n readonly height: number;\n readonly cornerRadius?: number;\n}\n\n/** Circle-shape option. */\nexport interface CircleShapeOption {\n readonly kind: 'circle';\n readonly radius: number;\n}\n\n/** Arc (annular sector) shape option. All four geometry params required. */\nexport interface ArcShapeOption {\n readonly kind: 'arc';\n readonly innerR: number;\n readonly outerR: number;\n readonly startAngle: number;\n readonly endAngle: number;\n}\n\n/**\n * Regular n-gon. With `rotation = 0` the first vertex points straight up, so\n * a triangle / pentagon / hexagon points up by default. Pass\n * `rotation: Math.PI / sides` for flat-top.\n */\nexport interface RegularPolygonShapeOption {\n readonly kind: 'regular-polygon';\n readonly sides: number;\n readonly radius: number;\n readonly rotation?: number;\n}\n\n/**\n * N-pointed star. Classic 5-point star uses\n * `{ points: 5, outerRadius: r, innerRadius: r * 0.4 }`.\n */\nexport interface StarShapeOption {\n readonly kind: 'star';\n readonly points: number;\n readonly innerRadius: number;\n readonly outerRadius: number;\n readonly rotation?: number;\n}\n\n/**\n * Free-form polygon. `vertices` are centre-relative — closed implicitly\n * (last vertex connects to first).\n */\nexport interface PolygonShapeOption {\n readonly kind: 'polygon';\n readonly vertices: ReadonlyArray<Point>;\n}\n\n/**\n * Escape-hatch variant for shape kinds registered at runtime via\n * `canvas.primitives.registerShape(name, ctor)`. The widened `kind` accepts\n * any string the type-checker can't match against a built-in variant;\n * additional spec params are erased at the type level but pass through to\n * the renderer untouched at runtime (the adapter spreads the whole shape\n * record into the spec).\n *\n * Authors of custom shapes typically declare a local interface\n * (`interface ChevronShapeOption { kind: 'chevron'; size: number }`) and\n * cast at the boundary (`style: { shape: chevron as NodeShapeOptions }`).\n * The index signature was deliberately omitted here so that discriminant\n * narrowing on the typed built-in variants (`shape.kind === 'rect'` →\n * `RectShapeOption`) keeps working everywhere else in the codebase.\n *\n * Built-in kinds (`'rect'`, `'circle'`, `'arc'`, `'regular-polygon'`,\n * `'star'`, `'polygon'`) are matched by the typed variants above before\n * this fallback applies.\n */\nexport interface CustomShapeOption {\n readonly kind: string & {};\n}\n\n/**\n * Closed union of the six shape kinds that `@invana/canvas` registers out\n * of the box. Exported so internal switch-narrowing sites can target it\n * directly via the {@link isBuiltInNodeShape} type guard.\n */\nexport type BuiltInNodeShapeOptions =\n | RectShapeOption\n | CircleShapeOption\n | ArcShapeOption\n | RegularPolygonShapeOption\n | StarShapeOption\n | PolygonShapeOption;\n\n/**\n * Discriminated union of node shape options. The `kind` field enforces\n * per-variant required fields at compile time for the six built-in kinds\n * registered by `@invana/canvas`. {@link CustomShapeOption} provides an\n * open-keyed fallback for shapes registered at runtime by the consumer.\n *\n * Internal call sites that need to read variant-specific fields should\n * narrow via the {@link isBuiltInNodeShape} type guard first — the\n * open-keyed `CustomShapeOption.kind` prevents `switch (shape.kind)` over\n * literals from excluding the custom variant on its own.\n */\nexport type NodeShapeOptions = BuiltInNodeShapeOptions | CustomShapeOption;\n\n/**\n * Type guard separating the typed built-in variants from\n * {@link CustomShapeOption}. Use this before reading variant-specific\n * fields so TypeScript narrows cleanly inside each `case`.\n */\nexport function isBuiltInNodeShape(\n shape: NodeShapeOptions,\n): shape is BuiltInNodeShapeOptions {\n switch (shape.kind) {\n case 'rect':\n case 'circle':\n case 'arc':\n case 'regular-polygon':\n case 'star':\n case 'polygon':\n return true;\n default:\n return false;\n }\n}\n\n// ─── NodeIcon / NodeImage / NodeBadge / BadgePlacement ────────────────────\n\n/**\n * Vector inset rendered inside a node's body — glyph (font codepoint), SVG\n * path, or SVG by URL. Kept structured (discriminated union) because each\n * kind carries different required params.\n */\nexport type NodeIcon =\n | {\n readonly kind: 'glyph';\n readonly char: string;\n readonly fontFamily?: string;\n readonly fontWeight?: number | string;\n readonly fontStyle?: 'normal' | 'italic';\n readonly color?: number;\n readonly alpha?: number;\n readonly sizeRatio?: number;\n readonly anchor?: InsetAnchor;\n }\n | {\n readonly kind: 'svg';\n readonly pathD: string;\n readonly viewBox?: { readonly width: number; readonly height: number };\n readonly strokeWidth?: number;\n readonly color?: number;\n readonly alpha?: number;\n readonly sizeRatio?: number;\n readonly anchor?: InsetAnchor;\n }\n | {\n readonly kind: 'svg-url';\n readonly url: string;\n readonly viewBox?: { readonly width: number; readonly height: number };\n readonly strokeWidth?: number;\n readonly color?: number;\n readonly alpha?: number;\n readonly sizeRatio?: number;\n readonly anchor?: InsetAnchor;\n };\n\n/**\n * Raster image attached to a node. Mirrors the canvas-level `kind: 'image'`\n * `ShapeFillLayer` field-for-field. Two orthogonal sizing knobs:\n *\n * - `fit` (default `'cover'`) — `'cover'` scales by `max(...)` and fully\n * covers the silhouette's AABB (may crop on the cross-axis);\n * `'contain'` scales by `min(...)` and fully fits, leaving the\n * cross-axis margin transparent (the underlying `bgFill` reads\n * through; the texture sampler is pinned to `clamp-to-edge` so the\n * margin doesn't tile).\n * - `padding` (default `0`) — pixel inset on the silhouette before fit\n * math runs. The silhouette is re-traced at that inset for the image\n * layer only, so the gap between full and inset silhouette paints\n * from layers underneath (typically a `solid` `bgFill`). Useful when\n * the host silhouette is more restrictive than its AABB (circle,\n * polygon, star, arc) and texture corners would otherwise clip\n * against the curve.\n */\nexport interface NodeImage {\n readonly url: string;\n readonly alpha?: number;\n readonly fit?: 'cover' | 'contain';\n readonly padding?: number;\n}\n\n/**\n * Anchor point on the host node where a badge attaches. The eight cardinal\n * names address the midpoints / corners of the host's axis-aligned bounding\n * box; the `{ x, y }` variant pins to an explicit world point and is rarely\n * needed (use {@link NodeBadge.offsetX} / `offsetY` to nudge an enum anchor\n * before reaching for raw coordinates).\n */\nexport type BadgePlacement =\n | 'top-right'\n | 'top-left'\n | 'bottom-right'\n | 'bottom-left'\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | { readonly x: number; readonly y: number };\n\n/**\n * Point on the badge's own AABB that lands at the host anchor.\n *\n * - The eight cardinal names mirror {@link BadgePlacement} (without the\n * custom `{x, y}` variant — origin is always a named point on the badge).\n * - `'center'` centres the badge on the host anchor — yields the classic\n * \"half-overhanging\" notification-bubble look.\n *\n * When omitted, the projection defaults to the **mirror** of `placement`\n * (e.g. `placement: 'top-right'` → origin `'bottom-left'`) so the badge\n * sits fully outside the host edge.\n */\nexport type BadgeOrigin =\n | 'top-right'\n | 'top-left'\n | 'bottom-right'\n | 'bottom-left'\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'center';\n\n/**\n * Host-modulation effects on a badge. Re-exports the {@link NodeEffects}\n * surface because a badge is rendered as a shape under the hood — the same\n * `shake` / `breathing` / future shape-effect kinds apply field-for-field.\n */\nexport type BadgeEffects = NodeEffects;\n\n/**\n * Small overlay attached to a node — e.g. notification dot, count chip,\n * status indicator. A badge is rendered as a real shape, so it inherits the\n * full shape surface: any registered {@link NodeShapeOptions} kind as the\n * plate, optional {@link NodeIcon} as content, optional label text, plus\n * nested {@link decorations} / {@link effects} that compose exactly the way\n * they do on a node body.\n *\n * Position resolves from the host's AABB + the `placement` anchor + an\n * `origin` (which point of the badge sits at the anchor — defaults to the\n * mirror of `placement` so the badge nests fully outside the host edge).\n * Use `'center'` for the half-overhanging notification-bubble look.\n */\nexport interface NodeBadge {\n /**\n * Stable id within the node, for keyed updates / state-overlay diffing.\n * When omitted, identity falls back to the badge's position in the\n * containing `badges[]` array.\n */\n readonly id?: string;\n\n /** Anchor point on the host node's AABB, or an explicit world point. */\n readonly placement: BadgePlacement;\n\n /**\n * Which point of the badge's own AABB lands at the host anchor.\n * Default: mirror of `placement` (badge sits fully outside the host edge).\n * Use `'center'` for the half-overhanging look.\n */\n readonly origin?: BadgeOrigin;\n\n /**\n * Pure geometry — any registered {@link NodeShapeOptions} kind. Fill /\n * stroke / alpha come from the flat sugar fields below, mirroring the\n * `NodeStyle.shape` + `bgFill` split used for node bodies.\n */\n readonly shape: NodeShapeOptions;\n\n /** Solid plate colour — projects to the badge shape's first fill layer. */\n readonly fill?: number;\n readonly alpha?: number;\n readonly strokeColor?: number;\n readonly strokeWidth?: number;\n\n /**\n * Vector inset rendered inside the badge plate (glyph / svg / svg-url).\n * Projects to an extra fill layer stacked on top of the solid plate.\n */\n readonly icon?: NodeIcon;\n\n /**\n * Optional short text rendered centred on the badge (count \"3\", \"!\").\n * Projects to a `'label'` decoration on the badge.\n */\n readonly labelText?: string;\n readonly labelColor?: number;\n readonly labelFontSize?: number;\n\n /** Pixel offset applied after placement resolution. */\n readonly offsetX?: number;\n readonly offsetY?: number;\n\n readonly zIndex?: number;\n\n /**\n * Decorations attached to the badge plate. Each entry is a regular\n * {@link NodeDecorationSpec} — glow, ring, marching-ants, pulse-ring, etc.\n * Identity / merge rules match {@link NodeStyle.decorations} (id-keyed,\n * `remove: true` drops earlier same-id entries from base under a state\n * overlay).\n */\n readonly decorations?: readonly NodeDecorationSpec[];\n\n /**\n * Effects modulating the badge plate's transform / style each frame\n * (`shake`, `breathing`, …). Same surface as {@link NodeStyle.effects}.\n */\n readonly effects?: BadgeEffects;\n}\n\n/**\n * Anchor point along an edge's routed path.\n *\n * - `'start'` / `'end'` — anchored *near* the source / target endpoint with\n * automatic clearance: the badge is shifted tangentially by its own\n * half-extent so it kisses the endpoint node's silhouette from outside\n * rather than half-overlapping it. The natural choice for endpoint\n * chips, status icons, etc.\n * - `'middle'` — exact arc-length midpoint (`t = 0.5`).\n * - A `number` in `[0, 1]` — raw arc-length `t`, no clearance applied.\n * Use `placement: 1` when you explicitly want a badge centred on the\n * silhouette point. Values outside `[0, 1]` are clamped.\n *\n * `'middle'` (not `'center'`) avoids term-clashing with `BadgeOrigin`\n * where `'center'` means \"centre the badge on its own AABB\".\n */\nexport type EdgeBadgePlacement = 'start' | 'middle' | 'end' | number;\n\n/**\n * Small overlay attached to an edge — e.g. flow-rate chip on the midpoint,\n * count badge at the source endpoint, arrow-tag at the target. A badge is\n * rendered as a real shape (any registered {@link NodeShapeOptions} kind);\n * placement is parametric along the routed path.\n *\n * Position resolves via `samplePathAt(path, t)` so the badge re-anchors\n * automatically when the path changes (source / target shape moves, anchor\n * / router / waypoints change). For loop edges, `'middle'` naturally lands\n * on the loop apex because the path passes through it at `t ≈ 0.5`.\n *\n * Decorations and effects compose exactly the way they do on\n * {@link NodeBadge}; the badge being shape-rendered means shape decorations\n * (`glow`, `ring`, `marching-ants`, `pulse-ring`, …) apply uniformly.\n */\nexport interface EdgeBadge {\n /**\n * Stable id within the edge, for keyed updates / state-overlay diffing.\n * When omitted, identity falls back to the badge's position in the\n * containing `badges[]` array.\n */\n readonly id?: string;\n\n /** Where along the routed path the badge attaches. */\n readonly placement: EdgeBadgePlacement;\n\n /**\n * Which point of the badge's own AABB lands at the path anchor.\n * Default for edge badges is `'center'` — the badge centres on the path\n * point. Use other origins to lift the badge off the line (e.g.\n * `origin: 'bottom'` puts the badge above the line with its bottom edge\n * touching the path).\n */\n readonly origin?: BadgeOrigin;\n\n /**\n * Pure geometry — any registered {@link NodeShapeOptions} kind. Fill /\n * stroke / alpha come from the flat sugar fields below, mirroring the\n * `NodeStyle.shape` + `bgFill` split used for node bodies.\n */\n readonly shape: NodeShapeOptions;\n\n /** Solid plate colour — projects to the badge shape's first fill layer. */\n readonly fill?: number;\n readonly alpha?: number;\n readonly strokeColor?: number;\n readonly strokeWidth?: number;\n\n /**\n * Vector inset rendered inside the badge plate (glyph / svg / svg-url).\n * Projects to an extra fill layer stacked on top of the solid plate.\n */\n readonly icon?: NodeIcon;\n\n /**\n * Optional short text rendered centred on the badge (count \"3\", \"!\").\n * Projects to a `'label'` decoration on the badge.\n */\n readonly labelText?: string;\n readonly labelColor?: number;\n readonly labelFontSize?: number;\n\n /**\n * Shift the path-anchor along the local tangent (positive = forward\n * toward `'end'`, negative = backward toward `'start'`). Useful for\n * nudging a `'middle'`-anchored badge sideways without changing `t`.\n */\n readonly pathOffset?: number;\n\n /** Pixel offset applied after placement resolution. */\n readonly offsetX?: number;\n readonly offsetY?: number;\n\n /**\n * When `true`, the badge rotates to follow the path tangent at the\n * anchor point. Default `false` (badges stay axis-aligned). Useful for\n * arrow-shaped or directional badges on curved edges.\n */\n readonly autoRotate?: boolean;\n\n /**\n * When {@link autoRotate} is `true`, flip the badge by 180° on the\n * \"downward\" half of the path so text decorations stay readable on\n * every edge orientation. Default `true`. Ignored when `autoRotate` is\n * `false`.\n */\n readonly keepUpright?: boolean;\n\n readonly zIndex?: number;\n\n /**\n * Decorations attached to the badge plate. Same surface as\n * {@link NodeBadge.decorations} — shape decorations (`glow`, `ring`,\n * `marching-ants`, `pulse-ring`) apply because the badge is itself a\n * shape, regardless of being hosted on a connector.\n */\n readonly decorations?: readonly NodeDecorationSpec[];\n\n /**\n * Effects modulating the badge plate's transform / style each frame\n * (`shake`, `breathing`, …). Same surface as\n * {@link NodeBadge.effects}.\n */\n readonly effects?: BadgeEffects;\n}\n\n// ─── NodeDecorationSpec / EdgeDecorationSpec / NodeEffects ────────────────\n\n/**\n * Common fields on every entry in a `decorations[]` array. The `id` gives\n * stable diff identity (state overlays can re-declare the same id to\n * override, or set `remove: true` to drop a base-level decoration while a\n * state is active). When `id` is absent, identity falls back to `kind + array index`.\n */\nexport interface DecorationSpecCommon {\n /** Stable id for diffing. Optional — falls back to `kind#<index>` when absent. */\n readonly id?: string;\n /**\n * When `true`, this entry instructs the resolver to drop any earlier-\n * precedence decoration with the same `id`. Use it in a state overlay to\n * temporarily remove a base-level decoration while the state is active.\n */\n readonly remove?: boolean;\n}\n\n/**\n * Discriminated union of decoration specs attachable to a node via\n * {@link NodeStyle.decorations}. Each variant pairs `kind` (the registered\n * canvas decoration name) with the matching style payload from\n * `@invana/canvas/primitives`.\n *\n * Multiples are allowed — the same kind can appear several times (e.g. an\n * inner + outer ring on a single node), as long as their `id`s differ.\n * `label` is intentionally absent — labels are managed by the flat\n * `labelText` / `label*` fields on `NodeStyle`, not by the decorations\n * array.\n */\nexport type NodeDecorationSpec =\n | (DecorationSpecCommon & { readonly kind: 'ring' } & RingDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'glow' } & GlowDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'pulse-ring' } & PulseRingDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'marching-ants' } & MarchingAntsDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'liquid-fill' } & LiquidFillDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'toggle' } & ToggleDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'resize-handle' } & ResizeHandleDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'selection-frame' } & SelectionFrameDecorationStyle);\n\n/**\n * Discriminated union of decoration specs attachable to an edge via\n * {@link EdgeStyle.decorations}. Mirrors {@link NodeDecorationSpec} for\n * the connector-target decoration registry. `label-connector` is excluded\n * for the same reason `label` is — labels live on the flat label fields.\n */\nexport type EdgeDecorationSpec =\n | (DecorationSpecCommon & { readonly kind: 'ring-connector' } & RingConnectorDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'glow-connector' } & GlowConnectorDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'marching-ants-connector' } & MarchingAntsConnectorDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'ripple-connector' } & RippleConnectorDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'fly-marker-connector' } & FlyMarkerConnectorDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'flow-particles-connector' } & FlowParticlesConnectorDecorationStyle)\n | (DecorationSpecCommon & { readonly kind: 'reveal-connector' } & RevealConnectorDecorationStyle);\n\n/**\n * Host-modulation effects (sibling of decorations). Effects don't add\n * geometry — they modulate the host's transform (`shake`, `breathing`) or\n * style channels (tint/alpha). One spec per kind.\n */\nexport interface NodeEffects {\n readonly shake?: unknown | null;\n readonly breathing?: unknown | null;\n readonly [kind: string]: unknown | null | undefined;\n}\n\n// ─── GroupOptions ──────────────────────────────────────────────────────────\n\n/**\n * Marks a node as a **compound group** — a visual frame drawn behind its\n * descendants (children point to it via `parentId`). The presence of this\n * field on a node's resolved {@link NodeStyle} is the only signal the layer\n * uses to decide whether to apply group semantics; the structural shape\n * (`style.shape`) stays a regular `rect` / `circle` / etc.\n *\n * Group semantics, in summary:\n *\n * - **Expanded state** (`collapsed !== true`):\n * - The node renders behind its children (z-index pushed underneath when\n * `behindChildren !== false`) and is **non-hittable** — pointer events\n * pass through the frame to the canvas background. The frame is a pure\n * drawing, not an interactive node.\n * - With `autoFit: true`, the layer recomputes `width` / `height` (rect)\n * or `radius` (circle) every flush from the children's bounding box,\n * plus `padding` and optional `headerHeight`. The declared `width` /\n * `height` / `radius` fields act as a **lower bound** in this mode.\n * - With `autoFit: false`, the layer uses the declared `width` / `height`\n * / `radius` literally; children may visually leak outside.\n *\n * - **Collapsed state** (`collapsed === true`):\n * - The node renders as a normal interactive node (`hittable: true`,\n * default z-order). All descendants are hidden from the renderer; edges\n * pointing at a hidden descendant are re-routed to the nearest visible\n * collapsed-group ancestor at render time (no mutation to the edge data).\n * - The layer synthesises a count badge showing the number of hidden\n * descendants. The `+`/`−` toggle is rendered via the\n * {@link ToggleDecorationStyle} decoration on the group — wire up\n * `CollapseExpandBehaviour` to make the toggle clickable.\n *\n * Nested groups fall out of the `parentId` chain for free: a group node\n * whose own `parentId` points at another group becomes a sub-group; the\n * recompute walks deepest-first.\n *\n * Membership uses the existing `GraphNode.parentId` (single hierarchy field\n * shared with tree structures) — no separate group-membership concept.\n */\nexport interface GroupOptions {\n /**\n * When `true`, the frame's size tracks the bounding box of its direct\n * children (computed every flush). When `false`, the declared `width` /\n * `height` / `radius` are used verbatim. Default `false`.\n */\n readonly autoFit?: boolean;\n /**\n * When `true`, `GroupResizeBehaviour` mounts corner / radial handle\n * decorations on this group and lets the user drag to resize. Composes\n * with `autoFit` per the floor rule on `width` / `height` / `radius`.\n * Default `false`.\n */\n readonly userResizable?: boolean;\n /** Inset around the children bbox before the frame outline. Default `16`. */\n readonly padding?: number;\n /**\n * True = render the group as a collapsed super-node (children hidden,\n * +/- toggle shows `+`, count badge shows the hidden descendant count).\n * Toggle through `CollapseExpandBehaviour` or by updating this field\n * directly via `store.updateNode`. Default `false`.\n */\n readonly collapsed?: boolean;\n /**\n * Frame renders at `style.zIndex − 1` so descendants paint on top. Set to\n * `false` to keep the frame at its declared z-index (and let descendants\n * paint underneath when their z-index is lower). Default `true`.\n */\n readonly behindChildren?: boolean;\n /**\n * Optional header band height (px) added above the children bbox. The\n * frame still draws as a single rect / circle — `headerHeight` only\n * shifts the auto-fit recompute so the label area at the top stays clear\n * of children. Default `0`.\n */\n readonly headerHeight?: number;\n /**\n * Floor (with `autoFit`) or fixed (without) width. Rect frames only.\n * Ignored for circle frames.\n */\n readonly width?: number;\n /** Sibling of {@link width} for `kind: 'rect'`. */\n readonly height?: number;\n /**\n * Floor (with `autoFit`) or fixed (without) radius. Circle frames only.\n * Ignored for rect frames.\n */\n readonly radius?: number;\n /**\n * Where the auto-attached `+` / `−` toggle sits relative to the group's\n * frame. Two forms:\n *\n * - **Keyword** — one of the {@link TogglePlacement} aliases\n * (`'bottom'`, `'inside-bottom'`, `'top-right'`, `'bottom-left'`, …).\n * Resolved against the host's AABB by the toggle decoration.\n * - **Shape-local coords** — `{ x, y }`, an absolute point inside the\n * host shape's local frame (centre-relative for `circle`, top-left-\n * relative for `rect`). Use this when none of the keywords place the\n * toggle where you want it (diagonal offsets, mock-specific spots).\n *\n * Default `'bottom'` — centred just below the silhouette, matching the\n * \"small bubble attached to the rim\" pattern in the reference UI.\n * Clicks are dispatched at the canvas level by `CollapseExpandBehaviour`,\n * so the toggle remains clickable regardless of whether the resolved\n * position falls inside or outside the host's hit area.\n */\n readonly togglePlacement?: TogglePlacement | { readonly x: number; readonly y: number };\n}\n\n// ─── NodeStyle ─────────────────────────────────────────────────────────────\n\n/**\n * Visual + structural style for a node. Flat-prefixed scalars for orthogonal\n * properties (`bgFill`, `bgStrokeWidth`, `labelColor`); polymorphic values\n * kept structured (`shape`, `icon`, `image`, `decorations`, `effects`,\n * `badges`).\n *\n * Per-instance state overlays for a node live at {@link NodeData.state}\n * (a sibling of `style`), NOT inside `NodeStyle`.\n */\nexport interface NodeStyle {\n // ===== Structural geometry =====\n readonly shape?: NodeShapeOptions;\n\n /**\n * Unified normalized size. When set, overrides the resolved `shape`'s\n * intrinsic size fields at style-resolution time (before the spec reaches\n * the renderer, `boundsOfNode`, or any layout's bounds query). Per-kind\n * mapping:\n *\n * - `circle` / `regular-polygon` — `shape.radius = size`\n * - `rect` — `shape.width = shape.height = 2 * size`\n * - `arc` — `shape.outerR = size` (and `shape.innerR` scaled so its ratio\n * to `outerR` is preserved)\n * - `star` — `shape.outerRadius = size` (and `shape.innerRadius` scaled to\n * preserve its ratio)\n * - `polygon` / custom — no canonical size axis; `size` is ignored\n *\n * Honoured uniformly by `boundsOfNode`, `D3ForceLayout` (collide.radius\n * receives the `GraphNode` and reads the normalized `shape.radius` via\n * `resolveNodeStyle`), and `ElkLayout` (reads bounds via `boundsOfNode`).\n * Use this when a single number should drive a node's footprint regardless\n * of which shape kind it renders as — e.g. degree-based sizing,\n * data-driven scaling.\n */\n readonly size?: number;\n\n /**\n * Marks this node as a compound group (visual frame drawn behind its\n * descendants). See {@link GroupOptions} for the full contract — autoFit\n * vs userResizable, expanded vs collapsed semantics, header band, edge\n * re-routing.\n *\n * Presence of this field is the only discriminator. The structural shape\n * (`shape: { kind: 'rect' | 'circle' }`) is unchanged; groups reuse the\n * same primitives as regular nodes.\n */\n readonly group?: GroupOptions;\n\n /**\n * When `true`, `NodeResizeBehaviour` mounts corner-handle decorations on\n * this node (rect / circle only) and lets the user drag to resize. The\n * drag writes back to `style.shape.width` / `height` / `radius` directly\n * (and `position` for non-corner-anchored rect drags). Independent from\n * `style.group?.userResizable`, which targets group frames specifically\n * — but both are honoured by the same behaviour, so a single registered\n * `NodeResizeBehaviour` handles every resizable node in the layer.\n */\n readonly resizable?: boolean;\n\n // ===== Background paint =====\n /**\n * Accepts every `ShapeFillLayer` kind — `solid` / `image` / `glyph` /\n * `svg` / `svg-url` — and arrays for stacked layers. The `image` kind\n * doubles as silhouette filler and inset content via its `fit` field\n * (`'inset'` vs the silhouette modes).\n */\n readonly bgFill?: ShapeFill;\n readonly bgAlpha?: number;\n readonly bgStrokeColor?: number;\n readonly bgStrokeAlpha?: number;\n readonly bgStrokeWidth?: number;\n readonly bgStrokeAlignment?: 'inside' | 'center' | 'outside';\n readonly bgStrokeDashArray?: readonly [number, number];\n readonly bgStrokeDashOffset?: number;\n readonly bgStrokeCap?: 'butt' | 'round' | 'square';\n readonly bgStrokeJoin?: 'miter' | 'round' | 'bevel';\n\n // ===== Icon / image insets =====\n readonly icon?: NodeIcon;\n readonly image?: NodeImage;\n\n // ===== Label =====\n readonly labelText?: string;\n readonly labelColor?: number;\n readonly labelFontSize?: number;\n readonly labelFontFamily?: string;\n readonly labelFontWeight?: number | string;\n readonly labelFontStyle?: 'normal' | 'italic';\n readonly labelAlign?: 'left' | 'center' | 'right';\n readonly labelLineHeight?: number;\n readonly labelLetterSpacing?: number;\n readonly labelPlacement?: ShapeLabelPlacement;\n readonly labelOffsetX?: number;\n readonly labelOffsetY?: number;\n readonly labelAlpha?: number;\n readonly labelMinFontSize?: number;\n /** Radians. */\n readonly labelRotation?: number;\n\n // ===== Label resolution / LOD / collision =====\n /** Hide the label below this camera zoom level. */\n readonly labelMinZoom?: number;\n /** Hide the label above this camera zoom level. */\n readonly labelMaxZoom?: number;\n /** Collision priority — higher wins when two labels overlap. */\n readonly labelPriority?: number;\n /** Collision partition — labels in different groups never compete. */\n readonly labelCollisionGroup?: string;\n /** Bypass collision entirely — label always renders. */\n readonly labelForceShow?: boolean;\n\n // Label background (flattened from ShapeLabelStyle.background)\n readonly labelBackgroundFill?: number;\n readonly labelBackgroundAlpha?: number;\n readonly labelBackgroundStrokeColor?: number;\n readonly labelBackgroundStrokeWidth?: number;\n readonly labelBackgroundPadding?: number;\n readonly labelBackgroundCornerRadius?: number;\n\n /**\n * Escape hatch — full `ShapeLabelStyle` payload from `@invana/canvas`.\n * Use this when the flat `label*` fields don't cover the case (wrap,\n * html-text content, custom collision settings, etc.). When set, the\n * adapter uses this payload verbatim instead of building one from the\n * flat fields. Flat label fields are ignored on the same node.\n */\n readonly labelStyle?: ShapeLabelStyle;\n\n // ===== Badges (multiple) =====\n readonly badges?: readonly NodeBadge[];\n\n // ===== Decorations (array of discriminated specs) =====\n /**\n * Ordered list of decorations attached to the node. Each entry's `kind`\n * names a registered canvas decoration; the rest of the entry is that\n * decoration's style payload. See {@link NodeDecorationSpec}.\n *\n * The resolver concatenates this array across base style + every active\n * state's overlay, then dedupes by `id` (later precedence wins). Use\n * `remove: true` in a higher-precedence overlay to drop an earlier entry\n * with the same id while a state is active.\n */\n readonly decorations?: readonly NodeDecorationSpec[];\n\n // ===== Effects (slot dict) — see NodeEffects =====\n readonly effects?: NodeEffects;\n}\n\n/**\n * Resolver-aware mirror of {@link NodeStyle}. Each field is either a static\n * value or `(D) => T`. Two scopes use this generic at different `D`:\n *\n * - `NodeInput<D>.style` — resolvers fire at insert (`D` = raw node data).\n * - `NodeOption.style` — resolvers fire at render (`D` = stored `GraphNode`).\n */\nexport type ResolvableNodeStyle<D = unknown> = {\n readonly [K in keyof NodeStyle]?: Resolvable<NonNullable<NodeStyle[K]>, D>;\n};\n\n// ─── NodeData / NodeInput / NodeOption ─────────────────────────────────────\n\n/**\n * Per-instance node descriptor as stored by `GraphStore`. All values\n * concrete (no functions). Flat field layout matching G6's `NodeData`\n * convention.\n *\n * - `state` (singular) = per-instance overlay catalogue.\n * - `states` (plural) = currently-active state names.\n */\nexport interface NodeData<D = unknown> {\n readonly id: string;\n /** Type tag (free-form). Matches a `NodeOption` template if any. */\n readonly type?: string;\n readonly data?: D;\n readonly style?: NodeStyle;\n /** Per-instance overlay catalogue (singular `state`). */\n readonly state?: Readonly<Record<string, NodeStyle>>;\n /** Currently-active state names (plural `states`). */\n readonly states?: readonly string[] | null;\n // store-side concerns:\n readonly position?: { readonly x: number; readonly y: number };\n readonly pinned?: boolean;\n /**\n * Logical parent id — the only hierarchy field. Use this for both tree\n * structures AND group/combo membership (the parent is just a regular\n * node that visually represents the group). The store auto-maintains an\n * inverse index, queryable via `store.childrenOf(id)` /\n * `store.descendantsOf(id)`.\n */\n readonly parentId?: string;\n}\n\n/**\n * What the consumer passes to `GraphLayer.setData`. Same shape as\n * {@link NodeData} but with Resolvable fields — `id` and per-field styles\n * may be functions over `data`. Resolvers fire once at insert; the store\n * holds `NodeData`.\n */\nexport interface NodeInput<D = unknown> {\n readonly id?: ResolvableId<D>;\n readonly type?: string;\n readonly data?: D;\n readonly style?: ResolvableNodeStyle<D>;\n readonly state?: Readonly<Record<string, ResolvableNodeStyle<D>>>;\n readonly states?: readonly string[];\n readonly position?: { readonly x: number; readonly y: number };\n readonly pinned?: boolean;\n readonly parentId?: string;\n}\n\n/**\n * Layer-level node template — G6's `node` field on GraphOptions. Resolvers\n * fire every frame against the stored `GraphNode`.\n *\n * No `animation` field — per [[feedback_decoration_vs_animation]], animation\n * is the per-frame engine, not a node-level config. Decoration / effect\n * attachments live on `NodeStyle.decorations` / `NodeStyle.effects`.\n */\nexport interface NodeOption {\n /** Type tag this template defines (e.g. 'person', 'doc'). Optional. */\n readonly type?: string;\n readonly style?: ResolvableNodeStyle<GraphNode>;\n readonly state?: Readonly<Record<string, ResolvableNodeStyle<GraphNode>>>;\n /** Reserved for palette-driven theming. Deferred wiring. */\n readonly palette?: unknown;\n}\n\n// ─── Edge mirror ───────────────────────────────────────────────────────────\n\n/** Arrowhead shape catalogue. */\nexport type ArrowShape = 'triangle' | 'diamond' | 'circle' | 'none';\n\n/**\n * Structural variant of an edge — the three-stage connector pipeline\n * (anchor → router → pathStyle). Variant-specific params live inside\n * `pathStyleOpts`, so this stays non-discriminated.\n */\nexport interface EdgeShapeOptions {\n readonly pathType?: EdgePathType;\n readonly sourceAnchor?: EdgeAnchor;\n readonly targetAnchor?: EdgeAnchor;\n readonly sourceAnchorOpts?: Readonly<Record<string, unknown>>;\n readonly targetAnchorOpts?: Readonly<Record<string, unknown>>;\n readonly pathStyleOpts?: Readonly<Record<string, unknown>>;\n readonly waypoints?: ReadonlyArray<{ readonly x: number; readonly y: number }>;\n}\n\n/**\n * Flat-prefixed style bag for an edge. Edges have one stroke (the path), so\n * stroke fields are unprefixed. Arrow ends and label keep their distinct\n * prefixes.\n */\nexport interface EdgeStyle {\n // ===== Structural =====\n readonly shape?: EdgeShapeOptions;\n\n // ===== Path stroke =====\n readonly strokeColor?: number;\n readonly strokeAlpha?: number;\n readonly strokeWidth?: number;\n readonly strokeAlignment?: 'inside' | 'center' | 'outside';\n readonly strokeDashArray?: readonly [number, number];\n readonly strokeDashOffset?: number;\n readonly strokeCap?: 'butt' | 'round' | 'square';\n readonly strokeJoin?: 'miter' | 'round' | 'bevel';\n\n // ===== Arrows (two ends — flat prefix per end) =====\n readonly arrowSourceShape?: ArrowShape;\n readonly arrowSourceSize?: number;\n readonly arrowSourceColor?: number;\n readonly arrowSourceAlpha?: number;\n readonly arrowTargetShape?: ArrowShape;\n readonly arrowTargetSize?: number;\n readonly arrowTargetColor?: number;\n readonly arrowTargetAlpha?: number;\n\n // ===== Label =====\n readonly labelText?: string;\n readonly labelColor?: number;\n readonly labelFontSize?: number;\n readonly labelFontFamily?: string;\n readonly labelFontWeight?: number | string;\n readonly labelFontStyle?: 'normal' | 'italic';\n readonly labelAlign?: 'left' | 'center' | 'right';\n readonly labelLineHeight?: number;\n readonly labelLetterSpacing?: number;\n readonly labelPlacement?: ConnectorLabelPlacement;\n readonly labelPathOffset?: number;\n readonly labelAutoRotate?: boolean;\n readonly labelKeepUpright?: boolean;\n readonly labelOffsetX?: number;\n readonly labelOffsetY?: number;\n readonly labelAlpha?: number;\n readonly labelMinFontSize?: number;\n\n // ===== Label resolution / LOD / collision =====\n /** Hide the label below this camera zoom level. */\n readonly labelMinZoom?: number;\n /** Hide the label above this camera zoom level. */\n readonly labelMaxZoom?: number;\n /** Collision priority — higher wins when two labels overlap. */\n readonly labelPriority?: number;\n /** Collision partition — labels in different groups never compete. */\n readonly labelCollisionGroup?: string;\n /** Bypass collision entirely — label always renders. */\n readonly labelForceShow?: boolean;\n readonly labelBackgroundFill?: number;\n readonly labelBackgroundAlpha?: number;\n readonly labelBackgroundStrokeColor?: number;\n readonly labelBackgroundStrokeWidth?: number;\n readonly labelBackgroundPadding?: number;\n readonly labelBackgroundCornerRadius?: number;\n\n /**\n * Escape hatch — full `ConnectorLabelStyle` payload from `@invana/canvas`.\n * Use this when the flat `label*` fields don't cover the case (wrap,\n * html-text content, etc.). When set, the adapter uses this payload\n * verbatim instead of building one from the flat fields.\n */\n readonly labelStyle?: ConnectorLabelStyle;\n\n // ===== Decorations (array of discriminated specs) =====\n /**\n * Ordered list of decorations attached to the edge. Each entry's `kind`\n * names a registered canvas connector-decoration; the rest is that\n * decoration's style payload. See {@link EdgeDecorationSpec}.\n *\n * Resolver semantics match {@link NodeStyle.decorations}: concatenate\n * across base + active state overlays, dedupe by `id`, later precedence\n * wins.\n */\n readonly decorations?: readonly EdgeDecorationSpec[];\n\n // ===== Badges (multiple, along the routed path) =====\n /**\n * Ordered list of badges attached to the edge. Each entry is a real\n * {@link EdgeBadge} — any registered shape kind as the plate, optional\n * icon / labelText sugar, optional nested decorations and effects.\n * Placement is parametric along the routed path (`'start' | 'middle' |\n * 'end' | number`) and re-anchors automatically when the path changes\n * (source / target shape moves, anchor / router / waypoints change).\n *\n * Resolver semantics match {@link decorations}: concatenate across base\n * + active state overlays, dedupe by `id`, later precedence wins.\n */\n readonly badges?: readonly EdgeBadge[];\n}\n\n/** Resolver-aware mirror of {@link EdgeStyle}; generic over the resolver argument. */\nexport type ResolvableEdgeStyle<D = unknown> = {\n readonly [K in keyof EdgeStyle]?: Resolvable<NonNullable<EdgeStyle[K]>, D>;\n};\n\n/** Per-instance edge descriptor — stored by GraphStore, concrete values. */\nexport interface EdgeData<D = unknown> {\n readonly id: string;\n readonly source: string;\n readonly target: string;\n /** Predicate / FK label. Free-form. G6 calls this `type`. */\n readonly type?: string;\n readonly data?: D;\n readonly style?: EdgeStyle;\n readonly state?: Readonly<Record<string, EdgeStyle>>;\n readonly states?: readonly string[] | null;\n}\n\n/** Resolver-aware input shape for an edge. */\nexport interface EdgeInput<D = unknown> {\n readonly id?: ResolvableId<D>;\n readonly source: string;\n readonly target: string;\n readonly type?: string;\n readonly data?: D;\n readonly style?: ResolvableEdgeStyle<D>;\n readonly state?: Readonly<Record<string, ResolvableEdgeStyle<D>>>;\n readonly states?: readonly string[];\n}\n\n/** Layer-level edge template — G6's `edge` field. */\nexport interface EdgeOption {\n readonly type?: string;\n readonly style?: ResolvableEdgeStyle<GraphEdge>;\n readonly state?: Readonly<Record<string, ResolvableEdgeStyle<GraphEdge>>>;\n readonly palette?: unknown;\n}\n\n// ─── Canonical state defaults ─────────────────────────────────────────────\n\n/**\n * Canonical node-state overlays auto-merged into every `GraphLayer`'s\n * `options.node.state` catalogue on construction (unless\n * `GraphLayerOptions.useDefaultStates: false`). Consumer-supplied\n * `options.node.state[name]` entries override individual fields per the\n * normal merge precedence; this map provides the resting visual identity\n * of each canonical state so a layer that touches no state code still\n * gets a sensible hover / select / error ring out of the box.\n *\n * All values are flat NodeStyle fields — extending or overriding is the\n * same shape as any other layer-template state overlay. Decorations are\n * intentionally not declared here so consumers compose them additively\n * (e.g. a ring decoration on hover) without colliding with the canonical\n * stroke treatment below.\n */\nexport const DEFAULT_NODE_STATES: Readonly<Record<CanonicalStateName, NodeStyle>> = {\n // Hovered — detached white ring sitting 2px outside the body. Real\n // decoration (not a stroke) so it composes cleanly with `selected`'s\n // own ring + halo when both states are active simultaneously.\n hovered: {\n decorations: [\n { kind: 'ring', id: 'canonical-hover-ring', color: 0xffffff, width: 3, gap: 5, alpha: 1 },\n ],\n },\n // Click-selected — sharp ring outside the body plus a soft halo for\n // extra prominence. Ring sits at `gap: 7` with `width: 3`; halo extends\n // a further ~10px outward with quadratic alpha falloff (built into\n // `glow`). `id`s scope the slots so per-layer overlays can swap or\n // remove either independently.\n selected: {\n decorations: [\n { kind: 'ring', id: 'canonical-select-ring', color: 0xfacc15, width: 3, gap: 7, alpha: 1 },\n { kind: 'glow', id: 'canonical-select-halo', color: 0xfacc15, strokeWidth: 30, innerAlpha: 0.4, layers: 4 },\n ],\n },\n highlighted: {\n decorations: [\n { kind: 'ring', id: 'canonical-hover-ring', color: 0xfde68a, width: 3, gap: 5, alpha: 1 },\n ],\n},\n dimmed: { bgAlpha: 0.25 },\n disabled: { bgFill: 0x9ca3af, bgAlpha: 0.6 },\n};\n\n/**\n * Canonical edge-state overlays — sibling of {@link DEFAULT_NODE_STATES}.\n * Auto-merged into every `GraphLayer`'s `options.edge.state` catalogue\n * unless `GraphLayerOptions.useDefaultStates: false`.\n */\nexport const DEFAULT_EDGE_STATES: Readonly<Record<CanonicalStateName, EdgeStyle>> = {\n hovered: { strokeColor: 0x111827, strokeWidth: 3 },\n selected: { strokeColor: 0xfacc15, strokeWidth: 3 },\n highlighted: { strokeColor: 0xfde68a, strokeWidth: 2 },\n dimmed: { strokeAlpha: 0.2 },\n disabled: { strokeColor: 0x9ca3af, strokeAlpha: 0.6, arrowTargetShape: 'none' },\n};\n\n// ─── GraphDataOptions ──────────────────────────────────────────────────────\n\n/**\n * Top-level data input shape for `GraphLayer.setData(opts)`. Carries node /\n * edge inputs plus optional layer-wide id resolvers.\n */\nexport interface GraphDataOptions<DN = unknown, DE = unknown> {\n readonly nodes: readonly NodeInput<DN>[];\n readonly edges: readonly EdgeInput<DE>[];\n /** Optional layer-wide id resolver applied to nodes that lack an explicit `id`. */\n readonly nodeIdResolver?: (data: DN) => string;\n readonly edgeIdResolver?: (data: DE) => string;\n}\n\n/** Constructor options for `GraphLayer`. */\nexport interface GraphLayerOptions {\n /**\n * Optional pre-built store. If omitted, the layer creates its own with\n * default options (`flushMode: 'sync'`, `unknownEndpoint: 'throw'`). Pass\n * a store you own to share data with other layers / sync code.\n */\n store?: import('../store/GraphStore').GraphStore;\n\n /**\n * Layer-level node template (G6's `node` field). Carries `style` (base\n * appearance) and `state` (catalogue of named overlays applied while a\n * state in `node.states[]` is active). Resolver-aware: every field on\n * `style` / each `state[name]` may be a static value or a function\n * `(node: GraphNode) => value` that fires every render.\n */\n node?: NodeOption;\n\n /** Sibling of {@link node} for edges. */\n edge?: EdgeOption;\n\n /**\n * Auto-merge {@link DEFAULT_NODE_STATES} / {@link DEFAULT_EDGE_STATES}\n * into `options.node.state` / `options.edge.state` on construction so\n * every canonical state has a sensible default appearance even when the\n * consumer supplied no state overlays. Consumer entries win on a\n * per-name basis (no per-field deep merge here — declare a full\n * `NodeStyle` if you want to replace a default entry). Default `true`.\n */\n useDefaultStates?: boolean;\n\n /**\n * Minimum hover/click target in screen pixels, forwarded to the\n * internal `PrimitivesRenderer`. Default `6`.\n *\n * Behaves as a *fallback*: exact geometric hits always win; only\n * when no shape contains the cursor does the dispatcher pick the\n * closest candidate within `hitFloorPx` screen pixels. See\n * `PrimitivesRendererOptions.hitFloorPx` for details.\n */\n hitFloorPx?: number;\n}\n\n/**\n * Layer-level event payloads (separate from store events). Pointer/drag/etc.\n * arrive in later phases; today this is just the aggregated lifecycle.\n */\nexport interface GraphLayerEvents {\n 'data:changed': {\n addedNodes: number;\n removedNodes: number;\n updatedNodes: number;\n addedEdges: number;\n removedEdges: number;\n updatedEdges: number;\n };\n 'positions:updated': { count: number };\n /**\n * A user-driven node drag began. Behaviours emitting this signal the\n * intent to hold a node's position against any physics / layout that\n * would otherwise move it. Layouts (e.g. `D3ForceLayout`) subscribe and\n * apply a *transient* lock — they MUST NOT mutate the store's\n * `GraphNode.pinned` flag in response, since that is reserved for\n * user-data semantics (permanent pin). The matching `node:drag-end`\n * releases the transient lock.\n *\n * `nodeId` is the *grabbed* node (the gesture's primary). `nodeIds` is the\n * full set of primary nodes being dragged together — `[nodeId]` for a plain\n * single-node drag, or every selected node for a multi-selection drag. Group\n * descendants are NOT listed here; consumers that care about them expand via\n * `store.descendantsOf(id)`.\n */\n 'node:drag-start': { nodeId: string; nodeIds: readonly string[] };\n 'node:drag-end': { nodeId: string; nodeIds: readonly string[] };\n [event: string]: unknown;\n}\n","/**\n * `GraphLayer` — `WorldLayer` subclass that renders a `GraphStore` via a\n * `PrimitivesRenderer`. Subscribes to store events and projects them into\n * `addShape` / `addConnector` / `updateShape` / `updateConnector` /\n * `removeShape` / `removeConnector` calls.\n *\n * The store is the source of truth. The layer is a thin projection — no\n * domain data lives here. Re-emits aggregated `data:changed` and\n * `positions:updated` events at the layer level for application code that\n * only cares about visible-graph changes.\n *\n * See `apps/docs/graph/data-model.md` for the data model and\n * `apps/docs/graph/events.md` for the event model.\n */\n\nimport { PrimitivesRenderer, WorldLayer } from '@invana/canvas';\nimport type {\n BaseConnectorSpec,\n BaseShapeSpec,\n CanvasContext,\n ConnectorLabelStyle,\n LayerOptions,\n ShapeLabelStyle,\n WorldLayerHit,\n} from '@invana/canvas';\nimport type {\n BadgeOptions,\n DecorationSpec,\n EffectSpec,\n Rect,\n ShapeFillLayer,\n} from '@invana/canvas/primitives';\n\nimport { GraphStore } from '../store/GraphStore';\nimport type { EdgeDirection, GraphEdge, GraphNode } from '../store/types';\n\nimport {\n DEFAULT_EDGE_STATES,\n DEFAULT_NODE_STATES,\n resolveField,\n type EdgeAnchor,\n type EdgeBadge,\n type EdgeDecorationSpec,\n type EdgeOption,\n type EdgePathType,\n type EdgeStyle,\n type GraphData,\n type GraphLayerEvents,\n type GraphLayerOptions,\n type GroupOptions,\n type NodeBadge,\n type NodeDecorationSpec,\n type NodeOption,\n type NodeShapeOptions,\n type NodeStyle,\n type ArcShapeOption,\n type CircleShapeOption,\n type RectShapeOption,\n type RegularPolygonShapeOption,\n type StarShapeOption,\n type ResolvableEdgeStyle,\n type ResolvableNodeStyle,\n} from './types';\n\n/**\n * Translate a {@link EdgePathType} shortcut into the canvas `router` +\n * `pathStyle` pair the renderer understands.\n */\nfunction pathTypeToRouterPathStyle(t: EdgePathType): { router: string; pathStyle: string } {\n switch (t) {\n case 'straight':\n return { router: 'straight', pathStyle: 'normal' };\n case 'bezier':\n return { router: 'straight', pathStyle: 'bezier' };\n case 'quadratic':\n return { router: 'straight', pathStyle: 'quadratic' };\n case 'bump-radial':\n return { router: 'straight', pathStyle: 'bump-radial' };\n case 'bump-horizontal':\n return { router: 'straight', pathStyle: 'bump-horizontal' };\n case 'step-radial':\n return { router: 'straight', pathStyle: 'step-radial' };\n case 'orth':\n return { router: 'orth', pathStyle: 'normal' };\n case 'manhattan':\n return { router: 'manhattan', pathStyle: 'normal' };\n case 'rounded':\n return { router: 'orth', pathStyle: 'rounded' };\n case 'smooth':\n return { router: 'orth', pathStyle: 'smooth' };\n case 'bundle':\n // The bundle curve consumes the polyline literally — including all\n // intermediate `waypoints` — so it has to pair with `straight`, the\n // only router that passes waypoints through unaltered.\n return { router: 'straight', pathStyle: 'bundle' };\n case 'loop-curve':\n case 'loop-polyline':\n // Self-loop styles: source and target reference the same shape, so\n // the anchor/router stage emits a degenerate two-coincident-point\n // polyline. The pathStyle generates the loop geometry from its own\n // opts; `straight` is the cheapest pass-through router.\n return { router: 'straight', pathStyle: t };\n }\n}\n\n// ─── State (none for now) ──────────────────────────────────────────────────\n\ninterface GraphLayerState {\n /** Reserved for hover / selection / decoration state in later phases. */\n readonly _placeholder?: never;\n}\n\n// ─── GraphLayer ────────────────────────────────────────────────────────────\n\nexport class GraphLayer extends WorldLayer<\n GraphLayerOptions,\n GraphLayerState,\n GraphLayerEvents,\n never,\n WorldLayerHit\n> {\n /**\n * Pixi-backed primitives renderer; created in `onMount`.\n *\n * Public so behaviours can subscribe to `shape:*` / `connector:*` pointer\n * events on `graph.getRenderer().events`. Returns `undefined` before mount.\n */\n private _renderer?: PrimitivesRenderer;\n\n /** Renderer accessor for behaviours. Undefined before `onMount`. */\n getRenderer(): PrimitivesRenderer | undefined {\n return this._renderer;\n }\n\n /**\n * Per-frame tick — delegated to `PrimitivesRenderer.tickAnimations` so\n * animated decorations (`pulse-ring`, `marching-ants`, …) and the\n * viewport-clipped label-resolution sweep advance every frame.\n *\n * `Canvas.tickOnce` duck-types this hook on each layer; without it the\n * renderer would never tick for graph layers because the field that\n * holds it (`_renderer`) is private and the alternative fallback path\n * looks for a public `renderer` property.\n */\n tickAnimations(deltaMs: number): void {\n this._renderer?.tickAnimations(deltaMs);\n }\n\n /** Data source. Either supplied by the caller or self-created. */\n readonly store: GraphStore;\n\n /** Subscription disposers, called in `onUnmount`. */\n private subs: Array<() => void> = [];\n\n /**\n * Edge ids whose endpoint moved since last flush. The connector path is\n * pinned to shape positions via the `boundary` anchor, but PixiJS doesn't\n * auto-reroute connectors when an anchored shape moves — we drain this set\n * on each store flush and call `updateConnector(eid, {})` to force re-route.\n */\n private dirtyConnectors: Set<string> = new Set();\n\n /**\n * Last-projected collapsed flag per group node id. Read by the\n * `node:update` handler so it can detect a collapse → expand (or\n * expand → collapse) flip — the patch itself doesn't carry the\n * previous style, and the store has already overwritten it by the\n * time the event fires. Updated by {@link syncGroupSyntheticDecorations}\n * on every group render.\n */\n private readonly lastCollapsedByGroup: Map<string, boolean> = new Map();\n\n /**\n * Group node ids whose visible frame may need re-projection (auto-fit\n * recompute, descendant visibility change, collapse / expand toggle).\n * Drained per flush in deepest-first order — see {@link drainDirtyGroups}.\n *\n * Populated by store subscriptions when:\n * - a group's own spec changes (add / update with `style.group` patch),\n * - a child's position changes and its parent is a group with `autoFit`,\n * - a child is added / removed from a group.\n *\n * Holding ids (not full snapshots) keeps the bucket idempotent — multiple\n * mutations within a single batch coalesce to one rerender per group.\n */\n private dirtyGroups: Set<string> = new Set();\n\n /**\n * Nodes / edges whose active-state set changed since the last flush — drained\n * once per flush into `rerenderNode` / `rerenderEdge`. Populated from the\n * store's `node:state` / `edge:state` events; the dedup + once-per-flush drain\n * keeps an N-item highlight to ≤1 rebuild per item (mirrors\n * {@link dirtyConnectors}). State itself is owned by the `GraphStore` (presence\n * compartment) — the layer holds none, just reads `store.nodeStatesOf` at\n * render. See `store-owns-state-plan.md` § 0 / § 2.5.\n */\n private readonly dirtyStateNodes: Set<string> = new Set();\n private readonly dirtyStateEdges: Set<string> = new Set();\n\n /**\n * Currently-mounted decoration slot ids per node / edge, so the resolver\n * can diff (mount new / dispose removed / replace changed) against the\n * previous render's set. Slot ids are synthesized from `spec.id` or\n * `${kind}#<index>`. The `'label'` slot is managed separately by\n * `syncNodeLabel` / `syncEdgeLabel` and never appears in these maps.\n */\n private readonly nodeDecorationSlots: Map<string, Set<string>> = new Map();\n private readonly edgeDecorationSlots: Map<string, Set<string>> = new Map();\n\n /**\n * Currently-mounted badge slot ids per node, mirroring\n * {@link nodeDecorationSlots} for badge diffing. Slot id falls back to\n * `${badge.placement-name}#<index>` when `NodeBadge.id` is absent so\n * id-less badges stack rather than collapse.\n */\n private readonly nodeBadgeSlots: Map<string, Set<string>> = new Map();\n\n /** Edge-side counterpart of {@link nodeBadgeSlots}. */\n private readonly edgeBadgeSlots: Map<string, Set<string>> = new Map();\n\n // ─── v3 G6-aligned layer template ────────────────────────────────────\n // `options.node` and `options.edge` carry layer-level NodeOption /\n // EdgeOption templates (style + state catalogue, resolver-aware).\n private nodeOption: NodeOption | undefined;\n private edgeOption: EdgeOption | undefined;\n\n constructor(opts: LayerOptions<GraphLayerOptions>) {\n super(opts);\n // Stamp the store's telemetry source id with the layer id so multiple\n // graphs are distinguishable on the tap channel (§ 6).\n this.store = opts.options.store ?? new GraphStore({ id: this.id });\n // v3 G6-aligned layer template — single source of truth for style /\n // state catalogue. Both fields are resolver-aware via the\n // `ResolvableNodeStyle` / `ResolvableEdgeStyle` shape. The canonical\n // state defaults are auto-merged underneath so a layer that touches\n // no state code still renders distinct hover / select / error / etc.\n // visuals. Opt out with `useDefaultStates: false`.\n const useDefaults = opts.options.useDefaultStates !== false;\n this.nodeOption = mergeNodeOptionWithDefaults(opts.options.node, useDefaults);\n this.edgeOption = mergeEdgeOptionWithDefaults(opts.options.edge, useDefaults);\n }\n\n protected createState(): GraphLayerState {\n return {};\n }\n\n protected override onMount(ctx: CanvasContext): void {\n // Route the store's events onto the canvas tap channel so telemetry sees\n // every data + interaction-state mutation (§ 6). Detached in onUnmount.\n this.store.bindBus(ctx.events);\n this._renderer = new PrimitivesRenderer({\n container: this.container,\n camera: ctx.camera,\n ...(this.options.hitFloorPx !== undefined\n ? { hitFloorPx: this.options.hitFloorPx }\n : {}),\n // Forwarded so the renderer's pointer router can apply\n // `cursor: pointer` on shape / connector hover.\n ...(ctx.canvasElement ? { canvasElement: ctx.canvasElement } : {}),\n });\n\n // Initial sync — render anything the store already has. Document `states`\n // fold into the resolved style via `store.nodeStatesOf` at render time, so\n // there's no separate state-mirror step.\n for (const node of this.store.nodes()) {\n this.installNodeShape(node);\n if (this.isGroupNode(node)) this.dirtyGroups.add(node.id);\n }\n for (const edge of this.store.edges()) {\n this.installEdgeConnector(edge);\n }\n // Settle every group's auto-fit frame and visibility state in one pass\n // before the first user input — `installNodeShape` iterated linearly,\n // so a parent inserted before its children rendered against zero\n // children. Drain now to re-fit those frames against the freshly-mounted\n // descendants.\n this.drainDirtyGroups();\n\n // Subscribe to fine-grained store events.\n const s = this.store.events;\n this.subs.push(\n s.on('node:add', ({ nodeId }) => {\n const node = this.store.getNode(nodeId);\n if (!node) return;\n this.installNodeShape(node);\n // Document states (`node.states`) are folded in by `resolveNodeStyle`\n // via `store.nodeStatesOf` at render — no mirror step needed.\n // Inserting a child node may extend an ancestor group's auto-fit\n // bbox; mark the parent chain for recompute. Also re-mark this\n // node if it is itself a group, so its initial frame projects with\n // whatever children landed first.\n if (this.isGroupNode(node)) this.dirtyGroups.add(node.id);\n if (node.parentId) this.markGroupAncestorsDirty(node.parentId);\n }),\n s.on('node:update', ({ nodeId, patch }) => {\n const node = this.store.getNode(nodeId);\n if (!node) return;\n const wasCollapsed = this.lastCollapsedByGroup.get(nodeId) === true;\n // `updateNodeShape` re-resolves the style (incl. document `states` via\n // `store.nodeStatesOf`), so a `states` patch repaints with no mirror.\n this.updateNodeShape(node, patch);\n // A position patch on a child propagates up to any auto-fit group\n // ancestor; their frames re-shrink / grow on the next flush.\n if (patch.position && node.parentId) {\n this.markGroupAncestorsDirty(node.parentId);\n }\n // A re-parent triggers a recompute on the *new* parent chain. We\n // can't reach the *previous* parent through the patch alone (the\n // store has already mutated the index), so old-parent shrinkage\n // mirrors the `node:remove` limitation: explicit `recomputeGroup`\n // is the escape hatch when the feed re-parents individually.\n if ('parentId' in patch && node.parentId) {\n this.markGroupAncestorsDirty(node.parentId);\n }\n // A group's own style patch (collapsed flip, padding change, size\n // change) re-projects this group; if collapsed changed, descendants'\n // visibility and incident-edge endpoints need a refresh too.\n if (this.isGroupNode(node)) {\n this.dirtyGroups.add(node.id);\n const isNowCollapsed = this.isCollapsedGroup(node);\n if (wasCollapsed !== isNowCollapsed) {\n this.refreshDescendantsAndIncidentEdges(node.id);\n }\n }\n }),\n s.on('node:remove', ({ nodeId }) => {\n this.dirtyStateNodes.delete(nodeId);\n this.nodeDecorationSlots.delete(nodeId);\n this.nodeBadgeSlots.delete(nodeId);\n this._renderer?.removeShape(nodeId);\n this.dirtyGroups.delete(nodeId);\n this.lastCollapsedByGroup.delete(nodeId);\n // We can't infer the removed node's parentId from the event payload\n // (the store has already cleaned it up). For an auto-fit group whose\n // child was just removed, the frame will not auto-shrink on its own\n // — call `recomputeGroup(parentId)` explicitly if your feed removes\n // children individually and you want the frame to track. Frames\n // grow / shrink correctly on add and on every position change.\n }),\n s.on('edge:add', ({ edgeId }) => {\n const edge = this.store.getEdge(edgeId);\n if (!edge) return;\n this.installEdgeConnector(edge);\n }),\n s.on('edge:update', ({ edgeId, patch }) => {\n const edge = this.store.getEdge(edgeId);\n if (!edge) return;\n this.updateEdgeConnector(edge, patch);\n }),\n s.on('edge:remove', ({ edgeId }) => {\n this.dirtyStateEdges.delete(edgeId);\n this.edgeDecorationSlots.delete(edgeId);\n this.edgeBadgeSlots.delete(edgeId);\n this._renderer?.removeConnector(edgeId);\n }),\n // Runtime (presence) state toggles — mark dirty; the flush handler drains\n // them once each (dedup), keeping an N-item highlight to one paint (§2.5).\n s.on('node:state', ({ nodeId }) => {\n this.dirtyStateNodes.add(nodeId);\n }),\n s.on('edge:state', ({ edgeId }) => {\n this.dirtyStateEdges.add(edgeId);\n }),\n s.on('flush', (counters) => {\n // Groups first — their frames may grow / shrink based on freshly-\n // mutated child positions, which in turn shifts the anchor points\n // every incident connector sees on the next route.\n this.drainDirtyGroups();\n // Then state-driven re-renders (selected/highlighted/… overlays, which\n // may change node size) — drained once per dirty id before connectors\n // reroute, so anchors see the updated geometry.\n if (this.dirtyStateNodes.size > 0) {\n for (const nodeId of this.dirtyStateNodes) this.rerenderNode(nodeId);\n this.dirtyStateNodes.clear();\n }\n if (this.dirtyStateEdges.size > 0) {\n for (const edgeId of this.dirtyStateEdges) this.rerenderEdge(edgeId);\n this.dirtyStateEdges.clear();\n }\n if (this.dirtyConnectors.size > 0 && this._renderer) {\n for (const edgeId of this.dirtyConnectors) {\n // Empty partial — triggers recomputeConnectorPath which re-runs\n // anchors against the current shape positions.\n this._renderer.updateConnector(edgeId, {});\n }\n this.dirtyConnectors.clear();\n }\n this.events.emit('data:changed', { ...counters });\n }),\n );\n }\n\n protected override onUnmount(): void {\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.store.bindBus(undefined);\n this._renderer?.destroy();\n this._renderer = undefined;\n }\n\n // ─── Bulk loading ────────────────────────────────────────────────────────\n\n /**\n * Bulk-load nodes + edges, **replacing** any prior data. Wraps the\n * underlying store inserts in a single `batch()` so subscribers see one\n * flush.\n *\n * For streaming consumers (constantly arriving data), use the store\n * directly: `graph.store.addData({ nodes, edges })` appends without\n * clearing, and `graph.store.applyDelta({ added, updated, removed })`\n * applies an incremental change in one batch. All other per-id CRUD\n * (`upsertNode`, `updateNode`, `removeNode`, edge equivalents, `batch`,\n * `flush`, `clear`) lives on `graph.store` — the store is the single\n * source of truth and the layer just orchestrates store → renderer.\n */\n setData(data: GraphData): void {\n // Pure wipe — delegate to `clear()` so the renderer teardown, store reset,\n // and `data:changed` notification all live in one place.\n if (data.nodes.length === 0 && data.edges.length === 0) {\n this.clear();\n return;\n }\n // Replace: `store.clear()` is a silent fast-wipe — it emits no per-node\n // `node:remove` events, so the renderer (which projects those events into\n // `removeShape` / `removeConnector`) would keep the old shapes painted.\n // Detach them explicitly first; the new data's `node:add` / `edge:add`\n // events then repaint on the batch's flush.\n this.detachAllFromRenderer();\n this.store.batch(() => {\n this.store.clear();\n this.store.addNodesBulk(data.nodes);\n this.store.addEdgesBulk(data.edges);\n });\n }\n\n /**\n * Remove every node and edge — tearing down their rendered shapes /\n * connectors and notifying full-repaint consumers (e.g. `MiniMapLayer`). The\n * canonical way to empty the graph; prefer it over\n * `setData({ nodes: [], edges: [] })`.\n *\n * Note the difference from the low-level `graph.store.clear()`: that is a\n * silent fast-wipe (no events, drops the pending queues), so on its own it\n * would leave the canvas painted and dependent layers stale. This method\n * keeps the renderer and store in sync and fires a single `data:changed`\n * (which `store.clear()` alone never produces, since `doFlush` skips an empty\n * flush) so consumers update immediately rather than on some later event.\n */\n clear(): void {\n const removedNodes = this.store.nodeCount();\n const removedEdges = this.store.edgeCount();\n this.detachAllFromRenderer();\n this.store.clear();\n this.events.emit('data:changed', {\n addedNodes: 0,\n updatedNodes: 0,\n removedNodes,\n addedEdges: 0,\n updatedEdges: 0,\n removedEdges,\n });\n }\n\n /**\n * Force a full re-render of every node and edge from current store state +\n * active states. Does **not** mutate data and is **not** undoable — it is a\n * pure render pass. Use it after an external style/theme change that bypassed\n * the store (e.g. swapping the renderer's palette) or to recover from a\n * suspected render desync. For data edits prefer the store mutators, which\n * re-render the affected items automatically.\n */\n redraw(): void {\n for (const node of this.store.nodes()) this.rerenderNode(node.id);\n for (const edge of this.store.edges()) this.rerenderEdge(edge.id);\n }\n\n /**\n * Drop every shape / connector this layer has mounted on the renderer and\n * reset transient routing state. Shared by `clear` / `setData`: `store.clear()`\n * is silent, so it never drives the renderer's event-based removal path —\n * the layer must detach explicitly.\n */\n private detachAllFromRenderer(): void {\n const renderer = this._renderer;\n if (!renderer) return;\n for (const node of this.store.nodes()) renderer.removeShape(node.id);\n for (const edge of this.store.edges()) renderer.removeConnector(edge.id);\n this.dirtyConnectors.clear();\n }\n\n // ─── Layer-level template (defaults) ──────────────────────────────────────\n\n /**\n * Patch the layer-level node template (`options.node.style`) and re-render\n * every node so the change takes effect immediately. Use this for global\n * \"apply to all nodes\" changes (e.g. a toolbar default-fill picker) instead\n * of looping `store.updateNode` per node.\n *\n * Merge is shallow (top-level): structured fields (`shape`, `decorations`,\n * `badges`, `effects`) are replaced wholesale — spread the prior value if you\n * mean to patch a single sub-field. Per-node `style`, active states, and\n * resolver functions still win over the template at resolve time (see\n * {@link resolveNodeStyle}). No-op visually if the layer isn't mounted yet,\n * but the template is still updated so later mounts pick it up.\n */\n setNodeDefaults(patch: Partial<NodeStyle>): void {\n this.nodeOption = {\n ...this.nodeOption,\n style: {\n ...(this.nodeOption?.style ?? {}),\n ...patch,\n } as ResolvableNodeStyle<GraphNode>,\n };\n for (const node of this.store.nodes()) this.rerenderNode(node.id);\n }\n\n /**\n * Sibling of {@link setNodeDefaults} for the edge template\n * (`options.edge.style`). Patches the shared edge styling and re-renders\n * every edge. Same shallow-merge contract — e.g. changing edge \"type\" means\n * `setEdgeDefaults({ shape: { ...prevShape, pathType: 'bezier' } })`.\n */\n setEdgeDefaults(patch: Partial<EdgeStyle>): void {\n this.edgeOption = {\n ...this.edgeOption,\n style: {\n ...(this.edgeOption?.style ?? {}),\n ...patch,\n } as ResolvableEdgeStyle<GraphEdge>,\n };\n for (const edge of this.store.edges()) this.rerenderEdge(edge.id);\n }\n\n /** Read-only snapshot of the current node template style (resolved per node at render). */\n get nodeDefaults(): ResolvableNodeStyle<GraphNode> | undefined {\n return this.nodeOption?.style;\n }\n\n /** Read-only snapshot of the current edge template style. */\n get edgeDefaults(): ResolvableEdgeStyle<GraphEdge> | undefined {\n return this.edgeOption?.style;\n }\n\n // ─── State sugar ──────────────────────────────────────────────────────────\n //\n // Interaction state is owned by the `GraphStore` (presence compartment) — set\n // it via `layer.store.addNodeState` / `removeNodeState` / `clearNodeState`\n // (+ edge variants). The layer only adds graph-domain *sugar* that composes\n // several store writes; the layer itself holds no state.\n\n /**\n * Highlight a node together with its neighbours (in `dir`) and incident edges\n * — adds the runtime state `state` to all of them in a single\n * {@link GraphStore.batch}, so the whole neighbourhood repaints in one flush.\n * No-op if the seed id is unknown. Clear with `store.clearNodeState(state)` +\n * `store.clearEdgeState(state)`.\n *\n * @param id Seed node id.\n * @param dir Adjacency direction for neighbours + incident edges. Default `'both'`.\n * @param state Runtime state name to apply. Default `'highlighted'`.\n */\n highlightNeighbourhood(\n id: string,\n dir: EdgeDirection = 'both',\n state = 'highlighted',\n ): void {\n if (!this.store.hasNode(id)) return;\n this.store.batch(() => {\n this.store.addNodeState(id, state);\n for (const nb of this.store.neighborsOf(id, dir)) this.store.addNodeState(nb, state);\n for (const e of this.store.edgesOf(id, dir)) this.store.addEdgeState(e.id, state);\n });\n }\n\n // ─── Hit testing (placeholder) ───────────────────────────────────────────\n\n /**\n * Placeholder hit test — returns `null` until proper hit testing wires up\n * in a later phase (likely via the canvas hit-test pipeline reading the\n * renderer's shape registry).\n */\n hitTest(_worldX: number, _worldY: number): WorldLayerHit | null {\n return null;\n }\n\n // ─── Internals: data → spec translation ─────────────────────────────────\n\n /**\n * Resolve the active node hints — merges base `node.data` hints (legacy)\n * and v3 `node.style` with each active state's overlay (legacy + v3),\n * resolving layer-side resolver functions against the current node.\n *\n * Precedence (lowest → highest):\n * 1. layer `node.style` (resolved against GraphNode, adapted)\n * 2. `node.data` (legacy hints)\n * 3. per-node `node.style` (concrete NodeStyle, adapted)\n * 4. For each active state name in `node.states[]`:\n * a. layer legacy `nodeStateConfigs[name]` (resolved)\n * b. layer v3 `node.state[name]` (resolved against GraphNode, adapted)\n * c. per-node `node.state[name]` (concrete NodeStyle, adapted)\n */\n /**\n * Resolve the final flat NodeStyle for a node by merging contributions from\n * the layer-level template (`options.node.style`), the per-node `style`,\n * and every active state's layer + per-node overlay. Object.assign order\n * encodes precedence (later wins).\n *\n * Exposed publicly so behaviours (NodeSizeLODBehaviour, label collision,\n * minimap, etc.) can read the same effective style the renderer sees,\n * without duplicating the merge logic.\n */\n resolveNodeStyle(node: GraphNode): Partial<NodeStyle> {\n const merged: Partial<NodeStyle> = {};\n if (this.nodeOption?.style) {\n Object.assign(merged, resolveNodeStyleFields(this.nodeOption.style, node));\n }\n Object.assign(merged, (node.style as Partial<NodeStyle> | undefined) ?? {});\n\n const activeStates = this.store.nodeStatesOf(node.id);\n if (activeStates.length > 0) {\n const perNodeCatalogue = node.state as Readonly<Record<string, NodeStyle>> | undefined;\n for (const name of activeStates) {\n const layerOverlay = this.nodeOption?.state?.[name];\n if (layerOverlay) {\n Object.assign(merged, resolveNodeStyleFields(layerOverlay, node));\n }\n const perNodeOverlay = perNodeCatalogue?.[name];\n if (perNodeOverlay) Object.assign(merged, perNodeOverlay);\n }\n }\n\n // Apply the unified `style.size` override. Done here (not in `nodeSpec`)\n // so every consumer of the resolved style — `boundsOfNode`, D3's\n // collide.radius callback (which reads `style.shape.radius` directly off\n // a `resolveNodeStyle` result), and ELK's bounds query — observes the\n // same normalized geometry. Skips shape kinds with no canonical size axis\n // (polygon, custom) and is a no-op when `size` is undefined.\n if (merged.size !== undefined) {\n // Synthesize a default circle shape when `size` is set but no `shape`\n // was contributed by template / per-node / state overlays — keeps the\n // contract \"setting `size` resizes the node\" honest in the no-shape\n // case (which still flows through `nodeSpec`'s default circle).\n const baseShape: NodeShapeOptions =\n merged.shape ?? ({ kind: 'circle', radius: 0 } as NodeShapeOptions);\n const normalized = normalizeShapeSize(baseShape, merged.size);\n if (normalized !== baseShape || merged.shape === undefined) {\n (merged as { shape?: NodeShapeOptions }).shape = normalized;\n }\n }\n\n return merged;\n }\n\n /** Sibling of {@link resolveNodeStyle} for edges. Public for the same reason. */\n resolveEdgeStyle(edge: GraphEdge): Partial<EdgeStyle> {\n const merged: Partial<EdgeStyle> = {};\n if (this.edgeOption?.style) {\n Object.assign(merged, resolveEdgeStyleFields(this.edgeOption.style, edge));\n }\n Object.assign(merged, (edge.style as Partial<EdgeStyle> | undefined) ?? {});\n\n const activeStates = this.store.edgeStatesOf(edge.id);\n if (activeStates.length > 0) {\n const perEdgeCatalogue = edge.state as Readonly<Record<string, EdgeStyle>> | undefined;\n for (const name of activeStates) {\n const layerOverlay = this.edgeOption?.state?.[name];\n if (layerOverlay) {\n Object.assign(merged, resolveEdgeStyleFields(layerOverlay, edge));\n }\n const perEdgeOverlay = perEdgeCatalogue?.[name];\n if (perEdgeOverlay) Object.assign(merged, perEdgeOverlay);\n }\n }\n return merged;\n }\n\n /**\n * Build the renderer-facing shape spec from the resolved {@link NodeStyle}.\n * Geometry is driven by the discriminated `style.shape` union; paint comes\n * from the flat `bg*` fields.\n *\n * The `kind` discriminator and any spec params on `style.shape` pass\n * straight through to the renderer, so any shape registered via\n * `canvas.primitives.registerShape(name, ctor)` is usable by name — built-\n * ins (`rect` / `circle` / `arc` / `regular-polygon` / `star` / `polygon`)\n * and custom shapes alike. An unknown `kind` errors loudly in the\n * renderer's `addShape` rather than silently falling back to a circle.\n */\n /**\n * Local AABB for `node`'s resolved shape. Delegates to the registered\n * shape's `static boundsOf` via `PrimitivesRenderer.boundsOfSpec`, so\n * built-in and custom shape kinds flow through the same hook.\n *\n * Returns `undefined` when:\n * - the renderer isn't mounted yet,\n * - the resolved `style.shape.kind` isn't registered, or\n * - the registered ctor doesn't implement `boundsOf`.\n *\n * The returned rect is in the shape's local (centre-relative) frame —\n * `node.position` is *not* baked in. Consumers that only need a size\n * read `width` / `height`; consumers that need world-space corners\n * offset by `node.position` themselves.\n *\n * Used by `MiniMapLayer` to estimate node footprint before the source\n * renderer mounts and by `ElkLayout` (and other layouts) to read node\n * sizes for layout-time placement — both without switching over a\n * closed shape-kind enum.\n */\n boundsOfNode(node: GraphNode): Rect | undefined {\n if (!this._renderer) return undefined;\n return this._renderer.boundsOfSpec(this.nodeSpec(node));\n }\n\n // ─── Viewport framing ─────────────────────────────────────────────────────\n\n /**\n * Frame the camera on a set of nodes — fit the viewport to the world-space\n * box spanning their positions, plus `padding` screen px. Unknown ids are\n * skipped; a no-op when none resolve or the layer isn't mounted.\n *\n * Graph-domain sugar over the geometry-only {@link Camera.fitContent}: it\n * resolves ids → positions so callers (e.g. a \"zoom to node\" context-menu\n * action) don't have to.\n *\n * @param ids Node ids to frame.\n * @param padding Screen-pixel padding around the fitted box. Default `160`.\n */\n focusNodes(ids: Iterable<string>, padding = 160): void {\n const pts: Array<{ x: number; y: number }> = [];\n for (const id of ids) {\n const pos = this.store.getPosition(id);\n if (pos) pts.push(pos);\n }\n this.fitPoints(pts, padding);\n }\n\n /**\n * Frame the camera on a set of edges — fit the viewport to the box spanning\n * both endpoints of each edge, plus `padding` screen px. Unknown ids (or\n * edges with an unplaced endpoint) are skipped; a no-op when none resolve or\n * the layer isn't mounted.\n *\n * @param ids Edge ids to frame.\n * @param padding Screen-pixel padding around the fitted box. Default `160`.\n */\n focusEdges(ids: Iterable<string>, padding = 160): void {\n const pts: Array<{ x: number; y: number }> = [];\n for (const id of ids) {\n const edge = this.store.getEdge(id);\n if (!edge) continue;\n const a = this.store.getPosition(edge.source);\n const b = this.store.getPosition(edge.target);\n if (a) pts.push(a);\n if (b) pts.push(b);\n }\n this.fitPoints(pts, padding);\n }\n\n /** Fit the camera to the AABB spanning `pts` (+ padding). No-op if empty / unmounted. */\n private fitPoints(pts: ReadonlyArray<{ x: number; y: number }>, padding: number): void {\n const camera = this.ctx?.camera;\n if (!camera || pts.length === 0) return;\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const p of pts) {\n minX = Math.min(minX, p.x);\n minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n }\n camera.fitContent(\n { x: minX, y: minY, width: Math.max(1, maxX - minX), height: Math.max(1, maxY - minY) },\n padding,\n );\n }\n\n private nodeSpec(node: GraphNode): BaseShapeSpec {\n const style = this.resolveNodeStyle(node);\n let shape: NodeShapeOptions = style.shape ?? { kind: 'circle', radius: 10 };\n let pos = node.position ?? { x: 0, y: 0 };\n\n // Group projection — frame-size / position recompute for expanded\n // auto-fit groups, and zIndex push-back so descendants paint on top.\n // Collapsed groups skip the recompute and project as a regular node;\n // children are hidden separately via the `visible: false` branch below.\n const group = style.group;\n if (group && !group.collapsed) {\n const fitted = this.projectGroupShape(node.id, shape, group, pos);\n shape = fitted.shape;\n pos = fitted.pos;\n }\n\n // Visibility — a node is hidden when any ancestor is a collapsed group.\n // We still emit a spec (so decorations / size are valid for any incident\n // edge re-route math against the group node), but with `visible: false`\n // so PixiJS skips drawing it.\n const hiddenByGroup = this.collapsedAncestor(node.id) !== undefined;\n\n // Project the resolved style into a `ShapeFill` for the renderer.\n // Layers stack bottom-up:\n // 1. `bgFill` — `number` (shorthand solid), single `ShapeFillLayer`,\n // or `ReadonlyArray<ShapeFillLayer>`. Arrays are passed through\n // so consumers can express e.g. tint + glow / image-cover +\n // colour-wash compositions directly.\n // 2. `style.image` — projects 1:1 to a `kind: 'image'` layer. The\n // canvas renderer cover-fits the texture into the silhouette.\n // 3. `style.icon` — projects verbatim to a `glyph` / `svg` /\n // `svg-url` layer. The discriminated union mirrors\n // `ShapeFillLayer` field-for-field.\n // The fast path (no image, no icon, `bgFill` is a number) collapses\n // to the bare-number shorthand so simple solid nodes stay cheap.\n const bg = style.bgFill;\n const hasImage = style.image !== undefined;\n const hasIcon = style.icon !== undefined;\n let fill: number | ReadonlyArray<ShapeFillLayer> | undefined;\n if (!hasImage && !hasIcon && typeof bg === 'number') {\n fill = bg;\n } else if (bg === undefined && !hasImage && !hasIcon) {\n fill = undefined;\n } else {\n const layers: ShapeFillLayer[] = [];\n if (typeof bg === 'number') {\n layers.push({ kind: 'solid', color: bg });\n } else if (Array.isArray(bg)) {\n for (const l of bg) layers.push(l as ShapeFillLayer);\n } else if (bg !== undefined) {\n layers.push(bg as ShapeFillLayer);\n }\n if (style.image !== undefined) {\n const img = style.image;\n layers.push({\n kind: 'image',\n url: img.url,\n ...(img.alpha !== undefined ? { alpha: img.alpha } : {}),\n ...(img.fit !== undefined ? { fit: img.fit } : {}),\n ...(img.padding !== undefined ? { padding: img.padding } : {}),\n });\n }\n if (style.icon !== undefined) {\n layers.push(style.icon as ShapeFillLayer);\n }\n fill = layers.length > 0 ? layers : undefined;\n }\n\n const bgStrokeWidth = style.bgStrokeWidth ?? 0;\n const stroke =\n style.bgStrokeColor !== undefined && bgStrokeWidth > 0\n ? {\n color: style.bgStrokeColor,\n width: bgStrokeWidth,\n alignment: style.bgStrokeAlignment ?? 'outside',\n ...(style.bgStrokeAlpha !== undefined ? { alpha: style.bgStrokeAlpha } : {}),\n ...(style.bgStrokeDashArray ? { dashArray: style.bgStrokeDashArray } : {}),\n ...(style.bgStrokeDashOffset !== undefined ? { dashOffset: style.bgStrokeDashOffset } : {}),\n }\n : undefined;\n\n // Compute the effective zIndex. Expanded group nodes paint underneath\n // their descendants by default (`behindChildren !== false`); subtract\n // one from any declared zIndex so children (at zIndex 0 by default)\n // sit on top. Collapsed groups skip this — they render like a regular\n // interactive node.\n const baseZ = (style as { zIndex?: number }).zIndex;\n let zIndex: number | undefined = baseZ;\n if (group && !group.collapsed && group.behindChildren !== false) {\n zIndex = (baseZ ?? 0) - 1;\n }\n\n // Map the canonical `node.position` to the shape's render origin. The\n // `composite` shape draws from its top-left corner (unlike `circle`,\n // centred at (x,y)), so it's shifted by -size/2 to sit centred on `pos`.\n // MUST match the fast-path in `updateNodeShape`, or a position-only update\n // (layout / drag) would place the card differently than a full rebuild\n // (add / hover), making it visibly jump. See {@link shapeRenderXY}.\n const { x, y } = shapeRenderXY(shape, pos);\n\n return {\n ...(shape as unknown as Record<string, unknown>),\n x,\n y,\n // Always emit `alpha` (default opaque) — same partial-merge reasoning as\n // `visible` below. A transient state (e.g. `dimmed`, `bgAlpha: 0.25`) sets\n // it; when that state clears and the base style doesn't pin `bgAlpha`,\n // omitting the field here would leave the dimmed alpha stuck on the cached\n // spec. Emitting `1` restores opacity on state removal.\n alpha: style.bgAlpha ?? 1,\n ...(fill !== undefined ? { fill } : {}),\n ...(stroke ? { stroke } : {}),\n ...(zIndex !== undefined ? { zIndex } : {}),\n // Always emit `visible` — the renderer partial-merges patches onto\n // the cached spec, so omitting the field on the \"now visible\" pass\n // after a collapse → expand transition would leave the previous\n // `visible: false` in place and the descendant would stay hidden.\n visible: !hiddenByGroup,\n } as BaseShapeSpec;\n }\n\n /**\n * Build the renderer-facing connector spec from the resolved\n * {@link EdgeStyle}. The three-stage pipeline (anchor → router →\n * pathStyle) is driven by `style.shape.pathType` + the anchor / router\n * options on the same struct; paint comes from the flat `stroke*` fields.\n */\n private edgeSpec(edge: GraphEdge): BaseConnectorSpec {\n const style = this.resolveEdgeStyle(edge);\n const shape = style.shape ?? {};\n\n const pathType: EdgePathType = shape.pathType ?? 'straight';\n const { router, pathStyle } = pathTypeToRouterPathStyle(pathType);\n\n const baseAnchor: EdgeAnchor = 'boundary';\n const sourceAnchorName: EdgeAnchor = shape.sourceAnchor ?? baseAnchor;\n const targetAnchorName: EdgeAnchor = shape.targetAnchor ?? baseAnchor;\n const sourceAnchorOpts = shape.sourceAnchorOpts;\n const targetAnchorOpts = shape.targetAnchorOpts;\n const pathStyleOpts = shape.pathStyleOpts ?? {};\n const waypoints = shape.waypoints;\n\n const strokeColor = style.strokeColor ?? 0x94a3b8;\n const strokeWidth = style.strokeWidth ?? 1.5;\n const alpha = style.strokeAlpha ?? 1;\n\n const arrowTargetShape = style.arrowTargetShape ?? 'triangle';\n const arrowTargetColor = style.arrowTargetColor ?? strokeColor;\n\n const sourceAnchorSpec =\n sourceAnchorOpts && Object.keys(sourceAnchorOpts).length > 0\n ? { name: sourceAnchorName, opts: sourceAnchorOpts }\n : sourceAnchorName;\n const targetAnchorSpec =\n targetAnchorOpts && Object.keys(targetAnchorOpts).length > 0\n ? { name: targetAnchorName, opts: targetAnchorOpts }\n : targetAnchorName;\n\n // When an endpoint sits under a collapsed group ancestor, re-route the\n // connector to that ancestor so the line ends at the visible super-node\n // instead of pointing at a hidden descendant. The store edge is not\n // mutated — `edge.source` / `edge.target` stay authoritative.\n const sourceShapeId = this.effectiveEndpoint(edge.source);\n const targetShapeId = this.effectiveEndpoint(edge.target);\n\n // Collapse-induced self-loop: an intra-group edge whose both endpoints\n // now resolve to the same collapsed group. Rendering it would produce\n // a degenerate stub at the group's silhouette — visible as a stray\n // segment near the super-node. Hide it. Always emit `visible` so the\n // renderer's partial-merge restores the field on re-expand.\n const isCollapseSelfLoop =\n sourceShapeId === targetShapeId && edge.source !== edge.target;\n\n return {\n kind: 'connector',\n source: { kind: 'shape', shapeId: sourceShapeId, anchor: sourceAnchorSpec },\n target: { kind: 'shape', shapeId: targetShapeId, anchor: targetAnchorSpec },\n router,\n pathStyle,\n ...(pathStyleOpts && Object.keys(pathStyleOpts).length > 0 ? { pathStyleOpts } : {}),\n ...(waypoints && waypoints.length > 0 ? { waypoints } : {}),\n stroke: {\n color: strokeColor,\n width: strokeWidth,\n ...(style.strokeAlignment !== undefined ? { alignment: style.strokeAlignment } : {}),\n ...(style.strokeDashArray ? { dashArray: style.strokeDashArray } : {}),\n ...(style.strokeDashOffset !== undefined ? { dashOffset: style.strokeDashOffset } : {}),\n },\n alpha,\n visible: !isCollapseSelfLoop,\n ...(arrowTargetShape !== 'none'\n ? { targetMarker: { kind: 'arrow', fill: arrowTargetColor } }\n : {}),\n ...(style.arrowSourceShape && style.arrowSourceShape !== 'none'\n ? { sourceMarker: { kind: 'arrow', fill: style.arrowSourceColor ?? strokeColor } }\n : {}),\n };\n }\n\n /**\n * Re-render a single node from its current data + active state stack.\n *\n * Prefers `renderer.updateShape` (instance-preserving) over the\n * `removeShape + addShape` fallback so the renderer's per-instance\n * state — `gfxScale` (written by `NodeSizeLODBehaviour`), attached\n * decorations, badges, effects — survives a state toggle. Falls back\n * to remove+add only when the rebuilt spec has a different `kind`,\n * which `updateShape` can't safely handle (the `IShape` class is\n * fixed at construction time).\n */\n private rerenderNode(id: string): void {\n if (!this._renderer) return;\n const node = this.store.getNode(id);\n if (!node) return;\n const spec = this.nodeSpec(node);\n const currentKind = this._renderer.getShapeKind(id);\n if (currentKind === undefined) {\n this._renderer.addShape(id, spec);\n } else if (currentKind === spec.kind) {\n // Kind already matches — instance-preserving partial update.\n this._renderer.updateShape<BaseShapeSpec>(id, spec);\n } else {\n this._renderer.removeShape(id);\n // `removeShape` disposes every mounted decoration AND badge on the\n // host. Drop our tracking so the next sync treats it as a full mount\n // instead of diffing against ghost slots.\n this.nodeDecorationSlots.delete(id);\n this.nodeBadgeSlots.delete(id);\n this._renderer.addShape(id, spec);\n }\n // `syncNodeLabel` / `syncNodeDecorations` / `syncNodeBadges` are\n // idempotent — `setDecoration` / `setBadge` replace a slot whether or\n // not one was already there. Cheap to call in both branches.\n this.syncNodeLabel(id);\n this.syncNodeDecorations(id);\n this.syncNodeBadges(id);\n this.syncGroupSyntheticDecorations(id);\n // Anchors of incident connectors point to this shape — re-route in\n // either branch since the shape's bounds may have changed (size\n // hint shift, kind change, etc.).\n for (const edge of this.store.edgesOf(id, 'both')) {\n this.dirtyConnectors.add(edge.id);\n }\n this.drainDirtyConnectors();\n }\n\n /**\n * Re-render a single edge from its current data + active state stack.\n *\n * Always uses `renderer.updateConnector` so `inst.strokeWidthScale`\n * (written by `EdgeSizeLODBehaviour` as `1/cameraScale`) survives the\n * state-driven full-spec replacement. The fresh spec carries the new\n * \"base\" stroke width; the multiplier applies on top at draw time.\n */\n private rerenderEdge(id: string): void {\n if (!this._renderer) return;\n const edge = this.store.getEdge(id);\n if (!edge) return;\n const spec = this.edgeSpec(edge);\n if (this._renderer.hasConnector(id)) {\n this._renderer.updateConnector(id, spec);\n } else {\n this._renderer.addConnector(id, spec);\n }\n this.syncEdgeLabel(id);\n this.syncEdgeDecorations(id);\n this.syncEdgeBadges(id);\n }\n\n private drainDirtyConnectors(): void {\n if (this.dirtyConnectors.size === 0 || !this._renderer) return;\n for (const edgeId of this.dirtyConnectors) {\n this._renderer.updateConnector(edgeId, {});\n }\n this.dirtyConnectors.clear();\n }\n\n private installNodeShape(node: GraphNode): void {\n if (!this._renderer) return;\n this._renderer.addShape(node.id, this.nodeSpec(node));\n this.syncNodeLabel(node.id);\n this.syncNodeDecorations(node.id);\n this.syncNodeBadges(node.id);\n this.syncGroupSyntheticDecorations(node.id);\n }\n\n private installEdgeConnector(edge: GraphEdge): void {\n if (!this._renderer) return;\n this._renderer.addConnector(edge.id, this.edgeSpec(edge));\n this.syncEdgeLabel(edge.id);\n this.syncEdgeDecorations(edge.id);\n this.syncEdgeBadges(edge.id);\n }\n\n /**\n * Project the resolved `label` hint onto the canvas `'label'` decoration\n * slot for the given node. A `null` / `undefined` hint clears the slot.\n * Called after every `addShape` and every `rerenderNode` since decorations\n * are dropped when the shape is destroyed.\n */\n private syncNodeLabel(id: string): void {\n if (!this._renderer) return;\n const node = this.store.getNode(id);\n if (!node) return;\n const style = this.resolveNodeStyle(node);\n // Escape hatch wins over flat-field synthesis.\n const labelStyle = style.labelStyle ?? buildShapeLabelStyle(style);\n if (!labelStyle) {\n this._renderer.setDecoration(id, 'label', null);\n return;\n }\n this._renderer.setDecoration(id, 'label', { kind: 'label', style: labelStyle });\n }\n\n private syncEdgeLabel(id: string): void {\n if (!this._renderer) return;\n const edge = this.store.getEdge(id);\n if (!edge) return;\n const style = this.resolveEdgeStyle(edge);\n const labelStyle = style.labelStyle ?? buildConnectorLabelStyle(style);\n if (!labelStyle) {\n this._renderer.setDecoration(id, 'label', null);\n return;\n }\n this._renderer.setDecoration(id, 'label', { kind: 'label-connector', style: labelStyle });\n }\n\n /**\n * Resolve the final list of decorations for a node by concatenating every\n * contributing layer (layer template + per-node base + each active state\n * overlay) and deduping by `id`. Later precedence wins; `remove: true`\n * drops an earlier same-id entry. Entries without an explicit `id` fall\n * back to `${kind}#<combined-index>` — unique per source position, so\n * id-less decorations stack rather than collapsing.\n *\n * Returns a `Map<slotId, NodeDecorationSpec>` keyed by the resolved\n * identity. Caller emits one `setDecoration` call per slot to the\n * renderer; the slot id is reused on subsequent renders to enable diffing.\n */\n private resolveNodeDecorations(node: GraphNode): Map<string, NodeDecorationSpec> {\n const collected: NodeDecorationSpec[] = [];\n\n const pushFrom = (style: Partial<NodeStyle> | undefined): void => {\n const decos = style?.decorations;\n if (decos && decos.length > 0) collected.push(...decos);\n };\n\n if (this.nodeOption?.style) {\n pushFrom(resolveNodeStyleFields(this.nodeOption.style, node));\n }\n pushFrom(node.style as Partial<NodeStyle> | undefined);\n\n const activeStates = this.store.nodeStatesOf(node.id);\n if (activeStates.length > 0) {\n const perNodeCatalogue = node.state as Readonly<Record<string, NodeStyle>> | undefined;\n for (const name of activeStates) {\n const layerOverlay = this.nodeOption?.state?.[name];\n if (layerOverlay) {\n pushFrom(resolveNodeStyleFields(layerOverlay, node));\n }\n const perNodeOverlay = perNodeCatalogue?.[name];\n if (perNodeOverlay) pushFrom(perNodeOverlay);\n }\n }\n\n const out = new Map<string, NodeDecorationSpec>();\n for (let i = 0; i < collected.length; i++) {\n const spec = collected[i]!;\n const slotId = spec.id ?? `${spec.kind}#${i}`;\n if (spec.remove) {\n out.delete(slotId);\n } else {\n out.set(slotId, spec);\n }\n }\n return out;\n }\n\n /** Sibling of {@link resolveNodeDecorations} for edges. */\n private resolveEdgeDecorations(edge: GraphEdge): Map<string, EdgeDecorationSpec> {\n const collected: EdgeDecorationSpec[] = [];\n\n const pushFrom = (style: Partial<EdgeStyle> | undefined): void => {\n const decos = style?.decorations;\n if (decos && decos.length > 0) collected.push(...decos);\n };\n\n if (this.edgeOption?.style) {\n pushFrom(resolveEdgeStyleFields(this.edgeOption.style, edge));\n }\n pushFrom(edge.style as Partial<EdgeStyle> | undefined);\n\n const activeStates = this.store.edgeStatesOf(edge.id);\n if (activeStates.length > 0) {\n const perEdgeCatalogue = edge.state as Readonly<Record<string, EdgeStyle>> | undefined;\n for (const name of activeStates) {\n const layerOverlay = this.edgeOption?.state?.[name];\n if (layerOverlay) {\n pushFrom(resolveEdgeStyleFields(layerOverlay, edge));\n }\n const perEdgeOverlay = perEdgeCatalogue?.[name];\n if (perEdgeOverlay) pushFrom(perEdgeOverlay);\n }\n }\n\n const out = new Map<string, EdgeDecorationSpec>();\n for (let i = 0; i < collected.length; i++) {\n const spec = collected[i]!;\n const slotId = spec.id ?? `${spec.kind}#${i}`;\n if (spec.remove) {\n out.delete(slotId);\n } else {\n out.set(slotId, spec);\n }\n }\n return out;\n }\n\n /**\n * Project the resolved decoration array onto the canvas renderer for the\n * given node. Diffs against the previous render's slot set tracked in\n * {@link nodeDecorationSlots}: mounts new ids, removes vanished ones,\n * replaces specs whose slot id appears in both.\n */\n private syncNodeDecorations(id: string): void {\n if (!this._renderer) return;\n const node = this.store.getNode(id);\n if (!node) return;\n const next = this.resolveNodeDecorations(node);\n const prev = this.nodeDecorationSlots.get(id);\n\n if (prev) {\n for (const slotId of prev) {\n if (!next.has(slotId)) this._renderer.setDecoration(id, slotId, null);\n }\n }\n for (const [slotId, spec] of next) {\n const { kind, style } = splitDecorationSpec(spec);\n this._renderer.setDecoration(id, slotId, { kind, style });\n }\n\n if (next.size === 0) this.nodeDecorationSlots.delete(id);\n else this.nodeDecorationSlots.set(id, new Set(next.keys()));\n }\n\n /** Sibling of {@link syncNodeDecorations} for edges. */\n private syncEdgeDecorations(id: string): void {\n if (!this._renderer) return;\n const edge = this.store.getEdge(id);\n if (!edge) return;\n const next = this.resolveEdgeDecorations(edge);\n const prev = this.edgeDecorationSlots.get(id);\n\n if (prev) {\n for (const slotId of prev) {\n if (!next.has(slotId)) this._renderer.setDecoration(id, slotId, null);\n }\n }\n for (const [slotId, spec] of next) {\n const { kind, style } = splitDecorationSpec(spec);\n this._renderer.setDecoration(id, slotId, { kind, style });\n }\n\n if (next.size === 0) this.edgeDecorationSlots.delete(id);\n else this.edgeDecorationSlots.set(id, new Set(next.keys()));\n }\n\n /**\n * Resolve the final list of badges for a node by concatenating every\n * contributing layer (layer template + per-node base + each active state\n * overlay) and deduping by `id`. Later precedence wins. Entries without an\n * explicit `id` fall back to `badge#<combined-index>` so id-less badges\n * stack rather than collapsing.\n */\n private resolveNodeBadges(node: GraphNode): Map<string, NodeBadge> {\n const collected: NodeBadge[] = [];\n\n const pushFrom = (style: Partial<NodeStyle> | undefined): void => {\n const badges = style?.badges;\n if (badges && badges.length > 0) collected.push(...badges);\n };\n\n if (this.nodeOption?.style) {\n pushFrom(resolveNodeStyleFields(this.nodeOption.style, node));\n }\n pushFrom(node.style as Partial<NodeStyle> | undefined);\n\n const activeStates = this.store.nodeStatesOf(node.id);\n if (activeStates.length > 0) {\n const perNodeCatalogue = node.state as Readonly<Record<string, NodeStyle>> | undefined;\n for (const name of activeStates) {\n const layerOverlay = this.nodeOption?.state?.[name];\n if (layerOverlay) {\n pushFrom(resolveNodeStyleFields(layerOverlay, node));\n }\n const perNodeOverlay = perNodeCatalogue?.[name];\n if (perNodeOverlay) pushFrom(perNodeOverlay);\n }\n }\n\n const out = new Map<string, NodeBadge>();\n for (let i = 0; i < collected.length; i++) {\n const badge = collected[i]!;\n const slotId = badge.id ?? `badge#${i}`;\n out.set(slotId, badge);\n }\n return out;\n }\n\n /**\n * Project the resolved badge map onto the canvas renderer for the given\n * node. Diffs against the previous render's slot set tracked in\n * {@link nodeBadgeSlots}: mounts new ids, removes vanished ones, replaces\n * specs whose slot id appears in both.\n */\n private syncNodeBadges(id: string): void {\n if (!this._renderer) return;\n const node = this.store.getNode(id);\n if (!node) return;\n const next = this.resolveNodeBadges(node);\n const prev = this.nodeBadgeSlots.get(id);\n\n if (prev) {\n for (const slotId of prev) {\n if (!next.has(slotId)) this._renderer.removeBadge(id, slotId);\n }\n }\n for (const [slotId, badge] of next) {\n this._renderer.setBadge(id, slotId, nodeBadgeToCanvasOptions(badge));\n }\n\n if (next.size === 0) this.nodeBadgeSlots.delete(id);\n else this.nodeBadgeSlots.set(id, new Set(next.keys()));\n }\n\n /** Sibling of {@link resolveNodeBadges} for edges. */\n private resolveEdgeBadges(edge: GraphEdge): Map<string, EdgeBadge> {\n const collected: EdgeBadge[] = [];\n\n const pushFrom = (style: Partial<EdgeStyle> | undefined): void => {\n const badges = style?.badges;\n if (badges && badges.length > 0) collected.push(...badges);\n };\n\n if (this.edgeOption?.style) {\n pushFrom(resolveEdgeStyleFields(this.edgeOption.style, edge));\n }\n pushFrom(edge.style as Partial<EdgeStyle> | undefined);\n\n const activeStates = this.store.edgeStatesOf(edge.id);\n if (activeStates.length > 0) {\n const perEdgeCatalogue = edge.state as Readonly<Record<string, EdgeStyle>> | undefined;\n for (const name of activeStates) {\n const layerOverlay = this.edgeOption?.state?.[name];\n if (layerOverlay) {\n pushFrom(resolveEdgeStyleFields(layerOverlay, edge));\n }\n const perEdgeOverlay = perEdgeCatalogue?.[name];\n if (perEdgeOverlay) pushFrom(perEdgeOverlay);\n }\n }\n\n const out = new Map<string, EdgeBadge>();\n for (let i = 0; i < collected.length; i++) {\n const badge = collected[i]!;\n const slotId = badge.id ?? `badge#${i}`;\n out.set(slotId, badge);\n }\n return out;\n }\n\n /** Sibling of {@link syncNodeBadges} for edges. */\n private syncEdgeBadges(id: string): void {\n if (!this._renderer) return;\n const edge = this.store.getEdge(id);\n if (!edge) return;\n const next = this.resolveEdgeBadges(edge);\n const prev = this.edgeBadgeSlots.get(id);\n\n if (prev) {\n for (const slotId of prev) {\n if (!next.has(slotId)) this._renderer.removeBadge(id, slotId);\n }\n }\n for (const [slotId, badge] of next) {\n this._renderer.setBadge(id, slotId, edgeBadgeToCanvasOptions(badge));\n }\n\n if (next.size === 0) this.edgeBadgeSlots.delete(id);\n else this.edgeBadgeSlots.set(id, new Set(next.keys()));\n }\n\n private updateNodeShape(node: GraphNode, patch: Partial<GraphNode>): void {\n if (!this._renderer) return;\n\n // Skip the renderer entirely for patches whose fields don't affect what\n // the shape *looks* like. `pinned` is metadata for layouts; `parentId`\n // is metadata for hierarchy queries. Critically, **a renderer rebuild\n // during pixi's pointer-event flow would invalidate the in-flight\n // gesture** (the user clicks → drag-node pins → shape gets re-created\n // → pixi's synthesized `shape:click` for the original instance is\n // dropped). So a no-visual update must remain a no-op here.\n const patchKeys = Object.keys(patch);\n const nonVisualOnly = patchKeys.every((k) => k === 'pinned' || k === 'parentId');\n if (nonVisualOnly) return;\n\n // Position-only updates: cheap partial. Connectors anchored to this node\n // need re-routing too; queue them for the flush-time drain. Run the\n // position through `shapeRenderXY` so the render origin matches the full\n // `nodeSpec` rebuild — otherwise a `composite` card lands at its raw\n // top-left here but centred on a rebuild, so it jumps on hover / restyle.\n if ('position' in patch && patch.position && patchKeys.length === 1) {\n const shape = (this.resolveNodeStyle(node).shape ?? { kind: 'circle', radius: 10 }) as NodeShapeOptions;\n const { x, y } = shapeRenderXY(shape, patch.position);\n this._renderer.updateShape<BaseShapeSpec>(node.id, { x, y });\n this.queueIncidentConnectors(node.id);\n return;\n }\n\n // Data change: prefer `updateShape` (instance-preserving — keeps the\n // renderer's `gfxScale`, decorations, badges, effects) and fall back\n // to `removeShape + addShape` only when the new spec has a different\n // `kind` (e.g. `circle` → `rect`). `updateShape` can't safely change\n // kind because the underlying `IShape` class is fixed at construction.\n const spec = this.nodeSpec(node);\n const currentKind = this._renderer.getShapeKind(node.id);\n if (currentKind === undefined) {\n this._renderer.addShape(node.id, spec);\n } else if (currentKind === spec.kind) {\n // See `rerenderNode` for the `BaseShapeSpec` cast rationale.\n this._renderer.updateShape<BaseShapeSpec>(node.id, spec);\n } else {\n this._renderer.removeShape(node.id);\n // `removeShape` disposes attached decorations + badges — drop our tracking.\n this.nodeDecorationSlots.delete(node.id);\n this.nodeBadgeSlots.delete(node.id);\n this._renderer.addShape(node.id, spec);\n }\n this.syncNodeLabel(node.id);\n this.syncNodeDecorations(node.id);\n this.syncNodeBadges(node.id);\n this.syncGroupSyntheticDecorations(node.id);\n // Connectors anchored to this shape may need re-routing in either\n // branch — the shape's bounds can shift on a size/kind change.\n this.queueIncidentConnectors(node.id);\n }\n\n private queueIncidentConnectors(nodeId: string): void {\n for (const edge of this.store.edgesOf(nodeId, 'both')) {\n this.dirtyConnectors.add(edge.id);\n }\n // When the moved node is a collapsed group, the renderer-side anchor\n // for any descendant's edge has been re-routed to *this* group via\n // `effectiveEndpoint`. Those edges live under the descendants in the\n // store (`edge.source` / `edge.target` are never mutated), so the\n // top-level `edgesOf(group)` walk doesn't see them. Sweep the\n // descendant subtree explicitly so the connector re-routes when the\n // collapsed group is dragged.\n const node = this.store.getNode(nodeId);\n if (node && this.isCollapsedGroup(node)) {\n for (const descId of this.store.descendantsOf(nodeId)) {\n for (const edge of this.store.edgesOf(descId, 'both')) {\n this.dirtyConnectors.add(edge.id);\n }\n }\n }\n }\n\n // ─── Group helpers ────────────────────────────────────────────────────\n\n /**\n * True iff `node`'s resolved style carries a `group` field — the only\n * signal that promotes the node from a regular renderable into a\n * compound-group frame.\n *\n * Cheap to call: reads {@link resolveNodeStyle} which is already\n * memoised per render cycle through `Object.assign` of the merged\n * contributions.\n */\n isGroupNode(node: GraphNode): boolean {\n const style = this.resolveNodeStyle(node);\n return style.group !== undefined;\n }\n\n /** True when this group node's resolved style carries `group.collapsed === true`. */\n isCollapsedGroup(node: GraphNode): boolean {\n const style = this.resolveNodeStyle(node);\n return style.group?.collapsed === true;\n }\n\n /**\n * Public predicate behaviours can use to filter group nodes out of their\n * own hit pipeline. Hover / select / drag should typically skip groups\n * when the group is *expanded* (the frame is interaction-less) but treat\n * a collapsed group as a regular node. Returns one of:\n *\n * - `'none'` — the id is not a group (treat as a regular node).\n * - `'expanded'` — group, currently expanded. Behaviours wanting to honour\n * the \"interaction-less frame\" intent should early-return.\n * - `'collapsed'` — group, currently collapsed. Behaviours that act on\n * regular nodes should treat this as a normal target.\n * - `undefined` — no such node.\n *\n * The string form is preferred over a boolean pair so a future\n * `'collapsed-locked'` (or similar) can be added without breaking callers.\n */\n getGroupRole(nodeId: string): 'none' | 'expanded' | 'collapsed' | undefined {\n const node = this.store.getNode(nodeId);\n if (!node) return undefined;\n if (!this.isGroupNode(node)) return 'none';\n return this.isCollapsedGroup(node) ? 'collapsed' : 'expanded';\n }\n\n /**\n * Climb the `parentId` chain from `nodeId` (exclusive) and return the\n * first ancestor whose resolved style has `group.collapsed === true`, or\n * `undefined` if no such ancestor exists. Used to decide whether a node\n * is currently hidden (any collapsed ancestor → hidden) and where to\n * re-route an incident edge (to that collapsed ancestor).\n */\n collapsedAncestor(nodeId: string): string | undefined {\n let cur = this.store.getNode(nodeId);\n while (cur?.parentId) {\n const parent = this.store.getNode(cur.parentId);\n if (!parent) return undefined;\n if (this.isCollapsedGroup(parent)) return parent.id;\n cur = parent;\n }\n return undefined;\n }\n\n /**\n * Resolve which renderer-side shape id an edge endpoint should attach to\n * for `nodeId`. Returns the nearest collapsed-group ancestor when the\n * node is hidden, or `nodeId` unchanged when the node is visible. Pure\n * read — the store's `edge.source` / `edge.target` are never mutated.\n */\n effectiveEndpoint(nodeId: string): string {\n return this.collapsedAncestor(nodeId) ?? nodeId;\n }\n\n /**\n * Walk the `parentId` chain from `nodeId` and `add` every group ancestor\n * to {@link dirtyGroups}. Called whenever a descendant moves, is added,\n * or otherwise triggers an auto-fit recompute.\n */\n private markGroupAncestorsDirty(nodeId: string): void {\n let cur: GraphNode | undefined = this.store.getNode(nodeId);\n while (cur) {\n if (this.isGroupNode(cur)) this.dirtyGroups.add(cur.id);\n if (!cur.parentId) break;\n cur = this.store.getNode(cur.parentId);\n }\n }\n\n /**\n * After a group flips `collapsed`, every descendant changes visibility\n * and every incident edge of every descendant needs re-routing (the\n * endpoint now resolves to either the original node or to the collapsed\n * group ancestor). Walk the subtree once, re-render each descendant\n * (which re-projects `visible`), and queue incident edges for re-route.\n */\n private refreshDescendantsAndIncidentEdges(groupId: string): void {\n // Avoid re-rendering the same connector twice when both endpoints are\n // descendants of the toggled group.\n const seenEdges = new Set<string>();\n const refreshEdge = (edgeId: string): void => {\n if (seenEdges.has(edgeId)) return;\n seenEdges.add(edgeId);\n // Full rerender (not just dirtyConnectors → empty partial). On a\n // collapse-induced self-loop the new spec carries `visible: false`,\n // and on re-expand it switches back to `visible: true`. The empty\n // partial path only re-routes the path; it doesn't refresh the\n // spec's `visible` field, so the renderer's cached value would\n // survive the transition.\n this.rerenderEdge(edgeId);\n };\n for (const descId of this.store.descendantsOf(groupId)) {\n const desc = this.store.getNode(descId);\n if (!desc) continue;\n this.rerenderNode(descId);\n for (const edge of this.store.edgesOf(descId, 'both')) refreshEdge(edge.id);\n }\n // Edges of the group node itself can swap from a \"real\" endpoint to\n // the same ancestor's id when there's a nested-collapse scenario.\n for (const edge of this.store.edgesOf(groupId, 'both')) refreshEdge(edge.id);\n }\n\n /**\n * Compute the world-space AABB of the direct (one-level) children of\n * `groupId`. Returns `undefined` when the group has no children — the\n * caller falls back to whatever floor size the group's declared\n * width/height/radius provides.\n *\n * Recurses into child groups via {@link boundsOfNode} so a child whose\n * own frame has already been auto-fit contributes its current size, not\n * its stored declared size.\n */\n private directChildrenWorldBounds(\n groupId: string,\n ): { minX: number; minY: number; maxX: number; maxY: number } | undefined {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n let any = false;\n for (const childId of this.store.childrenOf(groupId)) {\n const child = this.store.getNode(childId);\n if (!child) continue;\n const local = this.boundsOfNode(child);\n if (!local) continue;\n const pos = child.position ?? { x: 0, y: 0 };\n const wx = pos.x + local.x;\n const wy = pos.y + local.y;\n if (wx < minX) minX = wx;\n if (wy < minY) minY = wy;\n if (wx + local.width > maxX) maxX = wx + local.width;\n if (wy + local.height > maxY) maxY = wy + local.height;\n any = true;\n }\n return any ? { minX, minY, maxX, maxY } : undefined;\n }\n\n /**\n * Project an expanded group's spec — apply auto-fit (when enabled),\n * compose the children-derived width/height/radius with the group's\n * declared floor, and shift `pos` so the frame wraps the bbox correctly.\n *\n * For `kind: 'rect'`: `pos` becomes top-left of the framed area; size is\n * `max(declared, childrenAABB) + 2 · padding (+ headerHeight on y)`.\n *\n * For `kind: 'circle'`: `pos` becomes the AABB centroid; `radius` is\n * `max(declared, AABB half-diagonal) + padding`. The half-diagonal is\n * the smallest enclosing-circle approximation that's still cheap\n * (`Math.hypot` over AABB half-extents); true minimum-enclosing-circle\n * (Welzl) is out of scope.\n *\n * Non-rect / non-circle group shapes pass through untouched — autoFit is\n * a no-op outside those two kinds. Domain shapes that want their own\n * fit math can extend the layer's projection later.\n */\n private projectGroupShape(\n groupId: string,\n shape: NodeShapeOptions,\n group: GroupOptions,\n pos: { x: number; y: number },\n ): { shape: NodeShapeOptions; pos: { x: number; y: number } } {\n const padding = group.padding ?? 16;\n const header = group.headerHeight ?? 0;\n const bbox = group.autoFit ? this.directChildrenWorldBounds(groupId) : undefined;\n\n if (shape.kind === 'rect') {\n const rectShape = shape as { kind: 'rect'; width: number; height: number; cornerRadius?: number };\n let width = group.width ?? rectShape.width;\n let height = group.height ?? rectShape.height;\n let nextPos = pos;\n if (bbox) {\n const childW = bbox.maxX - bbox.minX;\n const childH = bbox.maxY - bbox.minY;\n width = Math.max(width ?? 0, childW) + 2 * padding;\n height = Math.max(height ?? 0, childH) + 2 * padding + header;\n nextPos = { x: bbox.minX - padding, y: bbox.minY - padding - header };\n } else {\n // No children: honour declared dims; ensure non-zero so the frame\n // still renders something rather than a 0×0 silhouette.\n width = Math.max(width ?? 0, 1);\n height = Math.max(height ?? 0, 1);\n }\n const out: NodeShapeOptions = { ...rectShape, width, height };\n return { shape: out, pos: nextPos };\n }\n if (shape.kind === 'circle') {\n const circleShape = shape as { kind: 'circle'; radius: number };\n let radius = group.radius ?? circleShape.radius;\n let nextPos = pos;\n if (bbox) {\n const halfW = (bbox.maxX - bbox.minX) / 2;\n const halfH = (bbox.maxY - bbox.minY) / 2;\n const halfDiag = Math.hypot(halfW, halfH);\n radius = Math.max(radius ?? 0, halfDiag) + padding;\n nextPos = {\n x: bbox.minX + halfW,\n y: bbox.minY + halfH,\n };\n } else {\n radius = Math.max(radius ?? 0, 1);\n }\n const out: NodeShapeOptions = { ...circleShape, radius };\n return { shape: out, pos: nextPos };\n }\n // Non-fit-aware shape kind — pass through.\n return { shape, pos };\n }\n\n /**\n * Force a group's frame to re-project right now (outside the normal\n * flush cycle). Public escape hatch for feeds that remove children\n * individually without triggering a position change on a sibling — the\n * `node:remove` event doesn't carry the parentId, so the layer can't\n * mark the parent dirty on its own. Domain code can call this after\n * `store.removeNode` to make the auto-fit frame catch up.\n */\n recomputeGroup(groupId: string): void {\n this.dirtyGroups.add(groupId);\n this.drainDirtyGroups();\n }\n\n /**\n * Drain {@link dirtyGroups} in deepest-first order. Each pop re-renders\n * the group (re-running `nodeSpec` with the latest auto-fit math) and\n * marks the group's own parent chain dirty so a multi-level nested\n * group cascade settles in one flush.\n *\n * Bounded by `MAX_PASSES` to defend against a pathological cycle (which\n * the cycle-rejecting store should already prevent on insert, but the\n * extra guard is cheap).\n */\n private drainDirtyGroups(): void {\n const MAX_PASSES = 32;\n let pass = 0;\n while (this.dirtyGroups.size > 0 && pass++ < MAX_PASSES) {\n // Sort current set by ancestor-chain depth, deepest first. New ids\n // that get added during the pass will be processed in the next\n // outer iteration — bounded by MAX_PASSES.\n const ids = [...this.dirtyGroups];\n this.dirtyGroups.clear();\n ids.sort((a, b) => this.depthOf(b) - this.depthOf(a));\n for (const id of ids) {\n const node = this.store.getNode(id);\n if (!node) continue;\n this.rerenderNode(id);\n // Mark the group's incident edges dirty — the frame may have\n // moved or resized, shifting where boundary anchors land.\n for (const edge of this.store.edgesOf(id, 'both')) {\n this.dirtyConnectors.add(edge.id);\n }\n // Propagate the size change up to the parent group, if any.\n if (node.parentId) {\n const parent = this.store.getNode(node.parentId);\n if (parent && this.isGroupNode(parent)) {\n this.dirtyGroups.add(parent.id);\n }\n }\n }\n }\n }\n\n /**\n * Count of ancestors between `nodeId` and the root (`parentId === undefined`).\n * Used by {@link drainDirtyGroups} to order deepest first so a child\n * group recomputes before any group that depends on its bounds.\n */\n private depthOf(nodeId: string): number {\n let d = 0;\n let cur = this.store.getNode(nodeId);\n while (cur?.parentId) {\n d++;\n cur = this.store.getNode(cur.parentId);\n }\n return d;\n }\n\n /**\n * Project the synthetic group-only decorations onto the renderer:\n * - the `+` / `−` toggle button at the group's bottom anchor; and\n * - a centred count badge (label decoration) when the group is\n * collapsed, showing the number of hidden descendants.\n *\n * Called on every node lifecycle event for group nodes. Cleared\n * automatically when `style.group` goes away (the slots get `null` so\n * any previous mount disposes).\n */\n private syncGroupSyntheticDecorations(id: string): void {\n if (!this._renderer) return;\n const node = this.store.getNode(id);\n if (!node) return;\n const style = this.resolveNodeStyle(node);\n const group = style.group;\n if (!group) {\n this._renderer.setDecoration(id, 'group-toggle', null);\n this._renderer.setDecoration(id, 'group-count', null);\n this.lastCollapsedByGroup.delete(id);\n return;\n }\n const isCollapsed = group.collapsed === true;\n this.lastCollapsedByGroup.set(id, isCollapsed);\n // Toggle button — present on every group, glyph mirrors collapsed state.\n // Placement is configurable via `group.togglePlacement`: a keyword\n // (`'bottom'`, `'inside-bottom'`, …) resolves against the host AABB,\n // or a `{ x, y }` object pins the toggle to exact shape-local coords.\n // Default `'bottom'` — centred just below the silhouette, matching\n // the \"small bubble attached to the rim\" pattern in the reference UI.\n // The behaviour does its own canvas-level hit math, so outside-\n // silhouette placements remain fully clickable.\n const tp = group.togglePlacement;\n const placementStyle =\n typeof tp === 'object' && tp !== null\n ? { position: tp }\n : { placement: tp ?? 'bottom' };\n this._renderer.setDecoration(id, 'group-toggle', {\n kind: 'toggle',\n style: {\n state: isCollapsed ? 'plus' : 'minus',\n radius: 10,\n ...placementStyle,\n },\n });\n if (isCollapsed) {\n let count = 0;\n for (const _ of this.store.descendantsOf(id)) count++;\n this._renderer.setDecoration(id, 'group-count', {\n kind: 'label',\n style: {\n content: {\n kind: 'text',\n text: String(count),\n fill: 0xffffff,\n fontSize: 14,\n fontWeight: 700,\n },\n placement: 'inside-center',\n },\n });\n } else {\n this._renderer.setDecoration(id, 'group-count', null);\n }\n }\n\n private updateEdgeConnector(edge: GraphEdge, _patch: Partial<GraphEdge>): void {\n if (!this._renderer) return;\n // Prefer `updateConnector` (instance-preserving — keeps `strokeWidthScale`\n // from `EdgeSizeLODBehaviour`, attached decorations, effects). The\n // underlying `recomputeConnectorPath` rebuilds the routed geometry,\n // so router / pathStyle / marker changes still apply cleanly.\n const spec = this.edgeSpec(edge);\n if (this._renderer.hasConnector(edge.id)) {\n this._renderer.updateConnector(edge.id, spec);\n } else {\n this._renderer.addConnector(edge.id, spec);\n }\n this.syncEdgeLabel(edge.id);\n }\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\n/**\n * Map a node's canonical `position` to the render origin its shape expects.\n *\n * Most shapes (`circle`, `regular-polygon`, …) are centred at `(x, y)`, so the\n * position passes through unchanged. The `composite` shape draws from its\n * top-left corner, so it's shifted by `-size/2` to sit centred on `position` —\n * matching how layouts (and edge anchoring / obstacle bounds) treat the\n * position as the node centre.\n *\n * Both the full {@link GraphLayer.nodeSpec} rebuild and the position-only fast\n * path in `updateNodeShape` route through this, so a `composite` card lands at\n * the same place whether it's added, dragged, re-laid-out, or re-rendered on\n * hover — otherwise it visibly jumps between the two paths.\n */\nfunction shapeRenderXY(\n shape: NodeShapeOptions,\n pos: { x: number; y: number },\n): { x: number; y: number } {\n const sc = shape as { kind?: string; width?: number; height?: number };\n if (sc.kind === 'composite' && typeof sc.width === 'number' && typeof sc.height === 'number') {\n return { x: pos.x - sc.width / 2, y: pos.y - sc.height / 2 };\n }\n return { x: pos.x, y: pos.y };\n}\n\n/**\n * Rewrite a {@link NodeShapeOptions} so its intrinsic size fields express\n * the unified `style.size` value. Returns the *same* reference for shape\n * kinds with no canonical size axis (`polygon`, custom) — callers can use\n * `===` to short-circuit a write.\n *\n * Per-kind mapping (see {@link NodeStyle.size} TSDoc):\n *\n * circle / regular-polygon → radius = size\n * rect → width = height = 2 * size\n * arc → outerR = size, innerR scaled proportionally\n * star → outerRadius = size, innerRadius scaled\n * polygon / custom → passthrough (no normalized size axis)\n */\nfunction normalizeShapeSize(shape: NodeShapeOptions, size: number): NodeShapeOptions {\n // CustomShapeOption widens `kind` to `string & {}`, which intersects the\n // built-in literal kinds in TS's type system — so a plain `switch` on\n // `shape.kind` doesn't narrow the spread away from the custom branch.\n // We dispatch via the literal kind explicitly and re-assert the specific\n // shape type per branch.\n switch (shape.kind) {\n case 'circle':\n return { ...(shape as CircleShapeOption), radius: size };\n case 'regular-polygon':\n return { ...(shape as RegularPolygonShapeOption), radius: size };\n case 'rect': {\n const side = size * 2;\n return { ...(shape as RectShapeOption), width: side, height: side };\n }\n case 'arc': {\n const arc = shape as ArcShapeOption;\n const ratio = arc.outerR > 0 ? arc.innerR / arc.outerR : 0;\n return { ...arc, outerR: size, innerR: size * ratio };\n }\n case 'star': {\n const star = shape as StarShapeOption;\n const ratio = star.outerRadius > 0 ? star.innerRadius / star.outerRadius : 0;\n return { ...star, outerRadius: size, innerRadius: size * ratio };\n }\n default:\n // `polygon` carries its own vertex array; `custom` is opaque. Neither\n // has a uniform size axis we can rewrite without ambiguity, so we\n // leave them alone and signal \"no-op\" via referential equality.\n return shape;\n }\n}\n\n/**\n * Build the effective `NodeOption` by merging the caller's option (if any)\n * with {@link DEFAULT_NODE_STATES}. Consumer entries on `state[name]` win\n * outright — no per-field deep merge. When `applyDefaults` is `false`,\n * just returns the caller's option verbatim.\n */\nfunction mergeNodeOptionWithDefaults(\n opt: NodeOption | undefined,\n applyDefaults: boolean,\n): NodeOption | undefined {\n if (!applyDefaults) return opt;\n const mergedState = { ...DEFAULT_NODE_STATES, ...(opt?.state ?? {}) };\n return { ...(opt ?? {}), state: mergedState };\n}\n\n/** Sibling of {@link mergeNodeOptionWithDefaults} for edges. */\nfunction mergeEdgeOptionWithDefaults(\n opt: EdgeOption | undefined,\n applyDefaults: boolean,\n): EdgeOption | undefined {\n if (!applyDefaults) return opt;\n const mergedState = { ...DEFAULT_EDGE_STATES, ...(opt?.state ?? {}) };\n return { ...(opt ?? {}), state: mergedState };\n}\n\n/**\n * Split a `NodeDecorationSpec` / `EdgeDecorationSpec` (a discriminated\n * union with `{ kind, id?, remove?, ...style }`) into the renderer-facing\n * `{ kind, style }` shape. Strips the resolver-only `id` and `remove`\n * fields — they're consumed during {@link resolveNodeDecorations} /\n * {@link resolveEdgeDecorations} and aren't part of the decoration's\n * style payload.\n */\nfunction splitDecorationSpec(\n spec: NodeDecorationSpec | EdgeDecorationSpec,\n): { kind: string; style: Record<string, unknown> } {\n const { kind, id: _id, remove: _remove, ...style } = spec as NodeDecorationSpec & {\n id?: string;\n remove?: boolean;\n };\n return { kind, style: style as Record<string, unknown> };\n}\n\n/**\n * Translate a graph-level {@link NodeBadge} into the canvas-level\n * {@link BadgeOptions} `setBadge` expects.\n *\n * Sugar fields collapse onto the structured shape spec:\n * - `fill` → first `solid` fill layer; `icon` → second fill layer stacked\n * on top (mirrors the node-body fill stack in `nodeSpec`).\n * - `strokeColor` + `strokeWidth` → `stroke` on the shape spec.\n * - `labelText` (+ colour / size) → a `'label'` decoration on the badge,\n * centred on the plate.\n *\n * Nested `decorations` are id-keyed (slot id falls back to `${kind}#<i>`);\n * `effects` flatten into a `{ [kind]: { kind, style } }` record. The\n * canvas-level `setBadge` projects both maps internally.\n */\nfunction nodeBadgeToCanvasOptions(badge: NodeBadge): BadgeOptions {\n const fillLayers: ShapeFillLayer[] = [];\n if (badge.fill !== undefined) {\n fillLayers.push({ kind: 'solid', color: badge.fill });\n }\n if (badge.icon !== undefined) {\n fillLayers.push(badge.icon as ShapeFillLayer);\n }\n\n const strokeWidth = badge.strokeWidth ?? 0;\n const stroke =\n badge.strokeColor !== undefined && strokeWidth > 0\n ? { color: badge.strokeColor, width: strokeWidth }\n : undefined;\n\n const shape = {\n ...(badge.shape as unknown as Record<string, unknown>),\n ...(fillLayers.length > 0 ? { fill: fillLayers } : {}),\n ...(stroke ? { stroke } : {}),\n ...(badge.alpha !== undefined ? { alpha: badge.alpha } : {}),\n ...(badge.zIndex !== undefined ? { zIndex: badge.zIndex } : {}),\n } as BadgeOptions['shape'];\n\n const decorations: Record<string, DecorationSpec> = {};\n if (badge.decorations) {\n badge.decorations.forEach((spec, i) => {\n if (spec.remove) return;\n const slotId = spec.id ?? `${spec.kind}#${i}`;\n const { kind, style } = splitDecorationSpec(spec);\n decorations[slotId] = { kind, style } as DecorationSpec;\n });\n }\n if (badge.labelText !== undefined) {\n decorations.label = {\n kind: 'label',\n style: {\n content: {\n kind: 'text',\n text: badge.labelText,\n ...(badge.labelColor !== undefined ? { fill: badge.labelColor } : {}),\n ...(badge.labelFontSize !== undefined ? { fontSize: badge.labelFontSize } : {}),\n },\n placement: 'center',\n },\n } as DecorationSpec;\n }\n\n const effects: Record<string, EffectSpec> = {};\n if (badge.effects) {\n for (const [kind, style] of Object.entries(badge.effects)) {\n if (style === undefined || style === null) continue;\n effects[kind] = { kind, style } as EffectSpec;\n }\n }\n\n return {\n shape,\n placement: badge.placement,\n ...(badge.origin !== undefined ? { origin: badge.origin } : {}),\n ...(badge.offsetX !== undefined ? { offsetX: badge.offsetX } : {}),\n ...(badge.offsetY !== undefined ? { offsetY: badge.offsetY } : {}),\n ...(Object.keys(decorations).length > 0 ? { decorations } : {}),\n ...(Object.keys(effects).length > 0 ? { effects } : {}),\n };\n}\n\n/**\n * Edge-side counterpart of {@link nodeBadgeToCanvasOptions}. Translates a\n * graph-level {@link EdgeBadge} into the canvas-level {@link BadgeOptions}\n * `setBadge` expects, carrying the path-only fields (`pathOffset`,\n * `autoRotate`, `keepUpright`) through verbatim. The sugar-to-canvas\n * collapse is identical to the node-side helper — the only structural\n * difference is the `placement` is an {@link EdgeBadgePlacement}, which\n * `setBadge` dispatches on at runtime when the host is a connector.\n */\nfunction edgeBadgeToCanvasOptions(badge: EdgeBadge): BadgeOptions {\n const fillLayers: ShapeFillLayer[] = [];\n if (badge.fill !== undefined) {\n fillLayers.push({ kind: 'solid', color: badge.fill });\n }\n if (badge.icon !== undefined) {\n fillLayers.push(badge.icon as ShapeFillLayer);\n }\n\n const strokeWidth = badge.strokeWidth ?? 0;\n const stroke =\n badge.strokeColor !== undefined && strokeWidth > 0\n ? { color: badge.strokeColor, width: strokeWidth }\n : undefined;\n\n const shape = {\n ...(badge.shape as unknown as Record<string, unknown>),\n ...(fillLayers.length > 0 ? { fill: fillLayers } : {}),\n ...(stroke ? { stroke } : {}),\n ...(badge.alpha !== undefined ? { alpha: badge.alpha } : {}),\n ...(badge.zIndex !== undefined ? { zIndex: badge.zIndex } : {}),\n } as BadgeOptions['shape'];\n\n const decorations: Record<string, DecorationSpec> = {};\n if (badge.decorations) {\n badge.decorations.forEach((spec, i) => {\n if (spec.remove) return;\n const slotId = spec.id ?? `${spec.kind}#${i}`;\n const { kind, style } = splitDecorationSpec(spec);\n decorations[slotId] = { kind, style } as DecorationSpec;\n });\n }\n if (badge.labelText !== undefined) {\n decorations.label = {\n kind: 'label',\n style: {\n content: {\n kind: 'text',\n text: badge.labelText,\n ...(badge.labelColor !== undefined ? { fill: badge.labelColor } : {}),\n ...(badge.labelFontSize !== undefined ? { fontSize: badge.labelFontSize } : {}),\n },\n placement: 'center',\n },\n } as DecorationSpec;\n }\n\n const effects: Record<string, EffectSpec> = {};\n if (badge.effects) {\n for (const [kind, style] of Object.entries(badge.effects)) {\n if (style === undefined || style === null) continue;\n effects[kind] = { kind, style } as EffectSpec;\n }\n }\n\n return {\n shape,\n placement: badge.placement,\n ...(badge.origin !== undefined ? { origin: badge.origin } : {}),\n ...(badge.offsetX !== undefined ? { offsetX: badge.offsetX } : {}),\n ...(badge.offsetY !== undefined ? { offsetY: badge.offsetY } : {}),\n ...(badge.pathOffset !== undefined ? { pathOffset: badge.pathOffset } : {}),\n ...(badge.autoRotate !== undefined ? { autoRotate: badge.autoRotate } : {}),\n ...(badge.keepUpright !== undefined ? { keepUpright: badge.keepUpright } : {}),\n ...(Object.keys(decorations).length > 0 ? { decorations } : {}),\n ...(Object.keys(effects).length > 0 ? { effects } : {}),\n };\n}\n\n/**\n * Build a `ShapeLabelStyle` from the flat label fields on a NodeStyle.\n * Returns `undefined` when there's no `labelText` — a label without text\n * is meaningless, and silently emitting an empty-text label would show\n * a 0×0 decoration on nodes that only inherit layer-level label *settings*\n * without supplying any text.\n */\nfunction buildShapeLabelStyle(style: Partial<NodeStyle>): ShapeLabelStyle | undefined {\n if (style.labelText === undefined) {\n return undefined;\n }\n return {\n content: {\n kind: 'text',\n text: style.labelText ?? '',\n ...(style.labelColor !== undefined ? { fill: style.labelColor } : {}),\n ...(style.labelFontSize !== undefined ? { fontSize: style.labelFontSize } : {}),\n ...(style.labelFontFamily !== undefined ? { fontFamily: style.labelFontFamily } : {}),\n ...(style.labelFontWeight !== undefined ? { fontWeight: style.labelFontWeight } : {}),\n ...(style.labelFontStyle !== undefined ? { fontStyle: style.labelFontStyle } : {}),\n ...(style.labelAlign !== undefined ? { align: style.labelAlign } : {}),\n ...(style.labelLineHeight !== undefined ? { lineHeight: style.labelLineHeight } : {}),\n ...(style.labelLetterSpacing !== undefined ? { letterSpacing: style.labelLetterSpacing } : {}),\n },\n ...(style.labelPlacement !== undefined ? { placement: style.labelPlacement } : {}),\n ...(style.labelRotation !== undefined ? { rotation: style.labelRotation } : {}),\n ...(style.labelAlpha !== undefined ? { alpha: style.labelAlpha } : {}),\n ...(style.labelMinFontSize !== undefined ? { minFontSize: style.labelMinFontSize } : {}),\n ...(style.labelPriority !== undefined ? { priority: style.labelPriority } : {}),\n ...(style.labelCollisionGroup !== undefined ? { collisionGroup: style.labelCollisionGroup } : {}),\n ...(style.labelForceShow !== undefined ? { forceShow: style.labelForceShow } : {}),\n ...(style.labelMinZoom !== undefined || style.labelMaxZoom !== undefined\n ? {\n visibility: {\n ...(style.labelMinZoom !== undefined ? { minZoom: style.labelMinZoom } : {}),\n ...(style.labelMaxZoom !== undefined ? { maxZoom: style.labelMaxZoom } : {}),\n },\n }\n : {}),\n ...(style.labelOffsetX !== undefined || style.labelOffsetY !== undefined\n ? {\n offset: {\n ...(style.labelOffsetX !== undefined ? { x: style.labelOffsetX } : {}),\n ...(style.labelOffsetY !== undefined ? { y: style.labelOffsetY } : {}),\n },\n }\n : {}),\n ...(buildLabelBackground(style) !== undefined ? { background: buildLabelBackground(style)! } : {}),\n };\n}\n\n/** Build the `LabelBackground` payload from flat `labelBackground*` fields. */\nfunction buildLabelBackground(\n style: Partial<NodeStyle> | Partial<EdgeStyle>,\n): ShapeLabelStyle['background'] | undefined {\n if (\n style.labelBackgroundFill === undefined\n && style.labelBackgroundAlpha === undefined\n && style.labelBackgroundStrokeColor === undefined\n && style.labelBackgroundStrokeWidth === undefined\n && style.labelBackgroundPadding === undefined\n && style.labelBackgroundCornerRadius === undefined\n ) {\n return undefined;\n }\n return {\n ...(style.labelBackgroundFill !== undefined ? { fill: style.labelBackgroundFill } : {}),\n ...(style.labelBackgroundAlpha !== undefined ? { fillAlpha: style.labelBackgroundAlpha } : {}),\n ...(style.labelBackgroundStrokeColor !== undefined ? { stroke: style.labelBackgroundStrokeColor } : {}),\n ...(style.labelBackgroundStrokeWidth !== undefined ? { strokeWidth: style.labelBackgroundStrokeWidth } : {}),\n ...(style.labelBackgroundPadding !== undefined ? { padding: style.labelBackgroundPadding } : {}),\n ...(style.labelBackgroundCornerRadius !== undefined ? { radius: style.labelBackgroundCornerRadius } : {}),\n };\n}\n\n/**\n * Resolve every Resolvable field on a ResolvableNodeStyle against `subject`\n * (raw input data at insert-time, or stored GraphNode at render-time).\n */\nfunction resolveNodeStyleFields<D>(\n cfg: ResolvableNodeStyle<D>,\n subject: D,\n): Partial<NodeStyle> {\n const out: Record<string, unknown> = {};\n for (const k of Object.keys(cfg) as (keyof ResolvableNodeStyle<D>)[]) {\n const v = resolveField(cfg[k] as never, subject);\n if (v !== undefined) out[k as string] = v;\n }\n return out as Partial<NodeStyle>;\n}\n\n/**\n * Build a `ConnectorLabelStyle` from the flat label fields on an EdgeStyle.\n * Returns `undefined` when there's no `labelText` — same rationale as\n * {@link buildShapeLabelStyle}.\n */\nfunction buildConnectorLabelStyle(style: Partial<EdgeStyle>): ConnectorLabelStyle | undefined {\n if (style.labelText === undefined) {\n return undefined;\n }\n return {\n content: {\n kind: 'text',\n text: style.labelText ?? '',\n ...(style.labelColor !== undefined ? { fill: style.labelColor } : {}),\n ...(style.labelFontSize !== undefined ? { fontSize: style.labelFontSize } : {}),\n ...(style.labelFontFamily !== undefined ? { fontFamily: style.labelFontFamily } : {}),\n ...(style.labelFontWeight !== undefined ? { fontWeight: style.labelFontWeight } : {}),\n ...(style.labelFontStyle !== undefined ? { fontStyle: style.labelFontStyle } : {}),\n ...(style.labelAlign !== undefined ? { align: style.labelAlign } : {}),\n ...(style.labelLineHeight !== undefined ? { lineHeight: style.labelLineHeight } : {}),\n ...(style.labelLetterSpacing !== undefined ? { letterSpacing: style.labelLetterSpacing } : {}),\n },\n ...(style.labelPlacement !== undefined ? { placement: style.labelPlacement } : {}),\n ...(style.labelPathOffset !== undefined ? { pathOffset: style.labelPathOffset } : {}),\n ...(style.labelAutoRotate !== undefined ? { autoRotate: style.labelAutoRotate } : {}),\n ...(style.labelKeepUpright !== undefined ? { keepUpright: style.labelKeepUpright } : {}),\n ...(style.labelAlpha !== undefined ? { alpha: style.labelAlpha } : {}),\n ...(style.labelMinFontSize !== undefined ? { minFontSize: style.labelMinFontSize } : {}),\n ...(style.labelPriority !== undefined ? { priority: style.labelPriority } : {}),\n ...(style.labelCollisionGroup !== undefined ? { collisionGroup: style.labelCollisionGroup } : {}),\n ...(style.labelForceShow !== undefined ? { forceShow: style.labelForceShow } : {}),\n ...(style.labelMinZoom !== undefined || style.labelMaxZoom !== undefined\n ? {\n visibility: {\n ...(style.labelMinZoom !== undefined ? { minZoom: style.labelMinZoom } : {}),\n ...(style.labelMaxZoom !== undefined ? { maxZoom: style.labelMaxZoom } : {}),\n },\n }\n : {}),\n ...(style.labelOffsetX !== undefined || style.labelOffsetY !== undefined\n ? {\n offset: {\n ...(style.labelOffsetX !== undefined ? { x: style.labelOffsetX } : {}),\n ...(style.labelOffsetY !== undefined ? { y: style.labelOffsetY } : {}),\n },\n }\n : {}),\n ...(buildLabelBackground(style) !== undefined ? { background: buildLabelBackground(style)! } : {}),\n };\n}\n\n/**\n * Resolve every Resolvable field on a ResolvableEdgeStyle against `subject`.\n */\nfunction resolveEdgeStyleFields<D>(\n cfg: ResolvableEdgeStyle<D>,\n subject: D,\n): Partial<EdgeStyle> {\n const out: Record<string, unknown> = {};\n for (const k of Object.keys(cfg) as (keyof ResolvableEdgeStyle<D>)[]) {\n const v = resolveField(cfg[k] as never, subject);\n if (v !== undefined) out[k as string] = v;\n }\n return out as Partial<EdgeStyle>;\n}\n","/**\n * `MiniMapLayer` — bird's-eye overview of a `GraphLayer` with a draggable\n * viewport indicator.\n *\n * Implemented as a `ScreenLayer` rather than a self-hosted pixi `Application`\n * — much cheaper, no extra GPU surface, and pans/zooms/visibility integrate\n * with the main canvas naturally. The minimap occupies a fixed\n * `width × height` rectangle anchored to a corner of the viewport.\n *\n * Cross-layer dependency declared via `graphLayerId` per the canvas\n * architecture rule: no inference of \"the only graph layer\". You must point\n * the minimap at a specific id.\n *\n * @example\n * ```ts\n * const graph = new GraphLayer({ id: 'graph', options: {} });\n * canvas.layers.add(graph);\n *\n * const minimap = new MiniMapLayer({\n * id: 'minimap',\n * options: { graphLayerId: 'graph', position: 'bottom-right' },\n * });\n * canvas.layers.add(minimap);\n * ```\n */\n\nimport { Container, FederatedPointerEvent, Graphics } from 'pixi.js';\nimport { ScreenLayer, type CanvasContext, type ScreenLayerHit } from '@invana/canvas';\nimport type { LayerOptions, Rect } from '@invana/canvas';\n\nimport { GraphLayer } from './GraphLayer';\nimport type { GraphNode } from '../store/types';\nimport type { EdgeStyle, NodeStyle } from './types';\n\n/** Anchor corner inside the canvas viewport. */\nexport type MiniMapPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\n/** Constructor options for `MiniMapLayer`. */\nexport interface MiniMapLayerOptions {\n /** Required — the `GraphLayer` id this minimap mirrors. */\n graphLayerId: string;\n\n /** Minimap width in screen pixels. Default `200`. */\n width?: number;\n /** Minimap height in screen pixels. Default `150`. */\n height?: number;\n /** Background fill `0xRRGGBB`. Default `0x1a1a2e`. */\n backgroundColor?: number;\n /** Border colour `0xRRGGBB`. Default `0x444444`. */\n borderColor?: number;\n /** Border stroke width. Default `1`. */\n borderWidth?: number;\n\n /** Viewport indicator fill. Default `0x4a90d9`. */\n viewportFill?: number;\n /** Viewport indicator stroke. Default `0x2a70b9`. */\n viewportStroke?: number;\n /** Viewport indicator fill alpha 0–1. Default `0.3`. */\n viewportFillAlpha?: number;\n /** Viewport indicator stroke width. Default `2`. */\n viewportStrokeWidth?: number;\n\n /** World-space padding around node bounds. Default `20`. */\n padding?: number;\n /** Whether dragging the minimap pans the main camera. Default `true`. */\n enableDrag?: boolean;\n /** Anchor corner. Default `'bottom-right'`. */\n position?: MiniMapPosition;\n /**\n * Inset from the chosen corner, in screen pixels. Pass a single number for a\n * symmetric inset, or `{ x, y }` for independent horizontal / vertical insets\n * (e.g. to bottom-align the minimap with a control rail while clearing its\n * width). A missing axis on the object form falls back to `10`. Default `10`.\n */\n margin?: number | { x?: number; y?: number };\n}\n\nconst DEFAULTS: Required<Omit<MiniMapLayerOptions, 'graphLayerId'>> = {\n width: 200,\n height: 150,\n backgroundColor: 0x1a1a2e,\n borderColor: 0x444444,\n borderWidth: 1,\n viewportFill: 0x4a90d9,\n viewportStroke: 0x2a70b9,\n viewportFillAlpha: 0.3,\n viewportStrokeWidth: 2,\n padding: 20,\n enableDrag: true,\n position: 'bottom-right',\n margin: 10,\n};\n\ninterface Bounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\ninterface MiniMapState {\n readonly _placeholder?: never;\n}\n\nexport class MiniMapLayer extends ScreenLayer<\n MiniMapLayerOptions,\n MiniMapState,\n Record<string, never>,\n never,\n ScreenLayerHit\n> {\n private opts: Required<Omit<MiniMapLayerOptions, 'graphLayerId'>>;\n private readonly graphLayerId: string;\n\n private graph: GraphLayer | null = null;\n private ctxRef: CanvasContext | null = null;\n\n /** Inner content container (the minimap's drawable area). */\n private inner: Container | null = null;\n private bgGfx: Graphics | null = null;\n private worldGfx: Graphics | null = null;\n private viewportGfx: Graphics | null = null;\n\n /** Per-frame projection scale + offset (world → minimap-local). */\n private scale = 1;\n private offsetX = 0;\n private offsetY = 0;\n\n /** Drag state. */\n private isDragging = false;\n private dragOffsetX = 0;\n private dragOffsetY = 0;\n\n /** ResizeObserver disposer. */\n private offResize: (() => void) | null = null;\n private offCameraPan: (() => void) | null = null;\n private offCameraZoom: (() => void) | null = null;\n\n constructor(opts: LayerOptions<MiniMapLayerOptions>) {\n super({\n ...opts,\n zIndex: opts.zIndex ?? 1000,\n cullable: opts.cullable ?? false,\n hittable: opts.hittable ?? false,\n });\n this.graphLayerId = opts.options.graphLayerId;\n this.opts = { ...DEFAULTS, ...opts.options, graphLayerId: undefined } as typeof DEFAULTS;\n }\n\n protected createState(): MiniMapState {\n return {};\n }\n\n protected override onMount(ctx: CanvasContext): void {\n const graph = ctx.layers.get<GraphLayer>(this.graphLayerId);\n if (!graph) {\n throw new Error(\n `MiniMapLayer \"${this.id}\": graph layer \"${this.graphLayerId}\" not found. ` +\n `Add the GraphLayer before MiniMapLayer.`,\n );\n }\n this.graph = graph;\n this.ctxRef = ctx;\n\n // Build the screen-space minimap container.\n this.inner = new Container();\n this.inner.label = `${this.id}-inner`;\n this.bgGfx = new Graphics();\n this.worldGfx = new Graphics();\n this.viewportGfx = new Graphics();\n this.inner.addChild(this.bgGfx);\n this.inner.addChild(this.worldGfx);\n this.inner.addChild(this.viewportGfx);\n this.container.addChild(this.inner);\n\n if (this.opts.enableDrag) this.wireInteractions();\n\n this.layoutPosition();\n this.repaint();\n\n // Re-paint when graph data changes or the camera moves.\n this.offCameraPan = ctx.events.on('camera:pan', () => this.repaint());\n this.offCameraZoom = ctx.events.on('camera:zoom', () => this.repaint());\n const offDataChanged = graph.events.on('data:changed', () => this.repaint());\n\n if (typeof ResizeObserver !== 'undefined' && ctx.canvasElement) {\n const ro = new ResizeObserver(() => {\n this.layoutPosition();\n this.repaint();\n });\n ro.observe(ctx.canvasElement);\n this.offResize = () => ro.disconnect();\n }\n\n // Subscription to data:changed returns an unsubscribe function — capture it\n // so we drop it on unmount.\n const prevOffResize = this.offResize;\n this.offResize = () => {\n offDataChanged();\n prevOffResize?.();\n };\n }\n\n protected override onUnmount(): void {\n this.offCameraPan?.();\n this.offCameraZoom?.();\n this.offResize?.();\n this.offCameraPan = null;\n this.offCameraZoom = null;\n this.offResize = null;\n\n this.inner?.removeFromParent();\n this.inner?.destroy({ children: true });\n this.inner = null;\n this.bgGfx = null;\n this.worldGfx = null;\n this.viewportGfx = null;\n this.graph = null;\n this.ctxRef = null;\n }\n\n hitTest(): ScreenLayerHit | null {\n return null;\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /** Force a re-paint. Cheap — call after mutating colours / sizes externally. */\n refresh(): void {\n this.repaint();\n }\n\n setOptions(patch: Partial<Omit<MiniMapLayerOptions, 'graphLayerId'>>): void {\n this.opts = { ...this.opts, ...patch };\n this.layoutPosition();\n this.repaint();\n }\n\n // ─── Layout ─────────────────────────────────────────────────────────────\n\n private viewportSize(): { width: number; height: number } {\n const el = this.ctxRef?.canvasElement;\n if (el) return { width: el.clientWidth || 800, height: el.clientHeight || 600 };\n return { width: 800, height: 600 };\n }\n\n private layoutPosition(): void {\n if (!this.inner) return;\n const { width, height, position, margin } = this.opts;\n const vp = this.viewportSize();\n // Resolve symmetric (number) or per-axis ({ x, y }) insets; missing axis → 10.\n const mx = typeof margin === 'number' ? margin : (margin.x ?? 10);\n const my = typeof margin === 'number' ? margin : (margin.y ?? 10);\n let x = 0;\n let y = 0;\n switch (position) {\n case 'top-left':\n x = mx;\n y = my;\n break;\n case 'top-right':\n x = vp.width - width - mx;\n y = my;\n break;\n case 'bottom-left':\n x = mx;\n y = vp.height - height - my;\n break;\n case 'bottom-right':\n x = vp.width - width - mx;\n y = vp.height - height - my;\n break;\n }\n this.inner.position.set(x, y);\n }\n\n // ─── Painting ───────────────────────────────────────────────────────────\n\n private repaint(): void {\n if (!this.inner || !this.graph || !this.ctxRef) return;\n this.projectBounds(this.effectiveBounds());\n this.paintBackground();\n this.paintWorld();\n this.paintViewportIndicator();\n }\n\n private paintBackground(): void {\n const g = this.bgGfx;\n if (!g) return;\n const { width, height, backgroundColor, borderColor, borderWidth } = this.opts;\n g.clear();\n g.rect(0, 0, width, height).fill(backgroundColor);\n if (borderWidth > 0) {\n g.rect(0, 0, width, height).stroke({ color: borderColor, width: borderWidth });\n }\n }\n\n private paintWorld(): void {\n const g = this.worldGfx;\n const graph = this.graph;\n if (!g || !graph) return;\n g.clear();\n const renderer = graph.getRenderer();\n\n // Edges first so node markers cover them at intersections. Use the actual\n // routed polyline from the renderer — preserves orthogonal kinks, bezier\n // curves, waypoints, anchor offsets, everything the canvas drew. Falls\n // back to a straight endpoint-to-endpoint line only when the renderer\n // isn't available (pre-mount) or hasn't installed the connector yet.\n for (const edge of graph.store.edges()) {\n const edgeStyle = (edge.style as Partial<EdgeStyle> | undefined) ?? {};\n const stroke = typeof edgeStyle.strokeColor === 'number' ? edgeStyle.strokeColor : 0x666666;\n\n const polyline = renderer?.getConnectorPolyline(edge.id);\n if (polyline && polyline.length >= 2) {\n const first = this.worldToMinimap(polyline[0]!.x, polyline[0]!.y);\n g.moveTo(first.x, first.y);\n for (let i = 1; i < polyline.length; i++) {\n const p = this.worldToMinimap(polyline[i]!.x, polyline[i]!.y);\n g.lineTo(p.x, p.y);\n }\n g.stroke({ width: 1, color: stroke });\n continue;\n }\n\n const src = graph.store.getNode(edge.source);\n const dst = graph.store.getNode(edge.target);\n if (!src || !dst) continue;\n const sp = src.position ?? { x: 0, y: 0 };\n const tp = dst.position ?? { x: 0, y: 0 };\n const p1 = this.worldToMinimap(sp.x, sp.y);\n const p2 = this.worldToMinimap(tp.x, tp.y);\n g.moveTo(p1.x, p1.y);\n g.lineTo(p2.x, p2.y);\n g.stroke({ width: 1, color: stroke });\n }\n\n // Nodes — ask the renderer for the world-space AABB of whatever it\n // actually drew (circle, rect, arc, polygon, star, custom kind). The\n // minimap paints each shape as a small rect at its true footprint —\n // geometry-driven, no per-kind switching. Fill colour reads from the\n // per-node `style.bgFill` when concrete; falls back to a neutral\n // green-grey for the layer-template / resolver case (the minimap\n // doesn't run the full style resolution pipeline).\n for (const node of graph.store.nodes()) {\n const bounds = renderer?.getShapeWorldBounds(node.id) ?? this.fallbackNodeBounds(node);\n if (!bounds) continue;\n const tl = this.worldToMinimap(bounds.x, bounds.y);\n const br = this.worldToMinimap(bounds.x + bounds.width, bounds.y + bounds.height);\n const w = Math.max(2, br.x - tl.x);\n const h = Math.max(2, br.y - tl.y);\n\n const nodeStyle = (node.style as Partial<NodeStyle> | undefined) ?? {};\n const fillColor = typeof nodeStyle.bgFill === 'number' ? nodeStyle.bgFill : 0x4caf50;\n\n g.rect(tl.x, tl.y, w, h).fill(fillColor);\n }\n }\n\n /**\n * Pre-mount / pre-install fallback for shape bounds. Used when the renderer\n * hasn't yet built an instance for a node (very brief window — the layer's\n * `data:changed` event repaints the minimap as soon as the renderer catches\n * up).\n *\n * Delegates to {@link GraphLayer.boundsOfNode}, which routes through the\n * shape registry's `static boundsOf` hook — built-in and custom shape\n * kinds flow through the same code path. Falls back to a 32px square\n * AABB centred on the node's stored position when the resolved shape\n * isn't registered or its ctor doesn't expose `boundsOf`.\n */\n private fallbackNodeBounds(node: GraphNode): Rect | null {\n const graph = this.graph;\n if (!graph) return null;\n const pos = node.position ?? { x: 0, y: 0 };\n const local = graph.boundsOfNode(node) ?? FALLBACK_LOCAL_BOUNDS;\n return {\n x: pos.x + local.x,\n y: pos.y + local.y,\n width: local.width,\n height: local.height,\n };\n }\n\n private paintViewportIndicator(): void {\n const g = this.viewportGfx;\n const ctx = this.ctxRef;\n if (!g || !ctx) return;\n const vis = ctx.camera.getVisibleBounds();\n const tl = this.worldToMinimap(vis.x, vis.y);\n const br = this.worldToMinimap(vis.x + vis.width, vis.y + vis.height);\n const x = tl.x;\n const y = tl.y;\n const w = br.x - tl.x;\n const h = br.y - tl.y;\n g.clear();\n g.rect(x, y, w, h);\n g.fill({ color: this.opts.viewportFill, alpha: this.opts.viewportFillAlpha });\n g.rect(x, y, w, h);\n g.stroke({ color: this.opts.viewportStroke, width: this.opts.viewportStrokeWidth });\n }\n\n // ─── Bounds + projection ────────────────────────────────────────────────\n\n /** Union node bounds with the current camera-visible bounds. */\n private effectiveBounds(): Bounds {\n const node = this.nodeBounds();\n const vis = this.ctxRef?.camera.getVisibleBounds() ?? {\n x: 0,\n y: 0,\n width: 1,\n height: 1,\n };\n const minX = Math.min(node.x, vis.x);\n const minY = Math.min(node.y, vis.y);\n const maxX = Math.max(node.x + node.width, vis.x + vis.width);\n const maxY = Math.max(node.y + node.height, vis.y + vis.height);\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n }\n\n /**\n * AABB of all drawn node *footprints* + padding, queried directly from the\n * renderer's per-instance world bounds — so arcs / polygons / stars /\n * custom shapes contribute their true extent, not a hardcoded size-derived\n * estimate. Pre-mount nodes fall through to a position+default-size box.\n * Returns a 1000×1000 placeholder when the layer has no nodes yet.\n */\n private nodeBounds(): Bounds {\n const graph = this.graph;\n if (!graph || graph.store.nodeCount() === 0) {\n return { x: -500, y: -500, width: 1000, height: 1000 };\n }\n const renderer = graph.getRenderer();\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n let any = false;\n for (const node of graph.store.nodes()) {\n const b = renderer?.getShapeWorldBounds(node.id) ?? this.fallbackNodeBounds(node);\n if (!b) continue;\n any = true;\n if (b.x < minX) minX = b.x;\n if (b.y < minY) minY = b.y;\n if (b.x + b.width > maxX) maxX = b.x + b.width;\n if (b.y + b.height > maxY) maxY = b.y + b.height;\n }\n if (!any) return { x: -500, y: -500, width: 1000, height: 1000 };\n const pad = this.opts.padding;\n return {\n x: minX - pad,\n y: minY - pad,\n width: Math.max(1, maxX - minX + pad * 2),\n height: Math.max(1, maxY - minY + pad * 2),\n };\n }\n\n private projectBounds(b: Bounds): void {\n const { width, height } = this.opts;\n const sx = width / b.width;\n const sy = height / b.height;\n this.scale = Math.min(sx, sy) * 0.9;\n this.offsetX = (width - b.width * this.scale) / 2 - b.x * this.scale;\n this.offsetY = (height - b.height * this.scale) / 2 - b.y * this.scale;\n }\n\n private worldToMinimap(wx: number, wy: number): { x: number; y: number } {\n return {\n x: wx * this.scale + this.offsetX,\n y: wy * this.scale + this.offsetY,\n };\n }\n\n private minimapToWorld(mx: number, my: number): { x: number; y: number } {\n return {\n x: (mx - this.offsetX) / this.scale,\n y: (my - this.offsetY) / this.scale,\n };\n }\n\n // ─── Interactions ───────────────────────────────────────────────────────\n\n private wireInteractions(): void {\n const inner = this.inner;\n if (!inner) return;\n inner.eventMode = 'static';\n inner.hitArea = {\n contains: (x, y) => x >= 0 && x <= this.opts.width && y >= 0 && y <= this.opts.height,\n };\n inner.cursor = 'pointer';\n inner.on('pointerdown', this.onMiniPointerDown);\n inner.on('pointermove', this.onMiniPointerMove);\n inner.on('pointerup', this.onMiniPointerUp);\n inner.on('pointerupoutside', this.onMiniPointerUp);\n }\n\n private onMiniPointerDown = (e: FederatedPointerEvent): void => {\n const ctx = this.ctxRef;\n if (!ctx || !this.inner) return;\n const local = e.getLocalPosition(this.inner);\n const world = this.minimapToWorld(local.x, local.y);\n const vis = ctx.camera.getVisibleBounds();\n const cx = vis.x + vis.width / 2;\n const cy = vis.y + vis.height / 2;\n const inside =\n world.x >= vis.x &&\n world.x <= vis.x + vis.width &&\n world.y >= vis.y &&\n world.y <= vis.y + vis.height;\n\n this.isDragging = true;\n if (inside) {\n this.dragOffsetX = world.x - cx;\n this.dragOffsetY = world.y - cy;\n } else {\n this.dragOffsetX = 0;\n this.dragOffsetY = 0;\n this.panMainCameraTo(world.x, world.y);\n }\n };\n\n private onMiniPointerMove = (e: FederatedPointerEvent): void => {\n if (!this.isDragging || !this.ctxRef || !this.inner) return;\n const local = e.getLocalPosition(this.inner);\n const world = this.minimapToWorld(local.x, local.y);\n this.panMainCameraTo(world.x - this.dragOffsetX, world.y - this.dragOffsetY);\n };\n\n private onMiniPointerUp = (): void => {\n this.isDragging = false;\n };\n\n /** Position the main camera so the world point `(wx, wy)` lands at screen centre. */\n private panMainCameraTo(wx: number, wy: number): void {\n const cam = this.ctxRef?.camera;\n if (!cam) return;\n const s = cam.scale;\n const tx = cam.screenWidth / 2 - wx * s;\n const ty = cam.screenHeight / 2 - wy * s;\n cam.setPosition(tx, ty);\n }\n}\n\n/**\n * Default local AABB used when the resolved shape isn't registered or its\n * ctor doesn't expose `static boundsOf`. Centred on the origin so the\n * minimap places it symmetrically around the node's stored position.\n */\nconst FALLBACK_LOCAL_BOUNDS: Rect = { x: -16, y: -16, width: 32, height: 32 };\n","/**\n * `GraphHistory` — undo/redo for a {@link GraphStore}.\n *\n * A **command/transaction journal**, not a snapshot store and not a passive\n * event listener. Mutations are recorded only when routed through\n * {@link GraphHistory.transaction} (or {@link GraphHistory.push}); everything\n * else — streaming feed deltas, silent layout-sim position writes — bypasses the\n * journal, so the undo stack stays meaningful and small.\n *\n * @example\n * ```ts\n * const history = new GraphHistory(layer.store);\n * history.transaction('delete selection', (rec) => {\n * for (const id of selectedIds) rec.removeNode(id);\n * });\n * history.undo(); // restores the nodes + their incident edges\n * ```\n */\n\nimport { EventEmitter } from '@invana/canvas';\n\nimport type { GraphStore } from '../store';\nimport type { GraphEdge, GraphNode, Vec2 } from '../store';\nimport type {\n GraphHistoryEventMap,\n GraphHistoryOptions,\n HistoryEntry,\n HistoryOp,\n HistoryRecorder,\n} from './types';\n\nconst DEFAULT_LIMIT = 100;\n\nexport class GraphHistory {\n /** Fires `change` after every mutation so observers can re-read undo/redo state. */\n readonly events = new EventEmitter<GraphHistoryEventMap>();\n\n private readonly store: GraphStore;\n private readonly limit: number;\n\n private readonly undoStack: HistoryEntry[] = [];\n private readonly redoStack: HistoryEntry[] = [];\n\n /** Ops buffer for the in-flight transaction. Non-null only while recording. */\n private recording: HistoryOp[] | null = null;\n /** Nesting depth — only the outermost `transaction` commits an entry. */\n private depth = 0;\n\n constructor(store: GraphStore, opts: GraphHistoryOptions = {}) {\n this.store = store;\n this.limit = opts.limit ?? DEFAULT_LIMIT;\n }\n\n // ─── Public state ─────────────────────────────────────────────────────────\n\n /** True iff there is at least one entry that can be undone. */\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n /** True iff there is at least one undone entry that can be redone. */\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n // ─── Recording ────────────────────────────────────────────────────────────\n\n /**\n * Run `fn`'s mutations as one undoable entry. Mutations MUST go through the\n * {@link HistoryRecorder} passed to `fn` to be journaled. The whole body runs\n * inside {@link GraphStore.batch}, so the canvas sees a single flush. Nested\n * `transaction` calls merge into the outermost entry. Returns `fn`'s result.\n */\n transaction<T>(label: string, fn: (rec: HistoryRecorder) => T): T {\n const outermost = this.depth === 0;\n if (outermost) this.recording = [];\n this.depth++;\n let result: T;\n try {\n result = this.store.batch(() => fn(this.recorder));\n } finally {\n this.depth--;\n if (outermost) {\n const ops = this.recording ?? [];\n this.recording = null;\n if (ops.length > 0) this.commit({ ops, label });\n }\n }\n return result;\n }\n\n /**\n * Record an already-applied entry. Escape hatch for mutations that happen\n * outside {@link transaction} — e.g. a drag behaviour that writes positions\n * during the gesture and, on release, pushes a single `moveNode` op with the\n * captured start/end positions. The ops are assumed to be applied already;\n * this only journals them.\n */\n push(entry: HistoryEntry): void {\n if (entry.ops.length === 0) return;\n this.commit(entry);\n }\n\n // ─── Undo / redo ──────────────────────────────────────────────────────────\n\n /** Revert the most recent entry and move it onto the redo stack. No-op if empty. */\n undo(): void {\n const entry = this.undoStack.pop();\n if (!entry) return;\n this.store.batch(() => {\n for (let i = entry.ops.length - 1; i >= 0; i--) this.applyInverse(entry.ops[i]!);\n });\n this.redoStack.push(entry);\n this.emitChange();\n }\n\n /** Re-apply the most recently undone entry and move it back onto the undo stack. */\n redo(): void {\n const entry = this.redoStack.pop();\n if (!entry) return;\n this.store.batch(() => {\n for (const op of entry.ops) this.applyForward(op);\n });\n this.undoStack.push(entry);\n this.emitChange();\n }\n\n /** Wipe both stacks. Use when loading a fresh dataset. */\n clear(): void {\n this.undoStack.length = 0;\n this.redoStack.length = 0;\n this.emitChange();\n }\n\n // ─── Internals ────────────────────────────────────────────────────────────\n\n private commit(entry: HistoryEntry): void {\n this.undoStack.push(entry);\n if (this.undoStack.length > this.limit) this.undoStack.shift();\n // Any new recorded change invalidates the redo branch.\n this.redoStack.length = 0;\n this.emitChange();\n }\n\n private emitChange(): void {\n this.events.emit('change', {\n canUndo: this.canUndo,\n canRedo: this.canRedo,\n undoDepth: this.undoStack.length,\n redoDepth: this.redoStack.length,\n });\n }\n\n /**\n * The recorder handed to `transaction` callbacks. Each method applies the\n * change to the store and appends its op (carrying the pre-mutation state) to\n * the in-flight ops buffer.\n */\n private readonly recorder: HistoryRecorder = {\n addNode: (node) => {\n this.store.addNode(node);\n this.record({ kind: 'addNode', node: { ...node } });\n },\n removeNode: (id) => {\n const node = this.store.getNode(id);\n if (!node) return;\n const edges = this.incidentEdges(id);\n this.store.removeNode(id, { cascade: true });\n this.record({ kind: 'removeNode', node, edges });\n },\n updateNode: (id, patch) => {\n const before = this.captureNodeBefore(id, patch);\n if (before === null) return;\n this.store.updateNode(id, patch);\n this.record({ kind: 'updateNode', id, before, after: { ...patch } });\n },\n moveNode: (id, position) => {\n const before = this.store.getPosition(id);\n if (!before) return;\n this.store.setPosition(id, position);\n this.record({ kind: 'moveNode', id, before, after: { ...position } });\n },\n addEdge: (edge) => {\n this.store.addEdge(edge);\n this.record({ kind: 'addEdge', edge: { ...edge } });\n },\n removeEdge: (id) => {\n const edge = this.store.getEdge(id);\n if (!edge) return;\n this.store.removeEdge(id);\n this.record({ kind: 'removeEdge', edge });\n },\n updateEdge: (id, patch) => {\n const before = this.captureEdgeBefore(id, patch);\n if (before === null) return;\n this.store.updateEdge(id, patch);\n this.record({ kind: 'updateEdge', id, before, after: { ...patch } });\n },\n };\n\n private record(op: HistoryOp): void {\n // Outside a transaction (shouldn't happen via recorder) drop silently.\n this.recording?.push(op);\n }\n\n /** Snapshot the patched fields' prior values for a node. `null` if unknown id. */\n private captureNodeBefore(id: string, patch: Partial<GraphNode>): Partial<GraphNode> | null {\n const node = this.store.getNode(id);\n if (!node) return null;\n const before: Partial<GraphNode> = {};\n for (const key of Object.keys(patch) as (keyof GraphNode)[]) {\n (before as Record<string, unknown>)[key] = node[key];\n }\n return before;\n }\n\n private captureEdgeBefore(id: string, patch: Partial<GraphEdge>): Partial<GraphEdge> | null {\n const edge = this.store.getEdge(id);\n if (!edge) return null;\n const before: Partial<GraphEdge> = {};\n for (const key of Object.keys(patch) as (keyof GraphEdge)[]) {\n (before as Record<string, unknown>)[key] = edge[key];\n }\n return before;\n }\n\n /** Cloned incident edges (both directions), deduped — self-loops appear once. */\n private incidentEdges(nodeId: string): GraphEdge[] {\n const seen = new Set<string>();\n const out: GraphEdge[] = [];\n for (const edge of this.store.edgesOf(nodeId, 'both')) {\n if (seen.has(edge.id)) continue;\n seen.add(edge.id);\n out.push(edge);\n }\n return out;\n }\n\n // ─── Replay (no re-journal — calls plain store.* directly) ─────────────────\n\n private applyForward(op: HistoryOp): void {\n switch (op.kind) {\n case 'addNode':\n if (!this.store.hasNode(op.node.id)) this.store.addNode(op.node);\n break;\n case 'removeNode':\n if (this.store.hasNode(op.node.id)) this.store.removeNode(op.node.id, { cascade: true });\n break;\n case 'updateNode':\n this.store.updateNode(op.id, op.after);\n break;\n case 'moveNode':\n this.store.setPosition(op.id, op.after);\n break;\n case 'addEdge':\n if (!this.store.hasEdge(op.edge.id)) this.store.addEdge(op.edge);\n break;\n case 'removeEdge':\n if (this.store.hasEdge(op.edge.id)) this.store.removeEdge(op.edge.id);\n break;\n case 'updateEdge':\n this.store.updateEdge(op.id, op.after);\n break;\n }\n }\n\n private applyInverse(op: HistoryOp): void {\n switch (op.kind) {\n case 'addNode':\n if (this.store.hasNode(op.node.id)) this.store.removeNode(op.node.id, { cascade: true });\n break;\n case 'removeNode':\n if (!this.store.hasNode(op.node.id)) this.store.addNode(op.node);\n this.readdEdges(op.edges);\n break;\n case 'updateNode':\n this.store.updateNode(op.id, op.before);\n break;\n case 'moveNode':\n this.store.setPosition(op.id, op.before);\n break;\n case 'addEdge':\n if (this.store.hasEdge(op.edge.id)) this.store.removeEdge(op.edge.id);\n break;\n case 'removeEdge':\n if (!this.store.hasEdge(op.edge.id)) this.store.addEdge(op.edge);\n break;\n case 'updateEdge':\n this.store.updateEdge(op.id, op.before);\n break;\n }\n }\n\n /** Re-add edges whose both endpoints exist; skip duplicates and danglers. */\n private readdEdges(edges: GraphEdge[]): void {\n for (const edge of edges) {\n if (this.store.hasEdge(edge.id)) continue;\n if (!this.store.hasNode(edge.source) || !this.store.hasNode(edge.target)) continue;\n this.store.addEdge(edge);\n }\n }\n}\n\n/** Re-export Vec2 for callers that build `moveNode` ops. */\nexport type { Vec2 };\n","/**\n * `GraphClipboard` — copy / cut / paste / delete for a {@link GraphStore}.\n *\n * Holds an in-memory buffer of cloned node/edge specs. It does **not** read the\n * current selection itself — the caller passes the ids in (the canvas-react\n * `useClipboard` hook reads them off a `ClickSelectBehaviour`). This keeps the\n * clipboard decoupled from the selection mechanism and trivially testable.\n *\n * cut / paste / delete each run as a single undoable {@link GraphHistory}\n * transaction when a history instance is supplied; otherwise they fall back to a\n * plain {@link GraphStore.batch} (one flush, not undoable).\n *\n * @example\n * ```ts\n * const clipboard = new GraphClipboard(layer.store);\n * clipboard.copy(selectedNodeIds, selectedEdgeIds);\n * const { nodeIds } = clipboard.paste(history); // offset + re-id'd\n * clickSelect.selectMultiple(nodeIds.map((id) => ({ id })));\n * ```\n */\n\nimport { EventEmitter } from '@invana/canvas';\n\nimport type { GraphStore } from '../store';\nimport type { GraphEdge, GraphNode, Vec2 } from '../store';\nimport type { GraphHistory, HistoryRecorder } from '../history';\n\nconst DEFAULT_OFFSET: Vec2 = { x: 24, y: 24 };\n\n/** Event-map for {@link GraphClipboard.events}. */\nexport type GraphClipboardEventMap = {\n /** Fired whenever the buffer's contents change (copy / clear). Drives \"can paste\". */\n change: { hasContent: boolean };\n};\n\n/** Constructor options for {@link GraphClipboard}. */\nexport interface GraphClipboardOptions {\n /** Offset applied to pasted node positions to avoid exact overlap. Default `{x:24,y:24}`. */\n pasteOffset?: Vec2;\n /**\n * Candidate id generator for pasted nodes/edges. Called with increasing\n * `attempt` until the returned id is free. Default `${oldId}-copy[-N]`.\n */\n remapId?: (oldId: string, attempt: number) => string;\n}\n\n/** Ids produced by a {@link GraphClipboard.paste}. */\nexport interface PasteResult {\n nodeIds: string[];\n edgeIds: string[];\n}\n\nfunction defaultRemapId(oldId: string, attempt: number): string {\n return attempt === 0 ? `${oldId}-copy` : `${oldId}-copy-${attempt}`;\n}\n\nexport class GraphClipboard {\n /** Fires `change` whenever the buffer's contents change (copy / clear). */\n readonly events = new EventEmitter<GraphClipboardEventMap>();\n\n private readonly store: GraphStore;\n private readonly pasteOffset: Vec2;\n private readonly remapId: (oldId: string, attempt: number) => string;\n\n private bufferedNodes: GraphNode[] = [];\n private bufferedEdges: GraphEdge[] = [];\n\n constructor(store: GraphStore, opts: GraphClipboardOptions = {}) {\n this.store = store;\n this.pasteOffset = opts.pasteOffset ?? DEFAULT_OFFSET;\n this.remapId = opts.remapId ?? defaultRemapId;\n }\n\n /** True iff the buffer holds at least one node or edge (drives \"can paste\"). */\n get hasContent(): boolean {\n return this.bufferedNodes.length > 0 || this.bufferedEdges.length > 0;\n }\n\n /** Empty the buffer. */\n clearBuffer(): void {\n this.bufferedNodes = [];\n this.bufferedEdges = [];\n this.events.emit('change', { hasContent: false });\n }\n\n /**\n * Snapshot the given ids into the buffer (clones, so later store mutations\n * don't mutate the buffer). Unknown ids are skipped. Replaces prior contents.\n */\n copy(nodeIds: readonly string[], edgeIds: readonly string[] = []): void {\n this.bufferedNodes = [];\n this.bufferedEdges = [];\n for (const id of nodeIds) {\n const node = this.store.getNode(id);\n if (node) this.bufferedNodes.push(node);\n }\n for (const id of edgeIds) {\n const edge = this.store.getEdge(id);\n if (edge) this.bufferedEdges.push(edge);\n }\n this.events.emit('change', { hasContent: this.hasContent });\n }\n\n /** Copy the ids into the buffer, then delete them as one undoable transaction. */\n cut(nodeIds: readonly string[], edgeIds: readonly string[], history?: GraphHistory): void {\n this.copy(nodeIds, edgeIds);\n this.removeAsTransaction('cut', nodeIds, edgeIds, history);\n }\n\n /** Delete the given ids as one undoable transaction. Buffer is left untouched. */\n delete(nodeIds: readonly string[], edgeIds: readonly string[], history?: GraphHistory): void {\n this.removeAsTransaction('delete', nodeIds, edgeIds, history);\n }\n\n /**\n * Insert the buffer with fresh ids (collision-free) and a position offset, as\n * one undoable transaction. Only buffered edges whose **both** endpoints were\n * also buffered are pasted, with endpoints remapped to the new node ids.\n * `parentId` is remapped when the parent was pasted too, else dropped.\n *\n * Returns the new ids so the caller can re-select the pasted items.\n */\n paste(history?: GraphHistory): PasteResult {\n if (!this.hasContent) return { nodeIds: [], edgeIds: [] };\n\n // Build the id remap up front so edge endpoints can be resolved.\n const nodeIdMap = new Map<string, string>();\n const taken = new Set<string>();\n for (const node of this.bufferedNodes) {\n nodeIdMap.set(node.id, this.freshId(node.id, taken));\n }\n\n const newNodes: GraphNode[] = this.bufferedNodes.map((node) => {\n const next: GraphNode = { ...node, id: nodeIdMap.get(node.id)! };\n if (node.position) {\n next.position = {\n x: node.position.x + this.pasteOffset.x,\n y: node.position.y + this.pasteOffset.y,\n };\n }\n if (node.parentId !== undefined) {\n const mapped = nodeIdMap.get(node.parentId);\n if (mapped) next.parentId = mapped;\n else delete next.parentId;\n }\n return next;\n });\n\n const newEdges: GraphEdge[] = [];\n for (const edge of this.bufferedEdges) {\n const source = nodeIdMap.get(edge.source);\n const target = nodeIdMap.get(edge.target);\n if (!source || !target) continue; // dangling — endpoint wasn't copied\n newEdges.push({ ...edge, id: this.freshId(edge.id, taken), source, target });\n }\n\n const apply = (rec: HistoryRecorder): PasteResult => {\n for (const node of newNodes) rec.addNode(node);\n for (const edge of newEdges) rec.addEdge(edge);\n return { nodeIds: newNodes.map((n) => n.id), edgeIds: newEdges.map((e) => e.id) };\n };\n\n if (history) return history.transaction('paste', apply);\n return this.store.batch(() => apply(this.plainRecorder()));\n }\n\n // ─── Internals ────────────────────────────────────────────────────────────\n\n /** Remove explicit edges first, then nodes (cascade), mirroring `applyDelta`. */\n private removeAsTransaction(\n label: string,\n nodeIds: readonly string[],\n edgeIds: readonly string[],\n history?: GraphHistory,\n ): void {\n const run = (rec: HistoryRecorder): void => {\n for (const id of edgeIds) if (this.store.hasEdge(id)) rec.removeEdge(id);\n for (const id of nodeIds) if (this.store.hasNode(id)) rec.removeNode(id);\n };\n if (history) history.transaction(label, run);\n else this.store.batch(() => run(this.plainRecorder()));\n }\n\n /** Pick the first remapped id that is neither already in the store nor reserved. */\n private freshId(oldId: string, taken: Set<string>): string {\n let attempt = 0;\n let candidate = this.remapId(oldId, attempt);\n while (this.store.hasNode(candidate) || this.store.hasEdge(candidate) || taken.has(candidate)) {\n attempt++;\n candidate = this.remapId(oldId, attempt);\n }\n taken.add(candidate);\n return candidate;\n }\n\n /**\n * A recorder that mutates the store directly without journaling — used when no\n * {@link GraphHistory} is supplied so paste/cut/delete still run as one batch.\n */\n private plainRecorder(): HistoryRecorder {\n return {\n addNode: (node) => this.store.addNode(node),\n removeNode: (id) => this.store.removeNode(id, { cascade: true }),\n updateNode: (id, patch) => this.store.updateNode(id, patch),\n moveNode: (id, position) => this.store.setPosition(id, position),\n addEdge: (edge) => this.store.addEdge(edge),\n removeEdge: (id) => this.store.removeEdge(id),\n updateEdge: (id, patch) => this.store.updateEdge(id, patch),\n };\n }\n}\n","/**\n * `HoverActivateBehaviour` — toggles a named visual state on hovered nodes /\n * edges (and optionally their N-hop neighbours), with optional dimming of\n * everything else.\n *\n * Layer-scoped: constructed with a target `layerId` referencing a\n * {@link GraphLayer}. Subscribes to that layer's renderer pointer events\n * (`shape:pointerover` / `connector:pointerover`) and drives layer state via\n * `layer.store.setNodeState` / `layer.store.setEdgeState`.\n *\n * Default `enabled: false` — register, then explicitly enable. Matches the\n * project rule that no behaviour auto-activates.\n *\n * Defaults align with the canonical state catalogue auto-merged into\n * every `GraphLayer`: `state: 'hovered'` for the focal (and N-hop\n * neighbours when `degree > 0`), and optional `inactiveState: 'dimmed'`\n * for everything else. Override these when the project's state\n * vocabulary diverges.\n *\n * @example\n * ```ts\n * // Layer defaults already include `hovered`, `highlighted`, `dimmed` —\n * // no setup needed beyond registering the behaviour.\n *\n * canvas.behaviours.register(\n * new HoverActivateBehaviour({\n * id: 'hover',\n * layerId: 'graph',\n * enabled: true,\n * // state defaults to 'hovered'\n * inactiveState: 'dimmed',\n * degree: 1,\n * }),\n * );\n * ```\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\n\n/** Element kind for hover targets. */\nexport type HoverableElementType = 'shape' | 'connector';\n\n/** Edge-traversal direction filter for neighbour expansion. */\nexport type HoverDirection = 'in' | 'out' | 'both';\n\n/** Element handed to hover callbacks. */\nexport interface HoverableElement {\n readonly id: string;\n readonly type: HoverableElementType;\n /** Arbitrary user payload from `node.data` or `edge.data`. */\n readonly data: unknown;\n}\n\n/** Constructor options for `HoverActivateBehaviour`. */\nexport interface HoverActivateBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour drives. */\n layerId: string;\n\n /**\n * Per-target enable predicate. `boolean` is a global on/off; a function\n * runs per pointer-over and may veto activation. Default `true`.\n */\n enable?: boolean | ((element: HoverableElement) => boolean);\n\n /**\n * State name applied to the hovered focal element (and its N-hop\n * neighbours when `degree > 0`). Default `'hovered'` — matches the\n * canonical state catalogue auto-merged into every `GraphLayer`. Pass\n * a custom name when the behaviour should write a project-specific\n * state instead (e.g. `'focal'`).\n */\n state?: string;\n\n /**\n * State name applied to every element *not* in the active set. Leave\n * `undefined` to skip inactive dimming. Default `undefined`.\n */\n inactiveState?: string;\n\n /**\n * Lift the active set (the hovered focal element + its N-hop neighbours)\n * above the rest within its render layer for the duration of the hover, so\n * unrelated nodes / edges don't paint over the highlighted data. Edges raise\n * above other edges (still below all nodes); neighbour nodes raise above\n * other nodes. Reset when the hover clears. Visual-only — restacking doesn't\n * affect hit-testing. Default `true`.\n */\n raiseActive?: boolean;\n\n /**\n * N-hop neighbour radius. `0` = hovered element only; `1` = direct\n * neighbours + connecting edges; `N` = N-hop. Default `0`.\n */\n degree?: number;\n\n /** Direction for neighbour traversal. Default `'both'`. */\n direction?: HoverDirection;\n\n /**\n * Camera scale at or below which the behaviour swaps `state` for\n * `zoomedOutState` (and `zoomedOutEdgeState` for edges). The hovered set\n * gets re-painted through the swapped state names whenever the camera\n * crosses this threshold mid-hover. Omit (or leave both zoomed-out names\n * undefined) and the behaviour is identical to today.\n *\n * Typical use: at world-level zoom every node collapses to ~1 anti-aliased\n * pixel, so the normal `active` state is invisible against background\n * dots. A bigger `active-far` config (size + strokeWidth bumped) makes\n * the hovered node pop.\n */\n zoomThreshold?: number;\n\n /**\n * State name applied to the hovered node + N-hop neighbour nodes when\n * `camera.scale <= zoomThreshold`. Falls back to `state` when undefined\n * (no node-side zoom swap, but edges may still swap via\n * `zoomedOutEdgeState`).\n */\n zoomedOutState?: string;\n\n /**\n * State name applied to connecting edges when\n * `camera.scale <= zoomThreshold` AND `degree > 0`. Falls back to `state`\n * when undefined.\n */\n zoomedOutEdgeState?: string;\n\n /**\n * Gfx-transform scale multiplier applied to each hovered node (and the\n * N-hop neighbour nodes) when `camera.scale <= zoomThreshold`. Pure\n * transform write via {@link PrimitivesRenderer.scaleShape} — no geometry\n * rebuild, no styling change. Use this when you want the hovered node to\n * just *grow visually* at low zoom (so it stands out against ~1 px\n * background dots) while keeping its original colour, stroke, and label.\n *\n * Multiplies the existing `gfx.scale`, so if `NodeSizeLODBehaviour` is\n * also active it will overwrite the multiplier on the next zoom frame —\n * prefer `zoomedOutState` with a bigger `size` in that case. For stories\n * without an LOD behaviour, this is the cleanest \"scale on hover\" knob.\n *\n * Only nodes are scaled — connectors don't compose cleanly with\n * `gfx.scale` (the polyline would shift, not just thicken). The hovered\n * node's outgoing edges still anchor to its geometric position, which\n * sits inside the now-bigger silhouette — visually acceptable.\n *\n * `undefined` (default) and `1` both disable the multiplier.\n */\n zoomedOutScale?: number;\n\n /** Fired when an element first becomes hovered. */\n onHover?: (element: HoverableElement) => void;\n /** Fired when hover ends on a previously hovered element. */\n onHoverEnd?: (element: HoverableElement) => void;\n}\n\ninterface ResolvedOptions {\n enable: boolean | ((element: HoverableElement) => boolean);\n state: string;\n inactiveState: string | undefined;\n raiseActive: boolean;\n degree: number;\n direction: HoverDirection;\n zoomThreshold: number | undefined;\n zoomedOutState: string | undefined;\n zoomedOutEdgeState: string | undefined;\n zoomedOutScale: number | undefined;\n onHover: ((element: HoverableElement) => void) | undefined;\n onHoverEnd: ((element: HoverableElement) => void) | undefined;\n}\n\nfunction resolveOptions(\n prev: ResolvedOptions | null,\n patch: Partial<HoverActivateBehaviourOptions>,\n): ResolvedOptions {\n const base: ResolvedOptions = prev ?? {\n enable: true,\n state: 'hovered',\n inactiveState: undefined,\n raiseActive: true,\n degree: 0,\n direction: 'both',\n zoomThreshold: undefined,\n zoomedOutState: undefined,\n zoomedOutEdgeState: undefined,\n zoomedOutScale: undefined,\n onHover: undefined,\n onHoverEnd: undefined,\n };\n return {\n enable: patch.enable ?? base.enable,\n state: patch.state ?? base.state,\n inactiveState: 'inactiveState' in patch ? patch.inactiveState : base.inactiveState,\n raiseActive: patch.raiseActive ?? base.raiseActive,\n degree: patch.degree ?? base.degree,\n direction: patch.direction ?? base.direction,\n zoomThreshold:\n 'zoomThreshold' in patch ? patch.zoomThreshold : base.zoomThreshold,\n zoomedOutState:\n 'zoomedOutState' in patch ? patch.zoomedOutState : base.zoomedOutState,\n zoomedOutEdgeState:\n 'zoomedOutEdgeState' in patch\n ? patch.zoomedOutEdgeState\n : base.zoomedOutEdgeState,\n zoomedOutScale:\n 'zoomedOutScale' in patch ? patch.zoomedOutScale : base.zoomedOutScale,\n onHover: 'onHover' in patch ? patch.onHover : base.onHover,\n onHoverEnd: 'onHoverEnd' in patch ? patch.onHoverEnd : base.onHoverEnd,\n };\n}\n\nexport class HoverActivateBehaviour extends Behaviour {\n /** Bound target layer — resolved in `onRegister`. */\n private layer: GraphLayer | null = null;\n\n private opts: ResolvedOptions;\n\n /** Subscription disposers, called in `onDestroy`. */\n private subs: Array<() => void> = [];\n\n /** Currently hovered element, or `null`. */\n private current: HoverableElement | null = null;\n /** Neighbour ids that received the active state (excluding `current`). */\n private activeIds = new Set<string>();\n /** Element ids that received the inactive state. */\n private inactiveIds = new Set<string>();\n\n /**\n * State name actually applied to nodes for the current hover — equals\n * `opts.state` normally, `opts.zoomedOutState` when the camera was below\n * `opts.zoomThreshold` at activation (or after a mid-hover swap). Tracked\n * so `clearHover` / `swapStates` remove whatever was actually applied,\n * not just whatever the current `opts.state` is now.\n */\n private appliedNodeState: string | null = null;\n /** Sibling of {@link appliedNodeState} for edges. */\n private appliedEdgeState: string | null = null;\n\n /**\n * Gfx-transform multiplier currently applied to the hovered node set.\n * `1` (or `null`) means no multiplier is active. Tracked so a threshold\n * cross or clear can reset only the ids we actually scaled.\n */\n private appliedScale: number = 1;\n /** Node ids currently scaled via `renderer.scaleShape` — reset on clear. */\n private readonly scaledNodeIds = new Set<string>();\n\n /**\n * `gfx.zIndex` written to the active set when `raiseActive` is on. Any value\n * above the default `0` lifts the element over its untouched peers; `1` is\n * enough and keeps hover- and selection-raises on the same tier.\n */\n private static readonly RAISED_Z_INDEX = 1;\n /** Ids currently raised via `renderer.raiseShape` / `raiseConnector`. */\n private readonly raisedIds = new Set<string>();\n\n constructor(opts: HoverActivateBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['pointer+hover'] });\n this.opts = resolveOptions(null, opts);\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `HoverActivateBehaviour \"${this.id}\": layer \"${this.layerId}\" not found. ` +\n `Add the GraphLayer before registering this behaviour.`,\n );\n }\n this.layer = layer;\n\n const renderer = layer.getRenderer();\n if (!renderer) {\n throw new Error(\n `HoverActivateBehaviour \"${this.id}\": target layer \"${this.layerId}\" is not mounted. ` +\n `Add the GraphLayer to the canvas before registering this behaviour.`,\n );\n }\n\n const onShapeOver = (e: { id: string }) => this.handlePointerOver(e.id, 'shape');\n const onShapeOut = (e: { id: string }) => this.handlePointerOut(e.id, 'shape');\n const onConnOver = (e: { id: string }) => this.handlePointerOver(e.id, 'connector');\n const onConnOut = (e: { id: string }) => this.handlePointerOut(e.id, 'connector');\n\n renderer.events.on('shape:pointerover', onShapeOver);\n renderer.events.on('shape:pointerout', onShapeOut);\n renderer.events.on('connector:pointerover', onConnOver);\n renderer.events.on('connector:pointerout', onConnOut);\n\n this.subs.push(\n () => renderer.events.off('shape:pointerover', onShapeOver),\n () => renderer.events.off('shape:pointerout', onShapeOut),\n () => renderer.events.off('connector:pointerover', onConnOver),\n () => renderer.events.off('connector:pointerout', onConnOut),\n );\n\n // When the pointer leaves the canvas entirely (onto a toolbar/panel or out\n // of the window), the renderer's `globalpointermove` stream stops, so no\n // `pointerout` fires for the element still under the cursor and the hover\n // states would stick. Clear on the canvas element's `pointerleave`.\n const el = ctx.canvasElement;\n if (el) {\n const onLeave = (): void => {\n if (!this.current) return;\n this.opts.onHoverEnd?.(this.current);\n this.clearHover();\n };\n el.addEventListener('pointerleave', onLeave);\n this.subs.push(() => el.removeEventListener('pointerleave', onLeave));\n }\n\n // Camera-zoom subscription is **conditional** — only wired when a\n // `zoomThreshold` is configured. Stories that don't use the zoom-tier\n // pay zero per-zoom cost.\n if (this.opts.zoomThreshold !== undefined) {\n const onZoom = (): void => this.handleCameraZoom();\n ctx.events.on('camera:zoom', onZoom);\n this.subs.push(() => ctx.events.off('camera:zoom', onZoom));\n }\n }\n\n protected override onDestroy(): void {\n this.clearHover();\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.layer = null;\n }\n\n protected override onDisable(): void {\n this.clearHover();\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /** The element currently driving the hover effect, or `null`. */\n get hoveredElement(): HoverableElement | null {\n return this.current;\n }\n\n /** Read-only snapshot of resolved options. */\n get options(): Readonly<ResolvedOptions> {\n return this.opts;\n }\n\n /**\n * Runtime option update. State-affecting changes clear any in-flight hover\n * so the next hover applies the new visuals cleanly.\n */\n setOptions(patch: Partial<HoverActivateBehaviourOptions>): void {\n const stateChanged =\n (patch.state !== undefined && patch.state !== this.opts.state) ||\n ('inactiveState' in patch && patch.inactiveState !== this.opts.inactiveState) ||\n ('zoomedOutState' in patch &&\n patch.zoomedOutState !== this.opts.zoomedOutState) ||\n ('zoomedOutEdgeState' in patch &&\n patch.zoomedOutEdgeState !== this.opts.zoomedOutEdgeState);\n const raiseChanged =\n patch.raiseActive !== undefined && patch.raiseActive !== this.opts.raiseActive;\n if (stateChanged) this.clearHover();\n this.opts = resolveOptions(this.opts, patch);\n // Re-pick states / scale if the threshold or scale moved while a hover\n // is active — runtime knob changes (GUI sliders) should swap immediately.\n if (this.current) this.handleCameraZoom();\n // Toggle raise on/off live for the in-flight hover (e.g. a GUI checkbox).\n if (this.current && raiseChanged) {\n if (this.opts.raiseActive) this.applyRaise();\n else this.resetRaise();\n }\n }\n\n /** Clear all states applied by the current hover. */\n clearHover(): void {\n if (!this.layer) {\n this.current = null;\n this.activeIds.clear();\n this.inactiveIds.clear();\n this.scaledNodeIds.clear();\n this.raisedIds.clear();\n this.appliedNodeState = null;\n this.appliedEdgeState = null;\n this.appliedScale = 1;\n return;\n }\n // Use the state names that were *actually* applied — they may differ\n // from `opts.state` when a zoom-tier swap happened mid-hover, or when\n // the user changed `state` via `setOptions` after the hover started.\n const nodeState = this.appliedNodeState ?? this.opts.state;\n const edgeState = this.appliedEdgeState ?? this.opts.state;\n if (this.current) {\n if (this.current.type === 'shape') {\n this.layer.store.setNodeState(this.current.id, nodeState, false);\n } else {\n this.layer.store.setEdgeState(this.current.id, edgeState, false);\n }\n }\n for (const id of this.activeIds) {\n // Active ids can be either nodes or edges; try both.\n this.layer.store.setNodeState(id, nodeState, false);\n this.layer.store.setEdgeState(id, edgeState, false);\n }\n this.activeIds.clear();\n\n const inactive = this.opts.inactiveState;\n if (inactive) {\n for (const id of this.inactiveIds) {\n this.layer.store.setNodeState(id, inactive, false);\n this.layer.store.setEdgeState(id, inactive, false);\n }\n }\n this.inactiveIds.clear();\n\n // Reset any gfx.scale bumps we applied during this hover.\n if (this.scaledNodeIds.size > 0) {\n const renderer = this.layer.getRenderer();\n if (renderer) {\n for (const id of this.scaledNodeIds) renderer.scaleShape(id, 1);\n }\n this.scaledNodeIds.clear();\n }\n this.appliedScale = 1;\n\n // Drop the active set back to its natural stacking.\n this.resetRaise();\n\n this.current = null;\n this.appliedNodeState = null;\n this.appliedEdgeState = null;\n }\n\n // ─── Pointer handlers ───────────────────────────────────────────────────\n\n private handlePointerOver(id: string, type: HoverableElementType): void {\n if (!this._enabled) return;\n const target = this.resolveElement(id, type);\n if (!target) return;\n\n const { enable } = this.opts;\n if (enable === false) return;\n if (typeof enable === 'function' && !enable(target)) return;\n\n if (this.current && this.current.id !== id) {\n this.clearHover();\n } else if (this.current && this.current.id === id) {\n return;\n }\n this.activate(target);\n }\n\n private handlePointerOut(id: string, _type: HoverableElementType): void {\n if (!this.current || this.current.id !== id) return;\n const ending = this.current;\n this.opts.onHoverEnd?.(ending);\n this.clearHover();\n }\n\n private activate(target: HoverableElement): void {\n const layer = this.layer;\n if (!layer) return;\n\n this.current = target;\n const picked = this.pickTier();\n this.appliedNodeState = picked.node;\n this.appliedEdgeState = picked.edge;\n\n if (target.type === 'shape') layer.store.setNodeState(target.id, picked.node, true);\n else layer.store.setEdgeState(target.id, picked.edge, true);\n\n if (this.opts.degree > 0 && target.type === 'shape') {\n const { nodeIds, edgeIds } = this.collectNeighbours(target.id, this.opts.degree);\n for (const nid of nodeIds) {\n layer.store.setNodeState(nid, picked.node, true);\n this.activeIds.add(nid);\n }\n for (const eid of edgeIds) {\n layer.store.setEdgeState(eid, picked.edge, true);\n this.activeIds.add(eid);\n }\n }\n\n if (this.opts.inactiveState) this.applyInactive(target.id);\n\n // Visual scale-up bump must run AFTER the active set is finalised\n // (so neighbour shapes are included). State+scale are independent\n // dimensions of the zoom-tier — either, both, or neither may activate.\n if (picked.scale !== 1) this.applyScale(picked.scale);\n\n // Lift the finalised active set above the rest so unrelated nodes / edges\n // don't paint over the highlighted data.\n if (this.opts.raiseActive) this.applyRaise();\n\n this.opts.onHover?.(target);\n }\n\n /**\n * Choose which node + edge state names AND gfx scale to apply right now,\n * based on `camera.scale` vs. `opts.zoomThreshold`.\n *\n * - `node` / `edge`: `opts.state` (or `opts.zoomedOutState` /\n * `opts.zoomedOutEdgeState` at far zoom). Each role falls back to\n * `opts.state` independently.\n * - `scale`: `1` (or `opts.zoomedOutScale` at far zoom). The scale\n * multiplier is independent of the state-name swap — a story can\n * configure either, both, or neither.\n */\n private pickTier(): { node: string; edge: string; scale: number } {\n const o = this.opts;\n const scale = this.ctx?.camera.scale ?? Infinity;\n const usingZoomed =\n o.zoomThreshold !== undefined && scale <= o.zoomThreshold;\n return {\n node: usingZoomed && o.zoomedOutState ? o.zoomedOutState : o.state,\n edge: usingZoomed && o.zoomedOutEdgeState ? o.zoomedOutEdgeState : o.state,\n scale:\n usingZoomed && o.zoomedOutScale !== undefined && o.zoomedOutScale > 0\n ? o.zoomedOutScale\n : 1,\n };\n }\n\n /**\n * Handle a `camera:zoom` event while a hover is active. Two independent\n * dimensions may change as the camera crosses the threshold:\n *\n * - State names — swap via {@link swapStates} (state-config-driven\n * restyle, composes with `NodeSizeLODBehaviour`).\n * - Scale multiplier — re-apply via {@link applyScale} (`gfx.scale`\n * write, does NOT compose with LOD).\n *\n * Idempotent: a zoom that doesn't cross the threshold leaves both\n * dimensions unchanged and exits cheaply.\n */\n private handleCameraZoom(): void {\n if (!this.current || !this.layer) return;\n const picked = this.pickTier();\n const statesChanged =\n picked.node !== this.appliedNodeState ||\n picked.edge !== this.appliedEdgeState;\n const scaleChanged = picked.scale !== this.appliedScale;\n if (!statesChanged && !scaleChanged) return;\n if (statesChanged) {\n this.swapStates({ node: picked.node, edge: picked.edge });\n }\n if (scaleChanged) {\n this.applyScale(picked.scale);\n }\n }\n\n /**\n * Set / reset `gfx.scale` on the hovered node set. Pure transform write\n * via {@link PrimitivesRenderer.scaleShape} — no geometry rebuild,\n * preserves the node's spec-driven colour, stroke, label, etc.\n *\n * Resets any previously-scaled ids first so `applyScale(1)` is a clean\n * teardown. Only ids that resolve to shapes (not connectors) are\n * touched — `activeIds` is a flat set of mixed kinds; `renderer.hasShape`\n * filters out edge ids cheaply.\n */\n private applyScale(scale: number): void {\n const renderer = this.layer?.getRenderer();\n if (!renderer) {\n this.scaledNodeIds.clear();\n this.appliedScale = 1;\n return;\n }\n for (const id of this.scaledNodeIds) renderer.scaleShape(id, 1);\n this.scaledNodeIds.clear();\n this.appliedScale = 1;\n\n if (scale === 1) return;\n\n if (this.current?.type === 'shape') {\n renderer.scaleShape(this.current.id, scale);\n this.scaledNodeIds.add(this.current.id);\n }\n for (const id of this.activeIds) {\n if (!renderer.hasShape(id)) continue;\n renderer.scaleShape(id, scale);\n this.scaledNodeIds.add(id);\n }\n this.appliedScale = scale;\n }\n\n /**\n * Raise the current hovered set (`current` + `activeIds`) above their peers\n * via `renderer.raiseShape` / `raiseConnector`. `activeIds` is a flat set of\n * mixed kinds, so each id is dispatched by `hasShape` / `hasConnector`.\n * Tracked in {@link raisedIds} so {@link resetRaise} restores exactly the\n * ids we touched.\n */\n private applyRaise(): void {\n const renderer = this.layer?.getRenderer();\n if (!renderer) return;\n const z = HoverActivateBehaviour.RAISED_Z_INDEX;\n const raise = (id: string): void => {\n if (renderer.hasShape(id)) renderer.raiseShape(id, z);\n else if (renderer.hasConnector(id)) renderer.raiseConnector(id, z);\n else return;\n this.raisedIds.add(id);\n };\n if (this.current) raise(this.current.id);\n for (const id of this.activeIds) raise(id);\n }\n\n /** Reset every id raised by {@link applyRaise} back to the default z (0). */\n private resetRaise(): void {\n if (this.raisedIds.size === 0) return;\n const renderer = this.layer?.getRenderer();\n if (renderer) {\n for (const id of this.raisedIds) {\n if (renderer.hasShape(id)) renderer.raiseShape(id, 0);\n else if (renderer.hasConnector(id)) renderer.raiseConnector(id, 0);\n }\n }\n this.raisedIds.clear();\n }\n\n /**\n * Walk the current hovered set (`current` + `activeIds`) and replace the\n * previously-applied state names with `picked.node` / `picked.edge`.\n * Skips work per-role when the state name didn't change for that role\n * (e.g. only the edge state swapped while the node state stayed put).\n *\n * `activeIds` is a flat set containing both node and edge ids — we don't\n * track type per id, so we call `setNodeState` / `setEdgeState` for both;\n * mismatched calls (an id that doesn't exist in that store) no-op\n * gracefully. Matches the existing pattern in {@link clearHover}.\n */\n private swapStates(picked: { node: string; edge: string }): void {\n const layer = this.layer;\n if (!layer) return;\n const prevNode = this.appliedNodeState ?? this.opts.state;\n const prevEdge = this.appliedEdgeState ?? this.opts.state;\n const nodeChanged = prevNode !== picked.node;\n const edgeChanged = prevEdge !== picked.edge;\n if (!nodeChanged && !edgeChanged) return;\n\n if (this.current) {\n if (this.current.type === 'shape' && nodeChanged) {\n layer.store.setNodeState(this.current.id, prevNode, false);\n layer.store.setNodeState(this.current.id, picked.node, true);\n } else if (this.current.type === 'connector' && edgeChanged) {\n layer.store.setEdgeState(this.current.id, prevEdge, false);\n layer.store.setEdgeState(this.current.id, picked.edge, true);\n }\n }\n for (const id of this.activeIds) {\n if (nodeChanged) {\n layer.store.setNodeState(id, prevNode, false);\n layer.store.setNodeState(id, picked.node, true);\n }\n if (edgeChanged) {\n layer.store.setEdgeState(id, prevEdge, false);\n layer.store.setEdgeState(id, picked.edge, true);\n }\n }\n\n this.appliedNodeState = picked.node;\n this.appliedEdgeState = picked.edge;\n }\n\n /** BFS neighbourhood expansion using the store's adjacency index. */\n private collectNeighbours(\n rootId: string,\n degree: number,\n ): { nodeIds: Set<string>; edgeIds: Set<string> } {\n const nodeIds = new Set<string>();\n const edgeIds = new Set<string>();\n const layer = this.layer;\n if (!layer) return { nodeIds, edgeIds };\n const store = layer.store;\n\n let frontier: string[] = [rootId];\n const visited = new Set<string>([rootId]);\n for (let hop = 0; hop < degree; hop++) {\n const next: string[] = [];\n for (const u of frontier) {\n for (const e of store.edgesOf(u, this.opts.direction)) {\n edgeIds.add(e.id);\n const otherId = e.source === u ? e.target : e.source;\n if (!visited.has(otherId)) {\n visited.add(otherId);\n nodeIds.add(otherId);\n next.push(otherId);\n }\n }\n }\n frontier = next;\n if (frontier.length === 0) break;\n }\n return { nodeIds, edgeIds };\n }\n\n private applyInactive(hoveredId: string): void {\n const inactive = this.opts.inactiveState;\n if (!inactive) return;\n const layer = this.layer;\n if (!layer) return;\n\n const activeIds = new Set<string>([hoveredId, ...this.activeIds]);\n for (const node of layer.store.nodes()) {\n if (activeIds.has(node.id)) continue;\n layer.store.setNodeState(node.id, inactive, true);\n this.inactiveIds.add(node.id);\n }\n for (const edge of layer.store.edges()) {\n if (activeIds.has(edge.id)) continue;\n layer.store.setEdgeState(edge.id, inactive, true);\n this.inactiveIds.add(edge.id);\n }\n }\n\n private resolveElement(id: string, type: HoverableElementType): HoverableElement | null {\n const layer = this.layer;\n if (!layer) return null;\n if (type === 'shape') {\n const node = layer.store.getNode(id);\n return node ? { id, type, data: node.data } : null;\n }\n const edge = layer.store.getEdge(id);\n return edge ? { id, type, data: edge.data } : null;\n }\n}\n","/**\n * `ModifierTracker` — global helper that tracks which keyboard modifier keys\n * are currently held. Several behaviours (Click/Brush/Lasso) need to know\n * the modifier state at the moment of a pointer event, but the renderer's\n * shape/connector pointer events don't carry that info — they're synthesised\n * from PixiJS events. Tracking modifiers via window-level key events is the\n * pragmatic substitute.\n *\n * Reference-counted: the first behaviour to call `attach()` installs the\n * window listeners; subsequent `attach()` calls just bump the counter.\n * `detach()` removes the listeners when the count returns to zero.\n *\n * @internal — not exported from `@invana/graph`. Used by behaviours.\n */\n\nexport type ModifierKey = 'shift' | 'control' | 'alt' | 'meta';\n\nconst held: Set<ModifierKey> = new Set();\nlet refCount = 0;\n\nfunction onKeyDown(e: KeyboardEvent): void {\n if (e.shiftKey) held.add('shift');\n if (e.ctrlKey) held.add('control');\n if (e.altKey) held.add('alt');\n if (e.metaKey) held.add('meta');\n}\n\nfunction onKeyUp(e: KeyboardEvent): void {\n if (!e.shiftKey) held.delete('shift');\n if (!e.ctrlKey) held.delete('control');\n if (!e.altKey) held.delete('alt');\n if (!e.metaKey) held.delete('meta');\n}\n\nfunction onBlur(): void {\n held.clear();\n}\n\nexport const ModifierTracker = {\n /** Install window listeners (refcounted). Safe to call repeatedly. */\n attach(): void {\n if (refCount === 0 && typeof window !== 'undefined') {\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n window.addEventListener('blur', onBlur);\n }\n refCount++;\n },\n\n /** Remove window listeners when the last user detaches. */\n detach(): void {\n if (refCount === 0) return;\n refCount--;\n if (refCount === 0 && typeof window !== 'undefined') {\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n window.removeEventListener('blur', onBlur);\n held.clear();\n }\n },\n\n /** True iff *any* of the given modifier keys is currently held. */\n anyHeld(keys: readonly ModifierKey[]): boolean {\n for (const k of keys) if (held.has(k)) return true;\n return false;\n },\n\n /** Snapshot of currently held modifiers. */\n snapshot(): ReadonlySet<ModifierKey> {\n return new Set(held);\n },\n};\n","/**\n * `ClickSelectBehaviour` — toggles a named visual state on clicked nodes /\n * edges with optional N-degree neighbour expansion, modifier-driven\n * multi-select, and optional dimming of unselected elements.\n *\n * Layer-scoped: constructed with a target `layerId`. Subscribes to that\n * layer's renderer click events and to the canvas-level `background:click`\n * for clear-on-background behaviour.\n *\n * Default `enabled: false` — register, then explicitly enable.\n *\n * The canonical `selected` state is auto-merged into every\n * `GraphLayer`'s state catalogue — no setup needed. Override the layer's\n * `options.node.state.selected` to customise the visual.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new ClickSelectBehaviour({\n * id: 'select',\n * layerId: 'graph',\n * enabled: true,\n * multiple: true,\n * degree: 1,\n * }),\n * );\n * ```\n */\n\nimport { Behaviour, EventEmitter, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport { ModifierTracker, type ModifierKey } from './ModifierTracker';\nimport type { HoverableElementType, HoverDirection } from './HoverActivateBehaviour';\n\n/** Element kind for selection targets. */\nexport type SelectableElementType = HoverableElementType;\n\n/** Edge-traversal direction filter. */\nexport type SelectDirection = HoverDirection;\n\n/** Modifier-key names accepted by `trigger`. */\nexport type SelectModifierKey = ModifierKey;\n\n/** Element handed to selection callbacks. */\nexport interface SelectableElement {\n readonly id: string;\n readonly type: SelectableElementType;\n /** Arbitrary user payload from `node.data` or `edge.data`. */\n readonly data: unknown;\n}\n\n/** Per-flush snapshot fired to `onSelectionChange`. */\nexport interface SelectionSnapshot {\n shapeIds: string[];\n connectorIds: string[];\n}\n\n/** Event-map for {@link ClickSelectBehaviour.events}. */\nexport type ClickSelectEventMap = {\n /**\n * Fired once whenever the selection set is replaced (click, `select*`,\n * `clearSelection`, or brush/lasso delegation). The non-clobbering complement\n * to the `onSelectionChange` callback — observers (e.g. the canvas-react\n * `useSelection` hook) subscribe here instead of hijacking the callback.\n */\n 'selection:change': SelectionSnapshot;\n};\n\n/** Constructor options for `ClickSelectBehaviour`. */\nexport interface ClickSelectBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour drives. */\n layerId: string;\n\n /**\n * Per-target enable predicate. `boolean` is a global on/off; a function\n * runs per click and may veto. Default `true`.\n */\n enable?: boolean | ((element: SelectableElement) => boolean);\n\n /**\n * Allow more than one element selected at a time. When `true`, a qualifying\n * click (see `trigger`) toggles the element in/out of the selection; when\n * `false` it replaces the selection with the clicked element. Default `false`.\n */\n multiple?: boolean;\n\n /**\n * Modifier key(s) required for a click to affect the selection **at all**.\n * When non-empty, a click that holds none of these is ignored — a plain\n * (unmodified) click selects nothing, and a plain left-drag stays a pure\n * pan. With a modifier held, the click selects (replacing the selection, or\n * toggling membership when `multiple` is `true`). Empty array = every click\n * selects, no modifier needed. Default `[]` (plain click selects). Pass\n * `['shift']` to gate selection behind the Shift key.\n */\n trigger?: SelectModifierKey[];\n\n /**\n * N-hop neighbour radius around each seed. `0` = clicked element only.\n * Default `0`.\n */\n degree?: number;\n\n /** Direction for neighbour traversal. Default `'both'`. */\n direction?: SelectDirection;\n\n /** Active-state name. Default `'selected'`. */\n state?: string;\n\n /**\n * State applied to every element that is *not* selected. `undefined`\n * disables dimming. Default `undefined`.\n */\n unselectedState?: string;\n\n /**\n * Lift the selected set (seeds + degree-expanded neighbours) above the rest\n * within its render layer, so unrelated nodes / edges don't paint over the\n * selection. Edges raise above other edges (still below all nodes); nodes\n * raise above other nodes. Reset when the selection clears. Visual-only —\n * restacking doesn't affect hit-testing. Default `true`.\n */\n raiseActive?: boolean;\n\n /** Clear selection when clicking the empty canvas background. Default `true`. */\n clearOnBackground?: boolean;\n\n /** Fired when an element becomes selected. */\n onSelect?: (element: SelectableElement) => void;\n /** Fired when an element becomes deselected. */\n onDeselect?: (element: SelectableElement) => void;\n /** Fired once per click with the post-settle selection snapshot. */\n onSelectionChange?: (snapshot: SelectionSnapshot) => void;\n}\n\ninterface ResolvedOptions {\n enable: boolean | ((element: SelectableElement) => boolean);\n multiple: boolean;\n trigger: SelectModifierKey[];\n degree: number;\n direction: SelectDirection;\n state: string;\n unselectedState: string | undefined;\n raiseActive: boolean;\n clearOnBackground: boolean;\n onSelect: ((element: SelectableElement) => void) | undefined;\n onDeselect: ((element: SelectableElement) => void) | undefined;\n onSelectionChange: ((snapshot: SelectionSnapshot) => void) | undefined;\n}\n\nfunction resolveOptions(\n prev: ResolvedOptions | null,\n patch: Partial<ClickSelectBehaviourOptions>,\n): ResolvedOptions {\n const base: ResolvedOptions = prev ?? {\n enable: true,\n multiple: false,\n trigger: [],\n degree: 0,\n direction: 'both',\n state: 'selected',\n unselectedState: undefined,\n raiseActive: true,\n clearOnBackground: true,\n onSelect: undefined,\n onDeselect: undefined,\n onSelectionChange: undefined,\n };\n return {\n enable: patch.enable ?? base.enable,\n multiple: patch.multiple ?? base.multiple,\n trigger: patch.trigger ?? base.trigger,\n degree: patch.degree ?? base.degree,\n direction: patch.direction ?? base.direction,\n state: patch.state ?? base.state,\n unselectedState:\n 'unselectedState' in patch\n ? patch.unselectedState === ''\n ? undefined\n : patch.unselectedState\n : base.unselectedState,\n raiseActive: patch.raiseActive ?? base.raiseActive,\n clearOnBackground: patch.clearOnBackground ?? base.clearOnBackground,\n onSelect: 'onSelect' in patch ? patch.onSelect : base.onSelect,\n onDeselect: 'onDeselect' in patch ? patch.onDeselect : base.onDeselect,\n onSelectionChange:\n 'onSelectionChange' in patch ? patch.onSelectionChange : base.onSelectionChange,\n };\n}\n\nexport class ClickSelectBehaviour extends Behaviour {\n /**\n * Selection event bus. Subscribe to `'selection:change'` for a reactive\n * snapshot every time the selection set is replaced. Independent of (and\n * additive to) the `onSelectionChange` option.\n */\n readonly events = new EventEmitter<ClickSelectEventMap>();\n\n private layer: GraphLayer | null = null;\n private opts: ResolvedOptions;\n\n /** Subscription disposers. */\n private subs: Array<() => void> = [];\n\n /** Seed set — ids the user *directly* clicked / passed to `select*`. */\n private seeds = new Map<string, SelectableElementType>();\n /** Expanded set — seeds + degree-expanded neighbours. */\n private selected = new Map<string, SelectableElementType>();\n /** Ids currently rendered with the `unselectedState`. */\n private unselectedIds = new Set<string>();\n\n /**\n * `gfx.zIndex` written to the selected set when `raiseActive` is on. Any\n * value above the default `0` lifts the element over its untouched peers;\n * `1` matches `HoverActivateBehaviour`'s raise tier.\n */\n private static readonly RAISED_Z_INDEX = 1;\n /** Ids currently raised via `renderer.raiseShape` / `raiseConnector`. */\n private readonly raisedIds = new Set<string>();\n\n /** True when the most recent click already consumed an element. */\n private clickConsumedByElement = false;\n\n /** Pointerdown screen-position — used to distinguish a click from a drag. */\n private pointerDownScreen: { x: number; y: number } | null = null;\n\n /**\n * Set once the pointer travels past the click/drag threshold while a button\n * is held. Used to suppress the synthetic element `click` that fires at the\n * end of a node drag — without it, dragging a selected node would collapse\n * the whole selection down to that one node on release.\n */\n private pressMoved = false;\n\n constructor(opts: ClickSelectBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['pointer+click'] });\n this.opts = resolveOptions(null, opts);\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `ClickSelectBehaviour \"${this.id}\": layer \"${this.layerId}\" not found. ` +\n `Add the GraphLayer before registering this behaviour.`,\n );\n }\n this.layer = layer;\n\n const renderer = layer.getRenderer();\n if (!renderer) {\n throw new Error(\n `ClickSelectBehaviour \"${this.id}\": target layer is not mounted. ` +\n `Add the GraphLayer to the canvas before registering this behaviour.`,\n );\n }\n\n ModifierTracker.attach();\n\n const onShapeClick = (e: { id: string }) => {\n this.clickConsumedByElement = true;\n // A drag (e.g. moving a selected node) ends with a synthetic element\n // click; ignore it so the gesture doesn't replace the selection.\n if (this.pressMoved) return;\n this.handleElementClick(e.id, 'shape');\n };\n const onConnClick = (e: { id: string }) => {\n this.clickConsumedByElement = true;\n if (this.pressMoved) return;\n this.handleElementClick(e.id, 'connector');\n };\n // `background:click` is declared on the canvas event bus but the engine\n // doesn't emit it today, so we listen to native DOM `click` on the canvas\n // element instead. PixiJS dispatches `shape:click` / `connector:click`\n // synchronously *during* the DOM event, so by the time this handler runs\n // `clickConsumedByElement` is already set when a shape was hit.\n //\n // We also track pointerdown screen-position to distinguish a click\n // (small movement) from a drag (e.g. brush / lasso select). A click\n // after a drag would otherwise clear the just-applied selection.\n const DRAG_VS_CLICK_THRESHOLD_PX = 4;\n const onPointerDown = (e: PointerEvent) => {\n this.pressMoved = false;\n if (e.button !== 0) {\n this.pointerDownScreen = null;\n return;\n }\n this.pointerDownScreen = { x: e.clientX, y: e.clientY };\n };\n const onPointerMove = (e: PointerEvent) => {\n const down = this.pointerDownScreen;\n if (!down || this.pressMoved) return;\n if (Math.hypot(e.clientX - down.x, e.clientY - down.y) > DRAG_VS_CLICK_THRESHOLD_PX) {\n this.pressMoved = true;\n }\n };\n const onCanvasClick = (e: MouseEvent) => {\n const down = this.pointerDownScreen;\n this.pointerDownScreen = null;\n if (this.clickConsumedByElement) {\n this.clickConsumedByElement = false;\n return;\n }\n if (e.button !== 0) return;\n // If the pointer moved more than the threshold between pointerdown\n // and click, this was a drag — don't treat it as a background click.\n if (down) {\n const dx = e.clientX - down.x;\n const dy = e.clientY - down.y;\n if (Math.hypot(dx, dy) > DRAG_VS_CLICK_THRESHOLD_PX) return;\n }\n if (this.opts.clearOnBackground) this.clearSelection();\n };\n\n renderer.events.on('shape:click', onShapeClick);\n renderer.events.on('connector:click', onConnClick);\n const el = ctx.canvasElement;\n if (el) {\n el.addEventListener('pointerdown', onPointerDown);\n el.addEventListener('pointermove', onPointerMove);\n el.addEventListener('click', onCanvasClick);\n }\n\n this.subs.push(\n () => renderer.events.off('shape:click', onShapeClick),\n () => renderer.events.off('connector:click', onConnClick),\n () => {\n if (el) {\n el.removeEventListener('pointerdown', onPointerDown);\n el.removeEventListener('pointermove', onPointerMove);\n el.removeEventListener('click', onCanvasClick);\n }\n },\n );\n }\n\n protected override onDestroy(): void {\n this.clearSelection();\n for (const off of this.subs) off();\n this.subs.length = 0;\n ModifierTracker.detach();\n this.layer = null;\n }\n\n protected override onDisable(): void {\n this.clearSelection();\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /** Resolved current options (read-only snapshot). */\n get options(): Readonly<ResolvedOptions> {\n return this.opts;\n }\n\n /**\n * Runtime option update. State-affecting changes clear the current\n * visual selection and re-apply with the new options.\n */\n setOptions(patch: Partial<ClickSelectBehaviourOptions>): void {\n const prev = this.opts;\n const stateChanged = patch.state !== undefined && patch.state !== prev.state;\n const unselChanged =\n 'unselectedState' in patch &&\n (patch.unselectedState === '' ? undefined : patch.unselectedState) !==\n prev.unselectedState;\n const expansionChanged =\n (patch.degree !== undefined && patch.degree !== prev.degree) ||\n (patch.direction !== undefined && patch.direction !== prev.direction);\n const raiseChanged =\n patch.raiseActive !== undefined && patch.raiseActive !== prev.raiseActive;\n\n const seedsSnapshot = new Map(this.seeds);\n const hadSelection = this.selected.size > 0;\n const reapply = hadSelection && (stateChanged || unselChanged || expansionChanged);\n\n if (reapply) this.clearVisualsOnly();\n this.opts = resolveOptions(this.opts, patch);\n if (reapply) {\n // The full reapply path re-raises through the new opts already.\n this.applySelection(seedsSnapshot, false);\n } else if (hadSelection && raiseChanged) {\n // Pure raise toggle on a live selection — apply / reset in place.\n if (this.opts.raiseActive) this.applyRaise();\n else this.resetRaise();\n }\n }\n\n /** Replace the selection with a single element. */\n select(id: string, type: SelectableElementType = 'shape'): void {\n this.applySelection(new Map([[id, type]]), true);\n }\n\n /** Replace the selection with the given (id, type) pairs. */\n selectMultiple(elements: Array<{ id: string; type?: SelectableElementType }>): void {\n const next = new Map<string, SelectableElementType>();\n for (const el of elements) next.set(el.id, el.type ?? 'shape');\n this.applySelection(next, true);\n }\n\n /** Add a single element to the current selection. */\n addToSelection(id: string, type: SelectableElementType = 'shape'): void {\n if (this.seeds.has(id)) return;\n const next = new Map(this.seeds);\n next.set(id, type);\n this.applySelection(next, true);\n }\n\n /** Remove a single element from the current selection. */\n deselect(id: string): void {\n if (!this.seeds.has(id)) return;\n const next = new Map(this.seeds);\n next.delete(id);\n this.applySelection(next, true);\n }\n\n /** Toggle the membership of `id` in the selection. */\n toggle(id: string, type: SelectableElementType = 'shape'): void {\n if (this.seeds.has(id)) this.deselect(id);\n else this.addToSelection(id, type);\n }\n\n /** True iff `id` is part of the rendered selection (seed or expanded). */\n isSelected(id: string): boolean {\n return this.selected.has(id);\n }\n\n /** All currently selected ids (seeds + expanded). */\n getSelectedIds(): string[] {\n return [...this.selected.keys()];\n }\n\n /** Currently selected shape (node) ids. */\n getSelectedShapeIds(): string[] {\n const out: string[] = [];\n for (const [id, type] of this.selected) if (type === 'shape') out.push(id);\n return out;\n }\n\n /** Currently selected connector (edge) ids. */\n getSelectedConnectorIds(): string[] {\n const out: string[] = [];\n for (const [id, type] of this.selected) if (type === 'connector') out.push(id);\n return out;\n }\n\n /** Clear the entire selection and any dimming. */\n clearSelection(): void {\n if (this.selected.size === 0 && this.unselectedIds.size === 0 && this.seeds.size === 0)\n return;\n this.applySelection(new Map(), true);\n }\n\n /**\n * Select every node and edge on the target layer. Replaces the current\n * selection. No-op if the layer isn't mounted.\n */\n selectAll(): void {\n if (!this.layer) return;\n const store = this.layer.store;\n const next: Array<{ id: string; type: SelectableElementType }> = [];\n for (const node of store.nodes()) next.push({ id: node.id, type: 'shape' });\n for (const edge of store.edges()) next.push({ id: edge.id, type: 'connector' });\n this.selectMultiple(next);\n }\n\n /**\n * Select a node together with its neighbours (in the given direction) and the\n * edges incident to it. Replaces the current selection. No-op if the layer\n * isn't mounted.\n *\n * @param id Seed node id.\n * @param dir Adjacency direction for neighbours + incident edges. Default `'both'`.\n */\n selectNeighbourhood(id: string, dir: 'in' | 'out' | 'both' = 'both'): void {\n if (!this.layer) return;\n const store = this.layer.store;\n const next: Array<{ id: string; type: SelectableElementType }> = [{ id, type: 'shape' }];\n for (const nb of store.neighborsOf(id, dir)) next.push({ id: nb, type: 'shape' });\n for (const e of store.edgesOf(id, dir)) next.push({ id: e.id, type: 'connector' });\n this.selectMultiple(next);\n }\n\n // ─── Internals ──────────────────────────────────────────────────────────\n\n private handleElementClick(id: string, type: SelectableElementType): void {\n if (!this._enabled) return;\n const target = this.resolveElement(id, type);\n if (!target) return;\n const { enable } = this.opts;\n if (enable === false) return;\n if (typeof enable === 'function' && !enable(target)) return;\n\n const { multiple, trigger } = this.opts;\n // `trigger` gates selection entirely: with a modifier configured, a click\n // that holds none of them is a no-op (plain click selects nothing; a plain\n // drag stays a pure pan). Empty `trigger` = every click selects.\n if (trigger.length > 0 && !ModifierTracker.anyHeld(trigger)) return;\n\n if (multiple) {\n // Toggle membership — extend or shrink the existing selection.\n const next = new Map(this.seeds);\n if (next.has(id)) next.delete(id);\n else next.set(id, type);\n this.applySelection(next, true);\n } else {\n // Single-select — replace the selection with just this element.\n this.applySelection(new Map([[id, type]]), true);\n }\n }\n\n /**\n * Core selection engine: replace seeds, recompute expansion, swap visuals,\n * diff-emit callbacks.\n */\n private applySelection(\n seeds: Map<string, SelectableElementType>,\n emitEvents: boolean,\n ): void {\n if (!this.layer) return;\n const expanded = this.expandSeeds(seeds);\n const prevSelected = new Map(this.selected);\n\n this.clearVisualsOnly();\n\n this.seeds = new Map(seeds);\n this.selected = new Map(expanded);\n for (const [id, type] of this.selected) {\n if (type === 'shape') this.layer.store.setNodeState(id, this.opts.state, true);\n else this.layer.store.setEdgeState(id, this.opts.state, true);\n }\n\n if (this.opts.unselectedState && this.selected.size > 0) {\n this.applyUnselected(this.selected);\n }\n\n // Lift the selected set above the rest so unrelated nodes / edges don't\n // paint over it.\n if (this.opts.raiseActive) this.applyRaise();\n\n if (!emitEvents) return;\n\n // Diff and fire callbacks.\n for (const [id, type] of prevSelected) {\n if (this.selected.has(id)) continue;\n const target = this.resolveElement(id, type);\n if (target) this.opts.onDeselect?.(target);\n }\n for (const [id, type] of this.selected) {\n if (prevSelected.has(id)) continue;\n const target = this.resolveElement(id, type);\n if (target) this.opts.onSelect?.(target);\n }\n const snapshot = this.buildSnapshot();\n if (this.opts.onSelectionChange) this.opts.onSelectionChange(snapshot);\n this.events.emit('selection:change', snapshot);\n }\n\n /** Expand seeds by `degree` hops (BFS) — same shape as HoverActivate. */\n private expandSeeds(\n seeds: Map<string, SelectableElementType>,\n ): Map<string, SelectableElementType> {\n const expanded = new Map(seeds);\n const { degree, direction } = this.opts;\n if (!this.layer || degree <= 0 || seeds.size === 0) return expanded;\n const store = this.layer.store;\n\n let frontier: string[] = [];\n for (const [id, type] of seeds) if (type === 'shape') frontier.push(id);\n\n for (let hop = 0; hop < degree && frontier.length > 0; hop++) {\n const next: string[] = [];\n for (const u of frontier) {\n for (const e of store.edgesOf(u, direction)) {\n if (!expanded.has(e.id)) expanded.set(e.id, 'connector');\n const otherId = e.source === u ? e.target : e.source;\n if (!expanded.has(otherId)) {\n expanded.set(otherId, 'shape');\n next.push(otherId);\n }\n }\n }\n frontier = next;\n }\n return expanded;\n }\n\n private clearVisualsOnly(): void {\n if (!this.layer) {\n this.seeds.clear();\n this.selected.clear();\n this.unselectedIds.clear();\n this.resetRaise();\n return;\n }\n for (const [id, type] of this.selected) {\n if (type === 'shape') this.layer.store.setNodeState(id, this.opts.state, false);\n else this.layer.store.setEdgeState(id, this.opts.state, false);\n }\n const unsel = this.opts.unselectedState;\n if (unsel) {\n for (const id of this.unselectedIds) {\n this.layer.store.setNodeState(id, unsel, false);\n this.layer.store.setEdgeState(id, unsel, false);\n }\n }\n this.resetRaise();\n this.seeds.clear();\n this.selected.clear();\n this.unselectedIds.clear();\n }\n\n /**\n * Raise the selected set above its peers via `renderer.raiseShape` /\n * `raiseConnector`. `selected` carries the element type per id, so each is\n * dispatched directly. Tracked in {@link raisedIds} so {@link resetRaise}\n * restores exactly the ids we touched.\n */\n private applyRaise(): void {\n const renderer = this.layer?.getRenderer();\n if (!renderer) return;\n const z = ClickSelectBehaviour.RAISED_Z_INDEX;\n for (const [id, type] of this.selected) {\n if (type === 'shape') renderer.raiseShape(id, z);\n else renderer.raiseConnector(id, z);\n this.raisedIds.add(id);\n }\n }\n\n /** Reset every id raised by {@link applyRaise} back to the default z (0). */\n private resetRaise(): void {\n if (this.raisedIds.size === 0) return;\n const renderer = this.layer?.getRenderer();\n if (renderer) {\n for (const id of this.raisedIds) {\n if (renderer.hasShape(id)) renderer.raiseShape(id, 0);\n else if (renderer.hasConnector(id)) renderer.raiseConnector(id, 0);\n }\n }\n this.raisedIds.clear();\n }\n\n private applyUnselected(selected: Map<string, SelectableElementType>): void {\n const unsel = this.opts.unselectedState;\n if (!unsel || !this.layer) return;\n for (const node of this.layer.store.nodes()) {\n if (selected.has(node.id)) continue;\n this.layer.store.setNodeState(node.id, unsel, true);\n this.unselectedIds.add(node.id);\n }\n for (const edge of this.layer.store.edges()) {\n if (selected.has(edge.id)) continue;\n this.layer.store.setEdgeState(edge.id, unsel, true);\n this.unselectedIds.add(edge.id);\n }\n }\n\n private resolveElement(id: string, type: SelectableElementType): SelectableElement | null {\n if (!this.layer) return null;\n if (type === 'shape') {\n const node = this.layer.store.getNode(id);\n return node ? { id, type, data: node.data } : null;\n }\n const edge = this.layer.store.getEdge(id);\n return edge ? { id, type, data: edge.data } : null;\n }\n\n private buildSnapshot(): SelectionSnapshot {\n const shapeIds: string[] = [];\n const connectorIds: string[] = [];\n for (const [id, type] of this.selected) {\n if (type === 'shape') shapeIds.push(id);\n else connectorIds.push(id);\n }\n return { shapeIds, connectorIds };\n }\n}\n","/**\n * `ClickInspectBehaviour` — tracks the **single** node / edge a user clicked for\n * *inspection / editing*, independent of {@link ClickSelectBehaviour}.\n *\n * Selection and inspection are different concerns: selection drives highlighting\n * and multi-element drag (and may hold many elements at once); inspection feeds a\n * property editor (`InspectorPanel`), which only ever edits **one** element. This\n * behaviour is the authority for the latter — it remembers the last element\n * clicked and clears on a background click — so the editor never has to reach\n * into the selection set (where a multi-select would leave it with nothing single\n * to show).\n *\n * Layer-scoped: constructed with a target `layerId`. Subscribes to that layer's\n * renderer click events; uses a native DOM `click` listener for the\n * clear-on-background path (the engine doesn't emit `background:click` today),\n * mirroring `ClickSelectBehaviour`.\n *\n * Default `enabled: false` — register, then explicitly enable.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new ClickInspectBehaviour({ id: 'click-inspect', layerId: 'graph', enabled: true }),\n * );\n * canvas.behaviours.get<ClickInspectBehaviour>('click-inspect')\n * ?.events.on('inspect:change', (t) => console.log(t)); // { kind, id } | null\n * ```\n */\n\nimport { Behaviour, EventEmitter, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\n\n/** The single element currently targeted for inspection / editing. */\nexport interface InspectTarget {\n kind: 'node' | 'edge';\n id: string;\n}\n\n/** Event-map for {@link ClickInspectBehaviour.events}. */\nexport type ClickInspectEventMap = {\n /**\n * Fired whenever the inspected element changes — a node / edge click sets it,\n * a background click (or `clear`) sets it to `null`.\n */\n 'inspect:change': InspectTarget | null;\n};\n\n/** Constructor options for `ClickInspectBehaviour`. */\nexport interface ClickInspectBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour reads clicks from. */\n layerId: string;\n\n /** Clear the inspected element when clicking the empty canvas. Default `true`. */\n clearOnBackground?: boolean;\n}\n\nexport class ClickInspectBehaviour extends Behaviour {\n /**\n * Inspection event bus. Subscribe to `'inspect:change'` for the current\n * single target (or `null`) every time it changes.\n */\n readonly events = new EventEmitter<ClickInspectEventMap>();\n\n private layer: GraphLayer | null = null;\n private readonly clearOnBackground: boolean;\n\n /** Subscription disposers. */\n private subs: Array<() => void> = [];\n\n /** Current inspected element, or `null`. */\n private target: InspectTarget | null = null;\n\n /** True when the most recent click already consumed an element. */\n private clickConsumedByElement = false;\n /** Pointerdown screen-position — used to distinguish a click from a drag. */\n private pointerDownScreen: { x: number; y: number } | null = null;\n /**\n * Set once the pointer travels past the click/drag threshold while a button\n * is held — suppresses the synthetic element `click` fired at the end of a\n * node drag so a drag doesn't open the inspector.\n */\n private pressMoved = false;\n\n constructor(opts: ClickInspectBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['pointer+click'] });\n this.clearOnBackground = opts.clearOnBackground ?? true;\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `ClickInspectBehaviour \"${this.id}\": layer \"${this.layerId}\" not found. ` +\n `Add the GraphLayer before registering this behaviour.`,\n );\n }\n this.layer = layer;\n\n const renderer = layer.getRenderer();\n if (!renderer) {\n throw new Error(\n `ClickInspectBehaviour \"${this.id}\": target layer is not mounted. ` +\n `Add the GraphLayer to the canvas before registering this behaviour.`,\n );\n }\n\n const onShapeClick = (e: { id: string }) => {\n this.clickConsumedByElement = true;\n if (this.pressMoved) return;\n this.handleElementClick(e.id, 'node');\n };\n const onConnClick = (e: { id: string }) => {\n this.clickConsumedByElement = true;\n if (this.pressMoved) return;\n this.handleElementClick(e.id, 'edge');\n };\n\n // Background clear — same DOM-`click` carve-out as `ClickSelectBehaviour`:\n // PixiJS dispatches `shape:click` / `connector:click` synchronously during\n // the DOM event, so `clickConsumedByElement` is already set when a hit\n // occurred. We also track pointer movement to ignore drags.\n const DRAG_VS_CLICK_THRESHOLD_PX = 4;\n const onPointerDown = (e: PointerEvent) => {\n this.pressMoved = false;\n if (e.button !== 0) {\n this.pointerDownScreen = null;\n return;\n }\n this.pointerDownScreen = { x: e.clientX, y: e.clientY };\n };\n const onPointerMove = (e: PointerEvent) => {\n const down = this.pointerDownScreen;\n if (!down || this.pressMoved) return;\n if (Math.hypot(e.clientX - down.x, e.clientY - down.y) > DRAG_VS_CLICK_THRESHOLD_PX) {\n this.pressMoved = true;\n }\n };\n const onCanvasClick = (e: MouseEvent) => {\n const down = this.pointerDownScreen;\n this.pointerDownScreen = null;\n if (this.clickConsumedByElement) {\n this.clickConsumedByElement = false;\n return;\n }\n if (e.button !== 0) return;\n if (down) {\n if (Math.hypot(e.clientX - down.x, e.clientY - down.y) > DRAG_VS_CLICK_THRESHOLD_PX) return;\n }\n if (this.clearOnBackground) this.clear();\n };\n\n renderer.events.on('shape:click', onShapeClick);\n renderer.events.on('connector:click', onConnClick);\n const el = ctx.canvasElement;\n if (el) {\n el.addEventListener('pointerdown', onPointerDown);\n el.addEventListener('pointermove', onPointerMove);\n el.addEventListener('click', onCanvasClick);\n }\n\n this.subs.push(\n () => renderer.events.off('shape:click', onShapeClick),\n () => renderer.events.off('connector:click', onConnClick),\n () => {\n if (el) {\n el.removeEventListener('pointerdown', onPointerDown);\n el.removeEventListener('pointermove', onPointerMove);\n el.removeEventListener('click', onCanvasClick);\n }\n },\n );\n }\n\n protected override onDestroy(): void {\n this.setTarget(null);\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.layer = null;\n }\n\n protected override onDisable(): void {\n this.setTarget(null);\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /** The element currently targeted for inspection, or `null`. */\n getTarget(): InspectTarget | null {\n return this.target;\n }\n\n /** Set the inspected element explicitly (e.g. from a context menu). */\n setTarget(target: InspectTarget | null): void {\n const same =\n (target === null && this.target === null) ||\n (target !== null &&\n this.target !== null &&\n target.kind === this.target.kind &&\n target.id === this.target.id);\n if (same) return;\n this.target = target;\n this.events.emit('inspect:change', target);\n }\n\n /** Clear the inspected element. */\n clear(): void {\n this.setTarget(null);\n }\n\n // ─── Internals ──────────────────────────────────────────────────────────\n\n private handleElementClick(id: string, kind: 'node' | 'edge'): void {\n if (!this._enabled || !this.layer) return;\n const exists = kind === 'node' ? this.layer.store.hasNode(id) : this.layer.store.hasEdge(id);\n if (!exists) return;\n this.setTarget({ kind, id });\n }\n}\n","/**\n * `BrushSelectBehaviour` — click-and-drag rectangular selection in screen\n * space. Every shape (and optionally connector) enclosed by the rectangle is\n * unioned with the existing selection.\n *\n * When a {@link ClickSelectBehaviour} is registered on the canvas (default\n * id `'click-select'`), the brush delegates selection mutations through it\n * so both behaviours stay in sync. Without a click-select target, the brush\n * falls back to driving `GraphLayer` state directly.\n *\n * Default `enabled: false` — register, then explicitly enable.\n *\n * Note: this behaviour creates a `Graphics` overlay attached to `ctx.stage`\n * for the rubber-band rectangle. That's one of two narrow carve-outs where\n * `@invana/graph` reaches into pixi directly — the alternative would be to\n * mount a private `ScreenLayer` per behaviour, which leaks an unnamed layer\n * id into the public registry.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new BrushSelectBehaviour({\n * id: 'brush',\n * layerId: 'graph',\n * enabled: true,\n * trigger: ['shift'],\n * enableElements: ['shape', 'connector'],\n * }),\n * );\n * ```\n */\n\nimport { Container, Graphics } from 'pixi.js';\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type {\n ClickSelectBehaviour,\n SelectableElementType,\n SelectionSnapshot,\n} from './ClickSelectBehaviour';\nimport type { ModifierKey } from './ModifierTracker';\n\n/** Element kinds the brush will pick up. */\nexport type BrushSelectElementType = SelectableElementType;\n\n/** Modifier-key names accepted by `trigger`. */\nexport type BrushModifierKey = ModifierKey;\n\n/** Visual style for the rubber-band rectangle. */\nexport interface BrushSelectStyle {\n /** Fill color `0xRRGGBB`. Default `0x1677ff`. */\n fill?: number;\n /** Fill opacity 0–1. Default `0.1`. */\n fillAlpha?: number;\n /** Stroke color `0xRRGGBB`. Default `0x1677ff`. */\n stroke?: number;\n /** Stroke opacity 0–1. Default `0.8`. */\n strokeAlpha?: number;\n /** Stroke width in pixels. Default `1`. */\n strokeWidth?: number;\n /** Dash pattern `[dashLen, gapLen]`. `[]` for solid. Default `[4, 4]`. */\n strokeDash?: number[];\n}\n\n/** Constructor options for `BrushSelectBehaviour`. */\nexport interface BrushSelectBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour brushes over. */\n layerId: string;\n /**\n * Optional `ClickSelectBehaviour` id to delegate to. Default `'click-select'`.\n * If found, the brush hands the merged selection to the click-select layer\n * so both stay in sync. Otherwise the brush mutates `GraphLayer` state\n * directly.\n */\n clickSelectId?: string;\n\n /**\n * Per-drag enable predicate. `boolean` global on/off; or a function\n * called with the pointerdown native event. Default `true`.\n */\n enable?: boolean | ((event: PointerEvent) => boolean);\n\n /**\n * Element types eligible for brush selection. Default `['shape', 'connector']`.\n */\n enableElements?: BrushSelectElementType[];\n\n /**\n * Modifier key(s) that must be held during pointerdown to activate the\n * brush. Empty array = any left-drag activates. Default `['shift']`.\n */\n trigger?: BrushModifierKey[];\n\n /**\n * Live-update the selection as the rect grows. `false` = apply only on\n * release. Default `false`.\n */\n immediately?: boolean;\n\n /**\n * Visual state name applied to brushed elements when no `ClickSelectBehaviour`\n * is targeted. Ignored on the delegate path. Default `'selected'`.\n */\n state?: string;\n\n /** Rectangle style. */\n style?: BrushSelectStyle;\n\n /**\n * Clear selection when the user clicks on the empty background (no drag).\n * Default `true`.\n */\n clearOnBackground?: boolean;\n\n /** Fired once on release if the brush produced a selection change. */\n onSelect?: (snapshot: SelectionSnapshot) => void;\n}\n\ninterface ResolvedOptions {\n enable: boolean | ((event: PointerEvent) => boolean);\n enableElements: BrushSelectElementType[];\n trigger: BrushModifierKey[];\n immediately: boolean;\n state: string;\n style: BrushSelectStyle;\n clearOnBackground: boolean;\n onSelect: ((snapshot: SelectionSnapshot) => void) | undefined;\n}\n\nfunction resolveOptions(\n prev: ResolvedOptions | null,\n patch: Partial<BrushSelectBehaviourOptions>,\n): ResolvedOptions {\n const base: ResolvedOptions = prev ?? {\n enable: true,\n enableElements: ['shape', 'connector'],\n trigger: ['shift'],\n immediately: false,\n state: 'selected',\n style: {},\n clearOnBackground: true,\n onSelect: undefined,\n };\n return {\n enable: patch.enable ?? base.enable,\n enableElements: patch.enableElements ?? base.enableElements,\n trigger: patch.trigger ?? base.trigger,\n immediately: patch.immediately ?? base.immediately,\n state: patch.state ?? base.state,\n style: patch.style ?? base.style,\n clearOnBackground: patch.clearOnBackground ?? base.clearOnBackground,\n onSelect: 'onSelect' in patch ? patch.onSelect : base.onSelect,\n };\n}\n\nconst DRAG_THRESHOLD = 3;\n\nexport class BrushSelectBehaviour extends Behaviour {\n private readonly clickSelectId: string;\n private opts: ResolvedOptions;\n\n private layer: GraphLayer | null = null;\n private ctxRef: CanvasContext | null = null;\n\n private overlay: Container | null = null;\n private gfx: Graphics | null = null;\n\n private dragActive = false;\n private dragStart: { x: number; y: number } | null = null;\n private dragCurrent: { x: number; y: number } | null = null;\n\n // Native canvas-element listener disposers.\n private listenerDisposers: Array<() => void> = [];\n\n constructor(opts: BrushSelectBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['shift+drag-on-bg'] });\n this.clickSelectId = opts.clickSelectId ?? 'click-select';\n this.opts = resolveOptions(null, opts);\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `BrushSelectBehaviour \"${this.id}\": layer \"${this.layerId}\" not found.`,\n );\n }\n this.layer = layer;\n this.ctxRef = ctx;\n\n // Mount the screen-space overlay.\n this.overlay = new Container();\n this.overlay.label = `${this.id}-overlay`;\n this.overlay.zIndex = 9999;\n ctx.stage.sortableChildren = true;\n ctx.stage.addChild(this.overlay);\n this.gfx = new Graphics();\n this.overlay.addChild(this.gfx);\n\n const el = ctx.canvasElement;\n if (!el) {\n // Headless mode — no DOM listeners. Behaviour is effectively a no-op.\n return;\n }\n\n const onDown = (e: PointerEvent) => this.handlePointerDown(e);\n const onMove = (e: PointerEvent) => this.handlePointerMove(e);\n const onUp = (e: PointerEvent) => this.handlePointerUp(e);\n const onCancel = () => this.cancelDrag();\n\n el.addEventListener('pointerdown', onDown);\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n window.addEventListener('pointercancel', onCancel);\n // No `pointerleave` listener — see LassoSelectBehaviour for rationale.\n\n this.listenerDisposers.push(\n () => el.removeEventListener('pointerdown', onDown),\n () => window.removeEventListener('pointermove', onMove),\n () => window.removeEventListener('pointerup', onUp),\n () => window.removeEventListener('pointercancel', onCancel),\n );\n }\n\n protected override onDestroy(): void {\n this.cancelDrag();\n for (const off of this.listenerDisposers) off();\n this.listenerDisposers.length = 0;\n this.gfx?.destroy();\n this.gfx = null;\n this.overlay?.removeFromParent();\n this.overlay?.destroy({ children: true });\n this.overlay = null;\n this.layer = null;\n this.ctxRef = null;\n }\n\n protected override onDisable(): void {\n this.cancelDrag();\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n get options(): Readonly<ResolvedOptions> {\n return this.opts;\n }\n\n setOptions(patch: Partial<BrushSelectBehaviourOptions>): void {\n this.opts = resolveOptions(this.opts, patch);\n }\n\n // ─── Pointer handlers ───────────────────────────────────────────────────\n\n private screenFromEvent(e: PointerEvent): { x: number; y: number } {\n const el = this.ctxRef?.canvasElement;\n if (!el) return { x: e.clientX, y: e.clientY };\n const rect = el.getBoundingClientRect();\n return { x: e.clientX - rect.left, y: e.clientY - rect.top };\n }\n\n private handlePointerDown(e: PointerEvent): void {\n this.clearRect();\n this.dragActive = false;\n this.dragStart = null;\n this.dragCurrent = null;\n\n if (!this._enabled) return;\n if (e.button !== 0) return;\n\n const { enable } = this.opts;\n if (typeof enable === 'function' ? !enable(e) : !enable) return;\n if (!this.triggerActive(e)) return;\n\n // Reject presses that land on overlaid DOM chrome (lil-gui, HTML controls)\n // rather than the canvas itself.\n const target = e.target;\n if (target !== this.ctxRef?.canvasElement) return;\n\n const p = this.screenFromEvent(e);\n\n // Defer to the node-drag behaviour when the press lands on a node. In a\n // single-canvas renderer every pointer event targets the same <canvas>\n // element, so the `e.target` check above can't tell a node from the bare\n // background — a hit-test can. Pressing a node (e.g. to drag the current\n // selection) must not start a fresh brush on top of it.\n const world = this.ctxRef?.camera.toWorld(p.x, p.y);\n if (world && this.layer?.getRenderer()?.hitTest(world.x, world.y)?.kind === 'shape') {\n return;\n }\n\n // Pause camera pan so the canvas doesn't move while the brush is drawn.\n this.ctxRef?.camera.viewport.plugins.pause('drag');\n\n this.dragActive = true;\n this.dragStart = p;\n this.dragCurrent = p;\n }\n\n private handlePointerMove(e: PointerEvent): void {\n if (!this.dragActive || !this.dragStart) return;\n if (e.buttons === 0) {\n this.handlePointerUp(e);\n return;\n }\n const p = this.screenFromEvent(e);\n const dx = p.x - this.dragStart.x;\n const dy = p.y - this.dragStart.y;\n if (\n Math.sqrt(dx * dx + dy * dy) < DRAG_THRESHOLD &&\n this.dragCurrent &&\n this.dragCurrent.x === this.dragStart.x &&\n this.dragCurrent.y === this.dragStart.y\n ) {\n return;\n }\n this.dragCurrent = p;\n this.drawRect();\n if (this.opts.immediately) this.applySelection();\n }\n\n private handlePointerUp(_e: PointerEvent): void {\n if (!this.dragActive || !this.dragStart || !this.dragCurrent) {\n this.ctxRef?.camera.viewport.plugins.resume('drag');\n this.dragActive = false;\n return;\n }\n this.clearRect();\n const hasArea = this.rectHasArea();\n if (hasArea) {\n const snapshot = this.applySelection();\n if (snapshot) this.opts.onSelect?.(snapshot);\n } else if (this.opts.clearOnBackground) {\n this.clearSelection();\n }\n this.ctxRef?.camera.viewport.plugins.resume('drag');\n this.dragActive = false;\n this.dragStart = null;\n this.dragCurrent = null;\n }\n\n private cancelDrag(): void {\n if (!this.dragActive) return;\n this.clearRect();\n this.ctxRef?.camera.viewport.plugins.resume('drag');\n this.dragActive = false;\n this.dragStart = null;\n this.dragCurrent = null;\n }\n\n // ─── Drawing ────────────────────────────────────────────────────────────\n\n private drawRect(): void {\n const g = this.gfx;\n if (!g || !this.dragStart || !this.dragCurrent) return;\n const x = Math.min(this.dragStart.x, this.dragCurrent.x);\n const y = Math.min(this.dragStart.y, this.dragCurrent.y);\n const w = Math.abs(this.dragCurrent.x - this.dragStart.x);\n const h = Math.abs(this.dragCurrent.y - this.dragStart.y);\n\n const style = this.opts.style;\n const fill = style.fill ?? 0x1677ff;\n const fillAlpha = style.fillAlpha ?? 0.1;\n const stroke = style.stroke ?? 0x1677ff;\n const strokeAlpha = style.strokeAlpha ?? 0.8;\n const strokeWidth = style.strokeWidth ?? 1;\n const strokeDash = style.strokeDash ?? [4, 4];\n\n g.clear();\n g.rect(x, y, w, h);\n g.fill({ color: fill, alpha: fillAlpha });\n\n if (strokeDash.length >= 2) {\n this.drawDashedRect(g, x, y, w, h, strokeDash, stroke, strokeAlpha, strokeWidth);\n } else {\n g.rect(x, y, w, h);\n g.stroke({ color: stroke, alpha: strokeAlpha, width: strokeWidth });\n }\n }\n\n private drawDashedRect(\n g: Graphics,\n x: number,\n y: number,\n w: number,\n h: number,\n dash: number[],\n color: number,\n alpha: number,\n lineWidth: number,\n ): void {\n const dashLen = dash[0] ?? 4;\n const gapLen = dash[1] ?? 4;\n const sides: Array<[number, number, number, number]> = [\n [x, y, x + w, y],\n [x + w, y, x + w, y + h],\n [x + w, y + h, x, y + h],\n [x, y + h, x, y],\n ];\n for (const [x1, y1, x2, y2] of sides) {\n const totalLen = Math.hypot(x2 - x1, y2 - y1);\n if (totalLen === 0) continue;\n const nx = (x2 - x1) / totalLen;\n const ny = (y2 - y1) / totalLen;\n let dist = 0;\n let drawing = true;\n while (dist < totalLen) {\n const segLen = Math.min(drawing ? dashLen : gapLen, totalLen - dist);\n if (drawing) {\n g.moveTo(x1 + nx * dist, y1 + ny * dist);\n g.lineTo(x1 + nx * (dist + segLen), y1 + ny * (dist + segLen));\n g.stroke({ color, alpha, width: lineWidth });\n }\n dist += segLen;\n drawing = !drawing;\n }\n }\n }\n\n private clearRect(): void {\n this.gfx?.clear();\n }\n\n private rectHasArea(): boolean {\n if (!this.dragStart || !this.dragCurrent) return false;\n return (\n Math.abs(this.dragCurrent.x - this.dragStart.x) > DRAG_THRESHOLD ||\n Math.abs(this.dragCurrent.y - this.dragStart.y) > DRAG_THRESHOLD\n );\n }\n\n // ─── Selection ──────────────────────────────────────────────────────────\n\n private triggerActive(e: PointerEvent): boolean {\n const { trigger } = this.opts;\n if (trigger.length === 0) return true;\n const active = new Set<string>();\n if (e.shiftKey) active.add('shift');\n if (e.ctrlKey) active.add('control');\n if (e.altKey) active.add('alt');\n if (e.metaKey) active.add('meta');\n return trigger.some((k) => active.has(k.toLowerCase()));\n }\n\n private applySelection(): SelectionSnapshot | null {\n const layer = this.layer;\n const ctx = this.ctxRef;\n if (!layer || !ctx || !this.dragStart || !this.dragCurrent) return null;\n\n const tl = ctx.camera.toWorld(\n Math.min(this.dragStart.x, this.dragCurrent.x),\n Math.min(this.dragStart.y, this.dragCurrent.y),\n );\n const br = ctx.camera.toWorld(\n Math.max(this.dragStart.x, this.dragCurrent.x),\n Math.max(this.dragStart.y, this.dragCurrent.y),\n );\n const wx1 = Math.min(tl.x, br.x);\n const wy1 = Math.min(tl.y, br.y);\n const wx2 = Math.max(tl.x, br.x);\n const wy2 = Math.max(tl.y, br.y);\n\n const wantShapes = this.opts.enableElements.includes('shape');\n const wantConnectors = this.opts.enableElements.includes('connector');\n\n const enclosedShapes = new Set<string>();\n if (wantShapes) {\n for (const node of layer.store.nodes()) {\n const pos = node.position ?? { x: 0, y: 0 };\n if (pos.x >= wx1 && pos.x <= wx2 && pos.y >= wy1 && pos.y <= wy2) {\n enclosedShapes.add(node.id);\n }\n }\n }\n const enclosedConnectors = new Set<string>();\n if (wantConnectors) {\n for (const edge of layer.store.edges()) {\n if (enclosedShapes.has(edge.source) && enclosedShapes.has(edge.target)) {\n enclosedConnectors.add(edge.id);\n }\n }\n }\n\n // Delegate to ClickSelectBehaviour when present.\n const clickSelect = ctx.behaviours.get<ClickSelectBehaviour>(this.clickSelectId);\n if (clickSelect) {\n const merged = new Map<string, SelectableElementType>();\n for (const sid of clickSelect.getSelectedShapeIds()) merged.set(sid, 'shape');\n for (const cid of clickSelect.getSelectedConnectorIds()) merged.set(cid, 'connector');\n for (const sid of enclosedShapes) merged.set(sid, 'shape');\n for (const cid of enclosedConnectors) merged.set(cid, 'connector');\n const elements: Array<{ id: string; type: SelectableElementType }> = [];\n for (const [id, type] of merged) elements.push({ id, type });\n clickSelect.selectMultiple(elements);\n return {\n shapeIds: clickSelect.getSelectedShapeIds(),\n connectorIds: clickSelect.getSelectedConnectorIds(),\n };\n }\n\n // Fallback — toggle the state directly on the GraphLayer.\n const { state } = this.opts;\n for (const sid of enclosedShapes) layer.store.setNodeState(sid, state, true);\n for (const cid of enclosedConnectors) layer.store.setEdgeState(cid, state, true);\n\n return {\n shapeIds: [...enclosedShapes],\n connectorIds: [...enclosedConnectors],\n };\n }\n\n private clearSelection(): void {\n const ctx = this.ctxRef;\n const layer = this.layer;\n if (!ctx || !layer) return;\n const clickSelect = ctx.behaviours.get<ClickSelectBehaviour>(this.clickSelectId);\n if (clickSelect) {\n clickSelect.clearSelection();\n return;\n }\n layer.store.clearNodeState(this.opts.state);\n layer.store.clearEdgeState(this.opts.state);\n }\n}\n","/**\n * `LassoSelectBehaviour` — click-and-drag freeform polygon selection in\n * **world** space (the polygon stays anchored to the graph during pan/zoom).\n *\n * Mirrors {@link BrushSelectBehaviour} but operates with point-in-polygon\n * containment instead of an AABB rect. Delegates to a\n * {@link ClickSelectBehaviour} when one is registered.\n *\n * Default `enabled: false` — register, then explicitly enable.\n *\n * Same pixi-overlay carve-out as `BrushSelectBehaviour` — the world-space\n * polygon is rendered into a `Graphics` attached to `ctx.world` (which\n * pans/zooms with the camera).\n */\n\nimport { Container, Graphics } from 'pixi.js';\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type {\n ClickSelectBehaviour,\n SelectableElementType,\n SelectionSnapshot,\n} from './ClickSelectBehaviour';\nimport type { ModifierKey } from './ModifierTracker';\n\n/** Element kinds the lasso will pick up. */\nexport type LassoSelectElementType = SelectableElementType;\n\n/** Modifier-key names accepted by `trigger`. */\nexport type LassoModifierKey = ModifierKey;\n\n/** Visual style for the polygon overlay. Same shape as the brush style. */\nexport interface LassoSelectStyle {\n fill?: number;\n fillAlpha?: number;\n stroke?: number;\n strokeAlpha?: number;\n /** Stroke width in *screen* pixels (auto-divided by zoom). Default `1`. */\n strokeWidth?: number;\n /** Dash pattern in screen pixels `[dashLen, gapLen]`. Default `[4, 4]`. */\n strokeDash?: number[];\n}\n\n/** Constructor options for `LassoSelectBehaviour`. */\nexport interface LassoSelectBehaviourOptions extends BehaviourOptions {\n layerId: string;\n clickSelectId?: string;\n\n enable?: boolean | ((event: PointerEvent) => boolean);\n enableElements?: LassoSelectElementType[];\n trigger?: LassoModifierKey[];\n immediately?: boolean;\n state?: string;\n style?: LassoSelectStyle;\n clearOnBackground?: boolean;\n onSelect?: (snapshot: SelectionSnapshot) => void;\n}\n\ninterface ResolvedOptions {\n enable: boolean | ((event: PointerEvent) => boolean);\n enableElements: LassoSelectElementType[];\n trigger: LassoModifierKey[];\n immediately: boolean;\n state: string;\n style: LassoSelectStyle;\n clearOnBackground: boolean;\n onSelect: ((snapshot: SelectionSnapshot) => void) | undefined;\n}\n\nfunction resolveOptions(\n prev: ResolvedOptions | null,\n patch: Partial<LassoSelectBehaviourOptions>,\n): ResolvedOptions {\n const base: ResolvedOptions = prev ?? {\n enable: true,\n enableElements: ['shape', 'connector'],\n trigger: ['shift'],\n immediately: false,\n state: 'selected',\n style: {},\n clearOnBackground: true,\n onSelect: undefined,\n };\n return {\n enable: patch.enable ?? base.enable,\n enableElements: patch.enableElements ?? base.enableElements,\n trigger: patch.trigger ?? base.trigger,\n immediately: patch.immediately ?? base.immediately,\n state: patch.state ?? base.state,\n style: patch.style ?? base.style,\n clearOnBackground: patch.clearOnBackground ?? base.clearOnBackground,\n onSelect: 'onSelect' in patch ? patch.onSelect : base.onSelect,\n };\n}\n\n/** Min screen-space distance (px) between consecutive points — avoids over-sampling. */\nconst MIN_POINT_DISTANCE = 5;\n/** Min screen-space drag (px) before we treat the gesture as a lasso (vs. a click). */\nconst DRAG_THRESHOLD = 3;\n\n/** Ray-casting point-in-polygon. */\nfunction pointInPolygon(\n px: number,\n py: number,\n polygon: ReadonlyArray<{ x: number; y: number }>,\n): boolean {\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i]!.x;\n const yi = polygon[i]!.y;\n const xj = polygon[j]!.x;\n const yj = polygon[j]!.y;\n const intersect =\n yi > py !== yj > py && px < ((xj - xi) * (py - yi)) / (yj - yi) + xi;\n if (intersect) inside = !inside;\n }\n return inside;\n}\n\nexport class LassoSelectBehaviour extends Behaviour {\n private readonly clickSelectId: string;\n private opts: ResolvedOptions;\n\n private layer: GraphLayer | null = null;\n private ctxRef: CanvasContext | null = null;\n\n private overlay: Container | null = null;\n private gfx: Graphics | null = null;\n\n private dragActive = false;\n /** Polygon points in WORLD space. */\n private worldPoints: Array<{ x: number; y: number }> = [];\n private lastScreen: { x: number; y: number } | null = null;\n private startScreen: { x: number; y: number } | null = null;\n\n private listenerDisposers: Array<() => void> = [];\n\n constructor(opts: LassoSelectBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['shift+drag-lasso'] });\n this.clickSelectId = opts.clickSelectId ?? 'click-select';\n this.opts = resolveOptions(null, opts);\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `LassoSelectBehaviour \"${this.id}\": layer \"${this.layerId}\" not found.`,\n );\n }\n this.layer = layer;\n this.ctxRef = ctx;\n\n // World-space overlay so the polygon stays anchored when the user pans\n // the camera mid-draw.\n this.overlay = new Container();\n this.overlay.label = `${this.id}-overlay`;\n this.overlay.zIndex = 9999;\n ctx.world.sortableChildren = true;\n ctx.world.addChild(this.overlay);\n this.gfx = new Graphics();\n this.overlay.addChild(this.gfx);\n\n const el = ctx.canvasElement;\n if (!el) return;\n\n const onDown = (e: PointerEvent) => this.handlePointerDown(e);\n const onMove = (e: PointerEvent) => this.handlePointerMove(e);\n const onUp = (e: PointerEvent) => this.handlePointerUp(e);\n const onCancel = () => this.cancelDrag();\n\n el.addEventListener('pointerdown', onDown);\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n window.addEventListener('pointercancel', onCancel);\n // NOTE: no `pointerleave` listener. Freeform lassos routinely sweep over\n // the canvas edge (or over overlapping GUI panels) — cancelling on leave\n // mid-draw kills the gesture. Window-level pointerup + pointercancel\n // cover the genuine end-of-drag and OS-level cancellation cases.\n\n this.listenerDisposers.push(\n () => el.removeEventListener('pointerdown', onDown),\n () => window.removeEventListener('pointermove', onMove),\n () => window.removeEventListener('pointerup', onUp),\n () => window.removeEventListener('pointercancel', onCancel),\n );\n }\n\n protected override onDestroy(): void {\n this.cancelDrag();\n for (const off of this.listenerDisposers) off();\n this.listenerDisposers.length = 0;\n this.gfx?.destroy();\n this.gfx = null;\n this.overlay?.removeFromParent();\n this.overlay?.destroy({ children: true });\n this.overlay = null;\n this.layer = null;\n this.ctxRef = null;\n }\n\n protected override onDisable(): void {\n this.cancelDrag();\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n get options(): Readonly<ResolvedOptions> {\n return this.opts;\n }\n\n setOptions(patch: Partial<LassoSelectBehaviourOptions>): void {\n this.opts = resolveOptions(this.opts, patch);\n }\n\n // ─── Pointer handlers ───────────────────────────────────────────────────\n\n private screenFromEvent(e: PointerEvent): { x: number; y: number } {\n const el = this.ctxRef?.canvasElement;\n if (!el) return { x: e.clientX, y: e.clientY };\n const rect = el.getBoundingClientRect();\n return { x: e.clientX - rect.left, y: e.clientY - rect.top };\n }\n\n private handlePointerDown(e: PointerEvent): void {\n this.clearPolygon();\n this.dragActive = false;\n this.worldPoints = [];\n this.lastScreen = null;\n this.startScreen = null;\n\n if (!this._enabled) return;\n if (e.button !== 0) return;\n // Reject presses on overlaid DOM chrome rather than the canvas itself.\n if (e.target !== this.ctxRef?.canvasElement) return;\n\n const { enable } = this.opts;\n if (typeof enable === 'function' ? !enable(e) : !enable) return;\n if (!this.triggerActive(e)) return;\n\n const screen = this.screenFromEvent(e);\n const world = this.ctxRef!.camera.toWorld(screen.x, screen.y);\n\n // Defer to the node-drag behaviour when the press lands on a node. The\n // `e.target` check above is insufficient on a single-canvas renderer (every\n // pointer event targets the same <canvas>), so hit-test instead. Pressing a\n // node — e.g. to drag the current selection — must not begin a fresh lasso.\n if (this.layer?.getRenderer()?.hitTest(world.x, world.y)?.kind === 'shape') {\n return;\n }\n\n this.ctxRef?.camera.viewport.plugins.pause('drag');\n\n this.dragActive = true;\n this.worldPoints = [{ x: world.x, y: world.y }];\n this.lastScreen = screen;\n this.startScreen = screen;\n }\n\n private handlePointerMove(e: PointerEvent): void {\n if (!this.dragActive || !this.lastScreen) return;\n if (e.buttons === 0) {\n this.handlePointerUp(e);\n return;\n }\n const screen = this.screenFromEvent(e);\n const dx = screen.x - this.lastScreen.x;\n const dy = screen.y - this.lastScreen.y;\n if (Math.hypot(dx, dy) < MIN_POINT_DISTANCE) return;\n\n const world = this.ctxRef!.camera.toWorld(screen.x, screen.y);\n this.worldPoints.push({ x: world.x, y: world.y });\n this.lastScreen = screen;\n this.drawPolygon();\n if (this.opts.immediately) this.applySelection();\n }\n\n private handlePointerUp(_e: PointerEvent): void {\n if (!this.dragActive) {\n this.ctxRef?.camera.viewport.plugins.resume('drag');\n return;\n }\n this.clearPolygon();\n const hasArea = this.gestureHasArea();\n if (hasArea) {\n const snapshot = this.applySelection();\n if (snapshot) this.opts.onSelect?.(snapshot);\n } else if (this.opts.clearOnBackground) {\n this.clearSelection();\n }\n this.ctxRef?.camera.viewport.plugins.resume('drag');\n this.dragActive = false;\n this.worldPoints = [];\n this.lastScreen = null;\n this.startScreen = null;\n }\n\n private cancelDrag(): void {\n if (!this.dragActive) return;\n this.clearPolygon();\n this.ctxRef?.camera.viewport.plugins.resume('drag');\n this.dragActive = false;\n this.worldPoints = [];\n this.lastScreen = null;\n this.startScreen = null;\n }\n\n private gestureHasArea(): boolean {\n if (this.worldPoints.length < 3) return false;\n if (!this.startScreen || !this.lastScreen) return false;\n const dx = this.lastScreen.x - this.startScreen.x;\n const dy = this.lastScreen.y - this.startScreen.y;\n return Math.hypot(dx, dy) > DRAG_THRESHOLD;\n }\n\n // ─── Drawing ────────────────────────────────────────────────────────────\n\n private drawPolygon(): void {\n const g = this.gfx;\n if (!g || this.worldPoints.length < 2) return;\n\n const style = this.opts.style;\n const fill = style.fill ?? 0x1677ff;\n const fillAlpha = style.fillAlpha ?? 0.1;\n const stroke = style.stroke ?? 0x1677ff;\n const strokeAlpha = style.strokeAlpha ?? 0.8;\n const strokeWidthPx = style.strokeWidth ?? 1;\n const strokeDash = style.strokeDash ?? [4, 4];\n\n const zoom = this.ctxRef?.camera.scale ?? 1;\n const lineWidth = strokeWidthPx / Math.max(zoom, 1e-6);\n\n g.clear();\n const first = this.worldPoints[0]!;\n g.moveTo(first.x, first.y);\n for (let i = 1; i < this.worldPoints.length; i++) {\n const p = this.worldPoints[i]!;\n g.lineTo(p.x, p.y);\n }\n g.closePath();\n g.fill({ color: fill, alpha: fillAlpha });\n\n if (strokeDash.length >= 2) {\n this.drawDashedClosed(g, this.worldPoints, strokeDash, stroke, strokeAlpha, lineWidth, zoom);\n } else {\n g.moveTo(first.x, first.y);\n for (let i = 1; i < this.worldPoints.length; i++) {\n const p = this.worldPoints[i]!;\n g.lineTo(p.x, p.y);\n }\n g.lineTo(first.x, first.y);\n g.stroke({ color: stroke, alpha: strokeAlpha, width: lineWidth });\n }\n }\n\n private drawDashedClosed(\n g: Graphics,\n points: ReadonlyArray<{ x: number; y: number }>,\n dash: number[],\n color: number,\n alpha: number,\n lineWidth: number,\n zoom: number,\n ): void {\n const dashLen = (dash[0] ?? 4) / Math.max(zoom, 1e-6);\n const gapLen = (dash[1] ?? 4) / Math.max(zoom, 1e-6);\n const n = points.length;\n for (let i = 0; i < n; i++) {\n const a = points[i]!;\n const b = points[(i + 1) % n]!;\n const totalLen = Math.hypot(b.x - a.x, b.y - a.y);\n if (totalLen === 0) continue;\n const nx = (b.x - a.x) / totalLen;\n const ny = (b.y - a.y) / totalLen;\n let dist = 0;\n let drawing = true;\n while (dist < totalLen) {\n const segLen = Math.min(drawing ? dashLen : gapLen, totalLen - dist);\n if (drawing) {\n g.moveTo(a.x + nx * dist, a.y + ny * dist);\n g.lineTo(a.x + nx * (dist + segLen), a.y + ny * (dist + segLen));\n g.stroke({ color, alpha, width: lineWidth });\n }\n dist += segLen;\n drawing = !drawing;\n }\n }\n }\n\n private clearPolygon(): void {\n this.gfx?.clear();\n }\n\n // ─── Selection ──────────────────────────────────────────────────────────\n\n private triggerActive(e: PointerEvent): boolean {\n const { trigger } = this.opts;\n if (trigger.length === 0) return true;\n const active = new Set<string>();\n if (e.shiftKey) active.add('shift');\n if (e.ctrlKey) active.add('control');\n if (e.altKey) active.add('alt');\n if (e.metaKey) active.add('meta');\n return trigger.some((k) => active.has(k.toLowerCase()));\n }\n\n private applySelection(): SelectionSnapshot | null {\n const layer = this.layer;\n const ctx = this.ctxRef;\n if (!layer || !ctx || this.worldPoints.length < 3) return null;\n\n const polygon = this.worldPoints;\n const wantShapes = this.opts.enableElements.includes('shape');\n const wantConnectors = this.opts.enableElements.includes('connector');\n\n const enclosedShapes = new Set<string>();\n if (wantShapes) {\n for (const node of layer.store.nodes()) {\n const pos = node.position ?? { x: 0, y: 0 };\n if (pointInPolygon(pos.x, pos.y, polygon)) enclosedShapes.add(node.id);\n }\n }\n const enclosedConnectors = new Set<string>();\n if (wantConnectors) {\n for (const edge of layer.store.edges()) {\n if (enclosedShapes.has(edge.source) && enclosedShapes.has(edge.target)) {\n enclosedConnectors.add(edge.id);\n }\n }\n }\n\n const clickSelect = ctx.behaviours.get<ClickSelectBehaviour>(this.clickSelectId);\n if (clickSelect) {\n const merged = new Map<string, SelectableElementType>();\n for (const sid of clickSelect.getSelectedShapeIds()) merged.set(sid, 'shape');\n for (const cid of clickSelect.getSelectedConnectorIds()) merged.set(cid, 'connector');\n for (const sid of enclosedShapes) merged.set(sid, 'shape');\n for (const cid of enclosedConnectors) merged.set(cid, 'connector');\n const elements: Array<{ id: string; type: SelectableElementType }> = [];\n for (const [id, type] of merged) elements.push({ id, type });\n clickSelect.selectMultiple(elements);\n return {\n shapeIds: clickSelect.getSelectedShapeIds(),\n connectorIds: clickSelect.getSelectedConnectorIds(),\n };\n }\n\n const { state } = this.opts;\n for (const sid of enclosedShapes) layer.store.setNodeState(sid, state, true);\n for (const cid of enclosedConnectors) layer.store.setEdgeState(cid, state, true);\n return { shapeIds: [...enclosedShapes], connectorIds: [...enclosedConnectors] };\n }\n\n private clearSelection(): void {\n const ctx = this.ctxRef;\n const layer = this.layer;\n if (!ctx || !layer) return;\n const clickSelect = ctx.behaviours.get<ClickSelectBehaviour>(this.clickSelectId);\n if (clickSelect) {\n clickSelect.clearSelection();\n return;\n }\n layer.store.clearNodeState(this.opts.state);\n layer.store.clearEdgeState(this.opts.state);\n }\n}\n","/**\n * `DragNodeBehaviour` — pointer-drag a `GraphLayer` node by writing the new\n * position to its `GraphStore` (not directly to the renderer).\n *\n * Differs from `@invana/canvas` `DragShapeBehaviour` in one important way:\n * the position update flows through the store, so:\n * - `node:update` events fire — anyone listening (server replication,\n * analytics, animations) sees the move.\n * - The layer's connector-reroute pass runs naturally on the store flush.\n *\n * **Doesn't pin during the drag.** The transient hold against an active\n * physics layout is done via the layer's `node:drag-start` / `node:drag-end`\n * events — layouts (e.g. `D3ForceLayout` clamping `fx/fy`) subscribe and\n * manage the lock internally. The store's `GraphNode.pinned` flag is *not*\n * touched mid-gesture, since that flag is user-data semantics (permanent\n * pin) and a drag shouldn't silently mutate it.\n *\n * **Pin on release is opt-in.** Set `pinOnRelease: true` to call\n * `store.setPinned(id, true)` on drag-end — useful when you want the user's\n * placement to survive future layout passes. Off by default; when off, a\n * released node is free again and the next layout tick may move it.\n *\n * **Selection-aware.** With `dragSelection` (default on), grabbing a node that\n * is part of the current selection drags the whole selection together. The\n * selection is read from the layer's `selectionState` visual state, so it works\n * with any select behaviour (click / lasso / brush) — this behaviour is not\n * coupled to a specific one.\n *\n * Default `enabled: false` — register, then explicitly enable.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new DragNodeBehaviour({ id: 'drag', layerId: 'graph', enabled: true }),\n * );\n * ```\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\n\n/** Constructor options for `DragNodeBehaviour`. */\nexport interface DragNodeBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id whose nodes this behaviour drags. */\n layerId: string;\n\n /**\n * Predicate to restrict which node ids are draggable. Returning `false`\n * ignores the pointerdown. Default = every node is draggable.\n */\n filter?: (id: string) => boolean;\n\n /** Cursor applied to the canvas while dragging. Default `'grabbing'`. */\n dragCursor?: string;\n\n /**\n * When `true`, set `GraphNode.pinned = true` on the dragged node when\n * the gesture ends (real drag only — a click that didn't move is a\n * no-op). The store's pinned flag is read by layouts (e.g.\n * `D3ForceLayout` writes pinned nodes to d3-force's `fx/fy`) so the\n * node stays where the user dropped it across future layout passes.\n * Default `false`. To un-pin a pinned node, call\n * `graph.store.setPinned(id, false)` explicitly.\n */\n pinOnRelease?: boolean;\n\n /**\n * When `true` (the default), dragging a node that is itself a compound\n * group (resolved `style.group` set) translates every descendant by the\n * same delta in one `setPositionsBulk` call so the whole subtree moves\n * together. Set to `false` to drag the group frame on its own — useful\n * only when descendants are layout-driven and should stay put.\n *\n * For auto-fit groups the frame's position is layer-derived from the\n * children bbox; moving descendants moves the frame naturally on the\n * next flush. For non-auto-fit groups, the group's stored `position`\n * is also updated so the declared frame follows the cursor.\n */\n groupAware?: boolean;\n\n /**\n * When `true` (the default), grabbing a node that is part of the current\n * selection drags the **whole selection** together — every selected node\n * moves by the same delta. Grabbing an unselected node (or a selection of\n * one) falls back to a plain single-node drag. Set `false` to always drag\n * just the grabbed node regardless of selection.\n *\n * Selection is read from the layer's visual state (see `selectionState`),\n * so this works uniformly whatever set it — click, lasso, or brush — with\n * no coupling to a specific select behaviour.\n */\n dragSelection?: boolean;\n\n /**\n * Name of the layer visual-state that marks a node as selected. Default\n * `'selected'`, matching `ClickSelectBehaviour`'s default `state`. Only\n * consulted when `dragSelection` is on. Override if your select behaviour\n * writes a different state name.\n */\n selectionState?: string;\n\n /**\n * When `true` (the default), a plain (no-modifier) press anywhere inside the\n * current selection's union bounding box — *including the empty world space\n * between the selected nodes* — grabs the whole selection and drags it, the\n * way Figma / PowerPoint let you drag a multi-selection by its body rather\n * than by a specific item.\n *\n * Without this, a selection is only draggable by pressing squarely on one of\n * the selected nodes; pressing in the gaps does nothing (no shape is hit, so\n * no drag starts). Off the back of a brush/lasso selection that almost always\n * reads as \"the selection won't move\" — hence default on.\n *\n * Only meaningful when `dragSelection` is also on. The press must carry no\n * modifier key (so it never collides with brush / lasso / shift-to-add) and\n * must not land on a node (those go through the normal per-node path). This\n * does mean panning the camera by dragging from *inside* the selection box is\n * no longer possible — drag from outside the box, or set this `false`.\n */\n selectionBodyDrag?: boolean;\n\n /**\n * Extra world-space padding added around the selection's union bounding box\n * when testing a press for {@link selectionBodyDrag}. Widens the grab target\n * so presses just outside the tightest box still catch. Default `0`.\n */\n selectionBodyPadding?: number;\n}\n\ninterface DragState {\n /** The grabbed node — the gesture's primary, emitted as `nodeId`. */\n readonly primaryId: string;\n /**\n * All *primary* nodes being dragged together — `[primaryId]` for a plain\n * single-node drag, or the full selection for a multi-selection drag.\n * Emitted as the `nodeIds` event payload. Group descendants are NOT here;\n * they're folded into `moveIds` instead.\n */\n readonly ids: readonly string[];\n /**\n * Pointer's world position at the gesture's anchoring moment. Captured at\n * pointerdown initially and re-captured on the first real pointermove (the\n * same instant we emit `node:drag-start`) so the gesture's delta is\n * measured from a *fresh* cursor position — see the `starts` note.\n */\n pointerWorldStart: { x: number; y: number };\n /**\n * The full set of nodes actually translated each tick: every primary in\n * `ids` plus the group descendants of any primary that is an expanded\n * compound group. Computed once on the first real pointermove.\n */\n moveIds: readonly string[];\n /**\n * Each `moveIds` entry's position at the gesture's anchoring moment,\n * captured on the first real pointermove. Per-tick targets are\n * `start + cumulativeDelta`, so reading from a fixed start (rather than the\n * live position) is correct by construction and never snowballs. Capturing\n * on first move — not pointerdown — also refreshes the anchor against an\n * active layout (e.g. `D3ForceLayout`) that may have moved the nodes between\n * pointerdown and the first move, which would otherwise make them teleport.\n */\n starts: Map<string, { x: number; y: number }>;\n /**\n * Whether the first real movement has been seen yet. We defer emitting\n * `node:drag-start` until the first real movement so a plain click on a\n * node — which goes through pointerdown + pointerup with no movement —\n * doesn't disturb the layout (a layout might reheat on the start signal).\n */\n moved: boolean;\n}\n\nexport class DragNodeBehaviour extends Behaviour {\n private layer: GraphLayer | null = null;\n private ctxRef: CanvasContext | null = null;\n\n private readonly filter?: (id: string) => boolean;\n private readonly dragCursor: string;\n private readonly groupAware: boolean;\n private readonly pinOnRelease: boolean;\n private readonly dragSelection: boolean;\n private readonly selectionState: string;\n private readonly selectionBodyDrag: boolean;\n private readonly selectionBodyPadding: number;\n\n private state: DragState | null = null;\n private offShapeDown: (() => void) | null = null;\n private offCanvasDown: (() => void) | null = null;\n private canvasEl: HTMLCanvasElement | null = null;\n private prevCursor: string | null = null;\n /**\n * Pointer id captured on `pointerdown` so we can hold the capture on the\n * canvas element for the duration of the drag — otherwise the cursor\n * crossing the canvas bounds (e.g. over a lil-gui panel) fires\n * `pointercancel` on the document and the drag ends prematurely.\n */\n private capturedPointerId: number | null = null;\n\n constructor(opts: DragNodeBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['node+drag'] });\n this.filter = opts.filter;\n this.dragCursor = opts.dragCursor ?? 'grabbing';\n this.groupAware = opts.groupAware ?? true;\n this.pinOnRelease = opts.pinOnRelease ?? false;\n this.dragSelection = opts.dragSelection ?? true;\n this.selectionState = opts.selectionState ?? 'selected';\n this.selectionBodyDrag = opts.selectionBodyDrag ?? true;\n this.selectionBodyPadding = opts.selectionBodyPadding ?? 0;\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `DragNodeBehaviour \"${this.id}\": layer \"${this.layerId}\" not found.`,\n );\n }\n this.layer = layer;\n this.ctxRef = ctx;\n this.canvasEl = ctx.canvasElement ?? null;\n\n const renderer = layer.getRenderer();\n if (!renderer) {\n throw new Error(\n `DragNodeBehaviour \"${this.id}\": target layer is not mounted.`,\n );\n }\n\n const onShapeDown = (e: {\n id: string;\n worldX: number;\n worldY: number;\n pointerId: number;\n }): void => {\n if (!this._enabled) return;\n if (this.filter && !this.filter(e.id)) return;\n if (!layer.store.hasNode(e.id)) return;\n this.capturedPointerId = e.pointerId;\n this.startDrag(e.id, e.worldX, e.worldY);\n };\n renderer.events.on('shape:pointerdown', onShapeDown);\n this.offShapeDown = () => renderer.events.off('shape:pointerdown', onShapeDown);\n\n // Figma-style \"grab the selection by its body\". Empty-space presses never\n // reach `shape:pointerdown` (the renderer emits nothing for a no-hit\n // pointerdown), so we listen on the canvas DOM element directly — the same\n // carve-out `BrushSelectBehaviour` uses for its rubber-band.\n if (this.selectionBodyDrag && this.canvasEl) {\n const el = this.canvasEl;\n const onCanvasDown = (e: PointerEvent): void => this.onCanvasPointerDown(e);\n el.addEventListener('pointerdown', onCanvasDown);\n this.offCanvasDown = () => el.removeEventListener('pointerdown', onCanvasDown);\n }\n }\n\n protected override onDestroy(): void {\n this.endDrag();\n this.offShapeDown?.();\n this.offShapeDown = null;\n this.offCanvasDown?.();\n this.offCanvasDown = null;\n this.layer = null;\n this.ctxRef = null;\n this.canvasEl = null;\n }\n\n protected override onDisable(): void {\n if (this.state) this.endDrag();\n }\n\n // ─── Drag flow ──────────────────────────────────────────────────────────\n\n /**\n * Resolve the set of *primary* nodes a gesture on `grabbedId` should drag.\n * With `dragSelection` on, a grab on a selected node drags every selected\n * node (filtered by `filter`); otherwise — or for a selection of one — just\n * the grabbed node. Group descendants are added later, in the first move.\n */\n private resolveDragSet(grabbedId: string): readonly string[] {\n const layer = this.layer;\n if (!layer || !this.dragSelection) return [grabbedId];\n if (!layer.store.hasNodeState(grabbedId, this.selectionState)) return [grabbedId];\n // Need more than one to be a multi-drag. `grabbedId` is guaranteed present\n // — it carries the state and already passed `filter` at pointerdown.\n const selected = this.selectedNodeIds();\n return selected.length > 1 ? selected : [grabbedId];\n }\n\n /** Current selection (nodes carrying `selectionState`), filtered by `filter`. */\n private selectedNodeIds(): string[] {\n const layer = this.layer;\n if (!layer) return [];\n const ids: string[] = [];\n for (const id of layer.store.nodesWithState(this.selectionState)) {\n if (this.filter && !this.filter(id)) continue;\n ids.push(id);\n }\n return ids;\n }\n\n /**\n * World-space union AABB of the given nodes, or `null` if none resolve. Each\n * node contributes its `boundsOfNode` rect (centre-relative, so offset by the\n * node's stored position); a node whose shape kind reports no bounds collapses\n * to a zero-size point at its centre.\n */\n private selectionBounds(\n ids: readonly string[],\n ): { minX: number; minY: number; maxX: number; maxY: number } | null {\n const layer = this.layer;\n if (!layer) return null;\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const id of ids) {\n const node = layer.store.getNode(id);\n if (!node) continue;\n const pos = node.position ?? { x: 0, y: 0 };\n const local = layer.boundsOfNode(node);\n const x0 = pos.x + (local?.x ?? 0);\n const y0 = pos.y + (local?.y ?? 0);\n const x1 = x0 + (local?.width ?? 0);\n const y1 = y0 + (local?.height ?? 0);\n if (x0 < minX) minX = x0;\n if (y0 < minY) minY = y0;\n if (x1 > maxX) maxX = x1;\n if (y1 > maxY) maxY = y1;\n }\n if (minX === Infinity) return null;\n return { minX, minY, maxX, maxY };\n }\n\n /**\n * Selection-body drag entry point (see `selectionBodyDrag`). A plain press on\n * empty world space that falls inside the selection's union bounds grabs the\n * whole selection. Presses on a node, with a modifier held, or outside the\n * bounds are left alone so the per-node / brush / lasso / pan paths win.\n */\n private onCanvasPointerDown(e: PointerEvent): void {\n if (!this._enabled || !this.dragSelection) return;\n if (e.button !== 0) return;\n // Any modifier means a brush / lasso / shift-to-add gesture — never a body drag.\n if (e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) return;\n // Ignore presses on overlaid DOM chrome (lil-gui, HTML controls).\n if (e.target !== this.canvasEl) return;\n // A node press already won the race via `shape:pointerdown` — don't double-start.\n if (this.state) return;\n\n const ctx = this.ctxRef;\n const layer = this.layer;\n if (!ctx || !layer) return;\n\n const { screenX, screenY } = this.clientToScreen(e.clientX, e.clientY);\n const world = ctx.camera.toWorld(screenX, screenY);\n\n // A press squarely on a node flows through the normal per-node path.\n if (layer.getRenderer()?.hitTest(world.x, world.y)?.kind === 'shape') return;\n\n const ids = this.selectedNodeIds();\n if (ids.length === 0) return;\n const b = this.selectionBounds(ids);\n if (!b) return;\n const pad = this.selectionBodyPadding;\n if (\n world.x < b.minX - pad ||\n world.x > b.maxX + pad ||\n world.y < b.minY - pad ||\n world.y > b.maxY + pad\n ) {\n return;\n }\n\n this.capturedPointerId = e.pointerId;\n this.beginDrag(ids[0]!, ids, world.x, world.y);\n }\n\n private startDrag(grabbedId: string, worldX: number, worldY: number): void {\n if (!this.layer) return;\n this.beginDrag(grabbedId, this.resolveDragSet(grabbedId), worldX, worldY);\n }\n\n /**\n * Low-level drag start shared by the per-node path ({@link startDrag}) and the\n * selection-body path ({@link onCanvasPointerDown}). `primaryId` is the gesture's\n * emitted primary; `ids` is the full primary set to translate together.\n */\n private beginDrag(\n primaryId: string,\n ids: readonly string[],\n worldX: number,\n worldY: number,\n ): void {\n if (!this.layer) return;\n this.state = {\n primaryId,\n ids,\n pointerWorldStart: { x: worldX, y: worldY },\n moveIds: [],\n starts: new Map(),\n moved: false,\n };\n\n // Pause the camera-drag plugin so the world doesn't pan while moving the node.\n this.ctxRef?.camera.viewport.plugins.pause('drag');\n\n // Window-level move/up listeners — same rationale as DragShapeBehaviour.\n window.addEventListener('pointermove', this.onWindowPointerMove);\n window.addEventListener('pointerup', this.onWindowPointerUp);\n window.addEventListener('pointercancel', this.onWindowPointerUp);\n\n if (this.canvasEl) {\n this.prevCursor = this.canvasEl.style.cursor;\n this.canvasEl.style.cursor = this.dragCursor;\n // Hold the pointer capture on the canvas DOM element for the duration\n // of the drag. Without this, the cursor crossing the canvas bounds —\n // over a lil-gui panel, the storybook chrome, or off the page — fires\n // `pointercancel` on the document, prematurely ending the drag and\n // (because we paused the camera viewport's drag plugin on startDrag\n // and resume it in endDrag) handing the still-held button off to the\n // camera-pan plugin mid-gesture. Capturing keeps every subsequent\n // pointermove routed to the canvas.\n if (this.capturedPointerId !== null) {\n try {\n this.canvasEl.setPointerCapture(this.capturedPointerId);\n } catch {\n // Capture can throw if the pointer has already been released (rare\n // race when the browser cancels between pointerdown and our\n // startDrag). Swallow — endDrag handles the missing capture.\n }\n }\n }\n }\n\n private endDrag(): void {\n if (!this.state) return;\n const { primaryId, ids, moved } = this.state;\n\n window.removeEventListener('pointermove', this.onWindowPointerMove);\n window.removeEventListener('pointerup', this.onWindowPointerUp);\n window.removeEventListener('pointercancel', this.onWindowPointerUp);\n\n if (this.prevCursor !== null && this.canvasEl) {\n this.canvasEl.style.cursor = this.prevCursor;\n this.prevCursor = null;\n }\n if (this.canvasEl && this.capturedPointerId !== null) {\n try {\n this.canvasEl.releasePointerCapture(this.capturedPointerId);\n } catch {\n // Already released by the browser (pointer ended / cancelled).\n }\n }\n this.capturedPointerId = null;\n\n this.ctxRef?.camera.viewport.plugins.resume('drag');\n this.state = null;\n\n // Only emit `drag-end` when we actually emitted `drag-start` — a plain\n // click (pointerdown + pointerup, no movement) is a no-op gesture.\n if (moved && this.layer) {\n // Order matters: pin first, then emit drag-end. The layout's\n // `node:drag-end` handler clears its transient `fx/fy` lock *unless*\n // the node is now permanently pinned (`pinnedIds.has(id)`), so the\n // store mutation has to land first to be observed. Pin every primary\n // (one batched flush), not just the grabbed one.\n if (this.pinOnRelease) {\n this.layer.store.batch(() => {\n for (const id of ids) this.layer!.store.setPinned(id, true);\n });\n }\n this.layer.events.emit('node:drag-end', { nodeId: primaryId, nodeIds: ids });\n }\n }\n\n private readonly onWindowPointerMove = (e: PointerEvent): void => {\n if (!this.state || !this.ctxRef || !this.layer) return;\n const layer = this.layer;\n const state = this.state;\n const { screenX, screenY } = this.clientToScreen(e.clientX, e.clientY);\n const world = this.ctxRef.camera.toWorld(screenX, screenY);\n\n // First real pointermove: expand the move set and snapshot anchors.\n //\n // The move set is every primary in `ids` plus, for any primary that is an\n // expanded compound group, its descendants — so a group (or a selection of\n // groups) carries its subtree. Start positions are captured *now*, against\n // the live store, rather than at pointerdown: an active layout (e.g.\n // `D3ForceLayout`) may have moved the nodes in between, and anchoring to a\n // stale position would make them teleport. Emitting `node:drag-start` here\n // (deferred past a plain click) lets layouts clamp every dragged primary.\n if (!state.moved) {\n const moveIds: string[] = [];\n const seen = new Set<string>();\n const add = (id: string): void => {\n if (seen.has(id)) return;\n const pos = layer.store.getNode(id)?.position;\n if (!pos) return;\n seen.add(id);\n moveIds.push(id);\n state.starts.set(id, { x: pos.x, y: pos.y });\n };\n for (const id of state.ids) {\n add(id);\n if (this.groupAware && layer.getGroupRole(id) === 'expanded') {\n for (const descId of layer.store.descendantsOf(id)) add(descId);\n }\n }\n state.moveIds = moveIds;\n state.pointerWorldStart = { x: world.x, y: world.y };\n state.moved = true;\n layer.events.emit('node:drag-start', {\n nodeId: state.primaryId,\n nodeIds: state.ids,\n });\n }\n\n const dx = world.x - state.pointerWorldStart.x;\n const dy = world.y - state.pointerWorldStart.y;\n\n // Translate every node in the move set by the cumulative delta from its\n // captured start. Reading from a fixed start (not the live position) is\n // correct by construction and never snowballs across ticks. One\n // `setPositionsBulk` inside a `batch` collapses the whole set into a single\n // coherent flush — shape repaints plus incident-edge reroutes — and is\n // non-silent so the layer's `node:update` subscriber runs.\n const xy = new Float32Array(state.moveIds.length * 2);\n for (let i = 0; i < state.moveIds.length; i++) {\n const start = state.starts.get(state.moveIds[i]!)!;\n xy[i * 2] = start.x + dx;\n xy[i * 2 + 1] = start.y + dy;\n }\n layer.store.batch(() => {\n layer.store.setPositionsBulk(state.moveIds, xy);\n });\n };\n\n private readonly onWindowPointerUp = (): void => {\n this.endDrag();\n };\n\n private clientToScreen(\n clientX: number,\n clientY: number,\n ): { screenX: number; screenY: number } {\n if (!this.canvasEl) return { screenX: clientX, screenY: clientY };\n const rect = this.canvasEl.getBoundingClientRect();\n return { screenX: clientX - rect.left, screenY: clientY - rect.top };\n }\n}\n","/**\n * `ContextMenuBehaviour` — surfaces right-click (context-menu) gestures on\n * nodes, edges, and the empty canvas as a single `onContextMenu` callback.\n *\n * Layer-scoped: constructed with a target `layerId`. Subscribes to that\n * layer's renderer `shape:contextmenu` / `connector:contextmenu` events and to\n * the engine-level `background:contextmenu` (empty-canvas right-click).\n *\n * **Headless.** The behaviour does not render any menu UI — it resolves the\n * target (node id + `data`, edge id + `data`, or canvas) and hands the caller\n * everything needed to position and populate their own menu. The browser's\n * native menu is suppressed by `Canvas` (`suppressBrowserContextMenu`, default\n * `true`), so no `preventDefault` is needed here.\n *\n * Default `enabled: false` — register, then explicitly enable.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new ContextMenuBehaviour({\n * id: 'context-menu',\n * layerId: 'graph',\n * enabled: true,\n * onContextMenu: ({ targetType, id, screen }) => {\n * showMenu(targetType, id, screen.x, screen.y);\n * },\n * }),\n * );\n * ```\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\n\n/** Which kind of target a context-menu gesture landed on. */\nexport type ContextMenuTargetType = 'node' | 'edge' | 'canvas';\n\n/** Payload handed to {@link ContextMenuBehaviourOptions.onContextMenu}. */\nexport interface ContextMenuEvent {\n /** What was right-clicked. */\n readonly targetType: ContextMenuTargetType;\n /** Node/edge id, or `null` for an empty-canvas right-click. */\n readonly id: string | null;\n /**\n * Arbitrary user payload from `node.data` / `edge.data`. `undefined` for a\n * canvas right-click or when the resolved item carries no `data`.\n */\n readonly data: unknown;\n /** Pointer position in world (scene) coordinates. */\n readonly world: { readonly x: number; readonly y: number };\n /**\n * Pointer position in screen (canvas-relative) coordinates, via\n * `camera.toScreen`. Add the canvas element's bounding-rect offset to place\n * a `position: fixed` menu, or use directly inside a `position: relative`\n * canvas container.\n */\n readonly screen: { readonly x: number; readonly y: number };\n}\n\n/** Constructor options for `ContextMenuBehaviour`. */\nexport interface ContextMenuBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour drives. */\n layerId: string;\n\n /**\n * Which targets fire `onContextMenu`. A right-click on a target not in this\n * list is ignored. Default `['node', 'edge', 'canvas']`.\n */\n targets?: readonly ContextMenuTargetType[];\n\n /**\n * Optional transient state name applied to the right-clicked node/edge (e.g.\n * `'context-open'`). The previously marked target is cleared first, so at\n * most one element carries it at a time. Cleared on disable/destroy.\n * `null`/`undefined` disables this. Default `null`.\n */\n state?: string | null;\n\n /** Fired on a qualifying right-click. */\n onContextMenu?: (event: ContextMenuEvent) => void;\n}\n\ninterface ResolvedOptions {\n targets: readonly ContextMenuTargetType[];\n state: string | null;\n onContextMenu: ((event: ContextMenuEvent) => void) | undefined;\n}\n\nfunction resolveOptions(\n prev: ResolvedOptions | null,\n patch: Partial<ContextMenuBehaviourOptions>,\n): ResolvedOptions {\n const base: ResolvedOptions = prev ?? {\n targets: ['node', 'edge', 'canvas'],\n state: null,\n onContextMenu: undefined,\n };\n return {\n targets: patch.targets ?? base.targets,\n state: 'state' in patch ? (patch.state ?? null) : base.state,\n onContextMenu: 'onContextMenu' in patch ? patch.onContextMenu : base.onContextMenu,\n };\n}\n\nexport class ContextMenuBehaviour extends Behaviour {\n private layer: GraphLayer | null = null;\n private opts: ResolvedOptions;\n\n /** Subscription disposers. */\n private subs: Array<() => void> = [];\n\n /** Element currently carrying `opts.state`, so we can clear it on the next open. */\n private statedTarget: { type: 'node' | 'edge'; id: string } | null = null;\n\n constructor(opts: ContextMenuBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['pointer+rclick'] });\n this.opts = resolveOptions(null, opts);\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `ContextMenuBehaviour \"${this.id}\": layer \"${this.layerId}\" not found. ` +\n `Add the GraphLayer before registering this behaviour.`,\n );\n }\n this.layer = layer;\n\n const renderer = layer.getRenderer();\n if (!renderer) {\n throw new Error(\n `ContextMenuBehaviour \"${this.id}\": target layer is not mounted. ` +\n `Add the GraphLayer to the canvas before registering this behaviour.`,\n );\n }\n\n const onShape = (e: { id: string; worldX: number; worldY: number }): void => {\n this.handle('node', e.id, e.worldX, e.worldY);\n };\n const onConn = (e: { id: string; worldX: number; worldY: number }): void => {\n this.handle('edge', e.id, e.worldX, e.worldY);\n };\n const onBackground = (e: { worldX: number; worldY: number }): void => {\n this.handle('canvas', null, e.worldX, e.worldY);\n };\n\n renderer.events.on('shape:contextmenu', onShape);\n renderer.events.on('connector:contextmenu', onConn);\n renderer.events.on('background:contextmenu', onBackground);\n\n this.subs.push(\n () => renderer.events.off('shape:contextmenu', onShape),\n () => renderer.events.off('connector:contextmenu', onConn),\n () => renderer.events.off('background:contextmenu', onBackground),\n );\n }\n\n protected override onDestroy(): void {\n this.clearStatedTarget();\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.layer = null;\n }\n\n protected override onDisable(): void {\n this.clearStatedTarget();\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /** Resolved current options (read-only snapshot). */\n get options(): Readonly<ResolvedOptions> {\n return this.opts;\n }\n\n /** Merge new options. Unspecified fields keep their current value. */\n setOptions(patch: Partial<ContextMenuBehaviourOptions>): void {\n this.opts = resolveOptions(this.opts, patch);\n }\n\n // ─── Internals ────────────────────────────────────────────────────────────\n\n private handle(\n targetType: ContextMenuTargetType,\n id: string | null,\n worldX: number,\n worldY: number,\n ): void {\n if (!this.isEnabled) return;\n if (!this.opts.targets.includes(targetType)) return;\n const layer = this.layer;\n const ctx = this.ctx;\n if (!layer || !ctx) return;\n\n let data: unknown;\n if (targetType === 'node' && id !== null) {\n data = layer.store.getNode(id)?.data;\n } else if (targetType === 'edge' && id !== null) {\n data = layer.store.getEdge(id)?.data;\n }\n\n this.applyStatedTarget(targetType, id);\n\n const screen = ctx.camera.toScreen(worldX, worldY);\n this.opts.onContextMenu?.({\n targetType,\n id,\n data,\n world: { x: worldX, y: worldY },\n screen: { x: screen.x, y: screen.y },\n });\n }\n\n /** Move the transient `opts.state` marker onto the freshly clicked target. */\n private applyStatedTarget(targetType: ContextMenuTargetType, id: string | null): void {\n const state = this.opts.state;\n if (!state) return;\n this.clearStatedTarget();\n if (id === null || targetType === 'canvas') return;\n if (targetType === 'node') this.layer?.store.setNodeState(id, state, true);\n else this.layer?.store.setEdgeState(id, state, true);\n this.statedTarget = { type: targetType, id };\n }\n\n private clearStatedTarget(): void {\n const state = this.opts.state;\n const target = this.statedTarget;\n if (!state || !target) {\n this.statedTarget = null;\n return;\n }\n if (target.type === 'node') this.layer?.store.setNodeState(target.id, state, false);\n else this.layer?.store.setEdgeState(target.id, state, false);\n this.statedTarget = null;\n }\n}\n","/**\n * `CreateNodeBehaviour` — click empty canvas to add a node to a `GraphLayer`.\n *\n * Layer-scoped; mutates the store directly (like `DragNodeBehaviour`) and also\n * fires an `onNodeCreate` callback. A `createNode` factory lets the consumer\n * shape the node (id, style, data) or veto by returning `null`.\n *\n * Background-click detection mirrors `ClickSelectBehaviour`: the renderer fires\n * `shape:click` / `connector:click` synchronously during the native DOM click,\n * so a flag set there tells us the click landed on an element (don't create).\n * A pointer-move threshold between `pointerdown` and `click` distinguishes a\n * click from a camera pan.\n *\n * Default `enabled: false` — register, then explicitly enable (e.g. an \"Add\"\n * tool mode toggles it on).\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type { GraphNode } from '../store/types';\n\n/** Constructor options for `CreateNodeBehaviour`. */\nexport interface CreateNodeBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour adds nodes to. */\n layerId: string;\n\n /**\n * Build the node to insert from the click's world position. Return `null`\n * to veto creation. Default: `{ id: <generated>, position }`.\n */\n createNode?: (world: { x: number; y: number }) => GraphNode | null;\n\n /** Fired after a node is added to the store. */\n onNodeCreate?: (node: GraphNode) => void;\n}\n\nlet createNodeSeq = 0;\n\nexport class CreateNodeBehaviour extends Behaviour {\n private layer: GraphLayer | null = null;\n private ctxRef: CanvasContext | null = null;\n private canvasEl: HTMLCanvasElement | null = null;\n\n private readonly makeNode: (world: { x: number; y: number }) => GraphNode | null;\n private readonly onNodeCreate?: (node: GraphNode) => void;\n\n /** Subscription disposers. */\n private subs: Array<() => void> = [];\n /** True when the in-flight click already landed on a node/edge. */\n private clickConsumedByElement = false;\n /** Pointerdown screen-position — used to distinguish a click from a drag/pan. */\n private pointerDownScreen: { x: number; y: number } | null = null;\n\n constructor(opts: CreateNodeBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['pointer+click'] });\n this.makeNode =\n opts.createNode ??\n ((world) => ({\n id: `n-${Date.now().toString(36)}-${(createNodeSeq++).toString(36)}`,\n position: { x: world.x, y: world.y },\n }));\n this.onNodeCreate = opts.onNodeCreate;\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(`CreateNodeBehaviour \"${this.id}\": layer \"${this.layerId}\" not found.`);\n }\n this.layer = layer;\n this.ctxRef = ctx;\n this.canvasEl = ctx.canvasElement ?? null;\n\n const renderer = layer.getRenderer();\n if (!renderer) {\n throw new Error(`CreateNodeBehaviour \"${this.id}\": target layer is not mounted.`);\n }\n\n const consume = (): void => {\n this.clickConsumedByElement = true;\n };\n const DRAG_VS_CLICK_PX = 4;\n const onPointerDown = (e: PointerEvent): void => {\n this.pointerDownScreen = e.button === 0 ? { x: e.clientX, y: e.clientY } : null;\n };\n const onClick = (e: MouseEvent): void => {\n const down = this.pointerDownScreen;\n this.pointerDownScreen = null;\n if (this.clickConsumedByElement) {\n this.clickConsumedByElement = false;\n return;\n }\n if (!this.isEnabled || e.button !== 0 || !this.layer || !this.ctxRef) return;\n if (down && Math.hypot(e.clientX - down.x, e.clientY - down.y) > DRAG_VS_CLICK_PX) return;\n\n const { screenX, screenY } = this.clientToScreen(e.clientX, e.clientY);\n const world = this.ctxRef.camera.toWorld(screenX, screenY);\n const node = this.makeNode({ x: world.x, y: world.y });\n if (!node) return;\n this.layer.store.addNode(node);\n this.onNodeCreate?.(node);\n };\n\n renderer.events.on('shape:click', consume);\n renderer.events.on('connector:click', consume);\n const el = ctx.canvasElement;\n if (el) {\n el.addEventListener('pointerdown', onPointerDown);\n el.addEventListener('click', onClick);\n }\n\n this.subs.push(\n () => renderer.events.off('shape:click', consume),\n () => renderer.events.off('connector:click', consume),\n () => {\n if (el) {\n el.removeEventListener('pointerdown', onPointerDown);\n el.removeEventListener('click', onClick);\n }\n },\n );\n }\n\n protected override onDestroy(): void {\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.layer = null;\n this.ctxRef = null;\n this.canvasEl = null;\n }\n\n private clientToScreen(clientX: number, clientY: number): { screenX: number; screenY: number } {\n if (!this.canvasEl) return { screenX: clientX, screenY: clientY };\n const rect = this.canvasEl.getBoundingClientRect();\n return { screenX: clientX - rect.left, screenY: clientY - rect.top };\n }\n}\n","/**\n * `DrawEdgeBehaviour` — drag from a source node to a target node to create an\n * edge, with a dashed rubber-band preview that follows the cursor.\n *\n * Layer-scoped; mutates the store directly (like `DragNodeBehaviour`) and fires\n * an `onEdgeCreate` callback. A `createEdge` factory shapes the edge (id, style,\n * data) or vetoes by returning `null` (e.g. to reject duplicates).\n *\n * The preview is a **transient renderer connector** routed from the source\n * shape to a free `{ kind: 'point' }` endpoint updated on every pointermove —\n * no \"cursor node\", so hit-testing for the drop target is unaffected. The\n * target node under the cursor is found with `renderer.hitTest(...)`.\n *\n * Pointer-capture + `clientToScreen` lifecycle mirrors `DragNodeBehaviour`.\n *\n * Default `enabled: false`. Don't run this and `DragNodeBehaviour` enabled at\n * the same time — both start on `shape:pointerdown` (a tool mode toggle should\n * pick one).\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\nimport type { BaseConnectorSpec } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type { GraphEdge } from '../store/types';\n\n/** Constructor options for `DrawEdgeBehaviour`. */\nexport interface DrawEdgeBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour draws edges in. */\n layerId: string;\n\n /**\n * Allow releasing on the *source* node to create a self-loop. Default\n * `false` (releasing on the source cancels). When `true`, the default\n * `createEdge` factory styles a self-loop as `pathType: 'loop-curve'` with\n * `sourceAnchor`/`targetAnchor` set to `'center'` (a loop needs center\n * anchors — `'boundary'` collapses it onto a single silhouette point).\n */\n allowSelfLoop?: boolean;\n\n /**\n * Build the edge to insert from the endpoints. Return `null` to veto (e.g.\n * a duplicate or disallowed pair). Default: `{ id: <generated>, source, target }`,\n * or a loop-styled edge when `source === target` (see {@link allowSelfLoop}).\n */\n createEdge?: (source: string, target: string) => GraphEdge | null;\n\n /** Fired after an edge is added to the store. */\n onEdgeCreate?: (edge: GraphEdge) => void;\n\n /** Rubber-band preview stroke. Defaults to a dashed light-blue line. */\n draftStyle?: Partial<{ color: number; width: number; alpha: number; dash: [number, number] }>;\n}\n\n/** Renderer id of the transient preview connector — never a real edge id. */\nconst DRAFT_ID = '__draw_edge__';\n/** Exclude the preview from hit-testing so it can't mask the drop target. */\nconst DRAFT_EXCLUDE: ReadonlySet<string> = new Set([DRAFT_ID]);\n\nlet drawEdgeSeq = 0;\n\nexport class DrawEdgeBehaviour extends Behaviour {\n private layer: GraphLayer | null = null;\n private ctxRef: CanvasContext | null = null;\n private canvasEl: HTMLCanvasElement | null = null;\n\n private readonly makeEdge: (source: string, target: string) => GraphEdge | null;\n private readonly onEdgeCreate?: (edge: GraphEdge) => void;\n private readonly allowSelfLoop: boolean;\n private readonly draft: { color: number; width: number; alpha: number; dash: [number, number] };\n\n private offShapeDown: (() => void) | null = null;\n private sourceId: string | null = null;\n private candidateTarget: string | null = null;\n private capturedPointerId: number | null = null;\n\n constructor(opts: DrawEdgeBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['shape+drag'] });\n this.allowSelfLoop = opts.allowSelfLoop ?? false;\n this.makeEdge =\n opts.createEdge ??\n ((source, target) => {\n const id = `e-${Date.now().toString(36)}-${(drawEdgeSeq++).toString(36)}`;\n if (source === target) {\n // A loop needs center anchors — boundary anchors collapse it onto a\n // single silhouette point.\n return {\n id,\n source,\n target,\n style: {\n shape: { pathType: 'loop-curve', sourceAnchor: 'center', targetAnchor: 'center' },\n },\n };\n }\n return { id, source, target };\n });\n this.onEdgeCreate = opts.onEdgeCreate;\n this.draft = {\n color: opts.draftStyle?.color ?? 0x60a5fa,\n width: opts.draftStyle?.width ?? 2,\n alpha: opts.draftStyle?.alpha ?? 0.9,\n dash: opts.draftStyle?.dash ?? [6, 4],\n };\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(`DrawEdgeBehaviour \"${this.id}\": layer \"${this.layerId}\" not found.`);\n }\n this.layer = layer;\n this.ctxRef = ctx;\n this.canvasEl = ctx.canvasElement ?? null;\n\n const renderer = layer.getRenderer();\n if (!renderer) {\n throw new Error(`DrawEdgeBehaviour \"${this.id}\": target layer is not mounted.`);\n }\n\n const onShapeDown = (e: {\n id: string;\n worldX: number;\n worldY: number;\n button: number;\n pointerId: number;\n }): void => {\n if (!this.isEnabled || e.button !== 0) return;\n this.capturedPointerId = e.pointerId;\n this.startDraw(e.id, e.worldX, e.worldY);\n };\n renderer.events.on('shape:pointerdown', onShapeDown);\n this.offShapeDown = () => renderer.events.off('shape:pointerdown', onShapeDown);\n }\n\n protected override onDestroy(): void {\n this.endDraw(false);\n this.offShapeDown?.();\n this.offShapeDown = null;\n this.layer = null;\n this.ctxRef = null;\n this.canvasEl = null;\n }\n\n protected override onDisable(): void {\n if (this.sourceId !== null) this.endDraw(false);\n }\n\n // ─── Draw flow ────────────────────────────────────────────────────────────\n\n private startDraw(sourceId: string, worldX: number, worldY: number): void {\n const renderer = this.layer?.getRenderer();\n if (!renderer) return;\n this.sourceId = sourceId;\n this.candidateTarget = null;\n\n // Don't let the camera pan while drawing.\n this.ctxRef?.camera.viewport.plugins.pause('drag');\n\n const spec: BaseConnectorSpec = {\n kind: 'connector',\n source: { kind: 'shape', shapeId: sourceId },\n target: { kind: 'point', x: worldX, y: worldY },\n router: 'straight',\n stroke: {\n color: this.draft.color,\n width: this.draft.width,\n alpha: this.draft.alpha,\n dashArray: this.draft.dash,\n },\n zIndex: 10_000,\n };\n renderer.addConnector(DRAFT_ID, spec);\n\n window.addEventListener('pointermove', this.onWindowPointerMove);\n window.addEventListener('pointerup', this.onWindowPointerUp);\n window.addEventListener('pointercancel', this.onWindowPointerUp);\n\n if (this.canvasEl && this.capturedPointerId !== null) {\n try {\n this.canvasEl.setPointerCapture(this.capturedPointerId);\n } catch {\n // Pointer already released — endDraw handles the missing capture.\n }\n }\n }\n\n private endDraw(finalize: boolean): void {\n if (this.sourceId === null) return;\n const source = this.sourceId;\n const target = this.candidateTarget;\n this.sourceId = null;\n this.candidateTarget = null;\n\n window.removeEventListener('pointermove', this.onWindowPointerMove);\n window.removeEventListener('pointerup', this.onWindowPointerUp);\n window.removeEventListener('pointercancel', this.onWindowPointerUp);\n\n const renderer = this.layer?.getRenderer();\n if (renderer?.hasConnector(DRAFT_ID)) renderer.removeConnector(DRAFT_ID);\n\n if (this.canvasEl && this.capturedPointerId !== null) {\n try {\n this.canvasEl.releasePointerCapture(this.capturedPointerId);\n } catch {\n // Already released by the browser.\n }\n }\n this.capturedPointerId = null;\n this.ctxRef?.camera.viewport.plugins.resume('drag');\n\n // `candidateTarget` already enforced the self-loop rule, so a non-null\n // target is valid to connect (including target === source when allowed).\n if (finalize && target !== null && this.layer) {\n const edge = this.makeEdge(source, target);\n if (edge) {\n this.layer.store.addEdge(edge);\n this.onEdgeCreate?.(edge);\n }\n }\n }\n\n private readonly onWindowPointerMove = (e: PointerEvent): void => {\n if (this.sourceId === null || !this.ctxRef || !this.layer) return;\n const renderer = this.layer.getRenderer();\n if (!renderer) return;\n const { screenX, screenY } = this.clientToScreen(e.clientX, e.clientY);\n const world = this.ctxRef.camera.toWorld(screenX, screenY);\n\n renderer.updateConnector(DRAFT_ID, { target: { kind: 'point', x: world.x, y: world.y } });\n\n const hit = renderer.hitTest(world.x, world.y, DRAFT_EXCLUDE);\n const onNode = hit !== null && hit.kind === 'shape';\n // Releasing on the source is allowed only when self-loops are enabled.\n this.candidateTarget =\n onNode && (this.allowSelfLoop || hit.id !== this.sourceId) ? hit.id : null;\n };\n\n private readonly onWindowPointerUp = (): void => {\n this.endDraw(true);\n };\n\n private clientToScreen(clientX: number, clientY: number): { screenX: number; screenY: number } {\n if (!this.canvasEl) return { screenX: clientX, screenY: clientY };\n const rect = this.canvasEl.getBoundingClientRect();\n return { screenX: clientX - rect.left, screenY: clientY - rect.top };\n }\n}\n","/**\n * `EraseBehaviour` — click a node or edge to delete it from a `GraphLayer`.\n *\n * The \"eraser\" tool of a drawing toolbar: clicking a node removes it **and**\n * cascades its incident edges; clicking an edge removes just that edge. Like\n * {@link CreateNodeBehaviour} / `DrawEdgeBehaviour` it mutates the store\n * directly and fires a callback — but `onErase` reports the *removed* element\n * with enough captured state (the node + its incident edges, or the edge) to\n * reconstruct it, so a consumer can journal an undoable delete.\n *\n * Hit detection rides the renderer's synchronous `shape:click` /\n * `connector:click` channels — the same ones `ClickSelectBehaviour` uses — so\n * the clicked element's id arrives directly; no world-space hit-testing needed.\n *\n * Default `enabled: false` — register, then explicitly enable (e.g. a \"Delete\"\n * tool mode toggles it on). Don't run it enabled alongside `ClickSelect` /\n * `DragNode` on the same layer: all three react to a node press, so a tool-mode\n * switch should leave exactly one on.\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type { GraphEdge, GraphNode } from '../store/types';\n\n/** Which element kinds the eraser removes. */\nexport type EraseTargetKind = 'node' | 'edge' | 'both';\n\n/**\n * Payload describing what {@link EraseBehaviour} just removed. Carries the full\n * pre-removal element(s) so a consumer can rebuild them (undo). A removed node\n * carries its cascade-removed incident `edges`.\n */\nexport type ErasedElement =\n | { kind: 'node'; node: GraphNode; edges: GraphEdge[] }\n | { kind: 'edge'; edge: GraphEdge };\n\n/** Constructor options for `EraseBehaviour`. */\nexport interface EraseBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour erases from. */\n layerId: string;\n\n /** Which element kinds a click removes. Default `'both'`. */\n target?: EraseTargetKind;\n\n /** Fired after an element is removed, with the captured pre-removal state. */\n onErase?: (removed: ErasedElement) => void;\n}\n\nexport class EraseBehaviour extends Behaviour {\n private layer: GraphLayer | null = null;\n\n private readonly target: EraseTargetKind;\n private readonly onErase?: (removed: ErasedElement) => void;\n\n /** Subscription disposers. */\n private subs: Array<() => void> = [];\n\n constructor(opts: EraseBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['pointer+click'] });\n this.target = opts.target ?? 'both';\n this.onErase = opts.onErase;\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(`EraseBehaviour \"${this.id}\": layer \"${this.layerId}\" not found.`);\n }\n this.layer = layer;\n\n const renderer = layer.getRenderer();\n if (!renderer) {\n throw new Error(`EraseBehaviour \"${this.id}\": target layer is not mounted.`);\n }\n\n const onShapeClick = (e: { id: string; button: number }): void => {\n if (!this.isEnabled || e.button !== 0) return;\n if (this.target === 'edge') return;\n this.eraseNode(e.id);\n };\n const onConnClick = (e: { id: string; button: number }): void => {\n if (!this.isEnabled || e.button !== 0) return;\n if (this.target === 'node') return;\n this.eraseEdge(e.id);\n };\n\n renderer.events.on('shape:click', onShapeClick);\n renderer.events.on('connector:click', onConnClick);\n this.subs.push(\n () => renderer.events.off('shape:click', onShapeClick),\n () => renderer.events.off('connector:click', onConnClick),\n );\n }\n\n protected override onDestroy(): void {\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.layer = null;\n }\n\n // ─── Removal ──────────────────────────────────────────────────────────────\n\n /** Capture node + incident edges, cascade-remove, then report. */\n private eraseNode(id: string): void {\n const store = this.layer?.store;\n if (!store) return;\n const node = store.getNode(id);\n if (!node) return;\n const edges = this.incidentEdges(id);\n store.removeNode(id, { cascade: true });\n this.onErase?.({ kind: 'node', node, edges });\n }\n\n /** Capture the edge, remove it, then report. */\n private eraseEdge(id: string): void {\n const store = this.layer?.store;\n if (!store) return;\n const edge = store.getEdge(id);\n if (!edge) return;\n store.removeEdge(id);\n this.onErase?.({ kind: 'edge', edge });\n }\n\n /** Cloned incident edges (both directions), deduped — self-loops appear once. */\n private incidentEdges(nodeId: string): GraphEdge[] {\n const store = this.layer!.store;\n const seen = new Set<string>();\n const out: GraphEdge[] = [];\n for (const edge of store.edgesOf(nodeId, 'both')) {\n if (seen.has(edge.id)) continue;\n seen.add(edge.id);\n out.push(edge);\n }\n return out;\n }\n}\n","/**\n * `CollapseExpandBehaviour` — clicks on a group node's `+` / `−` toggle\n * decoration flip the group between expanded and collapsed states.\n *\n * Listens for native DOM `pointerdown` on the canvas element rather than\n * the renderer's `shape:pointerdown` channel. The reason: the toggle\n * decoration is typically anchored to (or *outside*) the host's\n * silhouette — outside-`'bottom'` for collapsed circles in the reference\n * UI — and PixiJS's hit-test rejects clicks outside the silhouette so a\n * shape-level subscription would never fire for those placements. A\n * canvas-wide listener tests the click against the toggle's cached hit\n * geometry regardless of where it sits.\n *\n * Layer-scoped. Default `enabled: false` per the no-auto-registration rule.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new CollapseExpandBehaviour({\n * id: 'collapse-expand',\n * layerId: 'graph',\n * enabled: true,\n * }),\n * );\n * ```\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\nimport type { ToggleHitGeometry } from '@invana/canvas/primitives';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type { GroupOptions, NodeStyle } from '../layer/types';\n\n/**\n * Duck-typed gate for the toggle decoration instance — checks for the\n * presence of {@link ToggleDecoration.getLocalHitGeometry} instead of\n * relying on `instanceof`. Module-identity-sensitive checks break in\n * dev when a workspace bundler (Storybook's Vite, etc.) ends up loading\n * `@invana/canvas` through two different module paths, so the behaviour\n * never matches the decoration and silently no-ops.\n */\nfunction asToggleDecoration(\n deco: unknown,\n): { getLocalHitGeometry(): ToggleHitGeometry } | null {\n if (\n deco &&\n typeof (deco as { getLocalHitGeometry?: unknown }).getLocalHitGeometry === 'function'\n ) {\n return deco as { getLocalHitGeometry(): ToggleHitGeometry };\n }\n return null;\n}\n\n/**\n * Slot id the `GraphLayer` mounts the group's `+` / `−` toggle decoration on.\n * Re-exported for advanced consumers that want to read or override the\n * decoration; most callers shouldn't need it.\n */\nexport const GROUP_TOGGLE_SLOT = 'group-toggle';\n\nexport interface CollapseExpandBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour drives. */\n layerId: string;\n}\n\nexport class CollapseExpandBehaviour extends Behaviour {\n private layer: GraphLayer | null = null;\n private ctxRef: CanvasContext | null = null;\n private canvasEl: HTMLCanvasElement | null = null;\n\n constructor(opts: CollapseExpandBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['pointer+click'] });\n }\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `CollapseExpandBehaviour \"${this.id}\": layer \"${this.layerId}\" not found. ` +\n `Add the GraphLayer before registering this behaviour.`,\n );\n }\n if (!layer.getRenderer()) {\n throw new Error(\n `CollapseExpandBehaviour \"${this.id}\": target layer is not mounted. ` +\n `Add the GraphLayer to the canvas before registering this behaviour.`,\n );\n }\n this.layer = layer;\n this.ctxRef = ctx;\n this.canvasEl = ctx.canvasElement ?? null;\n if (!this.canvasEl) {\n throw new Error(\n `CollapseExpandBehaviour \"${this.id}\": canvas element is not available on the context.`,\n );\n }\n // Capture-phase so we see the event before pixi's federated dispatcher\n // turns it into a shape:pointerdown — keeps the behaviour responsive\n // even when other shape-level handlers run on the same gesture.\n this.canvasEl.addEventListener('pointerdown', this.onPointerDown, true);\n }\n\n protected override onDestroy(): void {\n if (this.canvasEl) {\n this.canvasEl.removeEventListener('pointerdown', this.onPointerDown, true);\n }\n this.layer = null;\n this.ctxRef = null;\n this.canvasEl = null;\n }\n\n private readonly onPointerDown = (e: PointerEvent): void => {\n if (!this.isEnabled) return;\n if (e.button !== 0) return; // left click only\n const hit = this.findToggleHit(e);\n if (!hit) return;\n // Consume the gesture — stop pan / drag behaviours from also grabbing\n // it. `e.stopPropagation()` keeps it from bubbling to other listeners\n // on the canvas element; the gesture is ours.\n e.stopPropagation();\n this.toggleCollapsed(hit.nodeId);\n };\n\n /**\n * Convert a `PointerEvent` into world coordinates and walk every group\n * node in the layer. Return the first group whose mounted toggle\n * decoration's hit area contains the click, or `null` if none match.\n */\n private findToggleHit(e: PointerEvent): { nodeId: string } | null {\n const layer = this.layer;\n const ctx = this.ctxRef;\n const canvasEl = this.canvasEl;\n if (!layer || !ctx || !canvasEl) return null;\n const renderer = layer.getRenderer();\n if (!renderer) return null;\n\n const rect = canvasEl.getBoundingClientRect();\n const world = ctx.camera.toWorld(e.clientX - rect.left, e.clientY - rect.top);\n\n for (const node of layer.store.nodes()) {\n const style = layer.resolveNodeStyle(node);\n if (!style.group) continue;\n\n const toggle = asToggleDecoration(renderer.getDecoration(node.id, GROUP_TOGGLE_SLOT));\n if (!toggle) continue;\n const hg = toggle.getLocalHitGeometry();\n if (hg.radius <= 0) continue;\n\n const pos = renderer.getShapePosition(node.id);\n if (!pos) continue;\n\n const dx = world.x - (pos.x + hg.cx);\n const dy = world.y - (pos.y + hg.cy);\n if (dx * dx + dy * dy <= hg.radius * hg.radius) {\n return { nodeId: node.id };\n }\n }\n return null;\n }\n\n /**\n * Flip `style.group.collapsed` via `store.updateNode`, preserving the\n * rest of the prior style. Per `feedback_updatenode_replaces_style` the\n * store replaces `style` wholesale on update — the spread keeps every\n * other field intact.\n */\n private toggleCollapsed(nodeId: string): void {\n const layer = this.layer;\n if (!layer) return;\n const node = layer.store.getNode(nodeId);\n if (!node) return;\n const priorStyle = (node.style ?? {}) as NodeStyle;\n const priorGroup = (priorStyle.group ?? {}) as GroupOptions;\n const nextStyle: NodeStyle = {\n ...priorStyle,\n group: { ...priorGroup, collapsed: !priorGroup.collapsed },\n };\n layer.store.updateNode(nodeId, { style: nextStyle });\n }\n}\n","/**\n * `NodeResizeBehaviour` — drag-resize any node (group or regular) whose\n * resolved style opts into resizing.\n *\n * The behaviour:\n * 1. mounts a single `SelectionFrameDecoration` on every eligible node.\n * The decoration paints a dashed AABB outline plus round handles at\n * the corners (and edge midpoints for rect hosts). For circle hosts\n * only the radial `'right'` handle is exposed so the user always\n * grows / shrinks the radius isotropically. Eligibility =\n * `style.resizable === true` (regular nodes) OR\n * `style.group?.userResizable === true` (compound groups);\n * 2. listens at the **canvas DOM level** for `pointerdown`. The handles\n * sit at AABB corners, which fall outside the silhouette for circles\n * and on the edge for rects — PixiJS's shape hit-test rejects those\n * clicks. Canvas-level listening sidesteps the issue: every click is\n * tested against the decoration's cached per-handle hit geometry;\n * 3. on drag (window-level `pointermove`), writes the new size back via\n * `store.updateNode`. The target field depends on the eligibility\n * flag: groups go to `style.group.width / height / radius`, regular\n * nodes go to `style.shape.width / height / radius`. Position is also\n * rewritten so the opposite anchor stays fixed on rect drags (except\n * for auto-fit groups, where the layer derives the frame's position\n * from the children bbox).\n *\n * Layer-scoped. Default `enabled: false`.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new NodeResizeBehaviour({ id: 'resize', layerId: 'graph', enabled: true }),\n * );\n * ```\n */\n\nimport {\n Behaviour,\n type BehaviourOptions,\n type CanvasContext,\n} from '@invana/canvas';\nimport type {\n SelectionFrameHandleHit,\n SelectionFramePlacement,\n} from '@invana/canvas/primitives';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type { GroupOptions, NodeStyle } from '../layer/types';\nimport type { GraphNode } from '../store/types';\n\n/**\n * Duck-typed gate for the selection-frame decoration instance. See the\n * matching helper in `CollapseExpandBehaviour` for the rationale —\n * `instanceof` checks fail under workspace bundlers that double-load\n * `@invana/canvas`.\n */\nfunction asSelectionFrame(\n deco: unknown,\n): { getLocalHandleHits(): ReadonlyArray<SelectionFrameHandleHit> } | null {\n if (\n deco &&\n typeof (deco as { getLocalHandleHits?: unknown }).getLocalHandleHits === 'function'\n ) {\n return deco as { getLocalHandleHits(): ReadonlyArray<SelectionFrameHandleHit> };\n }\n return null;\n}\n\n/** Slot id the behaviour reserves on the renderer for its selection frame. */\nconst FRAME_SLOT = 'resize-frame';\n\n/** Rect hosts get all 8 anchors — corners drive diagonal resize, midpoints drive axial. */\nconst RECT_HANDLES: SelectionFramePlacement[] = [\n 'top-left',\n 'top',\n 'top-right',\n 'right',\n 'bottom-right',\n 'bottom',\n 'bottom-left',\n 'left',\n];\n\n/** Circle hosts get a single radial handle on the right; radius math is isotropic. */\nconst CIRCLE_HANDLES: SelectionFramePlacement[] = ['right'];\n\nexport interface NodeResizeBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour drives. */\n layerId: string;\n /** Handle outer radius in px. Default `5`. */\n handleRadius?: number;\n /** Handle fill colour. Default `0xffffff`. */\n handleFill?: number;\n /** Frame border + handle outline colour. Default `0x6b7fff`. */\n frameColor?: number;\n /** Dash pattern `[dashLength, gapLength]` in px. Default `[5, 4]`. */\n dashArray?: readonly [number, number];\n /** Gap between host silhouette and the dashed frame. Default `4`. */\n framePadding?: number;\n /** Minimum width / height / radius the behaviour allows during drag. Default `20`. */\n minSize?: number;\n}\n\ninterface ResolvedOptions {\n handleRadius: number;\n handleFill: number;\n frameColor: number;\n dashArray: readonly [number, number];\n framePadding: number;\n minSize: number;\n}\n\nfunction resolveOptions(patch: Partial<NodeResizeBehaviourOptions>): ResolvedOptions {\n return {\n handleRadius: patch.handleRadius ?? 5,\n handleFill: patch.handleFill ?? 0xffffff,\n frameColor: patch.frameColor ?? 0x6b7fff,\n dashArray: patch.dashArray ?? ([5, 4] as const),\n framePadding: patch.framePadding ?? 4,\n minSize: patch.minSize ?? 20,\n };\n}\n\n/**\n * What `style.*` field a drag writes back into. `group` targets\n * `style.group.width / height / radius`; `shape` targets\n * `style.shape.width / height / radius` directly. Decided at drag-start\n * based on which flag enabled the resize.\n */\ntype WriteTarget = 'group' | 'shape';\n\ninterface DragState {\n readonly id: string;\n readonly placement: SelectionFramePlacement;\n readonly shapeKind: 'rect' | 'circle';\n readonly target: WriteTarget;\n /** Group's `style.group` snapshot at drag start. `undefined` for non-group nodes. */\n readonly startGroup: GroupOptions | undefined;\n /** Full prior style — preserved verbatim outside the fields we mutate. */\n readonly startStyle: NodeStyle;\n /** Renderer-projected world bounds at drag start. */\n readonly startBounds: { left: number; top: number; right: number; bottom: number };\n /** AABB centroid (for circle radial drags). */\n readonly startCentre: { x: number; y: number };\n}\n\nexport class NodeResizeBehaviour extends Behaviour {\n private layer: GraphLayer | null = null;\n private ctxRef: CanvasContext | null = null;\n private canvasEl: HTMLCanvasElement | null = null;\n private prevCursor: string | null = null;\n private state: DragState | null = null;\n private subs: Array<() => void> = [];\n\n private readonly opts: ResolvedOptions;\n /** Node ids that currently have a selection-frame decoration mounted. */\n private readonly mountedNodes: Set<string> = new Set();\n\n constructor(opts: NodeResizeBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? ['handle+drag'] });\n this.opts = resolveOptions(opts);\n }\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `NodeResizeBehaviour \"${this.id}\": layer \"${this.layerId}\" not found.`,\n );\n }\n if (!layer.getRenderer()) {\n throw new Error(\n `NodeResizeBehaviour \"${this.id}\": target layer is not mounted.`,\n );\n }\n this.layer = layer;\n this.ctxRef = ctx;\n this.canvasEl = ctx.canvasElement ?? null;\n if (!this.canvasEl) {\n throw new Error(\n `NodeResizeBehaviour \"${this.id}\": canvas element is not available on the context.`,\n );\n }\n\n if (this._enabled) this.refreshAllFrames();\n\n // Re-mount frames after every store flush — `rerenderNode` may have\n // disposed our slot (when the underlying shape's kind rebuilt) and\n // newly-added eligible nodes need their frame wired up.\n const offChanged = layer.events.on('data:changed', () => {\n if (this._enabled) this.refreshAllFrames();\n });\n this.subs.push(offChanged);\n\n // Canvas-level pointerdown — same rationale as `CollapseExpandBehaviour`.\n // Capture-phase so we beat pixi's federated dispatcher to the gesture\n // when the click does land on a handle.\n this.canvasEl.addEventListener('pointerdown', this.onCanvasPointerDown, true);\n }\n\n protected override onDestroy(): void {\n this.endDrag();\n this.clearAllFrames();\n for (const off of this.subs) off();\n this.subs.length = 0;\n if (this.canvasEl) {\n this.canvasEl.removeEventListener('pointerdown', this.onCanvasPointerDown, true);\n }\n this.layer = null;\n this.ctxRef = null;\n this.canvasEl = null;\n }\n\n protected override onEnable(): void {\n this.refreshAllFrames();\n }\n\n protected override onDisable(): void {\n if (this.state) this.endDrag();\n this.clearAllFrames();\n }\n\n // ─── Eligibility ────────────────────────────────────────────────────────\n\n /**\n * Returns the write-target a drag on this node would use, or `null` when\n * the node isn't resizable. A group with `userResizable: true` always\n * writes to `style.group.*`; a non-group with `style.resizable: true`\n * writes to `style.shape.*`.\n */\n private resizeTarget(node: GraphNode): WriteTarget | null {\n if (!this.layer) return null;\n const style = this.layer.resolveNodeStyle(node);\n const group = style.group;\n if (group?.userResizable && !group.collapsed) return 'group';\n if (style.resizable) {\n const kind = style.shape?.kind;\n if (kind === 'rect' || kind === 'circle') return 'shape';\n }\n return null;\n }\n\n // ─── Frame mount / unmount ──────────────────────────────────────────────\n\n private refreshAllFrames(): void {\n if (!this.layer) return;\n const visited = new Set<string>();\n for (const node of this.layer.store.nodes()) {\n const target = this.resizeTarget(node);\n if (!target) {\n if (this.mountedNodes.has(node.id)) this.clearFrameFor(node.id);\n continue;\n }\n const style = this.layer.resolveNodeStyle(node);\n const kind = style.shape?.kind as 'rect' | 'circle' | undefined;\n if (kind !== 'rect' && kind !== 'circle') {\n if (this.mountedNodes.has(node.id)) this.clearFrameFor(node.id);\n continue;\n }\n this.mountFrameFor(node.id, kind);\n visited.add(node.id);\n }\n for (const id of [...this.mountedNodes]) {\n if (!visited.has(id)) this.clearFrameFor(id);\n }\n }\n\n private mountFrameFor(nodeId: string, kind: 'rect' | 'circle'): void {\n if (!this.layer) return;\n const renderer = this.layer.getRenderer();\n if (!renderer) return;\n const handles = kind === 'rect' ? RECT_HANDLES : CIRCLE_HANDLES;\n renderer.setDecoration(nodeId, FRAME_SLOT, {\n kind: 'selection-frame',\n style: {\n borderColor: this.opts.frameColor,\n dashArray: this.opts.dashArray,\n padding: this.opts.framePadding,\n handleRadius: this.opts.handleRadius,\n handleFill: this.opts.handleFill,\n handleStrokeColor: this.opts.frameColor,\n handles,\n },\n });\n this.mountedNodes.add(nodeId);\n }\n\n private clearFrameFor(nodeId: string): void {\n if (!this.layer) return;\n const renderer = this.layer.getRenderer();\n if (!renderer) return;\n try {\n renderer.setDecoration(nodeId, FRAME_SLOT, null);\n } catch {\n // Node may have been removed before we got here — swallow.\n }\n this.mountedNodes.delete(nodeId);\n }\n\n private clearAllFrames(): void {\n for (const id of [...this.mountedNodes]) this.clearFrameFor(id);\n }\n\n // ─── Drag flow ──────────────────────────────────────────────────────────\n\n private readonly onCanvasPointerDown = (e: PointerEvent): void => {\n if (!this._enabled) return;\n if (e.button !== 0) return;\n if (this.state) return; // a drag is already in flight\n const hit = this.findHandleHit(e);\n if (!hit) return;\n e.stopPropagation();\n this.startDrag(hit.nodeId, hit.placement);\n };\n\n private findHandleHit(\n e: PointerEvent,\n ): { nodeId: string; placement: SelectionFramePlacement } | null {\n const layer = this.layer;\n const ctx = this.ctxRef;\n const canvasEl = this.canvasEl;\n if (!layer || !ctx || !canvasEl) return null;\n const renderer = layer.getRenderer();\n if (!renderer) return null;\n\n const rect = canvasEl.getBoundingClientRect();\n const world = ctx.camera.toWorld(e.clientX - rect.left, e.clientY - rect.top);\n\n for (const nodeId of this.mountedNodes) {\n const frame = asSelectionFrame(renderer.getDecoration(nodeId, FRAME_SLOT));\n if (!frame) continue;\n const pos = renderer.getShapePosition(nodeId);\n if (!pos) continue;\n for (const h of frame.getLocalHandleHits()) {\n if (h.radius <= 0) continue;\n const dx = world.x - (pos.x + h.cx);\n const dy = world.y - (pos.y + h.cy);\n if (dx * dx + dy * dy <= h.radius * h.radius) {\n return { nodeId, placement: h.placement };\n }\n }\n }\n return null;\n }\n\n private startDrag(nodeId: string, placement: SelectionFramePlacement): void {\n if (!this.layer) return;\n const node = this.layer.store.getNode(nodeId);\n if (!node) return;\n const target = this.resizeTarget(node);\n if (!target) return;\n const style = this.layer.resolveNodeStyle(node);\n const shape = style.shape;\n if (shape?.kind !== 'rect' && shape?.kind !== 'circle') return;\n const renderer = this.layer.getRenderer();\n if (!renderer) return;\n const worldBounds = renderer.getShapeWorldBounds(nodeId);\n if (!worldBounds) return;\n\n this.state = {\n id: nodeId,\n placement,\n shapeKind: shape.kind as 'rect' | 'circle',\n target,\n startGroup: target === 'group' ? { ...(style.group as GroupOptions) } : undefined,\n startStyle: (node.style ?? {}) as NodeStyle,\n startBounds: {\n left: worldBounds.x,\n top: worldBounds.y,\n right: worldBounds.x + worldBounds.width,\n bottom: worldBounds.y + worldBounds.height,\n },\n startCentre: {\n x: worldBounds.x + worldBounds.width / 2,\n y: worldBounds.y + worldBounds.height / 2,\n },\n };\n\n this.ctxRef?.camera.viewport.plugins.pause('drag');\n window.addEventListener('pointermove', this.onWindowPointerMove);\n window.addEventListener('pointerup', this.onWindowPointerUp);\n window.addEventListener('pointercancel', this.onWindowPointerUp);\n\n if (this.canvasEl) {\n this.prevCursor = this.canvasEl.style.cursor;\n this.canvasEl.style.cursor = cursorFor(placement);\n }\n }\n\n private endDrag(): void {\n if (!this.state) return;\n window.removeEventListener('pointermove', this.onWindowPointerMove);\n window.removeEventListener('pointerup', this.onWindowPointerUp);\n window.removeEventListener('pointercancel', this.onWindowPointerUp);\n if (this.prevCursor !== null && this.canvasEl) {\n this.canvasEl.style.cursor = this.prevCursor;\n this.prevCursor = null;\n }\n this.ctxRef?.camera.viewport.plugins.resume('drag');\n this.state = null;\n }\n\n private readonly onWindowPointerMove = (e: PointerEvent): void => {\n if (!this.state || !this.ctxRef || !this.layer) return;\n const rect = this.canvasEl?.getBoundingClientRect();\n const screenX = rect ? e.clientX - rect.left : e.clientX;\n const screenY = rect ? e.clientY - rect.top : e.clientY;\n const world = this.ctxRef.camera.toWorld(screenX, screenY);\n\n const st = this.state;\n if (st.shapeKind === 'circle') {\n const dx = world.x - st.startCentre.x;\n const dy = world.y - st.startCentre.y;\n const r = Math.max(this.opts.minSize, Math.hypot(dx, dy));\n this.commit(st, { radius: r });\n return;\n }\n\n let left = st.startBounds.left;\n let top = st.startBounds.top;\n let right = st.startBounds.right;\n let bottom = st.startBounds.bottom;\n const min = this.opts.minSize;\n\n if (st.placement === 'top-left' || st.placement === 'left' || st.placement === 'bottom-left') {\n left = Math.min(world.x, right - min);\n }\n if (st.placement === 'top-right' || st.placement === 'right' || st.placement === 'bottom-right') {\n right = Math.max(world.x, left + min);\n }\n if (st.placement === 'top' || st.placement === 'top-left' || st.placement === 'top-right') {\n top = Math.min(world.y, bottom - min);\n }\n if (st.placement === 'bottom' || st.placement === 'bottom-left' || st.placement === 'bottom-right') {\n bottom = Math.max(world.y, top + min);\n }\n\n const width = right - left;\n const height = bottom - top;\n this.commit(st, { width, height, posX: left, posY: top });\n };\n\n private readonly onWindowPointerUp = (): void => {\n this.endDrag();\n };\n\n /**\n * Apply the new geometry to the store. Branch on `target`:\n *\n * - `target === 'group'` — write to `style.group.width / height / radius`.\n * Position is updated for rect drags only when `autoFit !== true` (the\n * layer derives the position from the children bbox when auto-fit is on,\n * so writing it would either be redundant or fight the recompute).\n * - `target === 'shape'` — write to `style.shape.width / height / radius`.\n * Position is updated for rect drags so the opposite anchor stays put.\n *\n * Either way the store replaces `style` wholesale on update (see\n * `feedback_updatenode_replaces_style`), so the spread preserves every\n * other field.\n */\n private commit(\n st: DragState,\n next: { width?: number; height?: number; radius?: number; posX?: number; posY?: number },\n ): void {\n if (!this.layer) return;\n let nextStyle: NodeStyle;\n let mayWritePos = false;\n if (st.target === 'group') {\n const priorGroup = st.startGroup ?? {};\n nextStyle = {\n ...st.startStyle,\n group: {\n ...priorGroup,\n ...(next.width !== undefined ? { width: next.width } : {}),\n ...(next.height !== undefined ? { height: next.height } : {}),\n ...(next.radius !== undefined ? { radius: next.radius } : {}),\n },\n };\n mayWritePos = !priorGroup.autoFit && st.shapeKind === 'rect';\n } else {\n // Shape target — mutate the shape options' size fields directly.\n // The shape kind discriminator is preserved by the spread. The cast\n // through `unknown` is required because the discriminated union's\n // variants don't have a common index signature, but the shape we're\n // assembling is one of the same variants with size fields rewritten.\n const priorShape = (st.startStyle.shape ?? { kind: st.shapeKind }) as unknown as Record<string, unknown>;\n const shapePatch: Record<string, unknown> = { ...priorShape };\n if (next.width !== undefined) shapePatch.width = next.width;\n if (next.height !== undefined) shapePatch.height = next.height;\n if (next.radius !== undefined) shapePatch.radius = next.radius;\n nextStyle = {\n ...st.startStyle,\n shape: shapePatch as unknown as NodeStyle['shape'],\n };\n mayWritePos = st.shapeKind === 'rect';\n }\n const patch: Partial<GraphNode> = { style: nextStyle };\n if (mayWritePos && next.posX !== undefined && next.posY !== undefined) {\n patch.position = { x: next.posX, y: next.posY };\n }\n this.layer.store.updateNode(st.id, patch);\n }\n}\n\nfunction cursorFor(placement: SelectionFramePlacement): string {\n switch (placement) {\n case 'top':\n case 'bottom':\n return 'ns-resize';\n case 'left':\n case 'right':\n return 'ew-resize';\n case 'top-left':\n case 'bottom-right':\n return 'nwse-resize';\n case 'top-right':\n case 'bottom-left':\n return 'nesw-resize';\n }\n}\n","/**\n * `LabelCollisionBehaviour` — hides overlapping node / edge labels via a\n * greedy priority-sorted sweep so dense graphs stay legible.\n *\n * Strategy: each pass collects every label's world-space AABB, sorts the\n * label set by `priority` (configurable resolver — `priority` field on the\n * style, node-degree, or a custom callback), and walks high-to-low. A label\n * is **shown** if its AABB doesn't overlap any label already shown in the\n * same `collisionGroup`; otherwise it's hidden for this frame. Labels with\n * `forceShow: true` skip the check entirely (use for hovered / selected\n * elements).\n *\n * Default groups partition node labels and edge labels — a node label never\n * loses to an edge label of higher priority.\n *\n * The behaviour reruns on every store flush (data churn) and on every\n * `camera:zoom` / `camera:pan` event (viewport churn). A small hysteresis\n * timer keeps just-flipped labels from immediately flipping back when zoom\n * leaves them right on the overlap boundary.\n *\n * Default `enabled: false` — register, then explicitly enable. Matches the\n * project rule that no behaviour auto-activates.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new LabelCollisionBehaviour({\n * id: 'label-collision',\n * layerId: 'graph',\n * enabled: true,\n * prioritise: 'node-degree',\n * }),\n * );\n * ```\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext, type Rect } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type { EdgeStyle, NodeStyle } from '../layer/types';\n\n/** Subset of label settings the collision pass needs — pulled from a\n * resolved {@link NodeStyle} / {@link EdgeStyle} via flat label fields or\n * the `labelStyle` escape hatch. */\ninterface LabelSettings {\n readonly priority?: number;\n readonly collisionGroup?: string;\n readonly forceShow?: boolean;\n}\n\nfunction labelSettingsFromStyle(\n style: Partial<NodeStyle> | Partial<EdgeStyle>,\n): LabelSettings | undefined {\n const hasFlat =\n style.labelText !== undefined\n || style.labelPriority !== undefined\n || style.labelCollisionGroup !== undefined\n || style.labelForceShow !== undefined;\n if (style.labelStyle === undefined && !hasFlat) return undefined;\n\n const ls = style.labelStyle;\n return {\n priority: style.labelPriority ?? ls?.priority,\n collisionGroup: style.labelCollisionGroup ?? ls?.collisionGroup,\n forceShow: style.labelForceShow ?? ls?.forceShow,\n };\n}\n\n/** What the behaviour does with an overlap. `'hide'` is the only strategy in v0. */\nexport type LabelCollisionStrategy = 'hide';\n\n/** How label priority is resolved when sorting. */\nexport type LabelPriorityResolver =\n | 'priority-field' // read `priority` from the label style (default)\n | 'node-degree' // higher node degree wins; edges fall back to 0\n | ((kind: 'node' | 'edge', id: string) => number);\n\nexport interface LabelCollisionBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour drives. */\n layerId: string;\n\n /** Default `'hide'`. */\n strategy?: LabelCollisionStrategy;\n\n /** Default `'priority-field'`. Falls back to node-degree when undefined. */\n prioritise?: LabelPriorityResolver;\n\n /**\n * Hysteresis: a just-hidden label stays hidden for at least this many ms\n * before it can re-appear, and vice versa. Stops flicker when zoom is\n * right at an overlap boundary. Default `100`.\n */\n flickerGuardMs?: number;\n\n /**\n * Default `'nodes'` for node labels, `'edges'` for edge labels. Set to a\n * custom mapping if you want different partitioning (e.g. all in one\n * group so edges can win priority against nodes).\n */\n groups?: {\n nodes?: string;\n edges?: string;\n };\n}\n\ninterface ResolvedOptions {\n strategy: LabelCollisionStrategy;\n prioritise: LabelPriorityResolver;\n flickerGuardMs: number;\n nodeGroup: string;\n edgeGroup: string;\n}\n\ninterface LabelRecord {\n kind: 'node' | 'edge';\n id: string;\n bounds: Rect;\n priority: number;\n group: string;\n forceShow: boolean;\n}\n\nexport class LabelCollisionBehaviour extends Behaviour {\n private layer: GraphLayer | null = null;\n private opts: ResolvedOptions;\n\n /** Last-flip timestamp per label id (perf.now()). */\n private readonly lastFlip = new Map<string, number>();\n /** Last visibility decision per label id. */\n private readonly lastVisible = new Map<string, boolean>();\n\n /** Subscription disposers, called in onDestroy. */\n private subs: Array<() => void> = [];\n\n /** Coalesce repeated triggers within a single frame. */\n private scheduled = false;\n\n constructor(opts: LabelCollisionBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? [] });\n this.opts = {\n strategy: opts.strategy ?? 'hide',\n prioritise: opts.prioritise ?? 'priority-field',\n flickerGuardMs: opts.flickerGuardMs ?? 100,\n nodeGroup: opts.groups?.nodes ?? 'nodes',\n edgeGroup: opts.groups?.edges ?? 'edges',\n };\n }\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `LabelCollisionBehaviour \"${this.id}\": layer \"${this.layerId}\" not found.`,\n );\n }\n this.layer = layer;\n\n // Recompute on data churn — labels appear / disappear / move when the\n // store emits a flush after a batch of node / edge inserts or updates.\n const offFlush = layer.store.events.on('flush', () => this.schedule());\n this.subs.push(offFlush);\n\n // Recompute on camera change — zoom alters effective overlap, pan can\n // bring previously-out-of-viewport labels into bounds (and vice versa).\n const bus = ctx.events;\n const onCameraChange = (): void => this.schedule();\n bus.on('camera:zoom', onCameraChange);\n bus.on('camera:pan', onCameraChange);\n this.subs.push(\n () => bus.off('camera:zoom', onCameraChange),\n () => bus.off('camera:pan', onCameraChange),\n );\n\n // Initial sweep.\n if (this.enabled) this.schedule();\n }\n\n protected override onDestroy(): void {\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.lastFlip.clear();\n this.lastVisible.clear();\n this.layer = null;\n }\n\n protected override onEnable(): void {\n this.schedule();\n }\n\n protected override onDisable(): void {\n // Restore every previously-hidden label so the visual state is clean.\n if (!this.layer) return;\n const r = this.layer.getRenderer();\n if (!r) return;\n for (const id of this.lastVisible.keys()) r.setDecorationVisible(id, 'label', true);\n this.lastVisible.clear();\n this.lastFlip.clear();\n }\n\n /** Coalesce repeated triggers within a microtask. Cheap; runs at most once per frame. */\n private schedule(): void {\n if (!this.enabled || this.scheduled) return;\n this.scheduled = true;\n queueMicrotask(() => {\n this.scheduled = false;\n this.runPass();\n });\n }\n\n /**\n * Walk every label, sort by priority, greedy-hide overlaps within the\n * same `collisionGroup`. Mutates label `gfx.visible`; doesn't touch\n * decoration state otherwise.\n */\n private runPass(): void {\n if (!this.enabled) return;\n const layer = this.layer;\n if (!layer) return;\n const renderer = layer.getRenderer();\n if (!renderer) return;\n\n const records: LabelRecord[] = [];\n\n for (const node of layer.store.nodes()) {\n const settings = labelSettingsFromStyle(layer.resolveNodeStyle(node));\n if (settings === undefined) continue;\n const b = renderer.getDecorationWorldBounds(node.id, 'label');\n if (!b || b.width === 0 || b.height === 0) continue;\n records.push({\n kind: 'node',\n id: node.id,\n bounds: b,\n priority: this.priorityFor('node', node.id, settings),\n group: settings.collisionGroup ?? this.opts.nodeGroup,\n forceShow: settings.forceShow === true,\n });\n }\n\n for (const edge of layer.store.edges()) {\n const settings = labelSettingsFromStyle(layer.resolveEdgeStyle(edge));\n if (settings === undefined) continue;\n const b = renderer.getDecorationWorldBounds(edge.id, 'label');\n if (!b || b.width === 0 || b.height === 0) continue;\n records.push({\n kind: 'edge',\n id: edge.id,\n bounds: b,\n priority: this.priorityFor('edge', edge.id, settings),\n group: settings.collisionGroup ?? this.opts.edgeGroup,\n forceShow: settings.forceShow === true,\n });\n }\n\n records.sort((a, b) => b.priority - a.priority);\n\n const shownByGroup = new Map<string, LabelRecord[]>();\n const now = performance.now();\n\n for (const rec of records) {\n let show: boolean;\n if (rec.forceShow) {\n show = true;\n } else {\n const group = shownByGroup.get(rec.group);\n show = !group || !group.some((r) => intersects(r.bounds, rec.bounds));\n }\n\n // Hysteresis: don't flip again if we just flipped recently.\n const last = this.lastVisible.get(rec.id);\n if (last !== undefined && last !== show) {\n const since = now - (this.lastFlip.get(rec.id) ?? 0);\n if (since < this.opts.flickerGuardMs) {\n show = last;\n }\n }\n\n if (show) {\n let g = shownByGroup.get(rec.group);\n if (!g) {\n g = [];\n shownByGroup.set(rec.group, g);\n }\n g.push(rec);\n }\n\n if (this.lastVisible.get(rec.id) !== show) {\n this.lastFlip.set(rec.id, now);\n this.lastVisible.set(rec.id, show);\n renderer.setDecorationVisible(rec.id, 'label', show);\n }\n }\n }\n\n private priorityFor(\n kind: 'node' | 'edge',\n id: string,\n settings: LabelSettings,\n ): number {\n const resolver = this.opts.prioritise;\n if (typeof resolver === 'function') return resolver(kind, id);\n if (resolver === 'priority-field') {\n if (settings.priority !== undefined) return settings.priority;\n // Fallback: degree for nodes, 0 for edges (edge labels rarely have a\n // natural ranking; consumers pass a function when they want one).\n return kind === 'node' ? this.degreeOf(id) : 0;\n }\n // resolver === 'node-degree'\n return kind === 'node' ? this.degreeOf(id) : 0;\n }\n\n private degreeOf(nodeId: string): number {\n if (!this.layer) return 0;\n let n = 0;\n for (const _ of this.layer.store.edgesOf(nodeId, 'both')) n++;\n return n;\n }\n}\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction intersects(a: Rect, b: Rect): boolean {\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\n","/**\n * `LabelResolutionLODBehaviour` — re-rasterise label glyphs at higher\n * resolution as the camera zooms in, so text stays crisp instead of\n * sampling-blurry when the user inspects nodes up close.\n *\n * **Why this is tier-based, not step-based.** Pixi rasterises each `Text`\n * to a glyph texture exactly once (default resolution = renderer DPR).\n * When the world is scaled 5×, that texture is upsampled 5× — fuzzy.\n * Re-rasterising fixes the fuzziness but regenerates every label's\n * texture on the GPU, which is the expensive part. With a few thousand\n * labels (e.g. the H-1B pack story) a re-raster is a multi-hundred-ms\n * frame pause — perceptible as a stutter mid-zoom.\n *\n * An earlier design snapped the zoom to a step (e.g. `step: 0.5`) and\n * re-rastered at every snap boundary — so a continuous zoom from 1× to\n * 6× crossed ~10 boundaries and dropped frames at each one. This design\n * uses **discrete tiers**: a few widely-spaced minZoom thresholds, with\n * a multiplier per tier. In a typical zoom-in-and-stay session the user\n * crosses one boundary, pays one re-raster, and the rest is GPU-cheap.\n *\n * **Hysteresis** keeps boundary scrolls (1.49 → 1.51 → 1.49) from\n * flickering between tiers. After crossing UP into tier N, the behaviour\n * only reverts to tier N-1 when zoom drops below\n * `levels[N].minZoom - hysteresis`.\n *\n * Default `enabled: false` — register, then explicitly enable. Matches\n * the project rule that no behaviour auto-activates.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new LabelResolutionLODBehaviour({\n * id: 'label-resolution',\n * layerId: 'graph',\n * enabled: true,\n * // Defaults: 1× DPR by default, jump to 4× DPR once zoom > 1.5.\n * // Override for more or fewer tiers.\n * levels: [\n * { minZoom: 0, multiplier: 1 },\n * { minZoom: 1.5, multiplier: 4 },\n * { minZoom: 5, multiplier: 8 },\n * ],\n * }),\n * );\n * ```\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\n\n/** One discrete LOD tier. Highest `minZoom` ≤ current zoom wins. */\nexport interface LabelResolutionLODTier {\n /** Camera zoom (`canvas.camera.scale`) at which this tier becomes active. */\n minZoom: number;\n /** Multiplier applied to `baseResolution` while this tier is active. */\n multiplier: number;\n}\n\nexport interface LabelResolutionLODBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour drives. */\n layerId: string;\n\n /**\n * Base resolution to multiply by the active tier's multiplier. Default\n * `window.devicePixelRatio` (≈ 1 on standard displays, 2 on retina). Set\n * this if your Canvas was initialised with a custom `resolution` option.\n */\n baseResolution?: number;\n\n /**\n * Discrete zoom tiers, evaluated as a step function. Each tier names a\n * `minZoom` at which it activates and a `multiplier` applied to\n * `baseResolution` while it's active. Order doesn't matter — the\n * behaviour sorts by `minZoom` internally.\n *\n * Pick *few, widely-spaced* tiers: every additional tier means another\n * GPU re-raster of every label during a typical zoom-in pass. Default:\n * `[{ minZoom: 0, multiplier: 1 }, { minZoom: 1.5, multiplier: 4 }]` —\n * one threshold, one re-raster.\n */\n levels?: LabelResolutionLODTier[];\n\n /**\n * Hysteresis applied to *downward* tier changes. After crossing UP into\n * tier N at `levels[N].minZoom`, the behaviour only reverts to tier N-1\n * once zoom drops below `levels[N].minZoom - hysteresis`. Prevents\n * flicker when the user dithers on a threshold. Default `0.1`.\n */\n hysteresis?: number;\n}\n\ninterface ResolvedOptions {\n baseResolution: number;\n /** Sorted ascending by `minZoom`. Guaranteed non-empty. */\n levels: LabelResolutionLODTier[];\n hysteresis: number;\n}\n\nconst DEFAULT_LEVELS: LabelResolutionLODTier[] = [\n // Each tier covers a ~2.5× zoom band so sampling stays ≥ ~1px-per-glyph-\n // px through the whole zoom range. The math: at zoom Z with multiplier M\n // and DPR=2, glyph-texture sampling per displayed pixel = (M * 2) / Z.\n // Aim for ≥ 1 to keep text crisp. So multiplier ≈ Z / 2.\n { minZoom: 0, multiplier: 1 }, // 0 – 1.5×: native DPR\n { minZoom: 1.5, multiplier: 4 }, // 1.5 – 4×: sampling 8/Z ∈ [2, 5.3]\n { minZoom: 4, multiplier: 8 }, // 4 – 10×: sampling 16/Z ∈ [1.6, 4]\n { minZoom: 10, multiplier: 16 }, // 10×+ : sampling 32/Z, headroom for deep zoom\n];\n\nexport class LabelResolutionLODBehaviour extends Behaviour {\n private layer: GraphLayer | null = null;\n private readonly opts: ResolvedOptions;\n private subs: Array<() => void> = [];\n /**\n * Index into `opts.levels` of the currently active tier. Re-evaluated\n * on every camera-zoom event; the renderer is only nudged when this\n * index actually changes, so a continuous zoom inside one tier costs\n * nothing past the cheap comparison below.\n */\n private currentTierIdx = 0;\n /** Last resolution actually pushed to the renderer. */\n private lastPushed: number | null = null;\n\n constructor(opts: LabelResolutionLODBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? [] });\n const baseResolution =\n opts.baseResolution ??\n (typeof window !== 'undefined' ? window.devicePixelRatio : 1) ??\n 1;\n const rawLevels = opts.levels && opts.levels.length > 0 ? opts.levels : DEFAULT_LEVELS;\n // Sort + defensive-copy so callers can mutate their array after register.\n const levels = rawLevels.slice().sort((a, b) => a.minZoom - b.minZoom);\n // First tier must cover zoom 0; if the user didn't supply one, prepend.\n if (levels[0]!.minZoom > 0) {\n levels.unshift({ minZoom: 0, multiplier: 1 });\n }\n this.opts = {\n baseResolution,\n levels,\n hysteresis: opts.hysteresis ?? 0.1,\n };\n }\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `LabelResolutionLODBehaviour \"${this.id}\": layer \"${this.layerId}\" not found.`,\n );\n }\n this.layer = layer;\n\n const onCameraZoom = (): void => this.apply();\n ctx.events.on('camera:zoom', onCameraZoom);\n this.subs.push(() => ctx.events.off('camera:zoom', onCameraZoom));\n\n // Re-apply on layer data churn — newly added labels mount with the\n // renderer's tracked resolution automatically, but a one-shot push\n // here keeps the path predictable when the developer toggles the\n // behaviour off then back on after a data swap.\n const offFlush = layer.store.events.on('flush', () => this.apply());\n this.subs.push(offFlush);\n\n if (this.enabled) this.apply();\n }\n\n protected override onDestroy(): void {\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.layer = null;\n this.lastPushed = null;\n this.currentTierIdx = 0;\n }\n\n protected override onEnable(): void {\n this.apply();\n }\n\n protected override onDisable(): void {\n // Restore baseline so disabling the behaviour doesn't leave labels\n // stuck at a stale high resolution.\n const renderer = this.layer?.getRenderer();\n if (renderer) renderer.setLabelsResolution(this.opts.baseResolution);\n this.lastPushed = this.opts.baseResolution;\n this.currentTierIdx = 0;\n }\n\n /**\n * Re-evaluate the active tier under the current camera zoom and push the\n * tier's resolution to the renderer only when the tier index changes.\n * Continuous zoom inside one tier is a constant-time no-op past the\n * `idx === currentTierIdx` check below.\n */\n private apply(): void {\n if (!this.enabled) return;\n const renderer = this.layer?.getRenderer();\n if (!renderer || !this.ctx) return;\n const zoom = this.ctx.camera.scale;\n\n let idx = this.currentTierIdx;\n const levels = this.opts.levels;\n const hyst = this.opts.hysteresis;\n // Climb up: highest tier whose minZoom ≤ zoom wins.\n while (idx + 1 < levels.length && levels[idx + 1]!.minZoom <= zoom) idx++;\n // Climb down with hysteresis: only fall out of tier N when we're a\n // full `hysteresis` below its minZoom, never flicker on the boundary.\n while (idx > 0 && zoom < levels[idx]!.minZoom - hyst) idx--;\n\n if (idx === this.currentTierIdx && this.lastPushed !== null) return;\n this.currentTierIdx = idx;\n const next = levels[idx]!.multiplier * this.opts.baseResolution;\n if (this.lastPushed !== null && Math.abs(this.lastPushed - next) < 1e-6) return;\n this.lastPushed = next;\n renderer.setLabelsResolution(next);\n }\n}\n","/**\n * `NodeSizeLODBehaviour` — keep `GraphLayer` node bodies (and their\n * outline strokes) at a fixed screen-pixel size across camera zoom.\n *\n * Concrete subclass of `ElementSizeLODBehaviour` — that base owns the\n * RAF coalescing, `camera:zoom` subscription, and enable/disable\n * lifecycle. This class only knows how to rescale graph nodes.\n *\n * ## How it works (transform-scale fast path)\n *\n * On enable (and on `reflow()` after a GUI knob moves), the behaviour\n * does **one** expensive O(N) pass: it rewrites every node's spec so\n * the geometric values (`radius`, `width`, `height`, `stroke.width`)\n * carry the target-pixel sizes as if they were world units. Then per\n * `camera:zoom` it does the cheap pass: a single\n * `renderer.scaleShape(id, 1 / cameraScale)` per node, which just writes\n * the gfx transform — no `Graphics.clear()`, no path retrace, no spec\n * mutation. That collapses thousands of geometry rebuilds per zoom\n * frame into thousands of transform writes (~50× cheaper).\n *\n * Stroke width travels along the transform (Pixi strokes are in local\n * units), so the stroke is pixel-constant by construction. There is no\n * way to opt the stroke out of the transform while keeping the body in\n * — the two are coupled by the single scale factor.\n *\n * Pair with {@link EdgeSizeLODBehaviour} when you also want pixel-constant\n * edge strokes. They're independent behaviours; their RAF callbacks\n * batch into the same animation frame, so registering both has the same\n * per-frame cost as one monolith doing both passes.\n *\n * Supports `circle` and `rect` node shapes. `arc`-shape nodes are\n * skipped — their geometry is in `innerR` / `outerR` / sweep angles and\n * doesn't map cleanly to a single screen-px input.\n *\n * Hosts with `setDecoration` decorations or attached badges are also\n * supported, but those auxiliary visuals are **not** re-anchored on\n * each zoom — the underlying `scaleShape` fast path skips the\n * decoration / badge refresh that `updateShape` performs. Acceptable\n * for halos/glows (still centred on the host); inappropriate for\n * placement-sensitive badges. Use `updateShape` directly in that case.\n *\n * @example\n * ```ts\n * import { NodeSizeLODBehaviour } from '@invana/graph';\n *\n * canvas.behaviours.register(\n * new NodeSizeLODBehaviour({\n * id: 'node-size-lod',\n * enabled: true,\n * layers: [\n * {\n * layerId: 'graph',\n * sizePx: 6, // node diameter in screen px\n * strokeWidthPx: 1, // outline width in screen px (omit to leave in world units)\n * },\n * ],\n * }),\n * );\n * ```\n */\n\nimport {\n ElementSizeLODBehaviour,\n resolveNumberOrGetter,\n type CanvasContext,\n type ElementSizeLODBehaviourOptions,\n type NumberOrGetter,\n type PrimitivesRenderer,\n} from '@invana/canvas';\n\nimport type { GraphLayer } from '../layer/GraphLayer';\n\n/** Per-`GraphLayer` config — one entry per layer this behaviour rescales. */\nexport interface NodeSizeLODConfig {\n /** Required — the `GraphLayer` whose nodes are rescaled. */\n layerId: string;\n /**\n * Target body size in screen px for nodes that don't carry a per-node\n * `data.size` override. Falls back to the layer's `nodeDefaults.size`\n * when omitted. Accepts a static number or a getter — getters re-read\n * on every reflow so GUI sliders update live.\n */\n sizePx?: NumberOrGetter;\n /**\n * Target outline width in screen px. When omitted, the layer's\n * `nodeDefaults.strokeWidth` (or each node's `data.strokeWidth`) is\n * reinterpreted as the implicit pixel target — the transform-scale\n * fast path always pins both body and stroke together, so the stroke\n * is pixel-constant even without an explicit value here. Setting an\n * explicit value just changes what that pixel target is.\n */\n strokeWidthPx?: NumberOrGetter;\n}\n\nexport interface NodeSizeLODBehaviourOptions extends ElementSizeLODBehaviourOptions {\n /** One config per `GraphLayer` to drive. */\n layers: NodeSizeLODConfig[];\n}\n\ninterface ResolvedTarget {\n config: NodeSizeLODConfig;\n layer: GraphLayer;\n}\n\n/**\n * Trailing-edge debounce for the reanchor pass — see\n * {@link NodeSizeLODBehaviour.apply}. Picked to match\n * {@link EdgeSizeLODBehaviour}'s `DEFAULT_EDGE_SETTLE_MS = 80`: short\n * enough to feel \"instant on release\", long enough that a fling never\n * fires it mid-gesture.\n */\nconst REANCHOR_SETTLE_MS = 80;\n\nexport class NodeSizeLODBehaviour extends ElementSizeLODBehaviour {\n private readonly configs: NodeSizeLODConfig[];\n private resolved: ResolvedTarget[] = [];\n /**\n * Pending reanchor timer. The per-frame `scaleShape` fast path is cheap\n * (transform writes only), but `reanchorAllConnectors` rebuilds every\n * connector's Pixi geometry — at thousands of edges that drops fps to\n * the floor under a continuous zoom gesture. Coalesce to a single\n * trailing-edge call.\n */\n private reanchorTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(opts: NodeSizeLODBehaviourOptions) {\n super(opts);\n this.configs = opts.layers.slice();\n }\n\n protected override onResolveTargets(ctx: CanvasContext): void {\n for (const config of this.configs) {\n const layer = ctx.layers.get<GraphLayer>(config.layerId);\n if (!layer) {\n throw new Error(\n `NodeSizeLODBehaviour \"${this.id}\": layer \"${config.layerId}\" not found in CanvasContext.`,\n );\n }\n this.resolved.push({ config, layer });\n }\n }\n\n protected override onReleaseTargets(): void {\n if (this.reanchorTimer !== null) {\n clearTimeout(this.reanchorTimer);\n this.reanchorTimer = null;\n }\n this.resolved = [];\n }\n\n /**\n * Per-frame fast path. Sets `gfx.scale = 1 / cameraScale` on every node\n * via the renderer's transform fast path — no geometry rebuild. The\n * spec was pre-set to \"target-px values treated as world units\" by\n * {@link writeBaseline} at enable / reflow time, so:\n *\n * on-screen = nativeWorldSize × cameraScale × gfxScale\n * = (sizePx / 1) × cameraScale × (1 / cameraScale)\n * = sizePx ✓\n *\n * Stroke width scales with the body (Pixi's stroke is in local units)\n * — which is precisely the pixel-constant intent.\n */\n protected override apply(rawScale: number): void {\n const scale = Math.max(rawScale, 1e-6);\n const gfxScale = 1 / scale;\n for (const { layer } of this.resolved) {\n const renderer = layer.getRenderer();\n if (!renderer) continue;\n for (const node of layer.store.nodes()) {\n renderer.scaleShape(node.id, gfxScale);\n }\n }\n // The transform-scale fast path mutates each shape's *visible*\n // silhouette without touching its spec. Connectors anchored to those\n // shapes cached a path against the pre-scale bounds, so they fall\n // short of (or overshoot) the now-resized shape until re-anchored.\n //\n // Reanchoring runs `recomputeConnectorPath` per edge, which redraws\n // the Pixi geometry — at multiple-thousand edges that flattens fps\n // during a continuous zoom. We debounce the reanchor to a trailing\n // call: mid-gesture frames stay on the cheap `scaleShape`-only path\n // and edges snap to the new silhouette ~80ms after the user stops\n // zooming. The transient mis-anchor is bounded by node radius in\n // screen px (≈ 5px at typical `sizePx`) — visually negligible.\n this.scheduleReanchor();\n }\n\n private scheduleReanchor(): void {\n if (this.reanchorTimer !== null) clearTimeout(this.reanchorTimer);\n this.reanchorTimer = setTimeout(() => {\n this.reanchorTimer = null;\n this.flushReanchor();\n }, REANCHOR_SETTLE_MS);\n }\n\n private flushReanchor(): void {\n if (this.reanchorTimer !== null) {\n clearTimeout(this.reanchorTimer);\n this.reanchorTimer = null;\n }\n for (const { layer } of this.resolved) {\n const renderer = layer.getRenderer();\n if (!renderer) continue;\n // Hit-test bboxes for this layer's nodes were intentionally left\n // stale by the mid-gesture `scaleShape` fast path (per-id `hit.update`\n // is O(N²) for thousands of shapes). Rebuild them once now via the\n // bulk path so pointer hit-tests are accurate the moment the user\n // stops zooming.\n const ids: string[] = [];\n for (const node of layer.store.nodes()) ids.push(node.id);\n renderer.reindexScaledShapeHits(ids);\n renderer.reanchorAllConnectors();\n }\n }\n\n protected override onEnable(): void {\n if (!this.ctx) return;\n // Heavy one-shot pass: rewrite every node's spec to \"target-px values\n // treated as world units\" so the per-frame `apply` can be pure\n // transform writes. Skipped when no targets resolved (paranoid guard\n // — `onRegister` always populates `this.resolved`).\n this.writeBaseline('target');\n super.onEnable();\n }\n\n protected override onDisable(): void {\n // `super.onDisable` calls `apply(1)` which sets `gfx.scale = 1` on\n // every node via the fast path. Then restore spec back to world-unit\n // values so the visual matches the LOD-off baseline at any camera\n // scale (otherwise nodes would render at `sizePx` world units on\n // disable, which is \"huge\" when sizePx > defaults.size).\n super.onDisable();\n this.writeBaseline('worldUnit');\n }\n\n override reflow(): void {\n // GUI sliders (`sizePx`, `strokeWidthPx`) push their new values through\n // `reflow()`. Re-write the baseline first so the spec carries the new\n // target px, then let the base reflow re-apply the transform.\n if (this.isEnabled) this.writeBaseline('target');\n super.reflow();\n }\n\n /**\n * One-shot O(N) pass that rewrites every node's spec via\n * `renderer.updateShape`. Two flavours:\n *\n * - `'target'` — write the LOD-on baseline: `radius = sizePx / 2`,\n * `stroke.width = strokeWidthPx`. The per-frame `gfx.scale = 1 / cs`\n * then collapses the world-unit values back to pixel-constant.\n * - `'worldUnit'` — restore the LOD-off baseline: `radius = (data.size\n * ?? defaults.size) / 2`, `stroke.width = data.strokeWidth ??\n * defaults.strokeWidth`. Matches what `GraphLayer.nodeSpec` would\n * write for a fresh `addShape`.\n *\n * Expensive (each `updateShape` rebuilds the underlying Pixi geometry)\n * — only call on transitions (enable / disable / slider change), not\n * per frame.\n */\n private writeBaseline(mode: 'target' | 'worldUnit'): void {\n for (const { config, layer } of this.resolved) {\n const renderer = layer.getRenderer();\n if (!renderer) continue;\n this.writeLayerBaseline(layer, renderer, mode, config);\n }\n // The spec just changed across every node — connectors anchored to\n // these nodes still hold paths against the previous radii. Re-anchor\n // once *synchronously* (writeBaseline is a one-shot enable / disable /\n // reflow event, not a per-frame gesture, so the cost is amortised over\n // the user's interaction). `flushReanchor` also cancels any pending\n // debounced reanchor so we don't double-pay.\n this.flushReanchor();\n }\n\n private writeLayerBaseline(\n layer: GraphLayer,\n renderer: PrimitivesRenderer,\n mode: 'target' | 'worldUnit',\n config: NodeSizeLODConfig,\n ): void {\n const sizePxFallback = resolveNumberOrGetter(config.sizePx);\n const strokePxFallback = resolveNumberOrGetter(config.strokeWidthPx);\n\n for (const node of layer.store.nodes()) {\n // Read the *currently effective* NodeStyle — what the renderer would\n // hand the shape if we drew it now. That accounts for the layer\n // template, per-node overrides, and any active state overlays.\n const style = layer.resolveNodeStyle(node);\n const shape = style.shape;\n if (!shape) continue;\n\n // Natural size: longest AABB dimension of the resolved shape, via\n // the shape registry's `static boundsOf` hook. Works for every\n // registered kind (built-in + custom) — no closed switch here.\n const naturalAABB = renderer.boundsOfSpec(shape);\n if (!naturalAABB) continue;\n const naturalSize = Math.max(naturalAABB.width, naturalAABB.height);\n if (naturalSize <= 0) continue;\n\n // For 'target' mode: write the LOD-on baseline so the per-frame\n // `gfx.scale = 1 / cameraScale` collapses to pixel-constant.\n // For 'worldUnit' mode: restore the natural world-unit baseline that\n // came from the resolved style (matches what `GraphLayer.nodeSpec`\n // would write for a fresh `addShape`).\n const baselineSize = mode === 'target' ? (sizePxFallback ?? naturalSize) : naturalSize;\n const factor = baselineSize / naturalSize;\n\n // Geometry partial: uniform scale via the shape's `static scaleSpec`\n // hook. Shapes that don't implement scaleSpec (e.g. a custom shape\n // that hasn't opted into LOD) are skipped — the alternative would\n // be guessing which fields to multiply, which silently misbehaves.\n const geomPartial = renderer.scaleShapeSpec(shape, factor);\n if (!geomPartial) continue;\n\n const partial: Record<string, unknown> = { ...geomPartial };\n\n // Stroke channel — kind-agnostic, applies to every shape that uses\n // the standard `bg*` paint surface.\n const strokeColor = style.bgStrokeColor;\n const naturalStrokeWidth = style.bgStrokeWidth;\n if (strokeColor !== undefined && naturalStrokeWidth !== undefined && naturalStrokeWidth > 0) {\n const baseSw = mode === 'target' ? (strokePxFallback ?? naturalStrokeWidth) : naturalStrokeWidth;\n partial.stroke = {\n color: strokeColor,\n width: baseSw,\n ...(style.bgStrokeAlignment ? { alignment: style.bgStrokeAlignment } : {}),\n };\n }\n\n renderer.updateShape(node.id, partial);\n }\n }\n}\n","/**\n * `EdgeSizeLODBehaviour` — keep `GraphLayer` connector stroke widths at\n * a fixed screen-pixel width across camera zoom.\n *\n * Concrete subclass of `ElementSizeLODBehaviour`. Pair with\n * {@link NodeSizeLODBehaviour} when you also want pixel-constant nodes\n * (typical for map-overlay use cases — at city zoom a `strokeWidth: 0.6`\n * becomes a 150-px slab without this behaviour).\n *\n * Uses `PrimitivesRenderer.setConnectorStroke` (not `updateConnector`)\n * to patch the stroke spec and redraw on the cached path. Crucially,\n * this skips `recomputeConnectorPath`, which would iterate every shape\n * in the renderer to build an obstacle list — `O(edges × shapes)` per\n * reflow and lethal during continuous zoom. The path doesn't depend on\n * camera scale, so re-routing on a stroke-only change is wasted work.\n *\n * @example\n * ```ts\n * import { EdgeSizeLODBehaviour } from '@invana/graph';\n *\n * canvas.behaviours.register(\n * new EdgeSizeLODBehaviour({\n * id: 'edge-size-lod',\n * enabled: true,\n * layers: [{ layerId: 'graph', strokeWidthPx: 0.6 }],\n * }),\n * );\n * ```\n */\n\nimport {\n ElementSizeLODBehaviour,\n type CanvasContext,\n type ElementSizeLODBehaviourOptions,\n type NumberOrGetter,\n} from '@invana/canvas';\n\nimport type { GraphLayer } from '../layer/GraphLayer';\n\n/**\n * Default debounce when the caller doesn't override `settleMs`.\n * Edge stroke updates are the expensive path (one Pixi geometry rebuild\n * per connector), so we trade mid-gesture stroke drift for sustained\n * frame rate — apply only after the user stops zooming. 80ms is short\n * enough to feel \"instant on release\" without firing during a fling.\n */\nconst DEFAULT_EDGE_SETTLE_MS = 80;\n\n/** Per-`GraphLayer` config — one entry per layer this behaviour rescales. */\nexport interface EdgeSizeLODConfig {\n /** Required — the `GraphLayer` whose edges are rescaled. */\n layerId: string;\n /**\n * Target stroke width in screen px for edges that don't carry a\n * per-edge `data.strokeWidth` override. Falls back to the layer's\n * `edgeDefaults.strokeWidth`. Accepts a static number or a getter\n * (`() => settings.targetEdgePx`).\n */\n strokeWidthPx?: NumberOrGetter;\n}\n\nexport interface EdgeSizeLODBehaviourOptions extends ElementSizeLODBehaviourOptions {\n /** One config per `GraphLayer` to drive. */\n layers: EdgeSizeLODConfig[];\n}\n\ninterface ResolvedTarget {\n config: EdgeSizeLODConfig;\n layer: GraphLayer;\n}\n\nexport class EdgeSizeLODBehaviour extends ElementSizeLODBehaviour {\n private readonly configs: EdgeSizeLODConfig[];\n private resolved: ResolvedTarget[] = [];\n\n constructor(opts: EdgeSizeLODBehaviourOptions) {\n super({ settleMs: DEFAULT_EDGE_SETTLE_MS, ...opts });\n this.configs = opts.layers.slice();\n }\n\n protected override onResolveTargets(ctx: CanvasContext): void {\n for (const config of this.configs) {\n const layer = ctx.layers.get<GraphLayer>(config.layerId);\n if (!layer) {\n throw new Error(\n `EdgeSizeLODBehaviour \"${this.id}\": layer \"${config.layerId}\" not found in CanvasContext.`,\n );\n }\n this.resolved.push({ config, layer });\n }\n }\n\n protected override onReleaseTargets(): void {\n this.resolved = [];\n }\n\n /**\n * Per-zoom-frame apply: write the screen-px / world-px ratio to every\n * managed edge as a render-time stroke multiplier. The renderer's draw\n * pipeline reads `inst.strokeWidthScale` and multiplies it into the\n * spec's `stroke.width` at draw time, so state-config strokes (e.g.\n * `active: { strokeWidth: 1.5 }`) are interpreted in the same screen-px\n * unit the layer's \"live\" strokes are interpreted in — no LOD-loss\n * across a `GraphLayer.rerenderEdge` rebuild, and no inversion of the\n * caller's intent.\n *\n * The strokeWidthPx config field is unused under this model — every\n * spec width is treated as the target screen-px. Kept on the type for\n * back-compat; a future revision may remove it.\n */\n protected override apply(rawScale: number): void {\n const scale = Math.max(rawScale, 1e-6);\n const multiplier = 1 / scale;\n for (const { layer } of this.resolved) {\n const renderer = layer.getRenderer();\n if (!renderer) continue;\n for (const edge of layer.store.edges()) {\n renderer.scaleConnectorStroke(edge.id, multiplier);\n }\n }\n }\n}\n","/**\n * `ParallelEdgeBehaviour` — fans edges that share the same `(source, target)`\n * pair so they don't overlap. Cross-edge coordination that belongs above the\n * per-edge connector pipeline (anchor → router → pathStyle), since each\n * pipeline stage sees only one edge in isolation.\n *\n * Layer-scoped: constructed with a target `layerId` referencing a\n * {@link GraphLayer}. Watches the store for edge add/remove and node\n * position changes, groups edges by `groupBy(edge)` (default\n * `${source}::${target}`), and rewrites each group's `style.shape` so its\n * members fan out symmetrically. Two dimensions are written, depending on\n * which anchor each edge uses:\n *\n * 1. **`sourceAnchorOpts.offset` / `targetAnchorOpts.offset`** — for edges\n * using `'edge-port'` or `'silhouette-port'` anchors, the endpoints are\n * pushed along the host's face by `rank × spacing`. Combined with the\n * port anchor's `side: 'auto'` mode, this fans the endpoints across the\n * shape silhouette without the caller having to derive sides manually.\n * 2. **A single midpoint `waypoint`** — bows the path's middle by\n * `rank × spacing`. The bow axis is chosen per edge from its\n * `pathType`: axis-aligned routers (`manhattan` / `orth` / `rounded`)\n * get an axis-aligned offset along the non-dominant axis;\n * curve-through-control-point styles (`straight` / `smooth` / `bundle`)\n * get a perpendicular offset. Override via `basis`.\n *\n * Default `enabled: false` — register, then explicitly enable. Matches the\n * project rule that no behaviour auto-activates.\n *\n * `onDisable` does **not** undo prior patches — edges keep whatever waypoint\n * / anchor opts they had at the moment of disable. Re-enabling resumes\n * patching on the next store mutation. Callers that need a clean slate must\n * clear edge styles themselves.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new ParallelEdgeBehaviour({\n * id: 'parallel-edges',\n * layerId: 'graph',\n * enabled: true,\n * spacing: 12,\n * }),\n * );\n * ```\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type {\n EdgeAnchor,\n EdgePathType,\n EdgeShapeOptions,\n EdgeStyle,\n} from '../layer/types';\nimport type { GraphEdge, Vec2 } from '../store/types';\n\n/**\n * Axis along which a group of parallel edges spreads.\n *\n * - `'auto'` — derive from each edge's `pathType`. Axis-aligned routers\n * (`manhattan`, `orth`, `rounded`) use `'axis-aligned'`; all others use\n * `'perpendicular'`.\n * - `'perpendicular'` — offset along the unit vector perpendicular to\n * `target - source`. Suitable for curve-through-midpoint styles\n * (`straight`, `smooth`, `bundle`).\n * - `'axis-aligned'` — offset along the non-dominant axis between source and\n * target. Suitable for axis-aligned routers (`manhattan`, `orth`,\n * `rounded`) where the bow control point should sit on a horizontal or\n * vertical mid-corridor.\n */\nexport type ParallelEdgeBasis = 'auto' | 'perpendicular' | 'axis-aligned';\n\n/** A bucket of edges that share endpoints and should be fanned together. */\nexport interface ParallelEdgeGroup {\n /** Source node id shared by every edge in this group. */\n readonly sourceId: string;\n /** Target node id shared by every edge in this group. */\n readonly targetId: string;\n /** Geometric centre of the source node (renderer ref or store position). */\n readonly sourceCenter: Vec2;\n /** Geometric centre of the target node. */\n readonly targetCenter: Vec2;\n /**\n * Edges in this group, in store iteration order. Distribution policies\n * decide which edge gets which rank — the default centres the group so\n * `edges[i]` receives rank `k = i - (N-1)/2`.\n */\n readonly edges: ReadonlyArray<GraphEdge>;\n}\n\n/** Patch a distribution policy emits for one edge in the group. */\nexport interface ParallelEdgePatch {\n /** Edge id this patch applies to. */\n readonly edgeId: string;\n /** New `sourceAnchorOpts`. Merged onto the edge's existing shape. */\n readonly sourceAnchorOpts?: Readonly<Record<string, unknown>>;\n /** New `targetAnchorOpts`. */\n readonly targetAnchorOpts?: Readonly<Record<string, unknown>>;\n /** New `waypoints`. Pass an empty array to clear. */\n readonly waypoints?: ReadonlyArray<{ readonly x: number; readonly y: number }>;\n}\n\n/** Settings the behaviour passes through to a distribution policy. */\nexport interface ParallelEdgeDistributeContext {\n readonly spacing: number;\n readonly basis: ParallelEdgeBasis;\n readonly anchorOffset: boolean;\n}\n\n/**\n * Pluggable distribution policy. Receives a group of co-located edges plus\n * the behaviour's settings and returns one patch per edge it wants to update.\n *\n * The default policy {@link centeredRanksPolicy} fans edges symmetrically\n * around rank zero — pass a custom function to implement one-sided fanout,\n * data-driven offsets, weighted spacing, etc.\n */\nexport type ParallelEdgeDistribute = (\n group: ParallelEdgeGroup,\n ctx: ParallelEdgeDistributeContext,\n) => ReadonlyArray<ParallelEdgePatch>;\n\n/** Constructor options for {@link ParallelEdgeBehaviour}. */\nexport interface ParallelEdgeBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour drives. */\n layerId: string;\n\n /** Spacing between adjacent ranks in world units. Default `12`. */\n spacing?: number;\n\n /**\n * Basis the default distribution policy uses to translate a rank into a\n * waypoint / anchor-offset direction. Default `'auto'`.\n */\n basis?: ParallelEdgeBasis;\n\n /**\n * When `true` and an edge uses a port anchor (`'edge-port'` or\n * `'silhouette-port'`), the default policy writes\n * `sourceAnchorOpts: { side: 'auto', offset }` and the matching target\n * opts so endpoints fan along the host face. When `false`, the policy\n * only writes waypoints. Default `true`.\n */\n anchorOffset?: boolean;\n\n /**\n * Group key for an edge. Edges that produce the same key are bundled and\n * distributed together. Return `null` to exclude an edge. Default groups\n * by directed pair `${source}::${target}`.\n */\n groupBy?: (edge: GraphEdge) => string | null;\n\n /**\n * Distribution policy. Default {@link centeredRanksPolicy}.\n */\n distribute?: ParallelEdgeDistribute;\n}\n\ninterface ResolvedOptions {\n spacing: number;\n basis: ParallelEdgeBasis;\n anchorOffset: boolean;\n groupBy: (edge: GraphEdge) => string | null;\n distribute: ParallelEdgeDistribute;\n}\n\nconst defaultGroupBy = (edge: GraphEdge): string => `${edge.source}::${edge.target}`;\n\nfunction resolveOptions(\n prev: ResolvedOptions | null,\n patch: Partial<ParallelEdgeBehaviourOptions>,\n): ResolvedOptions {\n const base: ResolvedOptions = prev ?? {\n spacing: 12,\n basis: 'auto',\n anchorOffset: true,\n groupBy: defaultGroupBy,\n distribute: centeredRanksPolicy,\n };\n return {\n spacing: patch.spacing ?? base.spacing,\n basis: patch.basis ?? base.basis,\n anchorOffset: patch.anchorOffset ?? base.anchorOffset,\n groupBy: patch.groupBy ?? base.groupBy,\n distribute: patch.distribute ?? base.distribute,\n };\n}\n\nconst PORT_ANCHORS: ReadonlySet<EdgeAnchor> = new Set([\n 'edge-port',\n 'silhouette-port',\n] as readonly EdgeAnchor[]);\n\nconst AXIS_ALIGNED_PATH_TYPES: ReadonlySet<EdgePathType> = new Set<EdgePathType>([\n 'manhattan',\n 'orth',\n 'rounded',\n]);\n\n/**\n * Default distribution policy — centres `N` ranks around zero, then for each\n * edge writes one midpoint waypoint plus (optionally) port-anchor offsets.\n *\n * Exported so callers can compose it (e.g. wrap with a filter) or call\n * directly when implementing a custom variant that wants to reuse the\n * default geometry for some edges.\n */\nexport const centeredRanksPolicy: ParallelEdgeDistribute = (group, ctx) => {\n const { sourceCenter: src, targetCenter: tgt, edges } = group;\n const dx = tgt.x - src.x;\n const dy = tgt.y - src.y;\n const len = Math.hypot(dx, dy) || 1;\n const horizontal = Math.abs(dx) >= Math.abs(dy);\n // Perpendicular unit vector: rotate (dx, dy) by 90°.\n const nx = -dy / len;\n const ny = dx / len;\n const mx = (src.x + tgt.x) / 2;\n const my = (src.y + tgt.y) / 2;\n const half = (edges.length - 1) / 2;\n\n const patches: ParallelEdgePatch[] = [];\n for (let i = 0; i < edges.length; i++) {\n const edge = edges[i]!;\n const k = i - half;\n const off = k * ctx.spacing;\n\n const shape = (edge.style as EdgeStyle | undefined)?.shape;\n const pathType = shape?.pathType;\n const effectiveBasis =\n ctx.basis === 'auto'\n ? (pathType !== undefined && AXIS_ALIGNED_PATH_TYPES.has(pathType)\n ? 'axis-aligned'\n : 'perpendicular')\n : ctx.basis;\n\n // For axis-aligned routers (manhattan / orth / rounded), each edge needs\n // its OWN mid-corridor — if every waypoint shared the same dominant-axis\n // coordinate, all of their mid-segments would collapse onto a single\n // line. So when the chord is horizontal-dominant, each edge gets a\n // different `x` (its vertical run is at a unique column); when the\n // chord is vertical-dominant, each gets a different `y` (its horizontal\n // run is at a unique row).\n const waypoint =\n effectiveBasis === 'axis-aligned'\n ? horizontal\n ? { x: mx + off, y: my }\n : { x: mx, y: my + off }\n : { x: mx + nx * off, y: my + ny * off };\n\n const patch: ParallelEdgePatch = {\n edgeId: edge.id,\n waypoints: [waypoint],\n };\n\n if (ctx.anchorOffset) {\n const sourceAnchor = shape?.sourceAnchor;\n const targetAnchor = shape?.targetAnchor;\n if (sourceAnchor !== undefined && PORT_ANCHORS.has(sourceAnchor)) {\n (patch as { sourceAnchorOpts: Record<string, unknown> }).sourceAnchorOpts = {\n side: 'auto',\n offset: off,\n };\n }\n if (targetAnchor !== undefined && PORT_ANCHORS.has(targetAnchor)) {\n (patch as { targetAnchorOpts: Record<string, unknown> }).targetAnchorOpts = {\n side: 'auto',\n offset: off,\n };\n }\n }\n\n patches.push(patch);\n }\n return patches;\n};\n\nexport class ParallelEdgeBehaviour extends Behaviour {\n /** Bound target layer — resolved in `onRegister`. */\n private layer: GraphLayer | null = null;\n\n private opts: ResolvedOptions;\n\n /** Subscription disposers, called in `onDestroy`. */\n private subs: Array<() => void> = [];\n\n /** Re-entrancy guard: `true` while writing patches to the store. */\n private patching = false;\n\n constructor(opts: ParallelEdgeBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? [] });\n this.opts = resolveOptions(null, opts);\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `ParallelEdgeBehaviour \"${this.id}\": layer \"${this.layerId}\" not found. ` +\n `Add the GraphLayer before registering this behaviour.`,\n );\n }\n this.layer = layer;\n\n // Subscribe to events that can change group composition or endpoint\n // positions. We deliberately skip `'edge:update'` and `'flush'` — the\n // behaviour writes `edge:update`s of its own, and listening to either\n // would loop.\n const onChange = (): void => {\n if (!this.isEnabled) return;\n this.recompute();\n };\n this.subs.push(\n layer.store.events.on('edge:add', onChange),\n layer.store.events.on('edge:remove', onChange),\n layer.store.events.on('node:update', onChange),\n layer.store.events.on('node:remove', onChange),\n );\n }\n\n protected override onDestroy(): void {\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.layer = null;\n }\n\n protected override onEnable(): void {\n // Apply a pass immediately so the first frame already shows distributed\n // edges (the events that would otherwise drive `recompute` may have\n // fired before the behaviour was enabled).\n this.recompute();\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /** Read-only snapshot of resolved options. */\n get options(): Readonly<ResolvedOptions> {\n return this.opts;\n }\n\n /** Runtime option update. Re-runs the distribution immediately if enabled. */\n setOptions(patch: Partial<ParallelEdgeBehaviourOptions>): void {\n this.opts = resolveOptions(this.opts, patch);\n if (this.isEnabled) this.recompute();\n }\n\n /**\n * Force a recompute pass. Useful after bulk mutations performed inside a\n * `store.batch()` that callers want to flush through the behaviour\n * immediately.\n */\n recompute(): void {\n const layer = this.layer;\n if (!layer || this.patching) return;\n const store = layer.store;\n const renderer = layer.getRenderer();\n\n // Bucket edges by group key. A single pass over `store.edges()` — no\n // adjacency index needed because we visit every edge once and group by\n // a derived string key.\n const groups = new Map<string, GraphEdge[]>();\n for (const edge of store.edges()) {\n const key = this.opts.groupBy(edge);\n if (key === null) continue;\n let bucket = groups.get(key);\n if (bucket === undefined) {\n bucket = [];\n groups.set(key, bucket);\n }\n bucket.push(edge);\n }\n\n this.patching = true;\n try {\n for (const edges of groups.values()) {\n if (edges.length < 2) continue;\n const first = edges[0]!;\n const sourceCenter = resolveCenter(layer, renderer, first.source);\n const targetCenter = resolveCenter(layer, renderer, first.target);\n if (!sourceCenter || !targetCenter) continue;\n\n const patches = this.opts.distribute(\n {\n sourceId: first.source,\n targetId: first.target,\n sourceCenter,\n targetCenter,\n edges,\n },\n {\n spacing: this.opts.spacing,\n basis: this.opts.basis,\n anchorOffset: this.opts.anchorOffset,\n },\n );\n\n for (const patch of patches) {\n applyPatch(store, patch);\n }\n }\n } finally {\n this.patching = false;\n }\n }\n}\n\n/**\n * Prefer the renderer's geometric centre (which already accounts for\n * shapes whose local origin is top-left, e.g. `rect`); fall back to the\n * store's raw position before the renderer has mounted.\n */\nfunction resolveCenter(\n layer: GraphLayer,\n renderer: ReturnType<GraphLayer['getRenderer']>,\n nodeId: string,\n): Vec2 | null {\n const c = renderer?.getShapeCenter(nodeId);\n if (c) return { x: c.x, y: c.y };\n return layer.store.getPosition(nodeId) ?? null;\n}\n\n/**\n * Merge a patch into an edge's existing `style.shape` and write it back\n * via `updateEdge`. `updateEdge` replaces `style` wholesale, so we spread\n * the full prior style + shape before overlaying.\n */\nfunction applyPatch(\n store: GraphLayer['store'],\n patch: ParallelEdgePatch,\n): void {\n const edge = store.getEdge(patch.edgeId);\n if (!edge) return;\n const priorStyle = (edge.style as EdgeStyle | undefined) ?? {};\n const priorShape = priorStyle.shape ?? {};\n const nextShape: EdgeShapeOptions = { ...priorShape };\n if (patch.waypoints !== undefined) {\n (nextShape as { waypoints: ParallelEdgePatch['waypoints'] }).waypoints =\n patch.waypoints;\n }\n if (patch.sourceAnchorOpts !== undefined) {\n (nextShape as { sourceAnchorOpts: Record<string, unknown> }).sourceAnchorOpts =\n patch.sourceAnchorOpts;\n }\n if (patch.targetAnchorOpts !== undefined) {\n (nextShape as { targetAnchorOpts: Record<string, unknown> }).targetAnchorOpts =\n patch.targetAnchorOpts;\n }\n store.updateEdge(patch.edgeId, {\n style: { ...priorStyle, shape: nextShape },\n });\n}\n","/**\n * `DegreeSizeBehaviour` — sizes nodes by their connection count.\n *\n * For each node, counts incident edges in the configured `direction`\n * (`'in'` / `'out'` / `'both'`), normalizes against the max observed degree,\n * and writes a `style.size` value scaled between `minSize` and `maxSize`.\n *\n * Because `style.size` flows through `GraphLayer.resolveNodeStyle` (which\n * rewrites the node's `shape` geometry before any consumer reads it), the\n * sizes are picked up uniformly by:\n * - the renderer (visual radius / width grows),\n * - `boundsOfNode` (ELK and other layouts that query bounds),\n * - D3ForceLayout's collide.radius callback (reads `style.shape.radius`\n * off the resolved style).\n *\n * The behaviour does NOT auto-rerun any layout — write sizes first, then\n * call `layout.apply(graph)` yourself. This matches the rest of the\n * behaviour catalogue: no behaviour runs layouts implicitly.\n *\n * Lifecycle:\n * - `onEnable()` — snapshot prior per-node `style.size`, compute,\n * apply.\n * - on store changes — recompute and reapply (microtask-debounced).\n * - `onDisable()` — restore the snapshotted prior `style.size`\n * values, clear snapshot.\n *\n * Defaults are `direction: 'both'`, `minSize: 8`, `maxSize: 32`,\n * `scale: 'sqrt'` — the sqrt curve dampens the long-tail effect typical of\n * real graphs (a few super-hubs would otherwise blow past the slider) while\n * still giving visually distinct sizing.\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new DegreeSizeBehaviour({\n * id: 'degree-size',\n * layerId: 'graph',\n * enabled: true,\n * direction: 'both',\n * minSize: 6,\n * maxSize: 40,\n * scale: 'sqrt',\n * }),\n * );\n * // ...after registering, run the layout:\n * void layout.apply(graph);\n * ```\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type { NodeStyle } from '../layer/types';\nimport type { EdgeDirection } from '../store/types';\n\n/** Scaling curve used to map raw degree → output size. */\nexport type DegreeSizeScale = 'linear' | 'sqrt' | 'log';\n\n/** Constructor options for `DegreeSizeBehaviour`. */\nexport interface DegreeSizeBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour drives. */\n layerId: string;\n\n /**\n * Edges to count when computing each node's degree.\n *\n * - `'in'` — only edges where the node is the target.\n * - `'out'` — only edges where the node is the source.\n * - `'both'` — sum of in + out. Default.\n */\n direction?: EdgeDirection;\n\n /** Output `style.size` for a node with degree === 0. Default `8`. */\n minSize?: number;\n\n /**\n * Output `style.size` for the node with the maximum observed degree.\n * Default `32`. Anything smaller than `minSize` is allowed but pointless.\n */\n maxSize?: number;\n\n /**\n * Curve mapping normalized degree (0..1) to a size between `minSize` and\n * `maxSize`. Default `'sqrt'`.\n *\n * - `'linear'` — size = min + (max - min) * (degree / maxDegree)\n * - `'sqrt'` — size = min + (max - min) * sqrt(degree / maxDegree)\n * dampens the long tail typical of real graphs\n * - `'log'` — size = min + (max - min) * log1p(degree) / log1p(maxDegree)\n * aggressive dampening; better for power-law graphs\n */\n scale?: DegreeSizeScale;\n\n /**\n * Optional override. When provided, supersedes `minSize` / `maxSize` /\n * `scale` and is called per-node with that node's degree plus the max\n * degree across the layer. Returns the literal `style.size` to write.\n */\n sizeFn?: (degree: number, maxDegree: number) => number;\n}\n\ninterface ResolvedOptions {\n direction: EdgeDirection;\n minSize: number;\n maxSize: number;\n scale: DegreeSizeScale;\n sizeFn: ((degree: number, maxDegree: number) => number) | undefined;\n}\n\nfunction resolveOptions(\n prev: ResolvedOptions | null,\n patch: Partial<DegreeSizeBehaviourOptions>,\n): ResolvedOptions {\n const base: ResolvedOptions = prev ?? {\n direction: 'both',\n minSize: 8,\n maxSize: 32,\n scale: 'sqrt',\n sizeFn: undefined,\n };\n return {\n direction: patch.direction ?? base.direction,\n minSize: patch.minSize ?? base.minSize,\n maxSize: patch.maxSize ?? base.maxSize,\n scale: patch.scale ?? base.scale,\n sizeFn: 'sizeFn' in patch ? patch.sizeFn : base.sizeFn,\n };\n}\n\n/**\n * Map a node's degree to a size value per the resolved options.\n * Pulled out as a free function so unit-style reasoning is easier and the\n * call site stays branch-light.\n */\nfunction mapDegreeToSize(degree: number, maxDegree: number, opts: ResolvedOptions): number {\n if (opts.sizeFn) return opts.sizeFn(degree, maxDegree);\n if (maxDegree <= 0) return opts.minSize;\n const t = degree / maxDegree;\n let eased: number;\n switch (opts.scale) {\n case 'linear':\n eased = t;\n break;\n case 'log':\n eased = Math.log1p(degree) / Math.log1p(maxDegree);\n break;\n case 'sqrt':\n default:\n eased = Math.sqrt(t);\n break;\n }\n return opts.minSize + (opts.maxSize - opts.minSize) * eased;\n}\n\nexport class DegreeSizeBehaviour extends Behaviour {\n /** Bound target layer — resolved in `onRegister`. */\n private layer: GraphLayer | null = null;\n\n private opts: ResolvedOptions;\n\n /** Subscription disposers, called in `onDestroy`. */\n private readonly subs: Array<() => void> = [];\n\n /**\n * Snapshot of each touched node's prior `style.size`, captured on the\n * first write to that node. `undefined` means the node had no `size`\n * field before — restore by writing `undefined`. Cleared on `disable` /\n * `destroy`.\n */\n private readonly prior = new Map<string, number | undefined>();\n\n /** Microtask debounce flag — coalesces bursts of store events. */\n private recomputeScheduled = false;\n\n /** Re-entrancy guard — set while writing patches so our own emits no-op. */\n private patching = false;\n\n constructor(opts: DegreeSizeBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? [] });\n this.opts = resolveOptions(null, opts);\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `DegreeSizeBehaviour \"${this.id}\": layer \"${this.layerId}\" not found. ` +\n `Add the GraphLayer before registering this behaviour.`,\n );\n }\n this.layer = layer;\n\n // Recompute whenever the topology changes. We deliberately skip\n // `'node:update'` to avoid feedback loops — our own `updateNode` writes\n // would re-trigger us. `flush` covers bulk insertions; the granular\n // events cover live mutations after the initial setData.\n const schedule = (): void => this.scheduleRecompute();\n this.subs.push(\n layer.store.events.on('node:add', schedule),\n layer.store.events.on('node:remove', schedule),\n layer.store.events.on('edge:add', schedule),\n layer.store.events.on('edge:remove', schedule),\n layer.store.events.on('flush', schedule),\n );\n }\n\n protected override onEnable(): void {\n // Apply immediately so the first frame already reflects degree sizing.\n this.applyAll();\n }\n\n protected override onDisable(): void {\n this.revertAll();\n }\n\n protected override onDestroy(): void {\n // If destroyed while enabled, restore prior sizes before tearing down so\n // we don't leave the layer in a half-modified state.\n if (this.prior.size > 0) this.revertAll();\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.layer = null;\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /** Read-only snapshot of resolved options. */\n get options(): Readonly<ResolvedOptions> {\n return this.opts;\n }\n\n /**\n * Runtime option update. Re-runs `applyAll()` immediately if enabled so\n * GUI slider changes are visible without an extra call.\n */\n setOptions(patch: Partial<DegreeSizeBehaviourOptions>): void {\n this.opts = resolveOptions(this.opts, patch);\n if (this.isEnabled) this.applyAll();\n }\n\n /**\n * Force a recompute + write pass. Useful after a bulk `store.batch()`\n * the caller wants reflected immediately (the microtask-debounced\n * subscription would otherwise fire on the next tick).\n */\n recompute(): void {\n if (this.isEnabled) this.applyAll();\n }\n\n // ─── Internals ──────────────────────────────────────────────────────────\n\n private scheduleRecompute(): void {\n if (!this.isEnabled || this.patching || this.recomputeScheduled) return;\n this.recomputeScheduled = true;\n queueMicrotask(() => {\n this.recomputeScheduled = false;\n if (!this.isEnabled) return;\n this.applyAll();\n });\n }\n\n /**\n * Compute degree for every node, map to size, and write back via\n * `store.updateNode` (merged with the prior `style` per the\n * `updateNode replaces style wholesale` contract).\n *\n * Nodes touched here have their original `style.size` captured into\n * `this.prior` on first write so `revertAll()` can restore them.\n */\n private applyAll(): void {\n const layer = this.layer;\n if (!layer) return;\n const store = layer.store;\n const { direction } = this.opts;\n\n // First pass — collect (id, degree) and find maxDegree. Single iteration\n // over store.nodes(); inDegree/outDegree are O(1) lookups on the\n // adjacency index.\n const degrees: Array<{ id: string; degree: number; style: NodeStyle | undefined }> = [];\n let maxDegree = 0;\n for (const node of store.nodes()) {\n const degree =\n direction === 'in'\n ? store.inDegree(node.id)\n : direction === 'out'\n ? store.outDegree(node.id)\n : store.inDegree(node.id) + store.outDegree(node.id);\n if (degree > maxDegree) maxDegree = degree;\n degrees.push({\n id: node.id,\n degree,\n style: node.style as NodeStyle | undefined,\n });\n }\n\n // Second pass — compute size and write. The re-entrancy guard prevents\n // our own `'node:update'` flushes from re-triggering `scheduleRecompute`\n // mid-batch (we don't listen to `'node:update'` anyway, but `'flush'`\n // does fire after a batched write).\n this.patching = true;\n try {\n for (const { id, degree, style } of degrees) {\n const size = mapDegreeToSize(degree, maxDegree, this.opts);\n if (!this.prior.has(id)) {\n this.prior.set(id, style?.size);\n }\n const prevStyle: NodeStyle = (style ?? {}) as NodeStyle;\n store.updateNode(id, {\n style: { ...prevStyle, size },\n });\n }\n } finally {\n this.patching = false;\n }\n }\n\n /** Restore each touched node's prior `style.size` and clear the snapshot. */\n private revertAll(): void {\n const layer = this.layer;\n if (!layer || this.prior.size === 0) {\n this.prior.clear();\n return;\n }\n const store = layer.store;\n this.patching = true;\n try {\n for (const [id, prevSize] of this.prior) {\n const node = store.getNode(id);\n if (!node) continue;\n const prevStyle: NodeStyle = (node.style ?? {}) as NodeStyle;\n // Build a fresh style object that omits `size` when prevSize was\n // undefined; otherwise restore the prior numeric value.\n const { size: _drop, ...rest } = prevStyle as NodeStyle & { size?: number };\n const restored: NodeStyle =\n prevSize === undefined ? (rest as NodeStyle) : ({ ...rest, size: prevSize } as NodeStyle);\n store.updateNode(id, { style: restored });\n }\n } finally {\n this.patching = false;\n }\n this.prior.clear();\n }\n}\n","/**\n * `ResponsiveThemeBehaviour` — keeps a `GraphLayer`'s theme-dependent styling in\n * sync with the host's colour scheme.\n *\n * It owns the *entire* theme-driven look of graph content via three `light` /\n * `dark` variant pairs:\n * - `node` — applied to every node through `setNodeDefaults` (shallow-merge into\n * the shared template, re-rendering every node).\n * - `edge` — applied to every edge through `setEdgeDefaults`.\n * - `group` — applied *only* to group nodes (those carrying `style.group`),\n * layered on top of `node`. Since the engine has no group template /\n * `setGroupDefaults`, group variants are written per-group-node via\n * `store.updateNode` and re-applied as groups are added.\n *\n * Background theming is deliberately *not* this behaviour's job — that stays with\n * `BackgroundLayer` (`{ light, dark }` colour props) / `ThemedBackgroundLayer`.\n *\n * Why a behaviour and not React state: the declarative `<GraphLayer>` wrapper\n * applies its `node`/`edge` style props only at mount, so React-state colour\n * changes wouldn't reach existing — or freshly-drawn — items. Patching the layer\n * template imperatively does, and new nodes inherit the patched template.\n *\n * `mode`:\n * - `'auto'` (default) — follows the host's `prefers-color-scheme`, flipping\n * live when the OS appearance changes.\n * - `'light'` / `'dark'` — pin a variant explicitly.\n *\n * Lifecycle:\n * - `onEnable()` — arm the media query (when `auto`) and apply the resolved\n * variant immediately.\n * - `onDisable()` — detach the media query. The layer keeps the last applied\n * defaults (no revert — there is no \"un-themed\" baseline to\n * restore to).\n *\n * @example\n * ```ts\n * canvas.behaviours.register(\n * new ResponsiveThemeBehaviour({\n * id: 'theme',\n * layerId: 'graph',\n * enabled: true,\n * node: {\n * light: { bgStrokeColor: 0xffffff },\n * dark: { bgStrokeColor: 0x0f172a },\n * },\n * edge: {\n * light: { strokeColor: 0xcbd5e1 },\n * dark: { strokeColor: 0x475569 },\n * },\n * group: {\n * light: { bgFill: 0xeef2ff, bgStrokeColor: 0x6b7fff },\n * dark: { bgFill: 0x1e293b, bgStrokeColor: 0x475569 },\n * },\n * }),\n * );\n * ```\n *\n * @remarks\n * The `group` pass tracks `node:add` / `flush`, so groups present at `setData`\n * and groups added afterwards are themed. A node that *becomes* a group later via\n * `node:update` is not re-themed (we don't watch `node:update`, to avoid a write\n * loop with our own `updateNode` calls).\n */\n\nimport { Behaviour, type BehaviourOptions, type CanvasContext } from '@invana/canvas';\n\nimport { GraphLayer } from '../layer/GraphLayer';\nimport type { EdgeStyle, NodeStyle } from '../layer/types';\n\n/** The concrete variant currently being applied after mode resolution. */\nexport type ThemeKind = 'light' | 'dark';\n\n/** Mode selector. `'auto'` follows `prefers-color-scheme`; the rest pin. */\nexport type ThemeMode = 'auto' | 'light' | 'dark';\n\n/** A light / dark pair of style patches; each side is optional. */\nexport interface ThemeVariants<S> {\n /** Patch applied when the resolved kind is `'light'`. */\n light?: Partial<S>;\n /** Patch applied when the resolved kind is `'dark'`. */\n dark?: Partial<S>;\n}\n\n/** Constructor options for `ResponsiveThemeBehaviour`. */\nexport interface ResponsiveThemeBehaviourOptions extends BehaviourOptions {\n /** Required — the `GraphLayer` id this behaviour themes. */\n layerId: string;\n\n /**\n * How light vs dark is decided. `'auto'` (default) follows the host's\n * `prefers-color-scheme`; `'light'` / `'dark'` pin a variant.\n */\n mode?: ThemeMode;\n\n /**\n * Node style applied per resolved kind via `setNodeDefaults` (shallow-merge\n * into the layer's node template). Omit a side to leave it unthemed.\n */\n node?: ThemeVariants<NodeStyle>;\n\n /**\n * Edge style applied per resolved kind via `setEdgeDefaults` (shallow-merge\n * into the layer's edge template). Omit a side to leave it unthemed.\n */\n edge?: ThemeVariants<EdgeStyle>;\n\n /**\n * Style applied to group nodes only (those with `style.group`), layered on top\n * of `node`. Full `NodeStyle` per resolved kind. Because the engine has no\n * group template, this is written per-group-node via `store.updateNode` and\n * re-applied as groups are added. Omit a side to leave it unthemed.\n */\n group?: ThemeVariants<NodeStyle>;\n}\n\nexport class ResponsiveThemeBehaviour extends Behaviour {\n /** Bound target layer — resolved in `onRegister`. */\n private layer: GraphLayer | null = null;\n\n private mode: ThemeMode;\n private node?: ThemeVariants<NodeStyle>;\n private edge?: ThemeVariants<EdgeStyle>;\n private group?: ThemeVariants<NodeStyle>;\n\n private mediaQuery: MediaQueryList | null = null;\n private mediaListener: (() => void) | null = null;\n\n /** Store-event disposers for the group re-theme subscription. */\n private readonly subs: Array<() => void> = [];\n\n /** Microtask debounce flag — coalesces bursts of `node:add` / `flush`. */\n private groupApplyScheduled = false;\n\n /** Re-entrancy guard — set while our own `updateNode` writes are in flight. */\n private patching = false;\n\n constructor(opts: ResponsiveThemeBehaviourOptions) {\n super({ ...opts, shortcuts: opts.shortcuts ?? [] });\n this.mode = opts.mode ?? 'auto';\n this.node = opts.node;\n this.edge = opts.edge;\n this.group = opts.group;\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n protected override onRegister(ctx: CanvasContext): void {\n const layer = ctx.layers.get<GraphLayer>(this.layerId!);\n if (!layer) {\n throw new Error(\n `ResponsiveThemeBehaviour \"${this.id}\": layer \"${this.layerId}\" not found. ` +\n `Add the GraphLayer before registering this behaviour.`,\n );\n }\n this.layer = layer;\n\n // Group variants are written per-group-node (no group template exists), so\n // re-apply when groups appear. `node:add` covers live inserts; `flush`\n // covers bulk `setData`. We skip `node:update` to avoid feedback from our\n // own `updateNode` writes (cf. DegreeSizeBehaviour).\n if (this.group) {\n const schedule = (): void => this.scheduleGroupApply();\n this.subs.push(\n layer.store.events.on('node:add', schedule),\n layer.store.events.on('flush', schedule),\n );\n }\n }\n\n protected override onEnable(): void {\n this.wireMediaQuery();\n this.applyTheme();\n }\n\n protected override onDisable(): void {\n this.detachMediaQuery();\n }\n\n protected override onDestroy(): void {\n this.detachMediaQuery();\n for (const off of this.subs) off();\n this.subs.length = 0;\n this.layer = null;\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /** Current mode setting. */\n getMode(): ThemeMode {\n return this.mode;\n }\n\n /** Concrete kind currently resolved from the mode. */\n getResolvedKind(): ThemeKind {\n return resolveKind(this.mode);\n }\n\n /**\n * Switch mode. `'auto'` re-arms the system listener; `'light'` / `'dark'`\n * detach it and pin. Re-applies immediately when enabled.\n */\n setMode(mode: ThemeMode): void {\n if (mode === this.mode) return;\n this.mode = mode;\n if (!this.isEnabled) return;\n this.wireMediaQuery();\n this.applyTheme();\n }\n\n /**\n * Replace the light/dark style variants. Re-applies immediately when enabled\n * so live tweaking (e.g. from a GUI) is visible without an extra call.\n */\n setVariants(variants: {\n node?: ThemeVariants<NodeStyle>;\n edge?: ThemeVariants<EdgeStyle>;\n group?: ThemeVariants<NodeStyle>;\n }): void {\n if ('node' in variants) this.node = variants.node;\n if ('edge' in variants) this.edge = variants.edge;\n if ('group' in variants) this.group = variants.group;\n if (this.isEnabled) this.applyTheme();\n }\n\n // ─── Internals ──────────────────────────────────────────────────────────\n\n /** Resolve the active kind and push its variants onto the layer. */\n private applyTheme(): void {\n const layer = this.layer;\n if (!layer) return;\n const kind = resolveKind(this.mode);\n const nodePatch = this.node?.[kind];\n if (nodePatch) layer.setNodeDefaults(nodePatch);\n const edgePatch = this.edge?.[kind];\n if (edgePatch) layer.setEdgeDefaults(edgePatch);\n const groupPatch = this.group?.[kind];\n if (groupPatch) this.applyGroupTheme(groupPatch);\n }\n\n /**\n * Write the group variant onto every group node, layered over its current\n * style. There is no group template, so this targets instances directly; the\n * per-instance style wins over the node template, giving groups\n * `node[kind]` (base) + `group[kind]` (override).\n */\n private applyGroupTheme(patch: Partial<NodeStyle>): void {\n const layer = this.layer;\n if (!layer) return;\n const store = layer.store;\n this.patching = true;\n try {\n for (const node of store.nodes()) {\n if (!layer.isGroupNode(node)) continue;\n const prevStyle = (node.style ?? {}) as NodeStyle;\n store.updateNode(node.id, { style: { ...prevStyle, ...patch } });\n }\n } finally {\n this.patching = false;\n }\n }\n\n /**\n * Microtask-debounced re-apply of the group pass when new group nodes appear.\n * Node/edge variants need no rescheduling — they live on the template, so new\n * nodes inherit them automatically.\n */\n private scheduleGroupApply(): void {\n if (!this.isEnabled || this.patching || this.groupApplyScheduled) return;\n this.groupApplyScheduled = true;\n queueMicrotask(() => {\n this.groupApplyScheduled = false;\n if (!this.isEnabled) return;\n const groupPatch = this.group?.[resolveKind(this.mode)];\n if (groupPatch) this.applyGroupTheme(groupPatch);\n });\n }\n\n /**\n * Arm the `prefers-color-scheme` listener when in `'auto'` mode; detach it\n * otherwise. A system flip re-applies the resolved variant.\n */\n private wireMediaQuery(): void {\n if (this.mode !== 'auto') {\n this.detachMediaQuery();\n return;\n }\n if (this.mediaQuery) return;\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;\n\n this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n this.mediaListener = () => {\n if (this.mode !== 'auto' || !this.isEnabled) return;\n this.applyTheme();\n };\n this.mediaQuery.addEventListener('change', this.mediaListener);\n }\n\n private detachMediaQuery(): void {\n if (this.mediaQuery && this.mediaListener) {\n this.mediaQuery.removeEventListener('change', this.mediaListener);\n }\n this.mediaQuery = null;\n this.mediaListener = null;\n }\n}\n\n/** SSR-safe kind resolver. `'auto'` reads the media query; defaults to light. */\nfunction resolveKind(mode: ThemeMode): ThemeKind {\n if (mode === 'light' || mode === 'dark') return mode;\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return 'light';\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n}\n"]}