@x12i/diagrams 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -14
- package/dist/chunk-3DJFQRU3.js +2708 -0
- package/dist/chunk-3DJFQRU3.js.map +1 -0
- package/dist/index.d.ts +67 -54
- package/dist/index.js +204 -45
- package/dist/index.js.map +1 -1
- package/dist/messages-ZCyCfyO0.d.ts +857 -0
- package/dist/react.d.ts +348 -0
- package/dist/react.js +2525 -0
- package/dist/react.js.map +1 -0
- package/dist/styles.css +1389 -0
- package/package.json +51 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts","../src/ids.ts","../src/graph.ts","../src/connection.ts","../src/validate.ts","../src/geometry.ts","../src/mutations.ts","../src/layout.ts","../src/history.ts","../src/outline.ts","../src/outline-tree.ts","../src/svg.ts","../src/io.ts","../src/messages.ts"],"sourcesContent":["/**\r\n * The kit's own diagram document (spec section 10). It is versioned JSON, so\r\n * the node canvas engine can change without breaking saved diagrams.\r\n *\r\n * Coordinates: `position` is the top-left corner of the node. For a child of a\r\n * group or subflow (`parentId` set) it is relative to the parent's top-left\r\n * corner, the same convention React Flow uses. Everything here is plain data:\r\n * no React, no DOM.\r\n */\r\n\r\nexport const DIAGRAM_VERSION = 1;\r\n\r\n/** The node library. Every node reads kit tokens. */\r\nexport type NodeKind =\r\n | \"start\"\r\n | \"end\"\r\n | \"task\"\r\n | \"decision\"\r\n | \"group\"\r\n | \"note\"\r\n | \"image\"\r\n | \"entity\"\r\n | \"code\"\r\n | \"chart\"\r\n | \"agent\"\r\n | \"subflow\";\r\n\r\n/** Status colors match the rest of the kit: a status means the same in a badge, a chart and a node. */\r\nexport type NodeStatus = \"neutral\" | \"success\" | \"warning\" | \"danger\" | \"info\";\r\n\r\nexport type EdgeKind = \"straight\" | \"bezier\" | \"step\" | \"smooth-step\";\r\n\r\n/**\r\n * What the diagram models. It decides which structural rules `validateDiagram`\r\n * and `checkConnection` enforce:\r\n *\r\n * - `graph` (default) and `flowchart`: any shape, loops are allowed.\r\n * - `dag`: no cycles (workflows, data lineage).\r\n * - `tree`: no cycles and at most one incoming edge per node (org charts).\r\n */\r\nexport type DiagramKind = \"graph\" | \"flowchart\" | \"dag\" | \"tree\";\r\n\r\nexport interface Position {\r\n x: number;\r\n y: number;\r\n}\r\n\r\nexport interface DiagramNode {\r\n id: string;\r\n kind: NodeKind;\r\n /** The text read aloud in the outline. Pass a translated string. */\r\n label: string;\r\n position: Position;\r\n status?: NodeStatus;\r\n /** Set on children of a group or subflow. */\r\n parentId?: string;\r\n width?: number;\r\n height?: number;\r\n /** Typed handles, for connection validation. */\r\n ports?: Array<{ id: string; direction: \"in\" | \"out\"; type?: string }>;\r\n /** Free-form payload for custom node bodies, such as a ChartSpec for a chart node. */\r\n data?: Record<string, unknown>;\r\n /** A longer description, read after the label by screen readers. */\r\n description?: string;\r\n /** A collapsed group or subflow hides its children. */\r\n collapsed?: boolean;\r\n /** A locked node cannot be moved, resized, renamed or deleted in the editor. */\r\n locked?: boolean;\r\n}\r\n\r\nexport interface DiagramEdge {\r\n id: string;\r\n source: string;\r\n target: string;\r\n sourcePort?: string;\r\n targetPort?: string;\r\n kind?: EdgeKind;\r\n label?: string;\r\n /** Draw arrowheads at both ends. */\r\n bidirectional?: boolean;\r\n animated?: boolean;\r\n /** Draw the line dashed. Dashes carry meaning without color (for example \"optional\"). */\r\n dashed?: boolean;\r\n /** Tints the line with a status color, the same way a node status does. */\r\n status?: NodeStatus;\r\n}\r\n\r\nexport interface DiagramDocument {\r\n version: typeof DIAGRAM_VERSION;\r\n /** Every diagram has a title that states what it shows. */\r\n title: string;\r\n nodes: DiagramNode[];\r\n edges: DiagramEdge[];\r\n /** Defaults to `graph`. */\r\n kind?: DiagramKind;\r\n /** A longer text alternative, read after the title. */\r\n description?: string;\r\n}\r\n\r\n/** Every node kind, in palette order. */\r\nexport const NODE_KINDS: readonly NodeKind[] = [\r\n \"start\",\r\n \"task\",\r\n \"decision\",\r\n \"end\",\r\n \"group\",\r\n \"subflow\",\r\n \"note\",\r\n \"image\",\r\n \"entity\",\r\n \"code\",\r\n \"chart\",\r\n \"agent\",\r\n];\r\n\r\nexport const NODE_STATUSES: readonly NodeStatus[] = [\"neutral\", \"success\", \"warning\", \"danger\", \"info\"];\r\n\r\nexport const EDGE_KINDS: readonly EdgeKind[] = [\"straight\", \"bezier\", \"step\", \"smooth-step\"];\r\n\r\nexport const DIAGRAM_KINDS: readonly DiagramKind[] = [\"graph\", \"flowchart\", \"dag\", \"tree\"];\r\n\r\n/** Kinds that can contain other nodes. */\r\nexport function isContainerKind(kind: NodeKind): boolean {\r\n return kind === \"group\" || kind === \"subflow\";\r\n}\r\n\r\n/** Identity helper for authoring-time type checking. */\r\nexport function defineDiagram(document: DiagramDocument): DiagramDocument {\r\n return document;\r\n}\r\n\r\n/** An empty document with the current version. */\r\nexport function createDiagram(title = \"\", extra: Partial<Omit<DiagramDocument, \"version\" | \"title\">> = {}): DiagramDocument {\r\n return { version: DIAGRAM_VERSION, title, nodes: [], edges: [], ...extra };\r\n}\r\n","/**\n * Id utilities. They are deterministic where it matters (`nextId`), so\n * documents built by the editor stay diffable and tests stay stable.\n */\n\n/** A random id such as `node-k3j9x2ab`. Not for tests; use `nextId` there. */\nexport function generateId(prefix = \"id\", random: () => number = Math.random): string {\n let suffix = \"\";\n while (suffix.length < 8) suffix += random().toString(36).slice(2);\n return `${prefix}-${suffix.slice(0, 8)}`;\n}\n\n/** The smallest `prefix1`, `prefix2`, ... that is not taken. */\nexport function nextId(taken: Iterable<string>, prefix: string): string {\n const set = taken instanceof Set ? (taken as Set<string>) : new Set(taken);\n let n = 1;\n while (set.has(`${prefix}${n}`)) n += 1;\n return `${prefix}${n}`;\n}\n\nexport interface IdAllocator {\n /** Returns a new id and reserves it. */\n next(prefix: string): string;\n /** Marks an id as used. */\n reserve(id: string): void;\n has(id: string): boolean;\n}\n\n/** Hands out unique ids in bulk without rescanning the taken set each time. */\nexport function createIdAllocator(taken: Iterable<string> = []): IdAllocator {\n const used = new Set(taken);\n const counters = new Map<string, number>();\n return {\n next(prefix) {\n let n = counters.get(prefix) ?? 1;\n while (used.has(`${prefix}${n}`)) n += 1;\n counters.set(prefix, n + 1);\n const id = `${prefix}${n}`;\n used.add(id);\n return id;\n },\n reserve(id) {\n used.add(id);\n },\n has(id) {\n return used.has(id);\n },\n };\n}\n\n/** The readable stem of an id: `task12` becomes `task`, `a-copy` stays. Falls back to `fallback`. */\nexport function idStem(id: string, fallback: string): string {\n const stem = id.replace(/[-_]?\\d+$/, \"\");\n return stem === \"\" ? fallback : stem;\n}\n","import type { DiagramDocument, DiagramEdge, DiagramNode } from \"./schema\";\n\n/** Lookup tables over a document. Build once, query many times. */\nexport interface DiagramIndex {\n nodesById: Map<string, DiagramNode>;\n edgesById: Map<string, DiagramEdge>;\n /** Edges whose endpoints both exist, grouped by source node id. */\n outgoing: Map<string, DiagramEdge[]>;\n incoming: Map<string, DiagramEdge[]>;\n /** Child node ids by parent id, in document order. */\n children: Map<string, string[]>;\n}\n\n/** Builds the lookup tables. Dangling edges are left out of `outgoing` and `incoming`. */\nexport function buildIndex(doc: DiagramDocument): DiagramIndex {\n const nodesById = new Map<string, DiagramNode>();\n for (const node of doc.nodes) if (!nodesById.has(node.id)) nodesById.set(node.id, node);\n\n const edgesById = new Map<string, DiagramEdge>();\n const outgoing = new Map<string, DiagramEdge[]>();\n const incoming = new Map<string, DiagramEdge[]>();\n for (const edge of doc.edges) {\n if (!edgesById.has(edge.id)) edgesById.set(edge.id, edge);\n if (!nodesById.has(edge.source) || !nodesById.has(edge.target)) continue;\n const out = outgoing.get(edge.source);\n if (out) out.push(edge);\n else outgoing.set(edge.source, [edge]);\n const inc = incoming.get(edge.target);\n if (inc) inc.push(edge);\n else incoming.set(edge.target, [edge]);\n }\n\n const children = new Map<string, string[]>();\n for (const node of doc.nodes) {\n if (node.parentId === undefined || !nodesById.has(node.parentId) || node.parentId === node.id) continue;\n const list = children.get(node.parentId);\n if (list) list.push(node.id);\n else children.set(node.parentId, [node.id]);\n }\n\n return { nodesById, edgesById, outgoing, incoming, children };\n}\n\n/** The chain of ancestor ids, nearest first. Stops if the parent chain loops. */\nexport function getAncestors(index: DiagramIndex, id: string): string[] {\n const chain: string[] = [];\n const seen = new Set<string>([id]);\n let current = index.nodesById.get(id)?.parentId;\n while (current !== undefined && !seen.has(current) && index.nodesById.has(current)) {\n chain.push(current);\n seen.add(current);\n current = index.nodesById.get(current)?.parentId;\n }\n return chain;\n}\n\n/** All descendants of a node, depth first, in document order. */\nexport function getDescendants(index: DiagramIndex, id: string): string[] {\n const result: string[] = [];\n const seen = new Set<string>([id]);\n const stack = [...(index.children.get(id) ?? [])].reverse();\n while (stack.length > 0) {\n const next = stack.pop() as string;\n if (seen.has(next)) continue;\n seen.add(next);\n result.push(next);\n const kids = index.children.get(next);\n if (kids) for (let i = kids.length - 1; i >= 0; i -= 1) stack.push(kids[i] as string);\n }\n return result;\n}\n\n/**\n * Finds a directed cycle and returns its node ids in order (the first id is not\n * repeated at the end), or `undefined` when the graph is acyclic. Self-loops\n * count as cycles. Iterative, so a very long chain cannot overflow the stack.\n */\nexport function findCycle(doc: DiagramDocument, index: DiagramIndex = buildIndex(doc)): string[] | undefined {\n const state = new Map<string, 1 | 2>(); // 1 = on the current path, 2 = finished\n for (const root of doc.nodes) {\n if (state.has(root.id)) continue;\n const path: string[] = [];\n const cursors: number[] = [];\n path.push(root.id);\n cursors.push(0);\n state.set(root.id, 1);\n while (path.length > 0) {\n const current = path[path.length - 1] as string;\n const edges = index.outgoing.get(current) ?? [];\n const cursor = cursors[cursors.length - 1] as number;\n if (cursor >= edges.length) {\n state.set(current, 2);\n path.pop();\n cursors.pop();\n continue;\n }\n cursors[cursors.length - 1] = cursor + 1;\n const next = (edges[cursor] as DiagramEdge).target;\n const seen = state.get(next);\n if (seen === 1) return path.slice(path.indexOf(next));\n if (seen === undefined) {\n state.set(next, 1);\n path.push(next);\n cursors.push(0);\n }\n }\n }\n return undefined;\n}\n\n/** True when `to` can be reached from `from` by following edges forward. A node reaches itself. */\nexport function hasPath(index: DiagramIndex, from: string, to: string): boolean {\n if (from === to) return true;\n const seen = new Set<string>([from]);\n const queue = [from];\n for (let head = 0; head < queue.length; head += 1) {\n for (const edge of index.outgoing.get(queue[head] as string) ?? []) {\n if (edge.target === to) return true;\n if (!seen.has(edge.target)) {\n seen.add(edge.target);\n queue.push(edge.target);\n }\n }\n }\n return false;\n}\n\n/** Nodes with no incoming edge, in document order. */\nexport function getRoots(doc: DiagramDocument, index: DiagramIndex = buildIndex(doc)): string[] {\n return doc.nodes.filter((node) => !index.incoming.has(node.id)).map((node) => node.id);\n}\n\n/** Ids of nodes directly connected to `id` (either direction), without duplicates. */\nexport function getNeighbors(index: DiagramIndex, id: string): string[] {\n const result = new Set<string>();\n for (const edge of index.outgoing.get(id) ?? []) result.add(edge.target);\n for (const edge of index.incoming.get(id) ?? []) result.add(edge.source);\n result.delete(id);\n return [...result];\n}\n\n/** Topological order of the nodes (Kahn). Nodes on a cycle come last, in document order. */\nexport function topologicalOrder(doc: DiagramDocument, index: DiagramIndex = buildIndex(doc)): string[] {\n const indegree = new Map<string, number>();\n for (const node of doc.nodes) indegree.set(node.id, 0);\n for (const edges of index.outgoing.values()) {\n for (const edge of edges) indegree.set(edge.target, (indegree.get(edge.target) ?? 0) + 1);\n }\n const queue = doc.nodes.filter((node) => indegree.get(node.id) === 0).map((node) => node.id);\n const order: string[] = [];\n for (let head = 0; head < queue.length; head += 1) {\n const id = queue[head] as string;\n order.push(id);\n for (const edge of index.outgoing.get(id) ?? []) {\n const left = (indegree.get(edge.target) ?? 0) - 1;\n indegree.set(edge.target, left);\n if (left === 0) queue.push(edge.target);\n }\n }\n if (order.length < doc.nodes.length) {\n const placed = new Set(order);\n for (const node of doc.nodes) if (!placed.has(node.id)) order.push(node.id);\n }\n return order;\n}\n","import { buildIndex, getAncestors, hasPath, type DiagramIndex } from \"./graph\";\nimport type { DiagramDocument, DiagramNode, DiagramKind } from \"./schema\";\n\n/** A proposed edge, before it has an id. */\nexport interface DiagramConnection {\n source: string;\n target: string;\n sourcePort?: string;\n targetPort?: string;\n}\n\n/** Why a connection was refused. The canvas maps each code to a translated message. */\nexport type ConnectionRejection =\n | \"unknown-source\"\n | \"unknown-target\"\n | \"self-loop\"\n | \"duplicate\"\n | \"locked\"\n | \"container-descendant\"\n | \"source-port-missing\"\n | \"target-port-missing\"\n | \"source-port-not-output\"\n | \"target-port-not-input\"\n | \"port-type-mismatch\"\n | \"cycle\"\n | \"multiple-parents\"\n | \"custom\";\n\nexport type ConnectionCheck = { ok: true } | { ok: false; code: ConnectionRejection; message: string };\n\nexport interface ConnectionRules {\n /** Allow an edge from a node to itself. Defaults to true, except for `dag` and `tree` diagrams. */\n allowSelfLoops?: boolean;\n /** Allow a second edge with the same endpoints and ports. Defaults to false. */\n allowDuplicates?: boolean;\n /** Refuse edges that would close a cycle. Defaults to true for `dag` and `tree` diagrams. */\n acyclic?: boolean;\n /** Refuse a second incoming edge. Defaults to true for `tree` diagrams. */\n singleParent?: boolean;\n}\n\n/** The rules a diagram kind implies. Explicit rules override them. */\nexport function resolveConnectionRules(kind: DiagramKind | undefined, rules: ConnectionRules = {}): Required<ConnectionRules> {\n const strict = kind === \"dag\" || kind === \"tree\";\n return {\n allowSelfLoops: rules.allowSelfLoops ?? !strict,\n allowDuplicates: rules.allowDuplicates ?? false,\n acyclic: rules.acyclic ?? strict,\n singleParent: rules.singleParent ?? kind === \"tree\",\n };\n}\n\n/** Port types are compatible when either is untyped or `any`, or when they are equal. */\nexport function portTypesCompatible(a: string | undefined, b: string | undefined): boolean {\n return a === undefined || b === undefined || a === \"any\" || b === \"any\" || a === b;\n}\n\nconst reject = (code: ConnectionRejection, message: string): ConnectionCheck => ({ ok: false, code, message });\n\nfunction checkPort(node: DiagramNode, portId: string | undefined, wanted: \"in\" | \"out\"): ConnectionRejection | undefined {\n if (portId === undefined) return undefined;\n const port = node.ports?.find((candidate) => candidate.id === portId);\n if (!port) return wanted === \"out\" ? \"source-port-missing\" : \"target-port-missing\";\n if (port.direction !== wanted) return wanted === \"out\" ? \"source-port-not-output\" : \"target-port-not-input\";\n return undefined;\n}\n\n/**\n * Checks a proposed edge against the diagram's rules: both nodes exist, ports\n * exist, point the right way and have compatible types, and the structural\n * rules of the diagram kind hold. The result carries a machine code; show a\n * translated message for it.\n */\nexport function checkConnection(\n doc: DiagramDocument,\n connection: DiagramConnection,\n rules: ConnectionRules = {},\n index: DiagramIndex = buildIndex(doc),\n): ConnectionCheck {\n const resolved = resolveConnectionRules(doc.kind, rules);\n const source = index.nodesById.get(connection.source);\n const target = index.nodesById.get(connection.target);\n if (!source) return reject(\"unknown-source\", `Unknown source node \"${connection.source}\".`);\n if (!target) return reject(\"unknown-target\", `Unknown target node \"${connection.target}\".`);\n if (source.locked === true || target.locked === true) {\n return reject(\"locked\", \"A locked node cannot be connected.\");\n }\n\n if (source.id === target.id && !resolved.allowSelfLoops) {\n return reject(\"self-loop\", \"A node cannot connect to itself in this diagram.\");\n }\n\n // A container cannot connect to something inside it, or the other way round.\n if (source.id !== target.id) {\n if (getAncestors(index, target.id).includes(source.id) || getAncestors(index, source.id).includes(target.id)) {\n return reject(\"container-descendant\", \"A group cannot connect to a node inside it.\");\n }\n }\n\n const sourceProblem = checkPort(source, connection.sourcePort, \"out\");\n if (sourceProblem) return reject(sourceProblem, `The source port \"${connection.sourcePort}\" cannot start a connection.`);\n const targetProblem = checkPort(target, connection.targetPort, \"in\");\n if (targetProblem) return reject(targetProblem, `The target port \"${connection.targetPort}\" cannot receive a connection.`);\n\n if (connection.sourcePort !== undefined && connection.targetPort !== undefined) {\n const sourceType = source.ports?.find((port) => port.id === connection.sourcePort)?.type;\n const targetType = target.ports?.find((port) => port.id === connection.targetPort)?.type;\n if (!portTypesCompatible(sourceType, targetType)) {\n return reject(\"port-type-mismatch\", `Port types \"${sourceType}\" and \"${targetType}\" are not compatible.`);\n }\n }\n\n if (!resolved.allowDuplicates) {\n const duplicate = (index.outgoing.get(source.id) ?? []).some(\n (edge) =>\n edge.target === target.id &&\n edge.sourcePort === connection.sourcePort &&\n edge.targetPort === connection.targetPort,\n );\n if (duplicate) return reject(\"duplicate\", \"These nodes are already connected.\");\n }\n\n if (resolved.singleParent && (index.incoming.get(target.id)?.length ?? 0) > 0) {\n return reject(\"multiple-parents\", \"This node already has a parent.\");\n }\n\n if (resolved.acyclic && hasPath(index, target.id, source.id)) {\n return reject(\"cycle\", \"This connection would create a cycle.\");\n }\n\n return { ok: true };\n}\n","import { portTypesCompatible } from \"./connection\";\nimport { buildIndex, findCycle } from \"./graph\";\nimport {\n DIAGRAM_VERSION,\n EDGE_KINDS,\n NODE_KINDS,\n NODE_STATUSES,\n isContainerKind,\n type DiagramDocument,\n type DiagramKind,\n} from \"./schema\";\n\nexport type IssueSeverity = \"error\" | \"warning\";\n\nexport type IssueCode =\n | \"unsupported-version\"\n | \"missing-title\"\n | \"empty-id\"\n | \"duplicate-node-id\"\n | \"duplicate-edge-id\"\n | \"invalid-node-kind\"\n | \"invalid-edge-kind\"\n | \"invalid-status\"\n | \"invalid-position\"\n | \"invalid-size\"\n | \"empty-label\"\n | \"dangling-source\"\n | \"dangling-target\"\n | \"unknown-source-port\"\n | \"unknown-target-port\"\n | \"source-port-direction\"\n | \"target-port-direction\"\n | \"port-type-mismatch\"\n | \"duplicate-port-id\"\n | \"duplicate-edge\"\n | \"self-loop\"\n | \"parent-missing\"\n | \"parent-self\"\n | \"parent-cycle\"\n | \"parent-not-container\"\n | \"cycle\"\n | \"multiple-parents\";\n\n/**\n * One finding. `message` is English for developers and logs; show your own\n * translated text for end users, keyed by `code`.\n */\nexport interface DiagramIssue {\n code: IssueCode;\n severity: IssueSeverity;\n message: string;\n /** Where in the document the problem is, for example `[\"edges\", 2, \"target\"]`. */\n path: Array<string | number>;\n nodeId?: string;\n edgeId?: string;\n}\n\nexport interface ValidationResult {\n /** True when there are no errors. Warnings do not make a diagram invalid. */\n valid: boolean;\n issues: DiagramIssue[];\n errors: DiagramIssue[];\n warnings: DiagramIssue[];\n}\n\nexport interface ValidateOptions {\n /** Overrides `doc.kind`. */\n kind?: DiagramKind;\n /** Report nodes with an empty label as warnings. Defaults to true. */\n warnOnEmptyLabels?: boolean;\n}\n\nconst isFiniteNumber = (value: unknown): value is number => typeof value === \"number\" && Number.isFinite(value);\n\n/**\n * Checks a document and returns every problem it finds instead of stopping at\n * the first: unique ids, edges that point at nothing, ports that do not exist\n * or do not match, group (parent) structure, and, for `dag` and `tree`\n * diagrams, cycles and multiple parents.\n */\nexport function validateDiagram(doc: DiagramDocument, options: ValidateOptions = {}): ValidationResult {\n const issues: DiagramIssue[] = [];\n const add = (issue: Omit<DiagramIssue, \"severity\"> & { severity?: IssueSeverity }) =>\n issues.push({ severity: \"error\", ...issue });\n\n const kind = options.kind ?? doc.kind ?? \"graph\";\n\n if (doc.version !== DIAGRAM_VERSION) {\n add({\n code: \"unsupported-version\",\n message: `Unsupported diagram version ${String(doc.version)}. Expected ${DIAGRAM_VERSION}.`,\n path: [\"version\"],\n });\n }\n if (typeof doc.title !== \"string\" || doc.title.trim() === \"\") {\n add({\n code: \"missing-title\",\n severity: \"warning\",\n message: \"Every diagram needs a title that states what it shows.\",\n path: [\"title\"],\n });\n }\n\n const index = buildIndex(doc);\n\n // Nodes ---------------------------------------------------------------\n const seenNodes = new Set<string>();\n doc.nodes.forEach((node, i) => {\n if (typeof node.id !== \"string\" || node.id === \"\") {\n add({ code: \"empty-id\", message: \"A node needs a non-empty id.\", path: [\"nodes\", i, \"id\"] });\n } else if (seenNodes.has(node.id)) {\n add({\n code: \"duplicate-node-id\",\n message: `Node id \"${node.id}\" is used more than once.`,\n path: [\"nodes\", i, \"id\"],\n nodeId: node.id,\n });\n }\n seenNodes.add(node.id);\n\n if (!NODE_KINDS.includes(node.kind)) {\n add({\n code: \"invalid-node-kind\",\n message: `Unknown node kind \"${String(node.kind)}\".`,\n path: [\"nodes\", i, \"kind\"],\n nodeId: node.id,\n });\n }\n if (node.status !== undefined && !NODE_STATUSES.includes(node.status)) {\n add({\n code: \"invalid-status\",\n message: `Unknown node status \"${String(node.status)}\".`,\n path: [\"nodes\", i, \"status\"],\n nodeId: node.id,\n });\n }\n if (!node.position || !isFiniteNumber(node.position.x) || !isFiniteNumber(node.position.y)) {\n add({\n code: \"invalid-position\",\n message: `Node \"${node.id}\" needs a finite position.`,\n path: [\"nodes\", i, \"position\"],\n nodeId: node.id,\n });\n }\n for (const key of [\"width\", \"height\"] as const) {\n const value = node[key];\n if (value !== undefined && (!isFiniteNumber(value) || value <= 0)) {\n add({\n code: \"invalid-size\",\n message: `Node \"${node.id}\" has an invalid ${key}.`,\n path: [\"nodes\", i, key],\n nodeId: node.id,\n });\n }\n }\n if ((options.warnOnEmptyLabels ?? true) && (typeof node.label !== \"string\" || node.label.trim() === \"\")) {\n add({\n code: \"empty-label\",\n severity: \"warning\",\n message: `Node \"${node.id}\" has no label, so screen readers cannot name it.`,\n path: [\"nodes\", i, \"label\"],\n nodeId: node.id,\n });\n }\n\n const portIds = new Set<string>();\n node.ports?.forEach((port, p) => {\n if (portIds.has(port.id)) {\n add({\n code: \"duplicate-port-id\",\n message: `Port id \"${port.id}\" is used twice on node \"${node.id}\".`,\n path: [\"nodes\", i, \"ports\", p, \"id\"],\n nodeId: node.id,\n });\n }\n portIds.add(port.id);\n });\n\n // Groups ------------------------------------------------------------\n if (node.parentId !== undefined) {\n const parent = index.nodesById.get(node.parentId);\n if (node.parentId === node.id) {\n add({\n code: \"parent-self\",\n message: `Node \"${node.id}\" is its own parent.`,\n path: [\"nodes\", i, \"parentId\"],\n nodeId: node.id,\n });\n } else if (!parent) {\n add({\n code: \"parent-missing\",\n message: `Node \"${node.id}\" refers to a missing parent \"${node.parentId}\".`,\n path: [\"nodes\", i, \"parentId\"],\n nodeId: node.id,\n });\n } else {\n if (!isContainerKind(parent.kind)) {\n add({\n code: \"parent-not-container\",\n message: `Parent \"${parent.id}\" is a ${parent.kind}, not a group or subflow.`,\n path: [\"nodes\", i, \"parentId\"],\n nodeId: node.id,\n });\n }\n if (hasParentLoop(index, node.id)) {\n add({\n code: \"parent-cycle\",\n message: `Node \"${node.id}\" is inside a loop of groups.`,\n path: [\"nodes\", i, \"parentId\"],\n nodeId: node.id,\n });\n }\n }\n }\n });\n\n // Edges ---------------------------------------------------------------\n const seenEdges = new Set<string>();\n const seenPairs = new Set<string>();\n doc.edges.forEach((edge, i) => {\n if (typeof edge.id !== \"string\" || edge.id === \"\") {\n add({ code: \"empty-id\", message: \"An edge needs a non-empty id.\", path: [\"edges\", i, \"id\"] });\n } else if (seenEdges.has(edge.id)) {\n add({\n code: \"duplicate-edge-id\",\n message: `Edge id \"${edge.id}\" is used more than once.`,\n path: [\"edges\", i, \"id\"],\n edgeId: edge.id,\n });\n }\n seenEdges.add(edge.id);\n\n if (edge.kind !== undefined && !EDGE_KINDS.includes(edge.kind)) {\n add({\n code: \"invalid-edge-kind\",\n message: `Unknown edge kind \"${String(edge.kind)}\".`,\n path: [\"edges\", i, \"kind\"],\n edgeId: edge.id,\n });\n }\n if (edge.status !== undefined && !NODE_STATUSES.includes(edge.status)) {\n add({\n code: \"invalid-status\",\n message: `Unknown edge status \"${String(edge.status)}\".`,\n path: [\"edges\", i, \"status\"],\n edgeId: edge.id,\n });\n }\n\n const source = index.nodesById.get(edge.source);\n const target = index.nodesById.get(edge.target);\n if (!source) {\n add({\n code: \"dangling-source\",\n message: `Edge \"${edge.id}\" starts at a missing node \"${edge.source}\".`,\n path: [\"edges\", i, \"source\"],\n edgeId: edge.id,\n });\n }\n if (!target) {\n add({\n code: \"dangling-target\",\n message: `Edge \"${edge.id}\" ends at a missing node \"${edge.target}\".`,\n path: [\"edges\", i, \"target\"],\n edgeId: edge.id,\n });\n }\n if (!source || !target) return;\n\n const sourcePort = edge.sourcePort === undefined ? undefined : source.ports?.find((p) => p.id === edge.sourcePort);\n const targetPort = edge.targetPort === undefined ? undefined : target.ports?.find((p) => p.id === edge.targetPort);\n if (edge.sourcePort !== undefined) {\n if (!sourcePort) {\n add({\n code: \"unknown-source-port\",\n message: `Edge \"${edge.id}\" uses port \"${edge.sourcePort}\", which node \"${source.id}\" does not have.`,\n path: [\"edges\", i, \"sourcePort\"],\n edgeId: edge.id,\n });\n } else if (sourcePort.direction !== \"out\") {\n add({\n code: \"source-port-direction\",\n message: `Port \"${sourcePort.id}\" on \"${source.id}\" is an input and cannot start an edge.`,\n path: [\"edges\", i, \"sourcePort\"],\n edgeId: edge.id,\n });\n }\n }\n if (edge.targetPort !== undefined) {\n if (!targetPort) {\n add({\n code: \"unknown-target-port\",\n message: `Edge \"${edge.id}\" uses port \"${edge.targetPort}\", which node \"${target.id}\" does not have.`,\n path: [\"edges\", i, \"targetPort\"],\n edgeId: edge.id,\n });\n } else if (targetPort.direction !== \"in\") {\n add({\n code: \"target-port-direction\",\n message: `Port \"${targetPort.id}\" on \"${target.id}\" is an output and cannot end an edge.`,\n path: [\"edges\", i, \"targetPort\"],\n edgeId: edge.id,\n });\n }\n }\n if (sourcePort && targetPort && !portTypesCompatible(sourcePort.type, targetPort.type)) {\n add({\n code: \"port-type-mismatch\",\n message: `Edge \"${edge.id}\" joins incompatible port types \"${sourcePort.type}\" and \"${targetPort.type}\".`,\n path: [\"edges\", i],\n edgeId: edge.id,\n });\n }\n\n const pair = JSON.stringify([edge.source, edge.sourcePort ?? null, edge.target, edge.targetPort ?? null]);\n if (seenPairs.has(pair)) {\n add({\n code: \"duplicate-edge\",\n severity: \"warning\",\n message: `Edge \"${edge.id}\" repeats an existing connection.`,\n path: [\"edges\", i],\n edgeId: edge.id,\n });\n }\n seenPairs.add(pair);\n\n if (edge.source === edge.target && (kind === \"dag\" || kind === \"tree\")) {\n add({\n code: \"self-loop\",\n message: `Edge \"${edge.id}\" connects node \"${edge.source}\" to itself, which a ${kind} does not allow.`,\n path: [\"edges\", i],\n edgeId: edge.id,\n });\n }\n });\n\n // Structure -----------------------------------------------------------\n if (kind === \"dag\" || kind === \"tree\") {\n const cycle = findCycle(doc, index);\n if (cycle && !(cycle.length === 1 && issues.some((issue) => issue.code === \"self-loop\"))) {\n add({\n code: \"cycle\",\n message: `The diagram has a cycle: ${[...cycle, cycle[0]].join(\" -> \")}.`,\n path: [\"edges\"],\n nodeId: cycle[0],\n });\n }\n }\n if (kind === \"tree\") {\n for (const [id, edges] of index.incoming) {\n if (edges.length > 1) {\n add({\n code: \"multiple-parents\",\n message: `Node \"${id}\" has ${edges.length} incoming edges, but a tree node has one parent.`,\n path: [\"edges\"],\n nodeId: id,\n });\n }\n }\n }\n\n const errors = issues.filter((issue) => issue.severity === \"error\");\n const warnings = issues.filter((issue) => issue.severity === \"warning\");\n return { valid: errors.length === 0, issues, errors, warnings };\n}\n\n/** True when following parentId from `id` never terminates (it loops). */\nfunction hasParentLoop(index: ReturnType<typeof buildIndex>, id: string): boolean {\n const seen = new Set<string>();\n let current: string | undefined = id;\n while (current !== undefined) {\n if (seen.has(current)) return true;\n seen.add(current);\n current = index.nodesById.get(current)?.parentId;\n if (current !== undefined && !index.nodesById.has(current)) return false;\n }\n return false;\n}\n","import { buildIndex, getNeighbors, type DiagramIndex } from \"./graph\";\nimport { isContainerKind } from \"./schema\";\nimport type { DiagramDocument, DiagramEdge, DiagramNode, EdgeKind, NodeKind, Position } from \"./schema\";\n\n/** A point in diagram space. Same shape as `Position`. */\nexport type Point = Position;\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport interface Rect extends Point, Size {}\n\nexport type Side = \"top\" | \"right\" | \"bottom\" | \"left\";\n\n/** Flow direction of a layout: top to bottom, bottom to top, left to right, right to left. */\nexport type LayoutDirection = \"TB\" | \"BT\" | \"LR\" | \"RL\";\n\n/** The diagram grid in diagram units. Layout and snapping round to it (spec: everything sits on the 8 px grid). */\nexport const GRID_SIZE = 8;\n\n/** Default node sizes by kind, in diagram units. All are multiples of the grid. */\nexport const DEFAULT_NODE_SIZE: Readonly<Record<NodeKind, Size>> = {\n start: { width: 128, height: 48 },\n end: { width: 128, height: 48 },\n task: { width: 176, height: 64 },\n decision: { width: 160, height: 96 },\n group: { width: 320, height: 200 },\n subflow: { width: 320, height: 200 },\n note: { width: 176, height: 96 },\n image: { width: 160, height: 128 },\n entity: { width: 192, height: 128 },\n code: { width: 240, height: 128 },\n chart: { width: 240, height: 160 },\n agent: { width: 192, height: 80 },\n};\n\n/** Height of a collapsed group: just its title bar. */\nexport const COLLAPSED_HEIGHT = 48;\n\n/** Approximate text metrics, used to size nodes and labels without a DOM. */\nexport const TEXT_METRICS = { charWidth: 7, lineHeight: 20, nodePaddingX: 32, nodePaddingY: 24 } as const;\n\nconst roundUp = (value: number, step: number) => Math.ceil(value / step) * step;\n\nexport function estimateTextWidth(text: string, charWidth: number = TEXT_METRICS.charWidth): number {\n let units = 0;\n for (const char of text) {\n // Wide scripts (CJK) take about twice the width of Latin letters.\n const code = char.codePointAt(0) ?? 0;\n units += code >= 0x2e80 ? 2 : 1;\n }\n return units * charWidth;\n}\n\n/** Wraps text into lines that fit `maxWidth`, breaking at spaces and, for a very long word, anywhere. */\nexport function wrapText(text: string, maxWidth: number, charWidth: number = TEXT_METRICS.charWidth): string[] {\n const maxChars = Math.max(1, Math.floor(maxWidth / charWidth));\n const lines: string[] = [];\n for (const paragraph of text.split(/\\r?\\n/)) {\n let line = \"\";\n for (const word of paragraph.split(/\\s+/).filter(Boolean)) {\n let rest = word;\n while (rest.length > maxChars) {\n if (line !== \"\") {\n lines.push(line);\n line = \"\";\n }\n lines.push(rest.slice(0, maxChars));\n rest = rest.slice(maxChars);\n }\n const candidate = line === \"\" ? rest : `${line} ${rest}`;\n if (candidate.length <= maxChars) line = candidate;\n else {\n lines.push(line);\n line = rest;\n }\n }\n lines.push(line);\n }\n return lines.length === 0 ? [\"\"] : lines;\n}\n\nfunction dataList(node: DiagramNode, key: string): unknown[] {\n const value = node.data?.[key];\n return Array.isArray(value) ? value : [];\n}\n\n/**\n * The size a node is drawn at: its own `width` and `height` when set, otherwise\n * a default for its kind that grows to fit a long label (or the rows of an\n * entity). The estimate is deterministic, so layout, the canvas and the static\n * SVG all agree.\n */\nexport function getNodeSize(node: DiagramNode): Size {\n const base = DEFAULT_NODE_SIZE[node.kind] ?? DEFAULT_NODE_SIZE.task;\n // A collapsed group shrinks to its title bar.\n if (node.collapsed === true && isContainerKind(node.kind)) {\n return { width: node.width ?? base.width, height: COLLAPSED_HEIGHT };\n }\n if (node.width !== undefined && node.height !== undefined) return { width: node.width, height: node.height };\n let { width, height } = base;\n\n switch (node.kind) {\n case \"start\":\n case \"end\":\n case \"task\":\n case \"agent\":\n case \"note\":\n case \"decision\": {\n const diamond = node.kind === \"decision\";\n const usable = (w: number) => (diamond ? w * 0.5 : w - TEXT_METRICS.nodePaddingX);\n const needed = estimateTextWidth(node.label);\n if (needed > usable(width)) {\n const maxWidth = base.width * 2;\n const wanted = diamond ? needed * 2 : needed + TEXT_METRICS.nodePaddingX;\n width = Math.min(maxWidth, roundUp(wanted, 8));\n const lines = wrapText(node.label, usable(width)).length;\n const textHeight = lines * TEXT_METRICS.lineHeight;\n height = Math.max(base.height, roundUp(diamond ? textHeight * 2 + 16 : textHeight + TEXT_METRICS.nodePaddingY + 8, 8));\n }\n break;\n }\n case \"entity\": {\n const rows = dataList(node, \"fields\").length;\n height = Math.max(base.height, roundUp(32 + rows * 24 + 8, 8));\n break;\n }\n case \"code\": {\n const code = typeof node.data?.code === \"string\" ? node.data.code : \"\";\n const lines = Math.min(12, code === \"\" ? 0 : code.split(/\\r?\\n/).length);\n height = Math.max(base.height, roundUp(40 + lines * TEXT_METRICS.lineHeight, 8));\n break;\n }\n default:\n break;\n }\n\n return { width: node.width ?? width, height: node.height ?? height };\n}\n\n// ---------------------------------------------------------------- bounds\n\nexport function getNodeBounds(node: DiagramNode): Rect {\n const size = getNodeSize(node);\n return { x: node.position.x, y: node.position.y, ...size };\n}\n\nexport function rectCenter(rect: Rect): Point {\n return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };\n}\n\nexport function unionRects(rects: Iterable<Rect>): Rect {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const rect of rects) {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.width);\n maxY = Math.max(maxY, rect.y + rect.height);\n }\n if (minX === Infinity) return { x: 0, y: 0, width: 0, height: 0 };\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\nexport function rectsIntersect(a: Rect, b: Rect): boolean {\n return a.x < b.x + b.width && b.x < a.x + a.width && a.y < b.y + b.height && b.y < a.y + a.height;\n}\n\nexport function rectContainsPoint(rect: Rect, point: Point): boolean {\n return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height;\n}\n\n/** Absolute (diagram space) top-left position of every node, resolving parent offsets. Loop-safe. */\nexport function getAbsolutePositions(doc: DiagramDocument, index: DiagramIndex = buildIndex(doc)): Map<string, Point> {\n const result = new Map<string, Point>();\n const resolve = (id: string): Point => {\n const known = result.get(id);\n if (known) return known;\n // Walk up to the first known ancestor, then add offsets back down.\n const chain: DiagramNode[] = [];\n const seen = new Set<string>();\n let current = index.nodesById.get(id);\n let base: Point = { x: 0, y: 0 };\n while (current) {\n if (seen.has(current.id)) break;\n seen.add(current.id);\n const cached = result.get(current.id);\n if (cached) {\n base = cached;\n break;\n }\n chain.push(current);\n current = current.parentId === undefined ? undefined : index.nodesById.get(current.parentId);\n }\n for (let i = chain.length - 1; i >= 0; i -= 1) {\n const node = chain[i] as DiagramNode;\n base = { x: base.x + node.position.x, y: base.y + node.position.y };\n result.set(node.id, base);\n }\n return result.get(id) ?? base;\n };\n for (const node of doc.nodes) resolve(node.id);\n return result;\n}\n\nexport function getAbsolutePosition(doc: DiagramDocument, id: string): Point | undefined {\n return getAbsolutePositions(doc).get(id);\n}\n\n/** Absolute bounds of every node. */\nexport function getAbsoluteBounds(doc: DiagramDocument, index: DiagramIndex = buildIndex(doc)): Map<string, Rect> {\n const positions = getAbsolutePositions(doc, index);\n const bounds = new Map<string, Rect>();\n for (const node of doc.nodes) {\n const at = positions.get(node.id) ?? node.position;\n bounds.set(node.id, { x: at.x, y: at.y, ...getNodeSize(node) });\n }\n return bounds;\n}\n\n/** The rectangle that contains every node (absolute). An empty diagram gives a zero rectangle. */\nexport function getDocumentBounds(doc: DiagramDocument): Rect {\n return unionRects(getAbsoluteBounds(doc).values());\n}\n\n// ----------------------------------------------------------- grid and snap\n\nexport function snapValue(value: number, grid: number = GRID_SIZE): number {\n return grid > 0 ? Math.round(value / grid) * grid : value;\n}\n\nexport function snapPoint(point: Point, grid: number = GRID_SIZE): Point {\n return { x: snapValue(point.x, grid), y: snapValue(point.y, grid) };\n}\n\n// ------------------------------------------------------------------ ports\n\n/** Which sides new edges leave from and arrive at for a flow direction. */\nexport function directionSides(direction: LayoutDirection): { source: Side; target: Side } {\n switch (direction) {\n case \"TB\":\n return { source: \"bottom\", target: \"top\" };\n case \"BT\":\n return { source: \"top\", target: \"bottom\" };\n case \"LR\":\n return { source: \"right\", target: \"left\" };\n case \"RL\":\n return { source: \"left\", target: \"right\" };\n }\n}\n\n/** In a right-to-left page, horizontal flows mirror: LR becomes RL. Vertical flows keep their direction. */\nexport function mirrorDirection(direction: LayoutDirection, rtl: boolean): LayoutDirection {\n if (!rtl) return direction;\n if (direction === \"LR\") return \"RL\";\n if (direction === \"RL\") return \"LR\";\n return direction;\n}\n\nexport function isHorizontal(direction: LayoutDirection): boolean {\n return direction === \"LR\" || direction === \"RL\";\n}\n\nexport interface PortPlacement {\n /** Undefined for the default (unnamed) handle of a node without declared ports. */\n id: string | undefined;\n direction: \"in\" | \"out\";\n side: Side;\n type?: string;\n /** Position along the side, 0 to 1, measured from the start of that side. */\n offset: number;\n}\n\n/**\n * Where a node's connection points sit. A node without declared ports gets one\n * unnamed input and one unnamed output (a `start` node only an output, an `end`\n * node only an input). Declared ports are spread evenly along their side. In a\n * right-to-left page the spread along a horizontal edge mirrors.\n */\nexport function getPortPlacements(node: DiagramNode, direction: LayoutDirection = \"TB\", rtl = false): PortPlacement[] {\n const sides = directionSides(direction);\n const mirror = (offset: number, side: Side) => (rtl && (side === \"top\" || side === \"bottom\") ? 1 - offset : offset);\n\n if (!node.ports || node.ports.length === 0) {\n const placements: PortPlacement[] = [];\n if (node.kind !== \"start\") placements.push({ id: undefined, direction: \"in\", side: sides.target, offset: 0.5 });\n if (node.kind !== \"end\") placements.push({ id: undefined, direction: \"out\", side: sides.source, offset: 0.5 });\n return placements;\n }\n\n const placements: PortPlacement[] = [];\n for (const dir of [\"in\", \"out\"] as const) {\n const ports = node.ports.filter((port) => port.direction === dir);\n const side = dir === \"in\" ? sides.target : sides.source;\n ports.forEach((port, i) => {\n const placement: PortPlacement = {\n id: port.id,\n direction: dir,\n side,\n offset: mirror((i + 1) / (ports.length + 1), side),\n };\n if (port.type !== undefined) placement.type = port.type;\n placements.push(placement);\n });\n }\n return placements;\n}\n\n/** The point on a rectangle's side, `offset` (0 to 1) along it. */\nexport function sideAnchor(rect: Rect, side: Side, offset = 0.5): Point {\n switch (side) {\n case \"top\":\n return { x: rect.x + rect.width * offset, y: rect.y };\n case \"bottom\":\n return { x: rect.x + rect.width * offset, y: rect.y + rect.height };\n case \"left\":\n return { x: rect.x, y: rect.y + rect.height * offset };\n case \"right\":\n return { x: rect.x + rect.width, y: rect.y + rect.height * offset };\n }\n}\n\nconst SIDE_VECTOR: Record<Side, Point> = {\n top: { x: 0, y: -1 },\n right: { x: 1, y: 0 },\n bottom: { x: 0, y: 1 },\n left: { x: -1, y: 0 },\n};\n\nexport function sideVector(side: Side): Point {\n return SIDE_VECTOR[side];\n}\n\n// ---------------------------------------------------------------- edges\n\nconst fmt = (value: number): string => {\n const rounded = Math.round(value * 100) / 100;\n return Object.is(rounded, -0) ? \"0\" : String(rounded);\n};\n\nexport interface EdgePathInput {\n source: Point;\n target: Point;\n sourceSide: Side;\n targetSide: Side;\n kind?: EdgeKind;\n /** How far an edge leaves a node before it turns. Defaults to 24. */\n offset?: number;\n /** Corner radius of `smooth-step` edges. Defaults to 8. */\n radius?: number;\n /** Bezier curvature, as React Flow defines it. Defaults to 0.25. */\n curvature?: number;\n /** Draw a loop that returns to the same node, `loopSize` units wide. */\n loopSize?: number;\n}\n\nexport interface EdgePath {\n /** SVG path data. */\n path: string;\n /** Where to put the label: the visual middle of the edge. */\n label: Point;\n /** The polyline (or control polygon for curves). Useful for bounds and hit tests. */\n points: Point[];\n}\n\nconst add = (a: Point, b: Point): Point => ({ x: a.x + b.x, y: a.y + b.y });\nconst sub = (a: Point, b: Point): Point => ({ x: a.x - b.x, y: a.y - b.y });\nconst scale = (a: Point, k: number): Point => ({ x: a.x * k, y: a.y * k });\nconst dot = (a: Point, b: Point): number => a.x * b.x + a.y * b.y;\nconst same = (a: Point, b: Point): boolean => a.x === b.x && a.y === b.y;\nconst distance = (a: Point, b: Point): number => Math.hypot(a.x - b.x, a.y - b.y);\n\nfunction controlOffset(delta: number, curvature: number): number {\n return delta >= 0 ? 0.5 * delta : curvature * 25 * Math.sqrt(-delta);\n}\n\nfunction controlPoint(side: Side, from: Point, to: Point, curvature: number): Point {\n switch (side) {\n case \"left\":\n return { x: from.x - controlOffset(from.x - to.x, curvature), y: from.y };\n case \"right\":\n return { x: from.x + controlOffset(to.x - from.x, curvature), y: from.y };\n case \"top\":\n return { x: from.x, y: from.y - controlOffset(from.y - to.y, curvature) };\n case \"bottom\":\n return { x: from.x, y: from.y + controlOffset(to.y - from.y, curvature) };\n }\n}\n\nfunction sidestep(a: number, b: number, gap: number): number {\n return Math.abs(a - b) >= gap * 2 ? (a + b) / 2 : Math.max(a, b) + gap * 2;\n}\n\n/** An orthogonal polyline from `s` to `t` that leaves and arrives perpendicular to the given sides. */\nfunction orthogonalPoints(s: Point, ss: Side, t: Point, ts: Side, gap: number): Point[] {\n const sv = SIDE_VECTOR[ss];\n const tv = SIDE_VECTOR[ts];\n const s1 = add(s, scale(sv, gap));\n const t1 = add(t, scale(tv, gap));\n const sVertical = sv.y !== 0;\n const tVertical = tv.y !== 0;\n let points: Point[];\n\n if (sVertical === tVertical) {\n const opposite = sv.x === -tv.x && sv.y === -tv.y;\n if (opposite && dot(sub(t1, s1), sv) >= 0) {\n if (sVertical) {\n const y = (s.y + t.y) / 2;\n points = [s, { x: s.x, y }, { x: t.x, y }, t];\n } else {\n const x = (s.x + t.x) / 2;\n points = [s, { x, y: s.y }, { x, y: t.y }, t];\n }\n } else if (!opposite) {\n if (sVertical) {\n const y = sv.y > 0 ? Math.max(s1.y, t1.y) : Math.min(s1.y, t1.y);\n points = [s, { x: s.x, y }, { x: t.x, y }, t];\n } else {\n const x = sv.x > 0 ? Math.max(s1.x, t1.x) : Math.min(s1.x, t1.x);\n points = [s, { x, y: s.y }, { x, y: t.y }, t];\n }\n } else if (sVertical) {\n const x = sidestep(s.x, t.x, gap);\n points = [s, s1, { x, y: s1.y }, { x, y: t1.y }, t1, t];\n } else {\n const y = sidestep(s.y, t.y, gap);\n points = [s, s1, { x: s1.x, y }, { x: t1.x, y }, t1, t];\n }\n } else if (sVertical) {\n const corner = { x: s.x, y: t.y };\n const leavesOk = dot(sub(corner, s), sv) >= gap;\n const arrivesOk = dot(sub(t, corner), scale(tv, -1)) >= gap;\n points = leavesOk && arrivesOk ? [s, corner, t] : [s, s1, { x: s1.x, y: t1.y }, t1, t];\n } else {\n const corner = { x: t.x, y: s.y };\n const leavesOk = dot(sub(corner, s), sv) >= gap;\n const arrivesOk = dot(sub(t, corner), scale(tv, -1)) >= gap;\n points = leavesOk && arrivesOk ? [s, corner, t] : [s, s1, { x: t1.x, y: s1.y }, t1, t];\n }\n return simplify(points);\n}\n\n/** Drops repeated points and the middle point of any straight run. */\nfunction simplify(points: Point[]): Point[] {\n const out: Point[] = [];\n for (const point of points) {\n const last = out[out.length - 1];\n if (last && same(last, point)) continue;\n out.push(point);\n }\n for (let i = out.length - 2; i >= 1; i -= 1) {\n const a = out[i - 1] as Point;\n const b = out[i] as Point;\n const c = out[i + 1] as Point;\n if ((a.x === b.x && b.x === c.x) || (a.y === b.y && b.y === c.y)) out.splice(i, 1);\n }\n return out;\n}\n\nfunction polylineMidpoint(points: Point[]): Point {\n let total = 0;\n for (let i = 1; i < points.length; i += 1) total += distance(points[i - 1] as Point, points[i] as Point);\n let remaining = total / 2;\n for (let i = 1; i < points.length; i += 1) {\n const a = points[i - 1] as Point;\n const b = points[i] as Point;\n const length = distance(a, b);\n if (remaining <= length && length > 0) {\n const t = remaining / length;\n return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };\n }\n remaining -= length;\n }\n return points[0] ?? { x: 0, y: 0 };\n}\n\nfunction polylinePath(points: Point[], radius: number): string {\n const first = points[0];\n if (!first) return \"\";\n let d = `M ${fmt(first.x)} ${fmt(first.y)}`;\n for (let i = 1; i < points.length; i += 1) {\n const prev = points[i - 1] as Point;\n const current = points[i] as Point;\n const next = points[i + 1];\n if (radius > 0 && next) {\n const r = Math.min(radius, distance(prev, current) / 2, distance(current, next) / 2);\n const toPrev = sub(prev, current);\n const toNext = sub(next, current);\n const a = add(current, scale(toPrev, r / (distance(prev, current) || 1)));\n const b = add(current, scale(toNext, r / (distance(current, next) || 1)));\n d += ` L ${fmt(a.x)} ${fmt(a.y)} Q ${fmt(current.x)} ${fmt(current.y)} ${fmt(b.x)} ${fmt(b.y)}`;\n } else {\n d += ` L ${fmt(current.x)} ${fmt(current.y)}`;\n }\n }\n return d;\n}\n\n/**\n * The SVG path between two anchors. `step` and `smooth-step` run orthogonally\n * and leave each node perpendicular to the side they attach to; `bezier` uses\n * React Flow's control-point rule; `straight` is a line. The canvas and the\n * static SVG both call this, so they draw the same edge.\n */\nexport function computeEdgePath(input: EdgePathInput): EdgePath {\n const { source, target, sourceSide, targetSide } = input;\n const kind = input.kind ?? \"smooth-step\";\n const offset = input.offset ?? 24;\n const radius = input.radius ?? 8;\n const curvature = input.curvature ?? 0.25;\n\n if (input.loopSize !== undefined) {\n const size = input.loopSize;\n // Bulge toward the inline-end side of the node: right for vertical flows, below for horizontal ones.\n const bulge = sideVector(sourceSide).y !== 0 ? { x: 1, y: 0 } : { x: 0, y: 1 };\n const c1 = add(add(source, scale(SIDE_VECTOR[sourceSide], size)), scale(bulge, size));\n const c2 = add(add(target, scale(SIDE_VECTOR[targetSide], size)), scale(bulge, size));\n const label = {\n x: (source.x + 3 * c1.x + 3 * c2.x + target.x) / 8,\n y: (source.y + 3 * c1.y + 3 * c2.y + target.y) / 8,\n };\n return {\n path: `M ${fmt(source.x)} ${fmt(source.y)} C ${fmt(c1.x)} ${fmt(c1.y)} ${fmt(c2.x)} ${fmt(c2.y)} ${fmt(target.x)} ${fmt(target.y)}`,\n label,\n points: [source, c1, c2, target],\n };\n }\n\n if (kind === \"straight\") {\n return {\n path: `M ${fmt(source.x)} ${fmt(source.y)} L ${fmt(target.x)} ${fmt(target.y)}`,\n label: { x: (source.x + target.x) / 2, y: (source.y + target.y) / 2 },\n points: [source, target],\n };\n }\n\n if (kind === \"bezier\") {\n const c1 = controlPoint(sourceSide, source, target, curvature);\n const c2 = controlPoint(targetSide, target, source, curvature);\n return {\n path: `M ${fmt(source.x)} ${fmt(source.y)} C ${fmt(c1.x)} ${fmt(c1.y)} ${fmt(c2.x)} ${fmt(c2.y)} ${fmt(target.x)} ${fmt(target.y)}`,\n label: {\n x: (source.x + 3 * c1.x + 3 * c2.x + target.x) / 8,\n y: (source.y + 3 * c1.y + 3 * c2.y + target.y) / 8,\n },\n points: [source, c1, c2, target],\n };\n }\n\n const points = orthogonalPoints(source, sourceSide, target, targetSide, offset);\n return {\n path: polylinePath(points, kind === \"smooth-step\" ? radius : 0),\n label: polylineMidpoint(points),\n points,\n };\n}\n\nexport interface GeometryOptions {\n direction?: LayoutDirection;\n rtl?: boolean;\n /** Default edge kind for edges that do not set one. Defaults to `smooth-step`. */\n edgeKind?: EdgeKind;\n}\n\n/** Precomputed lookups for drawing many edges of one document. */\nexport interface GeometryContext {\n doc: DiagramDocument;\n index: DiagramIndex;\n direction: LayoutDirection;\n rtl: boolean;\n edgeKind: EdgeKind;\n /** Absolute bounds per node id. */\n bounds: Map<string, Rect>;\n}\n\nexport function createGeometryContext(doc: DiagramDocument, options: GeometryOptions = {}): GeometryContext {\n const index = buildIndex(doc);\n return {\n doc,\n index,\n direction: options.direction ?? \"TB\",\n rtl: options.rtl ?? false,\n edgeKind: options.edgeKind ?? \"smooth-step\",\n bounds: getAbsoluteBounds(doc, index),\n };\n}\n\nexport interface EdgeGeometry extends EdgePath {\n source: Point;\n target: Point;\n sourceSide: Side;\n targetSide: Side;\n selfLoop: boolean;\n}\n\nfunction anchorFor(\n node: DiagramNode,\n rect: Rect,\n wanted: \"in\" | \"out\",\n portId: string | undefined,\n direction: LayoutDirection,\n rtl: boolean,\n): { point: Point; side: Side } {\n const placements = getPortPlacements(node, direction, rtl);\n const sides = directionSides(direction);\n const match =\n placements.find((placement) => placement.direction === wanted && placement.id === portId) ??\n placements.find((placement) => placement.direction === wanted && portId === undefined);\n const side = match?.side ?? (wanted === \"out\" ? sides.source : sides.target);\n return { point: sideAnchor(rect, side, match?.offset ?? 0.5), side };\n}\n\n/** Where an edge runs and how it is drawn. Returns undefined when an endpoint is missing. */\nexport function getEdgeGeometry(context: GeometryContext, edge: DiagramEdge): EdgeGeometry | undefined {\n const sourceNode = context.index.nodesById.get(edge.source);\n const targetNode = context.index.nodesById.get(edge.target);\n const sourceRect = context.bounds.get(edge.source);\n const targetRect = context.bounds.get(edge.target);\n if (!sourceNode || !targetNode || !sourceRect || !targetRect) return undefined;\n\n const from = anchorFor(sourceNode, sourceRect, \"out\", edge.sourcePort, context.direction, context.rtl);\n const to = anchorFor(targetNode, targetRect, \"in\", edge.targetPort, context.direction, context.rtl);\n const selfLoop = edge.source === edge.target;\n const halfExtent = sideVector(from.side).y !== 0 ? sourceRect.width / 2 : sourceRect.height / 2;\n\n const path = computeEdgePath({\n source: from.point,\n target: to.point,\n sourceSide: from.side,\n targetSide: to.side,\n kind: edge.kind ?? context.edgeKind,\n ...(selfLoop ? { loopSize: Math.ceil(halfExtent / 0.75) + 24 } : {}),\n });\n return { ...path, source: from.point, target: to.point, sourceSide: from.side, targetSide: to.side, selfLoop };\n}\n\n// ------------------------------------------------------- reading order, focus\n\nexport interface ReadingOrderOptions {\n direction?: LayoutDirection;\n rtl?: boolean;\n /** Nodes whose centers are this close along the flow axis share a row. Defaults to 24. */\n tolerance?: number;\n}\n\n/**\n * Node ids in reading order: top to bottom then start to end of the line for a\n * vertical flow, or column by column for a horizontal one. A group comes\n * before its children. This is the order the canvas puts nodes in the DOM, so\n * Tab follows it.\n */\nexport function getReadingOrder(doc: DiagramDocument, options: ReadingOrderOptions = {}): string[] {\n const { direction = \"TB\", rtl = false, tolerance = 24 } = options;\n const index = buildIndex(doc);\n const horizontal = isHorizontal(direction);\n // Primary axis follows the flow; secondary axis follows the page's reading direction.\n const primarySign = direction === \"BT\" || direction === \"RL\" ? -1 : 1;\n const secondarySign = horizontal ? 1 : rtl ? -1 : 1;\n\n const sortSiblings = (ids: string[]): string[] => {\n const entries = ids.map((id) => {\n const node = index.nodesById.get(id) as DiagramNode;\n const c = rectCenter(getNodeBounds(node));\n return { id, p: (horizontal ? c.x : c.y) * primarySign, s: (horizontal ? c.y : c.x) * secondarySign };\n });\n entries.sort((a, b) => a.p - b.p);\n const rows: Array<typeof entries> = [];\n let anchor = -Infinity;\n for (const entry of entries) {\n const row = rows[rows.length - 1];\n if (row && entry.p - anchor <= tolerance) row.push(entry);\n else {\n rows.push([entry]);\n anchor = entry.p;\n }\n }\n return rows.flatMap((row) => row.sort((a, b) => a.s - b.s).map((entry) => entry.id));\n };\n\n const result: string[] = [];\n const visited = new Set<string>();\n const visit = (id: string) => {\n if (visited.has(id)) return;\n visited.add(id);\n result.push(id);\n const kids = index.children.get(id);\n if (kids) for (const child of sortSiblings(kids)) visit(child);\n };\n const roots = doc.nodes\n .filter((node) => node.parentId === undefined || !index.nodesById.has(node.parentId) || node.parentId === node.id)\n .map((node) => node.id);\n for (const id of sortSiblings(roots)) visit(id);\n // Nodes caught in a parent loop still need a place.\n for (const node of doc.nodes) visit(node.id);\n return result;\n}\n\nexport type FocusDirection = \"up\" | \"down\" | \"left\" | \"right\";\n\nconst FOCUS_VECTOR: Record<FocusDirection, Point> = {\n up: { x: 0, y: -1 },\n down: { x: 0, y: 1 },\n left: { x: -1, y: 0 },\n right: { x: 1, y: 0 },\n};\n\n/**\n * The node to move to when an arrow key is pressed on `fromId`. Connected nodes\n * in that direction win; if there is none, the nearest node of any kind in that\n * direction is used. Returns undefined when nothing lies that way.\n */\nexport function findDirectionalNeighbor(\n doc: DiagramDocument,\n fromId: string,\n direction: FocusDirection,\n options: { candidates?: Iterable<string> } = {},\n): string | undefined {\n const index = buildIndex(doc);\n const bounds = getAbsoluteBounds(doc, index);\n const origin = bounds.get(fromId);\n if (!origin) return undefined;\n const from = rectCenter(origin);\n const vector = FOCUS_VECTOR[direction];\n const connected = new Set(getNeighbors(index, fromId));\n const allowed = options.candidates === undefined ? undefined : new Set(options.candidates);\n\n let best: { id: string; score: number; linked: boolean } | undefined;\n for (const node of doc.nodes) {\n if (node.id === fromId || (allowed && !allowed.has(node.id))) continue;\n const rect = bounds.get(node.id);\n if (!rect) continue;\n const delta = sub(rectCenter(rect), from);\n const along = dot(delta, vector);\n const across = Math.abs(delta.x * vector.y - delta.y * vector.x);\n if (along <= 0 || across > along * 2) continue;\n const score = along + across * 2;\n const linked = connected.has(node.id);\n if (!best || (linked && !best.linked) || (linked === best.linked && score < best.score)) {\n best = { id: node.id, score, linked };\n }\n }\n return best?.id;\n}\n","import { checkConnection, type ConnectionRules, type DiagramConnection } from \"./connection\";\nimport { getAbsoluteBounds, getAbsolutePositions, unionRects, type Rect, type Size } from \"./geometry\";\nimport { buildIndex, getAncestors, getDescendants } from \"./graph\";\nimport { createIdAllocator, idStem, nextId } from \"./ids\";\nimport { isContainerKind } from \"./schema\";\nimport type { DiagramDocument, DiagramEdge, DiagramNode, NodeKind, Position } from \"./schema\";\n\nexport type MutationErrorCode =\n | \"duplicate-id\"\n | \"node-not-found\"\n | \"edge-not-found\"\n | \"parent-not-found\"\n | \"parent-not-container\"\n | \"invalid-connection\"\n | \"cannot-group\";\n\n/** Thrown when a mutation is asked to do something that would corrupt the document. */\nexport class DiagramMutationError extends Error {\n readonly code: MutationErrorCode;\n /** For `invalid-connection`: the `ConnectionRejection` code. */\n readonly detail?: string;\n constructor(code: MutationErrorCode, message: string, detail?: string) {\n super(message);\n this.name = \"DiagramMutationError\";\n this.code = code;\n if (detail !== undefined) this.detail = detail;\n }\n}\n\nconst withoutUndefined = <T extends object>(value: T): T => {\n const result = { ...value } as Record<string, unknown>;\n for (const key of Object.keys(result)) if (result[key] === undefined) delete result[key];\n return result as T;\n};\n\n// ------------------------------------------------------------------ nodes\n\nexport type NewNode = Omit<DiagramNode, \"id\" | \"label\" | \"position\"> & {\n id?: string;\n label?: string;\n position?: Position;\n};\n\n/** The id `addNode` would give a new node of this kind. */\nexport function nextNodeId(doc: DiagramDocument, prefix: string = \"node\"): string {\n return nextId(\n doc.nodes.map((node) => node.id),\n prefix,\n );\n}\n\n/** The id `connect` would give a new edge. */\nexport function nextEdgeId(doc: DiagramDocument, prefix: string = \"edge\"): string {\n return nextId(\n doc.edges.map((edge) => edge.id),\n prefix,\n );\n}\n\n/** Builds a complete node with a fresh id, without adding it. */\nexport function createNode(doc: DiagramDocument, input: NewNode): DiagramNode {\n const id = input.id ?? nextNodeId(doc, input.kind);\n return withoutUndefined({\n ...input,\n id,\n label: input.label ?? \"\",\n position: input.position ?? { x: 0, y: 0 },\n }) as DiagramNode;\n}\n\nfunction requireContainer(doc: DiagramDocument, parentId: string): void {\n const parent = doc.nodes.find((node) => node.id === parentId);\n if (!parent) throw new DiagramMutationError(\"parent-not-found\", `Parent node \"${parentId}\" does not exist.`);\n if (!isContainerKind(parent.kind)) {\n throw new DiagramMutationError(\"parent-not-container\", `Node \"${parentId}\" is a ${parent.kind}, not a group or subflow.`);\n }\n}\n\n/** Adds a node. Throws `duplicate-id` if the id exists, or a parent error if `parentId` is not a container. */\nexport function addNode(doc: DiagramDocument, input: NewNode): DiagramDocument {\n const node = createNode(doc, input);\n if (doc.nodes.some((existing) => existing.id === node.id)) {\n throw new DiagramMutationError(\"duplicate-id\", `A node with id \"${node.id}\" already exists.`);\n }\n if (node.parentId !== undefined) requireContainer(doc, node.parentId);\n return { ...doc, nodes: [...doc.nodes, node] };\n}\n\nexport type NodePatch = Partial<Omit<DiagramNode, \"id\">>;\n\n/** Changes a node. The patch can be an object or a function of the current node. Throws `node-not-found`. */\nexport function updateNode(doc: DiagramDocument, id: string, patch: NodePatch | ((node: DiagramNode) => NodePatch)): DiagramDocument {\n const current = doc.nodes.find((node) => node.id === id);\n if (!current) throw new DiagramMutationError(\"node-not-found\", `No node with id \"${id}\".`);\n const resolved = typeof patch === \"function\" ? patch(current) : patch;\n const { ...rest } = resolved as NodePatch & { id?: string };\n delete rest.id;\n if (rest.parentId !== undefined) requireContainer(doc, rest.parentId);\n const next = withoutUndefined({ ...current, ...rest });\n return { ...doc, nodes: doc.nodes.map((node) => (node === current ? next : node)) };\n}\n\nexport interface RemoveOptions {\n /**\n * What happens to the children of a removed group. `release` (default) keeps\n * them and moves them out to the group's parent without changing where they\n * appear; `remove` deletes them too.\n */\n children?: \"release\" | \"remove\";\n}\n\n/** Removes nodes and every edge that touches them. Unknown ids are ignored. */\nexport function removeNodes(doc: DiagramDocument, ids: Iterable<string>, options: RemoveOptions = {}): DiagramDocument {\n const index = buildIndex(doc);\n const removed = new Set<string>();\n for (const id of ids) {\n if (!index.nodesById.has(id)) continue;\n removed.add(id);\n if (options.children === \"remove\") for (const descendant of getDescendants(index, id)) removed.add(descendant);\n }\n if (removed.size === 0) return doc;\n\n const nodes: DiagramNode[] = [];\n for (const node of doc.nodes) {\n if (removed.has(node.id)) continue;\n if (node.parentId !== undefined && removed.has(node.parentId)) {\n // Climb past removed ancestors, adding their offsets so the node stays put.\n let x = node.position.x;\n let y = node.position.y;\n let parentId: string | undefined = node.parentId;\n const seen = new Set<string>();\n while (parentId !== undefined && removed.has(parentId) && !seen.has(parentId)) {\n seen.add(parentId);\n const parent = index.nodesById.get(parentId) as DiagramNode;\n x += parent.position.x;\n y += parent.position.y;\n parentId = parent.parentId;\n }\n const released = { ...node, position: { x, y } } as DiagramNode;\n if (parentId === undefined || removed.has(parentId)) delete released.parentId;\n else released.parentId = parentId;\n nodes.push(released);\n } else {\n nodes.push(node);\n }\n }\n const edges = doc.edges.filter((edge) => !removed.has(edge.source) && !removed.has(edge.target));\n return { ...doc, nodes, edges };\n}\n\n/** Removes a node and its edges. Throws `node-not-found` when the id is unknown. */\nexport function removeNode(doc: DiagramDocument, id: string, options: RemoveOptions = {}): DiagramDocument {\n if (!doc.nodes.some((node) => node.id === id)) throw new DiagramMutationError(\"node-not-found\", `No node with id \"${id}\".`);\n return removeNodes(doc, [id], options);\n}\n\n/** Moves nodes to the given positions (relative to their parents). Unknown ids are ignored. */\nexport function moveNodes(doc: DiagramDocument, positions: Record<string, Position>): DiagramDocument {\n let changed = false;\n const nodes = doc.nodes.map((node) => {\n const next = positions[node.id];\n if (!next || (next.x === node.position.x && next.y === node.position.y)) return node;\n changed = true;\n return { ...node, position: { x: next.x, y: next.y } };\n });\n return changed ? { ...doc, nodes } : doc;\n}\n\n/** Moves nodes by an offset. A group's children move with it, so they are not shifted twice. */\nexport function translateNodes(doc: DiagramDocument, ids: Iterable<string>, dx: number, dy: number): DiagramDocument {\n const wanted = new Set(ids);\n if ((dx === 0 && dy === 0) || wanted.size === 0) return doc;\n const nodes = doc.nodes.map((node) => {\n if (!wanted.has(node.id)) return node;\n return { ...node, position: { x: node.position.x + dx, y: node.position.y + dy } };\n });\n return { ...doc, nodes };\n}\n\n/** Sets a node's size. */\nexport function resizeNode(doc: DiagramDocument, id: string, size: Size, position?: Position): DiagramDocument {\n return updateNode(doc, id, { width: size.width, height: size.height, ...(position ? { position } : {}) });\n}\n\n/**\n * Moves a node into another group (or out to the top level with `undefined`)\n * without changing where it appears.\n */\nexport function setNodeParent(doc: DiagramDocument, id: string, parentId: string | undefined): DiagramDocument {\n const index = buildIndex(doc);\n const node = index.nodesById.get(id);\n if (!node) throw new DiagramMutationError(\"node-not-found\", `No node with id \"${id}\".`);\n if (parentId !== undefined) {\n requireContainer(doc, parentId);\n if (parentId === id || getAncestors(index, parentId).includes(id)) {\n throw new DiagramMutationError(\"cannot-group\", \"A group cannot be moved inside itself.\");\n }\n }\n const absolute = getAbsolutePositions(doc, index);\n const at = absolute.get(id) as Position;\n const base = parentId === undefined ? { x: 0, y: 0 } : (absolute.get(parentId) as Position);\n const next = { ...node, position: { x: at.x - base.x, y: at.y - base.y } } as DiagramNode;\n if (parentId === undefined) delete next.parentId;\n else next.parentId = parentId;\n return { ...doc, nodes: doc.nodes.map((candidate) => (candidate === node ? next : candidate)) };\n}\n\n// ------------------------------------------------------------------ edges\n\nexport type NewEdge = DiagramConnection & Partial<Omit<DiagramEdge, \"source\" | \"target\" | \"sourcePort\" | \"targetPort\">>;\n\nexport interface ConnectOptions extends ConnectionRules {\n /** Skip `checkConnection`. Defaults to true (validate). */\n validate?: boolean;\n}\n\n/**\n * Adds an edge. By default it runs `checkConnection` and throws\n * `invalid-connection` (with the rejection code in `detail`) when the rules\n * refuse it. Pass `{ validate: false }` to add it unconditionally.\n */\nexport function connect(doc: DiagramDocument, input: NewEdge, options: ConnectOptions = {}): DiagramDocument {\n const { validate = true, ...rules } = options;\n if (validate) {\n const check = checkConnection(doc, input, rules);\n if (!check.ok) throw new DiagramMutationError(\"invalid-connection\", check.message, check.code);\n }\n const id = input.id ?? nextEdgeId(doc);\n if (doc.edges.some((edge) => edge.id === id)) {\n throw new DiagramMutationError(\"duplicate-id\", `An edge with id \"${id}\" already exists.`);\n }\n const edge = withoutUndefined({ ...input, id }) as DiagramEdge;\n return { ...doc, edges: [...doc.edges, edge] };\n}\n\n/**\n * Removes an edge by id (throws `edge-not-found` if it does not exist), or all\n * edges between two nodes when given `{ source, target }` (a no-op if none).\n */\nexport function disconnect(doc: DiagramDocument, target: string | DiagramConnection): DiagramDocument {\n if (typeof target === \"string\") {\n if (!doc.edges.some((edge) => edge.id === target)) {\n throw new DiagramMutationError(\"edge-not-found\", `No edge with id \"${target}\".`);\n }\n return { ...doc, edges: doc.edges.filter((edge) => edge.id !== target) };\n }\n const edges = doc.edges.filter(\n (edge) =>\n !(\n edge.source === target.source &&\n edge.target === target.target &&\n (target.sourcePort === undefined || edge.sourcePort === target.sourcePort) &&\n (target.targetPort === undefined || edge.targetPort === target.targetPort)\n ),\n );\n return edges.length === doc.edges.length ? doc : { ...doc, edges };\n}\n\nexport function removeEdges(doc: DiagramDocument, ids: Iterable<string>): DiagramDocument {\n const wanted = new Set(ids);\n if (wanted.size === 0) return doc;\n const edges = doc.edges.filter((edge) => !wanted.has(edge.id));\n return edges.length === doc.edges.length ? doc : { ...doc, edges };\n}\n\nexport type EdgePatch = Partial<Omit<DiagramEdge, \"id\">>;\n\nexport function updateEdge(doc: DiagramDocument, id: string, patch: EdgePatch): DiagramDocument {\n const current = doc.edges.find((edge) => edge.id === id);\n if (!current) throw new DiagramMutationError(\"edge-not-found\", `No edge with id \"${id}\".`);\n const next = withoutUndefined({ ...current, ...patch, id });\n return { ...doc, edges: doc.edges.map((edge) => (edge === current ? next : edge)) };\n}\n\n// ----------------------------------------------------------------- groups\n\nexport interface GroupOptions {\n id?: string;\n label?: string;\n /** `group` (default) or `subflow`. */\n kind?: Extract<NodeKind, \"group\" | \"subflow\">;\n /** Space between the group border and its content. Defaults to 32. */\n padding?: number;\n /** Space reserved for the group title. Defaults to 40. */\n header?: number;\n}\n\n/**\n * Wraps nodes in a new group sized to fit them. The nodes keep their place on\n * the page. They must share one parent; a node whose ancestor is also selected\n * is left alone because it moves with that ancestor. Throws `cannot-group`.\n */\nexport function groupNodes(doc: DiagramDocument, ids: Iterable<string>, options: GroupOptions = {}): DiagramDocument {\n const index = buildIndex(doc);\n const selected = new Set<string>();\n for (const id of ids) if (index.nodesById.has(id)) selected.add(id);\n const members = [...selected].filter((id) => !getAncestors(index, id).some((ancestor) => selected.has(ancestor)));\n if (members.length === 0) throw new DiagramMutationError(\"cannot-group\", \"Select at least one node to group.\");\n\n const parents = new Set(members.map((id) => index.nodesById.get(id)?.parentId));\n if (parents.size > 1) throw new DiagramMutationError(\"cannot-group\", \"Nodes must share the same parent to be grouped.\");\n const parentId = [...parents][0];\n\n const kind = options.kind ?? \"group\";\n const padding = options.padding ?? 32;\n const header = options.header ?? 40;\n const id = options.id ?? nextNodeId(doc, kind);\n if (index.nodesById.has(id)) throw new DiagramMutationError(\"duplicate-id\", `A node with id \"${id}\" already exists.`);\n\n const bounds = getAbsoluteBounds(doc, index);\n const box: Rect = unionRects(members.map((member) => bounds.get(member) as Rect));\n const groupAbsolute = { x: box.x - padding, y: box.y - padding - header };\n const parentAbsolute = parentId === undefined ? { x: 0, y: 0 } : (getAbsolutePositions(doc, index).get(parentId) as Position);\n\n const group: DiagramNode = {\n id,\n kind,\n label: options.label ?? \"\",\n position: { x: groupAbsolute.x - parentAbsolute.x, y: groupAbsolute.y - parentAbsolute.y },\n width: box.width + padding * 2,\n height: box.height + padding * 2 + header,\n };\n if (parentId !== undefined) group.parentId = parentId;\n\n const memberSet = new Set(members);\n const nodes: DiagramNode[] = [];\n let inserted = false;\n for (const node of doc.nodes) {\n if (memberSet.has(node.id)) {\n if (!inserted) {\n nodes.push(group);\n inserted = true;\n }\n const at = bounds.get(node.id) as Rect;\n nodes.push({ ...node, parentId: id, position: { x: at.x - groupAbsolute.x, y: at.y - groupAbsolute.y } });\n } else {\n nodes.push(node);\n }\n }\n return { ...doc, nodes };\n}\n\n/** Dissolves a group: its children move out to the group's parent and the group is removed. */\nexport function ungroupNode(doc: DiagramDocument, groupId: string): DiagramDocument {\n return removeNode(doc, groupId, { children: \"release\" });\n}\n\n// ------------------------------------------------------- copy and paste\n\nexport interface DiagramFragment {\n nodes: DiagramNode[];\n edges: DiagramEdge[];\n}\n\n/**\n * Copies nodes (with all their descendants) and the edges between them. Nodes\n * whose parent is not part of the copy are stored with absolute positions and\n * no parent, so the fragment can be pasted anywhere.\n */\nexport function extractFragment(doc: DiagramDocument, ids: Iterable<string>): DiagramFragment {\n const index = buildIndex(doc);\n const wanted = new Set<string>();\n for (const id of ids) {\n if (!index.nodesById.has(id)) continue;\n wanted.add(id);\n for (const descendant of getDescendants(index, id)) wanted.add(descendant);\n }\n const absolute = getAbsolutePositions(doc, index);\n const nodes: DiagramNode[] = [];\n for (const node of doc.nodes) {\n if (!wanted.has(node.id)) continue;\n if (node.parentId !== undefined && wanted.has(node.parentId)) {\n nodes.push(structuredClone(node));\n } else {\n const copy = structuredClone(node);\n delete copy.parentId;\n const at = absolute.get(node.id) as Position;\n copy.position = { x: at.x, y: at.y };\n nodes.push(copy);\n }\n }\n const edges = doc.edges.filter((edge) => wanted.has(edge.source) && wanted.has(edge.target)).map((edge) => structuredClone(edge));\n return { nodes, edges };\n}\n\nexport interface PasteOptions {\n /** Shift applied to the pasted top-level nodes. Defaults to 24, 24. */\n offset?: Position;\n /** Paste inside this group. Pasted positions are then relative to it. */\n parentId?: string;\n}\n\nexport interface PasteResult {\n document: DiagramDocument;\n /** Ids of every new node, including children. */\n nodeIds: string[];\n /** Ids of the new top-level nodes of the paste. */\n rootIds: string[];\n edgeIds: string[];\n /** Old id to new id. */\n idMap: Record<string, string>;\n}\n\n/** Adds a copy of a fragment with fresh ids. */\nexport function pasteFragment(doc: DiagramDocument, fragment: DiagramFragment, options: PasteOptions = {}): PasteResult {\n const offset = options.offset ?? { x: 24, y: 24 };\n if (options.parentId !== undefined) requireContainer(doc, options.parentId);\n const parentAbsolute =\n options.parentId === undefined ? { x: 0, y: 0 } : (getAbsolutePositions(doc).get(options.parentId) as Position);\n\n const nodeIds = createIdAllocator(doc.nodes.map((node) => node.id));\n const edgeIds = createIdAllocator(doc.edges.map((edge) => edge.id));\n const idMap: Record<string, string> = {};\n for (const node of fragment.nodes) idMap[node.id] = nodeIds.next(idStem(node.id, node.kind));\n\n const fragmentIds = new Set(fragment.nodes.map((node) => node.id));\n const rootIds: string[] = [];\n const nodes = fragment.nodes.map((node) => {\n const copy = structuredClone(node);\n copy.id = idMap[node.id] as string;\n if (node.parentId !== undefined && fragmentIds.has(node.parentId)) {\n copy.parentId = idMap[node.parentId] as string;\n } else {\n delete copy.parentId;\n if (options.parentId !== undefined) copy.parentId = options.parentId;\n copy.position = {\n x: node.position.x + offset.x - parentAbsolute.x,\n y: node.position.y + offset.y - parentAbsolute.y,\n };\n rootIds.push(copy.id);\n }\n return copy;\n });\n const edges = fragment.edges\n .filter((edge) => fragmentIds.has(edge.source) && fragmentIds.has(edge.target))\n .map((edge) => {\n const copy = structuredClone(edge);\n copy.id = edgeIds.next(idStem(edge.id, \"edge\"));\n copy.source = idMap[edge.source] as string;\n copy.target = idMap[edge.target] as string;\n return copy;\n });\n\n return {\n document: { ...doc, nodes: [...doc.nodes, ...nodes], edges: [...doc.edges, ...edges] },\n nodeIds: nodes.map((node) => node.id),\n rootIds,\n edgeIds: edges.map((edge) => edge.id),\n idMap,\n };\n}\n\n/** Copies nodes (and the edges between them) next to the originals. Copies stay in the same group. */\nexport function duplicateNodes(doc: DiagramDocument, ids: Iterable<string>, options: PasteOptions = {}): PasteResult {\n const selected = [...ids];\n const index = buildIndex(doc);\n const fragment = extractFragment(doc, selected);\n const parents = new Set(\n selected.filter((id) => index.nodesById.has(id)).map((id) => index.nodesById.get(id)?.parentId),\n );\n const parentId = parents.size === 1 ? [...parents][0] : undefined;\n return pasteFragment(doc, fragment, { ...(parentId !== undefined ? { parentId } : {}), ...options });\n}\n\n// ----------------------------------------------------- alignment helpers\n\nexport type Alignment = \"left\" | \"center\" | \"right\" | \"top\" | \"middle\" | \"bottom\";\n\nfunction setAbsolute(doc: DiagramDocument, targets: Map<string, Position>): DiagramDocument {\n const absolute = getAbsolutePositions(doc);\n const nodes = doc.nodes.map((node) => {\n const target = targets.get(node.id);\n if (!target) return node;\n const parent = node.parentId === undefined ? undefined : absolute.get(node.parentId);\n return { ...node, position: { x: target.x - (parent?.x ?? 0), y: target.y - (parent?.y ?? 0) } };\n });\n return { ...doc, nodes };\n}\n\n/** Lines nodes up on one edge or center. Needs at least two nodes. */\nexport function alignNodes(doc: DiagramDocument, ids: Iterable<string>, alignment: Alignment): DiagramDocument {\n const bounds = getAbsoluteBounds(doc);\n const rects = [...new Set(ids)].flatMap((id) => {\n const rect = bounds.get(id);\n return rect ? [{ id, rect }] : [];\n });\n if (rects.length < 2) return doc;\n const box = unionRects(rects.map((entry) => entry.rect));\n const targets = new Map<string, Position>();\n for (const { id, rect } of rects) {\n let { x, y } = rect;\n if (alignment === \"left\") x = box.x;\n else if (alignment === \"right\") x = box.x + box.width - rect.width;\n else if (alignment === \"center\") x = box.x + (box.width - rect.width) / 2;\n else if (alignment === \"top\") y = box.y;\n else if (alignment === \"bottom\") y = box.y + box.height - rect.height;\n else y = box.y + (box.height - rect.height) / 2;\n targets.set(id, { x, y });\n }\n return setAbsolute(doc, targets);\n}\n\n/** Spaces three or more nodes so the gaps between them are equal. The outer two stay put. */\nexport function distributeNodes(doc: DiagramDocument, ids: Iterable<string>, axis: \"horizontal\" | \"vertical\"): DiagramDocument {\n const bounds = getAbsoluteBounds(doc);\n const horizontal = axis === \"horizontal\";\n const entries = [...new Set(ids)]\n .flatMap((id) => {\n const rect = bounds.get(id);\n return rect ? [{ id, rect }] : [];\n })\n .sort((a, b) => (horizontal ? a.rect.x - b.rect.x : a.rect.y - b.rect.y));\n if (entries.length < 3) return doc;\n const first = entries[0] as (typeof entries)[number];\n const last = entries[entries.length - 1] as (typeof entries)[number];\n const total = horizontal ? last.rect.x + last.rect.width - first.rect.x : last.rect.y + last.rect.height - first.rect.y;\n const occupied = entries.reduce((sum, entry) => sum + (horizontal ? entry.rect.width : entry.rect.height), 0);\n const gap = (total - occupied) / (entries.length - 1);\n const targets = new Map<string, Position>();\n let cursor = horizontal ? first.rect.x : first.rect.y;\n for (const { id, rect } of entries) {\n targets.set(id, horizontal ? { x: cursor, y: rect.y } : { x: rect.x, y: cursor });\n cursor += (horizontal ? rect.width : rect.height) + gap;\n }\n return setAbsolute(doc, targets);\n}","import { Graph, layout as dagreLayout } from \"@dagrejs/dagre\";\nimport { cluster, hierarchy, tree, type HierarchyNode, type HierarchyPointNode } from \"d3-hierarchy\";\nimport {\n COLLAPSED_HEIGHT,\n GRID_SIZE,\n getNodeSize,\n isHorizontal,\n mirrorDirection,\n snapValue,\n estimateTextWidth,\n unionRects,\n type LayoutDirection,\n type Point,\n type Rect,\n type Size,\n} from \"./geometry\";\nimport { buildIndex } from \"./graph\";\nimport type { DiagramDocument, DiagramNode, Position } from \"./schema\";\n\nexport type { LayoutDirection } from \"./geometry\";\n\nexport type LayoutAlgorithm = \"layered\" | \"tree\" | \"radial\" | \"grid\";\n\nexport interface LayoutSpacing {\n /** Gap between neighbors in the same rank, in diagram units. Defaults to 48. */\n node?: number;\n /** Gap between ranks (levels). Defaults to 80. */\n rank?: number;\n /** Padding between a group's border and its content. Defaults to 32. */\n group?: number;\n}\n\nexport interface LayoutOptions {\n /** `layered` (dagre, default), `tree` (d3-hierarchy), `radial` or `grid`. */\n algorithm?: LayoutAlgorithm;\n /** Flow direction. Defaults to `TB`. Radial layouts ignore it. */\n direction?: LayoutDirection;\n /** Mirror the layout for a right-to-left page: LR becomes RL, and vertical layouts flip left to right. */\n rtl?: boolean;\n /** Spacing in diagram units. A number sets the node gap. */\n spacing?: LayoutSpacing | number;\n /** `tree` and `radial`: the root node id. Defaults to the nodes with no incoming edge. */\n root?: string;\n /** `tree` and `radial`: `tidy` (default) or `cluster`, which puts every leaf on the same level. */\n treeVariant?: \"tidy\" | \"cluster\";\n /** `grid`: items per line. Defaults to the square root of the node count, rounded up. */\n columns?: number;\n /** `layered`: dagre's ranking algorithm. Defaults to `network-simplex`, or to the much faster `tight-tree` on levels with more than ~400 nodes and edges. */\n ranker?: \"network-simplex\" | \"tight-tree\" | \"longest-path\";\n /** Round positions and group sizes to this grid. Defaults to 8; 0 turns rounding off. */\n grid?: number;\n /** Space reserved for a group's title above its content. Defaults to 40. */\n groupHeader?: number;\n /** Where the top-left corner of the whole layout goes. Defaults to 0, 0. */\n origin?: Position;\n}\n\nexport interface LayoutResult {\n /** New `position` for every node (relative to its parent, as in the document). */\n positions: Record<string, Position>;\n /** New size for every group that was fitted around its children. */\n sizes: Record<string, Size>;\n /** Absolute bounds of the laid out diagram. */\n bounds: Rect;\n algorithm: LayoutAlgorithm;\n /** The direction actually used, after right-to-left mirroring. */\n direction: LayoutDirection;\n}\n\ninterface Item {\n id: string;\n width: number;\n height: number;\n}\n\ninterface LevelEdge {\n source: string;\n target: string;\n labelWidth: number;\n labelHeight: number;\n}\n\ninterface Resolved {\n algorithm: LayoutAlgorithm;\n direction: LayoutDirection;\n rtl: boolean;\n nodeSep: number;\n rankSep: number;\n pad: number;\n header: number;\n grid: number;\n options: LayoutOptions;\n}\n\nconst ROOT = \"\\u0000root\";\nconst VIRTUAL = \"\\u0000virtual\";\n\ntype Placement = Map<string, Point>;\n\n/**\n * Computes positions for every node. Deterministic: the same document and\n * options always give the same result. Groups are laid out from the inside out:\n * a group's children are arranged first, the group is sized to fit them, and\n * then the group is placed as one box among its siblings. Edges that cross a\n * group boundary are lifted to the level where both ends are visible.\n *\n * It does not change the document; pass the result to `applyLayout`.\n */\nexport function layoutDiagram(doc: DiagramDocument, options: LayoutOptions = {}): LayoutResult {\n const algorithm = options.algorithm ?? \"layered\";\n const rtl = options.rtl ?? false;\n const direction = mirrorDirection(options.direction ?? \"TB\", rtl);\n const spacing = typeof options.spacing === \"number\" ? { node: options.spacing } : (options.spacing ?? {});\n const resolved: Resolved = {\n algorithm,\n direction,\n rtl,\n nodeSep: spacing.node ?? 48,\n rankSep: spacing.rank ?? 80,\n pad: spacing.group ?? 32,\n header: options.groupHeader ?? 40,\n grid: options.grid ?? GRID_SIZE,\n options,\n };\n\n const index = buildIndex(doc);\n\n // Effective parents: ignore missing parents and break any parent loop.\n const parentOf = new Map<string, string | undefined>();\n for (const node of doc.nodes) {\n let parent = node.parentId !== node.id && node.parentId !== undefined && index.nodesById.has(node.parentId) ? node.parentId : undefined;\n const seen = new Set<string>([node.id]);\n for (let walker = parent; walker !== undefined; walker = index.nodesById.get(walker)?.parentId) {\n if (seen.has(walker)) {\n parent = undefined;\n break;\n }\n seen.add(walker);\n }\n parentOf.set(node.id, parent);\n }\n\n const kidsOf = new Map<string, string[]>();\n for (const node of doc.nodes) {\n const key = parentOf.get(node.id) ?? ROOT;\n const list = kidsOf.get(key);\n if (list) list.push(node.id);\n else kidsOf.set(key, [node.id]);\n }\n\n // Lift every edge to the level where both ends are siblings (or inside sibling groups).\n const pathTo = (id: string): string[] => {\n const chain: string[] = [id];\n for (let p = parentOf.get(id); p !== undefined; p = parentOf.get(p)) chain.push(p);\n return chain.reverse();\n };\n const levelEdges = new Map<string, Map<string, LevelEdge>>();\n for (const edge of doc.edges) {\n if (edge.source === edge.target || !index.nodesById.has(edge.source) || !index.nodesById.has(edge.target)) continue;\n const a = pathTo(edge.source);\n const b = pathTo(edge.target);\n let common = 0;\n while (common < a.length && common < b.length && a[common] === b[common]) common += 1;\n if (common === a.length || common === b.length) continue; // an edge between a group and its own content\n const level = common === 0 ? ROOT : (a[common - 1] as string);\n const ua = a[common] as string;\n const ub = b[common] as string;\n const map = levelEdges.get(level) ?? new Map<string, LevelEdge>();\n levelEdges.set(level, map);\n const key = `${ua}\\u0000${ub}`;\n const existing = map.get(key);\n const labelWidth = edge.label ? estimateTextWidth(edge.label) + 16 : 0;\n const labelHeight = edge.label ? 24 : 0;\n if (existing) {\n existing.labelWidth = Math.max(existing.labelWidth, labelWidth);\n existing.labelHeight = Math.max(existing.labelHeight, labelHeight);\n } else {\n map.set(key, { source: ua, target: ub, labelWidth, labelHeight });\n }\n }\n\n const positions: Record<string, Position> = {};\n const sizes: Record<string, Size> = {};\n const fitted = new Map<string, Size>();\n\n /** Lays out the children of `parent` and returns the size of their bounding box. */\n const layoutLevel = (parent: string): Size => {\n const kids = kidsOf.get(parent) ?? [];\n for (const kid of kids) {\n if (!kidsOf.has(kid)) continue;\n const content = layoutLevel(kid);\n const width = snapUp(content.width + resolved.pad * 2, resolved.grid);\n const height = snapUp(content.height + resolved.pad * 2 + resolved.header, resolved.grid);\n // A collapsed group is placed at its title-bar size, but remembers the size it expands to.\n const collapsed = index.nodesById.get(kid)?.collapsed === true;\n fitted.set(kid, collapsed ? { width, height: COLLAPSED_HEIGHT } : { width, height });\n sizes[kid] = { width, height };\n // Children were placed relative to the content box; move them inside the group's border.\n for (const child of kidsOf.get(kid) ?? []) {\n const at = positions[child] as Position;\n positions[child] = { x: at.x + resolved.pad, y: at.y + resolved.pad + resolved.header };\n }\n }\n\n const items: Item[] = kids.map((id) => {\n const size = fitted.get(id) ?? getNodeSize(index.nodesById.get(id) as DiagramNode);\n return { id, width: size.width, height: size.height };\n });\n const edges = [...(levelEdges.get(parent)?.values() ?? [])];\n\n let placement = place(items, edges, resolved);\n placement = normalize(placement, items, resolved);\n const mirrorX = resolved.rtl && (algorithm === \"radial\" || !isHorizontal(options.direction ?? \"TB\"));\n if (mirrorX) placement = mirror(placement, items);\n placement = normalize(placement, items, resolved);\n\n for (const item of items) {\n const at = placement.get(item.id) as Point;\n positions[item.id] = { x: at.x, y: at.y };\n }\n return extent(placement, items);\n };\n\n layoutLevel(ROOT);\n\n // Top-level nodes start at the origin.\n const origin = options.origin ?? { x: 0, y: 0 };\n for (const id of kidsOf.get(ROOT) ?? []) {\n const at = positions[id] as Position;\n positions[id] = { x: at.x + origin.x, y: at.y + origin.y };\n }\n\n // Absolute bounds.\n const absolute = new Map<string, Point>();\n const resolveAbsolute = (id: string): Point => {\n const known = absolute.get(id);\n if (known) return known;\n const own = positions[id] as Position;\n const parent = parentOf.get(id);\n const base = parent === undefined ? { x: 0, y: 0 } : resolveAbsolute(parent);\n const result = { x: base.x + own.x, y: base.y + own.y };\n absolute.set(id, result);\n return result;\n };\n const rects: Rect[] = [];\n for (const node of doc.nodes) {\n const at = resolveAbsolute(node.id);\n const size = fitted.get(node.id) ?? getNodeSize(node);\n rects.push({ x: at.x, y: at.y, ...size });\n }\n\n return { positions, sizes, bounds: unionRects(rects), algorithm, direction };\n}\n\n/** Writes a layout result into a document: new positions, and fitted sizes for groups. */\nexport function applyLayout(doc: DiagramDocument, result: LayoutResult): DiagramDocument {\n return {\n ...doc,\n nodes: doc.nodes.map((node) => {\n const position = result.positions[node.id];\n const size = result.sizes[node.id];\n if (!position && !size) return node;\n return { ...node, ...(position ? { position: { ...position } } : {}), ...(size ? { width: size.width, height: size.height } : {}) };\n }),\n };\n}\n\n/** Lays out and applies in one step. */\nexport function layoutedDiagram(doc: DiagramDocument, options: LayoutOptions = {}): DiagramDocument {\n return applyLayout(doc, layoutDiagram(doc, options));\n}\n\n// ---------------------------------------------------------------- helpers\n\nfunction snapUp(value: number, grid: number): number {\n return grid > 0 ? Math.ceil(value / grid) * grid : value;\n}\n\nfunction extent(placement: Placement, items: Item[]): Size {\n let width = 0;\n let height = 0;\n for (const item of items) {\n const at = placement.get(item.id) as Point;\n width = Math.max(width, at.x + item.width);\n height = Math.max(height, at.y + item.height);\n }\n return { width, height };\n}\n\n/** Moves the placement so its top-left corner is at 0, 0 and rounds to the grid. */\nfunction normalize(placement: Placement, items: Item[], resolved: Resolved): Placement {\n let minX = Infinity;\n let minY = Infinity;\n for (const item of items) {\n const at = placement.get(item.id) as Point;\n minX = Math.min(minX, at.x);\n minY = Math.min(minY, at.y);\n }\n const result: Placement = new Map();\n for (const item of items) {\n const at = placement.get(item.id) as Point;\n result.set(item.id, {\n x: snapValue(at.x - (minX === Infinity ? 0 : minX), resolved.grid),\n y: snapValue(at.y - (minY === Infinity ? 0 : minY), resolved.grid),\n });\n }\n return result;\n}\n\nfunction mirror(placement: Placement, items: Item[]): Placement {\n let right = 0;\n for (const item of items) right = Math.max(right, (placement.get(item.id) as Point).x + item.width);\n const result: Placement = new Map();\n for (const item of items) {\n const at = placement.get(item.id) as Point;\n result.set(item.id, { x: right - (at.x + item.width), y: at.y });\n }\n return result;\n}\n\nfunction place(items: Item[], edges: LevelEdge[], resolved: Resolved): Placement {\n if (items.length === 0) return new Map();\n switch (resolved.algorithm) {\n case \"tree\":\n return placeTree(items, edges, resolved);\n case \"radial\":\n return placeRadial(items, edges, resolved);\n case \"grid\":\n return placeGrid(items, resolved);\n case \"layered\":\n return placeLayered(items, edges, resolved);\n }\n}\n\n// ---------------------------------------------------------------- layered\n\n/**\n * dagre's network-simplex ranker gives the tidiest ranks but grows steeply with\n * size (1200 nodes take more than ten seconds). Above this many nodes plus\n * edges on one level the default switches to `tight-tree`, which is about ten\n * times faster and almost as compact. An explicit `ranker` always wins.\n */\nconst LARGE_LEVEL = 400;\n\nfunction placeLayered(items: Item[], edges: LevelEdge[], resolved: Resolved): Placement {\n const graph = new Graph();\n const ranker = resolved.options.ranker ?? (items.length + edges.length > LARGE_LEVEL ? \"tight-tree\" : \"network-simplex\");\n graph.setGraph({\n rankdir: resolved.direction,\n nodesep: resolved.nodeSep,\n ranksep: resolved.rankSep,\n edgesep: Math.max(8, Math.round(resolved.nodeSep / 2)),\n marginx: 0,\n marginy: 0,\n ranker,\n });\n graph.setDefaultEdgeLabel(() => ({}));\n // dagre breaks ties in the opposite order to the input, so feed it reversed\n // to keep siblings in document order from the start of the line to its end.\n for (const item of [...items].reverse()) graph.setNode(item.id, { width: item.width, height: item.height });\n for (const edge of [...edges].reverse()) {\n graph.setEdge(\n edge.source,\n edge.target,\n edge.labelWidth > 0 ? { width: edge.labelWidth, height: edge.labelHeight, labelpos: \"c\" } : {},\n );\n }\n dagreLayout(graph);\n\n const placement: Placement = new Map();\n for (const item of items) {\n const laid = graph.node(item.id) as { x: number; y: number } | undefined;\n placement.set(item.id, laid ? { x: laid.x - item.width / 2, y: laid.y - item.height / 2 } : { x: 0, y: 0 });\n }\n return placement;\n}\n\n// ------------------------------------------------------------ tree, radial\n\ninterface TreeData {\n id: string;\n children: TreeData[];\n}\n\n/** Turns a graph into a spanning forest: breadth first from the roots, first parent wins. */\nfunction buildForest(items: Item[], edges: LevelEdge[], rootId: string | undefined): TreeData[] {\n const known = new Set(items.map((item) => item.id));\n const outgoing = new Map<string, string[]>();\n const hasIncoming = new Set<string>();\n for (const edge of edges) {\n const list = outgoing.get(edge.source);\n if (list) list.push(edge.target);\n else outgoing.set(edge.source, [edge.target]);\n hasIncoming.add(edge.target);\n }\n\n const assigned = new Set<string>();\n const forest: TreeData[] = [];\n const grow = (id: string) => {\n if (assigned.has(id)) return;\n assigned.add(id);\n const root: TreeData = { id, children: [] };\n const lookup = new Map<string, TreeData>([[id, root]]);\n const queue = [id];\n for (let head = 0; head < queue.length; head += 1) {\n const current = queue[head] as string;\n const parent = lookup.get(current) as TreeData;\n for (const target of outgoing.get(current) ?? []) {\n if (assigned.has(target)) continue;\n assigned.add(target);\n const child: TreeData = { id: target, children: [] };\n parent.children.push(child);\n lookup.set(target, child);\n queue.push(target);\n }\n }\n forest.push(root);\n };\n\n if (rootId !== undefined && known.has(rootId)) grow(rootId);\n for (const item of items) if (!hasIncoming.has(item.id)) grow(item.id);\n for (const item of items) grow(item.id); // anything left sits on a cycle\n return forest;\n}\n\n/** Builds the spanning tree and runs d3's tidy tree or cluster layout over it. */\nfunction runTreeLayout(\n items: Item[],\n edges: LevelEdge[],\n resolved: Resolved,\n separation: (a: HierarchyNode<TreeData>, b: HierarchyNode<TreeData>) => number,\n): { root: HierarchyPointNode<TreeData>; virtual: boolean } {\n const forest = buildForest(items, edges, resolved.options.root);\n const virtual = forest.length > 1;\n const top: TreeData = virtual ? { id: VIRTUAL, children: forest } : (forest[0] as TreeData);\n const root = hierarchy<TreeData>(top, (d) => d.children);\n const laid =\n resolved.options.treeVariant === \"cluster\"\n ? cluster<TreeData>().nodeSize([1, 1]).separation(separation)(root)\n : tree<TreeData>().nodeSize([1, 1]).separation(separation)(root);\n return { root: laid, virtual };\n}\n\nfunction placeTree(items: Item[], edges: LevelEdge[], resolved: Resolved): Placement {\n const sizes = new Map(items.map((item) => [item.id, item]));\n const horizontal = isHorizontal(resolved.direction);\n const breadthOf = (id: string) => {\n const item = sizes.get(id);\n return item ? (horizontal ? item.height : item.width) : 0;\n };\n const depthExtentOf = (id: string) => {\n const item = sizes.get(id);\n return item ? (horizontal ? item.width : item.height) : 0;\n };\n\n const { root, virtual } = runTreeLayout(\n items,\n edges,\n resolved,\n (a, b) => (breadthOf(a.data.id) + breadthOf(b.data.id)) / 2 + resolved.nodeSep,\n );\n\n const nodes = root.descendants().filter((node) => node.data.id !== VIRTUAL);\n const base = virtual ? 1 : 0;\n const maxDepth = Math.max(0, ...nodes.map((node) => node.depth - base));\n const levelOf = (node: HierarchyPointNode<TreeData>) =>\n resolved.options.treeVariant === \"cluster\" && !node.children ? maxDepth : node.depth - base;\n\n // Each level is as thick as its thickest node, so ranks never overlap.\n const thickness: number[] = Array.from({ length: maxDepth + 1 }, () => 0);\n for (const node of nodes) {\n const level = levelOf(node);\n thickness[level] = Math.max(thickness[level] as number, depthExtentOf(node.data.id));\n }\n const centers: number[] = [];\n let cursor = 0;\n for (const level of thickness) {\n centers.push(cursor + level / 2);\n cursor += level + resolved.rankSep;\n }\n const total = cursor - resolved.rankSep;\n\n const placement: Placement = new Map();\n for (const node of nodes) {\n const item = sizes.get(node.data.id) as Item;\n let along = centers[levelOf(node)] as number;\n if (resolved.direction === \"BT\" || resolved.direction === \"RL\") along = total - along;\n const breadth = node.x;\n const center = horizontal ? { x: along, y: breadth } : { x: breadth, y: along };\n placement.set(item.id, { x: center.x - item.width / 2, y: center.y - item.height / 2 });\n }\n return placement;\n}\n\nfunction placeRadial(items: Item[], edges: LevelEdge[], resolved: Resolved): Placement {\n const sizes = new Map(items.map((item) => [item.id, item]));\n const thick = (id: string) => {\n const item = sizes.get(id);\n return item ? Math.max(item.width, item.height) : 0;\n };\n\n const { root } = runTreeLayout(items, edges, resolved, (a, b) => (a.parent === b.parent ? 1 : 2));\n\n const nodes = root.descendants();\n const xs = nodes.map((node) => node.x);\n const minX = Math.min(...xs);\n const span = Math.max(...xs) - minX;\n const slots = span + 2;\n\n // A ring must be long enough to hold the nodes on it, and far enough from the one inside it.\n const maxDepth = Math.max(...nodes.map((node) => node.depth));\n const widest: number[] = Array.from({ length: maxDepth + 1 }, () => 0);\n for (const node of nodes) widest[node.depth] = Math.max(widest[node.depth] as number, thick(node.data.id));\n const radius: number[] = [0];\n for (let depth = 1; depth <= maxDepth; depth += 1) {\n const previous = radius[depth - 1] as number;\n const current = widest[depth] as number;\n const fromInside = previous + resolved.rankSep + ((widest[depth - 1] as number) + current) / 2;\n const fromCircumference = (slots * (current + resolved.nodeSep)) / (2 * Math.PI);\n radius.push(Math.max(fromInside, fromCircumference));\n }\n\n const placement: Placement = new Map();\n for (const node of nodes) {\n if (node.data.id === VIRTUAL) continue;\n const item = sizes.get(node.data.id) as Item;\n const angle = ((node.x - minX) / slots) * 2 * Math.PI - Math.PI / 2;\n const r = radius[node.depth] as number;\n placement.set(item.id, {\n x: r * Math.cos(angle) - item.width / 2,\n y: r * Math.sin(angle) - item.height / 2,\n });\n }\n return placement;\n}\n\n// ------------------------------------------------------------------- grid\n\nfunction placeGrid(items: Item[], resolved: Resolved): Placement {\n const perLine = Math.max(1, Math.floor(resolved.options.columns ?? Math.ceil(Math.sqrt(items.length))));\n const horizontal = isHorizontal(resolved.direction);\n const lineCount = Math.ceil(items.length / perLine);\n\n // `line` runs across the flow, `slot` runs along a line.\n const at = (i: number) => ({ line: Math.floor(i / perLine), slot: i % perLine });\n const lineThickness: number[] = Array.from({ length: lineCount }, () => 0);\n const slotThickness: number[] = Array.from({ length: perLine }, () => 0);\n items.forEach((item, i) => {\n const { line, slot } = at(i);\n lineThickness[line] = Math.max(lineThickness[line] as number, horizontal ? item.width : item.height);\n slotThickness[slot] = Math.max(slotThickness[slot] as number, horizontal ? item.height : item.width);\n });\n const offsets = (sizes: number[], gap: number) => {\n let cursor = 0;\n return sizes.map((size) => {\n const start = cursor;\n cursor += size + gap;\n return start;\n });\n };\n const lineStart = offsets(lineThickness, resolved.rankSep / 2);\n const slotStart = offsets(slotThickness, resolved.nodeSep);\n const lineTotal = (lineStart[lineCount - 1] ?? 0) + (lineThickness[lineCount - 1] ?? 0);\n const reverseLines = resolved.direction === \"BT\" || resolved.direction === \"RL\";\n\n const placement: Placement = new Map();\n items.forEach((item, i) => {\n const { line, slot } = at(i);\n const thickness = lineThickness[line] as number;\n let along = lineStart[line] as number;\n if (reverseLines) along = lineTotal - along - thickness;\n const across = slotStart[slot] as number;\n placement.set(item.id, horizontal ? { x: along, y: across } : { x: across, y: along });\n });\n return placement;\n}\n","/**\n * Undo and redo as a pure reducer, so it works in a React `useReducer`, in a\n * store, or on a server. States are never mutated.\n */\n\nexport interface HistoryState<T> {\n past: T[];\n present: T;\n future: T[];\n /** The `coalesceKey` of the last `set`, so a run of similar changes becomes one undo step. */\n lastKey?: string;\n}\n\nexport interface HistoryOptions {\n /** The most undo steps to keep. Defaults to 100. */\n limit?: number;\n}\n\nexport type HistoryAction<T> =\n | {\n type: \"set\";\n value: T;\n /**\n * Changes with the same key in a row share one undo step, for example\n * every keystroke while renaming a node.\n */\n coalesceKey?: string;\n }\n | { type: \"undo\" }\n | { type: \"redo\" }\n /** Replace the present and forget the past and future. */\n | { type: \"reset\"; value: T }\n /** Forget the past and future, keeping the present. */\n | { type: \"clear\" };\n\nexport function createHistory<T>(initial: T): HistoryState<T> {\n return { past: [], present: initial, future: [] };\n}\n\nexport function canUndo<T>(state: HistoryState<T>): boolean {\n return state.past.length > 0;\n}\n\nexport function canRedo<T>(state: HistoryState<T>): boolean {\n return state.future.length > 0;\n}\n\nexport function historyReducer<T>(state: HistoryState<T>, action: HistoryAction<T>, options: HistoryOptions = {}): HistoryState<T> {\n const limit = Math.max(1, options.limit ?? 100);\n\n switch (action.type) {\n case \"set\": {\n if (Object.is(action.value, state.present)) return state;\n if (action.coalesceKey !== undefined && action.coalesceKey === state.lastKey) {\n return { past: state.past, present: action.value, future: [], lastKey: action.coalesceKey };\n }\n const past = [...state.past, state.present];\n if (past.length > limit) past.splice(0, past.length - limit);\n const next: HistoryState<T> = { past, present: action.value, future: [] };\n if (action.coalesceKey !== undefined) next.lastKey = action.coalesceKey;\n return next;\n }\n case \"undo\": {\n const previous = state.past[state.past.length - 1];\n if (state.past.length === 0 || previous === undefined) return state;\n return { past: state.past.slice(0, -1), present: previous, future: [state.present, ...state.future] };\n }\n case \"redo\": {\n const next = state.future[0];\n if (state.future.length === 0 || next === undefined) return state;\n return { past: [...state.past, state.present], present: next, future: state.future.slice(1) };\n }\n case \"reset\":\n return createHistory(action.value);\n case \"clear\":\n return createHistory(state.present);\n }\n}\n","import type { DiagramDocument } from \"./schema\";\r\n\r\nexport interface OutlineOptions {\r\n /** Joins labels along a path. Pass a translated word. Defaults to \"to\". */\r\n connector?: string;\r\n /** Stop after this many paths so a dense graph cannot flood the outline. */\r\n maxPaths?: number;\r\n}\r\n\r\n/**\r\n * Generates the text outline that makes a diagram readable by screen readers:\r\n * one line per path through the graph, such as \"Start to Review to Approve\".\r\n * Nodes with no connections get a line of their own, and a path that loops back\r\n * ends with the node it returns to.\r\n */\r\nexport function diagramToOutline(\r\n diagram: DiagramDocument,\r\n { connector = \"to\", maxPaths = 100 }: OutlineOptions = {},\r\n): string[] {\r\n const labels = new Map(diagram.nodes.map((node) => [node.id, node.label]));\r\n const outgoing = new Map<string, string[]>();\r\n const hasIncoming = new Set<string>();\r\n\r\n for (const edge of diagram.edges) {\r\n if (!labels.has(edge.source) || !labels.has(edge.target)) continue;\r\n outgoing.set(edge.source, [...(outgoing.get(edge.source) ?? []), edge.target]);\r\n hasIncoming.add(edge.target);\r\n }\r\n\r\n const lines: string[] = [];\r\n const visited = new Set<string>();\r\n const label = (id: string) => labels.get(id) ?? id;\r\n const sentence = (ids: string[]) => ids.map(label).join(` ${connector} `);\r\n\r\n /** `trail` holds the ids on the path so far, not including `id`. */\r\n const walk = (id: string, trail: string[]) => {\r\n if (lines.length >= maxPaths) return;\r\n visited.add(id);\r\n const path = [...trail, id];\r\n const next = outgoing.get(id) ?? [];\r\n\r\n if (next.length === 0) {\r\n lines.push(sentence(path));\r\n return;\r\n }\r\n\r\n for (const target of next) {\r\n if (path.includes(target)) lines.push(sentence([...path, target]));\r\n else walk(target, path);\r\n }\r\n };\r\n\r\n for (const node of diagram.nodes) {\r\n if (!hasIncoming.has(node.id)) walk(node.id, []);\r\n }\r\n\r\n // Anything left over sits on a cycle with no entry point.\r\n for (const node of diagram.nodes) {\r\n if (!visited.has(node.id)) walk(node.id, []);\r\n }\r\n\r\n return lines;\r\n}\r\n","import { getReadingOrder, type LayoutDirection } from \"./geometry\";\nimport { buildIndex } from \"./graph\";\nimport type { DiagramDocument, DiagramNode, NodeKind, NodeStatus } from \"./schema\";\n\nexport interface OutlineConnection {\n edgeId: string;\n /** The node at the other end. */\n nodeId: string;\n /** That node's label. */\n label: string;\n /** The edge's own label, if it has one (for example \"yes\" or \"no\"). */\n edgeLabel?: string;\n}\n\n/** One node of the structured outline. Groups hold their children in `children`. */\nexport interface OutlineItem {\n id: string;\n label: string;\n kind: NodeKind;\n status?: NodeStatus;\n description?: string;\n /** Edges that arrive at this node, with the node each comes from. */\n incoming: OutlineConnection[];\n /** Edges that leave this node, with the node each goes to. */\n outgoing: OutlineConnection[];\n children: OutlineItem[];\n}\n\nexport interface OutlineTreeOptions {\n /** Orders siblings the way the canvas orders Tab stops. Defaults to `TB`. */\n direction?: LayoutDirection;\n rtl?: boolean;\n}\n\n/**\n * The structured counterpart of `diagramToOutline`: every node once, nested\n * by group, in reading order, each with the nodes it connects to and from.\n * The `DiagramOutline` component renders it as a nested list.\n */\nexport function diagramToOutlineTree(doc: DiagramDocument, options: OutlineTreeOptions = {}): OutlineItem[] {\n const index = buildIndex(doc);\n const order = getReadingOrder(doc, {\n ...(options.direction === undefined ? {} : { direction: options.direction }),\n ...(options.rtl === undefined ? {} : { rtl: options.rtl }),\n });\n\n const items = new Map<string, OutlineItem>();\n for (const id of order) {\n const node = index.nodesById.get(id) as DiagramNode;\n const item: OutlineItem = {\n id,\n label: node.label,\n kind: node.kind,\n incoming: (index.incoming.get(id) ?? []).map((edge) => connection(edge.id, edge.source, edge.label)),\n outgoing: (index.outgoing.get(id) ?? []).map((edge) => connection(edge.id, edge.target, edge.label)),\n children: [],\n };\n if (node.status !== undefined) item.status = node.status;\n if (node.description !== undefined) item.description = node.description;\n items.set(id, item);\n }\n\n function connection(edgeId: string, nodeId: string, edgeLabel: string | undefined): OutlineConnection {\n const result: OutlineConnection = { edgeId, nodeId, label: index.nodesById.get(nodeId)?.label ?? nodeId };\n if (edgeLabel !== undefined && edgeLabel !== \"\") result.edgeLabel = edgeLabel;\n return result;\n }\n\n const roots: OutlineItem[] = [];\n const position = new Map(order.map((id, i) => [id, i]));\n for (const id of order) {\n const item = items.get(id) as OutlineItem;\n const parent = index.nodesById.get(id)?.parentId;\n const parentItem = parent === undefined || parent === id ? undefined : items.get(parent);\n // A parent normally precedes its children in reading order; a parent loop is flattened to the top level.\n if (parentItem && (position.get(parent as string) ?? Infinity) < (position.get(id) ?? 0)) parentItem.children.push(item);\n else roots.push(item);\n }\n return roots;\n}\n\n/** What a screen reader needs to name a node: its kind, label and how many connections it has. */\nexport interface NodeSummary {\n id: string;\n kind: NodeKind;\n label: string;\n incoming: number;\n outgoing: number;\n status?: NodeStatus;\n description?: string;\n}\n\n/** Summaries for every node, keyed by id. Cheap to build once per render. */\nexport function summarizeNodes(doc: DiagramDocument): Map<string, NodeSummary> {\n const index = buildIndex(doc);\n const result = new Map<string, NodeSummary>();\n for (const node of doc.nodes) {\n const summary: NodeSummary = {\n id: node.id,\n kind: node.kind,\n label: node.label,\n incoming: index.incoming.get(node.id)?.length ?? 0,\n outgoing: index.outgoing.get(node.id)?.length ?? 0,\n };\n if (node.status !== undefined) summary.status = node.status;\n if (node.description !== undefined) summary.description = node.description;\n result.set(node.id, summary);\n }\n return result;\n}\n","import { cssVar } from \"@x12i/tokens\";\nimport {\n createGeometryContext,\n estimateTextWidth,\n getEdgeGeometry,\n rectCenter,\n unionRects,\n wrapText,\n TEXT_METRICS,\n type EdgeGeometry,\n type LayoutDirection,\n type Point,\n type Rect,\n} from \"./geometry\";\nimport { getAncestors } from \"./graph\";\nimport { diagramToOutline } from \"./outline\";\nimport { isContainerKind } from \"./schema\";\nimport type { DiagramDocument, DiagramEdge, DiagramNode, EdgeKind, NodeStatus } from \"./schema\";\n\n// ------------------------------------------------------------ palette\n\nexport interface StatusPalette {\n background: string;\n foreground: string;\n border: string;\n}\n\n/**\n * The colors a static diagram uses. Every default is a `var(--kit-...)`\n * reference, so the SVG follows the theme of the page it is placed in. To save\n * a diagram as a stand-alone file, pass resolved colors (the React entry's\n * `readDiagramPalette` reads them from the DOM).\n */\nexport interface DiagramPalette {\n surface: string;\n canvas: string;\n text: string;\n textMuted: string;\n textInverse: string;\n /** Node outlines. */\n border: string;\n /** Soft separators, such as the table header rule. */\n borderSubtle: string;\n /** Edges. Keeps 3:1 against the surface. */\n edge: string;\n accent: string;\n accentSubtle: string;\n onAccent: string;\n inverse: string;\n status: Record<NodeStatus, StatusPalette>;\n fontSans: string;\n fontMono: string;\n}\n\nexport type DiagramPaletteOverride = Partial<Omit<DiagramPalette, \"status\">> & {\n status?: Partial<Record<NodeStatus, Partial<StatusPalette>>>;\n};\n\nexport const defaultPalette: DiagramPalette = {\n surface: cssVar(\"color.bg.surface\"),\n canvas: cssVar(\"color.bg.canvas\"),\n text: cssVar(\"color.text.primary\"),\n textMuted: cssVar(\"color.text.secondary\"),\n textInverse: cssVar(\"color.text.inverse\"),\n border: cssVar(\"color.border.default\"),\n borderSubtle: cssVar(\"color.border.subtle\"),\n edge: cssVar(\"color.border.strong\"),\n accent: cssVar(\"color.accent.default\"),\n accentSubtle: cssVar(\"color.accent.subtle\"),\n onAccent: cssVar(\"color.accent.on-accent\"),\n inverse: cssVar(\"color.bg.inverse\"),\n status: {\n neutral: {\n background: cssVar(\"color.bg.surface\"),\n foreground: cssVar(\"color.text.primary\"),\n border: cssVar(\"color.border.default\"),\n },\n success: {\n background: cssVar(\"color.status.success.background\"),\n foreground: cssVar(\"color.status.success.foreground\"),\n border: cssVar(\"color.status.success.border\"),\n },\n warning: {\n background: cssVar(\"color.status.warning.background\"),\n foreground: cssVar(\"color.status.warning.foreground\"),\n border: cssVar(\"color.status.warning.border\"),\n },\n danger: {\n background: cssVar(\"color.status.danger.background\"),\n foreground: cssVar(\"color.status.danger.foreground\"),\n border: cssVar(\"color.status.danger.border\"),\n },\n info: {\n background: cssVar(\"color.status.info.background\"),\n foreground: cssVar(\"color.status.info.foreground\"),\n border: cssVar(\"color.status.info.border\"),\n },\n },\n fontSans: cssVar(\"font.family.sans\"),\n fontMono: cssVar(\"font.family.mono\"),\n};\n\nexport function resolvePalette(override?: DiagramPaletteOverride): DiagramPalette {\n if (!override) return defaultPalette;\n const status = { ...defaultPalette.status };\n for (const key of Object.keys(override.status ?? {}) as NodeStatus[]) {\n status[key] = { ...defaultPalette.status[key], ...override.status?.[key] };\n }\n const rest = { ...override };\n delete rest.status;\n return { ...defaultPalette, ...rest, status };\n}\n\n// ------------------------------------------------------- element tree\n\nexport type SvgAttributes = Record<string, string | number | undefined>;\n\n/**\n * A tiny immutable tree of SVG elements. The string serializer and the React\n * `StaticDiagram` both render from it, so they draw the same picture and\n * nothing is ever injected as raw markup.\n */\nexport interface SvgElement {\n tag: string;\n attrs?: SvgAttributes;\n /** CSS declarations, written as the `style` attribute. */\n style?: Record<string, string>;\n /** Child elements and text. Text is escaped when serialized. */\n children?: Array<SvgElement | string>;\n}\n\n// eslint-disable-next-line no-control-regex\nconst XML_INVALID = /[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\uFFFE\\uFFFF]/g;\n\nexport function escapeXml(text: string): string {\n return text\n .replace(XML_INVALID, \"\")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/** Serializes an element tree to an SVG string. Text and attribute values are escaped. */\nexport function serializeSvg(element: SvgElement): string {\n const attrs = Object.entries(element.attrs ?? {})\n .filter((entry): entry is [string, string | number] => entry[1] !== undefined)\n .map(([name, value]) => ` ${name}=\"${escapeXml(String(value))}\"`)\n .join(\"\");\n const style =\n element.style && Object.keys(element.style).length > 0\n ? ` style=\"${escapeXml(\n Object.entries(element.style)\n .map(([name, value]) => `${name}:${value}`)\n .join(\";\"),\n )}\"`\n : \"\";\n const children = element.children ?? [];\n if (children.length === 0) return `<${element.tag}${attrs}${style}/>`;\n const inner = children.map((child) => (typeof child === \"string\" ? escapeXml(child) : serializeSvg(child))).join(\"\");\n return `<${element.tag}${attrs}${style}>${inner}</${element.tag}>`;\n}\n\nconst el = (\n tag: string,\n attrs?: SvgAttributes,\n style?: Record<string, string>,\n children?: Array<SvgElement | string>,\n): SvgElement => {\n const element: SvgElement = { tag };\n if (attrs) element.attrs = attrs;\n if (style) element.style = style;\n if (children) element.children = children;\n return element;\n};\n\nconst num = (value: number): number => Math.round(value * 100) / 100;\n\n// -------------------------------------------------------------- options\n\nexport interface SvgOptions {\n /** Flow direction, which decides where edges attach. Defaults to `TB`. */\n direction?: LayoutDirection;\n /** Right-to-left page: mirrors port order and aligns text to the right. */\n rtl?: boolean;\n /** Edge style for edges that do not set one. Defaults to `smooth-step`. */\n edgeKind?: EdgeKind;\n /** Space around the diagram, in diagram units. Defaults to 24. */\n padding?: number;\n palette?: DiagramPaletteOverride;\n /** Prefix for generated element ids. Defaults to `kit-diagram`. Use a unique one when several diagrams share a page. */\n idPrefix?: string;\n /** Accessible title. Defaults to the document title. */\n title?: string;\n /** Accessible description. Defaults to the text outline of the diagram. */\n description?: string;\n /** Joins labels in the default description (\"A to B\"). Pass a translated word. */\n connector?: string;\n /** Language of the text, as a BCP 47 tag. */\n lang?: string;\n /** Width of the `<svg>` element. Omit to let it size from its container. */\n width?: number | string;\n height?: number | string;\n /** Node ids to draw with the accent color: \"one accent marks the path or node the diagram is about\". */\n highlight?: Iterable<string>;\n /** Draw edge labels. Defaults to true. */\n showEdgeLabels?: boolean;\n /** Add the XML declaration, for saving as a `.svg` file. */\n standalone?: boolean;\n}\n\nconst SAFE_IMAGE = /^(?:https?:\\/\\/|data:image\\/(?:png|gif|jpe?g|webp|avif);base64,)/i;\n\n/**\n * True for an image address a diagram may load: http(s) and raster `data:`\n * URLs. Everything else (`javascript:`, `file:`, SVG data URLs, relative paths)\n * is refused, because a diagram document is data that may come from anyone.\n */\nexport function isSafeImageUrl(value: unknown): value is string {\n return typeof value === \"string\" && SAFE_IMAGE.test(value);\n}\n\nfunction dataText(node: DiagramNode, key: string): string | undefined {\n const value = node.data?.[key];\n return typeof value === \"string\" && value !== \"\" ? value : undefined;\n}\n\ninterface Colors {\n fill: string;\n stroke: string;\n text: string;\n}\n\n/** Builds the SVG element tree for a document. */\nexport function diagramToSvgTree(doc: DiagramDocument, options: SvgOptions = {}): SvgElement {\n const palette = resolvePalette(options.palette);\n const prefix = options.idPrefix ?? \"kit-diagram\";\n const padding = options.padding ?? 24;\n const rtl = options.rtl ?? false;\n const highlight = new Set(options.highlight ?? []);\n const showEdgeLabels = options.showEdgeLabels ?? true;\n\n const ctx = createGeometryContext(doc, {\n ...(options.direction === undefined ? {} : { direction: options.direction }),\n rtl,\n ...(options.edgeKind === undefined ? {} : { edgeKind: options.edgeKind }),\n });\n\n // A node is hidden when any ancestor is collapsed.\n const hidden = new Set<string>();\n for (const node of doc.nodes) {\n if (getAncestors(ctx.index, node.id).some((id) => ctx.index.nodesById.get(id)?.collapsed === true)) hidden.add(node.id);\n }\n const visibleNodes = doc.nodes.filter((node) => !hidden.has(node.id));\n\n const edges: Array<{ edge: DiagramEdge; geometry: EdgeGeometry }> = [];\n for (const edge of doc.edges) {\n if (hidden.has(edge.source) || hidden.has(edge.target)) continue;\n const geometry = getEdgeGeometry(ctx, edge);\n if (geometry) edges.push({ edge, geometry });\n }\n\n // Bounds: nodes, edge paths and label boxes.\n const rects: Rect[] = visibleNodes.map((node) => ctx.bounds.get(node.id) as Rect);\n for (const { edge, geometry } of edges) {\n for (const point of geometry.points) rects.push({ x: point.x, y: point.y, width: 0, height: 0 });\n if (showEdgeLabels && edge.label) {\n const width = estimateTextWidth(edge.label) + 16;\n rects.push({ x: geometry.label.x - width / 2, y: geometry.label.y - 12, width, height: 24 });\n }\n }\n const box = unionRects(rects);\n const view: Rect =\n rects.length === 0\n ? { x: 0, y: 0, width: 160, height: 80 }\n : { x: box.x - padding, y: box.y - padding, width: box.width + padding * 2, height: box.height + padding * 2 };\n\n // Markers: one arrowhead per color in use.\n const tones = new Set<string>([\"neutral\"]);\n for (const { edge } of edges) tones.add(edge.status ?? \"neutral\");\n const markerId = (tone: string) => `${prefix}-arrow-${tone}`;\n const markerColor = (tone: string) => (tone === \"neutral\" ? palette.edge : palette.status[tone as NodeStatus].border);\n const defs = el(\n \"defs\",\n undefined,\n undefined,\n [...tones].map((tone) =>\n el(\n \"marker\",\n {\n id: markerId(tone),\n viewBox: \"0 0 10 10\",\n markerWidth: 8,\n markerHeight: 8,\n refX: 9,\n refY: 5,\n orient: \"auto-start-reverse\",\n markerUnits: \"userSpaceOnUse\",\n },\n undefined,\n [el(\"path\", { d: \"M 0 0 L 10 5 L 0 10 z\" }, { fill: markerColor(tone) })],\n ),\n ),\n );\n\n // Draw order: groups (outermost first), then edges, then the rest in document order.\n const depth = (node: DiagramNode) => getAncestors(ctx.index, node.id).length;\n const containers = visibleNodes.filter((node) => isContainerKind(node.kind)).sort((a, b) => depth(a) - depth(b));\n const others = visibleNodes.filter((node) => !isContainerKind(node.kind));\n\n const colorsFor = (node: DiagramNode): Colors => {\n if (node.status !== undefined && node.status !== \"neutral\") {\n const tone = palette.status[node.status];\n return { fill: tone.background, stroke: tone.border, text: tone.foreground };\n }\n switch (node.kind) {\n case \"start\":\n return { fill: palette.accentSubtle, stroke: palette.accent, text: palette.text };\n case \"end\":\n return { fill: palette.inverse, stroke: palette.inverse, text: palette.textInverse };\n case \"note\": {\n const tone = palette.status.warning;\n return { fill: tone.background, stroke: tone.border, text: tone.foreground };\n }\n case \"agent\":\n return { fill: palette.accentSubtle, stroke: palette.accent, text: palette.text };\n case \"group\":\n case \"subflow\":\n return { fill: \"none\", stroke: palette.border, text: palette.textMuted };\n default:\n return { fill: palette.surface, stroke: palette.border, text: palette.text };\n }\n };\n\n const strokeWidth = (node: DiagramNode) =>\n highlight.has(node.id) || node.kind === \"end\" ? cssVar(\"border.width.emphasis\") : cssVar(\"border.width.default\");\n\n const textLines = (\n lines: string[],\n center: Point,\n colors: Colors,\n extra: Record<string, string> = {},\n ): SvgElement[] => {\n const lineHeight = TEXT_METRICS.lineHeight;\n const startY = center.y - ((lines.length - 1) * lineHeight) / 2;\n return lines.map((line, i) =>\n el(\n \"text\",\n {\n x: num(center.x),\n y: num(startY + i * lineHeight),\n \"text-anchor\": \"middle\",\n \"dominant-baseline\": \"central\",\n ...(rtl ? { direction: \"rtl\" } : {}),\n },\n { fill: colors.text, ...extra },\n [line],\n ),\n );\n };\n\n const startText = (\n text: string,\n rect: Rect,\n y: number,\n fill: string,\n extra: Record<string, string> = {},\n padX: number = 12,\n ): SvgElement =>\n el(\n \"text\",\n {\n x: num(rtl ? rect.x + rect.width - padX : rect.x + padX),\n y: num(y),\n \"text-anchor\": \"start\",\n \"dominant-baseline\": \"central\",\n ...(rtl ? { direction: \"rtl\" } : {}),\n },\n { fill, ...extra },\n [text],\n );\n\n const nodeElement = (node: DiagramNode): SvgElement => {\n const rect = ctx.bounds.get(node.id) as Rect;\n const colors = colorsFor(node);\n const center = rectCenter(rect);\n const accent = highlight.has(node.id);\n const shapeStyle = {\n fill: colors.fill,\n stroke: accent ? palette.accent : colors.stroke,\n \"stroke-width\": strokeWidth(node),\n };\n const children: SvgElement[] = [];\n const geometry = (x: number, y: number, w: number, h: number) => ({ x: num(x), y: num(y), width: num(w), height: num(h) });\n\n switch (node.kind) {\n case \"start\":\n case \"end\":\n children.push(el(\"rect\", { ...geometry(rect.x, rect.y, rect.width, rect.height), rx: num(rect.height / 2) }, shapeStyle));\n children.push(...textLines(wrapText(node.label, rect.width - 32), center, colors));\n break;\n case \"decision\": {\n const { x, y, width, height } = rect;\n const points = [`${num(x + width / 2)},${num(y)}`, `${num(x + width)},${num(y + height / 2)}`, `${num(x + width / 2)},${num(y + height)}`, `${num(x)},${num(y + height / 2)}`].join(\" \");\n children.push(el(\"polygon\", { points }, { ...shapeStyle, \"stroke-linejoin\": \"round\" }));\n children.push(...textLines(wrapText(node.label, width * 0.5), center, colors));\n break;\n }\n case \"note\": {\n const fold = 16;\n const { x, y, width, height } = rect;\n const d = `M ${num(x)} ${num(y)} H ${num(x + width - fold)} L ${num(x + width)} ${num(y + fold)} V ${num(y + height)} H ${num(x)} Z`;\n children.push(el(\"path\", { d }, shapeStyle));\n children.push(\n el(\"path\", { d: `M ${num(x + width - fold)} ${num(y)} V ${num(y + fold)} H ${num(x + width)}` }, { fill: \"none\", stroke: shapeStyle.stroke, \"stroke-width\": strokeWidth(node) }),\n );\n children.push(...textLines(wrapText(node.label, width - 32), center, colors));\n break;\n }\n case \"group\":\n case \"subflow\": {\n children.push(\n el(\"rect\", { ...geometry(rect.x, rect.y, rect.width, rect.height), rx: 8 }, {\n ...shapeStyle,\n \"stroke-dasharray\": node.kind === \"group\" ? \"6 4\" : \"none\",\n }),\n );\n children.push(startText(node.label, rect, rect.y + 20, colors.text, { \"font-weight\": \"600\" }));\n break;\n }\n case \"entity\": {\n const fields = Array.isArray(node.data?.fields) ? (node.data?.fields as unknown[]) : [];\n children.push(el(\"rect\", { ...geometry(rect.x, rect.y, rect.width, rect.height), rx: 6 }, shapeStyle));\n children.push(\n el(\"path\", { d: `M ${num(rect.x)} ${num(rect.y + 32)} H ${num(rect.x + rect.width)}` }, { fill: \"none\", stroke: palette.borderSubtle }),\n );\n children.push(startText(node.label, rect, rect.y + 16, colors.text, { \"font-weight\": \"600\" }));\n fields.forEach((field, i) => {\n const name = typeof field === \"string\" ? field : String((field as { name?: unknown } | null)?.name ?? \"\");\n const type = typeof field === \"object\" && field !== null ? String((field as { type?: unknown }).type ?? \"\") : \"\";\n const y = rect.y + 32 + 12 + i * 24;\n children.push(startText(name, rect, y, colors.text));\n if (type !== \"\") {\n children.push(\n el(\n \"text\",\n {\n x: num(rtl ? rect.x + 12 : rect.x + rect.width - 12),\n y: num(y),\n \"text-anchor\": \"end\",\n \"dominant-baseline\": \"central\",\n ...(rtl ? { direction: \"rtl\" } : {}),\n },\n { fill: palette.textMuted },\n [type],\n ),\n );\n }\n });\n break;\n }\n case \"code\": {\n const code = dataText(node, \"code\") ?? \"\";\n children.push(el(\"rect\", { ...geometry(rect.x, rect.y, rect.width, rect.height), rx: 6 }, { ...shapeStyle, fill: palette.canvas }));\n children.push(startText(node.label, rect, rect.y + 16, palette.textMuted, { \"font-size\": cssVar(\"text.caption.size\") }));\n code\n .split(/\\r?\\n/)\n .slice(0, 12)\n .forEach((line, i) => {\n children.push(\n el(\n \"text\",\n {\n x: num(rect.x + 12),\n y: num(rect.y + 40 + i * TEXT_METRICS.lineHeight + 10),\n \"text-anchor\": \"start\",\n \"dominant-baseline\": \"central\",\n direction: \"ltr\",\n },\n { fill: palette.text, \"font-family\": palette.fontMono, \"font-size\": cssVar(\"text.code.size\"), \"white-space\": \"pre\" },\n [line],\n ),\n );\n });\n break;\n }\n case \"image\": {\n children.push(el(\"rect\", { ...geometry(rect.x, rect.y, rect.width, rect.height), rx: 6 }, shapeStyle));\n const src = dataText(node, \"src\");\n if (isSafeImageUrl(src)) {\n children.push(\n el(\"image\", {\n href: src,\n ...geometry(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 28),\n preserveAspectRatio: \"xMidYMid slice\",\n }),\n );\n } else {\n // A simple landscape glyph stands in for the picture.\n const gx = rect.x + rect.width / 2;\n const gy = rect.y + (rect.height - 24) / 2;\n children.push(\n el(\"path\", { d: `M ${num(gx - 20)} ${num(gy + 12)} L ${num(gx - 6)} ${num(gy - 6)} L ${num(gx + 4)} ${num(gy + 6)} L ${num(gx + 10)} ${num(gy)} L ${num(gx + 20)} ${num(gy + 12)} Z` }, { fill: \"none\", stroke: palette.textMuted, \"stroke-width\": cssVar(\"border.width.default\"), \"stroke-linejoin\": \"round\" }),\n );\n }\n children.push(...textLines([node.label], { x: center.x, y: rect.y + rect.height - 14 }, colors));\n break;\n }\n case \"chart\": {\n children.push(el(\"rect\", { ...geometry(rect.x, rect.y, rect.width, rect.height), rx: 6 }, shapeStyle));\n const baseY = rect.y + rect.height - 40;\n [0.4, 0.7, 0.55, 0.9].forEach((ratio, i) => {\n const h = (rect.height - 64) * ratio;\n children.push(el(\"rect\", geometry(rect.x + 24 + i * 24, baseY - h, 16, h), { fill: palette.accent }));\n });\n children.push(...textLines([node.label], { x: center.x, y: rect.y + rect.height - 16 }, colors));\n break;\n }\n case \"agent\": {\n children.push(el(\"rect\", { ...geometry(rect.x, rect.y, rect.width, rect.height), rx: 12 }, shapeStyle));\n const cx = rtl ? rect.x + rect.width - 28 : rect.x + 28;\n children.push(el(\"circle\", { cx: num(cx), cy: num(center.y), r: 12 }, { fill: palette.accent }));\n const role = dataText(node, \"role\");\n const textX = rtl ? rect.x + rect.width - 52 : rect.x + 52;\n const anchor = { \"text-anchor\": \"start\", \"dominant-baseline\": \"central\", ...(rtl ? { direction: \"rtl\" } : {}) };\n children.push(\n el(\"text\", { x: num(textX), y: num(role ? center.y - 9 : center.y), ...anchor }, { fill: colors.text, \"font-weight\": \"600\" }, [node.label]),\n );\n if (role) {\n children.push(\n el(\"text\", { x: num(textX), y: num(center.y + 11), ...anchor }, { fill: palette.textMuted, \"font-size\": cssVar(\"text.caption.size\") }, [role]),\n );\n }\n break;\n }\n default: {\n children.push(el(\"rect\", { ...geometry(rect.x, rect.y, rect.width, rect.height), rx: 6 }, shapeStyle));\n children.push(...textLines(wrapText(node.label, rect.width - 32), center, colors));\n }\n }\n\n return el(\"g\", { \"data-node-id\": node.id, \"data-kind\": node.kind, ...(node.status ? { \"data-status\": node.status } : {}) }, undefined, children);\n };\n\n const edgeElement = ({ edge, geometry }: { edge: DiagramEdge; geometry: EdgeGeometry }): SvgElement => {\n const tone = edge.status ?? \"neutral\";\n const color = markerColor(tone);\n const children: SvgElement[] = [\n el(\n \"path\",\n {\n d: geometry.path,\n \"marker-end\": `url(#${markerId(tone)})`,\n ...(edge.bidirectional ? { \"marker-start\": `url(#${markerId(tone)})` } : {}),\n },\n {\n fill: \"none\",\n stroke: color,\n \"stroke-width\": cssVar(\"border.width.default\"),\n \"stroke-linecap\": \"round\",\n // A static picture cannot animate, so an animated edge is drawn dashed.\n ...(edge.dashed || edge.animated ? { \"stroke-dasharray\": \"6 4\" } : {}),\n },\n ),\n ];\n if (showEdgeLabels && edge.label) {\n const width = estimateTextWidth(edge.label) + 16;\n children.push(\n el(\"rect\", { x: num(geometry.label.x - width / 2), y: num(geometry.label.y - 12), width: num(width), height: 24, rx: 4 }, { fill: palette.surface, stroke: palette.borderSubtle }),\n );\n children.push(\n el(\n \"text\",\n { x: num(geometry.label.x), y: num(geometry.label.y), \"text-anchor\": \"middle\", \"dominant-baseline\": \"central\", ...(rtl ? { direction: \"rtl\" } : {}) },\n { fill: palette.textMuted, \"font-size\": cssVar(\"text.caption.size\") },\n [edge.label],\n ),\n );\n }\n return el(\"g\", { \"data-edge-id\": edge.id, ...(edge.status ? { \"data-status\": edge.status } : {}) }, undefined, children);\n };\n\n const title = options.title ?? doc.title;\n const lines = diagramToOutline(doc, options.connector === undefined ? {} : { connector: options.connector });\n const description = options.description ?? [doc.description, ...lines].filter((part): part is string => Boolean(part)).join(\". \");\n const titleId = `${prefix}-title`;\n const descId = `${prefix}-desc`;\n\n return el(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: `${num(view.x)} ${num(view.y)} ${num(view.width)} ${num(view.height)}`,\n ...(options.width === undefined ? {} : { width: options.width }),\n ...(options.height === undefined ? {} : { height: options.height }),\n role: \"img\",\n \"aria-labelledby\": description === \"\" ? titleId : `${titleId} ${descId}`,\n ...(options.lang === undefined ? {} : { lang: options.lang }),\n ...(rtl ? { direction: \"rtl\" } : {}),\n \"data-kit\": \"diagram-static\",\n },\n { \"font-family\": palette.fontSans, \"font-size\": cssVar(\"text.label.size\") },\n [\n el(\"title\", { id: titleId }, undefined, [title]),\n ...(description === \"\" ? [] : [el(\"desc\", { id: descId }, undefined, [description])]),\n defs,\n el(\"g\", { \"data-layer\": \"groups\" }, undefined, containers.map(nodeElement)),\n el(\"g\", { \"data-layer\": \"edges\" }, undefined, edges.map(edgeElement)),\n el(\"g\", { \"data-layer\": \"nodes\" }, undefined, others.map(nodeElement)),\n ],\n );\n}\n\n/**\n * Renders a diagram to an SVG string with no DOM and no React, so it works on a\n * server, in a report or for print. Colors are `var(--kit-...)` references by\n * default; pass `palette` for resolved colors when saving a stand-alone file.\n */\nexport function diagramToSvg(doc: DiagramDocument, options: SvgOptions = {}): string {\n const svg = serializeSvg(diagramToSvgTree(doc, options));\n return options.standalone ? `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n${svg}` : svg;\n}","import { diagramToSvg, type SvgOptions } from \"./svg\";\nimport { validateDiagram, type DiagramIssue } from \"./validate\";\nimport { DIAGRAM_VERSION, type DiagramDocument } from \"./schema\";\n\nexport type ImportErrorCode = \"invalid-json\" | \"not-an-object\" | \"missing-version\" | \"unsupported-version\" | \"missing-migration\" | \"invalid-structure\";\n\n/** Thrown by `importDiagram` when the input cannot become a document. */\nexport class DiagramImportError extends Error {\n readonly code: ImportErrorCode;\n readonly issues: DiagramIssue[];\n constructor(code: ImportErrorCode, message: string, issues: DiagramIssue[] = []) {\n super(message);\n this.name = \"DiagramImportError\";\n this.code = code;\n this.issues = issues;\n }\n}\n\n/** Upgrades the raw document by one version. It receives and returns plain JSON. */\nexport type DiagramMigration = (raw: Record<string, unknown>) => Record<string, unknown>;\n\nexport interface ImportOptions {\n /**\n * Migrations by the version they upgrade FROM: `{ 0: (raw) => ... }` turns a\n * version 0 document into version 1. They run in order until the current\n * version. The `version` field is advanced for you.\n */\n migrations?: Record<number, DiagramMigration>;\n /**\n * A single hook that runs after `migrations`, once per import, with the\n * version the data started at. Use it for changes not tied to one version.\n */\n migrate?: (raw: Record<string, unknown>, fromVersion: number) => Record<string, unknown>;\n /** Version to assume when the input has none. By default a missing version is an error. */\n assumeVersion?: number;\n /** Throw `invalid-structure` when validation finds errors. Defaults to false: errors are returned in `issues`. */\n strict?: boolean;\n}\n\nexport interface ImportResult {\n document: DiagramDocument;\n /** Everything `validateDiagram` found. Warnings and, unless `strict`, errors. */\n issues: DiagramIssue[];\n /** The version the input had before migration, when it was migrated. */\n migratedFrom?: number;\n}\n\nexport interface ExportJsonOptions {\n /** Indentation. Defaults to 2; pass 0 for compact output. */\n space?: number;\n}\n\n/** Serializes a document to JSON. The `version` field comes first. */\nexport function exportDiagramJson(doc: DiagramDocument, options: ExportJsonOptions = {}): string {\n const { version, title, ...rest } = doc;\n return JSON.stringify({ version, title, ...rest }, null, options.space ?? 2);\n}\n\n/** Exports a stand-alone SVG file's text. Pass a resolved `palette`; `var(--kit-...)` colors only work inside a themed page. */\nexport function exportDiagramSvg(doc: DiagramDocument, options: SvgOptions = {}): string {\n return diagramToSvg(doc, { ...options, standalone: true });\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n/**\n * Turns JSON text or a parsed object into a validated document. Old versions\n * are migrated, unknown newer versions are refused, and the result is checked\n * with `validateDiagram`. Round-trips with `exportDiagramJson`.\n */\nexport function importDiagram(input: string | unknown, options: ImportOptions = {}): ImportResult {\n let raw: unknown = input;\n if (typeof input === \"string\") {\n try {\n raw = JSON.parse(input);\n } catch (error) {\n throw new DiagramImportError(\"invalid-json\", `The diagram is not valid JSON: ${(error as Error).message}`);\n }\n }\n if (!isRecord(raw)) throw new DiagramImportError(\"not-an-object\", \"A diagram must be a JSON object.\");\n\n let data: Record<string, unknown> = { ...raw };\n let version = data.version;\n if (version === undefined && options.assumeVersion !== undefined) version = options.assumeVersion;\n if (typeof version !== \"number\" || !Number.isInteger(version)) {\n throw new DiagramImportError(\"missing-version\", \"The diagram has no numeric version field.\");\n }\n if (version > DIAGRAM_VERSION) {\n throw new DiagramImportError(\n \"unsupported-version\",\n `The diagram is version ${version}, but this library reads up to version ${DIAGRAM_VERSION}. Update @x12i/diagrams.`,\n );\n }\n\n const fromVersion = version;\n for (let current = version; current < DIAGRAM_VERSION; current += 1) {\n const step = options.migrations?.[current];\n if (!step) {\n throw new DiagramImportError(\"missing-migration\", `No migration from diagram version ${current} to ${current + 1}.`);\n }\n data = { ...step(data), version: current + 1 };\n }\n data.version = DIAGRAM_VERSION;\n if (options.migrate && fromVersion < DIAGRAM_VERSION) data = { ...options.migrate(data, fromVersion), version: DIAGRAM_VERSION };\n\n if (!Array.isArray(data.nodes) || !Array.isArray(data.edges)) {\n throw new DiagramImportError(\"invalid-structure\", \"A diagram needs `nodes` and `edges` arrays.\");\n }\n for (const [i, node] of (data.nodes as unknown[]).entries()) {\n if (!isRecord(node) || typeof node.id !== \"string\") {\n throw new DiagramImportError(\"invalid-structure\", `Node ${i} needs a string id.`);\n }\n }\n for (const [i, edge] of (data.edges as unknown[]).entries()) {\n if (!isRecord(edge) || typeof edge.id !== \"string\" || typeof edge.source !== \"string\" || typeof edge.target !== \"string\") {\n throw new DiagramImportError(\"invalid-structure\", `Edge ${i} needs string id, source and target fields.`);\n }\n }\n\n const document = { ...data, title: typeof data.title === \"string\" ? data.title : \"\" } as unknown as DiagramDocument;\n const { issues, errors } = validateDiagram(document);\n if (options.strict && errors.length > 0) {\n throw new DiagramImportError(\"invalid-structure\", `The diagram has ${errors.length} validation errors. First: ${errors[0]?.message}`, issues);\n }\n const result: ImportResult = { document, issues };\n if (fromVersion < DIAGRAM_VERSION) result.migratedFrom = fromVersion;\n return result;\n}\n","import type { ConnectionRejection } from \"./connection\";\nimport type { NodeKind, NodeStatus } from \"./schema\";\n\n/** Values available to a message template, for example `{ label: \"Review\" }`. */\nexport type MessageValues = Record<string, string | number>;\n\n/**\n * A translated string. Either a template with `{name}` placeholders, or a\n * function for languages that need plurals or word order a template cannot\n * express (use `Intl.PluralRules` inside it).\n */\nexport type Message = string | ((values: MessageValues) => string);\n\n/** Fills `{name}` placeholders. An unknown placeholder is left as written. */\nexport function formatMessage(message: Message, values: MessageValues = {}): string {\n if (typeof message === \"function\") return message(values);\n return message.replace(/\\{(\\w+)\\}/g, (match, name: string) => {\n const value = values[name];\n return value === undefined ? match : String(value);\n });\n}\n\nexport interface DiagramMessages {\n canvas: {\n /** Accessible name of the canvas. `{title}` */\n label: Message;\n /** Keyboard instructions for an editable canvas, read when it gets focus. */\n instructions: Message;\n /** Keyboard instructions for a read-only canvas. */\n instructionsReadOnly: Message;\n /** Shown instead of the nodes when the diagram is empty. */\n empty: Message;\n };\n kinds: Record<NodeKind, Message>;\n statuses: Record<NodeStatus, Message>;\n node: {\n /** `{label}`, `{kind}`, `{incoming}`, `{outgoing}` */\n label: Message;\n /** Appended when a node has a status other than neutral. `{status}` */\n status: Message;\n roleDescription: Message;\n /** Accessible name of the inline editor. `{label}` */\n editLabel: Message;\n /** `{label}` */\n collapse: Message;\n /** `{label}` */\n expand: Message;\n /** Accessible name of a connection point. */\n port: Message;\n /** Shown on a collapsed group. `{count}` */\n childCount: Message;\n };\n edge: {\n /** `{source}`, `{target}` */\n label: Message;\n /** `{label}`, `{source}`, `{target}` */\n labelWithText: Message;\n roleDescription: Message;\n /** Accessible name of the edge label editor. `{source}`, `{target}` */\n editLabel: Message;\n };\n toolbar: {\n label: Message;\n addNode: Message;\n palette: Message;\n undo: Message;\n redo: Message;\n delete: Message;\n duplicate: Message;\n autoLayout: Message;\n group: Message;\n ungroup: Message;\n zoomIn: Message;\n zoomOut: Message;\n fitView: Message;\n showMiniMap: Message;\n hideMiniMap: Message;\n showGrid: Message;\n hideGrid: Message;\n controlsLabel: Message;\n };\n minimap: Message;\n /** Spoken through a polite live region. */\n announce: {\n nodeAdded: Message;\n nodeRemoved: Message;\n itemsRemoved: Message;\n connected: Message;\n disconnected: Message;\n moved: Message;\n resized: Message;\n renamed: Message;\n selected: Message;\n selectedMany: Message;\n selectionCleared: Message;\n undone: Message;\n redone: Message;\n nothingToUndo: Message;\n nothingToRedo: Message;\n layoutApplied: Message;\n grouped: Message;\n ungrouped: Message;\n duplicated: Message;\n copied: Message;\n pasted: Message;\n connectStarted: Message;\n connectCancelled: Message;\n locked: Message;\n };\n /** Why a connection was refused, by rejection code. */\n connection: Record<ConnectionRejection, Message>;\n outline: {\n title: Message;\n nodes: Message;\n paths: Message;\n /** Joins labels along a path: \"A to B\". */\n connector: Message;\n connectsTo: Message;\n receivesFrom: Message;\n noConnections: Message;\n /** `{label}` */\n goToNode: Message;\n empty: Message;\n /** `{status}` */\n status: Message;\n /** Shown before a group's children. `{label}` */\n contains: Message;\n /** Accessible name of the button that removes a connection. `{source}`, `{target}` */\n disconnect: Message;\n };\n mermaid: {\n loading: Message;\n renderError: Message;\n loadError: Message;\n showSource: Message;\n hideSource: Message;\n sourceLabel: Message;\n };\n}\n\ntype DeepPartial<T> = { [K in keyof T]?: T[K] extends Message ? T[K] : DeepPartial<T[K]> };\n\nexport type DiagramMessagesOverride = DeepPartial<DiagramMessages>;\n\n/** English strings. Copy this object, translate it, and pass it as `messages`. */\nexport const defaultMessages: DiagramMessages = {\n canvas: {\n label: \"Diagram: {title}\",\n instructions:\n \"Press Tab to move between nodes. Arrow keys jump to the nearest node in that direction. Press Space to select a node, Enter to rename it, Delete to remove the selection, and C to start a connection. Hold Shift with an arrow key to nudge the selection. Press Escape to clear the selection. The diagram outline lists every node and connection.\",\n instructionsReadOnly:\n \"Press Tab to move between nodes. Arrow keys jump to the nearest node in that direction. The diagram outline lists every node and connection.\",\n empty: \"This diagram is empty.\",\n },\n kinds: {\n start: \"Start\",\n end: \"End\",\n task: \"Task\",\n decision: \"Decision\",\n group: \"Group\",\n note: \"Note\",\n image: \"Image\",\n entity: \"Entity\",\n code: \"Code\",\n chart: \"Chart\",\n agent: \"Agent\",\n subflow: \"Subflow\",\n },\n statuses: {\n neutral: \"Neutral\",\n success: \"Success\",\n warning: \"Warning\",\n danger: \"Danger\",\n info: \"Info\",\n },\n node: {\n label: \"{label}, {kind}. Incoming connections: {incoming}. Outgoing connections: {outgoing}.\",\n status: \"Status: {status}.\",\n roleDescription: \"node\",\n editLabel: \"Label for {label}\",\n collapse: \"Collapse {label}\",\n expand: \"Expand {label}\",\n port: \"Connection point\",\n childCount: \"{count} items\",\n },\n edge: {\n label: \"Connection from {source} to {target}\",\n labelWithText: \"{label}. Connection from {source} to {target}\",\n roleDescription: \"connection\",\n editLabel: \"Label for the connection from {source} to {target}\",\n },\n toolbar: {\n label: \"Diagram tools\",\n addNode: \"Add node\",\n palette: \"Node types\",\n undo: \"Undo\",\n redo: \"Redo\",\n delete: \"Delete selection\",\n duplicate: \"Duplicate selection\",\n autoLayout: \"Arrange automatically\",\n group: \"Group selection\",\n ungroup: \"Ungroup\",\n zoomIn: \"Zoom in\",\n zoomOut: \"Zoom out\",\n fitView: \"Fit diagram to view\",\n showMiniMap: \"Show minimap\",\n hideMiniMap: \"Hide minimap\",\n showGrid: \"Show grid\",\n hideGrid: \"Hide grid\",\n controlsLabel: \"View controls\",\n },\n minimap: \"Minimap\",\n announce: {\n nodeAdded: \"Added {kind}: {label}.\",\n nodeRemoved: \"Removed {label}.\",\n itemsRemoved: \"Items removed: {count}.\",\n connected: \"Connected {source} to {target}.\",\n disconnected: \"Removed the connection from {source} to {target}.\",\n moved: \"Moved {label} to x {x}, y {y}.\",\n resized: \"Resized {label} to {width} by {height}.\",\n renamed: \"Renamed to {label}.\",\n selected: \"Selected {label}.\",\n selectedMany: \"Selected items: {count}.\",\n selectionCleared: \"Selection cleared.\",\n undone: \"Undid the last change.\",\n redone: \"Redid the change.\",\n nothingToUndo: \"Nothing to undo.\",\n nothingToRedo: \"Nothing to redo.\",\n layoutApplied: \"Layout applied.\",\n grouped: \"Grouped into {label}.\",\n ungrouped: \"Ungrouped {label}.\",\n duplicated: \"Duplicated items: {count}.\",\n copied: \"Copied items: {count}.\",\n pasted: \"Pasted items: {count}.\",\n connectStarted: \"Connecting from {label}. Move to the target node and press Enter, or press Escape to cancel.\",\n connectCancelled: \"Connection cancelled.\",\n locked: \"{label} is locked.\",\n },\n connection: {\n \"unknown-source\": \"That node no longer exists.\",\n \"unknown-target\": \"That node no longer exists.\",\n \"self-loop\": \"A node cannot connect to itself in this diagram.\",\n duplicate: \"These nodes are already connected.\",\n locked: \"A locked node cannot be connected.\",\n \"container-descendant\": \"A group cannot connect to a node inside it.\",\n \"source-port-missing\": \"That connection point does not exist.\",\n \"target-port-missing\": \"That connection point does not exist.\",\n \"source-port-not-output\": \"That connection point only receives connections.\",\n \"target-port-not-input\": \"That connection point only starts connections.\",\n \"port-type-mismatch\": \"These connection points have different types and cannot be joined.\",\n cycle: \"This connection would create a cycle, which this diagram does not allow.\",\n \"multiple-parents\": \"This node already has a parent.\",\n custom: \"This connection is not allowed.\",\n },\n outline: {\n title: \"Diagram outline\",\n nodes: \"Nodes\",\n paths: \"Paths\",\n connector: \"to\",\n connectsTo: \"Connects to\",\n receivesFrom: \"Receives from\",\n noConnections: \"No connections\",\n goToNode: \"Show {label} in the diagram\",\n empty: \"This diagram has no nodes.\",\n status: \"Status: {status}\",\n contains: \"Contains\",\n disconnect: \"Remove the connection from {source} to {target}\",\n },\n mermaid: {\n loading: \"Rendering diagram…\",\n renderError: \"The diagram could not be rendered.\",\n loadError: \"Mermaid could not be loaded. Install the mermaid package and pass it with the loadMermaid prop.\",\n showSource: \"Show source\",\n hideSource: \"Hide source\",\n sourceLabel: \"Diagram source\",\n },\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction merge<T>(base: T, override: unknown): T {\n if (!isRecord(override) || typeof base === \"string\" || typeof base === \"function\") {\n return (override === undefined ? base : override) as T;\n }\n const result: Record<string, unknown> = { ...(base as Record<string, unknown>) };\n for (const [key, value] of Object.entries(override)) {\n if (value !== undefined) result[key] = merge((base as Record<string, unknown>)[key], value);\n }\n return result as T;\n}\n\n/** Merges partial translations over the English defaults. Missing keys fall back to English. */\nexport function resolveMessages(override?: DiagramMessagesOverride): DiagramMessages {\n return override ? merge(defaultMessages, override) : defaultMessages;\n}\n"],"mappings":"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","names":["add","mirror","placements","edge","id","lines","isRecord"]}
|