@visualli/core 0.2.1 → 0.2.3

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.
Files changed (62) hide show
  1. package/dist/{chunk-RFMUATWB.js → chunk-2AB4FH2E.js} +2 -2
  2. package/dist/{chunk-RFMUATWB.js.map → chunk-2AB4FH2E.js.map} +1 -1
  3. package/dist/{chunk-ITDZ72JE.js → chunk-2EVIMAJN.js} +2 -2
  4. package/dist/chunk-2EVIMAJN.js.map +1 -0
  5. package/dist/{chunk-UAMEJG2C.js → chunk-3ZEH2SFM.js} +9 -1
  6. package/dist/chunk-3ZEH2SFM.js.map +1 -0
  7. package/dist/{chunk-LOQLNYB3.js → chunk-GWR7CGWW.js} +2 -2
  8. package/dist/{chunk-64PUANNH.js → chunk-HONAB36P.js} +2 -2
  9. package/dist/{chunk-W2CAOOJJ.js → chunk-RHUW2OCC.js} +2 -2
  10. package/dist/{chunk-WO4JAAKP.js → chunk-RLZO3KIN.js} +3 -3
  11. package/dist/{chunk-P6PKWVYF.js → chunk-S6H66I62.js} +2 -2
  12. package/dist/config/index.cjs.map +1 -1
  13. package/dist/config/index.d.cts +4 -4
  14. package/dist/config/index.d.ts +4 -4
  15. package/dist/config/index.js +2 -2
  16. package/dist/constants/index.cjs.map +1 -1
  17. package/dist/constants/index.d.cts +2 -2
  18. package/dist/constants/index.d.ts +2 -2
  19. package/dist/constants/index.js +2 -2
  20. package/dist/{designSystem-D49xVfr8.d.cts → designSystem-BcBLKHJO.d.cts} +1 -1
  21. package/dist/{designSystem-D49xVfr8.d.ts → designSystem-BcBLKHJO.d.ts} +1 -1
  22. package/dist/{ideaSize-BTJu6thN.d.cts → ideaSize-BxYgVM2m.d.cts} +1 -1
  23. package/dist/{ideaSize-RKbms8K6.d.ts → ideaSize-DBcumOej.d.ts} +1 -1
  24. package/dist/{index-Dt--T2l8.d.cts → index-BD-rumDI.d.cts} +1 -1
  25. package/dist/{index-CcF0Jvmb.d.ts → index-CnQ3Vcwr.d.ts} +1 -1
  26. package/dist/index.cjs +9 -1
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +15 -5
  29. package/dist/index.d.ts +15 -5
  30. package/dist/index.js +8 -8
  31. package/dist/layout/index.d.cts +2 -2
  32. package/dist/layout/index.d.ts +2 -2
  33. package/dist/{mindmap-BO3YD5qu.d.cts → mindmap-Acjoll04.d.cts} +1 -1
  34. package/dist/{mindmap-D0Of0jaZ.d.ts → mindmap-BwFtEDQV.d.ts} +1 -1
  35. package/dist/parser/index.cjs.map +1 -1
  36. package/dist/parser/index.d.cts +3 -3
  37. package/dist/parser/index.d.ts +3 -3
  38. package/dist/parser/index.js +3 -3
  39. package/dist/performance/index.cjs.map +1 -1
  40. package/dist/performance/index.js +2 -2
  41. package/dist/theme/index.cjs +1 -1
  42. package/dist/theme/index.cjs.map +1 -1
  43. package/dist/theme/index.d.cts +2 -2
  44. package/dist/theme/index.d.ts +2 -2
  45. package/dist/theme/index.js +2 -2
  46. package/dist/types/index.d.cts +2 -2
  47. package/dist/types/index.d.ts +2 -2
  48. package/dist/viewport/index.cjs.map +1 -1
  49. package/dist/viewport/index.d.cts +2 -2
  50. package/dist/viewport/index.d.ts +2 -2
  51. package/dist/viewport/index.js +2 -2
  52. package/package.json +1 -1
  53. package/src/generated/designSystem.ts +1 -1
  54. package/src/generated/geometry/color.ts +4 -0
  55. package/src/generated/geometry/interaction.ts +6 -0
  56. package/dist/chunk-ITDZ72JE.js.map +0 -1
  57. package/dist/chunk-UAMEJG2C.js.map +0 -1
  58. /package/dist/{chunk-LOQLNYB3.js.map → chunk-GWR7CGWW.js.map} +0 -0
  59. /package/dist/{chunk-64PUANNH.js.map → chunk-HONAB36P.js.map} +0 -0
  60. /package/dist/{chunk-W2CAOOJJ.js.map → chunk-RHUW2OCC.js.map} +0 -0
  61. /package/dist/{chunk-WO4JAAKP.js.map → chunk-RLZO3KIN.js.map} +0 -0
  62. /package/dist/{chunk-P6PKWVYF.js.map → chunk-S6H66I62.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/parser/index.ts","../../src/parser/visualliParser.ts","../../src/generated/designSystem.ts","../../src/generated/geometry/color.ts","../../src/theme/index.ts","../../src/generated/geometry/idea.ts","../../src/rendering/ideaSize.ts","../../src/layout/circularLayout.ts","../../src/layout/linearLayout.ts","../../src/parser/visualliConverter.ts","../../src/parser/mindmapUtils.ts","../../src/constants/layout.ts","../../src/parser/configUtils.ts"],"sourcesContent":["export * from './visualliParser.js';\nexport * from './visualliConverter.js';\nexport * from './mindmapUtils.js';\nexport * from './configUtils.js';\n","// ─── .visualli File Parser ────────────────────────────────────────────────────\n//\n// Reads JSONL (JSON Lines) format and parses into a structured VisualliDocument.\n\nimport type { VisualliDocument, SemanticAnchor } from '../types/document.js';\nimport type { VisualliMeta } from '../types/meta.js';\nimport type { VisualliLayer } from '../types/layer.js';\nimport type { Layer } from '../types/schema.js';\n\n/**\n * Convert schema Layer to VisualliLayer by ensuring required arrays exist.\n */\nfunction toVisualliLayer(schemaLayer: Layer): VisualliLayer {\n return {\n type: 'layer',\n id: schemaLayer.id,\n level: schemaLayer.level,\n parentLayerId: schemaLayer.parentLayerId,\n parentNodeId: schemaLayer.parentNodeId,\n layout: schemaLayer.layout,\n nodes: schemaLayer.nodes ?? [],\n connections: schemaLayer.connections ?? [],\n containers: schemaLayer.containers ?? [],\n };\n}\n\nexport class VisualliParseError extends Error {\n constructor(message: string, public readonly lineNumber?: number) {\n super(message);\n this.name = 'VisualliParseError';\n }\n}\n\n/**\n * Parse a .visualli file content (JSONL format) into a VisualliDocument.\n *\n * @throws VisualliParseError on malformed input\n */\nexport function parseVisualliFile(content: string): VisualliDocument {\n const lines = content.trim().split('\\n');\n\n const doc: VisualliDocument = {\n meta: null as unknown as VisualliMeta,\n layers: new Map(),\n layersByLevel: new Map(),\n rootLayer: null,\n };\n\n let lineNumber = 0;\n\n for (const line of lines) {\n lineNumber++;\n if (!line.trim()) continue;\n\n let obj: Record<string, unknown>;\n try {\n obj = JSON.parse(line) as Record<string, unknown>;\n } catch (err) {\n throw new VisualliParseError(\n `Failed to parse JSON at line ${lineNumber}: ${err}`,\n lineNumber,\n );\n }\n\n if (!obj['type']) {\n throw new VisualliParseError(\n `Missing 'type' field at line ${lineNumber}`,\n lineNumber,\n );\n }\n\n switch (obj['type']) {\n case 'meta':\n doc.meta = obj as unknown as VisualliMeta;\n break;\n\n case 'layer': {\n // Convert schema Layer to VisualliLayer\n const schemaLayer = obj as unknown as Layer;\n const layer = toVisualliLayer(schemaLayer);\n \n doc.layers.set(layer.id, layer);\n\n if (!doc.layersByLevel.has(layer.level)) {\n doc.layersByLevel.set(layer.level, []);\n }\n doc.layersByLevel.get(layer.level)!.push(layer);\n\n if (layer.level === 0) {\n doc.rootLayer = layer;\n }\n break;\n }\n\n case 'extension': {\n const id = obj['id'];\n if (typeof id === 'string') {\n (doc.extensions ??= {})[id] = Array.isArray(obj['data']) ? (obj['data'] as unknown[]) : [];\n }\n break;\n }\n\n default:\n // Unknown type — silently skip\n break;\n }\n }\n\n if (!doc.meta) throw new VisualliParseError('Missing required meta section');\n if (!doc.rootLayer) throw new VisualliParseError('Missing root layer (level 0)');\n\n return doc;\n}\n\nexport async function fetchAndParseVisualli(url: string): Promise<VisualliDocument> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n return parseVisualliFile(await response.text());\n}\n\n/**\n * Parse .visualli JSONL data as returned from the MongoDB `visualli` field.\n *\n * @throws VisualliParseError\n */\nexport function parseVisualliFromMongoDB(visualliJsonl: string): VisualliDocument {\n if (!visualliJsonl || typeof visualliJsonl !== 'string') {\n throw new VisualliParseError('Invalid visualli data: expected a JSONL string');\n }\n const trimmed = visualliJsonl.trim();\n if (!trimmed) throw new VisualliParseError('Empty visualli data from MongoDB');\n return parseVisualliFile(trimmed);\n}\n\n/**\n * Parse a .visualli file from a browser `File` object.\n * (Browser-only – requires `FileReader`.)\n */\nexport function loadVisualliFileFromFile(file: File): Promise<VisualliDocument> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = e => {\n try {\n resolve(parseVisualliFile(e.target?.result as string));\n } catch (err) {\n reject(err);\n }\n };\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsText(file);\n });\n}\n\n// ── Tree Helpers ──────────────────────────────────────────────────────────────\n\n/** Return all layers whose `parentNodeId` matches the given node ID. */\n/** Terms defined by the document's `semantic-anchors` extension (empty when absent). */\nexport function getSemanticAnchors(doc: VisualliDocument): SemanticAnchor[] {\n const raw = doc.extensions?.['semantic-anchors'];\n if (!Array.isArray(raw)) return [];\n return raw.filter((a): a is SemanticAnchor => !!a && typeof (a as SemanticAnchor).word === 'string' && typeof (a as SemanticAnchor).description === 'string');\n}\n\nexport function getChildLayers(\n doc: VisualliDocument,\n nodeId: string,\n): VisualliLayer[] {\n const result: VisualliLayer[] = [];\n for (const layer of doc.layers.values()) {\n if (layer.parentNodeId === nodeId) result.push(layer);\n }\n return result;\n}\n\n/**\n * Count the maximum depth of layers beneath a node (its \"magnitude\").\n * Returns 0 when the node has no child layers.\n */\nexport function countLayersBeneath(\n doc: VisualliDocument,\n nodeId: string,\n visited = new Set<string>(),\n): number {\n if (visited.has(nodeId)) return 0;\n visited.add(nodeId);\n\n const children = getChildLayers(doc, nodeId);\n if (children.length === 0) return 0;\n\n let maxDepth = 0;\n for (const layer of children) {\n let depth = 1;\n for (const node of layer.nodes) {\n depth = Math.max(depth, 1 + countLayersBeneath(doc, node.id, visited));\n }\n maxDepth = Math.max(maxDepth, depth);\n }\n return maxDepth;\n}\n","// GENERATED by scripts/gen-design-system.mjs from design-system/ (tokens/tokens.json, tokens/tokens.css). Do not edit.\n// Change the design system instead; the next `npm run build` regenerates this file.\n\n/** Version of the design system these modules were generated from. */\nexport const DESIGN_SYSTEM_VERSION = \"0.2.1\" as const;\n\nexport const THEME_NAMES = [\n \"light\",\n \"dark\",\n \"focus-light\",\n \"focus-dark\",\n \"colorsafe-light\",\n \"colorsafe-dark\",\n \"contrast-light\",\n \"contrast-dark\"\n] as const;\nexport type ThemeName = (typeof THEME_NAMES)[number];\n\n/** Every token for every theme (each theme already merged over \"light\"). Keys match the CSS custom properties. */\nexport const TOKENS: Readonly<Record<ThemeName, Readonly<Record<string, string>>>> = {\n \"light\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#f6f3ee\",\n \"surface\": \"#ffffff\",\n \"surface-sunken\": \"#f0ece5\",\n \"surface-overlay\": \"#ffffff\",\n \"line\": \"#e4dfd6\",\n \"line-strong\": \"#7a7f94\",\n \"ink\": \"#182140\",\n \"ink-muted\": \"#4f5671\",\n \"ink-subtle\": \"#5f647c\",\n \"action\": \"#182140\",\n \"on-action\": \"#ffffff\",\n \"focus\": \"#325e8c\",\n \"link\": \"#2f5a87\",\n \"selection\": \"rgba(18, 199, 211, 0.28)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#2a3048\",\n \"edge-label\": \"#4f5671\",\n \"topic-teal\": \"#87f2f8\",\n \"topic-teal-ring\": \"#00cdd5\",\n \"topic-harbor\": \"#bcdbff\",\n \"topic-harbor-ring\": \"#76b2f5\",\n \"topic-iris\": \"#e0c8fe\",\n \"topic-iris-ring\": \"#bd96ea\",\n \"topic-berry\": \"#ffbdc4\",\n \"topic-berry-ring\": \"#f47e8f\",\n \"topic-coral\": \"#ffc7b2\",\n \"topic-coral-ring\": \"#f38e65\",\n \"topic-amber\": \"#ffcf9d\",\n \"topic-amber-ring\": \"#eb9c38\",\n \"topic-sun\": \"#ffea94\",\n \"topic-sun-ring\": \"#dfbd04\",\n \"topic-stone\": \"#e0dacf\",\n \"topic-stone-ring\": \"#bab09f\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"dark\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#0f1220\",\n \"surface\": \"#171b2b\",\n \"surface-sunken\": \"#0f1220\",\n \"surface-overlay\": \"#212639\",\n \"line\": \"#2b3148\",\n \"line-strong\": \"#6c7392\",\n \"ink\": \"#eef0f7\",\n \"ink-muted\": \"#b3b8cc\",\n \"ink-subtle\": \"#8f95ae\",\n \"action\": \"#f6f3ee\",\n \"on-action\": \"#182140\",\n \"focus\": \"#12c7d3\",\n \"link\": \"#5fd8e1\",\n \"selection\": \"rgba(18, 199, 211, 0.32)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#c9cddc\",\n \"edge-label\": \"#b3b8cc\",\n \"topic-teal\": \"#87f2f8\",\n \"topic-teal-ring\": \"#0fc5cd\",\n \"topic-harbor\": \"#bcdbff\",\n \"topic-harbor-ring\": \"#73aceb\",\n \"topic-iris\": \"#e0c8fe\",\n \"topic-iris-ring\": \"#b691e1\",\n \"topic-berry\": \"#ffbdc4\",\n \"topic-berry-ring\": \"#eb798a\",\n \"topic-coral\": \"#ffc7b2\",\n \"topic-coral-ring\": \"#ea8962\",\n \"topic-amber\": \"#ffcf9d\",\n \"topic-amber-ring\": \"#e29737\",\n \"topic-sun\": \"#ffea94\",\n \"topic-sun-ring\": \"#d8b70a\",\n \"topic-stone\": \"#e0dacf\",\n \"topic-stone-ring\": \"#b4a999\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(0, 0, 0, 0.40), 0 8px 24px rgba(0, 0, 0, 0.35)\",\n \"shadow-pop\": \"0 2px 4px rgba(0, 0, 0, 0.50), 0 16px 40px rgba(0, 0, 0, 0.50)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"focus-light\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#f4f2ee\",\n \"surface\": \"#ffffff\",\n \"surface-sunken\": \"#f0ece5\",\n \"surface-overlay\": \"#ffffff\",\n \"line\": \"#e4dfd6\",\n \"line-strong\": \"#7a7f94\",\n \"ink\": \"#182140\",\n \"ink-muted\": \"#4f5671\",\n \"ink-subtle\": \"#5f647c\",\n \"action\": \"#182140\",\n \"on-action\": \"#ffffff\",\n \"focus\": \"#325e8c\",\n \"link\": \"#2f5a87\",\n \"selection\": \"rgba(18, 199, 211, 0.28)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#5a6079\",\n \"edge-label\": \"#5a6079\",\n \"topic-teal\": \"#bce8ea\",\n \"topic-teal-ring\": \"#67c6cb\",\n \"topic-harbor\": \"#c9d9ec\",\n \"topic-harbor-ring\": \"#8bb2de\",\n \"topic-iris\": \"#d9cfe8\",\n \"topic-iris-ring\": \"#b79ed4\",\n \"topic-berry\": \"#edc6c9\",\n \"topic-berry-ring\": \"#da9099\",\n \"topic-coral\": \"#eecec1\",\n \"topic-coral-ring\": \"#db9b82\",\n \"topic-amber\": \"#eed4ba\",\n \"topic-amber-ring\": \"#d6a570\",\n \"topic-sun\": \"#f4eac1\",\n \"topic-sun-ring\": \"#d2bf73\",\n \"topic-stone\": \"#dddad5\",\n \"topic-stone-ring\": \"#bab09f\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"focus-dark\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#12141c\",\n \"surface\": \"#171b2b\",\n \"surface-sunken\": \"#0f1220\",\n \"surface-overlay\": \"#212639\",\n \"line\": \"#2b3148\",\n \"line-strong\": \"#6c7392\",\n \"ink\": \"#eef0f7\",\n \"ink-muted\": \"#b3b8cc\",\n \"ink-subtle\": \"#8f95ae\",\n \"action\": \"#f6f3ee\",\n \"on-action\": \"#182140\",\n \"focus\": \"#12c7d3\",\n \"link\": \"#5fd8e1\",\n \"selection\": \"rgba(18, 199, 211, 0.32)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#a9aec0\",\n \"edge-label\": \"#b3b8cc\",\n \"topic-teal\": \"#bce8ea\",\n \"topic-teal-ring\": \"#71bdc1\",\n \"topic-harbor\": \"#c9d9ec\",\n \"topic-harbor-ring\": \"#8cabce\",\n \"topic-iris\": \"#d9cfe8\",\n \"topic-iris-ring\": \"#ae9bc6\",\n \"topic-berry\": \"#edc6c9\",\n \"topic-berry-ring\": \"#cc8e95\",\n \"topic-coral\": \"#eecec1\",\n \"topic-coral-ring\": \"#cd9884\",\n \"topic-amber\": \"#eed4ba\",\n \"topic-amber-ring\": \"#c9a176\",\n \"topic-sun\": \"#f4eac1\",\n \"topic-sun-ring\": \"#c9b97a\",\n \"topic-stone\": \"#dddad5\",\n \"topic-stone-ring\": \"#b4a999\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"colorsafe-light\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#f6f3ee\",\n \"surface\": \"#ffffff\",\n \"surface-sunken\": \"#f0ece5\",\n \"surface-overlay\": \"#ffffff\",\n \"line\": \"#e4dfd6\",\n \"line-strong\": \"#7a7f94\",\n \"ink\": \"#182140\",\n \"ink-muted\": \"#4f5671\",\n \"ink-subtle\": \"#5f647c\",\n \"action\": \"#182140\",\n \"on-action\": \"#ffffff\",\n \"focus\": \"#325e8c\",\n \"link\": \"#2f5a87\",\n \"selection\": \"rgba(18, 199, 211, 0.28)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#2a3048\",\n \"edge-label\": \"#4f5671\",\n \"topic-teal\": \"#b0ecbc\",\n \"topic-teal-ring\": \"#6cc982\",\n \"topic-harbor\": \"#abdbfe\",\n \"topic-harbor-ring\": \"#60b4ec\",\n \"topic-iris\": \"#f6bde2\",\n \"topic-iris-ring\": \"#dc87c0\",\n \"topic-berry\": \"#feb79e\",\n \"topic-berry-ring\": \"#ec7f58\",\n \"topic-coral\": \"#fece96\",\n \"topic-coral-ring\": \"#e49d41\",\n \"topic-amber\": \"#b2e8fa\",\n \"topic-amber-ring\": \"#5cc4e2\",\n \"topic-sun\": \"#f6f097\",\n \"topic-sun-ring\": \"#d0c637\",\n \"topic-stone\": \"#dbdbdb\",\n \"topic-stone-ring\": \"#b7afb1\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"colorsafe-dark\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#0f1220\",\n \"surface\": \"#171b2b\",\n \"surface-sunken\": \"#0f1220\",\n \"surface-overlay\": \"#212639\",\n \"line\": \"#2b3148\",\n \"line-strong\": \"#6c7392\",\n \"ink\": \"#eef0f7\",\n \"ink-muted\": \"#b3b8cc\",\n \"ink-subtle\": \"#8f95ae\",\n \"action\": \"#f6f3ee\",\n \"on-action\": \"#182140\",\n \"focus\": \"#12c7d3\",\n \"link\": \"#5fd8e1\",\n \"selection\": \"rgba(18, 199, 211, 0.32)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#c9cddc\",\n \"edge-label\": \"#b3b8cc\",\n \"topic-teal\": \"#b0ecbc\",\n \"topic-teal-ring\": \"#69c27e\",\n \"topic-harbor\": \"#abdbfe\",\n \"topic-harbor-ring\": \"#5eade2\",\n \"topic-iris\": \"#f6bde2\",\n \"topic-iris-ring\": \"#d383b9\",\n \"topic-berry\": \"#feb79e\",\n \"topic-berry-ring\": \"#e37a55\",\n \"topic-coral\": \"#fece96\",\n \"topic-coral-ring\": \"#db9840\",\n \"topic-amber\": \"#b2e8fa\",\n \"topic-amber-ring\": \"#5bbdda\",\n \"topic-sun\": \"#f6f097\",\n \"topic-sun-ring\": \"#c9bf37\",\n \"topic-stone\": \"#dbdbdb\",\n \"topic-stone-ring\": \"#b1a8aa\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"contrast-light\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#ffffff\",\n \"surface\": \"#ffffff\",\n \"surface-sunken\": \"#f2f2f2\",\n \"surface-overlay\": \"#ffffff\",\n \"line\": \"#5c6178\",\n \"line-strong\": \"#000000\",\n \"ink\": \"#000000\",\n \"ink-muted\": \"#1f2433\",\n \"ink-subtle\": \"#3a3f52\",\n \"action\": \"#000000\",\n \"on-action\": \"#ffffff\",\n \"focus\": \"#0b4a8f\",\n \"link\": \"#0b4a8f\",\n \"selection\": \"rgba(18, 199, 211, 0.28)\",\n \"node-ink\": \"#000000\",\n \"edge\": \"#000000\",\n \"edge-label\": \"#1f2433\",\n \"topic-teal\": \"#87f2f8\",\n \"topic-teal-ring\": \"#006b70\",\n \"topic-harbor\": \"#bcdbff\",\n \"topic-harbor-ring\": \"#0e599d\",\n \"topic-iris\": \"#e0c8fe\",\n \"topic-iris-ring\": \"#683b92\",\n \"topic-berry\": \"#ffbdc4\",\n \"topic-berry-ring\": \"#96173a\",\n \"topic-coral\": \"#ffc7b2\",\n \"topic-coral-ring\": \"#923400\",\n \"topic-amber\": \"#ffcf9d\",\n \"topic-amber-ring\": \"#7e4d00\",\n \"topic-sun\": \"#ffea94\",\n \"topic-sun-ring\": \"#7a6600\",\n \"topic-stone\": \"#e0dacf\",\n \"topic-stone-ring\": \"#63594b\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"none\",\n \"shadow-pop\": \"none\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"contrast-dark\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#000000\",\n \"surface\": \"#000000\",\n \"surface-sunken\": \"#0d0d0d\",\n \"surface-overlay\": \"#0d0d0d\",\n \"line\": \"#9aa0b8\",\n \"line-strong\": \"#ffffff\",\n \"ink\": \"#ffffff\",\n \"ink-muted\": \"#e6e8f0\",\n \"ink-subtle\": \"#c8ccda\",\n \"action\": \"#ffffff\",\n \"on-action\": \"#000000\",\n \"focus\": \"#5fe8f0\",\n \"link\": \"#7ff0f5\",\n \"selection\": \"rgba(18, 199, 211, 0.32)\",\n \"node-ink\": \"#000000\",\n \"edge\": \"#ffffff\",\n \"edge-label\": \"#e6e8f0\",\n \"topic-teal\": \"#87f2f8\",\n \"topic-teal-ring\": \"#64eff7\",\n \"topic-harbor\": \"#bcdbff\",\n \"topic-harbor-ring\": \"#b0d5fe\",\n \"topic-iris\": \"#e0c8fe\",\n \"topic-iris-ring\": \"#dcbfff\",\n \"topic-berry\": \"#ffbdc4\",\n \"topic-berry-ring\": \"#feb3bb\",\n \"topic-coral\": \"#ffc7b2\",\n \"topic-coral-ring\": \"#ffbea5\",\n \"topic-amber\": \"#ffcf9d\",\n \"topic-amber-ring\": \"#ffc78a\",\n \"topic-sun\": \"#ffea94\",\n \"topic-sun-ring\": \"#ffe26d\",\n \"topic-stone\": \"#e0dacf\",\n \"topic-stone-ring\": \"#ddd3c2\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"none\",\n \"shadow-pop\": \"none\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n }\n};\n\n/** Topic palette names (token pairs `topic-<name>` / `topic-<name>-ring`). */\nexport const TOPICS = [\n \"teal\",\n \"harbor\",\n \"iris\",\n \"berry\",\n \"coral\",\n \"amber\",\n \"sun\",\n \"stone\"\n] as const;\nexport type TopicName = (typeof TOPICS)[number];\n\n/** Numeric tokens (px / ms stripped), camel-cased: nodeWidth, nodeStroke, edgeWidth, edgeGap, durationBase, zoomMin ... */\nexport const METRICS = {\n \"space1\": 4,\n \"space2\": 8,\n \"space3\": 12,\n \"space4\": 16,\n \"space7\": 48,\n \"radiusSm\": 10,\n \"radiusMd\": 16,\n \"radiusLg\": 24,\n \"radiusPill\": 999,\n \"nodeWidth\": 200,\n \"nodeHeight\": 148,\n \"nodeStroke\": 3,\n \"edgeWidth\": 2.5,\n \"edgeGap\": 15,\n \"edgeArcMax\": 45,\n \"immersionAlpha\": 0.15,\n \"zoomMin\": 0.3,\n \"zoomMax\": 5,\n \"durationInstant\": 100,\n \"durationQuick\": 160,\n \"durationBase\": 240,\n \"durationZoom\": 500,\n \"durationReveal\": 420,\n \"staggerReveal\": 70,\n \"zChrome\": 10,\n \"zCard\": 20,\n \"zMenu\": 40\n} as const;\n/** Overrides applied when motion is reduced. */\nexport const METRICS_REDUCED_MOTION = {\n \"durationInstant\": 120,\n \"durationQuick\": 0,\n \"durationBase\": 0,\n \"durationZoom\": 0,\n \"durationReveal\": 0,\n \"staggerReveal\": 0\n} as const;\n\n/** Canvas type styles (family is a token name: font-hand, font-note, font-ui ...). */\nexport const TYPE_STYLES = {\n \"heading\": {\n \"family\": \"font-ui\",\n \"size\": 17,\n \"lineHeight\": 24,\n \"weight\": 700\n },\n \"body\": {\n \"family\": \"font-ui\",\n \"size\": 15,\n \"lineHeight\": 22,\n \"weight\": 400\n },\n \"body-sm\": {\n \"family\": \"font-ui\",\n \"size\": 13,\n \"lineHeight\": 18,\n \"weight\": 400\n },\n \"label\": {\n \"family\": \"font-ui\",\n \"size\": 13,\n \"lineHeight\": 16,\n \"weight\": 600,\n \"letterSpacing\": 0.01\n },\n \"caption\": {\n \"family\": \"font-ui\",\n \"size\": 12,\n \"lineHeight\": 16,\n \"weight\": 400\n },\n \"node-root\": {\n \"family\": \"font-hand\",\n \"size\": 30,\n \"lineHeight\": 34,\n \"weight\": 700\n },\n \"node-label\": {\n \"family\": \"font-hand\",\n \"size\": 22,\n \"lineHeight\": 26,\n \"weight\": 700\n },\n \"edge-label\": {\n \"family\": \"font-note\",\n \"size\": 18,\n \"lineHeight\": 20,\n \"weight\": 500\n },\n \"annotation\": {\n \"family\": \"font-note\",\n \"size\": 24,\n \"lineHeight\": 26,\n \"weight\": 600\n }\n} as const;\n\n/** Canvas styling extracted from css/spec.css (node labels, hover, shadows, connector dashes, group frames). */\nexport const CANVAS_STYLE = {\n \"node\": {\n \"selectedStrokeWidth\": 4,\n \"hoverRingsRotate\": -2,\n \"hoverRingsScale\": 1.015,\n \"hoverLift\": -2,\n \"dimmedOpacity\": 1,\n \"dimmedOpacityFocus\": 0.4,\n \"dimmedOpacityTouch\": 0.6,\n \"dimmedOpacityFocusTouch\": 0.4,\n \"shadowLight\": \"0 6px 14px rgba(24, 33, 64, .10)\",\n \"shadowDark\": \"0 0 22px rgba(255, 255, 255, .10)\"\n },\n \"edge\": {\n \"dash\": [\n 7,\n 7\n ],\n \"labelWeight\": 500,\n \"labelSize\": 18,\n \"readableLabelSize\": 14,\n \"readableLabelWeight\": 600,\n \"labelHaloWidth\": 5\n },\n \"group\": {\n \"strokeWidth\": 1.5,\n \"dash\": [\n 10,\n 6\n ],\n \"labelWeight\": 700,\n \"labelLineHeight\": 1.1,\n \"labelSize\": 26,\n \"labelPadding\": {\n \"top\": 6,\n \"x\": 22,\n \"bottom\": 8\n },\n \"labelMaxWidth\": 420,\n \"labelBorderWidth\": 1.5,\n \"labelFill\": \"topic-stone\",\n \"labelBorder\": \"topic-stone-ring\",\n \"labelInk\": \"node-ink\",\n \"contrastLabelBorderWidth\": 2,\n \"contrastLabelBorder\": \"line-strong\"\n }\n} as const;\n","// Generated from visualli.ai design-system/components/src/color.ts — do not edit here.\n/* Which topic an idea is drawn in. A `.visualli` file's `data.color` may name one of the eight topics or be any\n other color, or be missing. Every renderer resolves it with this rule, so a file looks the same everywhere:\n a topic name ('teal', 'Harbor ') → that topic (case and surrounding spaces don't matter);\n no color → the topics in order, by the idea's position among its siblings (so siblings differ);\n anything else (e.g. '#b7e7f3') → null: not a topic — drawn as given (customColor): the color as the fill, and\n the fill darkened (CUSTOM.ringShade) as the ring; a custom color doesn't follow themes.\n No dependencies, so it can travel alone. */\n\n/** The eight topics, in the order missing colors cycle through. */\nexport const TOPIC_ORDER = ['teal', 'harbor', 'iris', 'berry', 'coral', 'amber', 'sun', 'stone'] as const;\nexport type TopicName = (typeof TOPIC_ORDER)[number];\n\n/** The topic a color names, or null. */\nexport function topicFromName(color: string | null | undefined): TopicName | null {\n if (!color) return null;\n const c = color.trim().toLowerCase();\n return (TOPIC_ORDER as readonly string[]).includes(c) ? (c as TopicName) : null;\n}\n\n/** The topic for an idea: its named topic; with no color, the next topic in sibling order; null for any other color. */\nexport function topicFor(color: string | null | undefined, siblingIndex: number): TopicName | null {\n if (!color || !color.trim()) return TOPIC_ORDER[((siblingIndex % TOPIC_ORDER.length) + TOPIC_ORDER.length) % TOPIC_ORDER.length];\n return topicFromName(color);\n}\n\n/** A custom (non-topic) color: drawn as given, with a darker ring. */\nexport const CUSTOM = { /** The ring is the fill with each RGB channel multiplied by this. */ ringShade: 0.78 } as const;\n\n/** Fill and ring for a custom color. `ring` is null when the color isn't a 6-digit hex (use the `edge` token then). */\nexport function customColor(color: string): { fill: string; ring: string | null } {\n const m = /^#?([0-9a-f]{6})$/i.exec((color || '').trim());\n if (!m) return { fill: color, ring: null };\n const n = parseInt(m[1], 16), f = CUSTOM.ringShade;\n const r = Math.round(((n >> 16) & 255) * f), g = Math.round(((n >> 8) & 255) * f), b = Math.round((n & 255) * f);\n return { fill: color.trim(), ring: '#' + ((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1) };\n}\n","// ─── Theme resolution ────────────────────────────────────────────────────────\n//\n// Everything visual comes from the generated design-system modules. This file\n// only decides WHICH of the 8 themes applies and resolves document colours with\n// the design system's colour rule. No colour literals live here.\n//\n// Dependencies: ../generated/designSystem.ts (generated from design-system/).\n\nimport {\n CANVAS_STYLE,\n DESIGN_SYSTEM_VERSION,\n METRICS,\n METRICS_REDUCED_MOTION,\n THEME_NAMES,\n TOKENS,\n TOPICS,\n TYPE_STYLES,\n type ThemeName,\n type TopicName,\n} from '../generated/designSystem.js';\nimport { TOPIC_ORDER, customColor, topicFor, topicFromName } from '../generated/geometry/color.js';\n\nexport { topicFromName, customColor };\n\nexport { CANVAS_STYLE, DESIGN_SYSTEM_VERSION, METRICS, METRICS_REDUCED_MOTION, THEME_NAMES, TOKENS, TOPICS, TYPE_STYLES };\nexport type { ThemeName, TopicName };\n\n// ── Theme selection ───────────────────────────────────────────────────────────\n\n/** Theme families: each resolves to its light or dark member. */\nexport type ThemeFamily = 'standard' | 'focus' | 'colorsafe' | 'contrast';\n\n/**\n * Anything a consumer may pass as `theme`:\n * - one of the 8 design-system themes ('light', 'dark', 'focus-light', ...)\n * - a family name ('focus' | 'colorsafe' | 'contrast') -> light/dark per the reader's scheme\n * - 'auto' -> light/dark per prefers-color-scheme (contrast under forced-colors)\n *\n * 'light' | 'dark' | 'auto' are the pre-0.2 values, kept as aliases for one release.\n */\nexport type ThemeInput = ThemeName | 'auto' | 'focus' | 'colorsafe' | 'contrast';\n\nexport interface ThemeEnv {\n /** prefers-color-scheme: dark */\n prefersDark?: boolean;\n /** forced-colors: active (Windows high contrast etc.) */\n forcedColors?: boolean;\n}\n\nconst FAMILIES: ReadonlySet<string> = new Set(['focus', 'colorsafe', 'contrast']);\n\nexport function isThemeName(v: unknown): v is ThemeName {\n return typeof v === 'string' && (THEME_NAMES as readonly string[]).includes(v);\n}\n\n/** Resolve any accepted `theme` value to one concrete design-system theme. */\nexport function resolveTheme(input: ThemeInput | undefined, env: ThemeEnv = {}): ThemeName {\n const scheme = env.prefersDark ? 'dark' : 'light';\n if (input === undefined || input === 'auto') return env.forcedColors ? (`contrast-${scheme}` as ThemeName) : scheme;\n if (FAMILIES.has(input)) return `${input}-${scheme}` as ThemeName;\n return isThemeName(input) ? input : 'light';\n}\n\nexport const isDarkTheme = (name: ThemeName): boolean => name.endsWith('dark');\nexport const isContrastTheme = (name: ThemeName): boolean => name.startsWith('contrast');\nexport const isFocusTheme = (name: ThemeName): boolean => name.startsWith('focus');\n\n/** All tokens of a theme (already merged over the light defaults). */\nexport const getTokens = (name: ThemeName): Readonly<Record<string, string>> => TOKENS[name];\n\n/** One token of a theme. Throws on an unknown key so typos fail loudly in tests. */\nexport function token(name: ThemeName, key: string): string {\n const v = TOKENS[name][key];\n if (v === undefined) throw new Error(`Unknown design-system token \"${key}\"`);\n return v;\n}\n\n// ── Comfort settings ──────────────────────────────────────────────────────────\n\nexport interface Comfort {\n /** Atkinson Hyperlegible for map labels instead of the handwritten faces (`data-type=\"readable\"`). */\n readableType?: boolean;\n /** Larger UI and label text (`data-scale=\"lg\"`). */\n largerText?: boolean;\n /** Skip transitions and reveal animations (`data-motion=\"reduced\"`). 'system' follows prefers-reduced-motion. */\n reducedMotion?: boolean | 'system';\n}\n\nexport interface ResolvedComfort { readableType: boolean; largerText: boolean; reducedMotion: boolean }\n\nexport function resolveComfort(c: Comfort | undefined, env: { prefersReducedMotion?: boolean } = {}): ResolvedComfort {\n const rm = c?.reducedMotion;\n return {\n readableType: !!c?.readableType,\n largerText: !!c?.largerText,\n reducedMotion: rm === undefined || rm === 'system' ? !!env.prefersReducedMotion : rm,\n };\n}\n\n/** Numeric design-system tokens (px / ms stripped). */\nexport type Metrics = { readonly [K in keyof typeof METRICS]: number };\n\n/** Numeric tokens with the reduced-motion overrides applied when requested. */\nexport function metricsFor(comfort: ResolvedComfort): Metrics {\n return comfort.reducedMotion ? { ...METRICS, ...METRICS_REDUCED_MOTION } : METRICS;\n}\n\n/** Multiplier the spec applies to label sizes under `data-scale=\"lg\"` (`--vi-label-scale`). */\nexport const labelScale = (c: ResolvedComfort): number => (c.largerText ? 1.15 : 1);\n\n// ── Topic palette ─────────────────────────────────────────────────────────────\n\nexport interface TopicStyle { topic: TopicName; fill: string; ring: string }\n\n/** Fill + ring colour of a topic in a theme. */\nexport function topicStyle(theme: ThemeName, topic: TopicName): TopicStyle {\n const t = TOKENS[theme];\n return { topic, fill: t[`topic-${topic}`]!, ring: t[`topic-${topic}-ring`]! };\n}\n\n/** An idea's colour by the design system's colour rule (geometry/color.ts, verbatim): a topic name → that topic; no\n * colour → the topics in sibling order; any other colour → custom, drawn as given (customColor: the colour as the fill,\n * the fill darkened by CUSTOM.ringShade as the ring). A custom colour doesn't follow themes. */\nexport interface IdeaColor { topic: TopicName | null; custom: { fill: string; ring: string | null } | null }\n\nexport function ideaColor(color: string | null | undefined, siblingIndex: number): IdeaColor {\n const topic = topicFor(color, siblingIndex);\n return topic ? { topic, custom: null } : { topic: null, custom: customColor(color!) };\n}\n\n/** Fill + ring an idea is drawn with in a theme: its topic's, or its custom colour (ring: the `edge` token when the\n * colour has no darker shade, i.e. isn't a 6-digit hex). */\nexport function ideaStyle(theme: ThemeName, c: { topic?: TopicName | null; custom?: IdeaColor['custom'] }): { fill: string; ring: string } {\n if (c.custom) return { fill: c.custom.fill, ring: c.custom.ring ?? TOKENS[theme]['edge']! };\n return topicStyle(theme, c.topic ?? TOPIC_ORDER[0]);\n}\n","// Generated from visualli.ai design-system/components/src/idea.ts — do not edit here.\n/* An idea's size and its label. An idea grows to show its whole label: it starts at its base width and widens in\n steps until the label fits in `labelLines` lines; at its widest it grows taller instead, so a label is never cut.\n Labels (and connector labels) grow a little when the map is zoomed out, so they stay readable. Every renderer sizes\n ideas with these rules, measuring text with its own font engine (`measure`). No dependencies, so it can travel alone. */\n\nexport type IdeaKind = 'root' | 'node' | 'mini';\n\n/** How much labels grow when zoomed out (`scale` = the map's zoom): never smaller than their size, up to these caps.\n * Idea labels and container names use `idea`; connector labels `connector`. Below 100% they grow; above, they don't. */\nexport const LABEL_GROWTH = { idea: 1.3, connector: 1.6 } as const;\n\nexport const IDEA = {\n /** Width an idea starts at… */ baseWidth: { root: 240, node: 200, mini: 120 },\n /** …and the widest it gets before it grows taller instead. */ maxWidth: { root: 400, node: 360, mini: 200 },\n /** Width grows in steps of this. */ step: 20,\n /** Height = width × aspect (at least `minRy` × 2), more if the label needs it. */ aspect: 0.74, minRy: 64,\n /** The label's box is the idea's width less this (22 each side). */ labelInset: 44,\n /** The idea widens until its label fits in this many lines. */ labelLines: 3,\n /** Label size (before the label scale and zoom growth), weight from the canvas type styles. */ labelSize: { root: 30, node: 22, mini: 15 },\n labelLineHeight: 1.15,\n /** The label may fill at most this share of the idea's height. */ labelFillHeight: 0.7,\n} as const;\n\n/** Greedy word wrap of `text` into lines no wider than `maxWidth` (a single word longer than that gets its own line). */\nexport function wrapLines(text: string, maxWidth: number, measure: (s: string) => number): string[] {\n const words = text.split(/\\s+/).filter(Boolean);\n const lines: string[] = [];\n let cur = '';\n for (const w of words) {\n const next = cur ? `${cur} ${w}` : w;\n if (cur && measure(next) > maxWidth) { lines.push(cur); cur = w; } else cur = next;\n }\n if (cur) lines.push(cur);\n return lines.length ? lines : [''];\n}\n\n/** An idea's size for its label: width, half-width / half-height for the blob, and the label's lines. The label is\n * measured at its largest drawn size — its type size × `labelScale` (Comfort: larger text) × LABEL_GROWTH.idea (zoomed\n * out) — so it fits at every zoom and the idea never changes size while zooming. `measure(text, px)` returns the\n * text's width in px in the label's face at `px`. */\nexport function ideaSize(kind: IdeaKind, label: string, measure: (text: string, px: number) => number, labelScale = 1) {\n const px = IDEA.labelSize[kind] * labelScale * LABEL_GROWTH.idea;\n const fit = (w: number) => wrapLines(label, w - IDEA.labelInset, (t) => measure(t, px));\n const base: number = IDEA.baseWidth[kind], max: number = IDEA.maxWidth[kind];\n let width = base, lines = fit(width);\n while (lines.length > IDEA.labelLines && width < max) { width = Math.min(max, width + IDEA.step); lines = fit(width); }\n const rx = width / 2;\n const ry = Math.max(IDEA.minRy, rx * IDEA.aspect, (lines.length * px * IDEA.labelLineHeight) / 2 / IDEA.labelFillHeight);\n return { width, height: ry * 2, rx, ry, lines };\n}\n\nexport function labelGrowth(scale: number): { idea: number; connector: number } {\n const inv = 1 / Math.max(scale, 0.0001);\n return { idea: Math.max(1, Math.min(inv, LABEL_GROWTH.idea)), connector: Math.max(1, Math.min(inv, LABEL_GROWTH.connector)) };\n}\n","// ─── Idea size and label growth ──────────────────────────────────────────────\n//\n// The design system's idea.ts (copied verbatim into generated/geometry): an idea\n// grows to show its whole label, and labels grow a little when zoomed out. The\n// SDK only supplies the text measurement (its font engine) and picks the kind.\n\nimport { IDEA, LABEL_GROWTH, ideaSize, labelGrowth, wrapLines, type IdeaKind } from '../generated/geometry/idea.js';\nimport type { VisualliLayer } from '../types/layer.js';\n\nexport { IDEA, LABEL_GROWTH, ideaSize, labelGrowth, wrapLines };\nexport type { IdeaKind };\n\n/** Width in px of `text` in the idea label's face at `px` (the label's weight; readable type adds its tracking). */\nexport type IdeaMeasure = (text: string, px: number) => number;\n\n/** Measurement without a font engine (server, tests): half an em per character. Renderers pass the real face. */\nexport const approximateMeasure: IdeaMeasure = (text, px) => text.length * px * 0.5;\n\n/** The size kind of the `index`-th idea of a layer: the centre of the root radial layer is the root, the rest ideas. */\nexport const ideaKindOf = (layer: Pick<VisualliLayer, 'level' | 'layout'>, index: number): IdeaKind =>\n layer.level === 0 && (layer.layout ?? 'radial') === 'radial' && index === 0 ? 'root' : 'node';\n","// ─── Circular Layout Algorithm ────────────────────────────────────────────────\n//\n// Positions nodes in a uniform circle with equal angular spacing.\n// PATTERN : Uniform circular distribution (polar coordinates)\n// SPACING : Equal angular intervals (2π/n)\n// ORIGIN : Configurable center (default 0, 0)\n// RADIUS : Configurable percentage of container (default 13.5%)\n\nimport type { FlatNode } from '../types/mindmap.js';\n\nexport interface CircularLayoutOptions {\n /** Radius as a fraction of the container's minimum dimension (0–1). Default: 0.135 */\n radiusPercentage?: number;\n /** Container width used to calculate absolute radius. Default: 2000 */\n containerWidth?: number;\n /** Container height used to calculate absolute radius. Default: 2000 */\n containerHeight?: number;\n /** World-space X of the circle centre. Default: 0 */\n centerX?: number;\n /** World-space Y of the circle centre. Default: 0 */\n centerY?: number;\n}\n\n/**\n * Apply circular layout to a set of nodes.\n * Mutates the `x` / `y` properties of each node and returns the same array.\n */\nexport function applyCircularLayout(\n nodes: FlatNode[],\n options: CircularLayoutOptions = {},\n): FlatNode[] {\n const {\n radiusPercentage = 0.135,\n containerWidth = 2000,\n containerHeight = 2000,\n centerX = 0,\n centerY = 0,\n } = options;\n\n if (nodes.length === 0) return nodes;\n\n if (nodes.length === 1) {\n nodes[0].x = centerX;\n nodes[0].y = centerY;\n return nodes;\n }\n\n const radius = Math.min(containerWidth, containerHeight) * radiusPercentage;\n\n // n=2 → horizontal; n≥3 → start at 12 o'clock\n const startAngle = nodes.length === 2 ? 0 : -Math.PI / 2;\n const angleStep = (2 * Math.PI) / nodes.length;\n\n for (let i = 0; i < nodes.length; i++) {\n const angle = startAngle + i * angleStep;\n nodes[i].x = centerX + radius * Math.cos(angle);\n nodes[i].y = centerY + radius * Math.sin(angle);\n }\n\n return nodes;\n}\n\n/**\n * Calculate the minimum radius needed to prevent node boxes from overlapping.\n *\n * Uses the chord-length formula: `chord = 2r · sin(θ/2)`, solved for `r`.\n */\nexport function calculateMinimumRadius(\n nodeCount: number,\n nodeWidth = 200,\n nodePadding = 150,\n): number {\n if (nodeCount <= 1) return 0;\n const angleStep = (2 * Math.PI) / nodeCount;\n const minChordLength = nodeWidth + nodePadding;\n return minChordLength / (2 * Math.sin(angleStep / 2));\n}\n\n/**\n * Calculate the optimal radius percentage for a given node count,\n * ensuring sufficient spacing for edge labels.\n *\n * @returns A value in [0.135, 0.45]\n */\nexport function calculateOptimalRadiusPercentage(\n nodeCount: number,\n containerWidth = 2000,\n containerHeight = 2000,\n nodeWidth = 200,\n nodePadding = 120,\n): number {\n const minRadius = calculateMinimumRadius(nodeCount, nodeWidth, nodePadding);\n const minDimension = Math.min(containerWidth, containerHeight);\n return Math.min(0.45, Math.max(0.135, minRadius / minDimension));\n}\n","// ─── Linear Layout Algorithms ─────────────────────────────────────────────────\n//\n// Positions nodes in a straight line without overlap, with enough gap between\n// node edges for edge-label text to render cleanly.\n//\n// linear-horizontal → left-to-right along X-axis\n// linear-vertical → top-to-bottom along Y-axis\n\nimport type { FlatNode } from '../types/mindmap.js';\n\nexport interface LinearLayoutOptions {\n /** Logical node width (px). Default: 200 */\n nodeWidth?: number;\n /** Logical node height (px). Default: 80 */\n nodeHeight?: number;\n /** Gap between node edges for horizontal layout (px). Default: 180 */\n hGap?: number;\n /** Gap between node edges for vertical layout (px). Default: 220 */\n vGap?: number;\n /** World X of the layout midpoint. Default: 0 */\n centerX?: number;\n /** World Y of the layout midpoint. Default: 0 */\n centerY?: number;\n}\n\n/**\n * Arrange nodes in a horizontal row (shared Y, varying X).\n * Row is centred on (`centerX`, `centerY`).\n */\nexport function applyLinearHorizontalLayout(\n nodes: FlatNode[],\n options: LinearLayoutOptions = {},\n): FlatNode[] {\n const { nodeWidth = 200, hGap = 180, centerX = 0, centerY = 0 } = options;\n\n if (nodes.length === 0) return nodes;\n\n if (nodes.length === 1) {\n nodes[0].x = centerX;\n nodes[0].y = centerY;\n return nodes;\n }\n\n const spacing = nodeWidth + hGap;\n const totalWidth = (nodes.length - 1) * spacing;\n const startX = centerX - totalWidth / 2;\n\n for (let i = 0; i < nodes.length; i++) {\n nodes[i].x = startX + i * spacing;\n nodes[i].y = centerY;\n }\n\n return nodes;\n}\n\n/**\n * Arrange nodes in a vertical column (shared X, varying Y).\n * Column is centred on (`centerX`, `centerY`).\n */\nexport function applyLinearVerticalLayout(\n nodes: FlatNode[],\n options: LinearLayoutOptions = {},\n): FlatNode[] {\n const { nodeHeight = 80, vGap = 220, centerX = 0, centerY = 0 } = options;\n\n if (nodes.length === 0) return nodes;\n\n if (nodes.length === 1) {\n nodes[0].x = centerX;\n nodes[0].y = centerY;\n return nodes;\n }\n\n const spacing = nodeHeight + vGap;\n const totalHeight = (nodes.length - 1) * spacing;\n const startY = centerY - totalHeight / 2;\n\n for (let i = 0; i < nodes.length; i++) {\n nodes[i].x = centerX;\n nodes[i].y = startY + i * spacing;\n }\n\n return nodes;\n}\n","// ─── .visualli → FlatNode Converter ──────────────────────────────────────────\n//\n// Transforms the layer-based .visualli format into the flat Map<id, FlatNode>\n// structure consumed by the canvas renderer.\n\nimport type { VisualliDocument } from '../types/document.js';\nimport type { VisualliLayer } from '../types/layer.js';\nimport type { FlatNode, NodeMap } from '../types/mindmap.js';\nimport { countLayersBeneath } from './visualliParser.js';\nimport { ideaColor } from '../theme/index.js';\nimport { approximateMeasure, ideaKindOf, ideaSize, type IdeaMeasure } from '../rendering/ideaSize.js';\nimport { applyCircularLayout, calculateOptimalRadiusPercentage } from '../layout/circularLayout.js';\nimport { applyLinearHorizontalLayout, applyLinearVerticalLayout } from '../layout/linearLayout.js';\n\n// ── Overlap Resolution ────────────────────────────────────────────────────────\n\nfunction doNodesOverlap(n1: FlatNode, n2: FlatNode, padding = 20): boolean {\n return !(\n n1.x + n1.width / 2 + padding < n2.x - n2.width / 2 - padding ||\n n1.x - n1.width / 2 - padding > n2.x + n2.width / 2 + padding ||\n n1.y + n1.height / 2 + padding < n2.y - n2.height / 2 - padding ||\n n1.y - n1.height / 2 - padding > n2.y + n2.height / 2 + padding\n );\n}\n\n/** Iteratively push overlapping nodes apart using symmetric force separation. */\nexport function resolveNodeOverlaps(nodes: FlatNode[], maxIterations = 10): void {\n const padding = 150;\n\n for (let iter = 0; iter < maxIterations; iter++) {\n let any = false;\n for (let i = 0; i < nodes.length; i++) {\n for (let j = i + 1; j < nodes.length; j++) {\n const n1 = nodes[i];\n const n2 = nodes[j];\n if (!doNodesOverlap(n1, n2, padding)) continue;\n\n any = true;\n const dx = n2.x - n1.x;\n const dy = n2.y - n1.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < 1) {\n n2.x += n2.width / 2 + padding;\n continue;\n }\n\n const minDist = (n1.width + n2.width) / 2 + padding;\n if (dist < minDist) {\n const push = (minDist - dist) / 2;\n n1.x -= (dx / dist) * push;\n n1.y -= (dy / dist) * push;\n n2.x += (dx / dist) * push;\n n2.y += (dy / dist) * push;\n }\n }\n }\n if (!any) break;\n }\n}\n\n// ── Options ───────────────────────────────────────────────────────────────────\n\nexport interface ConvertOptions {\n /** Measures label text in the idea face (the renderer's font engine); ideas are sized with the design system's\n * ideaSize. Defaults to an approximation (half an em per character) where no font engine exists. */\n measure?: IdeaMeasure;\n /** Label scale (comfort: larger text is 1.15); ideas grow to fit the larger label. */\n labelScale?: number;\n}\n\n/** Whether a layer's ideas carry their own positions: every idea has one, and (with more than one idea) they aren't\n * all on the same spot (a placeholder). Then the file's positions are used as they are. */\nfunction hasFilePositions(layer: VisualliLayer): boolean {\n const ps = layer.nodes.map((n) => n.position);\n if (!ps.length || !ps.every((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y))) return false;\n return ps.length === 1 || ps.some((p) => p!.x !== ps[0]!.x || p!.y !== ps[0]!.y);\n}\n\n// ── Container-formation Layout ────────────────────────────────────────────────\n\ninterface Proxy { id: string; x: number; y: number; width: number; height: number }\n\nfunction applyFormation(nodes: FlatNode[], formation: string): void {\n if (nodes.length === 0) return;\n if (nodes.length === 1) { nodes[0].x = 0; nodes[0].y = 0; return; }\n if (formation === 'linear-horizontal' || formation === 'linear') {\n applyLinearHorizontalLayout(nodes, { centerX: 0, centerY: 0 });\n } else if (formation === 'linear-vertical') {\n applyLinearVerticalLayout(nodes, { centerX: 0, centerY: 0 });\n } else {\n const r = Math.max(250, nodes.length * 70);\n const step = (2 * Math.PI) / nodes.length;\n for (let i = 0; i < nodes.length; i++) {\n nodes[i].x = r * Math.cos(i * step);\n nodes[i].y = r * Math.sin(i * step);\n }\n }\n}\n\nfunction containerBBox(nodes: FlatNode[], padding: number): { width: number; height: number } {\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n for (const n of nodes) {\n minX = Math.min(minX, n.x - n.width / 2);\n maxX = Math.max(maxX, n.x + n.width / 2);\n minY = Math.min(minY, n.y - n.height / 2);\n maxY = Math.max(maxY, n.y + n.height / 2);\n }\n return { width: maxX - minX + padding * 2, height: maxY - minY + padding * 2 };\n}\n\nfunction proxyLinearH(proxies: Proxy[], gap = 180): void {\n const total = proxies.reduce((s, p) => s + p.width, 0) + gap * (proxies.length - 1);\n let x = -total / 2;\n for (const p of proxies) { p.x = x + p.width / 2; p.y = 0; x += p.width + gap; }\n}\n\nfunction proxyLinearV(proxies: Proxy[], gap = 180): void {\n const total = proxies.reduce((s, p) => s + p.height, 0) + gap * (proxies.length - 1);\n let y = -total / 2;\n for (const p of proxies) { p.x = 0; p.y = y + p.height / 2; y += p.height + gap; }\n}\n\nfunction proxyRadial(proxies: Proxy[], radius = 500): void {\n if (proxies.length === 1) { proxies[0].x = 0; proxies[0].y = 0; return; }\n // Start at top (12 o'clock) for n>=3, horizontal for n=2 (matches circular layout)\n const startAngle = proxies.length === 2 ? 0 : -Math.PI / 2;\n const step = (2 * Math.PI) / proxies.length;\n for (let i = 0; i < proxies.length; i++) {\n const angle = startAngle + i * step;\n proxies[i].x = radius * Math.cos(angle);\n proxies[i].y = radius * Math.sin(angle);\n }\n}\n\n// ── Layer Conversion ──────────────────────────────────────────────────────────\n\nfunction makeFlatNode(\n node: VisualliLayer['nodes'][number],\n layer: VisualliLayer,\n doc: VisualliDocument,\n /** Position among the layer's ideas (file order): missing colours cycle the topics by it, and the first idea of the root radial layer is the root. */\n siblingIndex: number,\n opts: ConvertOptions,\n): FlatNode {\n const label = Array.isArray(node.data.label) ? (node.data.label as string[]).join(' ') : (node.data.label || 'Untitled');\n const branchCount = countLayersBeneath(doc, node.id);\n const kind = ideaKindOf(layer, siblingIndex);\n const size = ideaSize(kind, label, opts.measure ?? approximateMeasure, opts.labelScale ?? 1);\n const { topic, custom } = ideaColor(node.data.color, siblingIndex);\n return {\n id: node.id,\n parentId: layer.parentNodeId ?? null,\n x: node.position?.x ?? 0,\n y: node.position?.y ?? 0,\n level: layer.level,\n title: label,\n description: node.data.summary || '',\n color: node.data.color ?? '',\n ...(topic ? { topic } : {}),\n ...(custom ? { custom } : {}),\n kind,\n width: size.width,\n height: size.height,\n isExpanded: branchCount > 0,\n branchCount,\n createdAt: new Date(),\n updatedAt: new Date(),\n };\n}\n\nfunction layoutLayerWithContainers(layer: VisualliLayer, flatNodes: FlatNode[]): void {\n const PADDING = 80;\n const byId = new Map(flatNodes.map((n: FlatNode) => [n.id, n]));\n const containerNodeIds = new Set<string>();\n const containerGroups = new Map<string, FlatNode[]>();\n\n for (const container of layer.containers) {\n const group = container.nodes.map((id: string) => byId.get(id)).filter((n: FlatNode | undefined): n is FlatNode => !!n);\n if (!group.length) continue;\n container.nodes.forEach((id: string) => containerNodeIds.add(id));\n const formation = ((container.data as unknown as Record<string, unknown> | undefined)?.['formation'] as string | undefined) ?? 'radial';\n applyFormation(group, formation);\n containerGroups.set(container.id, group);\n }\n\n const proxies: Proxy[] = [];\n for (const n of flatNodes) {\n if (!containerNodeIds.has(n.id)) proxies.push({ id: n.id, x: 0, y: 0, width: n.width, height: n.height });\n }\n for (const container of layer.containers) {\n const group = containerGroups.get(container.id);\n if (!group?.length) continue;\n const bbox = containerBBox(group, PADDING);\n proxies.push({ id: `__c__${container.id}`, x: 0, y: 0, width: bbox.width, height: bbox.height });\n }\n\n const layout = layer.layout || 'radial';\n if (layout === 'linear-horizontal') proxyLinearH(proxies, 180);\n else if (layout === 'linear-vertical') proxyLinearV(proxies, 180);\n else proxyRadial(proxies, 500);\n\n for (const proxy of proxies) {\n if (proxy.id.startsWith('__c__')) {\n const group = containerGroups.get(proxy.id.slice(5));\n group?.forEach(n => { n.x += proxy.x; n.y += proxy.y; });\n } else {\n const fn = byId.get(proxy.id);\n if (fn) { fn.x = proxy.x; fn.y = proxy.y; }\n }\n }\n}\n\nfunction layoutLayer(layer: VisualliLayer, flatNodes: FlatNode[]): void {\n const layout = layer.layout || 'radial';\n if (layout === 'linear-horizontal') {\n applyLinearHorizontalLayout(flatNodes, { centerX: 0, centerY: 0 });\n } else if (layout === 'linear-vertical') {\n applyLinearVerticalLayout(flatNodes, { centerX: 0, centerY: 0 });\n } else {\n const pct = calculateOptimalRadiusPercentage(flatNodes.length, 2000, 2000, 200, 30);\n applyCircularLayout(flatNodes, {\n radiusPercentage: pct,\n containerWidth: 2000,\n containerHeight: 2000,\n centerX: 0,\n centerY: 0,\n });\n }\n}\n\n/**\n * Convert a single layer to an array of FlatNode objects, each sized for its label\n * (the design system's idea.ts) and coloured by its colour rule (color.ts).\n * Positions: the file's own when its ideas carry them; otherwise the SDK lays the\n * layer out by `layer.layout` (default radial) and container formations.\n */\nexport function convertLayerToFlatNodes(\n layer: VisualliLayer,\n doc: VisualliDocument,\n opts: ConvertOptions = {},\n): FlatNode[] {\n const flatNodes = layer.nodes.map((node, i) => makeFlatNode(node, layer, doc, i, opts));\n if (flatNodes.length === 0 || hasFilePositions(layer)) return flatNodes;\n for (const n of flatNodes) { n.x = 0; n.y = 0; }\n if ((layer.containers ?? []).length > 0) layoutLayerWithContainers(layer, flatNodes);\n else layoutLayer(layer, flatNodes);\n resolveNodeOverlaps(flatNodes);\n return flatNodes;\n}\n\n/**\n * Convert an entire .visualli document to a flat NodeMap.\n * All layers are converted and a children-index is built for O(1) tree traversal.\n */\nexport function convertVisualliToFlatNodes(doc: VisualliDocument, opts: ConvertOptions = {}): NodeMap {\n const map: NodeMap = new Map();\n\n for (const layer of doc.layers.values()) {\n for (const node of convertLayerToFlatNodes(layer, doc, opts)) {\n map.set(node.id, node);\n }\n }\n\n // Build children index\n for (const node of map.values()) {\n node.childrenIds = [];\n for (const candidate of map.values()) {\n if (candidate.parentId === node.id) node.childrenIds.push(candidate.id);\n }\n }\n\n return map;\n}\n\n/**\n * Get flat nodes for a specific layer only.\n *\n * @param doc - Parsed .visualli document\n * @param layerId - Layer ID to extract\n * @param opts - Text measurement and label scale for sizing ideas\n * @returns FlatNode array, or empty array if layer not found\n */\nexport function getNodesForLayer(doc: VisualliDocument, layerId: string, opts: ConvertOptions = {}): FlatNode[] {\n const layer = doc.layers.get(layerId);\n return layer ? convertLayerToFlatNodes(layer, doc, opts) : [];\n}\n","// ─── Mindmap Tree Utilities ───────────────────────────────────────────────────\n\nimport type { MindMapNode, TopLevelConnection } from '../types/mindmap.js';\n\n/** Flatten a nested MindMapNode tree into a depth-first array. */\nexport function flattenNodes(nodes: MindMapNode[]): MindMapNode[] {\n const result: MindMapNode[] = [];\n const traverse = (list: MindMapNode[]) => {\n for (const n of list) {\n result.push(n);\n if (n.children) traverse(n.children);\n }\n };\n traverse(nodes);\n return result;\n}\n\n/**\n * Return nodes visible at the given zoom level.\n *\n * At lower zoom values only top-level nodes are shown; each 5% zoom increment\n * reveals one additional hierarchy level.\n */\nexport function getVisibleNodes(\n nodes: MindMapNode[],\n zoom: number,\n focusedNode?: string,\n): MindMapNode[] {\n const flat = flattenNodes(nodes);\n\n if (focusedNode) {\n const focused = flat.find(n => n.id === focusedNode);\n if (focused) {\n return focused.children ? [focused, ...focused.children] : [focused];\n }\n }\n\n // Map zoom to max visible level (level 0 at ≤70%, +1 level per 5% increment)\n if (zoom <= 0.70) return flat.filter(n => n.level === 0);\n const maxLevel = Math.floor((zoom - 0.70) / 0.05);\n return flat.filter(n => n.level <= maxLevel);\n}\n\n/** Build parent→child connection pairs from the node tree. */\nexport function getNodeConnections(\n nodes: MindMapNode[],\n): Array<{ from: MindMapNode; to: MindMapNode; label?: string }> {\n const flat = flattenNodes(nodes);\n const result: Array<{ from: MindMapNode; to: MindMapNode; label?: string }> = [];\n for (const n of flat) {\n if (!n.parent) continue;\n const parent = flat.find(p => p.id === n.parent);\n if (parent) result.push({ from: parent, to: n, label: n.relationshipLabel });\n }\n return result;\n}\n\n/** Resolve top-level cross-connections to node pairs. */\nexport function getTopLevelConnections(\n nodes: MindMapNode[],\n topLevelConnections: TopLevelConnection[],\n): Array<{ from: MindMapNode; to: MindMapNode; label: string }> {\n const flat = flattenNodes(nodes);\n const result: Array<{ from: MindMapNode; to: MindMapNode; label: string }> = [];\n for (const conn of topLevelConnections) {\n const from = flat.find(n => n.id === conn.from);\n const to = flat.find(n => n.id === conn.to);\n if (from && to) result.push({ from, to, label: conn.label ?? '' });\n }\n return result;\n}\n\n/** Euclidean distance between two world-space points. */\nexport function calculateDistance(x1: number, y1: number, x2: number, y2: number): number {\n return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n}\n","// ─── Layout constants ────────────────────────────────────────────────────────\n//\n// Non-visual layout metrics (world units). Everything visual (colours, fonts,\n// radii, spacing, motion) comes from the design system: see ../theme.\n\nexport const LAYOUT_SPACING = {\n nodeSpacing: 200,\n levelSpacing: 150,\n containerPadding: 20,\n gridSize: 50,\n} as const;\n","// ─── MindMapConfig Utilities ──────────────────────────────────────────────────\n//\n// Helpers for creating and generating MindMapConfig objects (pure data, no UI).\n\nimport type { MindMapNode, MindMapConfig, TopLevelConnection } from '../types/mindmap.js';\nimport { LAYOUT_SPACING } from '../constants/layout.js';\nimport { TOKENS, TOPICS } from '../theme/index.js';\n\n/** Light-theme fill of the topic used for a level (cycles through the design-system topics). */\nconst levelColor = (level: number): string => TOKENS.light[`topic-${TOPICS[level % TOPICS.length]}`]!;\n\ntype LevelColors = { level0: string; level1: string; level2: string; level3: string; [key: `level${number}`]: string };\nconst levelColors = (count: number): LevelColors =>\n Object.fromEntries(Array.from({ length: count }, (_, i) => [`level${i}`, levelColor(i)])) as LevelColors;\n\nexport function createMindMapConfig(\n nodes: MindMapNode[],\n topLevelConnections: TopLevelConnection[],\n title = 'Untitled Mindmap',\n): MindMapConfig {\n const now = new Date().toISOString();\n return {\n metadata: {\n title,\n description: `Interactive mindmap with ${nodes.length} nodes`,\n version: '1.0.0',\n created: now,\n lastModified: now,\n },\n nodes,\n topLevelConnections,\n settings: {\n defaultColors: levelColors(4),\n layout: {\n nodeSpacing: LAYOUT_SPACING.nodeSpacing,\n levelSpacing: LAYOUT_SPACING.levelSpacing,\n },\n },\n };\n}\n\n// ── Sample Data Generator ─────────────────────────────────────────────────────\n\nfunction generateId(prefix: string, level: number, index: number): string {\n return `${prefix}-l${level}-${index}`;\n}\n\nfunction generateLevelNodes(\n parentId: string | null,\n level: number,\n maxLevels: number,\n xOffset = 0,\n yOffset = 0,\n): MindMapNode[] {\n if (level >= maxLevels) return [];\n\n const count = 5;\n const levelSpacing = 200;\n const nodeSpacing = 300;\n const nodes: MindMapNode[] = [];\n\n for (let i = 0; i < count; i++) {\n const nodeId = parentId\n ? generateId(`${parentId}-${i}`, level, i)\n : generateId('root', level, i);\n\n const x = xOffset + (i - (count - 1) / 2) * nodeSpacing;\n const y = yOffset + level * levelSpacing;\n\n const node: MindMapNode = {\n id: nodeId,\n title: `Level ${level} Node ${i + 1}`,\n level,\n x,\n y,\n color: levelColor(level),\n relationshipLabel: level > 0 ? 'child' : undefined,\n parent: parentId ?? undefined,\n };\n\n const children = generateLevelNodes(nodeId, level + 1, maxLevels, x, y + levelSpacing);\n if (children.length > 0) node.children = children;\n\n nodes.push(node);\n }\n\n return nodes;\n}\n\n/**\n * Generate a sample MindMapConfig with `maxLevels` of hierarchy.\n * Useful for testing and demos.\n */\nexport function generateSampleConfig(maxLevels = 9): MindMapConfig {\n const nodes = generateLevelNodes(null, 0, maxLevels, 0, 0);\n\n const topLevelConnections: TopLevelConnection[] = nodes.slice(0, -1).map((n, i) => ({\n from: n.id,\n to: nodes[i + 1].id,\n label: 'related to',\n }));\n\n return {\n metadata: {\n id: `mindmap-${Date.now()}`,\n title: 'Sample Mind Map',\n description: 'A sample mind map',\n version: '1.0.0',\n created: new Date().toISOString(),\n lastModified: new Date().toISOString(),\n },\n nodes,\n topLevelConnections,\n settings: {\n defaultColors: levelColors(9),\n layout: {\n nodeSpacing: LAYOUT_SPACING.nodeSpacing,\n levelSpacing: LAYOUT_SPACING.levelSpacing,\n },\n },\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/parser/index.ts","../../src/parser/visualliParser.ts","../../src/generated/designSystem.ts","../../src/generated/geometry/color.ts","../../src/theme/index.ts","../../src/generated/geometry/idea.ts","../../src/rendering/ideaSize.ts","../../src/layout/circularLayout.ts","../../src/layout/linearLayout.ts","../../src/parser/visualliConverter.ts","../../src/parser/mindmapUtils.ts","../../src/constants/layout.ts","../../src/parser/configUtils.ts"],"sourcesContent":["export * from './visualliParser.js';\nexport * from './visualliConverter.js';\nexport * from './mindmapUtils.js';\nexport * from './configUtils.js';\n","// ─── .visualli File Parser ────────────────────────────────────────────────────\n//\n// Reads JSONL (JSON Lines) format and parses into a structured VisualliDocument.\n\nimport type { VisualliDocument, SemanticAnchor } from '../types/document.js';\nimport type { VisualliMeta } from '../types/meta.js';\nimport type { VisualliLayer } from '../types/layer.js';\nimport type { Layer } from '../types/schema.js';\n\n/**\n * Convert schema Layer to VisualliLayer by ensuring required arrays exist.\n */\nfunction toVisualliLayer(schemaLayer: Layer): VisualliLayer {\n return {\n type: 'layer',\n id: schemaLayer.id,\n level: schemaLayer.level,\n parentLayerId: schemaLayer.parentLayerId,\n parentNodeId: schemaLayer.parentNodeId,\n layout: schemaLayer.layout,\n nodes: schemaLayer.nodes ?? [],\n connections: schemaLayer.connections ?? [],\n containers: schemaLayer.containers ?? [],\n };\n}\n\nexport class VisualliParseError extends Error {\n constructor(message: string, public readonly lineNumber?: number) {\n super(message);\n this.name = 'VisualliParseError';\n }\n}\n\n/**\n * Parse a .visualli file content (JSONL format) into a VisualliDocument.\n *\n * @throws VisualliParseError on malformed input\n */\nexport function parseVisualliFile(content: string): VisualliDocument {\n const lines = content.trim().split('\\n');\n\n const doc: VisualliDocument = {\n meta: null as unknown as VisualliMeta,\n layers: new Map(),\n layersByLevel: new Map(),\n rootLayer: null,\n };\n\n let lineNumber = 0;\n\n for (const line of lines) {\n lineNumber++;\n if (!line.trim()) continue;\n\n let obj: Record<string, unknown>;\n try {\n obj = JSON.parse(line) as Record<string, unknown>;\n } catch (err) {\n throw new VisualliParseError(\n `Failed to parse JSON at line ${lineNumber}: ${err}`,\n lineNumber,\n );\n }\n\n if (!obj['type']) {\n throw new VisualliParseError(\n `Missing 'type' field at line ${lineNumber}`,\n lineNumber,\n );\n }\n\n switch (obj['type']) {\n case 'meta':\n doc.meta = obj as unknown as VisualliMeta;\n break;\n\n case 'layer': {\n // Convert schema Layer to VisualliLayer\n const schemaLayer = obj as unknown as Layer;\n const layer = toVisualliLayer(schemaLayer);\n \n doc.layers.set(layer.id, layer);\n\n if (!doc.layersByLevel.has(layer.level)) {\n doc.layersByLevel.set(layer.level, []);\n }\n doc.layersByLevel.get(layer.level)!.push(layer);\n\n if (layer.level === 0) {\n doc.rootLayer = layer;\n }\n break;\n }\n\n case 'extension': {\n const id = obj['id'];\n if (typeof id === 'string') {\n (doc.extensions ??= {})[id] = Array.isArray(obj['data']) ? (obj['data'] as unknown[]) : [];\n }\n break;\n }\n\n default:\n // Unknown type — silently skip\n break;\n }\n }\n\n if (!doc.meta) throw new VisualliParseError('Missing required meta section');\n if (!doc.rootLayer) throw new VisualliParseError('Missing root layer (level 0)');\n\n return doc;\n}\n\nexport async function fetchAndParseVisualli(url: string): Promise<VisualliDocument> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n return parseVisualliFile(await response.text());\n}\n\n/**\n * Parse .visualli JSONL data as returned from the MongoDB `visualli` field.\n *\n * @throws VisualliParseError\n */\nexport function parseVisualliFromMongoDB(visualliJsonl: string): VisualliDocument {\n if (!visualliJsonl || typeof visualliJsonl !== 'string') {\n throw new VisualliParseError('Invalid visualli data: expected a JSONL string');\n }\n const trimmed = visualliJsonl.trim();\n if (!trimmed) throw new VisualliParseError('Empty visualli data from MongoDB');\n return parseVisualliFile(trimmed);\n}\n\n/**\n * Parse a .visualli file from a browser `File` object.\n * (Browser-only – requires `FileReader`.)\n */\nexport function loadVisualliFileFromFile(file: File): Promise<VisualliDocument> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = e => {\n try {\n resolve(parseVisualliFile(e.target?.result as string));\n } catch (err) {\n reject(err);\n }\n };\n reader.onerror = () => reject(new Error('Failed to read file'));\n reader.readAsText(file);\n });\n}\n\n// ── Tree Helpers ──────────────────────────────────────────────────────────────\n\n/** Return all layers whose `parentNodeId` matches the given node ID. */\n/** Terms defined by the document's `semantic-anchors` extension (empty when absent). */\nexport function getSemanticAnchors(doc: VisualliDocument): SemanticAnchor[] {\n const raw = doc.extensions?.['semantic-anchors'];\n if (!Array.isArray(raw)) return [];\n return raw.filter((a): a is SemanticAnchor => !!a && typeof (a as SemanticAnchor).word === 'string' && typeof (a as SemanticAnchor).description === 'string');\n}\n\nexport function getChildLayers(\n doc: VisualliDocument,\n nodeId: string,\n): VisualliLayer[] {\n const result: VisualliLayer[] = [];\n for (const layer of doc.layers.values()) {\n if (layer.parentNodeId === nodeId) result.push(layer);\n }\n return result;\n}\n\n/**\n * Count the maximum depth of layers beneath a node (its \"magnitude\").\n * Returns 0 when the node has no child layers.\n */\nexport function countLayersBeneath(\n doc: VisualliDocument,\n nodeId: string,\n visited = new Set<string>(),\n): number {\n if (visited.has(nodeId)) return 0;\n visited.add(nodeId);\n\n const children = getChildLayers(doc, nodeId);\n if (children.length === 0) return 0;\n\n let maxDepth = 0;\n for (const layer of children) {\n let depth = 1;\n for (const node of layer.nodes) {\n depth = Math.max(depth, 1 + countLayersBeneath(doc, node.id, visited));\n }\n maxDepth = Math.max(maxDepth, depth);\n }\n return maxDepth;\n}\n","// GENERATED by scripts/gen-design-system.mjs from design-system/ (tokens/tokens.json, tokens/tokens.css). Do not edit.\n// Change the design system instead; the next `npm run build` regenerates this file.\n\n/** Version of the design system these modules were generated from. */\nexport const DESIGN_SYSTEM_VERSION = \"0.3.0\" as const;\n\nexport const THEME_NAMES = [\n \"light\",\n \"dark\",\n \"focus-light\",\n \"focus-dark\",\n \"colorsafe-light\",\n \"colorsafe-dark\",\n \"contrast-light\",\n \"contrast-dark\"\n] as const;\nexport type ThemeName = (typeof THEME_NAMES)[number];\n\n/** Every token for every theme (each theme already merged over \"light\"). Keys match the CSS custom properties. */\nexport const TOKENS: Readonly<Record<ThemeName, Readonly<Record<string, string>>>> = {\n \"light\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#f6f3ee\",\n \"surface\": \"#ffffff\",\n \"surface-sunken\": \"#f0ece5\",\n \"surface-overlay\": \"#ffffff\",\n \"line\": \"#e4dfd6\",\n \"line-strong\": \"#7a7f94\",\n \"ink\": \"#182140\",\n \"ink-muted\": \"#4f5671\",\n \"ink-subtle\": \"#5f647c\",\n \"action\": \"#182140\",\n \"on-action\": \"#ffffff\",\n \"focus\": \"#325e8c\",\n \"link\": \"#2f5a87\",\n \"selection\": \"rgba(18, 199, 211, 0.28)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#2a3048\",\n \"edge-label\": \"#4f5671\",\n \"topic-teal\": \"#87f2f8\",\n \"topic-teal-ring\": \"#00cdd5\",\n \"topic-harbor\": \"#bcdbff\",\n \"topic-harbor-ring\": \"#76b2f5\",\n \"topic-iris\": \"#e0c8fe\",\n \"topic-iris-ring\": \"#bd96ea\",\n \"topic-berry\": \"#ffbdc4\",\n \"topic-berry-ring\": \"#f47e8f\",\n \"topic-coral\": \"#ffc7b2\",\n \"topic-coral-ring\": \"#f38e65\",\n \"topic-amber\": \"#ffcf9d\",\n \"topic-amber-ring\": \"#eb9c38\",\n \"topic-sun\": \"#ffea94\",\n \"topic-sun-ring\": \"#dfbd04\",\n \"topic-stone\": \"#e0dacf\",\n \"topic-stone-ring\": \"#bab09f\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"dark\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#0f1220\",\n \"surface\": \"#171b2b\",\n \"surface-sunken\": \"#0f1220\",\n \"surface-overlay\": \"#212639\",\n \"line\": \"#2b3148\",\n \"line-strong\": \"#6c7392\",\n \"ink\": \"#eef0f7\",\n \"ink-muted\": \"#b3b8cc\",\n \"ink-subtle\": \"#8f95ae\",\n \"action\": \"#f6f3ee\",\n \"on-action\": \"#182140\",\n \"focus\": \"#12c7d3\",\n \"link\": \"#5fd8e1\",\n \"selection\": \"rgba(18, 199, 211, 0.32)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#c9cddc\",\n \"edge-label\": \"#b3b8cc\",\n \"topic-teal\": \"#87f2f8\",\n \"topic-teal-ring\": \"#0fc5cd\",\n \"topic-harbor\": \"#bcdbff\",\n \"topic-harbor-ring\": \"#73aceb\",\n \"topic-iris\": \"#e0c8fe\",\n \"topic-iris-ring\": \"#b691e1\",\n \"topic-berry\": \"#ffbdc4\",\n \"topic-berry-ring\": \"#eb798a\",\n \"topic-coral\": \"#ffc7b2\",\n \"topic-coral-ring\": \"#ea8962\",\n \"topic-amber\": \"#ffcf9d\",\n \"topic-amber-ring\": \"#e29737\",\n \"topic-sun\": \"#ffea94\",\n \"topic-sun-ring\": \"#d8b70a\",\n \"topic-stone\": \"#e0dacf\",\n \"topic-stone-ring\": \"#b4a999\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(0, 0, 0, 0.40), 0 8px 24px rgba(0, 0, 0, 0.35)\",\n \"shadow-pop\": \"0 2px 4px rgba(0, 0, 0, 0.50), 0 16px 40px rgba(0, 0, 0, 0.50)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"focus-light\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#f4f2ee\",\n \"surface\": \"#ffffff\",\n \"surface-sunken\": \"#f0ece5\",\n \"surface-overlay\": \"#ffffff\",\n \"line\": \"#e4dfd6\",\n \"line-strong\": \"#7a7f94\",\n \"ink\": \"#182140\",\n \"ink-muted\": \"#4f5671\",\n \"ink-subtle\": \"#5f647c\",\n \"action\": \"#182140\",\n \"on-action\": \"#ffffff\",\n \"focus\": \"#325e8c\",\n \"link\": \"#2f5a87\",\n \"selection\": \"rgba(18, 199, 211, 0.28)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#5a6079\",\n \"edge-label\": \"#5a6079\",\n \"topic-teal\": \"#bce8ea\",\n \"topic-teal-ring\": \"#67c6cb\",\n \"topic-harbor\": \"#c9d9ec\",\n \"topic-harbor-ring\": \"#8bb2de\",\n \"topic-iris\": \"#d9cfe8\",\n \"topic-iris-ring\": \"#b79ed4\",\n \"topic-berry\": \"#edc6c9\",\n \"topic-berry-ring\": \"#da9099\",\n \"topic-coral\": \"#eecec1\",\n \"topic-coral-ring\": \"#db9b82\",\n \"topic-amber\": \"#eed4ba\",\n \"topic-amber-ring\": \"#d6a570\",\n \"topic-sun\": \"#f4eac1\",\n \"topic-sun-ring\": \"#d2bf73\",\n \"topic-stone\": \"#dddad5\",\n \"topic-stone-ring\": \"#bab09f\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"focus-dark\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#12141c\",\n \"surface\": \"#171b2b\",\n \"surface-sunken\": \"#0f1220\",\n \"surface-overlay\": \"#212639\",\n \"line\": \"#2b3148\",\n \"line-strong\": \"#6c7392\",\n \"ink\": \"#eef0f7\",\n \"ink-muted\": \"#b3b8cc\",\n \"ink-subtle\": \"#8f95ae\",\n \"action\": \"#f6f3ee\",\n \"on-action\": \"#182140\",\n \"focus\": \"#12c7d3\",\n \"link\": \"#5fd8e1\",\n \"selection\": \"rgba(18, 199, 211, 0.32)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#a9aec0\",\n \"edge-label\": \"#b3b8cc\",\n \"topic-teal\": \"#bce8ea\",\n \"topic-teal-ring\": \"#71bdc1\",\n \"topic-harbor\": \"#c9d9ec\",\n \"topic-harbor-ring\": \"#8cabce\",\n \"topic-iris\": \"#d9cfe8\",\n \"topic-iris-ring\": \"#ae9bc6\",\n \"topic-berry\": \"#edc6c9\",\n \"topic-berry-ring\": \"#cc8e95\",\n \"topic-coral\": \"#eecec1\",\n \"topic-coral-ring\": \"#cd9884\",\n \"topic-amber\": \"#eed4ba\",\n \"topic-amber-ring\": \"#c9a176\",\n \"topic-sun\": \"#f4eac1\",\n \"topic-sun-ring\": \"#c9b97a\",\n \"topic-stone\": \"#dddad5\",\n \"topic-stone-ring\": \"#b4a999\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"colorsafe-light\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#f6f3ee\",\n \"surface\": \"#ffffff\",\n \"surface-sunken\": \"#f0ece5\",\n \"surface-overlay\": \"#ffffff\",\n \"line\": \"#e4dfd6\",\n \"line-strong\": \"#7a7f94\",\n \"ink\": \"#182140\",\n \"ink-muted\": \"#4f5671\",\n \"ink-subtle\": \"#5f647c\",\n \"action\": \"#182140\",\n \"on-action\": \"#ffffff\",\n \"focus\": \"#325e8c\",\n \"link\": \"#2f5a87\",\n \"selection\": \"rgba(18, 199, 211, 0.28)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#2a3048\",\n \"edge-label\": \"#4f5671\",\n \"topic-teal\": \"#b0ecbc\",\n \"topic-teal-ring\": \"#6cc982\",\n \"topic-harbor\": \"#abdbfe\",\n \"topic-harbor-ring\": \"#60b4ec\",\n \"topic-iris\": \"#f6bde2\",\n \"topic-iris-ring\": \"#dc87c0\",\n \"topic-berry\": \"#feb79e\",\n \"topic-berry-ring\": \"#ec7f58\",\n \"topic-coral\": \"#fece96\",\n \"topic-coral-ring\": \"#e49d41\",\n \"topic-amber\": \"#b2e8fa\",\n \"topic-amber-ring\": \"#5cc4e2\",\n \"topic-sun\": \"#f6f097\",\n \"topic-sun-ring\": \"#d0c637\",\n \"topic-stone\": \"#dbdbdb\",\n \"topic-stone-ring\": \"#b7afb1\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"colorsafe-dark\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#0f1220\",\n \"surface\": \"#171b2b\",\n \"surface-sunken\": \"#0f1220\",\n \"surface-overlay\": \"#212639\",\n \"line\": \"#2b3148\",\n \"line-strong\": \"#6c7392\",\n \"ink\": \"#eef0f7\",\n \"ink-muted\": \"#b3b8cc\",\n \"ink-subtle\": \"#8f95ae\",\n \"action\": \"#f6f3ee\",\n \"on-action\": \"#182140\",\n \"focus\": \"#12c7d3\",\n \"link\": \"#5fd8e1\",\n \"selection\": \"rgba(18, 199, 211, 0.32)\",\n \"node-ink\": \"#182140\",\n \"edge\": \"#c9cddc\",\n \"edge-label\": \"#b3b8cc\",\n \"topic-teal\": \"#b0ecbc\",\n \"topic-teal-ring\": \"#69c27e\",\n \"topic-harbor\": \"#abdbfe\",\n \"topic-harbor-ring\": \"#5eade2\",\n \"topic-iris\": \"#f6bde2\",\n \"topic-iris-ring\": \"#d383b9\",\n \"topic-berry\": \"#feb79e\",\n \"topic-berry-ring\": \"#e37a55\",\n \"topic-coral\": \"#fece96\",\n \"topic-coral-ring\": \"#db9840\",\n \"topic-amber\": \"#b2e8fa\",\n \"topic-amber-ring\": \"#5bbdda\",\n \"topic-sun\": \"#f6f097\",\n \"topic-sun-ring\": \"#c9bf37\",\n \"topic-stone\": \"#dbdbdb\",\n \"topic-stone-ring\": \"#b1a8aa\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08)\",\n \"shadow-pop\": \"0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14)\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"contrast-light\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#ffffff\",\n \"surface\": \"#ffffff\",\n \"surface-sunken\": \"#f2f2f2\",\n \"surface-overlay\": \"#ffffff\",\n \"line\": \"#5c6178\",\n \"line-strong\": \"#000000\",\n \"ink\": \"#000000\",\n \"ink-muted\": \"#1f2433\",\n \"ink-subtle\": \"#3a3f52\",\n \"action\": \"#000000\",\n \"on-action\": \"#ffffff\",\n \"focus\": \"#0b4a8f\",\n \"link\": \"#0b4a8f\",\n \"selection\": \"rgba(18, 199, 211, 0.28)\",\n \"node-ink\": \"#000000\",\n \"edge\": \"#000000\",\n \"edge-label\": \"#1f2433\",\n \"topic-teal\": \"#87f2f8\",\n \"topic-teal-ring\": \"#006b70\",\n \"topic-harbor\": \"#bcdbff\",\n \"topic-harbor-ring\": \"#0e599d\",\n \"topic-iris\": \"#e0c8fe\",\n \"topic-iris-ring\": \"#683b92\",\n \"topic-berry\": \"#ffbdc4\",\n \"topic-berry-ring\": \"#96173a\",\n \"topic-coral\": \"#ffc7b2\",\n \"topic-coral-ring\": \"#923400\",\n \"topic-amber\": \"#ffcf9d\",\n \"topic-amber-ring\": \"#7e4d00\",\n \"topic-sun\": \"#ffea94\",\n \"topic-sun-ring\": \"#7a6600\",\n \"topic-stone\": \"#e0dacf\",\n \"topic-stone-ring\": \"#63594b\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"none\",\n \"shadow-pop\": \"none\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n },\n \"contrast-dark\": {\n \"font-display\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, sans-serif\",\n \"font-ui\": \"\\\"Atkinson Hyperlegible Next\\\", system-ui, -apple-system, \\\"Segoe UI\\\", sans-serif\",\n \"font-hand\": \"Kalam, \\\"Atkinson Hyperlegible Next\\\", cursive\",\n \"font-note\": \"Caveat, Kalam, cursive\",\n \"font-mono\": \"\\\"Atkinson Hyperlegible Mono\\\", ui-monospace, \\\"SF Mono\\\", Menlo, monospace\",\n \"canvas\": \"#000000\",\n \"surface\": \"#000000\",\n \"surface-sunken\": \"#0d0d0d\",\n \"surface-overlay\": \"#0d0d0d\",\n \"line\": \"#9aa0b8\",\n \"line-strong\": \"#ffffff\",\n \"ink\": \"#ffffff\",\n \"ink-muted\": \"#e6e8f0\",\n \"ink-subtle\": \"#c8ccda\",\n \"action\": \"#ffffff\",\n \"on-action\": \"#000000\",\n \"focus\": \"#5fe8f0\",\n \"link\": \"#7ff0f5\",\n \"selection\": \"rgba(18, 199, 211, 0.32)\",\n \"node-ink\": \"#000000\",\n \"edge\": \"#ffffff\",\n \"edge-label\": \"#e6e8f0\",\n \"topic-teal\": \"#87f2f8\",\n \"topic-teal-ring\": \"#64eff7\",\n \"topic-harbor\": \"#bcdbff\",\n \"topic-harbor-ring\": \"#b0d5fe\",\n \"topic-iris\": \"#e0c8fe\",\n \"topic-iris-ring\": \"#dcbfff\",\n \"topic-berry\": \"#ffbdc4\",\n \"topic-berry-ring\": \"#feb3bb\",\n \"topic-coral\": \"#ffc7b2\",\n \"topic-coral-ring\": \"#ffbea5\",\n \"topic-amber\": \"#ffcf9d\",\n \"topic-amber-ring\": \"#ffc78a\",\n \"topic-sun\": \"#ffea94\",\n \"topic-sun-ring\": \"#ffe26d\",\n \"topic-stone\": \"#e0dacf\",\n \"topic-stone-ring\": \"#ddd3c2\",\n \"space-1\": \"4px\",\n \"space-2\": \"8px\",\n \"space-3\": \"12px\",\n \"space-4\": \"16px\",\n \"space-7\": \"48px\",\n \"radius-sm\": \"10px\",\n \"radius-md\": \"16px\",\n \"radius-lg\": \"24px\",\n \"radius-pill\": \"999px\",\n \"shadow-float\": \"none\",\n \"shadow-pop\": \"none\",\n \"node-width\": \"200px\",\n \"node-height\": \"148px\",\n \"node-stroke\": \"3px\",\n \"edge-width\": \"2.5px\",\n \"edge-gap\": \"15px\",\n \"edge-arc-max\": \"45px\",\n \"immersion-alpha\": \"0.15\",\n \"zoom-min\": \"0.3\",\n \"zoom-max\": \"5\",\n \"duration-instant\": \"100ms\",\n \"duration-quick\": \"160ms\",\n \"duration-base\": \"240ms\",\n \"duration-zoom\": \"500ms\",\n \"duration-reveal\": \"420ms\",\n \"stagger-reveal\": \"70ms\",\n \"ease-zoom\": \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n \"ease-standard\": \"cubic-bezier(0.4, 0, 0.2, 1)\",\n \"ease-bloom\": \"cubic-bezier(0.34, 1.4, 0.64, 1)\",\n \"z-chrome\": \"10\",\n \"z-card\": \"20\",\n \"z-menu\": \"40\"\n }\n};\n\n/** Topic palette names (token pairs `topic-<name>` / `topic-<name>-ring`). */\nexport const TOPICS = [\n \"teal\",\n \"harbor\",\n \"iris\",\n \"berry\",\n \"coral\",\n \"amber\",\n \"sun\",\n \"stone\"\n] as const;\nexport type TopicName = (typeof TOPICS)[number];\n\n/** Numeric tokens (px / ms stripped), camel-cased: nodeWidth, nodeStroke, edgeWidth, edgeGap, durationBase, zoomMin ... */\nexport const METRICS = {\n \"space1\": 4,\n \"space2\": 8,\n \"space3\": 12,\n \"space4\": 16,\n \"space7\": 48,\n \"radiusSm\": 10,\n \"radiusMd\": 16,\n \"radiusLg\": 24,\n \"radiusPill\": 999,\n \"nodeWidth\": 200,\n \"nodeHeight\": 148,\n \"nodeStroke\": 3,\n \"edgeWidth\": 2.5,\n \"edgeGap\": 15,\n \"edgeArcMax\": 45,\n \"immersionAlpha\": 0.15,\n \"zoomMin\": 0.3,\n \"zoomMax\": 5,\n \"durationInstant\": 100,\n \"durationQuick\": 160,\n \"durationBase\": 240,\n \"durationZoom\": 500,\n \"durationReveal\": 420,\n \"staggerReveal\": 70,\n \"zChrome\": 10,\n \"zCard\": 20,\n \"zMenu\": 40\n} as const;\n/** Overrides applied when motion is reduced. */\nexport const METRICS_REDUCED_MOTION = {\n \"durationInstant\": 120,\n \"durationQuick\": 0,\n \"durationBase\": 0,\n \"durationZoom\": 0,\n \"durationReveal\": 0,\n \"staggerReveal\": 0\n} as const;\n\n/** Canvas type styles (family is a token name: font-hand, font-note, font-ui ...). */\nexport const TYPE_STYLES = {\n \"heading\": {\n \"family\": \"font-ui\",\n \"size\": 17,\n \"lineHeight\": 24,\n \"weight\": 700\n },\n \"body\": {\n \"family\": \"font-ui\",\n \"size\": 15,\n \"lineHeight\": 22,\n \"weight\": 400\n },\n \"body-sm\": {\n \"family\": \"font-ui\",\n \"size\": 13,\n \"lineHeight\": 18,\n \"weight\": 400\n },\n \"label\": {\n \"family\": \"font-ui\",\n \"size\": 13,\n \"lineHeight\": 16,\n \"weight\": 600,\n \"letterSpacing\": 0.01\n },\n \"caption\": {\n \"family\": \"font-ui\",\n \"size\": 12,\n \"lineHeight\": 16,\n \"weight\": 400\n },\n \"node-root\": {\n \"family\": \"font-hand\",\n \"size\": 30,\n \"lineHeight\": 34,\n \"weight\": 700\n },\n \"node-label\": {\n \"family\": \"font-hand\",\n \"size\": 22,\n \"lineHeight\": 26,\n \"weight\": 700\n },\n \"edge-label\": {\n \"family\": \"font-note\",\n \"size\": 18,\n \"lineHeight\": 20,\n \"weight\": 500\n },\n \"annotation\": {\n \"family\": \"font-note\",\n \"size\": 24,\n \"lineHeight\": 26,\n \"weight\": 600\n }\n} as const;\n\n/** Canvas styling extracted from css/spec.css (node labels, hover, shadows, connector dashes, group frames). */\nexport const CANVAS_STYLE = {\n \"node\": {\n \"selectedStrokeWidth\": 4,\n \"hoverRingsRotate\": -2,\n \"hoverRingsScale\": 1.015,\n \"hoverLift\": -2,\n \"dimmedOpacity\": 1,\n \"dimmedOpacityFocus\": 0.4,\n \"dimmedOpacityTouch\": 0.6,\n \"dimmedOpacityFocusTouch\": 0.4,\n \"shadowLight\": \"0 6px 14px rgba(24, 33, 64, .10)\",\n \"shadowDark\": \"0 0 22px rgba(255, 255, 255, .10)\"\n },\n \"edge\": {\n \"dash\": [\n 7,\n 7\n ],\n \"labelWeight\": 500,\n \"labelSize\": 18,\n \"readableLabelSize\": 14,\n \"readableLabelWeight\": 600,\n \"labelHaloWidth\": 5\n },\n \"group\": {\n \"strokeWidth\": 1.5,\n \"dash\": [\n 10,\n 6\n ],\n \"labelWeight\": 700,\n \"labelLineHeight\": 1.1,\n \"labelSize\": 26,\n \"labelPadding\": {\n \"top\": 6,\n \"x\": 22,\n \"bottom\": 8\n },\n \"labelMaxWidth\": 420,\n \"labelBorderWidth\": 1.5,\n \"labelFill\": \"topic-stone\",\n \"labelBorder\": \"topic-stone-ring\",\n \"labelInk\": \"node-ink\",\n \"contrastLabelBorderWidth\": 2,\n \"contrastLabelBorder\": \"line-strong\"\n }\n} as const;\n","// Generated from visualli.ai design-system/components/src/color.ts — do not edit here.\n/* Which topic an idea is drawn in. A `.visualli` file's `data.color` may name one of the eight topics or be any\n other color, or be missing. Every renderer resolves it with this rule, so a file looks the same everywhere:\n a topic name ('teal', 'Harbor ') → that topic (case and surrounding spaces don't matter);\n no color → the topics in order, by the idea's position among its siblings (so siblings differ);\n anything else (e.g. '#b7e7f3') → null: not a topic — drawn as given (customColor): the color as the fill, and\n the fill darkened (CUSTOM.ringShade) as the ring; a custom color doesn't follow themes.\n No dependencies, so it can travel alone. */\n\n/** The eight topics, in the order missing colors cycle through. */\nexport const TOPIC_ORDER = ['teal', 'harbor', 'iris', 'berry', 'coral', 'amber', 'sun', 'stone'] as const;\nexport type TopicName = (typeof TOPIC_ORDER)[number];\n\n/** The topic a color names, or null. */\nexport function topicFromName(color: string | null | undefined): TopicName | null {\n if (!color) return null;\n const c = color.trim().toLowerCase();\n return (TOPIC_ORDER as readonly string[]).includes(c) ? (c as TopicName) : null;\n}\n\n/** The topic for an idea: its named topic; with no color, the next topic in sibling order; null for any other color. */\nexport function topicFor(color: string | null | undefined, siblingIndex: number): TopicName | null {\n if (!color || !color.trim()) return TOPIC_ORDER[((siblingIndex % TOPIC_ORDER.length) + TOPIC_ORDER.length) % TOPIC_ORDER.length];\n return topicFromName(color);\n}\n\n/** Chromatic immersion: inside a layer, the canvas takes the fill of the idea you stepped into (at the `immersion-alpha`\n * token), so you always know whose inside you are in. Part of the spec, so it is on unless a host turns it off. */\nexport const IMMERSION = { /** Renderers draw it by default. */ defaultOn: true } as const;\n\n/** A custom (non-topic) color: drawn as given, with a darker ring. */\nexport const CUSTOM = { /** The ring is the fill with each RGB channel multiplied by this. */ ringShade: 0.78 } as const;\n\n/** Fill and ring for a custom color. `ring` is null when the color isn't a 6-digit hex (use the `edge` token then). */\nexport function customColor(color: string): { fill: string; ring: string | null } {\n const m = /^#?([0-9a-f]{6})$/i.exec((color || '').trim());\n if (!m) return { fill: color, ring: null };\n const n = parseInt(m[1], 16), f = CUSTOM.ringShade;\n const r = Math.round(((n >> 16) & 255) * f), g = Math.round(((n >> 8) & 255) * f), b = Math.round((n & 255) * f);\n return { fill: color.trim(), ring: '#' + ((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1) };\n}\n","// ─── Theme resolution ────────────────────────────────────────────────────────\n//\n// Everything visual comes from the generated design-system modules. This file\n// only decides WHICH of the 8 themes applies and resolves document colours with\n// the design system's colour rule. No colour literals live here.\n//\n// Dependencies: ../generated/designSystem.ts (generated from design-system/).\n\nimport {\n CANVAS_STYLE,\n DESIGN_SYSTEM_VERSION,\n METRICS,\n METRICS_REDUCED_MOTION,\n THEME_NAMES,\n TOKENS,\n TOPICS,\n TYPE_STYLES,\n type ThemeName,\n type TopicName,\n} from '../generated/designSystem.js';\nimport { TOPIC_ORDER, customColor, topicFor, topicFromName } from '../generated/geometry/color.js';\n\nexport { topicFromName, customColor };\n\nexport { CANVAS_STYLE, DESIGN_SYSTEM_VERSION, METRICS, METRICS_REDUCED_MOTION, THEME_NAMES, TOKENS, TOPICS, TYPE_STYLES };\nexport type { ThemeName, TopicName };\n\n// ── Theme selection ───────────────────────────────────────────────────────────\n\n/** Theme families: each resolves to its light or dark member. */\nexport type ThemeFamily = 'standard' | 'focus' | 'colorsafe' | 'contrast';\n\n/**\n * Anything a consumer may pass as `theme`:\n * - one of the 8 design-system themes ('light', 'dark', 'focus-light', ...)\n * - a family name ('focus' | 'colorsafe' | 'contrast') -> light/dark per the reader's scheme\n * - 'auto' -> light/dark per prefers-color-scheme (contrast under forced-colors)\n *\n * 'light' | 'dark' | 'auto' are the pre-0.2 values, kept as aliases for one release.\n */\nexport type ThemeInput = ThemeName | 'auto' | 'focus' | 'colorsafe' | 'contrast';\n\nexport interface ThemeEnv {\n /** prefers-color-scheme: dark */\n prefersDark?: boolean;\n /** forced-colors: active (Windows high contrast etc.) */\n forcedColors?: boolean;\n}\n\nconst FAMILIES: ReadonlySet<string> = new Set(['focus', 'colorsafe', 'contrast']);\n\nexport function isThemeName(v: unknown): v is ThemeName {\n return typeof v === 'string' && (THEME_NAMES as readonly string[]).includes(v);\n}\n\n/** Resolve any accepted `theme` value to one concrete design-system theme. */\nexport function resolveTheme(input: ThemeInput | undefined, env: ThemeEnv = {}): ThemeName {\n const scheme = env.prefersDark ? 'dark' : 'light';\n if (input === undefined || input === 'auto') return env.forcedColors ? (`contrast-${scheme}` as ThemeName) : scheme;\n if (FAMILIES.has(input)) return `${input}-${scheme}` as ThemeName;\n return isThemeName(input) ? input : 'light';\n}\n\nexport const isDarkTheme = (name: ThemeName): boolean => name.endsWith('dark');\nexport const isContrastTheme = (name: ThemeName): boolean => name.startsWith('contrast');\nexport const isFocusTheme = (name: ThemeName): boolean => name.startsWith('focus');\n\n/** All tokens of a theme (already merged over the light defaults). */\nexport const getTokens = (name: ThemeName): Readonly<Record<string, string>> => TOKENS[name];\n\n/** One token of a theme. Throws on an unknown key so typos fail loudly in tests. */\nexport function token(name: ThemeName, key: string): string {\n const v = TOKENS[name][key];\n if (v === undefined) throw new Error(`Unknown design-system token \"${key}\"`);\n return v;\n}\n\n// ── Comfort settings ──────────────────────────────────────────────────────────\n\nexport interface Comfort {\n /** Atkinson Hyperlegible for map labels instead of the handwritten faces (`data-type=\"readable\"`). */\n readableType?: boolean;\n /** Larger UI and label text (`data-scale=\"lg\"`). */\n largerText?: boolean;\n /** Skip transitions and reveal animations (`data-motion=\"reduced\"`). 'system' follows prefers-reduced-motion. */\n reducedMotion?: boolean | 'system';\n}\n\nexport interface ResolvedComfort { readableType: boolean; largerText: boolean; reducedMotion: boolean }\n\nexport function resolveComfort(c: Comfort | undefined, env: { prefersReducedMotion?: boolean } = {}): ResolvedComfort {\n const rm = c?.reducedMotion;\n return {\n readableType: !!c?.readableType,\n largerText: !!c?.largerText,\n reducedMotion: rm === undefined || rm === 'system' ? !!env.prefersReducedMotion : rm,\n };\n}\n\n/** Numeric design-system tokens (px / ms stripped). */\nexport type Metrics = { readonly [K in keyof typeof METRICS]: number };\n\n/** Numeric tokens with the reduced-motion overrides applied when requested. */\nexport function metricsFor(comfort: ResolvedComfort): Metrics {\n return comfort.reducedMotion ? { ...METRICS, ...METRICS_REDUCED_MOTION } : METRICS;\n}\n\n/** Multiplier the spec applies to label sizes under `data-scale=\"lg\"` (`--vi-label-scale`). */\nexport const labelScale = (c: ResolvedComfort): number => (c.largerText ? 1.15 : 1);\n\n// ── Topic palette ─────────────────────────────────────────────────────────────\n\nexport interface TopicStyle { topic: TopicName; fill: string; ring: string }\n\n/** Fill + ring colour of a topic in a theme. */\nexport function topicStyle(theme: ThemeName, topic: TopicName): TopicStyle {\n const t = TOKENS[theme];\n return { topic, fill: t[`topic-${topic}`]!, ring: t[`topic-${topic}-ring`]! };\n}\n\n/** An idea's colour by the design system's colour rule (geometry/color.ts, verbatim): a topic name → that topic; no\n * colour → the topics in sibling order; any other colour → custom, drawn as given (customColor: the colour as the fill,\n * the fill darkened by CUSTOM.ringShade as the ring). A custom colour doesn't follow themes. */\nexport interface IdeaColor { topic: TopicName | null; custom: { fill: string; ring: string | null } | null }\n\nexport function ideaColor(color: string | null | undefined, siblingIndex: number): IdeaColor {\n const topic = topicFor(color, siblingIndex);\n return topic ? { topic, custom: null } : { topic: null, custom: customColor(color!) };\n}\n\n/** Fill + ring an idea is drawn with in a theme: its topic's, or its custom colour (ring: the `edge` token when the\n * colour has no darker shade, i.e. isn't a 6-digit hex). */\nexport function ideaStyle(theme: ThemeName, c: { topic?: TopicName | null; custom?: IdeaColor['custom'] }): { fill: string; ring: string } {\n if (c.custom) return { fill: c.custom.fill, ring: c.custom.ring ?? TOKENS[theme]['edge']! };\n return topicStyle(theme, c.topic ?? TOPIC_ORDER[0]);\n}\n","// Generated from visualli.ai design-system/components/src/idea.ts — do not edit here.\n/* An idea's size and its label. An idea grows to show its whole label: it starts at its base width and widens in\n steps until the label fits in `labelLines` lines; at its widest it grows taller instead, so a label is never cut.\n Labels (and connector labels) grow a little when the map is zoomed out, so they stay readable. Every renderer sizes\n ideas with these rules, measuring text with its own font engine (`measure`). No dependencies, so it can travel alone. */\n\nexport type IdeaKind = 'root' | 'node' | 'mini';\n\n/** How much labels grow when zoomed out (`scale` = the map's zoom): never smaller than their size, up to these caps.\n * Idea labels and container names use `idea`; connector labels `connector`. Below 100% they grow; above, they don't. */\nexport const LABEL_GROWTH = { idea: 1.3, connector: 1.6 } as const;\n\nexport const IDEA = {\n /** Width an idea starts at… */ baseWidth: { root: 240, node: 200, mini: 120 },\n /** …and the widest it gets before it grows taller instead. */ maxWidth: { root: 400, node: 360, mini: 200 },\n /** Width grows in steps of this. */ step: 20,\n /** Height = width × aspect (at least `minRy` × 2), more if the label needs it. */ aspect: 0.74, minRy: 64,\n /** The label's box is the idea's width less this (22 each side). */ labelInset: 44,\n /** The idea widens until its label fits in this many lines. */ labelLines: 3,\n /** Label size (before the label scale and zoom growth), weight from the canvas type styles. */ labelSize: { root: 30, node: 22, mini: 15 },\n labelLineHeight: 1.15,\n /** The label may fill at most this share of the idea's height. */ labelFillHeight: 0.7,\n} as const;\n\n/** Greedy word wrap of `text` into lines no wider than `maxWidth` (a single word longer than that gets its own line). */\nexport function wrapLines(text: string, maxWidth: number, measure: (s: string) => number): string[] {\n const words = text.split(/\\s+/).filter(Boolean);\n const lines: string[] = [];\n let cur = '';\n for (const w of words) {\n const next = cur ? `${cur} ${w}` : w;\n if (cur && measure(next) > maxWidth) { lines.push(cur); cur = w; } else cur = next;\n }\n if (cur) lines.push(cur);\n return lines.length ? lines : [''];\n}\n\n/** An idea's size for its label: width, half-width / half-height for the blob, and the label's lines. The label is\n * measured at its largest drawn size — its type size × `labelScale` (Comfort: larger text) × LABEL_GROWTH.idea (zoomed\n * out) — so it fits at every zoom and the idea never changes size while zooming. `measure(text, px)` returns the\n * text's width in px in the label's face at `px`. */\nexport function ideaSize(kind: IdeaKind, label: string, measure: (text: string, px: number) => number, labelScale = 1) {\n const px = IDEA.labelSize[kind] * labelScale * LABEL_GROWTH.idea;\n const fit = (w: number) => wrapLines(label, w - IDEA.labelInset, (t) => measure(t, px));\n const base: number = IDEA.baseWidth[kind], max: number = IDEA.maxWidth[kind];\n let width = base, lines = fit(width);\n while (lines.length > IDEA.labelLines && width < max) { width = Math.min(max, width + IDEA.step); lines = fit(width); }\n const rx = width / 2;\n const ry = Math.max(IDEA.minRy, rx * IDEA.aspect, (lines.length * px * IDEA.labelLineHeight) / 2 / IDEA.labelFillHeight);\n return { width, height: ry * 2, rx, ry, lines };\n}\n\nexport function labelGrowth(scale: number): { idea: number; connector: number } {\n const inv = 1 / Math.max(scale, 0.0001);\n return { idea: Math.max(1, Math.min(inv, LABEL_GROWTH.idea)), connector: Math.max(1, Math.min(inv, LABEL_GROWTH.connector)) };\n}\n","// ─── Idea size and label growth ──────────────────────────────────────────────\n//\n// The design system's idea.ts (copied verbatim into generated/geometry): an idea\n// grows to show its whole label, and labels grow a little when zoomed out. The\n// SDK only supplies the text measurement (its font engine) and picks the kind.\n\nimport { IDEA, LABEL_GROWTH, ideaSize, labelGrowth, wrapLines, type IdeaKind } from '../generated/geometry/idea.js';\nimport type { VisualliLayer } from '../types/layer.js';\n\nexport { IDEA, LABEL_GROWTH, ideaSize, labelGrowth, wrapLines };\nexport type { IdeaKind };\n\n/** Width in px of `text` in the idea label's face at `px` (the label's weight; readable type adds its tracking). */\nexport type IdeaMeasure = (text: string, px: number) => number;\n\n/** Measurement without a font engine (server, tests): half an em per character. Renderers pass the real face. */\nexport const approximateMeasure: IdeaMeasure = (text, px) => text.length * px * 0.5;\n\n/** The size kind of the `index`-th idea of a layer: the centre of the root radial layer is the root, the rest ideas. */\nexport const ideaKindOf = (layer: Pick<VisualliLayer, 'level' | 'layout'>, index: number): IdeaKind =>\n layer.level === 0 && (layer.layout ?? 'radial') === 'radial' && index === 0 ? 'root' : 'node';\n","// ─── Circular Layout Algorithm ────────────────────────────────────────────────\n//\n// Positions nodes in a uniform circle with equal angular spacing.\n// PATTERN : Uniform circular distribution (polar coordinates)\n// SPACING : Equal angular intervals (2π/n)\n// ORIGIN : Configurable center (default 0, 0)\n// RADIUS : Configurable percentage of container (default 13.5%)\n\nimport type { FlatNode } from '../types/mindmap.js';\n\nexport interface CircularLayoutOptions {\n /** Radius as a fraction of the container's minimum dimension (0–1). Default: 0.135 */\n radiusPercentage?: number;\n /** Container width used to calculate absolute radius. Default: 2000 */\n containerWidth?: number;\n /** Container height used to calculate absolute radius. Default: 2000 */\n containerHeight?: number;\n /** World-space X of the circle centre. Default: 0 */\n centerX?: number;\n /** World-space Y of the circle centre. Default: 0 */\n centerY?: number;\n}\n\n/**\n * Apply circular layout to a set of nodes.\n * Mutates the `x` / `y` properties of each node and returns the same array.\n */\nexport function applyCircularLayout(\n nodes: FlatNode[],\n options: CircularLayoutOptions = {},\n): FlatNode[] {\n const {\n radiusPercentage = 0.135,\n containerWidth = 2000,\n containerHeight = 2000,\n centerX = 0,\n centerY = 0,\n } = options;\n\n if (nodes.length === 0) return nodes;\n\n if (nodes.length === 1) {\n nodes[0].x = centerX;\n nodes[0].y = centerY;\n return nodes;\n }\n\n const radius = Math.min(containerWidth, containerHeight) * radiusPercentage;\n\n // n=2 → horizontal; n≥3 → start at 12 o'clock\n const startAngle = nodes.length === 2 ? 0 : -Math.PI / 2;\n const angleStep = (2 * Math.PI) / nodes.length;\n\n for (let i = 0; i < nodes.length; i++) {\n const angle = startAngle + i * angleStep;\n nodes[i].x = centerX + radius * Math.cos(angle);\n nodes[i].y = centerY + radius * Math.sin(angle);\n }\n\n return nodes;\n}\n\n/**\n * Calculate the minimum radius needed to prevent node boxes from overlapping.\n *\n * Uses the chord-length formula: `chord = 2r · sin(θ/2)`, solved for `r`.\n */\nexport function calculateMinimumRadius(\n nodeCount: number,\n nodeWidth = 200,\n nodePadding = 150,\n): number {\n if (nodeCount <= 1) return 0;\n const angleStep = (2 * Math.PI) / nodeCount;\n const minChordLength = nodeWidth + nodePadding;\n return minChordLength / (2 * Math.sin(angleStep / 2));\n}\n\n/**\n * Calculate the optimal radius percentage for a given node count,\n * ensuring sufficient spacing for edge labels.\n *\n * @returns A value in [0.135, 0.45]\n */\nexport function calculateOptimalRadiusPercentage(\n nodeCount: number,\n containerWidth = 2000,\n containerHeight = 2000,\n nodeWidth = 200,\n nodePadding = 120,\n): number {\n const minRadius = calculateMinimumRadius(nodeCount, nodeWidth, nodePadding);\n const minDimension = Math.min(containerWidth, containerHeight);\n return Math.min(0.45, Math.max(0.135, minRadius / minDimension));\n}\n","// ─── Linear Layout Algorithms ─────────────────────────────────────────────────\n//\n// Positions nodes in a straight line without overlap, with enough gap between\n// node edges for edge-label text to render cleanly.\n//\n// linear-horizontal → left-to-right along X-axis\n// linear-vertical → top-to-bottom along Y-axis\n\nimport type { FlatNode } from '../types/mindmap.js';\n\nexport interface LinearLayoutOptions {\n /** Logical node width (px). Default: 200 */\n nodeWidth?: number;\n /** Logical node height (px). Default: 80 */\n nodeHeight?: number;\n /** Gap between node edges for horizontal layout (px). Default: 180 */\n hGap?: number;\n /** Gap between node edges for vertical layout (px). Default: 220 */\n vGap?: number;\n /** World X of the layout midpoint. Default: 0 */\n centerX?: number;\n /** World Y of the layout midpoint. Default: 0 */\n centerY?: number;\n}\n\n/**\n * Arrange nodes in a horizontal row (shared Y, varying X).\n * Row is centred on (`centerX`, `centerY`).\n */\nexport function applyLinearHorizontalLayout(\n nodes: FlatNode[],\n options: LinearLayoutOptions = {},\n): FlatNode[] {\n const { nodeWidth = 200, hGap = 180, centerX = 0, centerY = 0 } = options;\n\n if (nodes.length === 0) return nodes;\n\n if (nodes.length === 1) {\n nodes[0].x = centerX;\n nodes[0].y = centerY;\n return nodes;\n }\n\n const spacing = nodeWidth + hGap;\n const totalWidth = (nodes.length - 1) * spacing;\n const startX = centerX - totalWidth / 2;\n\n for (let i = 0; i < nodes.length; i++) {\n nodes[i].x = startX + i * spacing;\n nodes[i].y = centerY;\n }\n\n return nodes;\n}\n\n/**\n * Arrange nodes in a vertical column (shared X, varying Y).\n * Column is centred on (`centerX`, `centerY`).\n */\nexport function applyLinearVerticalLayout(\n nodes: FlatNode[],\n options: LinearLayoutOptions = {},\n): FlatNode[] {\n const { nodeHeight = 80, vGap = 220, centerX = 0, centerY = 0 } = options;\n\n if (nodes.length === 0) return nodes;\n\n if (nodes.length === 1) {\n nodes[0].x = centerX;\n nodes[0].y = centerY;\n return nodes;\n }\n\n const spacing = nodeHeight + vGap;\n const totalHeight = (nodes.length - 1) * spacing;\n const startY = centerY - totalHeight / 2;\n\n for (let i = 0; i < nodes.length; i++) {\n nodes[i].x = centerX;\n nodes[i].y = startY + i * spacing;\n }\n\n return nodes;\n}\n","// ─── .visualli → FlatNode Converter ──────────────────────────────────────────\n//\n// Transforms the layer-based .visualli format into the flat Map<id, FlatNode>\n// structure consumed by the canvas renderer.\n\nimport type { VisualliDocument } from '../types/document.js';\nimport type { VisualliLayer } from '../types/layer.js';\nimport type { FlatNode, NodeMap } from '../types/mindmap.js';\nimport { countLayersBeneath } from './visualliParser.js';\nimport { ideaColor } from '../theme/index.js';\nimport { approximateMeasure, ideaKindOf, ideaSize, type IdeaMeasure } from '../rendering/ideaSize.js';\nimport { applyCircularLayout, calculateOptimalRadiusPercentage } from '../layout/circularLayout.js';\nimport { applyLinearHorizontalLayout, applyLinearVerticalLayout } from '../layout/linearLayout.js';\n\n// ── Overlap Resolution ────────────────────────────────────────────────────────\n\nfunction doNodesOverlap(n1: FlatNode, n2: FlatNode, padding = 20): boolean {\n return !(\n n1.x + n1.width / 2 + padding < n2.x - n2.width / 2 - padding ||\n n1.x - n1.width / 2 - padding > n2.x + n2.width / 2 + padding ||\n n1.y + n1.height / 2 + padding < n2.y - n2.height / 2 - padding ||\n n1.y - n1.height / 2 - padding > n2.y + n2.height / 2 + padding\n );\n}\n\n/** Iteratively push overlapping nodes apart using symmetric force separation. */\nexport function resolveNodeOverlaps(nodes: FlatNode[], maxIterations = 10): void {\n const padding = 150;\n\n for (let iter = 0; iter < maxIterations; iter++) {\n let any = false;\n for (let i = 0; i < nodes.length; i++) {\n for (let j = i + 1; j < nodes.length; j++) {\n const n1 = nodes[i];\n const n2 = nodes[j];\n if (!doNodesOverlap(n1, n2, padding)) continue;\n\n any = true;\n const dx = n2.x - n1.x;\n const dy = n2.y - n1.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n if (dist < 1) {\n n2.x += n2.width / 2 + padding;\n continue;\n }\n\n const minDist = (n1.width + n2.width) / 2 + padding;\n if (dist < minDist) {\n const push = (minDist - dist) / 2;\n n1.x -= (dx / dist) * push;\n n1.y -= (dy / dist) * push;\n n2.x += (dx / dist) * push;\n n2.y += (dy / dist) * push;\n }\n }\n }\n if (!any) break;\n }\n}\n\n// ── Options ───────────────────────────────────────────────────────────────────\n\nexport interface ConvertOptions {\n /** Measures label text in the idea face (the renderer's font engine); ideas are sized with the design system's\n * ideaSize. Defaults to an approximation (half an em per character) where no font engine exists. */\n measure?: IdeaMeasure;\n /** Label scale (comfort: larger text is 1.15); ideas grow to fit the larger label. */\n labelScale?: number;\n}\n\n/** Whether a layer's ideas carry their own positions: every idea has one, and (with more than one idea) they aren't\n * all on the same spot (a placeholder). Then the file's positions are used as they are. */\nfunction hasFilePositions(layer: VisualliLayer): boolean {\n const ps = layer.nodes.map((n) => n.position);\n if (!ps.length || !ps.every((p) => p && Number.isFinite(p.x) && Number.isFinite(p.y))) return false;\n return ps.length === 1 || ps.some((p) => p!.x !== ps[0]!.x || p!.y !== ps[0]!.y);\n}\n\n// ── Container-formation Layout ────────────────────────────────────────────────\n\ninterface Proxy { id: string; x: number; y: number; width: number; height: number }\n\nfunction applyFormation(nodes: FlatNode[], formation: string): void {\n if (nodes.length === 0) return;\n if (nodes.length === 1) { nodes[0].x = 0; nodes[0].y = 0; return; }\n if (formation === 'linear-horizontal' || formation === 'linear') {\n applyLinearHorizontalLayout(nodes, { centerX: 0, centerY: 0 });\n } else if (formation === 'linear-vertical') {\n applyLinearVerticalLayout(nodes, { centerX: 0, centerY: 0 });\n } else {\n const r = Math.max(250, nodes.length * 70);\n const step = (2 * Math.PI) / nodes.length;\n for (let i = 0; i < nodes.length; i++) {\n nodes[i].x = r * Math.cos(i * step);\n nodes[i].y = r * Math.sin(i * step);\n }\n }\n}\n\nfunction containerBBox(nodes: FlatNode[], padding: number): { width: number; height: number } {\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n for (const n of nodes) {\n minX = Math.min(minX, n.x - n.width / 2);\n maxX = Math.max(maxX, n.x + n.width / 2);\n minY = Math.min(minY, n.y - n.height / 2);\n maxY = Math.max(maxY, n.y + n.height / 2);\n }\n return { width: maxX - minX + padding * 2, height: maxY - minY + padding * 2 };\n}\n\nfunction proxyLinearH(proxies: Proxy[], gap = 180): void {\n const total = proxies.reduce((s, p) => s + p.width, 0) + gap * (proxies.length - 1);\n let x = -total / 2;\n for (const p of proxies) { p.x = x + p.width / 2; p.y = 0; x += p.width + gap; }\n}\n\nfunction proxyLinearV(proxies: Proxy[], gap = 180): void {\n const total = proxies.reduce((s, p) => s + p.height, 0) + gap * (proxies.length - 1);\n let y = -total / 2;\n for (const p of proxies) { p.x = 0; p.y = y + p.height / 2; y += p.height + gap; }\n}\n\nfunction proxyRadial(proxies: Proxy[], radius = 500): void {\n if (proxies.length === 1) { proxies[0].x = 0; proxies[0].y = 0; return; }\n // Start at top (12 o'clock) for n>=3, horizontal for n=2 (matches circular layout)\n const startAngle = proxies.length === 2 ? 0 : -Math.PI / 2;\n const step = (2 * Math.PI) / proxies.length;\n for (let i = 0; i < proxies.length; i++) {\n const angle = startAngle + i * step;\n proxies[i].x = radius * Math.cos(angle);\n proxies[i].y = radius * Math.sin(angle);\n }\n}\n\n// ── Layer Conversion ──────────────────────────────────────────────────────────\n\nfunction makeFlatNode(\n node: VisualliLayer['nodes'][number],\n layer: VisualliLayer,\n doc: VisualliDocument,\n /** Position among the layer's ideas (file order): missing colours cycle the topics by it, and the first idea of the root radial layer is the root. */\n siblingIndex: number,\n opts: ConvertOptions,\n): FlatNode {\n const label = Array.isArray(node.data.label) ? (node.data.label as string[]).join(' ') : (node.data.label || 'Untitled');\n const branchCount = countLayersBeneath(doc, node.id);\n const kind = ideaKindOf(layer, siblingIndex);\n const size = ideaSize(kind, label, opts.measure ?? approximateMeasure, opts.labelScale ?? 1);\n const { topic, custom } = ideaColor(node.data.color, siblingIndex);\n return {\n id: node.id,\n parentId: layer.parentNodeId ?? null,\n x: node.position?.x ?? 0,\n y: node.position?.y ?? 0,\n level: layer.level,\n title: label,\n description: node.data.summary || '',\n color: node.data.color ?? '',\n ...(topic ? { topic } : {}),\n ...(custom ? { custom } : {}),\n kind,\n width: size.width,\n height: size.height,\n isExpanded: branchCount > 0,\n branchCount,\n createdAt: new Date(),\n updatedAt: new Date(),\n };\n}\n\nfunction layoutLayerWithContainers(layer: VisualliLayer, flatNodes: FlatNode[]): void {\n const PADDING = 80;\n const byId = new Map(flatNodes.map((n: FlatNode) => [n.id, n]));\n const containerNodeIds = new Set<string>();\n const containerGroups = new Map<string, FlatNode[]>();\n\n for (const container of layer.containers) {\n const group = container.nodes.map((id: string) => byId.get(id)).filter((n: FlatNode | undefined): n is FlatNode => !!n);\n if (!group.length) continue;\n container.nodes.forEach((id: string) => containerNodeIds.add(id));\n const formation = ((container.data as unknown as Record<string, unknown> | undefined)?.['formation'] as string | undefined) ?? 'radial';\n applyFormation(group, formation);\n containerGroups.set(container.id, group);\n }\n\n const proxies: Proxy[] = [];\n for (const n of flatNodes) {\n if (!containerNodeIds.has(n.id)) proxies.push({ id: n.id, x: 0, y: 0, width: n.width, height: n.height });\n }\n for (const container of layer.containers) {\n const group = containerGroups.get(container.id);\n if (!group?.length) continue;\n const bbox = containerBBox(group, PADDING);\n proxies.push({ id: `__c__${container.id}`, x: 0, y: 0, width: bbox.width, height: bbox.height });\n }\n\n const layout = layer.layout || 'radial';\n if (layout === 'linear-horizontal') proxyLinearH(proxies, 180);\n else if (layout === 'linear-vertical') proxyLinearV(proxies, 180);\n else proxyRadial(proxies, 500);\n\n for (const proxy of proxies) {\n if (proxy.id.startsWith('__c__')) {\n const group = containerGroups.get(proxy.id.slice(5));\n group?.forEach(n => { n.x += proxy.x; n.y += proxy.y; });\n } else {\n const fn = byId.get(proxy.id);\n if (fn) { fn.x = proxy.x; fn.y = proxy.y; }\n }\n }\n}\n\nfunction layoutLayer(layer: VisualliLayer, flatNodes: FlatNode[]): void {\n const layout = layer.layout || 'radial';\n if (layout === 'linear-horizontal') {\n applyLinearHorizontalLayout(flatNodes, { centerX: 0, centerY: 0 });\n } else if (layout === 'linear-vertical') {\n applyLinearVerticalLayout(flatNodes, { centerX: 0, centerY: 0 });\n } else {\n const pct = calculateOptimalRadiusPercentage(flatNodes.length, 2000, 2000, 200, 30);\n applyCircularLayout(flatNodes, {\n radiusPercentage: pct,\n containerWidth: 2000,\n containerHeight: 2000,\n centerX: 0,\n centerY: 0,\n });\n }\n}\n\n/**\n * Convert a single layer to an array of FlatNode objects, each sized for its label\n * (the design system's idea.ts) and coloured by its colour rule (color.ts).\n * Positions: the file's own when its ideas carry them; otherwise the SDK lays the\n * layer out by `layer.layout` (default radial) and container formations.\n */\nexport function convertLayerToFlatNodes(\n layer: VisualliLayer,\n doc: VisualliDocument,\n opts: ConvertOptions = {},\n): FlatNode[] {\n const flatNodes = layer.nodes.map((node, i) => makeFlatNode(node, layer, doc, i, opts));\n if (flatNodes.length === 0 || hasFilePositions(layer)) return flatNodes;\n for (const n of flatNodes) { n.x = 0; n.y = 0; }\n if ((layer.containers ?? []).length > 0) layoutLayerWithContainers(layer, flatNodes);\n else layoutLayer(layer, flatNodes);\n resolveNodeOverlaps(flatNodes);\n return flatNodes;\n}\n\n/**\n * Convert an entire .visualli document to a flat NodeMap.\n * All layers are converted and a children-index is built for O(1) tree traversal.\n */\nexport function convertVisualliToFlatNodes(doc: VisualliDocument, opts: ConvertOptions = {}): NodeMap {\n const map: NodeMap = new Map();\n\n for (const layer of doc.layers.values()) {\n for (const node of convertLayerToFlatNodes(layer, doc, opts)) {\n map.set(node.id, node);\n }\n }\n\n // Build children index\n for (const node of map.values()) {\n node.childrenIds = [];\n for (const candidate of map.values()) {\n if (candidate.parentId === node.id) node.childrenIds.push(candidate.id);\n }\n }\n\n return map;\n}\n\n/**\n * Get flat nodes for a specific layer only.\n *\n * @param doc - Parsed .visualli document\n * @param layerId - Layer ID to extract\n * @param opts - Text measurement and label scale for sizing ideas\n * @returns FlatNode array, or empty array if layer not found\n */\nexport function getNodesForLayer(doc: VisualliDocument, layerId: string, opts: ConvertOptions = {}): FlatNode[] {\n const layer = doc.layers.get(layerId);\n return layer ? convertLayerToFlatNodes(layer, doc, opts) : [];\n}\n","// ─── Mindmap Tree Utilities ───────────────────────────────────────────────────\n\nimport type { MindMapNode, TopLevelConnection } from '../types/mindmap.js';\n\n/** Flatten a nested MindMapNode tree into a depth-first array. */\nexport function flattenNodes(nodes: MindMapNode[]): MindMapNode[] {\n const result: MindMapNode[] = [];\n const traverse = (list: MindMapNode[]) => {\n for (const n of list) {\n result.push(n);\n if (n.children) traverse(n.children);\n }\n };\n traverse(nodes);\n return result;\n}\n\n/**\n * Return nodes visible at the given zoom level.\n *\n * At lower zoom values only top-level nodes are shown; each 5% zoom increment\n * reveals one additional hierarchy level.\n */\nexport function getVisibleNodes(\n nodes: MindMapNode[],\n zoom: number,\n focusedNode?: string,\n): MindMapNode[] {\n const flat = flattenNodes(nodes);\n\n if (focusedNode) {\n const focused = flat.find(n => n.id === focusedNode);\n if (focused) {\n return focused.children ? [focused, ...focused.children] : [focused];\n }\n }\n\n // Map zoom to max visible level (level 0 at ≤70%, +1 level per 5% increment)\n if (zoom <= 0.70) return flat.filter(n => n.level === 0);\n const maxLevel = Math.floor((zoom - 0.70) / 0.05);\n return flat.filter(n => n.level <= maxLevel);\n}\n\n/** Build parent→child connection pairs from the node tree. */\nexport function getNodeConnections(\n nodes: MindMapNode[],\n): Array<{ from: MindMapNode; to: MindMapNode; label?: string }> {\n const flat = flattenNodes(nodes);\n const result: Array<{ from: MindMapNode; to: MindMapNode; label?: string }> = [];\n for (const n of flat) {\n if (!n.parent) continue;\n const parent = flat.find(p => p.id === n.parent);\n if (parent) result.push({ from: parent, to: n, label: n.relationshipLabel });\n }\n return result;\n}\n\n/** Resolve top-level cross-connections to node pairs. */\nexport function getTopLevelConnections(\n nodes: MindMapNode[],\n topLevelConnections: TopLevelConnection[],\n): Array<{ from: MindMapNode; to: MindMapNode; label: string }> {\n const flat = flattenNodes(nodes);\n const result: Array<{ from: MindMapNode; to: MindMapNode; label: string }> = [];\n for (const conn of topLevelConnections) {\n const from = flat.find(n => n.id === conn.from);\n const to = flat.find(n => n.id === conn.to);\n if (from && to) result.push({ from, to, label: conn.label ?? '' });\n }\n return result;\n}\n\n/** Euclidean distance between two world-space points. */\nexport function calculateDistance(x1: number, y1: number, x2: number, y2: number): number {\n return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n}\n","// ─── Layout constants ────────────────────────────────────────────────────────\n//\n// Non-visual layout metrics (world units). Everything visual (colours, fonts,\n// radii, spacing, motion) comes from the design system: see ../theme.\n\nexport const LAYOUT_SPACING = {\n nodeSpacing: 200,\n levelSpacing: 150,\n containerPadding: 20,\n gridSize: 50,\n} as const;\n","// ─── MindMapConfig Utilities ──────────────────────────────────────────────────\n//\n// Helpers for creating and generating MindMapConfig objects (pure data, no UI).\n\nimport type { MindMapNode, MindMapConfig, TopLevelConnection } from '../types/mindmap.js';\nimport { LAYOUT_SPACING } from '../constants/layout.js';\nimport { TOKENS, TOPICS } from '../theme/index.js';\n\n/** Light-theme fill of the topic used for a level (cycles through the design-system topics). */\nconst levelColor = (level: number): string => TOKENS.light[`topic-${TOPICS[level % TOPICS.length]}`]!;\n\ntype LevelColors = { level0: string; level1: string; level2: string; level3: string; [key: `level${number}`]: string };\nconst levelColors = (count: number): LevelColors =>\n Object.fromEntries(Array.from({ length: count }, (_, i) => [`level${i}`, levelColor(i)])) as LevelColors;\n\nexport function createMindMapConfig(\n nodes: MindMapNode[],\n topLevelConnections: TopLevelConnection[],\n title = 'Untitled Mindmap',\n): MindMapConfig {\n const now = new Date().toISOString();\n return {\n metadata: {\n title,\n description: `Interactive mindmap with ${nodes.length} nodes`,\n version: '1.0.0',\n created: now,\n lastModified: now,\n },\n nodes,\n topLevelConnections,\n settings: {\n defaultColors: levelColors(4),\n layout: {\n nodeSpacing: LAYOUT_SPACING.nodeSpacing,\n levelSpacing: LAYOUT_SPACING.levelSpacing,\n },\n },\n };\n}\n\n// ── Sample Data Generator ─────────────────────────────────────────────────────\n\nfunction generateId(prefix: string, level: number, index: number): string {\n return `${prefix}-l${level}-${index}`;\n}\n\nfunction generateLevelNodes(\n parentId: string | null,\n level: number,\n maxLevels: number,\n xOffset = 0,\n yOffset = 0,\n): MindMapNode[] {\n if (level >= maxLevels) return [];\n\n const count = 5;\n const levelSpacing = 200;\n const nodeSpacing = 300;\n const nodes: MindMapNode[] = [];\n\n for (let i = 0; i < count; i++) {\n const nodeId = parentId\n ? generateId(`${parentId}-${i}`, level, i)\n : generateId('root', level, i);\n\n const x = xOffset + (i - (count - 1) / 2) * nodeSpacing;\n const y = yOffset + level * levelSpacing;\n\n const node: MindMapNode = {\n id: nodeId,\n title: `Level ${level} Node ${i + 1}`,\n level,\n x,\n y,\n color: levelColor(level),\n relationshipLabel: level > 0 ? 'child' : undefined,\n parent: parentId ?? undefined,\n };\n\n const children = generateLevelNodes(nodeId, level + 1, maxLevels, x, y + levelSpacing);\n if (children.length > 0) node.children = children;\n\n nodes.push(node);\n }\n\n return nodes;\n}\n\n/**\n * Generate a sample MindMapConfig with `maxLevels` of hierarchy.\n * Useful for testing and demos.\n */\nexport function generateSampleConfig(maxLevels = 9): MindMapConfig {\n const nodes = generateLevelNodes(null, 0, maxLevels, 0, 0);\n\n const topLevelConnections: TopLevelConnection[] = nodes.slice(0, -1).map((n, i) => ({\n from: n.id,\n to: nodes[i + 1].id,\n label: 'related to',\n }));\n\n return {\n metadata: {\n id: `mindmap-${Date.now()}`,\n title: 'Sample Mind Map',\n description: 'A sample mind map',\n version: '1.0.0',\n created: new Date().toISOString(),\n lastModified: new Date().toISOString(),\n },\n nodes,\n topLevelConnections,\n settings: {\n defaultColors: levelColors(9),\n layout: {\n nodeSpacing: LAYOUT_SPACING.nodeSpacing,\n levelSpacing: LAYOUT_SPACING.levelSpacing,\n },\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,9 +1,9 @@
1
1
  import { V as VisualliDocument, S as SemanticAnchor } from '../document-MEJEfxl3.cjs';
2
2
  import { V as VisualliLayer } from '../layer-B2A3Ki48.cjs';
3
- import { F as FlatNode, e as NodeMap, d as MindMapNode, T as TopLevelConnection, b as MindMapConfig } from '../mindmap-BO3YD5qu.cjs';
4
- import { I as IdeaMeasure } from '../ideaSize-BTJu6thN.cjs';
3
+ import { F as FlatNode, e as NodeMap, d as MindMapNode, T as TopLevelConnection, b as MindMapConfig } from '../mindmap-Acjoll04.cjs';
4
+ import { I as IdeaMeasure } from '../ideaSize-BxYgVM2m.cjs';
5
5
  import '@visualli/bindings';
6
- import '../designSystem-D49xVfr8.cjs';
6
+ import '../designSystem-BcBLKHJO.cjs';
7
7
 
8
8
  declare class VisualliParseError extends Error {
9
9
  readonly lineNumber?: number | undefined;
@@ -1,9 +1,9 @@
1
1
  import { V as VisualliDocument, S as SemanticAnchor } from '../document-BFBwn93X.js';
2
2
  import { V as VisualliLayer } from '../layer-B2A3Ki48.js';
3
- import { F as FlatNode, e as NodeMap, d as MindMapNode, T as TopLevelConnection, b as MindMapConfig } from '../mindmap-D0Of0jaZ.js';
4
- import { I as IdeaMeasure } from '../ideaSize-RKbms8K6.js';
3
+ import { F as FlatNode, e as NodeMap, d as MindMapNode, T as TopLevelConnection, b as MindMapConfig } from '../mindmap-BwFtEDQV.js';
4
+ import { I as IdeaMeasure } from '../ideaSize-DBcumOej.js';
5
5
  import '@visualli/bindings';
6
- import '../designSystem-D49xVfr8.js';
6
+ import '../designSystem-BcBLKHJO.js';
7
7
 
8
8
  declare class VisualliParseError extends Error {
9
9
  readonly lineNumber?: number | undefined;
@@ -18,12 +18,12 @@ import {
18
18
  parseVisualliFile,
19
19
  parseVisualliFromMongoDB,
20
20
  resolveNodeOverlaps
21
- } from "../chunk-WO4JAAKP.js";
21
+ } from "../chunk-RLZO3KIN.js";
22
22
  import "../chunk-25AJTPMS.js";
23
23
  import "../chunk-N7HCYULH.js";
24
24
  import "../chunk-GQMFBYLK.js";
25
- import "../chunk-ITDZ72JE.js";
26
- import "../chunk-RFMUATWB.js";
25
+ import "../chunk-2EVIMAJN.js";
26
+ import "../chunk-2AB4FH2E.js";
27
27
  export {
28
28
  VisualliParseError,
29
29
  calculateDistance,