sldeditor 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"sldeditor.cjs","sources":["../node_modules/lucide-react/dist/esm/shared/src/utils.js","../node_modules/lucide-react/dist/esm/defaultAttributes.js","../node_modules/lucide-react/dist/esm/Icon.js","../node_modules/lucide-react/dist/esm/createLucideIcon.js","../node_modules/lucide-react/dist/esm/icons/cable.js","../node_modules/lucide-react/dist/esm/icons/chevron-down.js","../node_modules/lucide-react/dist/esm/icons/clipboard.js","../node_modules/lucide-react/dist/esm/icons/copy.js","../node_modules/lucide-react/dist/esm/icons/download.js","../node_modules/lucide-react/dist/esm/icons/ellipsis.js","../node_modules/lucide-react/dist/esm/icons/file-box.js","../node_modules/lucide-react/dist/esm/icons/file-image.js","../node_modules/lucide-react/dist/esm/icons/file-plus.js","../node_modules/lucide-react/dist/esm/icons/file-type.js","../node_modules/lucide-react/dist/esm/icons/flip-horizontal.js","../node_modules/lucide-react/dist/esm/icons/folder-open.js","../node_modules/lucide-react/dist/esm/icons/grid-2x2.js","../node_modules/lucide-react/dist/esm/icons/hand.js","../node_modules/lucide-react/dist/esm/icons/layout-grid.js","../node_modules/lucide-react/dist/esm/icons/list-tree.js","../node_modules/lucide-react/dist/esm/icons/maximize-2.js","../node_modules/lucide-react/dist/esm/icons/minus.js","../node_modules/lucide-react/dist/esm/icons/mouse-pointer-2.js","../node_modules/lucide-react/dist/esm/icons/panel-bottom-close.js","../node_modules/lucide-react/dist/esm/icons/plus.js","../node_modules/lucide-react/dist/esm/icons/redo-2.js","../node_modules/lucide-react/dist/esm/icons/rotate-cw.js","../node_modules/lucide-react/dist/esm/icons/save.js","../node_modules/lucide-react/dist/esm/icons/scissors.js","../node_modules/lucide-react/dist/esm/icons/search.js","../node_modules/lucide-react/dist/esm/icons/shapes.js","../node_modules/lucide-react/dist/esm/icons/square-dashed.js","../node_modules/lucide-react/dist/esm/icons/trash-2.js","../node_modules/lucide-react/dist/esm/icons/type.js","../node_modules/lucide-react/dist/esm/icons/undo-2.js","../node_modules/lucide-react/dist/esm/icons/wand-sparkles.js","../node_modules/lucide-react/dist/esm/icons/x.js","../node_modules/clsx/dist/clsx.mjs","../node_modules/tailwind-merge/dist/bundle-mjs.mjs","../src/lib/utils.ts","../src/components/ContextMenu.tsx","../node_modules/zustand/esm/vanilla.mjs","../node_modules/zustand/esm/react.mjs","../src/i18n/messages.ts","../src/i18n/index.ts","../node_modules/zustand/esm/middleware.mjs","../src/compiler/internal-model.ts","../src/compiler/transforms.ts","../src/compiler/union-find.ts","../src/compiler/auto-layout.ts","../src/compiler/auto-route.ts","../src/element-library/index.ts","../src/compiler/library-index.ts","../src/compiler/compile.ts","../src/store/id-allocator.ts","../src/store/store.ts","../src/canvas/viewport-bus.ts","../src/canvas/grid.ts","../src/canvas/drop-on-bus.ts","../src/canvas/AnnotationLayer.tsx","../src/canvas/FreeAnnotationLayer.tsx","../src/canvas/BusHandles.tsx","../src/canvas/BusLayer.tsx","../src/canvas/BusbarPreview.tsx","../src/canvas/transform-attr.ts","../src/canvas/ElementLayer.tsx","../src/canvas/marquee-bus.ts","../src/canvas/MarqueeOverlay.tsx","../src/canvas/PlaceGhost.tsx","../src/canvas/SelectionOverlay.tsx","../src/canvas/TerminalLayer.tsx","../src/canvas/WireLayer.tsx","../src/canvas/wire-target-bus.ts","../src/canvas/WirePreview.tsx","../src/canvas/hit-test.ts","../src/canvas/synthetic-pointer-cancel.ts","../src/canvas/useKeyboardShortcuts.ts","../src/canvas/hover-bus.ts","../src/canvas/useHoverHighlight.ts","../src/canvas/resolve-wire-target.ts","../src/canvas/tools/SelectTool.ts","../src/canvas/tools/PanTool.ts","../src/hooks/editor-tier.ts","../src/canvas/touch.ts","../src/canvas/tools/WireTool.ts","../src/canvas/tools/PlaceTool.ts","../src/canvas/tools/BusbarTool.ts","../src/canvas/tools/TextTool.ts","../src/canvas/tools/index.ts","../src/canvas/useTools.ts","../src/canvas/zoom-bus.ts","../src/canvas/useViewport.ts","../src/canvas/CanvasSvg.tsx","../src/canvas/fit-to-content.ts","../src/canvas/ElementHoverLabel.tsx","../src/hooks/use-editor-tier.tsx","../node_modules/@radix-ui/react-compose-refs/dist/index.mjs","../node_modules/@radix-ui/react-slot/dist/index.mjs","../node_modules/class-variance-authority/dist/index.mjs","../src/components/ui/button.tsx","../src/components/ui/tooltip.tsx","../src/components/ContextualToolbar.tsx","../src/components/ui/upward-popover.tsx","../src/hooks/use-panels.ts","../src/components/ViewToolbar.tsx","../src/components/FloatingToolbar.tsx","../src/components/LeftPanel.tsx","../src/i18n/library.ts","../src/components/LibraryPopover.tsx","../src/hooks/use-onboarding.ts","../src/components/OnboardingCard.tsx","../src/components/PropertyPanel.tsx","../src/components/RightPanel.tsx","../src/components/EditorShell.tsx","../src/hooks/use-theme.ts","../src/OneLineEditor.tsx","../src/lib/file-io.ts","../src/components/FileMenu.tsx","../src/lib/export-dxf.ts","../src/lib/export-image.ts","../src/components/ExportMenu.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\n\nexport { mergeClasses, toKebabCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n ({\n color = \"currentColor\",\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = \"\",\n children,\n iconNode,\n ...rest\n }, ref) => {\n return createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: mergeClasses(\"lucide\", className),\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n );\n }\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(`lucide-${toKebabCase(iconName)}`, className),\n ...props\n })\n );\n Component.displayName = `${iconName}`;\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Cable = createLucideIcon(\"Cable\", [\n [\n \"path\",\n {\n d: \"M17 21v-2a1 1 0 0 1-1-1v-1a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1\",\n key: \"10bnsj\"\n }\n ],\n [\"path\", { d: \"M19 15V6.5a1 1 0 0 0-7 0v11a1 1 0 0 1-7 0V9\", key: \"1eqmu1\" }],\n [\"path\", { d: \"M21 21v-2h-4\", key: \"14zm7j\" }],\n [\"path\", { d: \"M3 5h4V3\", key: \"z442eg\" }],\n [\n \"path\",\n { d: \"M7 5a1 1 0 0 1 1 1v1a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a1 1 0 0 1 1-1V3\", key: \"ebdjd7\" }\n ]\n]);\n\nexport { Cable as default };\n//# sourceMappingURL=cable.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ChevronDown = createLucideIcon(\"ChevronDown\", [\n [\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]\n]);\n\nexport { ChevronDown as default };\n//# sourceMappingURL=chevron-down.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Clipboard = createLucideIcon(\"Clipboard\", [\n [\"rect\", { width: \"8\", height: \"4\", x: \"8\", y: \"2\", rx: \"1\", ry: \"1\", key: \"tgr4d6\" }],\n [\n \"path\",\n {\n d: \"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\",\n key: \"116196\"\n }\n ]\n]);\n\nexport { Clipboard as default };\n//# sourceMappingURL=clipboard.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Copy = createLucideIcon(\"Copy\", [\n [\"rect\", { width: \"14\", height: \"14\", x: \"8\", y: \"8\", rx: \"2\", ry: \"2\", key: \"17jyea\" }],\n [\"path\", { d: \"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\", key: \"zix9uf\" }]\n]);\n\nexport { Copy as default };\n//# sourceMappingURL=copy.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Download = createLucideIcon(\"Download\", [\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }],\n [\"polyline\", { points: \"7 10 12 15 17 10\", key: \"2ggqvy\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"15\", y2: \"3\", key: \"1vk2je\" }]\n]);\n\nexport { Download as default };\n//# sourceMappingURL=download.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Ellipsis = createLucideIcon(\"Ellipsis\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n [\"circle\", { cx: \"19\", cy: \"12\", r: \"1\", key: \"1wjl8i\" }],\n [\"circle\", { cx: \"5\", cy: \"12\", r: \"1\", key: \"1pcz8c\" }]\n]);\n\nexport { Ellipsis as default };\n//# sourceMappingURL=ellipsis.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileBox = createLucideIcon(\"FileBox\", [\n [\"path\", { d: \"M14.5 22H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4\", key: \"16lz6z\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\n \"path\",\n {\n d: \"M3 13.1a2 2 0 0 0-1 1.76v3.24a2 2 0 0 0 .97 1.78L6 21.7a2 2 0 0 0 2.03.01L11 19.9a2 2 0 0 0 1-1.76V14.9a2 2 0 0 0-.97-1.78L8 11.3a2 2 0 0 0-2.03-.01Z\",\n key: \"99pj1s\"\n }\n ],\n [\"path\", { d: \"M7 17v5\", key: \"1yj1jh\" }],\n [\"path\", { d: \"M11.7 14.2 7 17l-4.7-2.8\", key: \"1yk8tc\" }]\n]);\n\nexport { FileBox as default };\n//# sourceMappingURL=file-box.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileImage = createLucideIcon(\"FileImage\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"circle\", { cx: \"10\", cy: \"12\", r: \"2\", key: \"737tya\" }],\n [\"path\", { d: \"m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22\", key: \"wt3hpn\" }]\n]);\n\nexport { FileImage as default };\n//# sourceMappingURL=file-image.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FilePlus = createLucideIcon(\"FilePlus\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M9 15h6\", key: \"cctwl0\" }],\n [\"path\", { d: \"M12 18v-6\", key: \"17g6i2\" }]\n]);\n\nexport { FilePlus as default };\n//# sourceMappingURL=file-plus.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileType = createLucideIcon(\"FileType\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M9 13v-1h6v1\", key: \"1bb014\" }],\n [\"path\", { d: \"M12 12v6\", key: \"3ahymv\" }],\n [\"path\", { d: \"M11 18h2\", key: \"12mj7e\" }]\n]);\n\nexport { FileType as default };\n//# sourceMappingURL=file-type.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FlipHorizontal = createLucideIcon(\"FlipHorizontal\", [\n [\"path\", { d: \"M8 3H5a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h3\", key: \"1i73f7\" }],\n [\"path\", { d: \"M16 3h3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-3\", key: \"saxlbk\" }],\n [\"path\", { d: \"M12 20v2\", key: \"1lh1kg\" }],\n [\"path\", { d: \"M12 14v2\", key: \"8jcxud\" }],\n [\"path\", { d: \"M12 8v2\", key: \"1woqiv\" }],\n [\"path\", { d: \"M12 2v2\", key: \"tus03m\" }]\n]);\n\nexport { FlipHorizontal as default };\n//# sourceMappingURL=flip-horizontal.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FolderOpen = createLucideIcon(\"FolderOpen\", [\n [\n \"path\",\n {\n d: \"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2\",\n key: \"usdka0\"\n }\n ]\n]);\n\nexport { FolderOpen as default };\n//# sourceMappingURL=folder-open.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Grid2x2 = createLucideIcon(\"Grid2x2\", [\n [\"path\", { d: \"M12 3v18\", key: \"108xh3\" }],\n [\"path\", { d: \"M3 12h18\", key: \"1i2n21\" }],\n [\"rect\", { x: \"3\", y: \"3\", width: \"18\", height: \"18\", rx: \"2\", key: \"h1oib\" }]\n]);\n\nexport { Grid2x2 as default };\n//# sourceMappingURL=grid-2x2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Hand = createLucideIcon(\"Hand\", [\n [\"path\", { d: \"M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2\", key: \"1fvzgz\" }],\n [\"path\", { d: \"M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2\", key: \"1kc0my\" }],\n [\"path\", { d: \"M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8\", key: \"10h0bg\" }],\n [\n \"path\",\n {\n d: \"M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15\",\n key: \"1s1gnw\"\n }\n ]\n]);\n\nexport { Hand as default };\n//# sourceMappingURL=hand.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst LayoutGrid = createLucideIcon(\"LayoutGrid\", [\n [\"rect\", { width: \"7\", height: \"7\", x: \"3\", y: \"3\", rx: \"1\", key: \"1g98yp\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"14\", y: \"3\", rx: \"1\", key: \"6d4xhi\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"14\", y: \"14\", rx: \"1\", key: \"nxv5o0\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"3\", y: \"14\", rx: \"1\", key: \"1bb6yr\" }]\n]);\n\nexport { LayoutGrid as default };\n//# sourceMappingURL=layout-grid.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ListTree = createLucideIcon(\"ListTree\", [\n [\"path\", { d: \"M21 12h-8\", key: \"1bmf0i\" }],\n [\"path\", { d: \"M21 6H8\", key: \"1pqkrb\" }],\n [\"path\", { d: \"M21 18h-8\", key: \"1tm79t\" }],\n [\"path\", { d: \"M3 6v4c0 1.1.9 2 2 2h3\", key: \"1ywdgy\" }],\n [\"path\", { d: \"M3 10v6c0 1.1.9 2 2 2h3\", key: \"2wc746\" }]\n]);\n\nexport { ListTree as default };\n//# sourceMappingURL=list-tree.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Maximize2 = createLucideIcon(\"Maximize2\", [\n [\"polyline\", { points: \"15 3 21 3 21 9\", key: \"mznyad\" }],\n [\"polyline\", { points: \"9 21 3 21 3 15\", key: \"1avn1i\" }],\n [\"line\", { x1: \"21\", x2: \"14\", y1: \"3\", y2: \"10\", key: \"ota7mn\" }],\n [\"line\", { x1: \"3\", x2: \"10\", y1: \"21\", y2: \"14\", key: \"1atl0r\" }]\n]);\n\nexport { Maximize2 as default };\n//# sourceMappingURL=maximize-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Minus = createLucideIcon(\"Minus\", [[\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }]]);\n\nexport { Minus as default };\n//# sourceMappingURL=minus.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst MousePointer2 = createLucideIcon(\"MousePointer2\", [\n [\n \"path\",\n {\n d: \"M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z\",\n key: \"edeuup\"\n }\n ]\n]);\n\nexport { MousePointer2 as default };\n//# sourceMappingURL=mouse-pointer-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst PanelBottomClose = createLucideIcon(\"PanelBottomClose\", [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 15h18\", key: \"5xshup\" }],\n [\"path\", { d: \"m15 8-3 3-3-3\", key: \"1oxy1z\" }]\n]);\n\nexport { PanelBottomClose as default };\n//# sourceMappingURL=panel-bottom-close.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Plus = createLucideIcon(\"Plus\", [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n]);\n\nexport { Plus as default };\n//# sourceMappingURL=plus.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Redo2 = createLucideIcon(\"Redo2\", [\n [\"path\", { d: \"m15 14 5-5-5-5\", key: \"12vg1m\" }],\n [\"path\", { d: \"M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13\", key: \"6uklza\" }]\n]);\n\nexport { Redo2 as default };\n//# sourceMappingURL=redo-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RotateCw = createLucideIcon(\"RotateCw\", [\n [\"path\", { d: \"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\", key: \"1p45f6\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }]\n]);\n\nexport { RotateCw as default };\n//# sourceMappingURL=rotate-cw.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Save = createLucideIcon(\"Save\", [\n [\n \"path\",\n {\n d: \"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n]);\n\nexport { Save as default };\n//# sourceMappingURL=save.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Scissors = createLucideIcon(\"Scissors\", [\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M8.12 8.12 12 12\", key: \"1alkpv\" }],\n [\"path\", { d: \"M20 4 8.12 15.88\", key: \"xgtan2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M14.8 14.8 20 20\", key: \"ptml3r\" }]\n]);\n\nexport { Scissors as default };\n//# sourceMappingURL=scissors.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Search = createLucideIcon(\"Search\", [\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }],\n [\"path\", { d: \"m21 21-4.3-4.3\", key: \"1qie3q\" }]\n]);\n\nexport { Search as default };\n//# sourceMappingURL=search.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Shapes = createLucideIcon(\"Shapes\", [\n [\n \"path\",\n {\n d: \"M8.3 10a.7.7 0 0 1-.626-1.079L11.4 3a.7.7 0 0 1 1.198-.043L16.3 8.9a.7.7 0 0 1-.572 1.1Z\",\n key: \"1bo67w\"\n }\n ],\n [\"rect\", { x: \"3\", y: \"14\", width: \"7\", height: \"7\", rx: \"1\", key: \"1bkyp8\" }],\n [\"circle\", { cx: \"17.5\", cy: \"17.5\", r: \"3.5\", key: \"w3z12y\" }]\n]);\n\nexport { Shapes as default };\n//# sourceMappingURL=shapes.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst SquareDashed = createLucideIcon(\"SquareDashed\", [\n [\"path\", { d: \"M5 3a2 2 0 0 0-2 2\", key: \"y57alp\" }],\n [\"path\", { d: \"M19 3a2 2 0 0 1 2 2\", key: \"18rm91\" }],\n [\"path\", { d: \"M21 19a2 2 0 0 1-2 2\", key: \"1j7049\" }],\n [\"path\", { d: \"M5 21a2 2 0 0 1-2-2\", key: \"sbafld\" }],\n [\"path\", { d: \"M9 3h1\", key: \"1yesri\" }],\n [\"path\", { d: \"M9 21h1\", key: \"15o7lz\" }],\n [\"path\", { d: \"M14 3h1\", key: \"1ec4yj\" }],\n [\"path\", { d: \"M14 21h1\", key: \"v9vybs\" }],\n [\"path\", { d: \"M3 9v1\", key: \"1r0deq\" }],\n [\"path\", { d: \"M21 9v1\", key: \"mxsmne\" }],\n [\"path\", { d: \"M3 14v1\", key: \"vnatye\" }],\n [\"path\", { d: \"M21 14v1\", key: \"169vum\" }]\n]);\n\nexport { SquareDashed as default };\n//# sourceMappingURL=square-dashed.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Trash2 = createLucideIcon(\"Trash2\", [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"11\", y2: \"17\", key: \"1uufr5\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"11\", y2: \"17\", key: \"xtxkd\" }]\n]);\n\nexport { Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Type = createLucideIcon(\"Type\", [\n [\"polyline\", { points: \"4 7 4 4 20 4 20 7\", key: \"1nosan\" }],\n [\"line\", { x1: \"9\", x2: \"15\", y1: \"20\", y2: \"20\", key: \"swin9y\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"4\", y2: \"20\", key: \"1tx1rr\" }]\n]);\n\nexport { Type as default };\n//# sourceMappingURL=type.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Undo2 = createLucideIcon(\"Undo2\", [\n [\"path\", { d: \"M9 14 4 9l5-5\", key: \"102s5s\" }],\n [\"path\", { d: \"M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11\", key: \"f3b9sd\" }]\n]);\n\nexport { Undo2 as default };\n//# sourceMappingURL=undo-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst WandSparkles = createLucideIcon(\"WandSparkles\", [\n [\n \"path\",\n {\n d: \"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72\",\n key: \"ul74o6\"\n }\n ],\n [\"path\", { d: \"m14 7 3 3\", key: \"1r5n42\" }],\n [\"path\", { d: \"M5 6v4\", key: \"ilb8ba\" }],\n [\"path\", { d: \"M19 14v4\", key: \"blhpug\" }],\n [\"path\", { d: \"M10 2v2\", key: \"7u0qdc\" }],\n [\"path\", { d: \"M7 8H3\", key: \"zfb6yr\" }],\n [\"path\", { d: \"M21 16h-4\", key: \"1cnmox\" }],\n [\"path\", { d: \"M11 3H9\", key: \"1obp7u\" }]\n]);\n\nexport { WandSparkles as default };\n//# sourceMappingURL=wand-sparkles.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst X = createLucideIcon(\"X\", [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n]);\n\nexport { X as default };\n//# sourceMappingURL=x.js.map\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","const CLASS_PART_SEPARATOR = '-';\nconst createClassGroupUtils = config => {\n const classMap = createClassMap(config);\n const {\n conflictingClassGroups,\n conflictingClassGroupModifiers\n } = config;\n const getClassGroupId = className => {\n const classParts = className.split(CLASS_PART_SEPARATOR);\n // Classes like `-inset-1` produce an empty string as first classPart. We assume that classes for negative values are used correctly and remove it from classParts.\n if (classParts[0] === '' && classParts.length !== 1) {\n classParts.shift();\n }\n return getGroupRecursive(classParts, classMap) || getGroupIdForArbitraryProperty(className);\n };\n const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {\n const conflicts = conflictingClassGroups[classGroupId] || [];\n if (hasPostfixModifier && conflictingClassGroupModifiers[classGroupId]) {\n return [...conflicts, ...conflictingClassGroupModifiers[classGroupId]];\n }\n return conflicts;\n };\n return {\n getClassGroupId,\n getConflictingClassGroupIds\n };\n};\nconst getGroupRecursive = (classParts, classPartObject) => {\n if (classParts.length === 0) {\n return classPartObject.classGroupId;\n }\n const currentClassPart = classParts[0];\n const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);\n const classGroupFromNextClassPart = nextClassPartObject ? getGroupRecursive(classParts.slice(1), nextClassPartObject) : undefined;\n if (classGroupFromNextClassPart) {\n return classGroupFromNextClassPart;\n }\n if (classPartObject.validators.length === 0) {\n return undefined;\n }\n const classRest = classParts.join(CLASS_PART_SEPARATOR);\n return classPartObject.validators.find(({\n validator\n }) => validator(classRest))?.classGroupId;\n};\nconst arbitraryPropertyRegex = /^\\[(.+)\\]$/;\nconst getGroupIdForArbitraryProperty = className => {\n if (arbitraryPropertyRegex.test(className)) {\n const arbitraryPropertyClassName = arbitraryPropertyRegex.exec(className)[1];\n const property = arbitraryPropertyClassName?.substring(0, arbitraryPropertyClassName.indexOf(':'));\n if (property) {\n // I use two dots here because one dot is used as prefix for class groups in plugins\n return 'arbitrary..' + property;\n }\n }\n};\n/**\n * Exported for testing only\n */\nconst createClassMap = config => {\n const {\n theme,\n prefix\n } = config;\n const classMap = {\n nextPart: new Map(),\n validators: []\n };\n const prefixedClassGroupEntries = getPrefixedClassGroupEntries(Object.entries(config.classGroups), prefix);\n prefixedClassGroupEntries.forEach(([classGroupId, classGroup]) => {\n processClassesRecursively(classGroup, classMap, classGroupId, theme);\n });\n return classMap;\n};\nconst processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {\n classGroup.forEach(classDefinition => {\n if (typeof classDefinition === 'string') {\n const classPartObjectToEdit = classDefinition === '' ? classPartObject : getPart(classPartObject, classDefinition);\n classPartObjectToEdit.classGroupId = classGroupId;\n return;\n }\n if (typeof classDefinition === 'function') {\n if (isThemeGetter(classDefinition)) {\n processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);\n return;\n }\n classPartObject.validators.push({\n validator: classDefinition,\n classGroupId\n });\n return;\n }\n Object.entries(classDefinition).forEach(([key, classGroup]) => {\n processClassesRecursively(classGroup, getPart(classPartObject, key), classGroupId, theme);\n });\n });\n};\nconst getPart = (classPartObject, path) => {\n let currentClassPartObject = classPartObject;\n path.split(CLASS_PART_SEPARATOR).forEach(pathPart => {\n if (!currentClassPartObject.nextPart.has(pathPart)) {\n currentClassPartObject.nextPart.set(pathPart, {\n nextPart: new Map(),\n validators: []\n });\n }\n currentClassPartObject = currentClassPartObject.nextPart.get(pathPart);\n });\n return currentClassPartObject;\n};\nconst isThemeGetter = func => func.isThemeGetter;\nconst getPrefixedClassGroupEntries = (classGroupEntries, prefix) => {\n if (!prefix) {\n return classGroupEntries;\n }\n return classGroupEntries.map(([classGroupId, classGroup]) => {\n const prefixedClassGroup = classGroup.map(classDefinition => {\n if (typeof classDefinition === 'string') {\n return prefix + classDefinition;\n }\n if (typeof classDefinition === 'object') {\n return Object.fromEntries(Object.entries(classDefinition).map(([key, value]) => [prefix + key, value]));\n }\n return classDefinition;\n });\n return [classGroupId, prefixedClassGroup];\n });\n};\n\n// LRU cache inspired from hashlru (https://github.com/dominictarr/hashlru/blob/v1.0.4/index.js) but object replaced with Map to improve performance\nconst createLruCache = maxCacheSize => {\n if (maxCacheSize < 1) {\n return {\n get: () => undefined,\n set: () => {}\n };\n }\n let cacheSize = 0;\n let cache = new Map();\n let previousCache = new Map();\n const update = (key, value) => {\n cache.set(key, value);\n cacheSize++;\n if (cacheSize > maxCacheSize) {\n cacheSize = 0;\n previousCache = cache;\n cache = new Map();\n }\n };\n return {\n get(key) {\n let value = cache.get(key);\n if (value !== undefined) {\n return value;\n }\n if ((value = previousCache.get(key)) !== undefined) {\n update(key, value);\n return value;\n }\n },\n set(key, value) {\n if (cache.has(key)) {\n cache.set(key, value);\n } else {\n update(key, value);\n }\n }\n };\n};\nconst IMPORTANT_MODIFIER = '!';\nconst createParseClassName = config => {\n const {\n separator,\n experimentalParseClassName\n } = config;\n const isSeparatorSingleCharacter = separator.length === 1;\n const firstSeparatorCharacter = separator[0];\n const separatorLength = separator.length;\n // parseClassName inspired by https://github.com/tailwindlabs/tailwindcss/blob/v3.2.2/src/util/splitAtTopLevelOnly.js\n const parseClassName = className => {\n const modifiers = [];\n let bracketDepth = 0;\n let modifierStart = 0;\n let postfixModifierPosition;\n for (let index = 0; index < className.length; index++) {\n let currentCharacter = className[index];\n if (bracketDepth === 0) {\n if (currentCharacter === firstSeparatorCharacter && (isSeparatorSingleCharacter || className.slice(index, index + separatorLength) === separator)) {\n modifiers.push(className.slice(modifierStart, index));\n modifierStart = index + separatorLength;\n continue;\n }\n if (currentCharacter === '/') {\n postfixModifierPosition = index;\n continue;\n }\n }\n if (currentCharacter === '[') {\n bracketDepth++;\n } else if (currentCharacter === ']') {\n bracketDepth--;\n }\n }\n const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.substring(modifierStart);\n const hasImportantModifier = baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER);\n const baseClassName = hasImportantModifier ? baseClassNameWithImportantModifier.substring(1) : baseClassNameWithImportantModifier;\n const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart : undefined;\n return {\n modifiers,\n hasImportantModifier,\n baseClassName,\n maybePostfixModifierPosition\n };\n };\n if (experimentalParseClassName) {\n return className => experimentalParseClassName({\n className,\n parseClassName\n });\n }\n return parseClassName;\n};\n/**\n * Sorts modifiers according to following schema:\n * - Predefined modifiers are sorted alphabetically\n * - When an arbitrary variant appears, it must be preserved which modifiers are before and after it\n */\nconst sortModifiers = modifiers => {\n if (modifiers.length <= 1) {\n return modifiers;\n }\n const sortedModifiers = [];\n let unsortedModifiers = [];\n modifiers.forEach(modifier => {\n const isArbitraryVariant = modifier[0] === '[';\n if (isArbitraryVariant) {\n sortedModifiers.push(...unsortedModifiers.sort(), modifier);\n unsortedModifiers = [];\n } else {\n unsortedModifiers.push(modifier);\n }\n });\n sortedModifiers.push(...unsortedModifiers.sort());\n return sortedModifiers;\n};\nconst createConfigUtils = config => ({\n cache: createLruCache(config.cacheSize),\n parseClassName: createParseClassName(config),\n ...createClassGroupUtils(config)\n});\nconst SPLIT_CLASSES_REGEX = /\\s+/;\nconst mergeClassList = (classList, configUtils) => {\n const {\n parseClassName,\n getClassGroupId,\n getConflictingClassGroupIds\n } = configUtils;\n /**\n * Set of classGroupIds in following format:\n * `{importantModifier}{variantModifiers}{classGroupId}`\n * @example 'float'\n * @example 'hover:focus:bg-color'\n * @example 'md:!pr'\n */\n const classGroupsInConflict = [];\n const classNames = classList.trim().split(SPLIT_CLASSES_REGEX);\n let result = '';\n for (let index = classNames.length - 1; index >= 0; index -= 1) {\n const originalClassName = classNames[index];\n const {\n modifiers,\n hasImportantModifier,\n baseClassName,\n maybePostfixModifierPosition\n } = parseClassName(originalClassName);\n let hasPostfixModifier = Boolean(maybePostfixModifierPosition);\n let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);\n if (!classGroupId) {\n if (!hasPostfixModifier) {\n // Not a Tailwind class\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n continue;\n }\n classGroupId = getClassGroupId(baseClassName);\n if (!classGroupId) {\n // Not a Tailwind class\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n continue;\n }\n hasPostfixModifier = false;\n }\n const variantModifier = sortModifiers(modifiers).join(':');\n const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER : variantModifier;\n const classId = modifierId + classGroupId;\n if (classGroupsInConflict.includes(classId)) {\n // Tailwind class omitted due to conflict\n continue;\n }\n classGroupsInConflict.push(classId);\n const conflictGroups = getConflictingClassGroupIds(classGroupId, hasPostfixModifier);\n for (let i = 0; i < conflictGroups.length; ++i) {\n const group = conflictGroups[i];\n classGroupsInConflict.push(modifierId + group);\n }\n // Tailwind class not in conflict\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n }\n return result;\n};\n\n/**\n * The code in this file is copied from https://github.com/lukeed/clsx and modified to suit the needs of tailwind-merge better.\n *\n * Specifically:\n * - Runtime code from https://github.com/lukeed/clsx/blob/v1.2.1/src/index.js\n * - TypeScript types from https://github.com/lukeed/clsx/blob/v1.2.1/clsx.d.ts\n *\n * Original code has MIT license: Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)\n */\nfunction twJoin() {\n let index = 0;\n let argument;\n let resolvedValue;\n let string = '';\n while (index < arguments.length) {\n if (argument = arguments[index++]) {\n if (resolvedValue = toValue(argument)) {\n string && (string += ' ');\n string += resolvedValue;\n }\n }\n }\n return string;\n}\nconst toValue = mix => {\n if (typeof mix === 'string') {\n return mix;\n }\n let resolvedValue;\n let string = '';\n for (let k = 0; k < mix.length; k++) {\n if (mix[k]) {\n if (resolvedValue = toValue(mix[k])) {\n string && (string += ' ');\n string += resolvedValue;\n }\n }\n }\n return string;\n};\nfunction createTailwindMerge(createConfigFirst, ...createConfigRest) {\n let configUtils;\n let cacheGet;\n let cacheSet;\n let functionToCall = initTailwindMerge;\n function initTailwindMerge(classList) {\n const config = createConfigRest.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst());\n configUtils = createConfigUtils(config);\n cacheGet = configUtils.cache.get;\n cacheSet = configUtils.cache.set;\n functionToCall = tailwindMerge;\n return tailwindMerge(classList);\n }\n function tailwindMerge(classList) {\n const cachedResult = cacheGet(classList);\n if (cachedResult) {\n return cachedResult;\n }\n const result = mergeClassList(classList, configUtils);\n cacheSet(classList, result);\n return result;\n }\n return function callTailwindMerge() {\n return functionToCall(twJoin.apply(null, arguments));\n };\n}\nconst fromTheme = key => {\n const themeGetter = theme => theme[key] || [];\n themeGetter.isThemeGetter = true;\n return themeGetter;\n};\nconst arbitraryValueRegex = /^\\[(?:([a-z-]+):)?(.+)\\]$/i;\nconst fractionRegex = /^\\d+\\/\\d+$/;\nconst stringLengths = /*#__PURE__*/new Set(['px', 'full', 'screen']);\nconst tshirtUnitRegex = /^(\\d+(\\.\\d+)?)?(xs|sm|md|lg|xl)$/;\nconst lengthUnitRegex = /\\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\\b(calc|min|max|clamp)\\(.+\\)|^0$/;\nconst colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\\(.+\\)$/;\n// Shadow always begins with x and y offset separated by underscore optionally prepended by inset\nconst shadowRegex = /^(inset_)?-?((\\d+)?\\.?(\\d+)[a-z]+|0)_-?((\\d+)?\\.?(\\d+)[a-z]+|0)/;\nconst imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\\(.+\\)$/;\nconst isLength = value => isNumber(value) || stringLengths.has(value) || fractionRegex.test(value);\nconst isArbitraryLength = value => getIsArbitraryValue(value, 'length', isLengthOnly);\nconst isNumber = value => Boolean(value) && !Number.isNaN(Number(value));\nconst isArbitraryNumber = value => getIsArbitraryValue(value, 'number', isNumber);\nconst isInteger = value => Boolean(value) && Number.isInteger(Number(value));\nconst isPercent = value => value.endsWith('%') && isNumber(value.slice(0, -1));\nconst isArbitraryValue = value => arbitraryValueRegex.test(value);\nconst isTshirtSize = value => tshirtUnitRegex.test(value);\nconst sizeLabels = /*#__PURE__*/new Set(['length', 'size', 'percentage']);\nconst isArbitrarySize = value => getIsArbitraryValue(value, sizeLabels, isNever);\nconst isArbitraryPosition = value => getIsArbitraryValue(value, 'position', isNever);\nconst imageLabels = /*#__PURE__*/new Set(['image', 'url']);\nconst isArbitraryImage = value => getIsArbitraryValue(value, imageLabels, isImage);\nconst isArbitraryShadow = value => getIsArbitraryValue(value, '', isShadow);\nconst isAny = () => true;\nconst getIsArbitraryValue = (value, label, testValue) => {\n const result = arbitraryValueRegex.exec(value);\n if (result) {\n if (result[1]) {\n return typeof label === 'string' ? result[1] === label : label.has(result[1]);\n }\n return testValue(result[2]);\n }\n return false;\n};\nconst isLengthOnly = value =>\n// `colorFunctionRegex` check is necessary because color functions can have percentages in them which which would be incorrectly classified as lengths.\n// For example, `hsl(0 0% 0%)` would be classified as a length without this check.\n// I could also use lookbehind assertion in `lengthUnitRegex` but that isn't supported widely enough.\nlengthUnitRegex.test(value) && !colorFunctionRegex.test(value);\nconst isNever = () => false;\nconst isShadow = value => shadowRegex.test(value);\nconst isImage = value => imageRegex.test(value);\nconst validators = /*#__PURE__*/Object.defineProperty({\n __proto__: null,\n isAny,\n isArbitraryImage,\n isArbitraryLength,\n isArbitraryNumber,\n isArbitraryPosition,\n isArbitraryShadow,\n isArbitrarySize,\n isArbitraryValue,\n isInteger,\n isLength,\n isNumber,\n isPercent,\n isTshirtSize\n}, Symbol.toStringTag, {\n value: 'Module'\n});\nconst getDefaultConfig = () => {\n const colors = fromTheme('colors');\n const spacing = fromTheme('spacing');\n const blur = fromTheme('blur');\n const brightness = fromTheme('brightness');\n const borderColor = fromTheme('borderColor');\n const borderRadius = fromTheme('borderRadius');\n const borderSpacing = fromTheme('borderSpacing');\n const borderWidth = fromTheme('borderWidth');\n const contrast = fromTheme('contrast');\n const grayscale = fromTheme('grayscale');\n const hueRotate = fromTheme('hueRotate');\n const invert = fromTheme('invert');\n const gap = fromTheme('gap');\n const gradientColorStops = fromTheme('gradientColorStops');\n const gradientColorStopPositions = fromTheme('gradientColorStopPositions');\n const inset = fromTheme('inset');\n const margin = fromTheme('margin');\n const opacity = fromTheme('opacity');\n const padding = fromTheme('padding');\n const saturate = fromTheme('saturate');\n const scale = fromTheme('scale');\n const sepia = fromTheme('sepia');\n const skew = fromTheme('skew');\n const space = fromTheme('space');\n const translate = fromTheme('translate');\n const getOverscroll = () => ['auto', 'contain', 'none'];\n const getOverflow = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'];\n const getSpacingWithAutoAndArbitrary = () => ['auto', isArbitraryValue, spacing];\n const getSpacingWithArbitrary = () => [isArbitraryValue, spacing];\n const getLengthWithEmptyAndArbitrary = () => ['', isLength, isArbitraryLength];\n const getNumberWithAutoAndArbitrary = () => ['auto', isNumber, isArbitraryValue];\n const getPositions = () => ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top'];\n const getLineStyles = () => ['solid', 'dashed', 'dotted', 'double', 'none'];\n const getBlendModes = () => ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'];\n const getAlign = () => ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch'];\n const getZeroAndEmpty = () => ['', '0', isArbitraryValue];\n const getBreaks = () => ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'];\n const getNumberAndArbitrary = () => [isNumber, isArbitraryValue];\n return {\n cacheSize: 500,\n separator: ':',\n theme: {\n colors: [isAny],\n spacing: [isLength, isArbitraryLength],\n blur: ['none', '', isTshirtSize, isArbitraryValue],\n brightness: getNumberAndArbitrary(),\n borderColor: [colors],\n borderRadius: ['none', '', 'full', isTshirtSize, isArbitraryValue],\n borderSpacing: getSpacingWithArbitrary(),\n borderWidth: getLengthWithEmptyAndArbitrary(),\n contrast: getNumberAndArbitrary(),\n grayscale: getZeroAndEmpty(),\n hueRotate: getNumberAndArbitrary(),\n invert: getZeroAndEmpty(),\n gap: getSpacingWithArbitrary(),\n gradientColorStops: [colors],\n gradientColorStopPositions: [isPercent, isArbitraryLength],\n inset: getSpacingWithAutoAndArbitrary(),\n margin: getSpacingWithAutoAndArbitrary(),\n opacity: getNumberAndArbitrary(),\n padding: getSpacingWithArbitrary(),\n saturate: getNumberAndArbitrary(),\n scale: getNumberAndArbitrary(),\n sepia: getZeroAndEmpty(),\n skew: getNumberAndArbitrary(),\n space: getSpacingWithArbitrary(),\n translate: getSpacingWithArbitrary()\n },\n classGroups: {\n // Layout\n /**\n * Aspect Ratio\n * @see https://tailwindcss.com/docs/aspect-ratio\n */\n aspect: [{\n aspect: ['auto', 'square', 'video', isArbitraryValue]\n }],\n /**\n * Container\n * @see https://tailwindcss.com/docs/container\n */\n container: ['container'],\n /**\n * Columns\n * @see https://tailwindcss.com/docs/columns\n */\n columns: [{\n columns: [isTshirtSize]\n }],\n /**\n * Break After\n * @see https://tailwindcss.com/docs/break-after\n */\n 'break-after': [{\n 'break-after': getBreaks()\n }],\n /**\n * Break Before\n * @see https://tailwindcss.com/docs/break-before\n */\n 'break-before': [{\n 'break-before': getBreaks()\n }],\n /**\n * Break Inside\n * @see https://tailwindcss.com/docs/break-inside\n */\n 'break-inside': [{\n 'break-inside': ['auto', 'avoid', 'avoid-page', 'avoid-column']\n }],\n /**\n * Box Decoration Break\n * @see https://tailwindcss.com/docs/box-decoration-break\n */\n 'box-decoration': [{\n 'box-decoration': ['slice', 'clone']\n }],\n /**\n * Box Sizing\n * @see https://tailwindcss.com/docs/box-sizing\n */\n box: [{\n box: ['border', 'content']\n }],\n /**\n * Display\n * @see https://tailwindcss.com/docs/display\n */\n display: ['block', 'inline-block', 'inline', 'flex', 'inline-flex', 'table', 'inline-table', 'table-caption', 'table-cell', 'table-column', 'table-column-group', 'table-footer-group', 'table-header-group', 'table-row-group', 'table-row', 'flow-root', 'grid', 'inline-grid', 'contents', 'list-item', 'hidden'],\n /**\n * Floats\n * @see https://tailwindcss.com/docs/float\n */\n float: [{\n float: ['right', 'left', 'none', 'start', 'end']\n }],\n /**\n * Clear\n * @see https://tailwindcss.com/docs/clear\n */\n clear: [{\n clear: ['left', 'right', 'both', 'none', 'start', 'end']\n }],\n /**\n * Isolation\n * @see https://tailwindcss.com/docs/isolation\n */\n isolation: ['isolate', 'isolation-auto'],\n /**\n * Object Fit\n * @see https://tailwindcss.com/docs/object-fit\n */\n 'object-fit': [{\n object: ['contain', 'cover', 'fill', 'none', 'scale-down']\n }],\n /**\n * Object Position\n * @see https://tailwindcss.com/docs/object-position\n */\n 'object-position': [{\n object: [...getPositions(), isArbitraryValue]\n }],\n /**\n * Overflow\n * @see https://tailwindcss.com/docs/overflow\n */\n overflow: [{\n overflow: getOverflow()\n }],\n /**\n * Overflow X\n * @see https://tailwindcss.com/docs/overflow\n */\n 'overflow-x': [{\n 'overflow-x': getOverflow()\n }],\n /**\n * Overflow Y\n * @see https://tailwindcss.com/docs/overflow\n */\n 'overflow-y': [{\n 'overflow-y': getOverflow()\n }],\n /**\n * Overscroll Behavior\n * @see https://tailwindcss.com/docs/overscroll-behavior\n */\n overscroll: [{\n overscroll: getOverscroll()\n }],\n /**\n * Overscroll Behavior X\n * @see https://tailwindcss.com/docs/overscroll-behavior\n */\n 'overscroll-x': [{\n 'overscroll-x': getOverscroll()\n }],\n /**\n * Overscroll Behavior Y\n * @see https://tailwindcss.com/docs/overscroll-behavior\n */\n 'overscroll-y': [{\n 'overscroll-y': getOverscroll()\n }],\n /**\n * Position\n * @see https://tailwindcss.com/docs/position\n */\n position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],\n /**\n * Top / Right / Bottom / Left\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n inset: [{\n inset: [inset]\n }],\n /**\n * Right / Left\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n 'inset-x': [{\n 'inset-x': [inset]\n }],\n /**\n * Top / Bottom\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n 'inset-y': [{\n 'inset-y': [inset]\n }],\n /**\n * Start\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n start: [{\n start: [inset]\n }],\n /**\n * End\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n end: [{\n end: [inset]\n }],\n /**\n * Top\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n top: [{\n top: [inset]\n }],\n /**\n * Right\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n right: [{\n right: [inset]\n }],\n /**\n * Bottom\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n bottom: [{\n bottom: [inset]\n }],\n /**\n * Left\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n left: [{\n left: [inset]\n }],\n /**\n * Visibility\n * @see https://tailwindcss.com/docs/visibility\n */\n visibility: ['visible', 'invisible', 'collapse'],\n /**\n * Z-Index\n * @see https://tailwindcss.com/docs/z-index\n */\n z: [{\n z: ['auto', isInteger, isArbitraryValue]\n }],\n // Flexbox and Grid\n /**\n * Flex Basis\n * @see https://tailwindcss.com/docs/flex-basis\n */\n basis: [{\n basis: getSpacingWithAutoAndArbitrary()\n }],\n /**\n * Flex Direction\n * @see https://tailwindcss.com/docs/flex-direction\n */\n 'flex-direction': [{\n flex: ['row', 'row-reverse', 'col', 'col-reverse']\n }],\n /**\n * Flex Wrap\n * @see https://tailwindcss.com/docs/flex-wrap\n */\n 'flex-wrap': [{\n flex: ['wrap', 'wrap-reverse', 'nowrap']\n }],\n /**\n * Flex\n * @see https://tailwindcss.com/docs/flex\n */\n flex: [{\n flex: ['1', 'auto', 'initial', 'none', isArbitraryValue]\n }],\n /**\n * Flex Grow\n * @see https://tailwindcss.com/docs/flex-grow\n */\n grow: [{\n grow: getZeroAndEmpty()\n }],\n /**\n * Flex Shrink\n * @see https://tailwindcss.com/docs/flex-shrink\n */\n shrink: [{\n shrink: getZeroAndEmpty()\n }],\n /**\n * Order\n * @see https://tailwindcss.com/docs/order\n */\n order: [{\n order: ['first', 'last', 'none', isInteger, isArbitraryValue]\n }],\n /**\n * Grid Template Columns\n * @see https://tailwindcss.com/docs/grid-template-columns\n */\n 'grid-cols': [{\n 'grid-cols': [isAny]\n }],\n /**\n * Grid Column Start / End\n * @see https://tailwindcss.com/docs/grid-column\n */\n 'col-start-end': [{\n col: ['auto', {\n span: ['full', isInteger, isArbitraryValue]\n }, isArbitraryValue]\n }],\n /**\n * Grid Column Start\n * @see https://tailwindcss.com/docs/grid-column\n */\n 'col-start': [{\n 'col-start': getNumberWithAutoAndArbitrary()\n }],\n /**\n * Grid Column End\n * @see https://tailwindcss.com/docs/grid-column\n */\n 'col-end': [{\n 'col-end': getNumberWithAutoAndArbitrary()\n }],\n /**\n * Grid Template Rows\n * @see https://tailwindcss.com/docs/grid-template-rows\n */\n 'grid-rows': [{\n 'grid-rows': [isAny]\n }],\n /**\n * Grid Row Start / End\n * @see https://tailwindcss.com/docs/grid-row\n */\n 'row-start-end': [{\n row: ['auto', {\n span: [isInteger, isArbitraryValue]\n }, isArbitraryValue]\n }],\n /**\n * Grid Row Start\n * @see https://tailwindcss.com/docs/grid-row\n */\n 'row-start': [{\n 'row-start': getNumberWithAutoAndArbitrary()\n }],\n /**\n * Grid Row End\n * @see https://tailwindcss.com/docs/grid-row\n */\n 'row-end': [{\n 'row-end': getNumberWithAutoAndArbitrary()\n }],\n /**\n * Grid Auto Flow\n * @see https://tailwindcss.com/docs/grid-auto-flow\n */\n 'grid-flow': [{\n 'grid-flow': ['row', 'col', 'dense', 'row-dense', 'col-dense']\n }],\n /**\n * Grid Auto Columns\n * @see https://tailwindcss.com/docs/grid-auto-columns\n */\n 'auto-cols': [{\n 'auto-cols': ['auto', 'min', 'max', 'fr', isArbitraryValue]\n }],\n /**\n * Grid Auto Rows\n * @see https://tailwindcss.com/docs/grid-auto-rows\n */\n 'auto-rows': [{\n 'auto-rows': ['auto', 'min', 'max', 'fr', isArbitraryValue]\n }],\n /**\n * Gap\n * @see https://tailwindcss.com/docs/gap\n */\n gap: [{\n gap: [gap]\n }],\n /**\n * Gap X\n * @see https://tailwindcss.com/docs/gap\n */\n 'gap-x': [{\n 'gap-x': [gap]\n }],\n /**\n * Gap Y\n * @see https://tailwindcss.com/docs/gap\n */\n 'gap-y': [{\n 'gap-y': [gap]\n }],\n /**\n * Justify Content\n * @see https://tailwindcss.com/docs/justify-content\n */\n 'justify-content': [{\n justify: ['normal', ...getAlign()]\n }],\n /**\n * Justify Items\n * @see https://tailwindcss.com/docs/justify-items\n */\n 'justify-items': [{\n 'justify-items': ['start', 'end', 'center', 'stretch']\n }],\n /**\n * Justify Self\n * @see https://tailwindcss.com/docs/justify-self\n */\n 'justify-self': [{\n 'justify-self': ['auto', 'start', 'end', 'center', 'stretch']\n }],\n /**\n * Align Content\n * @see https://tailwindcss.com/docs/align-content\n */\n 'align-content': [{\n content: ['normal', ...getAlign(), 'baseline']\n }],\n /**\n * Align Items\n * @see https://tailwindcss.com/docs/align-items\n */\n 'align-items': [{\n items: ['start', 'end', 'center', 'baseline', 'stretch']\n }],\n /**\n * Align Self\n * @see https://tailwindcss.com/docs/align-self\n */\n 'align-self': [{\n self: ['auto', 'start', 'end', 'center', 'stretch', 'baseline']\n }],\n /**\n * Place Content\n * @see https://tailwindcss.com/docs/place-content\n */\n 'place-content': [{\n 'place-content': [...getAlign(), 'baseline']\n }],\n /**\n * Place Items\n * @see https://tailwindcss.com/docs/place-items\n */\n 'place-items': [{\n 'place-items': ['start', 'end', 'center', 'baseline', 'stretch']\n }],\n /**\n * Place Self\n * @see https://tailwindcss.com/docs/place-self\n */\n 'place-self': [{\n 'place-self': ['auto', 'start', 'end', 'center', 'stretch']\n }],\n // Spacing\n /**\n * Padding\n * @see https://tailwindcss.com/docs/padding\n */\n p: [{\n p: [padding]\n }],\n /**\n * Padding X\n * @see https://tailwindcss.com/docs/padding\n */\n px: [{\n px: [padding]\n }],\n /**\n * Padding Y\n * @see https://tailwindcss.com/docs/padding\n */\n py: [{\n py: [padding]\n }],\n /**\n * Padding Start\n * @see https://tailwindcss.com/docs/padding\n */\n ps: [{\n ps: [padding]\n }],\n /**\n * Padding End\n * @see https://tailwindcss.com/docs/padding\n */\n pe: [{\n pe: [padding]\n }],\n /**\n * Padding Top\n * @see https://tailwindcss.com/docs/padding\n */\n pt: [{\n pt: [padding]\n }],\n /**\n * Padding Right\n * @see https://tailwindcss.com/docs/padding\n */\n pr: [{\n pr: [padding]\n }],\n /**\n * Padding Bottom\n * @see https://tailwindcss.com/docs/padding\n */\n pb: [{\n pb: [padding]\n }],\n /**\n * Padding Left\n * @see https://tailwindcss.com/docs/padding\n */\n pl: [{\n pl: [padding]\n }],\n /**\n * Margin\n * @see https://tailwindcss.com/docs/margin\n */\n m: [{\n m: [margin]\n }],\n /**\n * Margin X\n * @see https://tailwindcss.com/docs/margin\n */\n mx: [{\n mx: [margin]\n }],\n /**\n * Margin Y\n * @see https://tailwindcss.com/docs/margin\n */\n my: [{\n my: [margin]\n }],\n /**\n * Margin Start\n * @see https://tailwindcss.com/docs/margin\n */\n ms: [{\n ms: [margin]\n }],\n /**\n * Margin End\n * @see https://tailwindcss.com/docs/margin\n */\n me: [{\n me: [margin]\n }],\n /**\n * Margin Top\n * @see https://tailwindcss.com/docs/margin\n */\n mt: [{\n mt: [margin]\n }],\n /**\n * Margin Right\n * @see https://tailwindcss.com/docs/margin\n */\n mr: [{\n mr: [margin]\n }],\n /**\n * Margin Bottom\n * @see https://tailwindcss.com/docs/margin\n */\n mb: [{\n mb: [margin]\n }],\n /**\n * Margin Left\n * @see https://tailwindcss.com/docs/margin\n */\n ml: [{\n ml: [margin]\n }],\n /**\n * Space Between X\n * @see https://tailwindcss.com/docs/space\n */\n 'space-x': [{\n 'space-x': [space]\n }],\n /**\n * Space Between X Reverse\n * @see https://tailwindcss.com/docs/space\n */\n 'space-x-reverse': ['space-x-reverse'],\n /**\n * Space Between Y\n * @see https://tailwindcss.com/docs/space\n */\n 'space-y': [{\n 'space-y': [space]\n }],\n /**\n * Space Between Y Reverse\n * @see https://tailwindcss.com/docs/space\n */\n 'space-y-reverse': ['space-y-reverse'],\n // Sizing\n /**\n * Width\n * @see https://tailwindcss.com/docs/width\n */\n w: [{\n w: ['auto', 'min', 'max', 'fit', 'svw', 'lvw', 'dvw', isArbitraryValue, spacing]\n }],\n /**\n * Min-Width\n * @see https://tailwindcss.com/docs/min-width\n */\n 'min-w': [{\n 'min-w': [isArbitraryValue, spacing, 'min', 'max', 'fit']\n }],\n /**\n * Max-Width\n * @see https://tailwindcss.com/docs/max-width\n */\n 'max-w': [{\n 'max-w': [isArbitraryValue, spacing, 'none', 'full', 'min', 'max', 'fit', 'prose', {\n screen: [isTshirtSize]\n }, isTshirtSize]\n }],\n /**\n * Height\n * @see https://tailwindcss.com/docs/height\n */\n h: [{\n h: [isArbitraryValue, spacing, 'auto', 'min', 'max', 'fit', 'svh', 'lvh', 'dvh']\n }],\n /**\n * Min-Height\n * @see https://tailwindcss.com/docs/min-height\n */\n 'min-h': [{\n 'min-h': [isArbitraryValue, spacing, 'min', 'max', 'fit', 'svh', 'lvh', 'dvh']\n }],\n /**\n * Max-Height\n * @see https://tailwindcss.com/docs/max-height\n */\n 'max-h': [{\n 'max-h': [isArbitraryValue, spacing, 'min', 'max', 'fit', 'svh', 'lvh', 'dvh']\n }],\n /**\n * Size\n * @see https://tailwindcss.com/docs/size\n */\n size: [{\n size: [isArbitraryValue, spacing, 'auto', 'min', 'max', 'fit']\n }],\n // Typography\n /**\n * Font Size\n * @see https://tailwindcss.com/docs/font-size\n */\n 'font-size': [{\n text: ['base', isTshirtSize, isArbitraryLength]\n }],\n /**\n * Font Smoothing\n * @see https://tailwindcss.com/docs/font-smoothing\n */\n 'font-smoothing': ['antialiased', 'subpixel-antialiased'],\n /**\n * Font Style\n * @see https://tailwindcss.com/docs/font-style\n */\n 'font-style': ['italic', 'not-italic'],\n /**\n * Font Weight\n * @see https://tailwindcss.com/docs/font-weight\n */\n 'font-weight': [{\n font: ['thin', 'extralight', 'light', 'normal', 'medium', 'semibold', 'bold', 'extrabold', 'black', isArbitraryNumber]\n }],\n /**\n * Font Family\n * @see https://tailwindcss.com/docs/font-family\n */\n 'font-family': [{\n font: [isAny]\n }],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-normal': ['normal-nums'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-ordinal': ['ordinal'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-slashed-zero': ['slashed-zero'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-figure': ['lining-nums', 'oldstyle-nums'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-spacing': ['proportional-nums', 'tabular-nums'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-fraction': ['diagonal-fractions', 'stacked-fractions'],\n /**\n * Letter Spacing\n * @see https://tailwindcss.com/docs/letter-spacing\n */\n tracking: [{\n tracking: ['tighter', 'tight', 'normal', 'wide', 'wider', 'widest', isArbitraryValue]\n }],\n /**\n * Line Clamp\n * @see https://tailwindcss.com/docs/line-clamp\n */\n 'line-clamp': [{\n 'line-clamp': ['none', isNumber, isArbitraryNumber]\n }],\n /**\n * Line Height\n * @see https://tailwindcss.com/docs/line-height\n */\n leading: [{\n leading: ['none', 'tight', 'snug', 'normal', 'relaxed', 'loose', isLength, isArbitraryValue]\n }],\n /**\n * List Style Image\n * @see https://tailwindcss.com/docs/list-style-image\n */\n 'list-image': [{\n 'list-image': ['none', isArbitraryValue]\n }],\n /**\n * List Style Type\n * @see https://tailwindcss.com/docs/list-style-type\n */\n 'list-style-type': [{\n list: ['none', 'disc', 'decimal', isArbitraryValue]\n }],\n /**\n * List Style Position\n * @see https://tailwindcss.com/docs/list-style-position\n */\n 'list-style-position': [{\n list: ['inside', 'outside']\n }],\n /**\n * Placeholder Color\n * @deprecated since Tailwind CSS v3.0.0\n * @see https://tailwindcss.com/docs/placeholder-color\n */\n 'placeholder-color': [{\n placeholder: [colors]\n }],\n /**\n * Placeholder Opacity\n * @see https://tailwindcss.com/docs/placeholder-opacity\n */\n 'placeholder-opacity': [{\n 'placeholder-opacity': [opacity]\n }],\n /**\n * Text Alignment\n * @see https://tailwindcss.com/docs/text-align\n */\n 'text-alignment': [{\n text: ['left', 'center', 'right', 'justify', 'start', 'end']\n }],\n /**\n * Text Color\n * @see https://tailwindcss.com/docs/text-color\n */\n 'text-color': [{\n text: [colors]\n }],\n /**\n * Text Opacity\n * @see https://tailwindcss.com/docs/text-opacity\n */\n 'text-opacity': [{\n 'text-opacity': [opacity]\n }],\n /**\n * Text Decoration\n * @see https://tailwindcss.com/docs/text-decoration\n */\n 'text-decoration': ['underline', 'overline', 'line-through', 'no-underline'],\n /**\n * Text Decoration Style\n * @see https://tailwindcss.com/docs/text-decoration-style\n */\n 'text-decoration-style': [{\n decoration: [...getLineStyles(), 'wavy']\n }],\n /**\n * Text Decoration Thickness\n * @see https://tailwindcss.com/docs/text-decoration-thickness\n */\n 'text-decoration-thickness': [{\n decoration: ['auto', 'from-font', isLength, isArbitraryLength]\n }],\n /**\n * Text Underline Offset\n * @see https://tailwindcss.com/docs/text-underline-offset\n */\n 'underline-offset': [{\n 'underline-offset': ['auto', isLength, isArbitraryValue]\n }],\n /**\n * Text Decoration Color\n * @see https://tailwindcss.com/docs/text-decoration-color\n */\n 'text-decoration-color': [{\n decoration: [colors]\n }],\n /**\n * Text Transform\n * @see https://tailwindcss.com/docs/text-transform\n */\n 'text-transform': ['uppercase', 'lowercase', 'capitalize', 'normal-case'],\n /**\n * Text Overflow\n * @see https://tailwindcss.com/docs/text-overflow\n */\n 'text-overflow': ['truncate', 'text-ellipsis', 'text-clip'],\n /**\n * Text Wrap\n * @see https://tailwindcss.com/docs/text-wrap\n */\n 'text-wrap': [{\n text: ['wrap', 'nowrap', 'balance', 'pretty']\n }],\n /**\n * Text Indent\n * @see https://tailwindcss.com/docs/text-indent\n */\n indent: [{\n indent: getSpacingWithArbitrary()\n }],\n /**\n * Vertical Alignment\n * @see https://tailwindcss.com/docs/vertical-align\n */\n 'vertical-align': [{\n align: ['baseline', 'top', 'middle', 'bottom', 'text-top', 'text-bottom', 'sub', 'super', isArbitraryValue]\n }],\n /**\n * Whitespace\n * @see https://tailwindcss.com/docs/whitespace\n */\n whitespace: [{\n whitespace: ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'break-spaces']\n }],\n /**\n * Word Break\n * @see https://tailwindcss.com/docs/word-break\n */\n break: [{\n break: ['normal', 'words', 'all', 'keep']\n }],\n /**\n * Hyphens\n * @see https://tailwindcss.com/docs/hyphens\n */\n hyphens: [{\n hyphens: ['none', 'manual', 'auto']\n }],\n /**\n * Content\n * @see https://tailwindcss.com/docs/content\n */\n content: [{\n content: ['none', isArbitraryValue]\n }],\n // Backgrounds\n /**\n * Background Attachment\n * @see https://tailwindcss.com/docs/background-attachment\n */\n 'bg-attachment': [{\n bg: ['fixed', 'local', 'scroll']\n }],\n /**\n * Background Clip\n * @see https://tailwindcss.com/docs/background-clip\n */\n 'bg-clip': [{\n 'bg-clip': ['border', 'padding', 'content', 'text']\n }],\n /**\n * Background Opacity\n * @deprecated since Tailwind CSS v3.0.0\n * @see https://tailwindcss.com/docs/background-opacity\n */\n 'bg-opacity': [{\n 'bg-opacity': [opacity]\n }],\n /**\n * Background Origin\n * @see https://tailwindcss.com/docs/background-origin\n */\n 'bg-origin': [{\n 'bg-origin': ['border', 'padding', 'content']\n }],\n /**\n * Background Position\n * @see https://tailwindcss.com/docs/background-position\n */\n 'bg-position': [{\n bg: [...getPositions(), isArbitraryPosition]\n }],\n /**\n * Background Repeat\n * @see https://tailwindcss.com/docs/background-repeat\n */\n 'bg-repeat': [{\n bg: ['no-repeat', {\n repeat: ['', 'x', 'y', 'round', 'space']\n }]\n }],\n /**\n * Background Size\n * @see https://tailwindcss.com/docs/background-size\n */\n 'bg-size': [{\n bg: ['auto', 'cover', 'contain', isArbitrarySize]\n }],\n /**\n * Background Image\n * @see https://tailwindcss.com/docs/background-image\n */\n 'bg-image': [{\n bg: ['none', {\n 'gradient-to': ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl']\n }, isArbitraryImage]\n }],\n /**\n * Background Color\n * @see https://tailwindcss.com/docs/background-color\n */\n 'bg-color': [{\n bg: [colors]\n }],\n /**\n * Gradient Color Stops From Position\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-from-pos': [{\n from: [gradientColorStopPositions]\n }],\n /**\n * Gradient Color Stops Via Position\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-via-pos': [{\n via: [gradientColorStopPositions]\n }],\n /**\n * Gradient Color Stops To Position\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-to-pos': [{\n to: [gradientColorStopPositions]\n }],\n /**\n * Gradient Color Stops From\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-from': [{\n from: [gradientColorStops]\n }],\n /**\n * Gradient Color Stops Via\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-via': [{\n via: [gradientColorStops]\n }],\n /**\n * Gradient Color Stops To\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-to': [{\n to: [gradientColorStops]\n }],\n // Borders\n /**\n * Border Radius\n * @see https://tailwindcss.com/docs/border-radius\n */\n rounded: [{\n rounded: [borderRadius]\n }],\n /**\n * Border Radius Start\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-s': [{\n 'rounded-s': [borderRadius]\n }],\n /**\n * Border Radius End\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-e': [{\n 'rounded-e': [borderRadius]\n }],\n /**\n * Border Radius Top\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-t': [{\n 'rounded-t': [borderRadius]\n }],\n /**\n * Border Radius Right\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-r': [{\n 'rounded-r': [borderRadius]\n }],\n /**\n * Border Radius Bottom\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-b': [{\n 'rounded-b': [borderRadius]\n }],\n /**\n * Border Radius Left\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-l': [{\n 'rounded-l': [borderRadius]\n }],\n /**\n * Border Radius Start Start\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-ss': [{\n 'rounded-ss': [borderRadius]\n }],\n /**\n * Border Radius Start End\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-se': [{\n 'rounded-se': [borderRadius]\n }],\n /**\n * Border Radius End End\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-ee': [{\n 'rounded-ee': [borderRadius]\n }],\n /**\n * Border Radius End Start\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-es': [{\n 'rounded-es': [borderRadius]\n }],\n /**\n * Border Radius Top Left\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-tl': [{\n 'rounded-tl': [borderRadius]\n }],\n /**\n * Border Radius Top Right\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-tr': [{\n 'rounded-tr': [borderRadius]\n }],\n /**\n * Border Radius Bottom Right\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-br': [{\n 'rounded-br': [borderRadius]\n }],\n /**\n * Border Radius Bottom Left\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-bl': [{\n 'rounded-bl': [borderRadius]\n }],\n /**\n * Border Width\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w': [{\n border: [borderWidth]\n }],\n /**\n * Border Width X\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-x': [{\n 'border-x': [borderWidth]\n }],\n /**\n * Border Width Y\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-y': [{\n 'border-y': [borderWidth]\n }],\n /**\n * Border Width Start\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-s': [{\n 'border-s': [borderWidth]\n }],\n /**\n * Border Width End\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-e': [{\n 'border-e': [borderWidth]\n }],\n /**\n * Border Width Top\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-t': [{\n 'border-t': [borderWidth]\n }],\n /**\n * Border Width Right\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-r': [{\n 'border-r': [borderWidth]\n }],\n /**\n * Border Width Bottom\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-b': [{\n 'border-b': [borderWidth]\n }],\n /**\n * Border Width Left\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-l': [{\n 'border-l': [borderWidth]\n }],\n /**\n * Border Opacity\n * @see https://tailwindcss.com/docs/border-opacity\n */\n 'border-opacity': [{\n 'border-opacity': [opacity]\n }],\n /**\n * Border Style\n * @see https://tailwindcss.com/docs/border-style\n */\n 'border-style': [{\n border: [...getLineStyles(), 'hidden']\n }],\n /**\n * Divide Width X\n * @see https://tailwindcss.com/docs/divide-width\n */\n 'divide-x': [{\n 'divide-x': [borderWidth]\n }],\n /**\n * Divide Width X Reverse\n * @see https://tailwindcss.com/docs/divide-width\n */\n 'divide-x-reverse': ['divide-x-reverse'],\n /**\n * Divide Width Y\n * @see https://tailwindcss.com/docs/divide-width\n */\n 'divide-y': [{\n 'divide-y': [borderWidth]\n }],\n /**\n * Divide Width Y Reverse\n * @see https://tailwindcss.com/docs/divide-width\n */\n 'divide-y-reverse': ['divide-y-reverse'],\n /**\n * Divide Opacity\n * @see https://tailwindcss.com/docs/divide-opacity\n */\n 'divide-opacity': [{\n 'divide-opacity': [opacity]\n }],\n /**\n * Divide Style\n * @see https://tailwindcss.com/docs/divide-style\n */\n 'divide-style': [{\n divide: getLineStyles()\n }],\n /**\n * Border Color\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color': [{\n border: [borderColor]\n }],\n /**\n * Border Color X\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-x': [{\n 'border-x': [borderColor]\n }],\n /**\n * Border Color Y\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-y': [{\n 'border-y': [borderColor]\n }],\n /**\n * Border Color S\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-s': [{\n 'border-s': [borderColor]\n }],\n /**\n * Border Color E\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-e': [{\n 'border-e': [borderColor]\n }],\n /**\n * Border Color Top\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-t': [{\n 'border-t': [borderColor]\n }],\n /**\n * Border Color Right\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-r': [{\n 'border-r': [borderColor]\n }],\n /**\n * Border Color Bottom\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-b': [{\n 'border-b': [borderColor]\n }],\n /**\n * Border Color Left\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-l': [{\n 'border-l': [borderColor]\n }],\n /**\n * Divide Color\n * @see https://tailwindcss.com/docs/divide-color\n */\n 'divide-color': [{\n divide: [borderColor]\n }],\n /**\n * Outline Style\n * @see https://tailwindcss.com/docs/outline-style\n */\n 'outline-style': [{\n outline: ['', ...getLineStyles()]\n }],\n /**\n * Outline Offset\n * @see https://tailwindcss.com/docs/outline-offset\n */\n 'outline-offset': [{\n 'outline-offset': [isLength, isArbitraryValue]\n }],\n /**\n * Outline Width\n * @see https://tailwindcss.com/docs/outline-width\n */\n 'outline-w': [{\n outline: [isLength, isArbitraryLength]\n }],\n /**\n * Outline Color\n * @see https://tailwindcss.com/docs/outline-color\n */\n 'outline-color': [{\n outline: [colors]\n }],\n /**\n * Ring Width\n * @see https://tailwindcss.com/docs/ring-width\n */\n 'ring-w': [{\n ring: getLengthWithEmptyAndArbitrary()\n }],\n /**\n * Ring Width Inset\n * @see https://tailwindcss.com/docs/ring-width\n */\n 'ring-w-inset': ['ring-inset'],\n /**\n * Ring Color\n * @see https://tailwindcss.com/docs/ring-color\n */\n 'ring-color': [{\n ring: [colors]\n }],\n /**\n * Ring Opacity\n * @see https://tailwindcss.com/docs/ring-opacity\n */\n 'ring-opacity': [{\n 'ring-opacity': [opacity]\n }],\n /**\n * Ring Offset Width\n * @see https://tailwindcss.com/docs/ring-offset-width\n */\n 'ring-offset-w': [{\n 'ring-offset': [isLength, isArbitraryLength]\n }],\n /**\n * Ring Offset Color\n * @see https://tailwindcss.com/docs/ring-offset-color\n */\n 'ring-offset-color': [{\n 'ring-offset': [colors]\n }],\n // Effects\n /**\n * Box Shadow\n * @see https://tailwindcss.com/docs/box-shadow\n */\n shadow: [{\n shadow: ['', 'inner', 'none', isTshirtSize, isArbitraryShadow]\n }],\n /**\n * Box Shadow Color\n * @see https://tailwindcss.com/docs/box-shadow-color\n */\n 'shadow-color': [{\n shadow: [isAny]\n }],\n /**\n * Opacity\n * @see https://tailwindcss.com/docs/opacity\n */\n opacity: [{\n opacity: [opacity]\n }],\n /**\n * Mix Blend Mode\n * @see https://tailwindcss.com/docs/mix-blend-mode\n */\n 'mix-blend': [{\n 'mix-blend': [...getBlendModes(), 'plus-lighter', 'plus-darker']\n }],\n /**\n * Background Blend Mode\n * @see https://tailwindcss.com/docs/background-blend-mode\n */\n 'bg-blend': [{\n 'bg-blend': getBlendModes()\n }],\n // Filters\n /**\n * Filter\n * @deprecated since Tailwind CSS v3.0.0\n * @see https://tailwindcss.com/docs/filter\n */\n filter: [{\n filter: ['', 'none']\n }],\n /**\n * Blur\n * @see https://tailwindcss.com/docs/blur\n */\n blur: [{\n blur: [blur]\n }],\n /**\n * Brightness\n * @see https://tailwindcss.com/docs/brightness\n */\n brightness: [{\n brightness: [brightness]\n }],\n /**\n * Contrast\n * @see https://tailwindcss.com/docs/contrast\n */\n contrast: [{\n contrast: [contrast]\n }],\n /**\n * Drop Shadow\n * @see https://tailwindcss.com/docs/drop-shadow\n */\n 'drop-shadow': [{\n 'drop-shadow': ['', 'none', isTshirtSize, isArbitraryValue]\n }],\n /**\n * Grayscale\n * @see https://tailwindcss.com/docs/grayscale\n */\n grayscale: [{\n grayscale: [grayscale]\n }],\n /**\n * Hue Rotate\n * @see https://tailwindcss.com/docs/hue-rotate\n */\n 'hue-rotate': [{\n 'hue-rotate': [hueRotate]\n }],\n /**\n * Invert\n * @see https://tailwindcss.com/docs/invert\n */\n invert: [{\n invert: [invert]\n }],\n /**\n * Saturate\n * @see https://tailwindcss.com/docs/saturate\n */\n saturate: [{\n saturate: [saturate]\n }],\n /**\n * Sepia\n * @see https://tailwindcss.com/docs/sepia\n */\n sepia: [{\n sepia: [sepia]\n }],\n /**\n * Backdrop Filter\n * @deprecated since Tailwind CSS v3.0.0\n * @see https://tailwindcss.com/docs/backdrop-filter\n */\n 'backdrop-filter': [{\n 'backdrop-filter': ['', 'none']\n }],\n /**\n * Backdrop Blur\n * @see https://tailwindcss.com/docs/backdrop-blur\n */\n 'backdrop-blur': [{\n 'backdrop-blur': [blur]\n }],\n /**\n * Backdrop Brightness\n * @see https://tailwindcss.com/docs/backdrop-brightness\n */\n 'backdrop-brightness': [{\n 'backdrop-brightness': [brightness]\n }],\n /**\n * Backdrop Contrast\n * @see https://tailwindcss.com/docs/backdrop-contrast\n */\n 'backdrop-contrast': [{\n 'backdrop-contrast': [contrast]\n }],\n /**\n * Backdrop Grayscale\n * @see https://tailwindcss.com/docs/backdrop-grayscale\n */\n 'backdrop-grayscale': [{\n 'backdrop-grayscale': [grayscale]\n }],\n /**\n * Backdrop Hue Rotate\n * @see https://tailwindcss.com/docs/backdrop-hue-rotate\n */\n 'backdrop-hue-rotate': [{\n 'backdrop-hue-rotate': [hueRotate]\n }],\n /**\n * Backdrop Invert\n * @see https://tailwindcss.com/docs/backdrop-invert\n */\n 'backdrop-invert': [{\n 'backdrop-invert': [invert]\n }],\n /**\n * Backdrop Opacity\n * @see https://tailwindcss.com/docs/backdrop-opacity\n */\n 'backdrop-opacity': [{\n 'backdrop-opacity': [opacity]\n }],\n /**\n * Backdrop Saturate\n * @see https://tailwindcss.com/docs/backdrop-saturate\n */\n 'backdrop-saturate': [{\n 'backdrop-saturate': [saturate]\n }],\n /**\n * Backdrop Sepia\n * @see https://tailwindcss.com/docs/backdrop-sepia\n */\n 'backdrop-sepia': [{\n 'backdrop-sepia': [sepia]\n }],\n // Tables\n /**\n * Border Collapse\n * @see https://tailwindcss.com/docs/border-collapse\n */\n 'border-collapse': [{\n border: ['collapse', 'separate']\n }],\n /**\n * Border Spacing\n * @see https://tailwindcss.com/docs/border-spacing\n */\n 'border-spacing': [{\n 'border-spacing': [borderSpacing]\n }],\n /**\n * Border Spacing X\n * @see https://tailwindcss.com/docs/border-spacing\n */\n 'border-spacing-x': [{\n 'border-spacing-x': [borderSpacing]\n }],\n /**\n * Border Spacing Y\n * @see https://tailwindcss.com/docs/border-spacing\n */\n 'border-spacing-y': [{\n 'border-spacing-y': [borderSpacing]\n }],\n /**\n * Table Layout\n * @see https://tailwindcss.com/docs/table-layout\n */\n 'table-layout': [{\n table: ['auto', 'fixed']\n }],\n /**\n * Caption Side\n * @see https://tailwindcss.com/docs/caption-side\n */\n caption: [{\n caption: ['top', 'bottom']\n }],\n // Transitions and Animation\n /**\n * Tranisition Property\n * @see https://tailwindcss.com/docs/transition-property\n */\n transition: [{\n transition: ['none', 'all', '', 'colors', 'opacity', 'shadow', 'transform', isArbitraryValue]\n }],\n /**\n * Transition Duration\n * @see https://tailwindcss.com/docs/transition-duration\n */\n duration: [{\n duration: getNumberAndArbitrary()\n }],\n /**\n * Transition Timing Function\n * @see https://tailwindcss.com/docs/transition-timing-function\n */\n ease: [{\n ease: ['linear', 'in', 'out', 'in-out', isArbitraryValue]\n }],\n /**\n * Transition Delay\n * @see https://tailwindcss.com/docs/transition-delay\n */\n delay: [{\n delay: getNumberAndArbitrary()\n }],\n /**\n * Animation\n * @see https://tailwindcss.com/docs/animation\n */\n animate: [{\n animate: ['none', 'spin', 'ping', 'pulse', 'bounce', isArbitraryValue]\n }],\n // Transforms\n /**\n * Transform\n * @see https://tailwindcss.com/docs/transform\n */\n transform: [{\n transform: ['', 'gpu', 'none']\n }],\n /**\n * Scale\n * @see https://tailwindcss.com/docs/scale\n */\n scale: [{\n scale: [scale]\n }],\n /**\n * Scale X\n * @see https://tailwindcss.com/docs/scale\n */\n 'scale-x': [{\n 'scale-x': [scale]\n }],\n /**\n * Scale Y\n * @see https://tailwindcss.com/docs/scale\n */\n 'scale-y': [{\n 'scale-y': [scale]\n }],\n /**\n * Rotate\n * @see https://tailwindcss.com/docs/rotate\n */\n rotate: [{\n rotate: [isInteger, isArbitraryValue]\n }],\n /**\n * Translate X\n * @see https://tailwindcss.com/docs/translate\n */\n 'translate-x': [{\n 'translate-x': [translate]\n }],\n /**\n * Translate Y\n * @see https://tailwindcss.com/docs/translate\n */\n 'translate-y': [{\n 'translate-y': [translate]\n }],\n /**\n * Skew X\n * @see https://tailwindcss.com/docs/skew\n */\n 'skew-x': [{\n 'skew-x': [skew]\n }],\n /**\n * Skew Y\n * @see https://tailwindcss.com/docs/skew\n */\n 'skew-y': [{\n 'skew-y': [skew]\n }],\n /**\n * Transform Origin\n * @see https://tailwindcss.com/docs/transform-origin\n */\n 'transform-origin': [{\n origin: ['center', 'top', 'top-right', 'right', 'bottom-right', 'bottom', 'bottom-left', 'left', 'top-left', isArbitraryValue]\n }],\n // Interactivity\n /**\n * Accent Color\n * @see https://tailwindcss.com/docs/accent-color\n */\n accent: [{\n accent: ['auto', colors]\n }],\n /**\n * Appearance\n * @see https://tailwindcss.com/docs/appearance\n */\n appearance: [{\n appearance: ['none', 'auto']\n }],\n /**\n * Cursor\n * @see https://tailwindcss.com/docs/cursor\n */\n cursor: [{\n cursor: ['auto', 'default', 'pointer', 'wait', 'text', 'move', 'help', 'not-allowed', 'none', 'context-menu', 'progress', 'cell', 'crosshair', 'vertical-text', 'alias', 'copy', 'no-drop', 'grab', 'grabbing', 'all-scroll', 'col-resize', 'row-resize', 'n-resize', 'e-resize', 's-resize', 'w-resize', 'ne-resize', 'nw-resize', 'se-resize', 'sw-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out', isArbitraryValue]\n }],\n /**\n * Caret Color\n * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities\n */\n 'caret-color': [{\n caret: [colors]\n }],\n /**\n * Pointer Events\n * @see https://tailwindcss.com/docs/pointer-events\n */\n 'pointer-events': [{\n 'pointer-events': ['none', 'auto']\n }],\n /**\n * Resize\n * @see https://tailwindcss.com/docs/resize\n */\n resize: [{\n resize: ['none', 'y', 'x', '']\n }],\n /**\n * Scroll Behavior\n * @see https://tailwindcss.com/docs/scroll-behavior\n */\n 'scroll-behavior': [{\n scroll: ['auto', 'smooth']\n }],\n /**\n * Scroll Margin\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-m': [{\n 'scroll-m': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin X\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mx': [{\n 'scroll-mx': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Y\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-my': [{\n 'scroll-my': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Start\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-ms': [{\n 'scroll-ms': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin End\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-me': [{\n 'scroll-me': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Top\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mt': [{\n 'scroll-mt': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Right\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mr': [{\n 'scroll-mr': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Bottom\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mb': [{\n 'scroll-mb': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Left\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-ml': [{\n 'scroll-ml': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-p': [{\n 'scroll-p': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding X\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-px': [{\n 'scroll-px': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Y\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-py': [{\n 'scroll-py': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Start\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-ps': [{\n 'scroll-ps': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding End\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pe': [{\n 'scroll-pe': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Top\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pt': [{\n 'scroll-pt': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Right\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pr': [{\n 'scroll-pr': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Bottom\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pb': [{\n 'scroll-pb': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Left\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pl': [{\n 'scroll-pl': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Snap Align\n * @see https://tailwindcss.com/docs/scroll-snap-align\n */\n 'snap-align': [{\n snap: ['start', 'end', 'center', 'align-none']\n }],\n /**\n * Scroll Snap Stop\n * @see https://tailwindcss.com/docs/scroll-snap-stop\n */\n 'snap-stop': [{\n snap: ['normal', 'always']\n }],\n /**\n * Scroll Snap Type\n * @see https://tailwindcss.com/docs/scroll-snap-type\n */\n 'snap-type': [{\n snap: ['none', 'x', 'y', 'both']\n }],\n /**\n * Scroll Snap Type Strictness\n * @see https://tailwindcss.com/docs/scroll-snap-type\n */\n 'snap-strictness': [{\n snap: ['mandatory', 'proximity']\n }],\n /**\n * Touch Action\n * @see https://tailwindcss.com/docs/touch-action\n */\n touch: [{\n touch: ['auto', 'none', 'manipulation']\n }],\n /**\n * Touch Action X\n * @see https://tailwindcss.com/docs/touch-action\n */\n 'touch-x': [{\n 'touch-pan': ['x', 'left', 'right']\n }],\n /**\n * Touch Action Y\n * @see https://tailwindcss.com/docs/touch-action\n */\n 'touch-y': [{\n 'touch-pan': ['y', 'up', 'down']\n }],\n /**\n * Touch Action Pinch Zoom\n * @see https://tailwindcss.com/docs/touch-action\n */\n 'touch-pz': ['touch-pinch-zoom'],\n /**\n * User Select\n * @see https://tailwindcss.com/docs/user-select\n */\n select: [{\n select: ['none', 'text', 'all', 'auto']\n }],\n /**\n * Will Change\n * @see https://tailwindcss.com/docs/will-change\n */\n 'will-change': [{\n 'will-change': ['auto', 'scroll', 'contents', 'transform', isArbitraryValue]\n }],\n // SVG\n /**\n * Fill\n * @see https://tailwindcss.com/docs/fill\n */\n fill: [{\n fill: [colors, 'none']\n }],\n /**\n * Stroke Width\n * @see https://tailwindcss.com/docs/stroke-width\n */\n 'stroke-w': [{\n stroke: [isLength, isArbitraryLength, isArbitraryNumber]\n }],\n /**\n * Stroke\n * @see https://tailwindcss.com/docs/stroke\n */\n stroke: [{\n stroke: [colors, 'none']\n }],\n // Accessibility\n /**\n * Screen Readers\n * @see https://tailwindcss.com/docs/screen-readers\n */\n sr: ['sr-only', 'not-sr-only'],\n /**\n * Forced Color Adjust\n * @see https://tailwindcss.com/docs/forced-color-adjust\n */\n 'forced-color-adjust': [{\n 'forced-color-adjust': ['auto', 'none']\n }]\n },\n conflictingClassGroups: {\n overflow: ['overflow-x', 'overflow-y'],\n overscroll: ['overscroll-x', 'overscroll-y'],\n inset: ['inset-x', 'inset-y', 'start', 'end', 'top', 'right', 'bottom', 'left'],\n 'inset-x': ['right', 'left'],\n 'inset-y': ['top', 'bottom'],\n flex: ['basis', 'grow', 'shrink'],\n gap: ['gap-x', 'gap-y'],\n p: ['px', 'py', 'ps', 'pe', 'pt', 'pr', 'pb', 'pl'],\n px: ['pr', 'pl'],\n py: ['pt', 'pb'],\n m: ['mx', 'my', 'ms', 'me', 'mt', 'mr', 'mb', 'ml'],\n mx: ['mr', 'ml'],\n my: ['mt', 'mb'],\n size: ['w', 'h'],\n 'font-size': ['leading'],\n 'fvn-normal': ['fvn-ordinal', 'fvn-slashed-zero', 'fvn-figure', 'fvn-spacing', 'fvn-fraction'],\n 'fvn-ordinal': ['fvn-normal'],\n 'fvn-slashed-zero': ['fvn-normal'],\n 'fvn-figure': ['fvn-normal'],\n 'fvn-spacing': ['fvn-normal'],\n 'fvn-fraction': ['fvn-normal'],\n 'line-clamp': ['display', 'overflow'],\n rounded: ['rounded-s', 'rounded-e', 'rounded-t', 'rounded-r', 'rounded-b', 'rounded-l', 'rounded-ss', 'rounded-se', 'rounded-ee', 'rounded-es', 'rounded-tl', 'rounded-tr', 'rounded-br', 'rounded-bl'],\n 'rounded-s': ['rounded-ss', 'rounded-es'],\n 'rounded-e': ['rounded-se', 'rounded-ee'],\n 'rounded-t': ['rounded-tl', 'rounded-tr'],\n 'rounded-r': ['rounded-tr', 'rounded-br'],\n 'rounded-b': ['rounded-br', 'rounded-bl'],\n 'rounded-l': ['rounded-tl', 'rounded-bl'],\n 'border-spacing': ['border-spacing-x', 'border-spacing-y'],\n 'border-w': ['border-w-s', 'border-w-e', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],\n 'border-w-x': ['border-w-r', 'border-w-l'],\n 'border-w-y': ['border-w-t', 'border-w-b'],\n 'border-color': ['border-color-s', 'border-color-e', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],\n 'border-color-x': ['border-color-r', 'border-color-l'],\n 'border-color-y': ['border-color-t', 'border-color-b'],\n 'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],\n 'scroll-mx': ['scroll-mr', 'scroll-ml'],\n 'scroll-my': ['scroll-mt', 'scroll-mb'],\n 'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],\n 'scroll-px': ['scroll-pr', 'scroll-pl'],\n 'scroll-py': ['scroll-pt', 'scroll-pb'],\n touch: ['touch-x', 'touch-y', 'touch-pz'],\n 'touch-x': ['touch'],\n 'touch-y': ['touch'],\n 'touch-pz': ['touch']\n },\n conflictingClassGroupModifiers: {\n 'font-size': ['leading']\n }\n };\n};\n\n/**\n * @param baseConfig Config where other config will be merged into. This object will be mutated.\n * @param configExtension Partial config to merge into the `baseConfig`.\n */\nconst mergeConfigs = (baseConfig, {\n cacheSize,\n prefix,\n separator,\n experimentalParseClassName,\n extend = {},\n override = {}\n}) => {\n overrideProperty(baseConfig, 'cacheSize', cacheSize);\n overrideProperty(baseConfig, 'prefix', prefix);\n overrideProperty(baseConfig, 'separator', separator);\n overrideProperty(baseConfig, 'experimentalParseClassName', experimentalParseClassName);\n for (const configKey in override) {\n overrideConfigProperties(baseConfig[configKey], override[configKey]);\n }\n for (const key in extend) {\n mergeConfigProperties(baseConfig[key], extend[key]);\n }\n return baseConfig;\n};\nconst overrideProperty = (baseObject, overrideKey, overrideValue) => {\n if (overrideValue !== undefined) {\n baseObject[overrideKey] = overrideValue;\n }\n};\nconst overrideConfigProperties = (baseObject, overrideObject) => {\n if (overrideObject) {\n for (const key in overrideObject) {\n overrideProperty(baseObject, key, overrideObject[key]);\n }\n }\n};\nconst mergeConfigProperties = (baseObject, mergeObject) => {\n if (mergeObject) {\n for (const key in mergeObject) {\n const mergeValue = mergeObject[key];\n if (mergeValue !== undefined) {\n baseObject[key] = (baseObject[key] || []).concat(mergeValue);\n }\n }\n }\n};\nconst extendTailwindMerge = (configExtension, ...createConfig) => typeof configExtension === 'function' ? createTailwindMerge(getDefaultConfig, configExtension, ...createConfig) : createTailwindMerge(() => mergeConfigs(getDefaultConfig(), configExtension), ...createConfig);\nconst twMerge = /*#__PURE__*/createTailwindMerge(getDefaultConfig);\nexport { createTailwindMerge, extendTailwindMerge, fromTheme, getDefaultConfig, mergeConfigs, twJoin, twMerge, validators };\n//# sourceMappingURL=bundle-mjs.mjs.map\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","/**\n * Lightweight right-click menu. Self-contained (no Radix popper) — items are\n * built on demand by the caller and passed via `useContextMenu().open()`.\n *\n * Position-flips by measuring the rendered menu in a layout effect, so the\n * first frame is hidden until the clamp is applied. Dismisses on outside\n * click, Esc, scroll, and window blur.\n */\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { cn } from '../lib/utils';\n\nexport interface ContextMenuItem {\n type?: 'item';\n label: string;\n shortcut?: string;\n icon?: React.ComponentType<{ className?: string }>;\n onSelect: () => void;\n disabled?: boolean;\n destructive?: boolean;\n}\nexport interface ContextMenuSeparator {\n type: 'separator';\n}\nexport type ContextMenuEntry = ContextMenuItem | ContextMenuSeparator;\n\ninterface ContextMenuApi {\n open: (x: number, y: number, items: ContextMenuEntry[]) => void;\n close: () => void;\n}\n\nconst Ctx = createContext<ContextMenuApi | null>(null);\n\nexport function useContextMenu(): ContextMenuApi {\n const api = useContext(Ctx);\n if (!api) {\n throw new Error('useContextMenu must be used inside <ContextMenuHost>');\n }\n return api;\n}\n\ninterface MenuState {\n open: boolean;\n x: number;\n y: number;\n items: ContextMenuEntry[];\n}\n\nconst VIEWPORT_PAD = 8;\n\nexport function ContextMenuHost({ children }: { children: ReactNode }) {\n const [state, setState] = useState<MenuState>({\n open: false,\n x: 0,\n y: 0,\n items: [],\n });\n const [clamped, setClamped] = useState<{ left: number; top: number } | null>(\n null,\n );\n const ref = useRef<HTMLDivElement>(null);\n\n const close = useCallback(() => {\n setState((s) => (s.open ? { ...s, open: false } : s));\n }, []);\n\n const open = useCallback(\n (x: number, y: number, items: ContextMenuEntry[]) => {\n setClamped(null);\n setState({ open: true, x, y, items });\n },\n [],\n );\n\n const api = useMemo<ContextMenuApi>(() => ({ open, close }), [open, close]);\n\n useLayoutEffect(() => {\n if (!state.open || !ref.current) return;\n const r = ref.current.getBoundingClientRect();\n let left = state.x;\n let top = state.y;\n // Flip to the opposite side if the menu would overflow.\n if (left + r.width > window.innerWidth - VIEWPORT_PAD) {\n left = Math.max(VIEWPORT_PAD, state.x - r.width);\n }\n if (top + r.height > window.innerHeight - VIEWPORT_PAD) {\n top = Math.max(VIEWPORT_PAD, state.y - r.height);\n }\n setClamped({ left, top });\n }, [state]);\n\n useEffect(() => {\n if (!state.open) return;\n const onPointerDown = (e: PointerEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) close();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n };\n const onWheel = () => close();\n const onBlur = () => close();\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('keydown', onKey, true);\n window.addEventListener('wheel', onWheel, { passive: true });\n window.addEventListener('blur', onBlur);\n return () => {\n document.removeEventListener('pointerdown', onPointerDown, true);\n document.removeEventListener('keydown', onKey, true);\n window.removeEventListener('wheel', onWheel);\n window.removeEventListener('blur', onBlur);\n };\n }, [state.open, close]);\n\n return (\n <Ctx.Provider value={api}>\n {children}\n {state.open && (\n <div\n ref={ref}\n role=\"menu\"\n aria-orientation=\"vertical\"\n className=\"ole-glass fixed z-50 min-w-[200px] rounded-md border border-border p-1 text-sm shadow-md\"\n style={{\n left: clamped?.left ?? state.x,\n top: clamped?.top ?? state.y,\n visibility: clamped ? 'visible' : 'hidden',\n }}\n onContextMenu={(e) => e.preventDefault()}\n >\n {state.items.map((entry, i) => {\n if (entry.type === 'separator') {\n return (\n <div\n key={`sep-${i}`}\n role=\"separator\"\n className=\"my-1 h-px bg-border\"\n />\n );\n }\n const Icon = entry.icon;\n return (\n <button\n key={`${entry.label}-${i}`}\n type=\"button\"\n role=\"menuitem\"\n disabled={entry.disabled}\n className={cn(\n 'flex w-full items-center justify-between gap-3 rounded-sm px-2 py-1.5 text-left',\n 'hover:bg-accent hover:text-accent-foreground',\n 'focus-visible:bg-accent focus-visible:text-accent-foreground focus-visible:outline-none',\n entry.destructive &&\n 'text-destructive hover:bg-destructive/10 hover:text-destructive',\n entry.disabled &&\n 'pointer-events-none text-muted-foreground opacity-60',\n )}\n onClick={() => {\n close();\n entry.onSelect();\n }}\n >\n <span className=\"flex items-center gap-2\">\n {Icon ? <Icon className=\"size-4\" /> : null}\n <span>{entry.label}</span>\n </span>\n {entry.shortcut ? (\n <span className=\"text-xs text-muted-foreground\">\n {entry.shortcut}\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n )}\n </Ctx.Provider>\n );\n}\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n","import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n","/**\n * Flat translation table keyed by dot-namespaced ids.\n *\n * Both locales must define the same key set — TypeScript enforces this via\n * the `LocaleKey` type derived from `messages.zh`. Placeholder syntax is\n * `{name}` and is substituted by the `t()` helper.\n */\n\nexport const messages = {\n zh: {\n 'common.unnamed': '未命名',\n 'common.close': '关闭',\n 'common.yes': '是',\n 'common.no': '否',\n\n 'topbar.theme.toLight': '切换到亮色',\n 'topbar.theme.toDark': '切换到暗色',\n 'topbar.theme.currentDark': '当前:暗色主题',\n 'topbar.theme.currentLight': '当前:亮色主题',\n 'topbar.lang.toEnglish': 'Switch to English',\n 'topbar.lang.toChinese': '切换到中文',\n 'topbar.lang.currentEnglish': 'Current: English',\n 'topbar.lang.currentChinese': '当前:中文',\n\n 'topbar.export.label': '导出',\n 'topbar.export.tooltip': 'SVG 矢量(可编辑)、PNG 位图(2× 高清)或 DXF(CAD)',\n 'topbar.export.pngFailed': '导出 PNG 失败:{err}',\n 'topbar.export.dxfFailed': '导出 DXF 失败:{err}',\n\n 'topbar.file.label': '文件',\n 'topbar.file.tooltip': '打开本地 .json 图、保存、或另存为',\n 'topbar.file.current': '当前:{name}',\n 'topbar.file.new': '新建',\n 'topbar.file.open': '打开…',\n 'topbar.file.save': '保存',\n 'topbar.file.saveAs': '另存为…',\n 'topbar.file.newConfirm': '新建会清空当前未保存的内容,是否继续?',\n 'topbar.file.openFailed': '打开失败:{err}',\n 'topbar.file.saveFailed': '保存失败:{err}',\n 'topbar.file.fileDescription': 'OneLineEditor 图纸',\n\n 'outline.title': '大纲',\n 'outline.collapse': '折叠',\n 'outline.collapseAria': '折叠大纲',\n 'outline.empty': '(无设备 — 从元件库拖入开始)',\n\n 'props.title': '属性',\n 'props.node': '电气节点',\n 'props.wire': '连线',\n 'props.bus': '母线',\n 'props.nSelected': '{n} 选中',\n 'props.empty': '未选中',\n 'props.multi': '已选中 {n} 个元件',\n 'props.name': '名称',\n 'props.note': '备注',\n 'props.nodeNotFound': '电气节点 {id} 不存在',\n 'props.wireNotFound': '连线 {id} 不存在',\n 'props.nodeStats': '{terminals} 个端子 · {elements} 个元件',\n 'props.selectElement': '选中 {label}',\n 'props.selectWholeNode': '选中整个电气节点',\n\n 'view.zoomOut': '缩小',\n 'view.zoomOutHint': '按预设档位缩小;也可滚轮 ↓ 或 ⌘−',\n 'view.reset': '重置到 100%',\n 'view.current': '当前 {z}%',\n 'view.zoomIn': '放大',\n 'view.zoomInHint': '按预设档位放大;也可滚轮 ↑ 或 ⌘+',\n 'view.fit': '适配视图',\n 'view.fitHint': '自动缩放并居中所有元件',\n 'view.gridHide': '隐藏网格',\n 'view.gridShow': '显示网格',\n 'view.gridHotkey': 'G',\n 'view.gridHideHint': '同时关闭对齐吸附(拖动可自由放置)',\n 'view.gridShowHint': '同时开启对齐吸附(拖动会贴到 10px 网格)',\n 'view.gridHideAria': '隐藏网格并关闭吸附',\n 'view.gridShowAria': '显示网格并开启吸附',\n 'view.label': '标签',\n 'view.labelOff': '关闭标签',\n 'view.labelId': '仅显示 ID',\n 'view.labelAll': 'ID + 参数',\n 'view.labelHint': '点击循环切换:关闭 → 仅 ID → ID + 参数',\n\n 'library.title': '元件库',\n 'library.empty': '没有匹配的元件',\n 'library.searchPlaceholder': '搜索元件…',\n 'library.searchAria': '搜索元件',\n 'library.clearSearch': '清除搜索',\n 'library.itemHint': '单击进入放置模式或拖到画布',\n\n 'tool.select': '选择',\n 'tool.selectHint': '点选元件,框选多个,或右键打开菜单',\n 'tool.pan': '平移',\n 'tool.panHint': '拖动画布;空格键可临时切换',\n 'tool.wire': '连线',\n 'tool.wireHint': '从一个端子拖动到另一个端子完成连线',\n 'tool.bus': '母线',\n 'tool.busHint': '画布上拖动一段母线,按下定起点、释放定终点',\n 'tool.place': '元件',\n 'tool.placeHint': '点击画布放置;或从端子/母线拖出,同时放置并连接',\n 'tool.text': '文字',\n 'tool.textHint': '点击画布放置一段文字注释;双击文字可重新编辑',\n\n 'mode.selectWithSel': '拖动元件移动 · 拖端子连线 · 右键打开菜单',\n 'mode.selectEmpty': '点选元件 · 拖动移动 · 框选多个 · 右键打开菜单',\n 'mode.pan': '拖动画布 · 滚轮缩放 · 按住空格可在其他工具下临时平移',\n 'mode.wireDragging': '拖到另一个端子或母线上释放完成连线',\n 'mode.wireInit': '从端子按下,拖动到另一个端子或母线上释放',\n 'mode.busDragging': '拖动决定母线方向,释放定终点',\n 'mode.busInit': '在画布按下定起点,拖动后释放定终点',\n 'mode.placeNoKind': '从左侧元件库选择一种元件',\n 'mode.placeFromTerm': '拖到目标位置释放,新元件将连接到起点端子',\n 'mode.placeNormal': '点击空白放置;或从已有端子 / 母线拖出,同时放置并连接',\n 'mode.text': '点击画布放置文字;双击已有文字可编辑;选中后可拖动 / 删除',\n 'mode.escSelect': 'Esc 清除选择',\n 'mode.escOther': '右键 / Esc 取消',\n\n 'tool.placeNoKindTooltip': '从左侧元件库选择一个元件后点击画布放置',\n 'tool.undo': '撤销',\n 'tool.undoHint': '撤销上一次编辑(移动 / 旋转 / 删除等)',\n 'tool.redo': '重做',\n 'tool.redoHint': '重做被撤销的操作',\n\n 'layout.label': '布局',\n 'layout.hint': '自动排版整个图或仅选中范围,并填补空缺',\n 'layout.allAuto': '重新自动布局',\n 'layout.selAuto': '重新自动布局选区',\n 'layout.allFill': '填补未排版位置',\n 'layout.selFill': '填补未排版选区',\n\n 'tool.more': '更多',\n 'tool.moreHint': '撤销 / 重做 / 布局',\n 'view.menu': '视图',\n 'view.menuHint': '缩放、适配、网格',\n\n 'ctx.ariaNode': '选中节点操作',\n 'ctx.ariaWire': '选中连线操作',\n 'ctx.ariaElement': '选中元件操作',\n 'ctx.rotate': '旋转 90°',\n 'ctx.rotateHint': '顺时针旋转选中元件,连线随端子自动重排',\n 'ctx.mirror': '水平镜像',\n 'ctx.mirrorTitle': '镜像',\n 'ctx.mirrorHint': '左右翻转选中元件',\n 'ctx.delete': '删除',\n 'ctx.deleteHintNode': '断开此电气节点上的所有连接(保留元件)',\n 'ctx.deleteHintWire': '移除这一根连线(其它同节点连线保留)',\n 'ctx.deleteHintElement': '移除选中元件及其连接的连线',\n\n 'menu.undo': '撤销',\n 'menu.redo': '重做',\n 'menu.cut': '剪切',\n 'menu.copy': '复制',\n 'menu.paste': '粘贴',\n 'menu.rotate': '旋转 90°',\n 'menu.mirror': '镜像',\n 'menu.selectAll': '全选',\n 'menu.disconnect': '断开此连线',\n 'menu.delete': '删除',\n\n 'io.parseFailed': 'JSON 解析失败:{err}',\n 'io.notObject': '文件不是 JSON 对象',\n 'io.versionMismatch': '版本不兼容:期望 \"1\",实际 {actual}',\n 'io.elementsMissing': 'elements 字段缺失或不是数组',\n\n 'compile.duplicateId': '元件 ID 重复:\"{id}\"',\n 'compile.unknownKind': '未知元件类型 kind=\"{kind}\"',\n 'compile.invalidTermRef': '非法端子引用 \"{ref}\"',\n 'compile.elementMissing': '引用了不存在的元件 \"{id}\"',\n 'compile.missingPin': '元件 \"{id}\" (kind={kind}) 没有引脚 \"{pin}\",可用引脚: {available}',\n 'compile.singleTerminal': '节点只包含一个端子,已忽略',\n 'compile.layoutMissingElement': 'layout 键 \"{id}\" 引用了不存在的元件',\n 'compile.elementUnconnected': '元件 \"{id}\" 没有任何连接',\n\n 'cat.busbar': '母线 / 接线',\n 'cat.switching': '开关',\n 'cat.protection': '保护',\n 'cat.motor-control': '电机控制',\n 'cat.transformer': '变压器',\n 'cat.instrument-transformer': '互感器',\n 'cat.measurement': '测量仪表',\n 'cat.source': '电源',\n 'cat.load': '负荷',\n 'cat.storage': '储能',\n 'cat.compensation': '无功补偿',\n 'cat.grounding': '中性点接地',\n 'cat.renewable': '新能源 / 电力电子',\n\n 'onboard.title': '上手三步',\n 'onboard.step1.title': '画母线',\n 'onboard.step1.body': '选择 母线 工具(B),在画布上按下拖动',\n 'onboard.step2.title': '从母线拖出元件',\n 'onboard.step2.body': '切到 元件(P)选一种,按住母线拖到目标位置 — 自动连接',\n 'onboard.step3.title': '继续串接',\n 'onboard.step3.body': '从任意端子拖出,落到目标即与该端子相连',\n 'onboard.dismiss': '知道了',\n },\n en: {\n 'common.unnamed': 'Untitled',\n 'common.close': 'Close',\n 'common.yes': 'Yes',\n 'common.no': 'No',\n\n 'topbar.theme.toLight': 'Switch to light',\n 'topbar.theme.toDark': 'Switch to dark',\n 'topbar.theme.currentDark': 'Current: dark theme',\n 'topbar.theme.currentLight': 'Current: light theme',\n 'topbar.lang.toEnglish': 'Switch to English',\n 'topbar.lang.toChinese': '切换到中文',\n 'topbar.lang.currentEnglish': 'Current: English',\n 'topbar.lang.currentChinese': 'Current: Chinese',\n\n 'topbar.export.label': 'Export',\n 'topbar.export.tooltip': 'SVG vector (editable), PNG bitmap (2× HiDPI), or DXF (CAD)',\n 'topbar.export.pngFailed': 'PNG export failed: {err}',\n 'topbar.export.dxfFailed': 'DXF export failed: {err}',\n\n 'topbar.file.label': 'File',\n 'topbar.file.tooltip': 'Open a local .json diagram, save, or save as',\n 'topbar.file.current': 'Current: {name}',\n 'topbar.file.new': 'New',\n 'topbar.file.open': 'Open…',\n 'topbar.file.save': 'Save',\n 'topbar.file.saveAs': 'Save as…',\n 'topbar.file.newConfirm': 'New will discard any unsaved changes. Continue?',\n 'topbar.file.openFailed': 'Open failed: {err}',\n 'topbar.file.saveFailed': 'Save failed: {err}',\n 'topbar.file.fileDescription': 'OneLineEditor diagram',\n\n 'outline.title': 'Outline',\n 'outline.collapse': 'Collapse',\n 'outline.collapseAria': 'Collapse outline',\n 'outline.empty': '(No elements — drag from the library to start)',\n\n 'props.title': 'Properties',\n 'props.node': 'Electrical node',\n 'props.wire': 'Wire',\n 'props.bus': 'Bus',\n 'props.nSelected': '{n} selected',\n 'props.empty': 'Nothing selected',\n 'props.multi': '{n} elements selected',\n 'props.name': 'Name',\n 'props.note': 'Note',\n 'props.nodeNotFound': 'Electrical node {id} not found',\n 'props.wireNotFound': 'Wire {id} not found',\n 'props.nodeStats': '{terminals} terminals · {elements} elements',\n 'props.selectElement': 'Select {label}',\n 'props.selectWholeNode': 'Select whole electrical node',\n\n 'view.zoomOut': 'Zoom out',\n 'view.zoomOutHint': 'Step zoom out; also wheel ↓ or ⌘−',\n 'view.reset': 'Reset to 100%',\n 'view.current': 'Current {z}%',\n 'view.zoomIn': 'Zoom in',\n 'view.zoomInHint': 'Step zoom in; also wheel ↑ or ⌘+',\n 'view.fit': 'Fit view',\n 'view.fitHint': 'Auto-zoom and center all elements',\n 'view.gridHide': 'Hide grid',\n 'view.gridShow': 'Show grid',\n 'view.gridHotkey': 'G',\n 'view.gridHideHint': 'Also disables snap-to-grid (free placement)',\n 'view.gridShowHint': 'Also enables snap-to-grid (snaps to 10px on drag)',\n 'view.gridHideAria': 'Hide grid and disable snap',\n 'view.gridShowAria': 'Show grid and enable snap',\n 'view.label': 'Labels',\n 'view.labelOff': 'Hide labels',\n 'view.labelId': 'ID only',\n 'view.labelAll': 'ID + params',\n 'view.labelHint': 'Cycle: off → ID → ID + params',\n\n 'library.title': 'Library',\n 'library.empty': 'No matching elements',\n 'library.searchPlaceholder': 'Search elements…',\n 'library.searchAria': 'Search elements',\n 'library.clearSearch': 'Clear search',\n 'library.itemHint': 'Click to enter place mode, or drag onto the canvas',\n\n 'tool.select': 'Select',\n 'tool.selectHint': 'Click to pick, marquee for multiple, right-click for menu',\n 'tool.pan': 'Pan',\n 'tool.panHint': 'Drag the canvas; Space toggles temporarily',\n 'tool.wire': 'Wire',\n 'tool.wireHint': 'Drag from one terminal to another to wire',\n 'tool.bus': 'Busbar',\n 'tool.busHint': 'Drag on the canvas — press to set start, release to set end',\n 'tool.place': 'Place',\n 'tool.placeHint': 'Click to place; or drag from a terminal/bus to place and connect',\n 'tool.text': 'Text',\n 'tool.textHint': 'Click the canvas to drop a text note; double-click an existing one to edit',\n\n 'mode.selectWithSel': 'Drag elements · drag terminals to wire · right-click for menu',\n 'mode.selectEmpty': 'Click to pick · drag to move · marquee for multiple · right-click for menu',\n 'mode.pan': 'Drag the canvas · scroll to zoom · hold Space to pan in any tool',\n 'mode.wireDragging': 'Release on another terminal or busbar to complete the wire',\n 'mode.wireInit': 'Press on a terminal, drag to another terminal or busbar, release',\n 'mode.busDragging': 'Drag sets bus direction; release sets the end',\n 'mode.busInit': 'Press on the canvas to set start, drag, release to set end',\n 'mode.placeNoKind': 'Pick an element kind from the library on the left',\n 'mode.placeFromTerm': 'Release at the target — the new element will connect back to the source terminal',\n 'mode.placeNormal': 'Click empty space to place; or drag from a terminal / bus to place and connect',\n 'mode.text': 'Click to drop text · double-click to edit · drag selected to move · Del to remove',\n 'mode.escSelect': 'Esc clears selection',\n 'mode.escOther': 'Right-click / Esc to cancel',\n\n 'tool.placeNoKindTooltip': 'Pick a kind in the library on the left, then click the canvas',\n 'tool.undo': 'Undo',\n 'tool.undoHint': 'Undo the last edit (move / rotate / delete, etc.)',\n 'tool.redo': 'Redo',\n 'tool.redoHint': 'Redo the last undone edit',\n\n 'layout.label': 'Layout',\n 'layout.hint': 'Auto-layout the whole diagram or just the selection, fill gaps',\n 'layout.allAuto': 'Auto-layout all',\n 'layout.selAuto': 'Auto-layout selection',\n 'layout.allFill': 'Fill unplaced',\n 'layout.selFill': 'Fill unplaced in selection',\n\n 'tool.more': 'More',\n 'tool.moreHint': 'Undo / redo / layout',\n 'view.menu': 'View',\n 'view.menuHint': 'Zoom, fit, grid',\n\n 'ctx.ariaNode': 'Node actions',\n 'ctx.ariaWire': 'Wire actions',\n 'ctx.ariaElement': 'Element actions',\n 'ctx.rotate': 'Rotate 90°',\n 'ctx.rotateHint': 'Rotate selection clockwise; wires re-route through new terminals',\n 'ctx.mirror': 'Mirror horizontally',\n 'ctx.mirrorTitle': 'Mirror',\n 'ctx.mirrorHint': 'Flip selection left-right',\n 'ctx.delete': 'Delete',\n 'ctx.deleteHintNode': 'Disconnect every wire on this node (elements stay)',\n 'ctx.deleteHintWire': 'Remove only this wire (siblings on the same node stay)',\n 'ctx.deleteHintElement': 'Remove the selection and its wires',\n\n 'menu.undo': 'Undo',\n 'menu.redo': 'Redo',\n 'menu.cut': 'Cut',\n 'menu.copy': 'Copy',\n 'menu.paste': 'Paste',\n 'menu.rotate': 'Rotate 90°',\n 'menu.mirror': 'Mirror',\n 'menu.selectAll': 'Select all',\n 'menu.disconnect': 'Disconnect this wire',\n 'menu.delete': 'Delete',\n\n 'io.parseFailed': 'JSON parse failed: {err}',\n 'io.notObject': 'File is not a JSON object',\n 'io.versionMismatch': 'Version mismatch: expected \"1\", got {actual}',\n 'io.elementsMissing': '`elements` is missing or not an array',\n\n 'compile.duplicateId': 'Duplicate element id: \"{id}\"',\n 'compile.unknownKind': 'Unknown element kind=\"{kind}\"',\n 'compile.invalidTermRef': 'Invalid terminal reference \"{ref}\"',\n 'compile.elementMissing': 'Reference to unknown element \"{id}\"',\n 'compile.missingPin': 'Element \"{id}\" (kind={kind}) has no pin \"{pin}\"; available: {available}',\n 'compile.singleTerminal': 'Node has only one terminal — ignored',\n 'compile.layoutMissingElement': 'layout key \"{id}\" references an unknown element',\n 'compile.elementUnconnected': 'Element \"{id}\" has no connections',\n\n 'cat.busbar': 'Busbar / wiring',\n 'cat.switching': 'Switching',\n 'cat.protection': 'Protection',\n 'cat.motor-control': 'Motor control',\n 'cat.transformer': 'Transformer',\n 'cat.instrument-transformer': 'Instrument transformer',\n 'cat.measurement': 'Measurement',\n 'cat.source': 'Source',\n 'cat.load': 'Load',\n 'cat.storage': 'Storage',\n 'cat.compensation': 'Compensation',\n 'cat.grounding': 'Grounding',\n 'cat.renewable': 'Renewables / power electronics',\n\n 'onboard.title': 'Quick start',\n 'onboard.step1.title': 'Draw a busbar',\n 'onboard.step1.body': 'Pick the busbar tool (B), then press and drag on the canvas',\n 'onboard.step2.title': 'Drag elements from the bus',\n 'onboard.step2.body': 'Switch to Place (P), pick a kind, then drag from the bus — it auto-connects',\n 'onboard.step3.title': 'Chain the next one',\n 'onboard.step3.body': 'Drag from any terminal — the new element drops pre-connected',\n 'onboard.dismiss': 'Got it',\n },\n} as const;\n\nexport type Locale = keyof typeof messages;\nexport type LocaleKey = keyof (typeof messages)['zh'];\n","/**\n * Tiny i18n primitive — Zustand-backed locale + key-based translation.\n *\n * Mirrors `usePanels` / `useTheme` patterns: a single store, localStorage\n * persistence, and a `useT()` hook for components plus a non-hook `t()`\n * for code outside React (compiler/file-io error messages).\n *\n * Substitution: `{name}` in a template is replaced with `params[name]`.\n */\n\nimport { create } from 'zustand';\nimport { messages, type Locale, type LocaleKey } from './messages';\n\nexport type { Locale, LocaleKey };\n\nconst STORAGE_KEY = 'ole-locale';\n\nfunction readInitial(): Locale {\n if (typeof window === 'undefined') return 'zh';\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (raw === 'zh' || raw === 'en') return raw;\n } catch {\n // ignore\n }\n if (typeof navigator !== 'undefined' && typeof navigator.language === 'string') {\n return navigator.language.toLowerCase().startsWith('zh') ? 'zh' : 'en';\n }\n return 'zh';\n}\n\nfunction persist(loc: Locale): void {\n try {\n window.localStorage.setItem(STORAGE_KEY, loc);\n } catch {\n // ignore quota / disabled storage\n }\n}\n\ninterface LocaleState {\n locale: Locale;\n setLocale: (loc: Locale) => void;\n toggle: () => void;\n}\n\nexport const useLocale = create<LocaleState>((set, get) => ({\n locale: readInitial(),\n setLocale: (locale) => {\n persist(locale);\n set({ locale });\n },\n toggle: () => {\n const next = get().locale === 'zh' ? 'en' : 'zh';\n persist(next);\n set({ locale: next });\n },\n}));\n\ntype Params = Record<string, string | number>;\n\nfunction format(tmpl: string, params?: Params): string {\n if (!params) return tmpl;\n return tmpl.replace(/\\{(\\w+)\\}/g, (_, k: string) =>\n params[k] !== undefined ? String(params[k]) : `{${k}}`,\n );\n}\n\nfunction lookup(locale: Locale, key: LocaleKey): string {\n return messages[locale][key] ?? messages.zh[key] ?? key;\n}\n\n/** Translate from a non-React context. Reads the current locale from the store. */\nexport function t(key: LocaleKey, params?: Params): string {\n return format(lookup(useLocale.getState().locale, key), params);\n}\n\n/** Hook for components: returns a translator bound to the current locale. */\nexport function useT(): (key: LocaleKey, params?: Params) => string {\n const locale = useLocale((s) => s.locale);\n return (key, params) => format(lookup(locale, key), params);\n}\n","const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst shouldDispatchFromDevtools = (api) => !!api.dispatchFromDevtools && typeof api.dispatch === \"function\";\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst v8StackLineRe = /.+ (.+) .+/;\nconst geckoStackLineRe = /^([^@]+)@/;\nfunction findCallerName(stack) {\n var _a, _b, _c;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return ((_b = v8StackLineRe.exec(callerLine)) == null ? void 0 : _b[1]) || ((_c = geckoStackLineRe.exec(callerLine)) == null ? void 0 : _c[1]);\n}\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (shouldDispatchFromDevtools(api)) {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (shouldDispatchFromDevtools(api)) {\n api.dispatch(action);\n }\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => window.localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n let hydrationVersion = 0;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n const currentVersion = ++hydrationVersion;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n if (currentVersion !== hydrationVersion) {\n return;\n }\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(get(), void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n","/**\n * Runtime-only model (`InternalModel`) — what the renderer consumes. Compiled\n * from `DiagramFile`; never serialized. Indexed for O(1) per-element lookup.\n */\n\nimport type {\n Bus,\n BusId,\n Element,\n ElementId,\n LibraryEntry,\n NodeId,\n Orientation,\n Placement,\n TerminalRef,\n WireEnd,\n} from '../model';\n\n/** Element + the resolved library record for its `kind`. */\nexport interface ResolvedElement {\n element: Element;\n /** Undefined if `kind` is unknown to the library — render as placeholder. */\n libraryDef?: LibraryEntry;\n}\n\n/** Placement after defaults applied (rot=0, mirror=false). Devices only. */\nexport interface ResolvedPlacement {\n at: [number, number];\n rot: 0 | 90 | 180 | 270;\n mirror: boolean;\n}\n\n/** Bus geometry resolved at compile time. `axis` derived from `rot`. */\nexport interface BusGeometry {\n at: [number, number];\n span: number;\n rot: 0 | 90 | 180 | 270;\n axis: 'x' | 'y';\n}\n\nexport interface ResolvedBus {\n bus: Bus;\n geometry: BusGeometry;\n}\n\nexport interface TerminalGeometry {\n ref: TerminalRef;\n elementId: ElementId;\n pin: string;\n /** Canvas coordinates (after rot/mirror/translate). */\n world: [number, number];\n /** Cardinal direction the terminal exits in canvas frame. */\n orientation: Orientation;\n}\n\nexport interface ConnectivityNode {\n id: NodeId;\n /** Mixed: device terminal refs (`X.Y`) and bare bus ids (`X`). */\n terminals: WireEnd[];\n}\n\n/** Compile-time issue. Non-fatal; renderer keeps drawing. */\nexport interface Diagnostic {\n /** Stable code (`E001`..`W999`). */\n code: string;\n severity: 'error' | 'warning';\n message: string;\n /** JSON Pointer pointing into the source DiagramFile, when applicable. */\n pointer?: string;\n}\n\n/**\n * Per-wire rendered path. One polyline per visible wire in the diagram.\n * Selection / hit-test / user-route override all key on `wireId`.\n */\nexport interface WireRender {\n wireId: import('../model').WireId;\n path: [number, number][];\n /** True if this came from `Wire.path` (user-edited); false = auto-routed. */\n userEdited?: boolean;\n}\n\nexport interface InternalModel {\n elements: Map<ElementId, ResolvedElement>;\n buses: Map<BusId, ResolvedBus>;\n terminals: Map<TerminalRef, TerminalGeometry>;\n nodes: Map<NodeId, ConnectivityNode>;\n layout: Map<ElementId, ResolvedPlacement>;\n /** Rendered polyline per wire id. */\n wireRenders: Map<import('../model').WireId, WireRender>;\n terminalToNode: Map<WireEnd, NodeId>;\n elementToTerminals: Map<ElementId, TerminalRef[]>;\n diagnostics: Diagnostic[];\n}\n\nexport function emptyInternalModel(): InternalModel {\n return {\n elements: new Map(),\n buses: new Map(),\n terminals: new Map(),\n nodes: new Map(),\n layout: new Map(),\n wireRenders: new Map(),\n terminalToNode: new Map(),\n elementToTerminals: new Map(),\n diagnostics: [],\n };\n}\n\nexport function resolvePlacement(p?: Placement): ResolvedPlacement {\n return {\n at: p?.at ?? [0, 0],\n rot: p?.rot ?? 0,\n mirror: p?.mirror ?? false,\n };\n}\n\nexport function busAxisFromRot(rot: 0 | 90 | 180 | 270): 'x' | 'y' {\n return rot === 90 || rot === 270 ? 'y' : 'x';\n}\n","/**\n * Geometric transforms for placing library-local coordinates onto the canvas.\n * Order applied to a local point: mirror (about y-axis) → rotate → translate.\n * The same convention drives ElementLayer's SVG `transform` attribute, so\n * SVG output and computed terminal coords stay in sync.\n */\n\nimport type { Orientation } from '../model';\nimport type { ResolvedPlacement } from './internal-model';\n\nexport function transformPoint(\n local: [number, number],\n p: ResolvedPlacement,\n): [number, number] {\n let [x, y] = local;\n if (p.mirror) x = -x;\n switch (p.rot) {\n case 0:\n break;\n case 90:\n [x, y] = [-y, x];\n break;\n case 180:\n [x, y] = [-x, -y];\n break;\n case 270:\n [x, y] = [y, -x];\n break;\n }\n return [x + p.at[0], y + p.at[1]];\n}\n\nconst ROT_NEXT: Record<Orientation, Orientation> = {\n n: 'e',\n e: 's',\n s: 'w',\n w: 'n',\n};\n\nconst MIRROR_X: Record<Orientation, Orientation> = {\n n: 'n',\n s: 's',\n e: 'w',\n w: 'e',\n};\n\nexport function transformOrientation(\n o: Orientation,\n p: ResolvedPlacement,\n): Orientation {\n let cur: Orientation = p.mirror ? MIRROR_X[o] : o;\n const steps = (p.rot / 90) | 0;\n for (let i = 0; i < steps; i++) cur = ROT_NEXT[cur];\n return cur;\n}\n\n/** Unit vector pointing the way an exit-line should leave a terminal. */\nexport function orientationVec(o: Orientation): [number, number] {\n switch (o) {\n case 'n':\n return [0, -1];\n case 's':\n return [0, 1];\n case 'e':\n return [1, 0];\n case 'w':\n return [-1, 0];\n }\n}\n","/**\n * Tiny Union-Find (disjoint set) keyed by string. Used to merge `connections`\n * into ConnectivityNode equivalence classes.\n */\nexport class UnionFind<K> {\n private parent = new Map<K, K>();\n private rank = new Map<K, number>();\n\n add(k: K): void {\n if (!this.parent.has(k)) {\n this.parent.set(k, k);\n this.rank.set(k, 0);\n }\n }\n\n find(k: K): K {\n this.add(k);\n let cur = k;\n while (this.parent.get(cur) !== cur) {\n const p = this.parent.get(cur)!;\n const gp = this.parent.get(p)!;\n this.parent.set(cur, gp);\n cur = gp;\n }\n return cur;\n }\n\n union(a: K, b: K): void {\n const ra = this.find(a);\n const rb = this.find(b);\n if (ra === rb) return;\n const da = this.rank.get(ra)!;\n const db = this.rank.get(rb)!;\n if (da < db) this.parent.set(ra, rb);\n else if (da > db) this.parent.set(rb, ra);\n else {\n this.parent.set(rb, ra);\n this.rank.set(ra, da + 1);\n }\n }\n\n /** Group all known keys by their representative. Insertion order preserved. */\n groups(): Map<K, K[]> {\n const out = new Map<K, K[]>();\n for (const k of this.parent.keys()) {\n const root = this.find(k);\n const arr = out.get(root);\n if (arr) arr.push(k);\n else out.set(root, [k]);\n }\n return out;\n }\n}\n","/**\n * Best-effort placement for elements lacking a `Placement` in the diagram.\n *\n * Strategy (hierarchy-aware):\n * 1. Identify \"linkers\" — elements connecting ≥2 distinct buses. Three\n * passes: (a) direct bus tap (the element is an electrical-node co-\n * member of ≥2 buses); (b) transitive BFS for category='transformer'\n * elements wired through chains of switches — the BFS finds *all*\n * reachable buses, so a transformer feeding two parallel HV bars\n * (BI + BII via a Y of disconnectors) registers as a 3-bus linker;\n * (c) breakers that bridge two buses through chains with no\n * transformer in path are flagged as horizontal linkers (bus\n * ties / couplers).\n * 2. Tier assignment via BFS from source-tapped buses. Vertical linkers\n * (transformers) step a level; horizontal linkers (bus ties) keep\n * the level unchanged so same-voltage buses share a Y. Disconnected\n * buses fall into an orphan tier at the bottom.\n * 3. Bottom-up bus span propagation. Each bus's span = max(BUS_MIN_SPAN,\n * total slot width + edge margin). Tap slots that stand in for a\n * downstream bus (vertical linker chain head, or the linker itself\n * for direct-tap) claim the child bus's span + spacing.\n * 4. Tier-walking placement: at each level pick the Y from previous\n * level + max parent-child gap; pick each bus's X (root → default\n * or sibling-spread; non-root → midpoint of all parent linkers'\n * chain-head X, so a 3-bus child naturally lands between its\n * upstream parents); distribute the bus's taps with slot ordering\n * biased by `tapPreferredX`; place vertical linkers (anchored to\n * the upper-side chain heads' midpoint, with Y-junction chain\n * alignment so the chain between merge node and linker sits cleanly\n * on the linker's column); place horizontal linkers (rotated\n * 90°/270° between the two same-level buses).\n * 5. Resolve electrical nodes via union-find. For each node with placed\n * and unplaced members, vote on an anchor (placed pin most directly\n * co-referenced) and lay out the remaining elements as parallel\n * branches perpendicular to the anchor's exit. Iterate to a fixpoint\n * so multi-step chains terminate on a real anchor instead of being\n * routed back across a bus.\n * 6. Anything still unplaced falls back to a grid in the lower-right.\n *\n * All resolved positions are snapped to a 10px grid so subsequent user\n * drags don't introduce sub-grid jitter.\n */\n\nimport type {\n Bus,\n BusId,\n Element,\n ElementId,\n LibraryEntry,\n Orientation,\n TerminalRef,\n Wire,\n WireEnd,\n} from '../model';\nimport {\n busAxisFromRot,\n type BusGeometry,\n type ResolvedPlacement,\n} from './internal-model';\nimport { orientationVec, transformOrientation, transformPoint } from './transforms';\nimport { UnionFind } from './union-find';\n\nconst ORIENT_CYCLE: readonly Orientation[] = ['n', 'e', 's', 'w'];\nconst OPPOSITE_ORIENT: Record<Orientation, Orientation> = {\n n: 's',\n s: 'n',\n e: 'w',\n w: 'e',\n};\n\nfunction rotationToAlignOrient(\n localO: Orientation,\n worldO: Orientation,\n): 0 | 90 | 180 | 270 {\n const li = ORIENT_CYCLE.indexOf(localO);\n const wi = ORIENT_CYCLE.indexOf(worldO);\n const steps = ((wi - li) % 4 + 4) % 4;\n return [0, 90, 180, 270][steps] as 0 | 90 | 180 | 270;\n}\n\ninterface AutoLayoutInput {\n /** Devices only. Buses are in `buses`. */\n elements: Element[];\n buses: Bus[];\n wires: Wire[];\n library: ReadonlyMap<string, LibraryEntry>;\n userLayout: ReadonlyMap<ElementId, ResolvedPlacement>;\n userBusLayout: ReadonlyMap<BusId, BusGeometry>;\n}\n\nexport interface AutoLayoutOutput {\n devices: Map<ElementId, ResolvedPlacement>;\n buses: Map<BusId, BusGeometry>;\n}\n\nconst BUS_X = 320;\nconst BUS_Y0 = 220;\nconst MIN_BUS_GAP_Y = 260;\nconst DEFAULT_BUS_SPAN = 720;\nconst CHAIN_GAP = 30;\n// Distance from a bus line to the first chain element's pin.\nconst BUS_TAP_OFFSET = 30;\nconst MIN_TAP_SPACING = 80;\nconst GRID = 10;\nconst FALLBACK_GRID_X0 = 60;\nconst FALLBACK_GRID_Y0 = 520;\nconst FALLBACK_GRID_DX = 80;\nconst FALLBACK_GRID_DY = 80;\nconst FALLBACK_GRID_COLS = 8;\n\nconst SOURCE_CATEGORIES = new Set(['source', 'renewable']);\n\ninterface BusAttachment {\n busId: BusId;\n pin: string;\n}\n\ninterface LinkerInfo {\n elementId: ElementId;\n attachments: BusAttachment[];\n orientation: 'vertical' | 'horizontal';\n}\n\nexport function autoLayout(input: AutoLayoutInput): AutoLayoutOutput {\n const { elements, buses: busList, wires, library, userLayout, userBusLayout } = input;\n\n const layout = new Map<ElementId, ResolvedPlacement>(userLayout);\n const busLayout = new Map<BusId, BusGeometry>(userBusLayout);\n\n const elementById = new Map<ElementId, Element>();\n for (const el of elements) elementById.set(el.id, el);\n const busById = new Map<BusId, Bus>();\n for (const b of busList) busById.set(b.id, b);\n\n const libOf = (id: ElementId): LibraryEntry | undefined => {\n const el = elementById.get(id);\n if (!el) return undefined;\n return library.get(el.kind);\n };\n\n const busIds = new Set<BusId>(busList.map((b) => b.id));\n const isBus = (end: WireEnd): boolean => busIds.has(end);\n\n // ---- 0. Union-find on wires → electrical nodes ------------------------\n // Members of a node are a mix of `TerminalRef` (\"X.Y\", device pins) and\n // bare bus ids (\"X\", hyperedge nodes).\n const uf = new UnionFind<WireEnd>();\n for (const w of wires) {\n uf.add(w.ends[0]);\n uf.add(w.ends[1]);\n uf.union(w.ends[0], w.ends[1]);\n }\n for (const el of elements) {\n const lib = library.get(el.kind);\n if (!lib) continue;\n for (const t of lib.terminals) uf.add(`${el.id}.${t.id}` as TerminalRef);\n }\n for (const bus of busList) uf.add(bus.id);\n\n const nodeGroups: WireEnd[][] = [];\n for (const [, members] of uf.groups()) {\n if (members.length >= 2) nodeGroups.push(members);\n }\n\n // For each end, the single node it belongs to (wrapped in the outer\n // array so iteration shape matches the legacy `[][]` form). `g.length\n // >= 3` then means \"merge node\" exactly as before.\n const pinToGroups = new Map<WireEnd, WireEnd[][]>();\n for (const group of nodeGroups) {\n for (const m of group) pinToGroups.set(m, [group]);\n }\n\n // Per-bus tap list: for each bus, the other members of its electrical\n // node. Picked up by stage 1 (linker detection), stage 4 (root buses),\n // and the bus-span / tap-distribution passes.\n const effectiveTaps = new Map<BusId, WireEnd[]>();\n for (const group of nodeGroups) {\n const busMembers = group.filter(isBus);\n if (busMembers.length === 0) continue;\n for (const busMember of busMembers) {\n const others = group.filter((m) => m !== busMember);\n const arr = effectiveTaps.get(busMember) ?? [];\n arr.push(...others);\n effectiveTaps.set(busMember, arr);\n }\n }\n\n // ---- 1. Detect linker elements (in node-co-membership with ≥2 buses) ---\n const tapsByElement = new Map<ElementId, BusAttachment[]>();\n for (const group of nodeGroups) {\n const busMembers = group.filter(isBus);\n if (busMembers.length === 0) continue;\n for (const end of group) {\n if (isBus(end)) continue;\n const dot = end.indexOf('.');\n if (dot < 0) continue;\n const elId = end.slice(0, dot);\n const pin = end.slice(dot + 1);\n const arr = tapsByElement.get(elId) ?? [];\n for (const busId of busMembers) {\n if (!arr.some((a) => a.busId === busId && a.pin === pin)) {\n arr.push({ busId, pin });\n }\n }\n tapsByElement.set(elId, arr);\n }\n }\n const linkers: LinkerInfo[] = [];\n // `linkerIds` holds only vertical linkers — those with explicit cross-tier\n // placement in stage 5. Horizontal linkers (bus ties) flow through stage\n // 4/6 like any chain element and stay out of this set so stage 6 picks\n // them up as regular branches.\n const linkerIds = new Set<ElementId>();\n for (const [elId, attachments] of tapsByElement) {\n const distinctBuses = new Set(attachments.map((a) => a.busId));\n if (distinctBuses.size >= 2) {\n const orientation: 'vertical' | 'horizontal' =\n library.get(elementById.get(elId)?.kind ?? '')?.category === 'transformer'\n ? 'vertical'\n : 'horizontal';\n linkers.push({ elementId: elId, attachments, orientation });\n if (orientation === 'vertical') linkerIds.add(elId);\n }\n }\n\n // ---- 1b. Transitive linker detection for transformer-family elements ---\n // The direct check above only catches elements *directly* sharing a node\n // with two buses. Most fixtures actually wire transformers through a\n // chain of switches/breakers (T1.t1 → QF → QS → B1), so T1 looks like a\n // single-bus device. We rebuild a per-end connection graph and BFS from\n // each terminal of a candidate transformer, checking reachability to ≥2\n // buses.\n const refAdj = new Map<WireEnd, Set<WireEnd>>();\n const addRefEdge = (a: WireEnd, b: WireEnd) => {\n if (a === b) return;\n if (!refAdj.has(a)) refAdj.set(a, new Set());\n if (!refAdj.has(b)) refAdj.set(b, new Set());\n refAdj.get(a)!.add(b);\n refAdj.get(b)!.add(a);\n };\n for (const w of wires) {\n addRefEdge(w.ends[0], w.ends[1]);\n }\n // Treat each device as a passthrough between its terminals so BFS can\n // walk QF.t1 → QF.t2 (different wires but same physical device) on its\n // way to the next bus.\n for (const el of elements) {\n const lib = library.get(el.kind);\n if (!lib || lib.terminals.length < 2) continue;\n const refs = lib.terminals.map(\n (t) => `${el.id}.${t.id}` as TerminalRef,\n );\n for (let i = 0; i < refs.length; i++) {\n for (let j = i + 1; j < refs.length; j++) {\n addRefEdge(refs[i], refs[j]);\n }\n }\n }\n\n for (const el of elements) {\n if (linkerIds.has(el.id)) continue;\n const lib = library.get(el.kind);\n if (!lib || lib.category !== 'transformer') continue;\n if (lib.terminals.length < 2) continue;\n\n const myRefs = lib.terminals.map(\n (t) => `${el.id}.${t.id}` as TerminalRef,\n );\n // pin -> ALL reachable buses (not just first). Crucial for 3-bus\n // configurations like a transformer whose HV side reaches two parallel\n // 220 kV bars (BI + BII) through a Y of disconnectors.\n const busesPerPin = new Map<string, Set<BusId>>();\n for (const startRef of myRefs) {\n const startPin = startRef.slice(el.id.length + 1);\n busesPerPin.set(startPin, new Set());\n const forbidden = new Set<WireEnd>(myRefs.filter((r) => r !== startRef));\n const visited = new Set<WireEnd>([startRef]);\n const queue: WireEnd[] = [startRef];\n while (queue.length > 0) {\n const cur = queue.shift()!;\n if (isBus(cur)) {\n busesPerPin.get(startPin)!.add(cur);\n // Don't expand bus further — every bus reachable, not other taps.\n continue;\n }\n const neighbors = refAdj.get(cur);\n if (!neighbors) continue;\n for (const nb of neighbors) {\n if (visited.has(nb) || forbidden.has(nb)) continue;\n visited.add(nb);\n queue.push(nb);\n }\n }\n }\n const distinctBuses = new Set<BusId>();\n for (const buses of busesPerPin.values()) {\n for (const b of buses) distinctBuses.add(b);\n }\n if (distinctBuses.size >= 2) {\n const attachments: BusAttachment[] = [];\n for (const [pin, buses] of busesPerPin) {\n for (const busId of buses) attachments.push({ busId, pin });\n }\n linkers.push({ elementId: el.id, attachments, orientation: 'vertical' });\n linkerIds.add(el.id);\n }\n }\n\n // ---- 1b'. Reclassify direct-tap horizontal linkers as vertical --------\n // Stage 1 defaults non-transformer direct-tap linkers to 'horizontal',\n // which suits a true bus tie between same-voltage bars. But the same\n // structure appears in the common main-panel-feeding-subpanel case (a\n // breaker directly tapped to both the main bus and the subpanel bus),\n // where the relationship is hierarchical, not lateral.\n //\n // Heuristic: if exactly one of the linker's buses can reach a source\n // element WITHOUT traversing this linker, the linker is a feeder\n // (vertical) — the stranded bus is downstream. If both sides are\n // independently sourced, it's a real bus tie and stays horizontal.\n const reachesSourceBypassing = (\n startBusId: BusId,\n linkerId: ElementId,\n ): boolean => {\n const linkerLib = libOf(linkerId);\n const blocked: WireEnd[] = linkerLib\n ? linkerLib.terminals.map((t) => `${linkerId}.${t.id}` as TerminalRef)\n : [];\n const startRef = startBusId as WireEnd;\n const visited = new Set<WireEnd>([startRef, ...blocked]);\n const queue: WireEnd[] = [startRef];\n while (queue.length > 0) {\n const cur = queue.shift()!;\n const dot = cur.indexOf('.');\n if (dot > 0) {\n const elemId = cur.slice(0, dot);\n const el = elementById.get(elemId);\n if (el) {\n const cat = library.get(el.kind)?.category;\n if (cat && SOURCE_CATEGORIES.has(cat)) return true;\n }\n }\n const neighbors = refAdj.get(cur);\n if (!neighbors) continue;\n for (const nb of neighbors) {\n if (visited.has(nb)) continue;\n visited.add(nb);\n queue.push(nb);\n }\n }\n return false;\n };\n\n for (const link of linkers) {\n if (link.orientation !== 'horizontal') continue;\n const busesInLink = new Set(link.attachments.map((a) => a.busId));\n let reachable = 0;\n for (const bid of busesInLink) {\n if (reachesSourceBypassing(bid, link.elementId)) reachable++;\n }\n if (reachable === 1) {\n link.orientation = 'vertical';\n linkerIds.add(link.elementId);\n }\n }\n\n // ---- 1c. Transitive horizontal-linker detection (bus-tie breakers) -----\n // A breaker bridging two buses through chains on each side — without a\n // transformer in either chain — is a bus tie / bus coupler. Detection is\n // restricted to kind='breaker' to avoid flooding the linker set with every\n // disconnector in a chain.\n for (const el of elements) {\n if (linkerIds.has(el.id)) continue;\n if (el.kind !== 'breaker') continue;\n const lib = library.get(el.kind);\n if (!lib || lib.terminals.length !== 2) continue;\n\n const myRefs = lib.terminals.map(\n (t) => `${el.id}.${t.id}` as TerminalRef,\n );\n const busPerPin = new Map<string, BusId>();\n\n for (const startRef of myRefs) {\n const startPin = startRef.slice(el.id.length + 1);\n const forbidden = new Set<WireEnd>(myRefs.filter((r) => r !== startRef));\n const visited = new Set<WireEnd>([startRef]);\n const queue: WireEnd[] = [startRef];\n while (queue.length > 0) {\n const cur = queue.shift()!;\n if (isBus(cur)) {\n busPerPin.set(startPin, cur);\n break;\n }\n const neighbors = refAdj.get(cur);\n if (!neighbors) continue;\n for (const nb of neighbors) {\n if (visited.has(nb) || forbidden.has(nb)) continue;\n // Block passthrough through transformers — transformer paths are\n // vertical linkers and don't make this candidate a bus tie.\n const nbDot = nb.indexOf('.');\n if (nbDot > 0) {\n const nbElemId = nb.slice(0, nbDot);\n if (nbElemId !== el.id) {\n const nbEl = elementById.get(nbElemId);\n const nbLib = nbEl ? library.get(nbEl.kind) : undefined;\n if (nbLib?.category === 'transformer') continue;\n }\n }\n visited.add(nb);\n queue.push(nb);\n }\n }\n }\n const distinctBuses = new Set(busPerPin.values());\n if (distinctBuses.size >= 2) {\n const attachments: BusAttachment[] = [];\n for (const [pin, busId] of busPerPin) {\n attachments.push({ busId, pin });\n }\n linkers.push({\n elementId: el.id,\n attachments,\n orientation: 'horizontal',\n });\n // Don't add to linkerIds — horizontal linkers don't have explicit\n // placement; they go through stage 4/6 as ordinary chain elements.\n }\n }\n\n // ---- 2. Topo-order buses ----------------------------------------------\n const busLinks = new Map<BusId, Map<BusId, LinkerInfo>>();\n for (const b of busList) busLinks.set(b.id, new Map());\n for (const link of linkers) {\n const ids = Array.from(new Set(link.attachments.map((a) => a.busId)));\n for (const a of ids) {\n for (const b of ids) {\n if (a !== b) busLinks.get(a)?.set(b, link);\n }\n }\n }\n\n const isSourceKind = (kind: string): boolean => {\n const cat = library.get(kind)?.category;\n return cat ? SOURCE_CATEGORIES.has(cat) : false;\n };\n\n const rootBuses: BusId[] = [];\n for (const bus of busList) {\n const refs = effectiveTaps.get(bus.id);\n if (!refs) continue;\n for (const ref of refs) {\n if (isBus(ref)) continue;\n const dot = ref.indexOf('.');\n if (dot < 0) continue;\n const otherId = ref.slice(0, dot);\n const otherEl = elementById.get(otherId);\n if (otherEl && isSourceKind(otherEl.kind)) {\n rootBuses.push(bus.id);\n break;\n }\n }\n }\n if (rootBuses.length === 0 && busList.length > 0) rootBuses.push(busList[0].id);\n\n const busLevel = new Map<BusId, number>();\n for (const r of rootBuses) busLevel.set(r, 0);\n {\n const bfsQ: BusId[] = [...rootBuses];\n while (bfsQ.length > 0) {\n const id = bfsQ.shift()!;\n const lvl = busLevel.get(id)!;\n const links = busLinks.get(id);\n if (!links) continue;\n for (const [otherId, link] of links) {\n if (busLevel.has(otherId)) continue;\n const childLevel =\n link.orientation === 'horizontal' ? lvl : lvl + 1;\n busLevel.set(otherId, childLevel);\n bfsQ.push(otherId);\n }\n }\n }\n for (const bus of busList) {\n if (busLevel.has(bus.id)) continue;\n const maxLvl = busLevel.size === 0\n ? -1\n : Math.max(...Array.from(busLevel.values()));\n busLevel.set(bus.id, maxLvl + 1);\n }\n const levelToBuses = new Map<number, BusId[]>();\n for (const bus of busList) {\n const lvl = busLevel.get(bus.id)!;\n const arr = levelToBuses.get(lvl) ?? [];\n arr.push(bus.id);\n levelToBuses.set(lvl, arr);\n }\n const sortedLevels = [...levelToBuses.keys()].sort((a, b) => a - b);\n\n // ---- 3. Chain-extent helper -------------------------------------------\n interface ChainResult {\n extent: number;\n /** The chain element directly tapped to the bus (for X-alignment). */\n head?: ElementId;\n }\n const chainExtentToBus = (\n linker: LinkerInfo,\n busId: BusId,\n pinName: string,\n ): ChainResult => {\n const startRef = `${linker.elementId}.${pinName}` as TerminalRef;\n const targetRef = busId as WireEnd;\n const linkerLib = libOf(linker.elementId);\n const forbidden = new Set<WireEnd>();\n if (linkerLib) {\n for (const t of linkerLib.terminals) {\n if (t.id === pinName) continue;\n forbidden.add(`${linker.elementId}.${t.id}` as TerminalRef);\n }\n }\n const visited = new Set<WireEnd>([startRef]);\n const queue: { ref: WireEnd; dist: number }[] = [\n { ref: startRef, dist: 0 },\n ];\n const parent = new Map<WireEnd, WireEnd>();\n const enqueue = (other: WireEnd, ref: WireEnd, addDist: number, dist: number) => {\n visited.add(other);\n parent.set(other, ref);\n queue.push({ ref: other, dist: dist + addDist });\n };\n while (queue.length > 0) {\n const { ref, dist } = queue.shift()!;\n if (ref === targetRef) {\n const prev = parent.get(targetRef);\n let head: ElementId | undefined;\n if (prev) {\n const d = prev.indexOf('.');\n if (d > 0) {\n const headId = prev.slice(0, d);\n // Direct-tap linker: skip self-as-head so callers fall through\n // to the slot-based fallback (linkerSlotX).\n if (headId !== linker.elementId) head = headId;\n }\n }\n return { extent: dist, head };\n }\n const dot = ref.indexOf('.');\n if (dot < 0) {\n // Bare bus id reached (not the target): don't expand through it.\n continue;\n }\n const elId = ref.slice(0, dot);\n const pin = ref.slice(dot + 1);\n // Passthrough through a non-bus, non-linker element: enqueue its other\n // terminals with the local pin-to-pin distance added.\n if (!isBus(elId) && !linkerIds.has(elId)) {\n const lib = libOf(elId);\n const thisTerm = lib?.terminals.find((t) => t.id === pin);\n if (lib && thisTerm) {\n for (const otherTerm of lib.terminals) {\n if (otherTerm.id === pin) continue;\n const otherRef = `${elId}.${otherTerm.id}` as TerminalRef;\n if (visited.has(otherRef) || forbidden.has(otherRef)) continue;\n enqueue(otherRef, ref, Math.abs(thisTerm.y - otherTerm.y), dist);\n }\n }\n }\n // Cross to other ends via electrical-node membership. Edges incident\n // to a bus end contribute BUS_TAP_OFFSET (the wire stub between bus\n // line and the tap pin); inter-element edges contribute CHAIN_GAP.\n for (const g of pinToGroups.get(ref) ?? []) {\n for (const other of g) {\n if (other === ref) continue;\n if (visited.has(other) || forbidden.has(other)) continue;\n const isBusEdge = isBus(ref) || isBus(other);\n enqueue(other, ref, isBusEdge ? BUS_TAP_OFFSET : CHAIN_GAP, dist);\n }\n }\n }\n return { extent: 0 };\n };\n\n const gapBetween = (idA: BusId, idB: BusId): number => {\n const link = busLinks.get(idA)?.get(idB);\n if (!link || link.orientation === 'horizontal') return MIN_BUS_GAP_Y;\n const linkerLib = libOf(link.elementId);\n if (!linkerLib) return MIN_BUS_GAP_Y;\n const pinAName = link.attachments.find((a) => a.busId === idA)?.pin;\n const pinBName = link.attachments.find((a) => a.busId === idB)?.pin;\n if (!pinAName || !pinBName) return MIN_BUS_GAP_Y;\n const pinA = linkerLib.terminals.find((t) => t.id === pinAName);\n const pinB = linkerLib.terminals.find((t) => t.id === pinBName);\n if (!pinA || !pinB) return MIN_BUS_GAP_Y;\n const pinSpan = Math.abs(pinB.y - pinA.y);\n const upperChain = chainExtentToBus(link, idA, pinAName).extent;\n const lowerChain = chainExtentToBus(link, idB, pinBName).extent;\n return upperChain + pinSpan + lowerChain;\n };\n\n // ---- Linker → upper-bus tap representative ----------------------------\n interface LinkerRep {\n lowerBusId: BusId;\n }\n const linkerUpperRep = new Map<ElementId, LinkerRep>();\n for (const link of linkers) {\n if (link.orientation !== 'vertical') continue;\n const sortedAttachments = link.attachments\n .slice()\n .sort(\n (a, b) => (busLevel.get(a.busId) ?? 0) - (busLevel.get(b.busId) ?? 0),\n );\n if (sortedAttachments.length < 2) continue;\n const upperBusId = sortedAttachments[0].busId;\n const lowerBusId = sortedAttachments[1].busId;\n const upperPin = sortedAttachments[0].pin;\n const result = chainExtentToBus(link, upperBusId, upperPin);\n const repElId = result.head ?? link.elementId;\n linkerUpperRep.set(repElId, { lowerBusId });\n }\n\n // ---- Bottom-up bus span computation -----------------------------------\n const BUS_MIN_SPAN = 320;\n const busSpan = new Map<BusId, number>();\n const isLinkerLowerSide = (\n elId: ElementId,\n busId: BusId,\n ): boolean => {\n if (!linkerIds.has(elId)) return false;\n const link = linkers.find((l) => l.elementId === elId);\n const otherBusAtt = link?.attachments.find((a) => a.busId !== busId);\n if (!otherBusAtt) return false;\n const myLvl = busLevel.get(busId) ?? 0;\n const otherLvl = busLevel.get(otherBusAtt.busId) ?? 0;\n return otherLvl < myLvl;\n };\n const slotWidthFor = (\n elId: ElementId,\n libWidth: number,\n ): number => {\n const rep = linkerUpperRep.get(elId);\n if (rep) {\n const childSpan = busSpan.get(rep.lowerBusId);\n if (childSpan !== undefined) {\n return Math.max(libWidth, childSpan + MIN_TAP_SPACING);\n }\n }\n return Math.max(libWidth, MIN_TAP_SPACING);\n };\n const computeSpan = (busId: BusId, visiting: Set<BusId>): number => {\n if (busSpan.has(busId)) return busSpan.get(busId)!;\n if (visiting.has(busId)) return BUS_MIN_SPAN; // cycle guard\n visiting.add(busId);\n const tapRefs = effectiveTaps.get(busId) ?? [];\n let aboveW = 0;\n let belowW = 0;\n for (const ref of tapRefs) {\n if (isBus(ref)) continue;\n const dot = ref.indexOf('.');\n if (dot < 0) continue;\n const elId = ref.slice(0, dot);\n const pin = ref.slice(dot + 1);\n if (isLinkerLowerSide(elId, busId)) continue;\n const lib = libOf(elId);\n if (!lib) continue;\n const localTerm = lib.terminals.find((t) => t.id === pin);\n if (!localTerm) continue;\n const rep = linkerUpperRep.get(elId);\n if (rep) {\n computeSpan(rep.lowerBusId, visiting);\n }\n const slotW = slotWidthFor(elId, lib.width);\n if (localTerm.y > 0) aboveW += slotW;\n else belowW += slotW;\n }\n const span = Math.max(\n BUS_MIN_SPAN,\n Math.max(aboveW, belowW) + MIN_TAP_SPACING,\n );\n busSpan.set(busId, span);\n visiting.delete(busId);\n return span;\n };\n for (const bus of busList) computeSpan(bus.id, new Set());\n\n // ---- 3-5. Tier-based bus / tap / linker placement ---------------------\n const linkerSlotX = new Map<ElementId, number>();\n\n interface TapEntry {\n elId: ElementId;\n lib: LibraryEntry;\n localTerm: { id: string; x: number; y: number; orientation: Orientation };\n isLinker: boolean;\n }\n\n // Find the X of the closest other-bus that this tap reaches via the\n // electrical-node graph. Returned only if that bus has already been\n // placed.\n const tapPreferredX = (\n busId: BusId,\n tapEl: ElementId,\n tapPin: string,\n ): number | undefined => {\n const tapLib = libOf(tapEl);\n if (!tapLib) return undefined;\n const tapRef = `${tapEl}.${tapPin}` as TerminalRef;\n const startRefs = tapLib.terminals\n .filter((t) => t.id !== tapPin)\n .map((t) => `${tapEl}.${t.id}` as TerminalRef);\n if (startRefs.length === 0) return undefined;\n const visited = new Set<WireEnd>([tapRef, ...startRefs]);\n const queue: WireEnd[] = startRefs.slice();\n while (queue.length > 0) {\n const cur = queue.shift()!;\n if (isBus(cur) && cur !== busId) {\n const geom = busLayout.get(cur);\n return geom ? geom.at[0] : undefined;\n }\n for (const g of pinToGroups.get(cur) ?? []) {\n for (const other of g) {\n if (other === cur || visited.has(other)) continue;\n visited.add(other);\n queue.push(other);\n }\n }\n const dot = cur.indexOf('.');\n if (dot > 0) {\n const elemId = cur.slice(0, dot);\n if (!isBus(elemId)) {\n const lib = libOf(elemId);\n if (lib) {\n for (const t of lib.terminals) {\n const otherRef = `${elemId}.${t.id}` as TerminalRef;\n if (visited.has(otherRef)) continue;\n visited.add(otherRef);\n queue.push(otherRef);\n }\n }\n }\n }\n }\n return undefined;\n };\n\n const distributeBusTaps = (busId: BusId): void => {\n const tapRefs = effectiveTaps.get(busId);\n if (!tapRefs || tapRefs.length === 0) return;\n const geom = busLayout.get(busId);\n if (!geom) return;\n\n const remaining: TapEntry[] = tapRefs.flatMap((ref): TapEntry[] => {\n if (isBus(ref)) return [];\n const dot = ref.indexOf('.');\n if (dot < 0) return [];\n const elId = ref.slice(0, dot);\n const pin = ref.slice(dot + 1);\n if (layout.has(elId)) return [];\n if (isLinkerLowerSide(elId, busId)) return [];\n const lib = libOf(elId);\n if (!lib) return [];\n const localTerm = lib.terminals.find((t) => t.id === pin);\n if (!localTerm) return [];\n return [{ elId, lib, localTerm, isLinker: linkerIds.has(elId) }];\n });\n if (remaining.length === 0) return;\n\n const aboveSide: TapEntry[] = [];\n const belowSide: TapEntry[] = [];\n for (const r of remaining) {\n if (r.localTerm.y > 0) aboveSide.push(r);\n else belowSide.push(r);\n }\n\n const sideTotalWidth = (group: TapEntry[]): number =>\n group.reduce((s, r) => s + slotWidthFor(r.elId, r.lib.width), 0);\n const requiredSpan =\n Math.max(sideTotalWidth(aboveSide), sideTotalWidth(belowSide)) +\n MIN_TAP_SPACING;\n const span = Math.max(geom.span, requiredSpan);\n if (span !== geom.span) {\n busLayout.set(busId, { ...geom, span });\n }\n const finalGeom = busLayout.get(busId)!;\n\n const distribute = (group: TapEntry[], offsetSign: -1 | 1): void => {\n if (group.length === 0) return;\n const prefByEl = new Map<ElementId, number>();\n for (const r of group) {\n const px = tapPreferredX(busId, r.elId, r.localTerm.id);\n if (px !== undefined) prefByEl.set(r.elId, px);\n }\n group.sort((a, b) => {\n const ax = prefByEl.get(a.elId) ?? finalGeom.at[0];\n const bx = prefByEl.get(b.elId) ?? finalGeom.at[0];\n if (ax !== bx) return ax - bx;\n // Same-preference taps: wider slots toward bus center, narrow ones\n // pushed to the extreme. Lets a small bus-tie disconnector land on\n // the actual edge even when a wide transformer-feeding slot wants\n // the same side.\n const aw = slotWidthFor(a.elId, a.lib.width);\n const bw = slotWidthFor(b.elId, b.lib.width);\n return bw - aw;\n });\n const widths = group.map((r) => slotWidthFor(r.elId, r.lib.width));\n const totalW = widths.reduce((s, w) => s + w, 0);\n const usableSpan = Math.max(span, totalW);\n const slotGap = (usableSpan - totalW) / (group.length + 1);\n let cursor = finalGeom.at[0] - usableSpan / 2 + slotGap;\n const tapWorldY = finalGeom.at[1] + offsetSign * BUS_TAP_OFFSET;\n for (let i = 0; i < group.length; i++) {\n const r = group[i];\n const slotW = widths[i];\n const tapWorldX = cursor + slotW / 2;\n if (r.isLinker) {\n if (!linkerSlotX.has(r.elId)) linkerSlotX.set(r.elId, tapWorldX);\n } else {\n layout.set(r.elId, {\n at: [snap(tapWorldX - r.localTerm.x), snap(tapWorldY - r.localTerm.y)],\n rot: 0,\n mirror: false,\n });\n }\n cursor += slotW + slotGap;\n }\n };\n distribute(aboveSide, -1);\n distribute(belowSide, +1);\n };\n\n const placeLinker = (link: LinkerInfo): void => {\n if (layout.has(link.elementId)) return;\n if (link.orientation === 'horizontal') return;\n const linkerLib = libOf(link.elementId);\n if (!linkerLib) return;\n\n const placedAttachments = link.attachments.filter((a) =>\n busLayout.has(a.busId),\n );\n if (placedAttachments.length < 2) return;\n const sorted = placedAttachments.slice().sort(\n (a, b) =>\n (busLevel.get(a.busId) ?? 0) - (busLevel.get(b.busId) ?? 0),\n );\n const upperBusId = sorted[0].busId;\n const upperGeom = busLayout.get(upperBusId)!;\n\n const upperPin = sorted[0].pin;\n const lowerPin = sorted[sorted.length - 1].pin;\n const upperLocal = linkerLib.terminals.find((t) => t.id === upperPin);\n const lowerLocal = linkerLib.terminals.find((t) => t.id === lowerPin);\n if (!upperLocal || !lowerLocal) return;\n\n const rot: 0 | 180 = upperLocal.y <= lowerLocal.y ? 0 : 180;\n\n const upperLevel = busLevel.get(upperBusId) ?? 0;\n const upperSideAttachments = placedAttachments.filter(\n (a) => (busLevel.get(a.busId) ?? 0) === upperLevel,\n );\n const upperHeadXs: number[] = [];\n let maxUpperExtent = 0;\n for (const att of upperSideAttachments) {\n const result = chainExtentToBus(link, att.busId, att.pin);\n maxUpperExtent = Math.max(maxUpperExtent, result.extent);\n const headPlace = result.head ? layout.get(result.head) : undefined;\n if (headPlace) {\n upperHeadXs.push(headPlace.at[0]);\n } else if (linkerSlotX.has(link.elementId)) {\n // Direct-tap linker (no intermediate chain head): use the slot X\n // allocated for it by the upper bus's tap distribution.\n upperHeadXs.push(linkerSlotX.get(link.elementId)!);\n } else {\n upperHeadXs.push(busLayout.get(att.busId)!.at[0]);\n }\n }\n let xCenter: number;\n if (upperHeadXs.length > 0) {\n xCenter =\n upperHeadXs.reduce((s, x) => s + x, 0) / upperHeadXs.length;\n } else if (linkerSlotX.has(link.elementId)) {\n xCenter = linkerSlotX.get(link.elementId)!;\n } else {\n xCenter = upperGeom.at[0];\n }\n const upperPinWorldY = upperGeom.at[1] + maxUpperExtent;\n\n const at: [number, number] =\n rot === 0\n ? [snap(xCenter - upperLocal.x), snap(upperPinWorldY - upperLocal.y)]\n : [snap(xCenter + upperLocal.x), snap(upperPinWorldY + upperLocal.y)];\n layout.set(link.elementId, { at, rot, mirror: false });\n\n if (upperSideAttachments.length > 1) {\n const linkerPlace = layout.get(link.elementId)!;\n const upperPinWorld = transformPoint(\n [upperLocal.x, upperLocal.y],\n linkerPlace,\n );\n const upperWorldOrient = transformOrientation(\n upperLocal.orientation,\n linkerPlace,\n );\n walkChainAlongAxis(\n `${link.elementId}.${upperPin}` as TerminalRef,\n upperPinWorld,\n upperWorldOrient,\n xCenter,\n );\n }\n };\n\n // Walk a single-pin chain starting from `startRef`, heading in the world\n // `startExit` direction. Stops at a merge node (electrical node with 3+\n // members), a bus, a linker, an already-placed element, or no neighbour.\n const walkChainAlongAxis = (\n startRef: TerminalRef,\n startWorld: [number, number],\n startExit: Orientation,\n axisX: number,\n ): void => {\n const visited = new Set<WireEnd>([startRef]);\n let prevRef: WireEnd = startRef;\n let prevWorld = startWorld;\n let prevExit = startExit;\n while (true) {\n const groups = pinToGroups.get(prevRef) ?? [];\n let nextRef: WireEnd | undefined;\n let blocked = false;\n for (const g of groups) {\n if (g.length >= 3) {\n // Multi-pin merge — stop and let auto-route draw the rake.\n blocked = true;\n break;\n }\n const other = g.find((r) => r !== prevRef);\n if (!other || visited.has(other)) continue;\n if (isBus(other)) {\n blocked = true;\n break;\n }\n nextRef = other;\n break;\n }\n if (blocked || !nextRef) break;\n const dot = nextRef.indexOf('.');\n if (dot < 0) break;\n const elId = nextRef.slice(0, dot);\n const pinName = nextRef.slice(dot + 1);\n if (isBus(elId) || linkerIds.has(elId)) break;\n if (layout.has(elId)) break;\n const lib = libOf(elId);\n if (!lib) break;\n const inTerm = lib.terminals.find((t) => t.id === pinName);\n if (!inTerm) break;\n\n const exitVec = orientationVec(prevExit);\n const target: [number, number] = [\n prevWorld[0] + exitVec[0] * CHAIN_GAP,\n prevWorld[1] + exitVec[1] * CHAIN_GAP,\n ];\n const desiredOrient = OPPOSITE_ORIENT[prevExit];\n const rot = rotationToAlignOrient(inTerm.orientation, desiredOrient);\n const rotatedInPin = transformPoint([inTerm.x, inTerm.y], {\n at: [0, 0],\n rot,\n mirror: false,\n });\n const at: [number, number] = [\n snap(axisX - rotatedInPin[0]),\n snap(target[1] - rotatedInPin[1]),\n ];\n layout.set(elId, { at, rot, mirror: false });\n visited.add(nextRef);\n\n const outTerm = lib.terminals.find((t) => t.id !== pinName);\n if (!outTerm) break;\n const outRef = `${elId}.${outTerm.id}` as TerminalRef;\n visited.add(outRef);\n const placement = { at, rot, mirror: false };\n prevWorld = transformPoint([outTerm.x, outTerm.y], placement);\n prevExit = transformOrientation(outTerm.orientation, placement);\n prevRef = outRef;\n }\n };\n\n const placeHorizontalLinker = (link: LinkerInfo): void => {\n if (layout.has(link.elementId)) return;\n if (link.orientation !== 'horizontal') return;\n const linkerLib = libOf(link.elementId);\n if (!linkerLib) return;\n const placed = link.attachments.filter((a) => busLayout.has(a.busId));\n if (placed.length < 2) return;\n\n interface HeadInfo {\n att: BusAttachment;\n x: number;\n extent: number;\n }\n const heads: HeadInfo[] = placed.map((att) => {\n const result = chainExtentToBus(link, att.busId, att.pin);\n const headPlace = result.head ? layout.get(result.head) : undefined;\n const x = headPlace\n ? headPlace.at[0]\n : busLayout.get(att.busId)!.at[0];\n return { att, x, extent: result.extent };\n });\n heads.sort((a, b) => a.x - b.x);\n const left = heads[0];\n const right = heads[heads.length - 1];\n const leftLocal = linkerLib.terminals.find((t) => t.id === left.att.pin);\n const rightLocal = linkerLib.terminals.find((t) => t.id === right.att.pin);\n if (!leftLocal || !rightLocal) return;\n\n const rot: 90 | 270 = leftLocal.y <= rightLocal.y ? 270 : 90;\n\n const xCenter = (left.x + right.x) / 2;\n const busY = busLayout.get(left.att.busId)!.at[1];\n const linkerY = busY + Math.max(left.extent, right.extent);\n\n layout.set(link.elementId, {\n at: [snap(xCenter), snap(linkerY)],\n rot,\n mirror: false,\n });\n };\n\n const SIBLING_X_GAP = 100;\n\n let prevLevelY = BUS_Y0;\n for (let li = 0; li < sortedLevels.length; li++) {\n const lvl = sortedLevels[li];\n const busIdsAtLevel = levelToBuses.get(lvl)!;\n\n let levelY: number;\n if (li === 0) {\n levelY = BUS_Y0;\n } else {\n const prevBusIds = levelToBuses.get(sortedLevels[li - 1])!;\n let maxGap = 0;\n for (const parent of prevBusIds) {\n for (const child of busIdsAtLevel) {\n if (busLinks.get(parent)?.get(child)) {\n maxGap = Math.max(maxGap, gapBetween(parent, child));\n }\n }\n }\n if (maxGap === 0) maxGap = MIN_BUS_GAP_Y;\n levelY = prevLevelY + maxGap;\n }\n prevLevelY = levelY;\n\n let nextSiblingX = BUS_X;\n for (const busId of busIdsAtLevel) {\n if (busLayout.has(busId)) {\n prevLevelY = Math.max(prevLevelY, busLayout.get(busId)!.at[1]);\n continue;\n }\n let busX: number | undefined;\n if (li > 0) {\n const prevBusIds = levelToBuses.get(sortedLevels[li - 1])!;\n const headXs: number[] = [];\n for (const parent of prevBusIds) {\n const link = busLinks.get(parent)?.get(busId);\n if (!link || link.orientation !== 'vertical') continue;\n const parentPin = link.attachments.find(\n (a) => a.busId === parent,\n )?.pin;\n if (!parentPin) continue;\n const result = chainExtentToBus(link, parent, parentPin);\n if (result.head && layout.has(result.head)) {\n headXs.push(layout.get(result.head)!.at[0]);\n } else if (linkerSlotX.has(link.elementId)) {\n headXs.push(linkerSlotX.get(link.elementId)!);\n } else {\n headXs.push(busLayout.get(parent)!.at[0]);\n }\n }\n if (headXs.length > 0) {\n busX = headXs.reduce((s, x) => s + x, 0) / headXs.length;\n }\n }\n if (busX === undefined) {\n const ownSpan = busSpan.get(busId) ?? DEFAULT_BUS_SPAN;\n busX = nextSiblingX + ownSpan / 2;\n nextSiblingX += ownSpan + SIBLING_X_GAP;\n }\n const span = busSpan.get(busId) ?? DEFAULT_BUS_SPAN;\n busLayout.set(busId, {\n at: [snap(busX), snap(levelY)],\n rot: 0,\n span,\n axis: busAxisFromRot(0),\n });\n }\n\n for (const busId of busIdsAtLevel) {\n distributeBusTaps(busId);\n }\n\n if (li > 0) {\n for (const link of linkers) {\n if (layout.has(link.elementId)) continue;\n const involvesThisLevel = link.attachments.some((a) =>\n busIdsAtLevel.includes(a.busId),\n );\n if (!involvesThisLevel) continue;\n placeLinker(link);\n }\n }\n\n for (const link of linkers) {\n if (link.orientation !== 'horizontal') continue;\n if (layout.has(link.elementId)) continue;\n const allHere = link.attachments.every((a) =>\n busIdsAtLevel.includes(a.busId),\n );\n if (!allHere) continue;\n placeHorizontalLinker(link);\n }\n }\n\n // ---- 6. Node-based parallel-branch placement --------------------------\n // For each electrical node with placed and unplaced members, pick the\n // anchor pin by voting on direct co-occurrence with the unplaced cluster,\n // and lay out the remaining elements as parallel branches perpendicular\n // to the anchor's exit. Iterate to a fixpoint so newly-placed elements\n // can anchor further chains.\n const isEndPlaced = (end: WireEnd): boolean => {\n if (isBus(end)) return busLayout.has(end);\n const dot = end.indexOf('.');\n if (dot < 0) return false;\n return layout.has(end.slice(0, dot));\n };\n\n let progressed = true;\n let safety = elements.length + 4;\n while (progressed && safety-- > 0) {\n progressed = false;\n\n for (const node of nodeGroups) {\n if (node.length < 2) continue;\n\n interface UnplacedPinInfo {\n ref: TerminalRef;\n elId: ElementId;\n lib: LibraryEntry;\n localTerm: {\n id: string;\n x: number;\n y: number;\n orientation: Orientation;\n };\n }\n const placedPins: TerminalRef[] = [];\n const unplacedByEl = new Map<ElementId, UnplacedPinInfo>();\n\n for (const end of node) {\n if (isBus(end)) {\n // Bus is a hyperedge node, not an anchor candidate.\n continue;\n }\n const dot = end.indexOf('.');\n if (dot < 0) continue;\n const id = end.slice(0, dot);\n const pinName = end.slice(dot + 1);\n if (layout.has(id)) {\n placedPins.push(end as TerminalRef);\n continue;\n }\n if (linkerIds.has(id)) continue;\n if (unplacedByEl.has(id)) continue;\n const lib = libOf(id);\n if (!lib) continue;\n const localTerm = lib.terminals.find((t) => t.id === pinName);\n if (!localTerm) continue;\n unplacedByEl.set(id, {\n ref: end as TerminalRef,\n elId: id,\n lib,\n localTerm,\n });\n }\n if (unplacedByEl.size === 0 || placedPins.length === 0) continue;\n const unplacedUnique = [...unplacedByEl.values()];\n\n // Vote on anchor: each unplaced pin contributes a vote to every other\n // placed non-bus pin in the same node. Strong winner = the placed pin\n // most directly connected to the unplaced cluster.\n const votes = new Map<TerminalRef, number>();\n for (const u of unplacedUnique) {\n for (const g of pinToGroups.get(u.ref) ?? []) {\n for (const p of g) {\n if (p === u.ref) continue;\n if (isBus(p)) continue;\n if (!isEndPlaced(p)) continue;\n const tref = p as TerminalRef;\n votes.set(tref, (votes.get(tref) ?? 0) + 1);\n }\n }\n }\n\n let anchor: TerminalRef | undefined;\n if (votes.size > 0) {\n let best = -1;\n for (const [p, v] of votes) {\n if (v > best || (v === best && (anchor === undefined || p < anchor))) {\n best = v;\n anchor = p;\n }\n }\n }\n if (!anchor) {\n anchor = [...placedPins].sort()[0];\n }\n if (!anchor) continue;\n\n const dot = anchor.indexOf('.');\n const anchorId = anchor.slice(0, dot);\n const anchorPin = anchor.slice(dot + 1);\n const anchorLib = libOf(anchorId);\n const anchorPlace = layout.get(anchorId);\n if (!anchorLib || !anchorPlace) continue;\n const anchorTerm = anchorLib.terminals.find((t) => t.id === anchorPin);\n if (!anchorTerm) continue;\n\n const anchorWorld = transformPoint(\n [anchorTerm.x, anchorTerm.y],\n anchorPlace,\n );\n const anchorOrient = transformOrientation(\n anchorTerm.orientation,\n anchorPlace,\n );\n const exit = orientationVec(anchorOrient);\n const perp: [number, number] = [-exit[1], exit[0]];\n\n unplacedUnique.sort((a, b) => a.elId.localeCompare(b.elId));\n const widths = unplacedUnique.map((u) =>\n Math.max(u.lib.width, MIN_TAP_SPACING),\n );\n const totalW = widths.reduce((sum, w) => sum + w, 0);\n let cursor = -totalW / 2;\n\n for (let i = 0; i < unplacedUnique.length; i++) {\n const u = unplacedUnique[i];\n const slotW = widths[i];\n const slotCenter = cursor + slotW / 2;\n cursor += slotW;\n\n const desiredOrient = OPPOSITE_ORIENT[anchorOrient];\n const rot = rotationToAlignOrient(\n u.localTerm.orientation,\n desiredOrient,\n );\n const rotatedPin = transformPoint(\n [u.localTerm.x, u.localTerm.y],\n { at: [0, 0], rot, mirror: false },\n );\n const targetWorld: [number, number] = [\n anchorWorld[0] + exit[0] * CHAIN_GAP + perp[0] * slotCenter,\n anchorWorld[1] + exit[1] * CHAIN_GAP + perp[1] * slotCenter,\n ];\n const at: [number, number] = [\n snap(targetWorld[0] - rotatedPin[0]),\n snap(targetWorld[1] - rotatedPin[1]),\n ];\n layout.set(u.elId, { at, rot, mirror: false });\n progressed = true;\n }\n }\n }\n\n // ---- 7. Fallback grid for orphans -------------------------------------\n let placedCount = 0;\n for (const el of elements) {\n if (layout.has(el.id)) continue;\n const col = placedCount % FALLBACK_GRID_COLS;\n const row = Math.floor(placedCount / FALLBACK_GRID_COLS);\n layout.set(el.id, {\n at: [\n snap(FALLBACK_GRID_X0 + col * FALLBACK_GRID_DX),\n snap(FALLBACK_GRID_Y0 + row * FALLBACK_GRID_DY),\n ],\n rot: 0,\n mirror: false,\n });\n placedCount++;\n }\n\n return { devices: layout, buses: busLayout };\n}\n\nfunction snap(v: number): number {\n return Math.round(v / GRID) * GRID;\n}\n","/**\n * Best-effort orthogonal routing per Wire. Each visible polyline maps 1-to-1\n * to a Wire, so selecting / deleting at the wire level just works.\n *\n * Routing rules per wire `[a, b]`:\n * - If one end is a bus: project the other end onto the bus axis, L-shape\n * to that point.\n * - Otherwise: simple L-shape between the two terminal world coords.\n */\n\nimport type { Wire, WireEnd, WireId } from '../model';\nimport type { InternalModel } from './internal-model';\n\ntype Pt = [number, number];\n\nexport interface WireRoute {\n wireId: WireId;\n path: Pt[];\n}\n\nexport function routeWire(wire: Wire, model: InternalModel): WireRoute | null {\n const a = wire.ends[0];\n const b = wire.ends[1];\n const aBus = isBus(a, model);\n const bBus = isBus(b, model);\n // Bus end → project the other end onto the bus axis.\n if (aBus || bBus) {\n const bus = aBus ? a : b;\n const other = aBus ? b : a;\n const otherWorld = endWorld(other, model);\n if (!otherWorld) return null;\n const rb = model.buses.get(bus);\n if (!rb) return null;\n const { axis, at, span } = rb.geometry;\n const half = span / 2;\n let target: Pt;\n if (axis === 'x') {\n const x = clamp(otherWorld[0], at[0] - half, at[0] + half);\n target = [x, at[1]];\n } else {\n const y = clamp(otherWorld[1], at[1] - half, at[1] + half);\n target = [at[0], y];\n }\n return { wireId: wire.id, path: orthogonalPath(otherWorld, target) };\n }\n const aw = endWorld(a, model);\n const bw = endWorld(b, model);\n if (!aw || !bw) return null;\n return { wireId: wire.id, path: orthogonalPath(aw, bw) };\n}\n\nfunction isBus(end: WireEnd, model: InternalModel): boolean {\n return !end.includes('.') && model.buses.has(end);\n}\n\nfunction endWorld(end: WireEnd, model: InternalModel): Pt | null {\n if (!end.includes('.')) {\n const rb = model.buses.get(end);\n return rb ? (rb.geometry.at as Pt) : null;\n }\n const term = model.terminals.get(end as `${string}.${string}`);\n return term ? (term.world as Pt) : null;\n}\n\nfunction orthogonalPath(a: Pt, b: Pt): Pt[] {\n if (a[0] === b[0] || a[1] === b[1]) return [a, b];\n return [a, [a[0], b[1]], b];\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n","import type { LibraryEntry } from '../model/library';\n\nconst modules = import.meta.glob<{ default: LibraryEntry }>('./*.json', {\n eager: true,\n});\n\n/** All library entries, in filesystem order. */\nexport const libraryEntries: LibraryEntry[] = Object.values(modules).map(\n (m) => m.default,\n);\n\n/** O(1) lookup by `LibraryEntry.id`. */\nexport const libraryById: Record<string, LibraryEntry> = Object.fromEntries(\n libraryEntries.map((e) => [e.id, e]),\n);\n\n/**\n * Display order and Chinese labels for palette categories.\n * Categories not listed here fall through to the end with their raw id.\n */\nexport const CATEGORY_ORDER: readonly string[] = [\n 'busbar',\n 'switching',\n 'protection',\n 'motor-control',\n 'transformer',\n 'instrument-transformer',\n 'measurement',\n 'source',\n 'load',\n 'storage',\n 'compensation',\n 'grounding',\n 'renewable',\n];\n\nexport const CATEGORY_LABELS: Record<string, string> = {\n busbar: '母线 / 接线',\n switching: '开关',\n protection: '保护',\n 'motor-control': '电机控制',\n transformer: '变压器',\n 'instrument-transformer': '互感器',\n measurement: '测量仪表',\n source: '电源',\n load: '负荷',\n storage: '储能',\n compensation: '无功补偿',\n grounding: '中性点接地',\n renewable: '新能源 / 电力电子',\n};\n\n/** Entries grouped by category, preserving filesystem order within each group. */\nexport const libraryByCategory: Record<string, LibraryEntry[]> = (() => {\n const groups: Record<string, LibraryEntry[]> = {};\n for (const entry of libraryEntries) {\n (groups[entry.category] ??= []).push(entry);\n }\n return groups;\n})();\n","/**\n * Re-export the element library indexed by `LibraryEntry.id` for use in the\n * compile pipeline. The actual library is loaded once in\n * `src/element-library/index.ts`.\n */\n\nimport { libraryById } from '../element-library';\nimport type { LibraryEntry } from '../model';\n\nexport const LIBRARY: ReadonlyMap<string, LibraryEntry> = new Map(\n Object.entries(libraryById),\n);\n\nexport function getLibraryEntry(kind: string): LibraryEntry | undefined {\n return libraryById[kind];\n}\n","/**\n * DiagramFile → InternalModel. Pipeline:\n *\n * 1. Resolve elements + library\n * 2. Resolve buses (geometry from `Bus.layout` or auto-layout below)\n * 3. Validate wire endpoints (errors → diagnostics; pipeline keeps going)\n * 4. Auto-layout for devices without `Placement` and buses without layout\n * 5. Compute world-frame terminal geometry\n * 6. Union-find on wires → ConnectivityNode set with deterministic ids\n * (sorted endpoints hashed) so `routes[nodeId]` keys stay stable\n * across saves\n * 7. Auto-route each ConnectivityNode unless the user supplied a path\n */\n\nimport { t } from '../i18n';\nimport type {\n Bus,\n BusId,\n DiagramFile,\n Element,\n ElementId,\n NodeId,\n TerminalRef,\n Wire,\n WireEnd,\n} from '../model';\nimport { autoLayout } from './auto-layout';\nimport { routeWire } from './auto-route';\nimport { LIBRARY } from './library-index';\nimport {\n emptyInternalModel,\n resolvePlacement,\n busAxisFromRot,\n type BusGeometry,\n type InternalModel,\n type ResolvedPlacement,\n} from './internal-model';\nimport { transformOrientation, transformPoint } from './transforms';\nimport { UnionFind } from './union-find';\n\n/**\n * Stable, content-derived node id. Same set of endpoints always maps to the\n * same NodeId across compile runs and across save/load cycles, so user-edited\n * `routes[nodeId]` overrides stay attached after reload.\n */\nfunction deterministicNodeId(members: WireEnd[]): NodeId {\n // FNV-1a 32-bit on the sorted, joined refs. Plenty of entropy for typical\n // diagram sizes (<10k nodes); collisions only cause a route override to\n // attach to the wrong node, never wrong electrical behavior.\n const sorted = [...members].sort();\n const text = sorted.join('|');\n let h = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return `n_${(h >>> 0).toString(36)}`;\n}\n\nconst DEFAULT_BUS_SPAN = 320;\n\nexport function compile(diagram: DiagramFile): InternalModel {\n const m = emptyInternalModel();\n\n // ---- 1. Resolve elements + library ------------------------------------\n const elementById = new Map<ElementId, Element>();\n diagram.elements.forEach((el, idx) => {\n if (elementById.has(el.id)) {\n m.diagnostics.push({\n code: 'E001',\n severity: 'error',\n message: t('compile.duplicateId', { id: el.id }),\n pointer: `/elements/${idx}`,\n });\n return;\n }\n elementById.set(el.id, el);\n const libDef = LIBRARY.get(el.kind);\n if (!libDef) {\n m.diagnostics.push({\n code: 'E003',\n severity: 'error',\n message: `${t('compile.unknownKind', { kind: el.kind })} (id=${el.id})`,\n pointer: `/elements/${idx}`,\n });\n }\n m.elements.set(el.id, { element: el, libraryDef: libDef });\n });\n\n // ---- 2. Resolve buses (preliminary; layout filled by auto-layout) -----\n const busById = new Map<BusId, Bus>();\n const userBusLayout = new Map<BusId, BusGeometry>();\n (diagram.buses ?? []).forEach((bus, idx) => {\n if (elementById.has(bus.id) || busById.has(bus.id)) {\n m.diagnostics.push({\n code: 'E001',\n severity: 'error',\n message: t('compile.duplicateId', { id: bus.id }),\n pointer: `/buses/${idx}`,\n });\n return;\n }\n busById.set(bus.id, bus);\n if (bus.layout) {\n const rot = bus.layout.rot ?? 0;\n userBusLayout.set(bus.id, {\n at: bus.layout.at,\n span: bus.layout.span,\n rot,\n axis: busAxisFromRot(rot),\n });\n }\n });\n\n // ---- 3. Validate wire endpoints ---------------------------------------\n const isBus = (end: WireEnd): boolean => !end.includes('.') && busById.has(end);\n const validEnd = (end: WireEnd, pointer: string): boolean => {\n if (isBus(end)) return true;\n const dot = end.indexOf('.');\n if (dot <= 0) {\n m.diagnostics.push({\n code: 'E003',\n severity: 'error',\n message: t('compile.invalidTermRef', { ref: end }),\n pointer,\n });\n return false;\n }\n const elemId = end.slice(0, dot);\n const pin = end.slice(dot + 1);\n const re = m.elements.get(elemId);\n if (!re) {\n m.diagnostics.push({\n code: 'E002',\n severity: 'error',\n message: t('compile.elementMissing', { id: elemId }),\n pointer,\n });\n return false;\n }\n if (!re.libraryDef) return false;\n if (!re.libraryDef.terminals.find((term) => term.id === pin)) {\n const avail = re.libraryDef.terminals.map((term) => term.id).join(', ');\n m.diagnostics.push({\n code: 'E003',\n severity: 'error',\n message: t('compile.missingPin', {\n id: elemId,\n kind: re.element.kind,\n pin,\n available: avail,\n }),\n pointer,\n });\n return false;\n }\n return true;\n };\n\n const validWires: Wire[] = [];\n (diagram.wires ?? []).forEach((w, i) => {\n const pointer = `/wires/${i}`;\n const a = validEnd(w.ends[0], pointer);\n const b = validEnd(w.ends[1], pointer);\n if (a && b) validWires.push(w);\n });\n\n // ---- 4. Auto-layout ----------------------------------------------------\n const userLayout = new Map<ElementId, ResolvedPlacement>();\n if (diagram.layout) {\n for (const [id, p] of Object.entries(diagram.layout)) {\n if (m.elements.has(id)) userLayout.set(id, resolvePlacement(p));\n else\n m.diagnostics.push({\n code: 'E004',\n severity: 'error',\n message: t('compile.layoutMissingElement', { id }),\n pointer: `/layout/${id}`,\n });\n }\n }\n const layoutResult = autoLayout({\n elements: diagram.elements,\n buses: diagram.buses ?? [],\n wires: validWires,\n library: LIBRARY,\n userLayout,\n userBusLayout,\n });\n m.layout = layoutResult.devices;\n for (const [busId, geom] of layoutResult.buses) {\n const bus = busById.get(busId);\n if (!bus) continue;\n m.buses.set(busId, { bus, geometry: geom });\n }\n // Any bus that still has no geometry (auto-layout couldn't position it)\n // gets a default. Defensive — shouldn't happen with non-empty wires.\n for (const [busId, bus] of busById) {\n if (m.buses.has(busId)) continue;\n m.buses.set(busId, {\n bus,\n geometry: {\n at: bus.layout?.at ?? [0, 0],\n span: bus.layout?.span ?? DEFAULT_BUS_SPAN,\n rot: bus.layout?.rot ?? 0,\n axis: busAxisFromRot(bus.layout?.rot ?? 0),\n },\n });\n }\n\n // ---- 5. Compute terminal geometry --------------------------------------\n for (const re of m.elements.values()) {\n if (!re.libraryDef) continue;\n const place = m.layout.get(re.element.id);\n if (!place) continue;\n const refs: TerminalRef[] = [];\n for (const lt of re.libraryDef.terminals) {\n const ref = `${re.element.id}.${lt.id}` as TerminalRef;\n const world = transformPoint([lt.x, lt.y], place);\n const orientation = transformOrientation(lt.orientation, place);\n m.terminals.set(ref, {\n ref,\n elementId: re.element.id,\n pin: lt.id,\n world,\n orientation,\n });\n refs.push(ref);\n }\n m.elementToTerminals.set(re.element.id, refs);\n }\n\n // ---- 6. Union-find over wires -----------------------------------------\n const uf = new UnionFind<WireEnd>();\n for (const w of validWires) {\n uf.add(w.ends[0]);\n uf.add(w.ends[1]);\n uf.union(w.ends[0], w.ends[1]);\n }\n for (const [, members] of uf.groups()) {\n const id = deterministicNodeId(members);\n m.nodes.set(id, { id, terminals: members });\n for (const end of members) m.terminalToNode.set(end, id);\n }\n\n // Warn about isolated elements / buses (no terminal in any node).\n for (const re of m.elements.values()) {\n const refs = m.elementToTerminals.get(re.element.id) ?? [];\n if (refs.length === 0) continue;\n const anyConnected = refs.some((r) => m.terminalToNode.has(r));\n if (!anyConnected) {\n m.diagnostics.push({\n code: 'W001',\n severity: 'warning',\n message: t('compile.elementUnconnected', { id: re.element.id }),\n });\n }\n }\n for (const busId of m.buses.keys()) {\n if (!m.terminalToNode.has(busId)) {\n m.diagnostics.push({\n code: 'W001',\n severity: 'warning',\n message: t('compile.elementUnconnected', { id: busId }),\n });\n }\n }\n\n // ---- 7. Per-wire rendering (Wire.path override; otherwise routeWire) ---\n for (const w of validWires) {\n if (w.path && w.path.length >= 2) {\n m.wireRenders.set(w.id, { wireId: w.id, path: w.path, userEdited: true });\n continue;\n }\n const r = routeWire(w, m);\n if (r) m.wireRenders.set(w.id, r);\n }\n\n return m;\n}\n","/**\n * ID minting for new elements / buses / annotations / wires. Element and bus\n * prefixes follow real-schematic conventions; wires use a deterministic\n * content hash so the same pair of endpoints always maps to the same id.\n */\n\nimport type { DiagramFile, ElementId, WireEnd, WireId } from '../model';\n\nconst PREFIX: Record<string, string> = {\n earth: 'GND',\n breaker: 'QF',\n disconnector: 'QS',\n 'earthing-switch': 'QE',\n 'load-switch': 'QL',\n fuse: 'FU',\n 'transformer-2w': 'T',\n 'transformer-3w': 'T',\n autotransformer: 'AT',\n ct: 'CT',\n pt: 'PT',\n generator: 'G',\n 'sync-motor': 'M',\n 'async-motor': 'M',\n 'grid-source': 'L',\n load: 'L',\n battery: 'BAT',\n 'shunt-reactor': 'LR',\n 'series-reactor': 'LR',\n 'shunt-capacitor': 'C',\n arrester: 'FBL',\n 'grounding-transformer': 'TG',\n ngr: 'NGR',\n 'arc-suppression-coil': 'ASC',\n pv: 'PV',\n 'wind-turbine': 'WT',\n rectifier: 'RT',\n inverter: 'INV',\n 'converter-bidir': 'PCS',\n};\n\nconst BUS_PREFIX = 'B';\n\nfunction usedIds(diagram: DiagramFile): Set<string> {\n return new Set([\n ...diagram.elements.map((e) => e.id),\n ...(diagram.buses ?? []).map((b) => b.id),\n ]);\n}\n\nexport function newElementId(diagram: DiagramFile, kind: string): ElementId {\n const prefix = PREFIX[kind] ?? kind;\n const used = usedIds(diagram);\n let n = 1;\n while (used.has(`${prefix}${n}`)) n++;\n return `${prefix}${n}`;\n}\n\nexport function newBusId(diagram: DiagramFile): ElementId {\n const used = usedIds(diagram);\n let n = 1;\n while (used.has(`${BUS_PREFIX}${n}`)) n++;\n return `${BUS_PREFIX}${n}`;\n}\n\nexport function newAnnotationId(diagram: DiagramFile): string {\n const used = new Set((diagram.annotations ?? []).map((a) => a.id));\n let n = 1;\n while (used.has(`a${n}`)) n++;\n return `a${n}`;\n}\n\n/**\n * Content-hashed wire id. Two wires with the same pair of endpoints collide\n * intentionally — duplicate `addWire` is a no-op, and migration / save\n * round-trips produce stable diffs.\n */\nexport function wireIdFromEnds(a: WireEnd, b: WireEnd): WireId {\n const sorted = [a, b].sort();\n const text = `${sorted[0]}|${sorted[1]}`;\n let h = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return `w_${(h >>> 0).toString(36)}`;\n}\n","/**\n * Zustand store — the single source of truth for the editor.\n *\n * Mutation rule: the only way to change `diagram` is `dispatch(mutator)`.\n * `dispatch` snapshots the previous diagram onto an undo stack, applies the\n * mutation, recompiles, and clears the redo stack. Targeted helpers\n * (`moveElements`, `addWire`, …) are thin wrappers around `dispatch`.\n *\n * Selection / tool / cursor state lives in the store too, but does *not*\n * participate in the undo stack — Figma convention: ephemeral UI state\n * doesn't pollute history.\n *\n * Viewport (pan/zoom) is deliberately *not* in the store: it lives on a DOM\n * ref to avoid React re-renders during gesture loops.\n */\n\nimport { create } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\nimport {\n compile,\n type InternalModel,\n type ResolvedPlacement,\n type BusGeometry,\n} from '../compiler';\nimport type { FileSession } from '../lib/file-io';\nimport type {\n AnnotationId,\n Bus,\n BusId,\n BusLayout,\n DiagramFile,\n Element,\n ElementId,\n NodeId,\n Placement,\n TextAnnotation,\n Wire,\n WireEnd,\n WireId,\n} from '../model';\nimport {\n newAnnotationId,\n newBusId,\n newElementId,\n wireIdFromEnds,\n} from './id-allocator';\n\nconst EMPTY_DIAGRAM: DiagramFile = { version: '1', elements: [] };\nconst HISTORY_LIMIT = 100;\nconst PASTE_OFFSET = 20;\n\nfunction defaultTool(): ToolId {\n if (typeof window === 'undefined') return 'select';\n try {\n return window.matchMedia('(pointer: coarse)').matches ? 'pan' : 'select';\n } catch {\n return 'select';\n }\n}\n\n/**\n * Self-contained snapshot of a copied selection. Placements are pre-resolved\n * (auto-layout positions baked in) so paste survives later edits to the\n * source diagram. Wires only include those whose endpoints are all within\n * the selection.\n */\nexport interface ClipboardData {\n elements: Element[];\n buses: Bus[];\n placements: Record<ElementId, Placement>;\n busLayouts: Record<BusId, BusLayout>;\n wires: Wire[];\n}\n\nexport type ToolId = 'select' | 'pan' | 'wire' | 'place' | 'busbar' | 'text';\n\nexport interface EditorState {\n // ---- Document --------------------------------------------------------\n diagram: DiagramFile;\n internal: InternalModel;\n fileSession: FileSession | null;\n\n // ---- Ephemeral UI state ---------------------------------------------\n activeTool: ToolId;\n placeKind: string | null;\n lastPlaceKind: string | null;\n wireFromTerminal: WireEnd | null;\n placeFromTerminal: WireEnd | null;\n busbarDrawStart: [number, number] | null;\n cursorSvg: [number, number] | null;\n /** Selected devices and/or buses (shared id namespace). */\n selection: ElementId[];\n /** Selected single wire (mutually exclusive with selection/selectedNode). */\n selectedWire: WireId | null;\n /** Selected ConnectivityNode — used for \"select the whole electrical\n * node\" operations. Mutually exclusive with the others. */\n selectedNode: NodeId | null;\n selectedAnnotation: AnnotationId | null;\n editingAnnotation: AnnotationId | null;\n editingElement: ElementId | null;\n\n // ---- History ---------------------------------------------------------\n past: DiagramFile[];\n future: DiagramFile[];\n\n // ---- Clipboard (ephemeral, not in history) --------------------------\n clipboard: ClipboardData | null;\n clipboardPasteIndex: number;\n\n // ---- Mutation API ----------------------------------------------------\n setDiagram: (diagram: DiagramFile) => void;\n setFileSession: (session: FileSession | null) => void;\n loadDiagramFromFile: (diagram: DiagramFile, session: FileSession) => void;\n\n dispatch: (mutator: (d: DiagramFile) => DiagramFile, label?: string) => void;\n undo: () => void;\n redo: () => void;\n\n // ---- UI actions ------------------------------------------------------\n setActiveTool: (tool: ToolId, opts?: { placeKind?: string | null }) => void;\n setPlaceKind: (kind: string | null) => void;\n setWireFromTerminal: (ref: WireEnd | null) => void;\n setPlaceFromTerminal: (ref: WireEnd | null) => void;\n setBusbarDrawStart: (pt: [number, number] | null) => void;\n setCursorSvg: (pt: [number, number] | null) => void;\n\n setSelection: (ids: ElementId[]) => void;\n toggleInSelection: (id: ElementId) => void;\n clearSelection: () => void;\n setSelectedWire: (id: WireId | null) => void;\n setSelectedNode: (nodeId: NodeId | null) => void;\n setSelectedAnnotation: (id: AnnotationId | null) => void;\n setEditingAnnotation: (id: AnnotationId | null) => void;\n setEditingElement: (id: ElementId | null) => void;\n\n // ---- Clipboard actions ----------------------------------------------\n copySelection: () => void;\n cutSelection: () => void;\n pasteClipboard: () => void;\n\n // ---- Auto-layout actions --------------------------------------------\n autoArrangeAll: () => void;\n autoArrangeSelection: () => void;\n fillUnplacedAll: () => void;\n fillUnplacedSelection: () => void;\n\n // ---- Document edit shortcuts ----------------------------------------\n moveElements: (deltas: Map<ElementId, [number, number]>) => void;\n deleteSelection: () => void;\n /** Drop a single wire by id. */\n deleteSelectedWire: () => void;\n /** Drop every wire touching the currently selected ConnectivityNode. */\n deleteSelectedNode: () => void;\n rotateSelection: (deltaDegrees: 90 | -90 | 180) => void;\n mirrorSelection: () => void;\n addElement: (\n kind: string,\n at: [number, number],\n extra?: Partial<Element>,\n ) => ElementId;\n addBus: (\n at: [number, number],\n span: number,\n rot?: 0 | 90 | 180 | 270,\n ) => BusId;\n /** Append a wire between two endpoints (idempotent — duplicate is a no-op). */\n addWire: (a: WireEnd, b: WireEnd) => void;\n updateElement: (id: ElementId, patch: Partial<Element>) => void;\n updatePlacement: (id: ElementId, patch: Partial<Placement>) => void;\n updateBus: (id: BusId, patch: Partial<BusLayout>) => void;\n addAnnotation: (at: [number, number], text?: string) => AnnotationId;\n updateAnnotation: (id: AnnotationId, patch: Partial<TextAnnotation>) => void;\n deleteAnnotation: (id: AnnotationId) => void;\n}\n\nexport const useEditorStore = create<EditorState>()(\n persist(\n (set, get) => ({\n diagram: EMPTY_DIAGRAM,\n internal: compile(EMPTY_DIAGRAM),\n fileSession: null,\n\n activeTool: defaultTool(),\n placeKind: null,\n lastPlaceKind: null,\n wireFromTerminal: null,\n placeFromTerminal: null,\n busbarDrawStart: null,\n cursorSvg: null,\n selection: [],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n editingAnnotation: null,\n editingElement: null,\n\n past: [],\n future: [],\n\n clipboard: null,\n clipboardPasteIndex: 0,\n\n setDiagram: (diagram) =>\n set({\n diagram,\n internal: compile(diagram),\n past: [],\n future: [],\n selection: [],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n editingAnnotation: null,\n editingElement: null,\n wireFromTerminal: null,\n placeFromTerminal: null,\n }),\n\n setFileSession: (fileSession) => set({ fileSession }),\n\n loadDiagramFromFile: (diagram, fileSession) =>\n set({\n diagram,\n internal: compile(diagram),\n fileSession,\n past: [],\n future: [],\n selection: [],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n editingAnnotation: null,\n editingElement: null,\n wireFromTerminal: null,\n placeFromTerminal: null,\n }),\n\n dispatch: (mutator) => {\n const { diagram, past } = get();\n const next = mutator(diagram);\n if (next === diagram) return;\n const trimmed = past.length >= HISTORY_LIMIT ? past.slice(1) : past;\n set({\n diagram: next,\n internal: compile(next),\n past: [...trimmed, diagram],\n future: [],\n });\n },\n\n undo: () => {\n const { past, future, diagram } = get();\n if (past.length === 0) return;\n const prev = past[past.length - 1];\n set({\n diagram: prev,\n internal: compile(prev),\n past: past.slice(0, -1),\n future: [...future, diagram],\n wireFromTerminal: null,\n placeFromTerminal: null,\n });\n },\n\n redo: () => {\n const { past, future, diagram } = get();\n if (future.length === 0) return;\n const next = future[future.length - 1];\n set({\n diagram: next,\n internal: compile(next),\n past: [...past, diagram],\n future: future.slice(0, -1),\n wireFromTerminal: null,\n placeFromTerminal: null,\n });\n },\n\n setActiveTool: (tool, opts) => {\n const cur = get();\n let placeKind: string | null;\n if (opts?.placeKind !== undefined) placeKind = opts.placeKind;\n else if (tool === 'place') placeKind = cur.placeKind ?? cur.lastPlaceKind;\n else placeKind = null;\n set({\n activeTool: tool,\n placeKind,\n lastPlaceKind: placeKind ?? cur.lastPlaceKind,\n wireFromTerminal: tool === 'wire' ? cur.wireFromTerminal : null,\n placeFromTerminal: tool === 'place' ? cur.placeFromTerminal : null,\n });\n },\n setPlaceKind: (kind) =>\n set((s) => ({\n placeKind: kind,\n lastPlaceKind: kind ?? s.lastPlaceKind,\n })),\n setWireFromTerminal: (ref) => set({ wireFromTerminal: ref }),\n setPlaceFromTerminal: (ref) => set({ placeFromTerminal: ref }),\n setBusbarDrawStart: (pt) => set({ busbarDrawStart: pt }),\n setCursorSvg: (pt) => set({ cursorSvg: pt }),\n\n setSelection: (ids) =>\n set({\n selection: dedupe(ids),\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: ids.length ? null : get().selectedAnnotation,\n }),\n toggleInSelection: (id) => {\n const sel = get().selection;\n set({\n selection: sel.includes(id) ? sel.filter((x) => x !== id) : [...sel, id],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n });\n },\n clearSelection: () =>\n set({\n selection: [],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n editingAnnotation: null,\n editingElement: null,\n }),\n setSelectedWire: (id) =>\n set({\n selectedWire: id,\n selection: id ? [] : get().selection,\n selectedNode: null,\n selectedAnnotation: id ? null : get().selectedAnnotation,\n }),\n setSelectedNode: (nodeId) =>\n set({\n selectedNode: nodeId,\n selection: nodeId ? [] : get().selection,\n selectedWire: null,\n selectedAnnotation: nodeId ? null : get().selectedAnnotation,\n }),\n setSelectedAnnotation: (id) =>\n set({\n selectedAnnotation: id,\n selection: id ? [] : get().selection,\n selectedWire: id ? null : get().selectedWire,\n selectedNode: id ? null : get().selectedNode,\n editingAnnotation: id ? get().editingAnnotation : null,\n }),\n setEditingAnnotation: (id) =>\n set({\n editingAnnotation: id,\n selectedAnnotation: id ?? get().selectedAnnotation,\n editingElement: id ? null : get().editingElement,\n }),\n setEditingElement: (id) =>\n set({\n editingElement: id,\n selection: id ? [id] : get().selection,\n editingAnnotation: id ? null : get().editingAnnotation,\n selectedAnnotation: id ? null : get().selectedAnnotation,\n selectedWire: id ? null : get().selectedWire,\n selectedNode: id ? null : get().selectedNode,\n }),\n\n copySelection: () => {\n const { selection, diagram, internal } = get();\n if (selection.length === 0) return;\n const sel = new Set(selection);\n\n const elements = diagram.elements\n .filter((e) => sel.has(e.id))\n .map((e) => structuredClone(e));\n\n const buses = (diagram.buses ?? [])\n .filter((b) => sel.has(b.id))\n .map((b) => structuredClone(b));\n\n const placements: Record<ElementId, Placement> = {};\n for (const id of selection) {\n if (sel.has(id) && !internal.buses.has(id)) {\n const explicit = diagram.layout?.[id];\n if (explicit) {\n placements[id] = structuredClone(explicit);\n continue;\n }\n const resolved = internal.layout.get(id);\n if (resolved) placements[id] = compactPlacement(resolved);\n }\n }\n\n const busLayouts: Record<BusId, BusLayout> = {};\n for (const id of selection) {\n const rb = internal.buses.get(id);\n if (!rb) continue;\n busLayouts[id] = compactBusLayout(rb.geometry);\n }\n\n const wires = (diagram.wires ?? [])\n .filter((w) =>\n w.ends.every((e) => sel.has(endOwner(e))),\n )\n .map((w) => structuredClone(w));\n\n set({\n clipboard: { elements, buses, placements, busLayouts, wires },\n clipboardPasteIndex: 0,\n });\n },\n\n cutSelection: () => {\n const { selection } = get();\n if (selection.length === 0) return;\n get().copySelection();\n get().deleteSelection();\n },\n\n pasteClipboard: () => {\n const { clipboard, clipboardPasteIndex, diagram } = get();\n if (!clipboard) return;\n if (clipboard.elements.length === 0 && clipboard.buses.length === 0) return;\n const step = clipboardPasteIndex + 1;\n const dx = PASTE_OFFSET * step;\n const dy = PASTE_OFFSET * step;\n\n const idMap = new Map<ElementId, ElementId>();\n let working = diagram;\n for (const el of clipboard.elements) {\n const newId = newElementId(working, el.kind);\n idMap.set(el.id, newId);\n working = {\n ...working,\n elements: [...working.elements, { id: newId, kind: el.kind }],\n };\n }\n for (const bus of clipboard.buses) {\n const newId = newBusId(working);\n idMap.set(bus.id, newId);\n working = {\n ...working,\n buses: [...(working.buses ?? []), { id: newId }],\n };\n }\n\n const remapEnd = (end: WireEnd): WireEnd => {\n const dot = end.indexOf('.');\n const head = dot < 0 ? end : end.slice(0, dot);\n const remapped = idMap.get(head);\n if (!remapped) return end;\n return (dot < 0 ? remapped : `${remapped}${end.slice(dot)}`) as WireEnd;\n };\n\n get().dispatch((d) => {\n const newElements: Element[] = clipboard.elements.map((e) => {\n const cloned = structuredClone(e);\n cloned.id = idMap.get(e.id)!;\n return cloned;\n });\n\n const newBuses: Bus[] = clipboard.buses.map((b) => {\n const cloned = structuredClone(b);\n cloned.id = idMap.get(b.id)!;\n const layout = clipboard.busLayouts[b.id];\n if (layout) {\n cloned.layout = {\n ...layout,\n at: [layout.at[0] + dx, layout.at[1] + dy],\n };\n }\n return cloned;\n });\n\n const newLayout: Record<ElementId, Placement> = { ...(d.layout ?? {}) };\n for (const [oldId, newId] of idMap) {\n const p = clipboard.placements[oldId];\n if (!p) continue;\n newLayout[newId] = {\n ...p,\n at: [p.at[0] + dx, p.at[1] + dy],\n };\n }\n\n const newWires: Wire[] = clipboard.wires.map((w) => {\n const ends: [WireEnd, WireEnd] = [\n remapEnd(w.ends[0]),\n remapEnd(w.ends[1]),\n ];\n return { id: wireIdFromEnds(ends[0], ends[1]), ends };\n });\n\n const wires = mergeWires(d.wires ?? [], newWires);\n\n return {\n ...d,\n elements: [...d.elements, ...newElements],\n buses: newBuses.length\n ? [...(d.buses ?? []), ...newBuses]\n : d.buses,\n wires: wires.length ? wires : undefined,\n layout: Object.keys(newLayout).length ? newLayout : undefined,\n };\n });\n\n set({\n selection: Array.from(idMap.values()),\n clipboardPasteIndex: step,\n });\n },\n\n autoArrangeAll: () => {\n get().dispatch((d) => {\n const hasDeviceLayout = d.layout && Object.keys(d.layout).length > 0;\n const hasBusLayout = (d.buses ?? []).some((b) => b.layout);\n if (!hasDeviceLayout && !hasBusLayout) return d;\n const { layout: _layout, ...rest } = d;\n void _layout;\n const buses = d.buses?.map((b) => {\n const { layout: _bl, ...bRest } = b;\n void _bl;\n return bRest;\n });\n return { ...rest, buses };\n });\n },\n\n autoArrangeSelection: () => {\n const { selection } = get();\n if (selection.length === 0) return;\n const drop = new Set(selection);\n get().dispatch((d) => {\n let changed = false;\n let layout = d.layout;\n if (layout) {\n const next: Record<ElementId, Placement> = {};\n for (const [id, p] of Object.entries(layout)) {\n if (drop.has(id)) {\n changed = true;\n continue;\n }\n next[id] = p;\n }\n if (changed) layout = Object.keys(next).length ? next : undefined;\n }\n let buses = d.buses;\n if (buses) {\n const next = buses.map((b) => {\n if (drop.has(b.id) && b.layout) {\n changed = true;\n const { layout: _bl, ...rest } = b;\n void _bl;\n return rest;\n }\n return b;\n });\n if (changed) buses = next;\n }\n if (!changed) return d;\n return { ...d, layout, buses };\n });\n },\n\n fillUnplacedAll: () => {\n const internal = get().internal;\n get().dispatch((d) => {\n const explicit = d.layout ?? {};\n const additions: Record<ElementId, Placement> = {};\n for (const el of d.elements) {\n if (explicit[el.id]) continue;\n const resolved = internal.layout.get(el.id);\n if (resolved) additions[el.id] = compactPlacement(resolved);\n }\n const busesNeedLayout: { idx: number; bus: Bus }[] = [];\n (d.buses ?? []).forEach((b, idx) => {\n if (b.layout) return;\n if (internal.buses.has(b.id)) busesNeedLayout.push({ idx, bus: b });\n });\n if (\n Object.keys(additions).length === 0 &&\n busesNeedLayout.length === 0\n ) {\n return d;\n }\n let buses = d.buses;\n if (busesNeedLayout.length > 0 && buses) {\n buses = buses.map((b) => {\n const rb = internal.buses.get(b.id);\n if (!b.layout && rb) {\n return { ...b, layout: compactBusLayout(rb.geometry) };\n }\n return b;\n });\n }\n return {\n ...d,\n layout: { ...explicit, ...additions },\n buses,\n };\n });\n },\n\n fillUnplacedSelection: () => {\n const { selection, internal } = get();\n if (selection.length === 0) return;\n get().dispatch((d) => {\n const explicit = d.layout ?? {};\n const additions: Record<ElementId, Placement> = {};\n const busesPatch = new Map<BusId, BusLayout>();\n for (const id of selection) {\n if (internal.buses.has(id)) {\n const rb = internal.buses.get(id)!;\n if (!d.buses?.find((b) => b.id === id && b.layout)) {\n busesPatch.set(id, compactBusLayout(rb.geometry));\n }\n } else {\n if (explicit[id]) continue;\n const resolved = internal.layout.get(id);\n if (resolved) additions[id] = compactPlacement(resolved);\n }\n }\n if (Object.keys(additions).length === 0 && busesPatch.size === 0) {\n return d;\n }\n let buses = d.buses;\n if (busesPatch.size > 0 && buses) {\n buses = buses.map((b) =>\n busesPatch.has(b.id) ? { ...b, layout: busesPatch.get(b.id)! } : b,\n );\n }\n return {\n ...d,\n layout: { ...explicit, ...additions },\n buses,\n };\n });\n },\n\n moveElements: (deltas) => {\n if (deltas.size === 0) return;\n const internal = get().internal;\n get().dispatch((d) => {\n const layout = { ...(d.layout ?? {}) };\n const busPatches = new Map<BusId, [number, number]>();\n for (const [id, delta] of deltas) {\n if (internal.buses.has(id)) {\n busPatches.set(id, delta);\n continue;\n }\n const resolved = internal.layout.get(id);\n const base: Placement =\n layout[id] ?? (resolved ? compactPlacement(resolved) : { at: [0, 0] });\n layout[id] = {\n ...base,\n at: [base.at[0] + delta[0], base.at[1] + delta[1]],\n };\n }\n let buses = d.buses;\n if (busPatches.size > 0) {\n buses = (d.buses ?? []).map((b) => {\n const delta = busPatches.get(b.id);\n if (!delta) return b;\n const cur =\n b.layout ?? compactBusLayout(internal.buses.get(b.id)!.geometry);\n return {\n ...b,\n layout: {\n ...cur,\n at: [cur.at[0] + delta[0], cur.at[1] + delta[1]],\n },\n };\n });\n }\n return { ...d, layout, buses };\n });\n },\n\n deleteSelection: () => {\n const { selection } = get();\n if (selection.length === 0) return;\n const ids = new Set(selection);\n get().dispatch((d) => {\n const elements = d.elements.filter((e) => !ids.has(e.id));\n const buses = (d.buses ?? []).filter((b) => !ids.has(b.id));\n const wires = (d.wires ?? []).filter(\n (w) => !ids.has(endOwner(w.ends[0])) && !ids.has(endOwner(w.ends[1])),\n );\n const layout = d.layout\n ? Object.fromEntries(\n Object.entries(d.layout).filter(([k]) => !ids.has(k)),\n )\n : undefined;\n return {\n ...d,\n elements,\n buses: buses.length ? buses : undefined,\n wires: wires.length ? wires : undefined,\n layout: layout && Object.keys(layout).length ? layout : undefined,\n };\n });\n set({ selection: [] });\n },\n\n deleteSelectedWire: () => {\n const { selectedWire } = get();\n if (!selectedWire) return;\n get().dispatch((d) => {\n const wires = (d.wires ?? []).filter((w) => w.id !== selectedWire);\n if (wires.length === (d.wires ?? []).length) return d;\n return {\n ...d,\n wires: wires.length ? wires : undefined,\n };\n });\n set({ selectedWire: null });\n },\n\n deleteSelectedNode: () => {\n const { selectedNode, internal } = get();\n if (!selectedNode) return;\n const node = internal.nodes.get(selectedNode);\n if (!node) return;\n const memberSet = new Set<WireEnd>(node.terminals);\n\n const affectedElementIds = new Set<ElementId>();\n for (const end of node.terminals) {\n const dot = end.indexOf('.');\n if (dot > 0) affectedElementIds.add(end.slice(0, dot));\n }\n\n get().dispatch((d) => {\n const layout = { ...(d.layout ?? {}) };\n for (const id of affectedElementIds) {\n if (layout[id]) continue;\n const resolved = internal.layout.get(id);\n if (!resolved) continue;\n const placement: Placement = { at: resolved.at };\n if (resolved.rot) placement.rot = resolved.rot;\n if (resolved.mirror) placement.mirror = resolved.mirror;\n layout[id] = placement;\n }\n\n const wires = (d.wires ?? []).filter(\n (w) => !memberSet.has(w.ends[0]) && !memberSet.has(w.ends[1]),\n );\n return {\n ...d,\n wires: wires.length ? wires : undefined,\n layout: Object.keys(layout).length ? layout : undefined,\n };\n });\n set({ selectedNode: null });\n },\n\n rotateSelection: (deltaDegrees) => {\n const { selection, internal } = get();\n if (selection.length === 0) return;\n get().dispatch((d) => {\n const layout = { ...(d.layout ?? {}) };\n const busPatches = new Map<BusId, 0 | 90 | 180 | 270>();\n for (const id of selection) {\n if (internal.buses.has(id)) {\n const rb = internal.buses.get(id)!;\n const cur =\n d.buses?.find((b) => b.id === id)?.layout?.rot ?? rb.geometry.rot;\n const next = (((cur ?? 0) + deltaDegrees) % 360 + 360) % 360;\n busPatches.set(id, next as 0 | 90 | 180 | 270);\n continue;\n }\n const cur = layout[id] ?? { at: internal.layout.get(id)?.at ?? [0, 0] };\n const next = (((cur.rot ?? 0) + deltaDegrees) % 360 + 360) % 360;\n layout[id] = { ...cur, rot: next as 0 | 90 | 180 | 270 };\n }\n let buses = d.buses;\n if (busPatches.size > 0) {\n buses = (d.buses ?? []).map((b) => {\n if (!busPatches.has(b.id)) return b;\n const cur =\n b.layout ?? compactBusLayout(internal.buses.get(b.id)!.geometry);\n return { ...b, layout: { ...cur, rot: busPatches.get(b.id)! } };\n });\n }\n return { ...d, layout, buses };\n });\n },\n\n mirrorSelection: () => {\n const { selection, internal } = get();\n if (selection.length === 0) return;\n get().dispatch((d) => {\n const layout = { ...(d.layout ?? {}) };\n for (const id of selection) {\n if (internal.buses.has(id)) continue; // buses don't mirror\n const cur = layout[id] ?? { at: internal.layout.get(id)?.at ?? [0, 0] };\n layout[id] = { ...cur, mirror: !(cur.mirror ?? false) };\n }\n return { ...d, layout };\n });\n },\n\n addElement: (kind, at, extra) => {\n if (kind === 'busbar') {\n return get().addBus(at, 320);\n }\n const id = newElementId(get().diagram, kind);\n get().dispatch((d) => {\n const newElement: Element = { id, kind, ...(extra ?? {}) };\n return {\n ...d,\n elements: [...d.elements, newElement],\n layout: { ...(d.layout ?? {}), [id]: { at } },\n };\n });\n set({ selection: [id] });\n return id;\n },\n\n addBus: (at, span, rot) => {\n const id = newBusId(get().diagram);\n get().dispatch((d) => {\n const bus: Bus = {\n id,\n layout: rot !== undefined ? { at, span, rot } : { at, span },\n };\n return {\n ...d,\n buses: [...(d.buses ?? []), bus],\n };\n });\n set({ selection: [id] });\n return id;\n },\n\n addWire: (a, b) => {\n if (a === b) return;\n const id = wireIdFromEnds(a, b);\n get().dispatch((d) => {\n const existing = d.wires ?? [];\n if (existing.some((w) => w.id === id)) return d;\n return {\n ...d,\n wires: [...existing, { id, ends: [a, b] }],\n };\n });\n },\n\n updateElement: (id, patch) => {\n get().dispatch((d) => ({\n ...d,\n elements: d.elements.map((e) => (e.id === id ? { ...e, ...patch } : e)),\n }));\n },\n\n updatePlacement: (id, patch) => {\n get().dispatch((d) => {\n const cur = d.layout?.[id] ?? get().internal.layout.get(id);\n const nextPlacement: Placement = {\n at: patch.at ?? cur?.at ?? [0, 0],\n ...(patch.rot !== undefined ? { rot: patch.rot } : cur?.rot ? { rot: cur.rot } : {}),\n ...(patch.mirror !== undefined\n ? { mirror: patch.mirror }\n : cur?.mirror ? { mirror: cur.mirror } : {}),\n };\n return {\n ...d,\n layout: { ...(d.layout ?? {}), [id]: nextPlacement },\n };\n });\n },\n\n updateBus: (id, patch) => {\n get().dispatch((d) => {\n const buses = (d.buses ?? []).map((b) => {\n if (b.id !== id) return b;\n const internal = get().internal;\n const cur =\n b.layout ?? (internal.buses.has(id)\n ? compactBusLayout(internal.buses.get(id)!.geometry)\n : { at: [0, 0] as [number, number], span: 320 });\n const next: BusLayout = {\n at: patch.at ?? cur.at,\n span: patch.span ?? cur.span,\n ...(patch.rot !== undefined\n ? { rot: patch.rot }\n : cur.rot ? { rot: cur.rot } : {}),\n };\n return { ...b, layout: next };\n });\n return { ...d, buses };\n });\n },\n\n addAnnotation: (at, text = '') => {\n const id = newAnnotationId(get().diagram);\n get().dispatch((d) => {\n const ann: TextAnnotation = { id, at, text };\n return { ...d, annotations: [...(d.annotations ?? []), ann] };\n });\n return id;\n },\n updateAnnotation: (id, patch) => {\n get().dispatch((d) => {\n const list = d.annotations ?? [];\n let changed = false;\n const next = list.map((a) => {\n if (a.id !== id) return a;\n changed = true;\n return { ...a, ...patch, id: a.id };\n });\n if (!changed) return d;\n return { ...d, annotations: next };\n });\n },\n deleteAnnotation: (id) => {\n get().dispatch((d) => {\n const list = d.annotations ?? [];\n const next = list.filter((a) => a.id !== id);\n if (next.length === list.length) return d;\n return {\n ...d,\n annotations: next.length ? next : undefined,\n };\n });\n if (get().selectedAnnotation === id) {\n set({ selectedAnnotation: null, editingAnnotation: null });\n }\n },\n }),\n {\n name: 'ole-editor',\n version: 2,\n storage: createJSONStorage(() => localStorage),\n partialize: (s) => ({\n diagram: s.diagram,\n activeTool: s.activeTool,\n placeKind: s.placeKind,\n lastPlaceKind: s.lastPlaceKind,\n }),\n onRehydrateStorage: () => (state) => {\n if (state?.diagram) state.internal = compile(state.diagram);\n },\n },\n ),\n);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction dedupe<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n}\n\nfunction endOwner(end: WireEnd): ElementId {\n const dot = end.indexOf('.');\n return dot < 0 ? end : end.slice(0, dot);\n}\n\n/** Concatenate two wire lists, dropping duplicates (by content-hash id). */\nfunction mergeWires(a: Wire[], b: Wire[]): Wire[] {\n const seen = new Set<WireId>(a.map((w) => w.id));\n const out = a.slice();\n for (const w of b) {\n if (seen.has(w.id)) continue;\n seen.add(w.id);\n out.push(w);\n }\n return out;\n}\n\n/**\n * `ResolvedPlacement` always carries `rot`/`mirror` (with 0/false defaults).\n * `Placement` (the file format) omits defaults — keep diagram JSON tight and\n * round-trip-stable.\n */\nfunction compactPlacement(rp: ResolvedPlacement): Placement {\n return {\n at: [rp.at[0], rp.at[1]],\n ...(rp.rot ? { rot: rp.rot } : {}),\n ...(rp.mirror ? { mirror: rp.mirror } : {}),\n };\n}\n\nfunction compactBusLayout(g: BusGeometry): BusLayout {\n return {\n at: [g.at[0], g.at[1]],\n span: g.span,\n ...(g.rot ? { rot: g.rot } : {}),\n };\n}\n","/**\n * Module-level singleton for the active viewport API. `CanvasSvg` registers\n * itself on mount; chrome (e.g. `ViewToolbar`) reads via `getViewportApi()`\n * and calls imperatively. Pairs with `zoom-bus` (which carries reactive\n * scale notifications) — this one is for command dispatch, not subscription.\n */\n\nimport type { ViewportApi } from './useViewport';\n\nlet current: ViewportApi | null = null;\n\nexport function setViewportApi(api: ViewportApi | null): void {\n current = api;\n}\n\nexport function getViewportApi(): ViewportApi | null {\n return current;\n}\n","/**\n * Grid snap helpers. Snapping is bound to the visual grid: when the user\n * hides the grid (ViewToolbar / `G`), `.hide-grid` lands on the canvas\n * root and snap() returns the value untouched. So \"show grid\" and \"snap to\n * grid\" are one switch.\n *\n * Used by: SelectTool drag move, BusHandles span resize, drop-on-bus\n * placement, drag-drop from palette.\n */\n\nexport const GRID_SIZE = 10;\n\nexport function isSnapEnabled(): boolean {\n if (typeof document === 'undefined') return true;\n const root = document.querySelector('.ole-canvas-root');\n return !!root && !root.classList.contains('hide-grid');\n}\n\nexport function snap(v: number): number {\n return isSnapEnabled() ? Math.round(v / GRID_SIZE) * GRID_SIZE : v;\n}\n\nexport function snapPoint(p: [number, number]): [number, number] {\n return [snap(p[0]), snap(p[1])];\n}\n","/**\n * Drop / place near-a-bus auto-tap helper. When the user drops a palette item\n * within reach of an existing bus, attach the new element's \"tap-side\"\n * terminal to that bus via a `Wire` — instead of just dropping the element\n * in free space.\n *\n * Tap-side picking: the element's terminal closest to the bus axis (smallest\n * |y - bus.y| in canvas coords for horizontal buses), so the body extends\n * away from the bus naturally.\n */\n\nimport { libraryById } from '../element-library';\nimport type {\n BusId,\n DiagramFile,\n Element,\n ElementId,\n LibraryEntry,\n LibraryTerminal,\n Orientation,\n Placement,\n TerminalRef,\n Wire,\n WireEnd,\n} from '../model';\nimport { newElementId, useEditorStore, wireIdFromEnds } from '../store';\nimport { snap } from './grid';\n\nconst PROXIMITY_PX = 30;\nconst CLICK_SLOP_SQ = 12 * 12;\n\nexport interface DropResult {\n newElementId: ElementId;\n attachedToBus: boolean;\n}\n\nexport function dropElement(kind: string, at: [number, number]): DropResult {\n const lib = libraryById[kind];\n const store = useEditorStore.getState();\n const diagram = store.diagram;\n\n // Busbar drops are handled by BusbarTool directly. Bus-on-bus = nonsense.\n if (!lib || kind === 'busbar') {\n const id = store.addElement(kind, at);\n return { newElementId: id, attachedToBus: false };\n }\n\n const target = nearestBus(diagram, at);\n if (!target) {\n const cursorPin = pickPlaceCursorTerminal(lib);\n const placedAt: [number, number] = cursorPin\n ? [snap(at[0]) - cursorPin.x, snap(at[1]) - cursorPin.y]\n : [snap(at[0]), snap(at[1])];\n const id = store.addElement(kind, placedAt);\n return { newElementId: id, attachedToBus: false };\n }\n\n const { busId, busAt, axis } = target;\n const tapPin = pickTapTerminal(lib, axis);\n const newId = newElementId(diagram, kind);\n\n const tapLocal = lib.terminals.find((t) => t.id === tapPin);\n const dropX = axis === 'x' ? at[0] : busAt[0];\n const dropY = axis === 'y' ? at[1] : busAt[1];\n const placedAt: [number, number] = tapLocal\n ? [snap(dropX) - tapLocal.x, snap(dropY) - tapLocal.y]\n : [snap(at[0]), snap(at[1])];\n\n store.dispatch((d) => {\n const newElement: Element = { id: newId, kind };\n const placement: Placement = { at: placedAt };\n const newEnd = `${newId}.${tapPin}` as TerminalRef;\n const wire: Wire = {\n id: wireIdFromEnds(busId, newEnd),\n ends: [busId, newEnd],\n };\n return {\n ...d,\n elements: [...d.elements, newElement],\n wires: [...(d.wires ?? []), wire],\n layout: { ...(d.layout ?? {}), [newId]: placement },\n };\n });\n\n store.setSelection([newId]);\n return { newElementId: newId, attachedToBus: true };\n}\n\ninterface NearestBus {\n busId: BusId;\n busAt: [number, number];\n axis: 'x' | 'y';\n}\n\nfunction nearestBus(d: DiagramFile, at: [number, number]): NearestBus | null {\n const internal = useEditorStore.getState().internal;\n let best: NearestBus & { dist: number } | null = null;\n for (const bus of d.buses ?? []) {\n const rb = internal.buses.get(bus.id);\n if (!rb) continue;\n const { axis, at: busAt, span } = rb.geometry;\n let dist: number;\n if (axis === 'x') {\n const minX = busAt[0] - span / 2;\n const maxX = busAt[0] + span / 2;\n const dx = at[0] < minX ? minX - at[0] : at[0] > maxX ? at[0] - maxX : 0;\n const dy = Math.abs(at[1] - busAt[1]);\n dist = Math.sqrt(dx * dx + dy * dy);\n } else {\n const minY = busAt[1] - span / 2;\n const maxY = busAt[1] + span / 2;\n const dy = at[1] < minY ? minY - at[1] : at[1] > maxY ? at[1] - maxY : 0;\n const dx = Math.abs(at[0] - busAt[0]);\n dist = Math.sqrt(dx * dx + dy * dy);\n }\n if (dist <= PROXIMITY_PX && (!best || dist < best.dist)) {\n best = { busId: bus.id, busAt: [busAt[0], busAt[1]], axis, dist };\n }\n }\n if (!best) return null;\n return { busId: best.busId, busAt: best.busAt, axis: best.axis };\n}\n\nfunction pickTapTerminal(lib: LibraryEntry, busAxis: 'x' | 'y'): string {\n if (lib.terminals.length === 0) return 't';\n const sorted = [...lib.terminals].sort((a, b) =>\n busAxis === 'x' ? a.y - b.y : a.x - b.x,\n );\n return sorted[0].id;\n}\n\n/**\n * The library terminal that should sit at the cursor while a free placement\n * is in progress — same \"tap-side\" rule as `pickTapTerminal`, returned as a\n * full terminal so callers can offset placement (or the place ghost) so the\n * cursor visually holds that pin instead of the element's hotspot.\n *\n * Stretchable kinds don't have a meaningful tap; returns null and callers\n * use the element's hotspot.\n */\nexport function pickPlaceCursorTerminal(\n lib: LibraryEntry,\n): LibraryTerminal | null {\n if (!lib || lib.stretchable || lib.terminals.length === 0) return null;\n const sorted = [...lib.terminals].sort((a, b) => a.y - b.y);\n return sorted[0];\n}\n\n/**\n * Resolved place-source: world coords + orientation of the terminal we're\n * dragging from. Handles both real device terminals and a bare bus id\n * (projected onto the bus axis at the cursor point, with orientation flipped\n * to point toward the drag side so the new element body extends away).\n */\nexport interface PlaceSource {\n ref: WireEnd;\n world: [number, number];\n orientation: Orientation;\n /** True iff `ref` is a bus id (bare, no dot). */\n isBus: boolean;\n /** Set when isBus. */\n busId?: BusId;\n}\n\nexport function resolvePlaceSource(\n ref: WireEnd,\n cursorWorld: [number, number],\n): PlaceSource | null {\n const internal = useEditorStore.getState().internal;\n if (!ref.includes('.') && internal.buses.has(ref)) {\n const rb = internal.buses.get(ref)!;\n const { axis, at, span } = rb.geometry;\n if (axis === 'x') {\n const minX = at[0] - span / 2;\n const maxX = at[0] + span / 2;\n const x = Math.max(minX, Math.min(maxX, cursorWorld[0]));\n const y = at[1];\n const orientation: Orientation = cursorWorld[1] >= y ? 's' : 'n';\n return { ref, world: [x, y], orientation, isBus: true, busId: ref };\n }\n const minY = at[1] - span / 2;\n const maxY = at[1] + span / 2;\n const y = Math.max(minY, Math.min(maxY, cursorWorld[1]));\n const x = at[0];\n const orientation: Orientation = cursorWorld[0] >= x ? 'e' : 'w';\n return { ref, world: [x, y], orientation, isBus: true, busId: ref };\n }\n const term = internal.terminals.get(ref as `${string}.${string}`);\n if (term) {\n return {\n ref,\n world: term.world,\n orientation: term.orientation,\n isBus: false,\n };\n }\n return null;\n}\n\nconst OPPOSITE: Record<Orientation, Orientation> = {\n n: 's',\n s: 'n',\n e: 'w',\n w: 'e',\n};\n\n/**\n * Pick which terminal of the new element should connect to the source.\n * Prefer a terminal whose orientation is opposite to the source's (so the\n * body extends naturally *away* from the source). Tie-break by world\n * distance to source.\n */\nexport function pickConnectTerminal(\n lib: LibraryEntry,\n source: PlaceSource,\n placeAt: [number, number],\n): LibraryTerminal {\n if (lib.terminals.length === 0) {\n return { id: 't', x: 0, y: 0, orientation: 'n' };\n }\n const wantOrient = OPPOSITE[source.orientation];\n const opposites = lib.terminals.filter((t) => t.orientation === wantOrient);\n const pool = opposites.length > 0 ? opposites : lib.terminals;\n let best = pool[0];\n let bestDist = termWorldDist(best, placeAt, source.world);\n for (let i = 1; i < pool.length; i++) {\n const t = pool[i];\n const d = termWorldDist(t, placeAt, source.world);\n if (d < bestDist) {\n bestDist = d;\n best = t;\n }\n }\n return best;\n}\n\nfunction termWorldDist(\n t: LibraryTerminal,\n placeAt: [number, number],\n source: [number, number],\n): number {\n const dx = placeAt[0] + t.x - source[0];\n const dy = placeAt[1] + t.y - source[1];\n return dx * dx + dy * dy;\n}\n\n/**\n * Place a new element with one of its terminals connected to `sourceRef` in\n * a single undo step.\n */\nexport function dropElementFromTerminal(\n kind: string,\n sourceRef: WireEnd,\n cursorAt: [number, number],\n): DropResult | null {\n const lib = libraryById[kind];\n const store = useEditorStore.getState();\n const diagram = store.diagram;\n if (!lib) return null;\n\n const source = resolvePlaceSource(sourceRef, cursorAt);\n if (!source) return null;\n\n const dx = cursorAt[0] - source.world[0];\n const dy = cursorAt[1] - source.world[1];\n const treatAsClick = dx * dx + dy * dy <= CLICK_SLOP_SQ;\n const cursorPlaceAt: [number, number] = [snap(cursorAt[0]), snap(cursorAt[1])];\n const chosen = pickConnectTerminal(lib, source, cursorPlaceAt);\n // The chosen pin lands at the anchor — `source.world` for a tap (so the\n // pin meets the source terminal) or the cursor for a drag (so the visible\n // PlaceGhost, which already anchors the chosen pin to the cursor, matches\n // where the element actually lands).\n const anchor = treatAsClick ? source.world : cursorPlaceAt;\n const placedAt: [number, number] = [\n snap(anchor[0] - chosen.x),\n snap(anchor[1] - chosen.y),\n ];\n const newId = newElementId(diagram, kind);\n\n store.dispatch((d) => {\n const newElement: Element = { id: newId, kind };\n const placement: Placement = { at: placedAt };\n const newPinRef = `${newId}.${chosen.id}` as TerminalRef;\n const tieEnd: WireEnd = source.isBus && source.busId ? source.busId : sourceRef;\n const wire: Wire = {\n id: wireIdFromEnds(tieEnd, newPinRef),\n ends: [tieEnd, newPinRef],\n };\n return {\n ...d,\n elements: [...d.elements, newElement],\n wires: [...(d.wires ?? []), wire],\n layout: { ...(d.layout ?? {}), [newId]: placement },\n };\n });\n\n store.setSelection([newId]);\n return { newElementId: newId, attachedToBus: source.isBus };\n}\n","/**\n * Renders structural labels (element ID + showOnCanvas params) next to each\n * element. Labels are derived purely from `Element` data and the library\n * schema — they do not live in the diagram's serialized form.\n *\n * The label block is positioned at the world projection of the element's\n * `LibraryEntry.label` anchor (or a viewBox-derived fallback). Element\n * rotation moves the anchor accordingly, but the text itself is rendered\n * upright (no rotate on the text group) so labels stay readable.\n *\n * Visibility is governed by `DiagramFile.meta.labelMode`:\n * - 'off' → no labels.\n * - 'id' → element name/ID only.\n * - 'all' → ID plus each library param marked `showOnCanvas: true`.\n * Default when unset: 'all'.\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useEditorStore } from '../store';\nimport type {\n LabelMode,\n LibraryEntry,\n LibraryLabelAnchor,\n} from '../model';\nimport type { ResolvedElement, ResolvedPlacement } from '../compiler';\n\nconst LINE_HEIGHT = 9;\n\nexport function AnnotationLayer() {\n const elements = useEditorStore((s) => s.internal.elements);\n const layout = useEditorStore((s) => s.internal.layout);\n const mode: LabelMode = useEditorStore(\n (s) => s.diagram.meta?.labelMode ?? 'all',\n );\n const editingElement = useEditorStore((s) => s.editingElement);\n\n return (\n <g className=\"ole-annotation-layer\" pointerEvents=\"none\">\n {Array.from(elements.values()).map((re) => {\n const place = layout.get(re.element.id);\n if (!place || !re.libraryDef) return null;\n const anchor = re.libraryDef.label ?? fallbackAnchor(re.libraryDef);\n const world = anchorWorld(anchor, place, re.libraryDef);\n const textAnchor = anchor.anchor ?? 'start';\n if (editingElement === re.element.id) {\n return (\n <NameEditor\n key={re.element.id}\n elementId={re.element.id}\n currentName={re.element.name?.trim() || re.element.id}\n world={world}\n anchor={textAnchor}\n />\n );\n }\n if (mode === 'off') return null;\n const lines = labelLines(re, mode);\n if (lines.length === 0) return null;\n return (\n <g\n key={re.element.id}\n className=\"ole-annotation\"\n transform={`translate(${world[0]} ${world[1]})`}\n >\n {lines.map((line, i) => (\n <text\n key={i}\n x={0}\n y={i * LINE_HEIGHT}\n textAnchor={textAnchor}\n className=\"ole-annotation-text\"\n >\n {line}\n </text>\n ))}\n </g>\n );\n })}\n </g>\n );\n}\n\nconst EDITOR_W = 200;\nconst EDITOR_FS = 9;\n\n/**\n * In-place editor for an element's `name`. Mounted at the same anchor as\n * the structural label so the inline edit happens where the user expects\n * to see the name. Empty content clears the override (label falls back to\n * the element's ID); non-empty content sets `Element.name`.\n */\nfunction NameEditor({\n elementId,\n currentName,\n world,\n anchor,\n}: {\n elementId: string;\n currentName: string;\n world: [number, number];\n anchor: 'start' | 'middle' | 'end';\n}) {\n const ref = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n el.focus();\n const range = document.createRange();\n range.selectNodeContents(el);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n }, [elementId]);\n\n function commit(): void {\n const store = useEditorStore.getState();\n const el = store.diagram.elements.find((x) => x.id === elementId);\n if (!el) {\n store.setEditingElement(null);\n return;\n }\n const text = (ref.current?.innerText ?? '').replace(/\\u00a0/g, ' ').trim();\n // Empty text clears the override; the structural label falls back to ID.\n const next = text === '' || text === elementId ? undefined : text;\n if (next !== el.name) store.updateElement(elementId, { name: next });\n store.setEditingElement(null);\n }\n\n function onKeyDown(e: React.KeyboardEvent<HTMLDivElement>): void {\n if (e.key === 'Escape' || (e.key === 'Enter' && !e.shiftKey)) {\n e.preventDefault();\n commit();\n return;\n }\n e.stopPropagation();\n }\n\n // Position the foreignObject so the contentEditable's left edge matches\n // the requested SVG text-anchor — text-anchor is glyph-relative, but our\n // editor is a div without that semantic, so we translate by hand.\n let x = world[0];\n if (anchor === 'middle') x -= EDITOR_W / 2;\n else if (anchor === 'end') x -= EDITOR_W;\n\n return (\n <foreignObject\n x={x}\n y={world[1] - EDITOR_FS}\n width={EDITOR_W}\n height={EDITOR_FS * 2.2}\n className=\"ole-element-name-editor\"\n >\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={commit}\n onKeyDown={onKeyDown}\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n style={{\n fontSize: `${EDITOR_FS}px`,\n fontFamily: 'ui-sans-serif, system-ui, sans-serif',\n color: 'var(--foreground)',\n background: 'var(--canvas-bg)',\n outline: '1px dashed var(--selection)',\n padding: '0 2px',\n display: 'inline-block',\n minWidth: '20px',\n lineHeight: 1.1,\n textAlign:\n anchor === 'middle' ? 'center' : anchor === 'end' ? 'right' : 'left',\n whiteSpace: 'nowrap',\n cursor: 'text',\n }}\n >\n {currentName}\n </div>\n </foreignObject>\n );\n}\n\nfunction labelLines(re: ResolvedElement, mode: LabelMode): string[] {\n const lines: string[] = [];\n const head = re.element.name?.trim() || re.element.id;\n if (head) lines.push(head);\n if (mode !== 'all' || !re.libraryDef?.params) return lines;\n const params = re.element.params ?? {};\n for (const p of re.libraryDef.params) {\n if (!p.showOnCanvas) continue;\n const v = params[p.name];\n if (v === undefined || v === null || v === '') continue;\n lines.push(`${v}${p.unit ?? ''}`);\n }\n return lines;\n}\n\nfunction fallbackAnchor(lib: LibraryEntry): LibraryLabelAnchor {\n const vb = parseViewBox(lib.viewBox);\n if (!vb) return { x: 0, y: 0, anchor: 'start' };\n return { x: vb.x + vb.w + 2, y: vb.y + 4, anchor: 'start' };\n}\n\nfunction parseViewBox(s: string): { x: number; y: number; w: number; h: number } | null {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n\n/**\n * Project an element-local point through the element's placement transform —\n * matches `transformAttr`'s composition (stretch → mirror → rotate → translate)\n * but yields a single world coordinate so the label can be rendered without\n * inheriting the element's rotation.\n */\nfunction anchorWorld(\n anchor: LibraryLabelAnchor,\n place: ResolvedPlacement,\n _lib: LibraryEntry,\n): [number, number] {\n let x = anchor.x;\n let y = anchor.y;\n\n // Mirror flips local x.\n if (place.mirror) x = -x;\n // Rotation (90° steps).\n switch (place.rot) {\n case 90:\n [x, y] = [-y, x];\n break;\n case 180:\n [x, y] = [-x, -y];\n break;\n case 270:\n [x, y] = [y, -x];\n break;\n default:\n break;\n }\n return [x + place.at[0], y + place.at[1]];\n}\n","/**\n * Renders user-created free text annotations from `diagram.annotations`.\n * Each annotation is a draggable, editable note unattached to any element.\n *\n * Three render states per annotation:\n * 1. Idle → `<text>` painted at its position.\n * 2. Selected (idle) → text plus a dashed bbox halo (matches element halo).\n * 3. Editing → `<foreignObject>` hosting a contentEditable div;\n * autoselects content on entry, commits on Enter or\n * blur, drops empty content on commit (auto-cleanup\n * of empty annotations created by the text tool).\n *\n * Hit-testing carries the annotation's id via `data-annotation-id` so tools\n * can route the gesture without React state lookups, mirroring how elements\n * use `data-element-id`.\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useEditorStore } from '../store';\nimport type { TextAnnotation } from '../model';\n\nconst DEFAULT_FONT_SIZE = 8;\nconst LINE_HEIGHT = 1.25;\n\nexport function FreeAnnotationLayer() {\n const annotations = useEditorStore((s) => s.diagram.annotations);\n const selected = useEditorStore((s) => s.selectedAnnotation);\n const editing = useEditorStore((s) => s.editingAnnotation);\n\n if (!annotations || annotations.length === 0) return null;\n\n return (\n <g className=\"ole-free-annotation-layer\">\n {annotations.map((a) =>\n editing === a.id ? (\n <EditingAnnotation key={a.id} ann={a} />\n ) : (\n <IdleAnnotation\n key={a.id}\n ann={a}\n isSelected={selected === a.id}\n />\n ),\n )}\n </g>\n );\n}\n\nfunction IdleAnnotation({\n ann,\n isSelected,\n}: {\n ann: TextAnnotation;\n isSelected: boolean;\n}) {\n const fs = ann.fontSize ?? DEFAULT_FONT_SIZE;\n const lines = ann.text === '' ? [''] : ann.text.split('\\n');\n // Reasonable bbox estimate purely for the selection halo. Width is heuristic\n // (avg ~0.55 em per char); the actual click hit is on the text glyphs.\n const widthGuess = Math.max(\n 20,\n ...lines.map((l) => l.length * fs * 0.55),\n );\n const heightGuess = lines.length * fs * LINE_HEIGHT;\n return (\n <g\n data-annotation-id={ann.id}\n className=\"ole-free-annotation\"\n data-selected={isSelected ? 'true' : undefined}\n >\n {/* Invisible hit-rect for easier dragging on whitespace within the text block. */}\n <rect\n x={ann.at[0] - 1}\n y={ann.at[1] - 1}\n width={widthGuess + 2}\n height={heightGuess + 2}\n fill=\"transparent\"\n className=\"ole-free-annotation-hit\"\n />\n {isSelected && (\n <rect\n x={ann.at[0] - 1}\n y={ann.at[1] - 1}\n width={widthGuess + 2}\n height={heightGuess + 2}\n className=\"ole-free-annotation-halo\"\n />\n )}\n {lines.map((line, i) => (\n <text\n key={i}\n x={ann.at[0]}\n y={ann.at[1] + fs * 0.85 + i * fs * LINE_HEIGHT}\n fontSize={fs}\n className=\"ole-free-annotation-text\"\n >\n {line}\n </text>\n ))}\n </g>\n );\n}\n\nfunction EditingAnnotation({ ann }: { ann: TextAnnotation }) {\n const ref = useRef<HTMLDivElement | null>(null);\n const fs = ann.fontSize ?? DEFAULT_FONT_SIZE;\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n el.focus();\n // Place caret at end and select-all so users can immediately type to\n // replace placeholder content (matches Figma / Keynote text-tool flow).\n const range = document.createRange();\n range.selectNodeContents(el);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n }, [ann.id]);\n\n function commit(): void {\n const store = useEditorStore.getState();\n const text = (ref.current?.innerText ?? '').replace(/\\u00a0/g, ' ').trimEnd();\n if (text === '') {\n store.deleteAnnotation(ann.id);\n } else if (text !== ann.text) {\n store.updateAnnotation(ann.id, { text });\n }\n store.setEditingAnnotation(null);\n if (text !== '') store.setSelectedAnnotation(ann.id);\n // Hand control back to the select tool — text mode is for one-off drops.\n if (store.activeTool === 'text') store.setActiveTool('select');\n }\n\n function onKeyDown(e: React.KeyboardEvent<HTMLDivElement>): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n commit();\n return;\n }\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n commit();\n return;\n }\n // Keep typing keys from leaking to global hotkeys (e.g. Delete deleting\n // the selection while the user is editing text).\n e.stopPropagation();\n }\n\n // foreignObject must be sized in canvas units; pick a generous box so the\n // editor can grow without clipping.\n const W = 320;\n const H = 200;\n return (\n <foreignObject\n x={ann.at[0]}\n y={ann.at[1]}\n width={W}\n height={H}\n data-annotation-id={ann.id}\n className=\"ole-free-annotation-edit-fo\"\n >\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={commit}\n onKeyDown={onKeyDown}\n // The pointer events handler in useTools captures pointerdown on the\n // host before this; stop it here so clicks inside the editor don't\n // commit and re-enter unexpectedly.\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n style={{\n fontSize: `${fs}px`,\n lineHeight: LINE_HEIGHT,\n fontFamily: 'ui-sans-serif, system-ui, sans-serif',\n color: 'var(--foreground)',\n background: 'var(--canvas-bg)',\n outline: '1px dashed var(--selection)',\n padding: '0 2px',\n minWidth: `${fs}px`,\n minHeight: `${fs * LINE_HEIGHT}px`,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n cursor: 'text',\n }}\n >\n {ann.text}\n </div>\n </foreignObject>\n );\n}\n","/**\n * Stretch handles for the selected bus. Two `<circle>` grips at the bus's\n * endpoints. Dragging a grip updates the bus's `span`, and — for the\n * trailing grip — shifts `at` so the opposite end stays fixed visually.\n *\n * Handles capture pointer events themselves; SelectTool sees the drag start\n * on a non-element target and won't try to also move the bus body.\n */\n\nimport { useRef } from 'react';\nimport { useEditorStore } from '../store';\nimport type { BusId } from '../model';\nimport { getViewportApi } from './viewport-bus';\nimport { isSnapEnabled, GRID_SIZE } from './grid';\n\nconst MIN_SPAN = 20;\n\nexport function BusHandles() {\n const selection = useEditorStore((s) => s.selection);\n const internal = useEditorStore((s) => s.internal);\n\n if (selection.length !== 1) return null;\n const id = selection[0];\n const rb = internal.buses.get(id);\n if (!rb) return null;\n\n const { axis, at, span } = rb.geometry;\n const half = span / 2;\n const startWorld: [number, number] =\n axis === 'x' ? [at[0] - half, at[1]] : [at[0], at[1] - half];\n const endWorld: [number, number] =\n axis === 'x' ? [at[0] + half, at[1]] : [at[0], at[1] + half];\n\n return (\n <g className=\"ole-bus-handles\" pointerEvents=\"auto\">\n <Handle\n x={startWorld[0]}\n y={startWorld[1]}\n busId={id}\n side=\"start\"\n axis={axis}\n />\n <Handle\n x={endWorld[0]}\n y={endWorld[1]}\n busId={id}\n side=\"end\"\n axis={axis}\n />\n </g>\n );\n}\n\nfunction Handle({\n x,\n y,\n busId,\n side,\n axis,\n}: {\n x: number;\n y: number;\n busId: BusId;\n side: 'start' | 'end';\n axis: 'x' | 'y';\n}) {\n const viewport = getViewportApi();\n const dragRef = useRef<{\n pointerId: number;\n startSpan: number;\n startAt: [number, number];\n startSvg: [number, number];\n } | null>(null);\n\n const onPointerDown = (e: React.PointerEvent<SVGCircleElement>) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n if (!viewport) return;\n const rb = useEditorStore.getState().internal.buses.get(busId);\n if (!rb) return;\n dragRef.current = {\n pointerId: e.pointerId,\n startSpan: rb.geometry.span,\n startAt: [...rb.geometry.at],\n startSvg: viewport.screenToSvg(e.clientX, e.clientY),\n };\n (e.target as SVGCircleElement).setPointerCapture(e.pointerId);\n };\n\n const onPointerMove = (e: React.PointerEvent<SVGCircleElement>) => {\n const drag = dragRef.current;\n if (!drag || e.pointerId !== drag.pointerId || !viewport) return;\n const cur = viewport.screenToSvg(e.clientX, e.clientY);\n const dRaw = axis === 'x' ? cur[0] - drag.startSvg[0] : cur[1] - drag.startSvg[1];\n const d = isSnapEnabled() ? Math.round(dRaw / GRID_SIZE) * GRID_SIZE : dRaw;\n\n const span = drag.startSpan + (side === 'end' ? d : -d);\n if (span < MIN_SPAN) return;\n const at: [number, number] =\n axis === 'x'\n ? [drag.startAt[0] + d / 2, drag.startAt[1]]\n : [drag.startAt[0], drag.startAt[1] + d / 2];\n\n useEditorStore.getState().updateBus(busId, { span, at });\n };\n\n const onPointerUp = (e: React.PointerEvent<SVGCircleElement>) => {\n const drag = dragRef.current;\n if (!drag || e.pointerId !== drag.pointerId) return;\n if ((e.target as SVGCircleElement).hasPointerCapture(e.pointerId)) {\n (e.target as SVGCircleElement).releasePointerCapture(e.pointerId);\n }\n dragRef.current = null;\n };\n\n return (\n <circle\n className=\"ole-bus-handle\"\n cx={x}\n cy={y}\n r={5}\n data-handle={side}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n />\n );\n}\n","/**\n * Renders one `<g>` per bus. Each bus is a horizontal or vertical line\n * segment whose length is `geometry.span` and direction is given by\n * `geometry.axis` (x → horizontal, y → vertical). Tagged with `data-bus-id`\n * so hit-test can identify clicks on the bus body.\n */\n\nimport { useEditorStore } from '../store';\n\nconst STROKE_WIDTH = 3;\n/** Invisible click target wider than the visible stroke, mirroring\n * ElementLayer's `HitRect`. */\nconst HIT_WIDTH = 12;\n\nexport function BusLayer() {\n const buses = useEditorStore((s) => s.internal.buses);\n const selection = useEditorStore((s) => s.selection);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const nodes = useEditorStore((s) => s.internal.nodes);\n const terminalToNode = useEditorStore((s) => s.internal.terminalToNode);\n const selSet = new Set(selection);\n\n // Buses whose ConnectivityNode is selected get a halo.\n const nodeRelatedBuses = new Set<string>();\n if (selectedNode) {\n const node = nodes.get(selectedNode);\n if (node) {\n for (const end of node.terminals) {\n if (!end.includes('.')) nodeRelatedBuses.add(end);\n }\n }\n }\n\n return (\n <g className=\"ole-bus-layer\">\n {Array.from(buses.values()).map(({ bus, geometry }) => {\n const { axis, at, span } = geometry;\n const half = span / 2;\n const x1 = axis === 'x' ? at[0] - half : at[0];\n const y1 = axis === 'x' ? at[1] : at[1] - half;\n const x2 = axis === 'x' ? at[0] + half : at[0];\n const y2 = axis === 'x' ? at[1] : at[1] + half;\n const isSelected = selSet.has(bus.id);\n const isNodeRelated = nodeRelatedBuses.has(bus.id);\n // Use the wire end's node id (if any) for `data-node-id` so a click\n // on the bus body resolves to its electrical node, mirroring the\n // wire layer's tagging convention.\n const nodeId = terminalToNode.get(bus.id) ?? undefined;\n // Wide invisible rect along the bus axis — gives a comfortable\n // click target without thickening the visible line.\n const hitHalf = HIT_WIDTH / 2;\n const hx = axis === 'x' ? at[0] - half : at[0] - hitHalf;\n const hy = axis === 'x' ? at[1] - hitHalf : at[1] - half;\n const hw = axis === 'x' ? span : HIT_WIDTH;\n const hh = axis === 'x' ? HIT_WIDTH : span;\n return (\n <g\n key={bus.id}\n data-bus-id={bus.id}\n data-element-id={bus.id}\n data-node-id={nodeId}\n data-selected={isSelected ? 'true' : undefined}\n data-node-related={isNodeRelated ? 'true' : undefined}\n className=\"ole-bus\"\n >\n <rect\n x={hx}\n y={hy}\n width={hw}\n height={hh}\n fill=\"transparent\"\n className=\"ole-bus-hit\"\n />\n <line\n x1={x1}\n y1={y1}\n x2={x2}\n y2={y2}\n stroke=\"currentColor\"\n strokeWidth={STROKE_WIDTH}\n strokeLinecap=\"round\"\n fill=\"none\"\n />\n </g>\n );\n })}\n </g>\n );\n}\n","/**\n * Live preview for the busbar tool. Snaps the cursor to the dominant axis\n * (horizontal or vertical) so users see exactly the line that will be\n * created on pointerup.\n */\n\nimport { useEditorStore } from '../store';\n\nexport function BusbarPreview() {\n const start = useEditorStore((s) => s.busbarDrawStart);\n const cursor = useEditorStore((s) => s.cursorSvg);\n\n if (!start || !cursor) return null;\n\n const dx = cursor[0] - start[0];\n const dy = cursor[1] - start[1];\n const horizontal = Math.abs(dx) >= Math.abs(dy);\n const endX = horizontal ? cursor[0] : start[0];\n const endY = horizontal ? start[1] : cursor[1];\n\n return (\n <g className=\"ole-busbar-preview\" pointerEvents=\"none\">\n <line\n x1={start[0]}\n y1={start[1]}\n x2={endX}\n y2={endY}\n className=\"ole-busbar-preview-line\"\n />\n <circle\n cx={start[0]}\n cy={start[1]}\n r={3.5}\n className=\"ole-busbar-preview-anchor\"\n />\n <circle\n cx={endX}\n cy={endY}\n r={3.5}\n className=\"ole-busbar-preview-anchor\"\n />\n </g>\n );\n}\n","/**\n * Build the SVG `transform` string for a device placement. Buses are\n * rendered separately by `BusLayer` and don't go through this helper.\n *\n * Composition (SVG applies left-to-right, parent-frame first):\n * translate(at) → rotate(rot) → scale(mirror?-1:1, 1)\n */\n\nimport type { ResolvedPlacement } from '../compiler';\n\nexport function transformAttr(p: ResolvedPlacement): string {\n const parts = [`translate(${p.at[0]} ${p.at[1]})`];\n if (p.rot) parts.push(`rotate(${p.rot})`);\n if (p.mirror) parts.push(`scale(-1 1)`);\n return parts.join(' ');\n}\n","/**\n * Renders one `<g>` per element. The library SVG fragment is inlined verbatim\n * via `dangerouslySetInnerHTML` — the library JSON is build-time content\n * (see `scripts/build-element-library.mjs`), not user input.\n *\n * Each `<g>` carries `data-element-id` so tools can hit-test via\n * `event.target.closest('[data-element-id]')` without React state. Selection\n * state is reflected as `data-selected=\"true\"` so CSS / overlays can react\n * without re-rendering this layer's children.\n *\n * To make every element comfortable to click — not just its thin strokes —\n * we paint an invisible `<rect>` covering the library's viewBox before the\n * symbol. `fill=\"transparent\"` is hittable (unlike `none`); the visual lines\n * still draw on top because they're added after.\n */\n\nimport { useEditorStore } from '../store';\nimport type { LibraryEntry } from '../model';\nimport { transformAttr } from './transform-attr';\n\ninterface BBox {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nfunction parseViewBox(s: string): BBox | null {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n\nfunction HitRect({ lib }: { lib: LibraryEntry }) {\n const bb = parseViewBox(lib.viewBox);\n if (!bb) return null;\n return (\n <rect\n className=\"ole-element-hit\"\n x={bb.x}\n y={bb.y}\n width={bb.w}\n height={bb.h}\n />\n );\n}\n\nexport function ElementLayer() {\n const elements = useEditorStore((s) => s.internal.elements);\n const layout = useEditorStore((s) => s.internal.layout);\n const selection = useEditorStore((s) => s.selection);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const nodes = useEditorStore((s) => s.internal.nodes);\n const selSet = new Set(selection);\n\n // Elements that have at least one terminal in the selected ConnectivityNode\n // get a halo to show \"this is what the wire connects\".\n const nodeRelated = new Set<string>();\n if (selectedNode) {\n const node = nodes.get(selectedNode);\n if (node) {\n for (const ref of node.terminals) {\n const dot = ref.indexOf('.');\n if (dot > 0) nodeRelated.add(ref.slice(0, dot));\n }\n }\n }\n\n return (\n <g className=\"ole-element-layer\">\n {Array.from(elements.values()).map((re) => {\n const place = layout.get(re.element.id);\n if (!place) return null;\n const isSelected = selSet.has(re.element.id);\n const isNodeRelated = nodeRelated.has(re.element.id);\n\n if (!re.libraryDef) {\n // Unknown kind → small red placeholder square.\n return (\n <g\n key={re.element.id}\n data-element-id={re.element.id}\n data-selected={isSelected ? 'true' : undefined}\n data-node-related={isNodeRelated ? 'true' : undefined}\n transform={transformAttr(place)}\n className=\"ole-element ole-element--unknown\"\n >\n <rect\n x={-10}\n y={-10}\n width={20}\n height={20}\n fill=\"none\"\n stroke=\"#EF4444\"\n strokeWidth={1}\n strokeDasharray=\"2 2\"\n />\n <text\n x={0}\n y={4}\n fontSize={8}\n fill=\"#EF4444\"\n textAnchor=\"middle\"\n fontFamily=\"system-ui, sans-serif\"\n >\n ?\n </text>\n </g>\n );\n }\n\n return (\n <g\n key={re.element.id}\n data-element-id={re.element.id}\n data-selected={isSelected ? 'true' : undefined}\n data-node-related={isNodeRelated ? 'true' : undefined}\n transform={transformAttr(place)}\n className=\"ole-element\"\n >\n <HitRect lib={re.libraryDef} />\n <g dangerouslySetInnerHTML={{ __html: re.libraryDef.svg }} />\n </g>\n );\n })}\n </g>\n );\n}\n","/**\n * Tiny pub/sub for the marquee selection rect (in SVG coords). Used by\n * SelectTool to publish rect updates and by `<MarqueeOverlay>` to render\n * without bouncing through the editor store.\n */\n\nexport interface MarqueeRect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ntype Listener = (rect: MarqueeRect | null) => void;\n\nlet current: MarqueeRect | null = null;\nconst listeners = new Set<Listener>();\n\nexport function publishMarquee(rect: MarqueeRect | null): void {\n current = rect;\n for (const l of listeners) l(rect);\n}\n\nexport function getMarquee(): MarqueeRect | null {\n return current;\n}\n\nexport function subscribeMarquee(fn: Listener): () => void {\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n","/**\n * Renders the in-progress marquee selection rect. Subscribes directly to\n * `marquee-bus` to avoid going through React state for every pointermove.\n */\n\nimport { useEffect, useState } from 'react';\nimport { getMarquee, subscribeMarquee, type MarqueeRect } from './marquee-bus';\n\nexport function MarqueeOverlay() {\n const [rect, setRect] = useState<MarqueeRect | null>(getMarquee());\n useEffect(() => subscribeMarquee(setRect), []);\n\n if (!rect || (rect.w === 0 && rect.h === 0)) return null;\n return (\n <rect\n className=\"ole-marquee\"\n x={rect.x}\n y={rect.y}\n width={rect.w}\n height={rect.h}\n pointerEvents=\"none\"\n />\n );\n}\n","/**\n * Half-transparent preview of the kind being placed, following the cursor\n * during the place tool.\n *\n * The cursor \"carries\" one of the new element's terminals (the tap-side\n * pin — same one `dropElement` snaps to a bus, and the same one used for\n * free-placement). Visually this means the pointer touches the pin you'd\n * expect to drop onto a wire/bus, not the element's centroid.\n *\n * In drag-from-terminal mode (`placeFromTerminal != null`) we additionally\n * draw a dashed wire from the source terminal to whichever pin of the ghost\n * is closest — same visual language as `WirePreview`, so the user sees the\n * connection that will be committed on release.\n */\n\nimport { useEditorStore } from '../store';\nimport { getLibraryEntry } from '../compiler';\nimport {\n pickConnectTerminal,\n pickPlaceCursorTerminal,\n resolvePlaceSource,\n} from './drop-on-bus';\n\nexport function PlaceGhost() {\n const tool = useEditorStore((s) => s.activeTool);\n const placeKind = useEditorStore((s) => s.placeKind);\n const cursor = useEditorStore((s) => s.cursorSvg);\n const fromRef = useEditorStore((s) => s.placeFromTerminal);\n\n if (tool !== 'place' || !placeKind || !cursor) return null;\n const lib = getLibraryEntry(placeKind);\n if (!lib) return null;\n\n // Anchor: cursor always carries one of the ghost's pins, so the visual\n // pointer-to-pin alignment stays continuous across the press → drag →\n // release sequence. Free-place uses the tap-side pin; drag-from-terminal\n // uses the pin that will connect back to the source, which also keeps\n // the dashed wire taut from source to cursor.\n let cursorPin: { x: number; y: number } | null = null;\n let connect: { source: [number, number]; pin: [number, number] } | null = null;\n if (fromRef) {\n const source = resolvePlaceSource(fromRef, cursor);\n if (source) {\n const chosen = pickConnectTerminal(lib, source, cursor);\n cursorPin = chosen;\n connect = { source: source.world, pin: cursor };\n }\n } else {\n cursorPin = pickPlaceCursorTerminal(lib);\n }\n const ghostX = cursor[0] - (cursorPin?.x ?? 0);\n const ghostY = cursor[1] - (cursorPin?.y ?? 0);\n\n return (\n <g className=\"ole-place-ghost-group\" pointerEvents=\"none\">\n {connect && (\n <>\n <line\n x1={connect.source[0]}\n y1={connect.source[1]}\n x2={connect.pin[0]}\n y2={connect.pin[1]}\n className=\"ole-wire-preview-line\"\n />\n <circle\n cx={connect.source[0]}\n cy={connect.source[1]}\n r={4}\n className=\"ole-wire-preview-anchor\"\n />\n </>\n )}\n <g\n className=\"ole-place-ghost\"\n transform={`translate(${ghostX} ${ghostY})`}\n opacity={0.5}\n >\n <g dangerouslySetInnerHTML={{ __html: lib.svg }} />\n </g>\n </g>\n );\n}\n","/**\n * Renders a non-scaling stroke rect around every selected element / bus\n * using the library viewBox (devices) or BusGeometry (buses) as the base\n * bbox, then applying the same transform.\n */\n\nimport { useEditorStore } from '../store';\nimport { transformAttr } from './transform-attr';\n\nexport function SelectionOverlay() {\n const selection = useEditorStore((s) => s.selection);\n const elements = useEditorStore((s) => s.internal.elements);\n const layout = useEditorStore((s) => s.internal.layout);\n const buses = useEditorStore((s) => s.internal.buses);\n\n if (selection.length === 0) return null;\n\n return (\n <g className=\"ole-selection-overlay\" pointerEvents=\"none\">\n {selection.map((id) => {\n const rb = buses.get(id);\n if (rb) {\n const { axis, at, span } = rb.geometry;\n const half = span / 2;\n const x = axis === 'x' ? at[0] - half : at[0] - 4;\n const y = axis === 'x' ? at[1] - 4 : at[1] - half;\n const w = axis === 'x' ? span : 8;\n const h = axis === 'x' ? 8 : span;\n return (\n <rect\n key={id}\n x={x}\n y={y}\n width={w}\n height={h}\n fill=\"none\"\n className=\"ole-selection-rect\"\n />\n );\n }\n const re = elements.get(id);\n const place = layout.get(id);\n if (!re?.libraryDef || !place) return null;\n const bb = parseViewBox(re.libraryDef.viewBox);\n if (!bb) return null;\n return (\n <rect\n key={id}\n x={bb.x}\n y={bb.y}\n width={bb.w}\n height={bb.h}\n fill=\"none\"\n className=\"ole-selection-rect\"\n transform={transformAttr(place)}\n />\n );\n })}\n </g>\n );\n}\n\nfunction parseViewBox(s: string): { x: number; y: number; w: number; h: number } | null {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n","/**\n * Renders a `<circle>` per terminal at its world coords. Hidden by default;\n * the wire tool reveals them via the `.tool-wire` class on the canvas root.\n * In select mode, terminals on currently-selected elements are also revealed\n * so the user can grab one to drag-connect without switching tools.\n * `data-connected` distinguishes solid (connected) from hollow (dangling).\n *\n * Selected stretchable elements (e.g. busbar) get their terminals suppressed\n * here because `BusHandles` already draws a larger grip at the same world\n * coords — showing both produces visible \"double\" control points.\n */\n\nimport { useEditorStore } from '../store';\n\nexport function TerminalLayer() {\n const terminals = useEditorStore((s) => s.internal.terminals);\n const terminalToNode = useEditorStore((s) => s.internal.terminalToNode);\n const wireFrom = useEditorStore((s) => s.wireFromTerminal);\n const selection = useEditorStore((s) => s.selection);\n\n const selectionSet = new Set<string>(selection);\n\n return (\n <g className=\"ole-terminal-layer\">\n {Array.from(terminals.values()).map((t) => {\n const nodeId = terminalToNode.get(t.ref);\n const connected = nodeId !== undefined;\n const isOrigin = wireFrom === t.ref;\n const onSelected = selectionSet.has(t.elementId);\n return (\n <circle\n key={t.ref}\n cx={t.world[0]}\n cy={t.world[1]}\n r={3}\n data-element-id={t.elementId}\n data-terminal-id={t.ref}\n data-node-id={nodeId}\n data-connected={connected ? 'true' : 'false'}\n data-active={isOrigin ? 'true' : undefined}\n data-on-selected={onSelected ? 'true' : undefined}\n className=\"ole-terminal\"\n />\n );\n })}\n </g>\n );\n}\n","/**\n * Renders one polyline per Wire. Each polyline carries `data-wire-id` so\n * hit-test resolves to the specific wire (not the whole electrical node)\n * and `data-node-id` for \"select-whole-node\" affordances.\n *\n * Each visible wire is paired with a wider invisible hit polyline. A 1px\n * wire is too thin to comfortably click; the hit poly catches pointer\n * events within ~8px of the line and carries the same data attributes.\n */\n\nimport { useEditorStore } from '../store';\n\nexport function WireLayer() {\n const wireRenders = useEditorStore((s) => s.internal.wireRenders);\n const terminalToNode = useEditorStore((s) => s.internal.terminalToNode);\n const wires = useEditorStore((s) => s.diagram.wires);\n const selectedWire = useEditorStore((s) => s.selectedWire);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n\n // Build a quick wireId → nodeId lookup so each rendered polyline knows\n // its containing electrical node.\n const wireToNode = new Map<string, string>();\n for (const w of wires ?? []) {\n const node = terminalToNode.get(w.ends[0]);\n if (node) wireToNode.set(w.id, node);\n }\n\n return (\n <g className=\"ole-wire-layer\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1}>\n {Array.from(wireRenders.values()).flatMap((r) => {\n const path = r.path;\n if (path.length < 2) return [];\n const points = path.map((p) => `${p[0]},${p[1]}`).join(' ');\n const nodeId = wireToNode.get(r.wireId);\n const isWireSelected = selectedWire === r.wireId;\n const isNodeSelected = selectedNode != null && selectedNode === nodeId;\n return [\n <polyline\n key={`hit-${r.wireId}`}\n data-wire-id={r.wireId}\n data-node-id={nodeId}\n className=\"ole-wire-hit\"\n points={points}\n />,\n <polyline\n key={r.wireId}\n data-wire-id={r.wireId}\n data-node-id={nodeId}\n data-manual={r.userEdited ? 'true' : undefined}\n data-selected={isWireSelected || isNodeSelected ? 'true' : undefined}\n className=\"ole-wire\"\n points={points}\n />,\n ];\n })}\n </g>\n );\n}\n","/**\n * Pub/sub for the in-progress wire target. WireTool publishes the current\n * candidate (a real terminal or a bus body projection); WirePreview\n * subscribes and renders an indicator so the user sees *where* a release\n * would land before they release.\n */\n\nimport type { WireEnd } from '../model';\n\nexport interface WireTarget {\n ref: WireEnd;\n /** World-frame coords of where the connection will physically attach. */\n world: [number, number];\n /** True when the target is a bare bus id. */\n isBus: boolean;\n}\n\ntype Listener = (target: WireTarget | null) => void;\n\nlet current: WireTarget | null = null;\nconst listeners = new Set<Listener>();\n\nexport function publishWireTarget(t: WireTarget | null): void {\n if (\n (t === null && current === null) ||\n (t &&\n current &&\n t.ref === current.ref &&\n t.world[0] === current.world[0] &&\n t.world[1] === current.world[1])\n ) {\n return;\n }\n current = t;\n for (const l of listeners) l(t);\n}\n\nexport function getWireTarget(): WireTarget | null {\n return current;\n}\n\nexport function subscribeWireTarget(fn: Listener): () => void {\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n","/**\n * Dashed line from the chosen first terminal to the current cursor position\n * while the wire tool is mid-drag. When the cursor is over a valid drop\n * target (a terminal or a bus body), an additional ring + dot marks the\n * exact landing point so the user can release with confidence.\n */\n\nimport { useEffect, useState } from 'react';\nimport { useEditorStore } from '../store';\nimport {\n getWireTarget,\n subscribeWireTarget,\n type WireTarget,\n} from './wire-target-bus';\n\nexport function WirePreview() {\n const fromRef = useEditorStore((s) => s.wireFromTerminal);\n const cursor = useEditorStore((s) => s.cursorSvg);\n const terminals = useEditorStore((s) => s.internal.terminals);\n const [target, setTarget] = useState<WireTarget | null>(getWireTarget());\n\n useEffect(() => subscribeWireTarget(setTarget), []);\n\n const buses = useEditorStore((s) => s.internal.buses);\n if (!fromRef || !cursor) return null;\n // `fromRef` may be a real terminal or a bare bus id — resolve world coords\n // from whichever map matches.\n let fromWorld: [number, number] | undefined;\n if (fromRef.includes('.')) {\n fromWorld = terminals.get(fromRef as `${string}.${string}`)?.world;\n } else {\n fromWorld = buses.get(fromRef)?.geometry.at;\n }\n if (!fromWorld) return null;\n\n // If we have a valid target, end the dashed line on it (snaps preview to\n // the actual landing point). Otherwise follow the raw cursor.\n const endX = target?.world[0] ?? cursor[0];\n const endY = target?.world[1] ?? cursor[1];\n\n return (\n <g className=\"ole-wire-preview\" pointerEvents=\"none\">\n <line\n x1={fromWorld[0]}\n y1={fromWorld[1]}\n x2={endX}\n y2={endY}\n className=\"ole-wire-preview-line\"\n />\n <circle\n cx={fromWorld[0]}\n cy={fromWorld[1]}\n r={4}\n className=\"ole-wire-preview-anchor\"\n />\n {target && (\n <>\n <circle\n cx={target.world[0]}\n cy={target.world[1]}\n r={target.isBus ? 7 : 8}\n className=\"ole-wire-preview-target-ring\"\n />\n <circle\n cx={target.world[0]}\n cy={target.world[1]}\n r={target.isBus ? 3 : 4}\n className=\"ole-wire-preview-target-dot\"\n />\n </>\n )}\n </g>\n );\n}\n","/**\n * DOM-based hit testing. The renderer tags every interactive node with a\n * `data-*` attribute (data-element-id, data-bus-id, data-terminal-id,\n * data-node-id, data-wire-id) so tools can locate the model they belong to\n * without React state lookups.\n */\n\nimport type {\n AnnotationId,\n BusId,\n ElementId,\n NodeId,\n TerminalRef,\n WireEnd,\n WireId,\n} from '../model';\n\nfunction ancestor(target: EventTarget | null, attr: string): Element | null {\n if (!(target instanceof Element)) return null;\n return target.closest(`[${attr}]`);\n}\n\nexport function hitElement(target: EventTarget | null): ElementId | null {\n return ancestor(target, 'data-element-id')?.getAttribute('data-element-id') ?? null;\n}\n\nexport function hitBus(target: EventTarget | null): BusId | null {\n return ancestor(target, 'data-bus-id')?.getAttribute('data-bus-id') ?? null;\n}\n\n/**\n * Returns either a device terminal ref (\"X.Y\") or a bare bus id under the\n * cursor. Direct hit on a `data-terminal-id` node wins; otherwise if the\n * click landed on a bus body fall back to the bus id so the wire tool can\n * attach anywhere along the bus.\n */\nexport function hitTerminal(target: EventTarget | null): WireEnd | null {\n const direct = ancestor(target, 'data-terminal-id')?.getAttribute('data-terminal-id');\n if (direct) return direct as TerminalRef;\n const busId = hitBus(target);\n if (busId) return busId;\n return null;\n}\n\nexport function hitNode(target: EventTarget | null): NodeId | null {\n return ancestor(target, 'data-node-id')?.getAttribute('data-node-id') ?? null;\n}\n\nexport function hitWire(target: EventTarget | null): WireId | null {\n return ancestor(target, 'data-wire-id')?.getAttribute('data-wire-id') ?? null;\n}\n\nexport function hitAnnotation(target: EventTarget | null): AnnotationId | null {\n return (\n ancestor(target, 'data-annotation-id')?.getAttribute('data-annotation-id') ??\n null\n );\n}\n","/**\n * Dispatch a synthetic `pointercancel` on the canvas host. Used by the\n * pinch-zoom hijack (useViewport) and the long-press → context-menu path\n * (CanvasSvg) to interrupt the active tool's in-progress gesture so it\n * runs its cancel cleanup instead of committing on the next pointerup.\n *\n * Best-effort: the `PointerEvent` constructor is missing on some older\n * touch browsers; failing silently is fine because the only downside is\n * the tool gesture lingering until the user lifts the finger naturally.\n */\nexport function dispatchSyntheticPointerCancel(\n host: EventTarget,\n pointerId: number,\n): void {\n try {\n host.dispatchEvent(\n new PointerEvent('pointercancel', {\n pointerId,\n bubbles: true,\n cancelable: true,\n pointerType: 'touch',\n }),\n );\n } catch {\n /* PointerEvent constructor unsupported — leave the gesture to time out */\n }\n}\n","/**\n * Global editor shortcuts. Runs once via the OneLineEditor root component\n * and reads/writes the store via `getState`. Shortcuts are inert when\n * focus is in an editable input/textarea so the property panel doesn't\n * eat the user's typing.\n */\n\nimport { useEffect } from 'react';\nimport { useEditorStore } from '../store';\n\nfunction isEditing(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n return (\n tag === 'INPUT' ||\n tag === 'TEXTAREA' ||\n tag === 'SELECT' ||\n target.isContentEditable\n );\n}\n\n/**\n * Step out of drawing state. Wire/busbar tools always return to select.\n * Place tool clears its placeKind first; if no kind is selected, returns to\n * select. For non-drawing tools, falls back to clearing selection. Shared\n * between Esc and the canvas right-click handler.\n */\nexport function exitDrawingState(): void {\n const store = useEditorStore.getState();\n const tool = store.activeTool;\n if (store.editingAnnotation || store.editingElement) {\n // Inline edit in progress: blur the contentEditable so its onBlur commits.\n if (typeof document !== 'undefined') {\n const ed = document.querySelector(\n '.ole-free-annotation-edit-fo div[contenteditable], .ole-element-name-editor div[contenteditable]',\n ) as HTMLElement | null;\n ed?.blur();\n }\n store.setEditingAnnotation(null);\n store.setEditingElement(null);\n return;\n }\n if (tool === 'wire' || tool === 'busbar' || tool === 'text') {\n store.setActiveTool('select');\n return;\n }\n if (tool === 'place') {\n if (store.placeFromTerminal) store.setPlaceFromTerminal(null);\n else if (store.placeKind) store.setPlaceKind(null);\n else store.setActiveTool('select');\n return;\n }\n if (\n store.selectedNode ||\n store.selectedWire ||\n store.selection.length > 0 ||\n store.selectedAnnotation\n ) {\n store.clearSelection();\n }\n}\n\n\nexport function useKeyboardShortcuts(): void {\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n if (isEditing(e.target)) return;\n\n const mod = e.metaKey || e.ctrlKey;\n const store = useEditorStore.getState();\n\n // Cmd+Z / Cmd+Shift+Z — undo / redo. Save shortcut handled in TopBar.\n if (mod && e.key.toLowerCase() === 'z') {\n e.preventDefault();\n if (e.shiftKey) store.redo();\n else store.undo();\n return;\n }\n // Cmd+Y — redo (Windows convention)\n if (mod && !e.shiftKey && e.key.toLowerCase() === 'y') {\n e.preventDefault();\n store.redo();\n return;\n }\n // Cmd+A — select all elements\n if (mod && e.key.toLowerCase() === 'a') {\n e.preventDefault();\n const ids = useEditorStore.getState().diagram.elements.map((x) => x.id);\n store.setSelection(ids);\n return;\n }\n // Cmd+C / Cmd+X / Cmd+V — copy / cut / paste\n if (mod && !e.shiftKey && !e.altKey) {\n const k = e.key.toLowerCase();\n if (k === 'c') {\n if (store.selection.length === 0) return;\n e.preventDefault();\n store.copySelection();\n return;\n }\n if (k === 'x') {\n if (store.selection.length === 0) return;\n e.preventDefault();\n store.cutSelection();\n return;\n }\n if (k === 'v') {\n if (!store.clipboard) return;\n e.preventDefault();\n store.pasteClipboard();\n return;\n }\n }\n if (mod) return; // ignore other modified keys\n\n switch (e.key) {\n case 'v':\n case 'V':\n store.setActiveTool('select');\n return;\n case 'h':\n case 'H':\n store.setActiveTool('pan');\n return;\n case 'w':\n case 'W':\n store.setActiveTool('wire');\n return;\n case 'b':\n case 'B':\n store.setActiveTool('busbar');\n return;\n case 'p':\n case 'P':\n store.setActiveTool('place');\n return;\n case 't':\n case 'T':\n store.setActiveTool('text');\n return;\n case 'r':\n case 'R':\n if (store.selection.length > 0) {\n e.preventDefault();\n store.rotateSelection(90);\n }\n return;\n case 'm':\n case 'M':\n if (store.selection.length > 0) {\n e.preventDefault();\n store.mirrorSelection();\n }\n return;\n case 'Delete':\n case 'Backspace':\n if (store.selectedAnnotation) {\n e.preventDefault();\n store.deleteAnnotation(store.selectedAnnotation);\n } else if (store.selectedWire) {\n e.preventDefault();\n store.deleteSelectedWire();\n } else if (store.selectedNode) {\n e.preventDefault();\n store.deleteSelectedNode();\n } else if (store.selection.length > 0) {\n e.preventDefault();\n store.deleteSelection();\n }\n return;\n case 'Escape':\n exitDrawingState();\n return;\n }\n };\n\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, []);\n}\n","/**\n * Pub/sub for the cursor's hover target on the canvas. `useHoverHighlight`\n * publishes the current `data-element-id` (or null when leaving an element);\n * `ElementHoverLabel` subscribes to render a small floating name tag.\n */\n\nimport type { ElementId } from '../model';\n\ntype Listener = (id: ElementId | null) => void;\n\nlet current: ElementId | null = null;\nconst listeners = new Set<Listener>();\n\nexport function publishHoverElement(id: ElementId | null): void {\n if (id === current) return;\n current = id;\n for (const l of listeners) l(id);\n}\n\nexport function getHoverElement(): ElementId | null {\n return current;\n}\n\nexport function subscribeHoverElement(fn: Listener): () => void {\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n","/**\n * Tracks which element / connectivity-node the cursor is over and toggles\n * marker classes on the affected DOM nodes. CSS reads those classes to\n * drive visual highlights without re-rendering React.\n *\n * Markers (added/removed by this hook):\n * .ole-hover-element-host — the element whose body the cursor is over;\n * its sibling terminals are also marked\n * .ole-hover-terminal-on — terminals belonging to the hovered element\n * (revealed regardless of tool, per ui-design §2.1)\n * .ole-hover-node-on — wires/terminals on the hovered ConnectivityNode\n * (highlighted, with non-members dimmed via root attr)\n */\n\nimport { useEffect, type RefObject } from 'react';\nimport { useEditorStore } from '../store';\nimport { hitElement, hitNode, hitTerminal } from './hit-test';\nimport { publishHoverElement } from './hover-bus';\n\nconst C_HOST = 'ole-hover-element-host';\nconst C_TERM = 'ole-hover-terminal-on';\nconst C_NODE = 'ole-hover-node-on';\n\nexport function useHoverHighlight(\n hostRef: RefObject<HTMLDivElement | null>,\n): void {\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n\n let lastElement: string | null = null;\n let lastNode: string | null = null;\n const markedTerminals = new Set<Element>();\n const markedNodeMembers = new Set<Element>();\n\n const clearAndMark = (\n pool: Set<Element>,\n next: Element[],\n cls: string,\n ) => {\n for (const el of pool) el.classList.remove(cls);\n pool.clear();\n for (const el of next) {\n el.classList.add(cls);\n pool.add(el);\n }\n };\n\n const updateElementHover = (id: string | null) => {\n if (id === lastElement) return;\n // Clear previous host class\n if (lastElement) {\n host\n .querySelector(`[data-element-id=\"${cssEscape(lastElement)}\"]`)\n ?.classList.remove(C_HOST);\n }\n // Set new host class\n if (id) {\n host\n .querySelector(`[data-element-id=\"${cssEscape(id)}\"]`)\n ?.classList.add(C_HOST);\n }\n // Mark terminals belonging to the hovered element\n const terms = id\n ? Array.from(\n host.querySelectorAll<SVGCircleElement>(\n `.ole-terminal[data-element-id=\"${cssEscape(id)}\"]`,\n ),\n )\n : [];\n clearAndMark(markedTerminals, terms, C_TERM);\n lastElement = id;\n // Mirror to root attr so CSS can distinguish \"any element hovered\" state\n if (id) host.setAttribute('data-hover-element', '');\n else host.removeAttribute('data-hover-element');\n publishHoverElement(id);\n };\n\n const updateNodeHover = (nodeId: string | null) => {\n if (nodeId === lastNode) return;\n const members = nodeId\n ? Array.from(\n host.querySelectorAll<Element>(\n `[data-node-id=\"${cssEscape(nodeId)}\"]`,\n ),\n )\n : [];\n clearAndMark(markedNodeMembers, members, C_NODE);\n lastNode = nodeId;\n if (nodeId) host.setAttribute('data-hover-node', '');\n else host.removeAttribute('data-hover-node');\n };\n\n const onPointerMove = (e: PointerEvent) => {\n updateElementHover(hitElement(e.target));\n\n const terminal = hitTerminal(e.target);\n let nodeId: string | null = null;\n if (terminal) {\n nodeId =\n useEditorStore.getState().internal.terminalToNode.get(terminal) ?? null;\n } else {\n nodeId = hitNode(e.target);\n }\n updateNodeHover(nodeId);\n };\n\n const onPointerLeave = () => {\n updateElementHover(null);\n updateNodeHover(null);\n };\n\n host.addEventListener('pointermove', onPointerMove);\n host.addEventListener('pointerleave', onPointerLeave);\n return () => {\n host.removeEventListener('pointermove', onPointerMove);\n host.removeEventListener('pointerleave', onPointerLeave);\n updateElementHover(null);\n updateNodeHover(null);\n };\n }, [hostRef]);\n}\n\nfunction cssEscape(s: string): string {\n // Avoid CSS.escape (not always typed in lib.dom); IDs may contain dots.\n return s.replace(/([\"\\\\])/g, '\\\\$1');\n}\n","/**\n * Resolve a WireEnd under the cursor into a concrete world-coord target,\n * including the bus body case. The wire tool drags toward terminals — but\n * for buses we accept a hit on the body itself and project the cursor onto\n * the bus axis to get a connection point.\n */\n\nimport { useEditorStore } from '../store';\nimport type { WireEnd } from '../model';\nimport type { WireTarget } from './wire-target-bus';\n\nexport function resolveWireTarget(\n ref: WireEnd,\n cursorWorld: [number, number],\n): WireTarget | null {\n const internal = useEditorStore.getState().internal;\n // Bare bus id: project cursor onto bus axis.\n if (!ref.includes('.')) {\n const rb = internal.buses.get(ref);\n if (!rb) return null;\n const { axis, at, span } = rb.geometry;\n if (axis === 'x') {\n const minX = at[0] - span / 2;\n const maxX = at[0] + span / 2;\n const x = Math.max(minX, Math.min(maxX, cursorWorld[0]));\n return { ref, world: [x, at[1]], isBus: true };\n }\n const minY = at[1] - span / 2;\n const maxY = at[1] + span / 2;\n const y = Math.max(minY, Math.min(maxY, cursorWorld[1]));\n return { ref, world: [at[0], y], isBus: true };\n }\n // Real device terminal.\n const term = internal.terminals.get(ref as `${string}.${string}`);\n if (term) {\n return { ref, world: term.world, isBus: false };\n }\n return null;\n}\n","/**\n * Select tool: click to select, shift-click to add/remove from selection,\n * drag a selected element (or one just clicked) to move all selected\n * elements together. Drag in *empty space* draws a marquee box and selects\n * every element whose bbox intersects the box (replace, or add with shift).\n *\n * Movement uses DOM-direct mutation (`setAttribute('transform')`) during\n * the drag and dispatches a single `moveElements` action on pointer-up.\n * This keeps the drag at 60fps even for diagrams that would otherwise\n * recompile on every pointermove.\n */\n\nimport { useEditorStore } from '../../store';\nimport type { ResolvedPlacement } from '../../compiler';\nimport type { AnnotationId, BusId, ElementId, WireEnd } from '../../model';\nimport { snap } from '../grid';\nimport { hitAnnotation, hitElement, hitNode, hitTerminal, hitWire } from '../hit-test';\nimport { publishMarquee, type MarqueeRect } from '../marquee-bus';\nimport { resolveWireTarget } from '../resolve-wire-target';\nimport { transformAttr } from '../transform-attr';\nimport { publishWireTarget } from '../wire-target-bus';\nimport type { Tool } from './types';\n\nconst MARQUEE_THRESHOLD = 3;\n\ninterface DragState {\n pointerId: number;\n startSvg: [number, number];\n /** Original placements of every dragged element. */\n originals: Map<ElementId, ResolvedPlacement>;\n /** Original `at` of every dragged bus. Buses live outside `internal.layout`\n * so they need a separate map; preview translates the wrapper `<g>`. */\n busOriginals: Map<BusId, [number, number]>;\n moved: boolean;\n}\n\ninterface MarqueeState {\n pointerId: number;\n startSvg: [number, number];\n shiftKey: boolean;\n /** Selection at gesture start; used as the base when shift-extending. */\n baseSelection: ElementId[];\n}\n\ninterface WireDragState {\n pointerId: number;\n fromRef: WireEnd;\n}\n\ninterface AnnotationDragState {\n pointerId: number;\n id: AnnotationId;\n startSvg: [number, number];\n origin: [number, number];\n moved: boolean;\n}\n\nlet drag: DragState | null = null;\nlet marquee: MarqueeState | null = null;\nlet wireDrag: WireDragState | null = null;\nlet annDrag: AnnotationDragState | null = null;\n\nexport const SelectTool: Tool = {\n id: 'select',\n cursor: 'default',\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return; // ignore middle/right\n\n // Bus stretch handles are *inside* the canvas host but their React\n // handlers run after the host's native bubble phase (React 17+ root\n // delegation). Ignoring handle hits here keeps SelectTool from\n // clearing the very selection that owns those handles.\n if (\n e.target instanceof Element &&\n e.target.closest('.ole-bus-handle')\n ) {\n return;\n }\n\n const store = useEditorStore.getState();\n\n // Free text annotation: takes priority over element / terminal because\n // the annotation rect can overlap them visually. Click selects + arms\n // a drag; double-click (separate handler) enters edit mode.\n const annId = hitAnnotation(e.target);\n if (annId) {\n e.preventDefault();\n e.stopPropagation();\n const ann = store.diagram.annotations?.find((a) => a.id === annId);\n if (!ann) return;\n store.setSelectedAnnotation(annId);\n annDrag = {\n pointerId: e.pointerId,\n id: annId,\n startSvg: ctx.viewport.screenToSvg(e.clientX, e.clientY),\n origin: [ann.at[0], ann.at[1]],\n moved: false,\n };\n // Capture deferred to first real movement (see element-drag note).\n return;\n }\n\n // If the user clicked a terminal on a currently-selected element, start a\n // wire drag — same gesture as the wire tool, but available without\n // switching modes. The selection set is the gating affordance. We only\n // accept *direct* terminal hits (`data-terminal-id` ancestor); the\n // busbar-body fallback in `hitTerminal` is excluded so dragging the bus\n // body still moves the bus instead of starting a wire.\n const directTerm =\n e.target instanceof Element\n ? e.target.closest('[data-terminal-id]')?.getAttribute('data-terminal-id')\n : null;\n const termRef = directTerm ? hitTerminal(e.target) : null;\n if (termRef) {\n const dot = termRef.indexOf('.');\n const elemId = dot > 0 ? termRef.slice(0, dot) : '';\n if (elemId && store.selection.includes(elemId)) {\n e.preventDefault();\n e.stopPropagation();\n if (\n e.target instanceof Element &&\n e.target.hasPointerCapture?.(e.pointerId)\n ) {\n e.target.releasePointerCapture(e.pointerId);\n }\n ctx.hostEl.classList.add('tool-wire');\n store.setWireFromTerminal(termRef);\n store.setCursorSvg(ctx.viewport.screenToSvg(e.clientX, e.clientY));\n wireDrag = { pointerId: e.pointerId, fromRef: termRef };\n return;\n }\n }\n\n const id = hitElement(e.target);\n\n if (!id) {\n // Click on a wire → select that single Wire. Alt-click selects the\n // whole electrical node (every wire sharing the same potential).\n const wireId = hitWire(e.target);\n if (wireId) {\n e.preventDefault();\n if (e.altKey) {\n const nodeId = hitNode(e.target);\n if (nodeId) {\n store.setSelectedNode(nodeId);\n return;\n }\n }\n store.setSelectedWire(wireId);\n return;\n }\n\n // Empty-space click → start marquee. The selection only changes on\n // pointerup; leaves selection unchanged for plain shift+drag.\n if (!e.shiftKey) store.clearSelection();\n marquee = {\n pointerId: e.pointerId,\n startSvg: ctx.viewport.screenToSvg(e.clientX, e.clientY),\n shiftKey: e.shiftKey,\n baseSelection: e.shiftKey ? store.selection.slice() : [],\n };\n ctx.hostEl.setPointerCapture(e.pointerId);\n e.preventDefault();\n return;\n }\n\n // Update selection.\n const sel = store.selection;\n if (e.shiftKey) {\n store.toggleInSelection(id);\n } else if (!sel.includes(id)) {\n store.setSelection([id]);\n }\n\n // Begin drag with the post-click selection.\n const targets = e.shiftKey\n ? useEditorStore.getState().selection\n : sel.includes(id)\n ? sel\n : [id];\n if (targets.length === 0) return;\n\n const internal = useEditorStore.getState().internal;\n const originals = new Map<ElementId, ResolvedPlacement>();\n const busOriginals = new Map<BusId, [number, number]>();\n for (const tid of targets) {\n const rb = internal.buses.get(tid);\n if (rb) {\n busOriginals.set(tid, [rb.geometry.at[0], rb.geometry.at[1]]);\n continue;\n }\n const p = internal.layout.get(tid);\n if (p) originals.set(tid, { ...p });\n }\n if (originals.size === 0 && busOriginals.size === 0) return;\n\n drag = {\n pointerId: e.pointerId,\n startSvg: ctx.viewport.screenToSvg(e.clientX, e.clientY),\n originals,\n busOriginals,\n moved: false,\n };\n // Defer pointer capture until the user actually starts moving (in\n // onPointerMove) — capturing on pointerdown can interfere with the\n // browser synthesizing `dblclick` from a click pair on the same target.\n e.preventDefault();\n },\n\n onPointerMove(e, ctx) {\n if (annDrag && e.pointerId === annDrag.pointerId) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const dx = snap(cur[0] - annDrag.startSvg[0]);\n const dy = snap(cur[1] - annDrag.startSvg[1]);\n if (!annDrag.moved && (dx !== 0 || dy !== 0)) {\n annDrag.moved = true;\n if (!ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.setPointerCapture(e.pointerId);\n }\n }\n // DOM-direct preview: update the wrapper group's transform so the\n // drag stays smooth. The store mutation lands once on pointerup.\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-annotation-id=\"${cssEscape(annDrag.id)}\"]`,\n );\n if (node) node.setAttribute('transform', `translate(${dx} ${dy})`);\n return;\n }\n\n if (wireDrag && e.pointerId === wireDrag.pointerId) {\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n useEditorStore.getState().setCursorSvg(pt);\n // Pointer capture would pin `e.target` to the origin terminal — sample\n // what's actually under the cursor for the live drop-target marker.\n const under =\n typeof document !== 'undefined'\n ? document.elementFromPoint(e.clientX, e.clientY)\n : null;\n const ref = under ? hitTerminal(under) : null;\n if (!ref || ref === wireDrag.fromRef) {\n publishWireTarget(null);\n return;\n }\n publishWireTarget(resolveWireTarget(ref, pt));\n return;\n }\n\n if (drag && e.pointerId === drag.pointerId) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const dx = snap(cur[0] - drag.startSvg[0]);\n const dy = snap(cur[1] - drag.startSvg[1]);\n if (!drag.moved && (dx !== 0 || dy !== 0)) {\n drag.moved = true;\n if (!ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.setPointerCapture(e.pointerId);\n }\n }\n\n for (const [id, orig] of drag.originals) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (!node) continue;\n const next: ResolvedPlacement = {\n ...orig,\n at: [orig.at[0] + dx, orig.at[1] + dy],\n };\n node.setAttribute('transform', transformAttr(next));\n }\n // Buses: wrapper g has no baseline transform (geometry is baked into\n // child line/rect coords), so a translate on the wrapper previews the\n // drop position without recomputing geometry.\n for (const id of drag.busOriginals.keys()) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (!node) continue;\n node.setAttribute('transform', `translate(${dx} ${dy})`);\n }\n return;\n }\n\n if (marquee && e.pointerId === marquee.pointerId) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n publishMarquee(rectFromPoints(marquee.startSvg, cur));\n return;\n }\n },\n\n onPointerUp(e, ctx) {\n if (annDrag && e.pointerId === annDrag.pointerId) {\n if (ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n }\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const dx = snap(cur[0] - annDrag.startSvg[0]);\n const dy = snap(cur[1] - annDrag.startSvg[1]);\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-annotation-id=\"${cssEscape(annDrag.id)}\"]`,\n );\n // Reset the preview transform — store update will repaint at the new at.\n if (node) node.removeAttribute('transform');\n if (annDrag.moved && (dx !== 0 || dy !== 0)) {\n useEditorStore.getState().updateAnnotation(annDrag.id, {\n at: [annDrag.origin[0] + dx, annDrag.origin[1] + dy],\n });\n }\n annDrag = null;\n return;\n }\n\n if (wireDrag && e.pointerId === wireDrag.pointerId) {\n const store = useEditorStore.getState();\n const from = wireDrag.fromRef;\n wireDrag = null;\n ctx.hostEl.classList.remove('tool-wire');\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n const ref = hitTerminal(e.target);\n if (ref && ref !== from) store.addWire(from, ref);\n return;\n }\n\n if (drag && e.pointerId === drag.pointerId) {\n if (ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n }\n if (drag.moved) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const dx = snap(cur[0] - drag.startSvg[0]);\n const dy = snap(cur[1] - drag.startSvg[1]);\n if (dx !== 0 || dy !== 0) {\n const deltas = new Map<ElementId, [number, number]>();\n for (const id of drag.originals.keys()) deltas.set(id, [dx, dy]);\n for (const id of drag.busOriginals.keys()) deltas.set(id, [dx, dy]);\n useEditorStore.getState().moveElements(deltas);\n }\n // Clear bus preview transforms — the store update repaints at new at.\n for (const id of drag.busOriginals.keys()) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (node) node.removeAttribute('transform');\n }\n }\n drag = null;\n return;\n }\n\n if (marquee && e.pointerId === marquee.pointerId) {\n if (ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n }\n const end = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const rect = rectFromPoints(marquee.startSvg, end);\n // Only treat as a real marquee if the user actually dragged.\n if (rect.w >= MARQUEE_THRESHOLD || rect.h >= MARQUEE_THRESHOLD) {\n const hit = elementsInRect(rect);\n if (marquee.shiftKey) {\n // Shift-marquee toggles each hit element's membership.\n const baseSet = new Set(marquee.baseSelection);\n for (const id of hit) {\n if (baseSet.has(id)) baseSet.delete(id);\n else baseSet.add(id);\n }\n useEditorStore.getState().setSelection([...baseSet]);\n } else {\n useEditorStore.getState().setSelection(hit);\n }\n }\n publishMarquee(null);\n marquee = null;\n }\n },\n\n onPointerCancel(e, ctx) {\n // Pinch-zoom hijack interrupted the gesture. Cleanly drop any in-flight\n // drag/marquee/wire/annotation state without committing — we don't want\n // to apply a move/marquee at the synthetic cancel coordinates.\n if (annDrag && e.pointerId === annDrag.pointerId) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-annotation-id=\"${cssEscape(annDrag.id)}\"]`,\n );\n if (node) node.removeAttribute('transform');\n if (ctx.hostEl.hasPointerCapture?.(e.pointerId)) {\n try {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n } catch {\n /* ignore */\n }\n }\n annDrag = null;\n }\n if (drag && e.pointerId === drag.pointerId) {\n // Reset the live preview transforms so the elements snap back to\n // their pre-drag placements (the store wasn't mutated yet).\n for (const [id, orig] of drag.originals) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (!node) continue;\n node.setAttribute('transform', transformAttr(orig));\n }\n for (const id of drag.busOriginals.keys()) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (node) node.removeAttribute('transform');\n }\n if (ctx.hostEl.hasPointerCapture?.(e.pointerId)) {\n try {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n } catch {\n /* ignore */\n }\n }\n drag = null;\n }\n if (wireDrag && e.pointerId === wireDrag.pointerId) {\n ctx.hostEl.classList.remove('tool-wire');\n const store = useEditorStore.getState();\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n wireDrag = null;\n }\n if (marquee && e.pointerId === marquee.pointerId) {\n if (ctx.hostEl.hasPointerCapture?.(e.pointerId)) {\n try {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n } catch {\n /* ignore */\n }\n }\n publishMarquee(null);\n marquee = null;\n }\n },\n\n onDoubleClick(e) {\n const store = useEditorStore.getState();\n const annId = hitAnnotation(e.target);\n if (annId) {\n e.preventDefault();\n e.stopPropagation();\n store.setEditingAnnotation(annId);\n return;\n }\n const id = hitElement(e.target);\n if (id) {\n e.preventDefault();\n e.stopPropagation();\n store.setEditingElement(id);\n }\n },\n\n onDeactivate(ctx) {\n drag = null;\n marquee = null;\n annDrag = null;\n if (wireDrag) {\n ctx.hostEl.classList.remove('tool-wire');\n const store = useEditorStore.getState();\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n wireDrag = null;\n }\n publishMarquee(null);\n },\n};\n\nfunction rectFromPoints(a: [number, number], b: [number, number]): MarqueeRect {\n const x = Math.min(a[0], b[0]);\n const y = Math.min(a[1], b[1]);\n const w = Math.abs(b[0] - a[0]);\n const h = Math.abs(b[1] - a[1]);\n return { x, y, w, h };\n}\n\n/**\n * Pick all element IDs whose library viewBox (transformed to world coords)\n * intersects the marquee rect. We approximate with the axis-aligned bbox of\n * the four corners after applying placement.\n */\nfunction elementsInRect(rect: MarqueeRect): ElementId[] {\n const { internal } = useEditorStore.getState();\n const hits: ElementId[] = [];\n for (const re of internal.elements.values()) {\n if (!re.libraryDef) continue;\n const place = internal.layout.get(re.element.id);\n if (!place) continue;\n const vb = parseViewBox(re.libraryDef.viewBox);\n if (!vb) continue;\n const corners: [number, number][] = [\n [vb.x, vb.y],\n [vb.x + vb.w, vb.y],\n [vb.x, vb.y + vb.h],\n [vb.x + vb.w, vb.y + vb.h],\n ].map(([x, y]) => transformLocalCorner([x, y], place));\n\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n for (const [x, y] of corners) {\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n if (\n maxX >= rect.x &&\n minX <= rect.x + rect.w &&\n maxY >= rect.y &&\n minY <= rect.y + rect.h\n ) {\n hits.push(re.element.id);\n }\n }\n // Buses: a horizontal/vertical segment is a tight rect.\n for (const { bus, geometry } of internal.buses.values()) {\n const { axis, at, span } = geometry;\n const half = span / 2;\n const minX = axis === 'x' ? at[0] - half : at[0];\n const maxX = axis === 'x' ? at[0] + half : at[0];\n const minY = axis === 'x' ? at[1] : at[1] - half;\n const maxY = axis === 'x' ? at[1] : at[1] + half;\n if (\n maxX >= rect.x &&\n minX <= rect.x + rect.w &&\n maxY >= rect.y &&\n minY <= rect.y + rect.h\n ) {\n hits.push(bus.id);\n }\n }\n return hits;\n}\n\nfunction transformLocalCorner(\n pt: [number, number],\n p: ResolvedPlacement,\n): [number, number] {\n let [x, y] = pt;\n if (p.mirror) x = -x;\n switch (p.rot) {\n case 0:\n break;\n case 90:\n [x, y] = [-y, x];\n break;\n case 180:\n [x, y] = [-x, -y];\n break;\n case 270:\n [x, y] = [y, -x];\n break;\n }\n return [x + p.at[0], y + p.at[1]];\n}\n\nfunction parseViewBox(s: string) {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n\nfunction cssEscape(s: string): string {\n return s.replace(/([\"\\\\])/g, '\\\\$1');\n}\n","/**\n * Pan tool: doubles as the touch-default tool. Three gestures off a single\n * finger:\n * - Tap on canvas → single-select (annotation > element > wire-node)\n * or clearSelection on empty space.\n * - Drag from selected → move the selected element(s) (DOM-direct preview,\n * element committed on pointerup via moveElements).\n * - Drag from elsewhere → pan the viewport.\n *\n * The drag-to-move path lets a phone user reposition elements without\n * switching tools — Pan is the everything-tool on touch, similar to how a\n * map app handles pins.\n */\n\nimport type { ResolvedPlacement } from '../../compiler';\nimport type { BusId, ElementId } from '../../model';\nimport { useEditorStore } from '../../store';\nimport { snap } from '../grid';\nimport { hitAnnotation, hitElement, hitNode } from '../hit-test';\nimport { transformAttr } from '../transform-attr';\nimport type { Tool } from './types';\n\nconst TAP_THRESHOLD_PX = 4;\n\ninterface PanState {\n pointerId: number;\n startX: number;\n startY: number;\n startTx: number;\n startTy: number;\n startTarget: EventTarget | null;\n moved: boolean;\n /** If set, the gesture started on these selected elements — drag = move\n * instead of pan. Stores each target's original placement so we can\n * preview via DOM transform and commit a delta on pointerup. Buses live\n * outside `internal.layout` so they're tracked separately by `at`. */\n elementDrag: {\n startSvg: [number, number];\n originals: Map<ElementId, ResolvedPlacement>;\n busOriginals: Map<BusId, [number, number]>;\n } | null;\n}\n\nlet pan: PanState | null = null;\n\nexport const PanTool: Tool = {\n id: 'pan',\n cursor: 'grab',\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n const vp = ctx.viewport.getViewport();\n\n // If the gesture starts on a currently-selected element, set up an\n // element drag so the same finger can move it instead of panning.\n const startId = hitElement(e.target);\n let elementDrag: PanState['elementDrag'] = null;\n if (startId) {\n const store = useEditorStore.getState();\n // If the user pressed on an unselected element, treat as a fresh\n // single-selection so the upcoming drag operates on that element.\n // The tap-without-move path also commits this selection on release.\n if (!store.selection.includes(startId)) {\n store.setSelection([startId]);\n }\n const sel = useEditorStore.getState().selection;\n const internal = useEditorStore.getState().internal;\n const originals = new Map<ElementId, ResolvedPlacement>();\n const busOriginals = new Map<BusId, [number, number]>();\n for (const id of sel) {\n const rb = internal.buses.get(id);\n if (rb) {\n busOriginals.set(id, [rb.geometry.at[0], rb.geometry.at[1]]);\n continue;\n }\n const p = internal.layout.get(id);\n if (p) originals.set(id, { ...p });\n }\n if (originals.size > 0 || busOriginals.size > 0) {\n elementDrag = {\n startSvg: ctx.viewport.screenToSvg(e.clientX, e.clientY),\n originals,\n busOriginals,\n };\n }\n }\n\n pan = {\n pointerId: e.pointerId,\n startX: e.clientX,\n startY: e.clientY,\n startTx: vp.tx,\n startTy: vp.ty,\n startTarget: e.target,\n moved: false,\n elementDrag,\n };\n // Defer pointer capture until the gesture actually moves so a quick tap\n // keeps its original target for the tap-select hit-test.\n ctx.hostEl.style.cursor = 'grabbing';\n e.preventDefault();\n },\n\n onPointerMove(e, ctx) {\n if (!pan || e.pointerId !== pan.pointerId) return;\n const dx = e.clientX - pan.startX;\n const dy = e.clientY - pan.startY;\n if (!pan.moved && Math.hypot(dx, dy) > TAP_THRESHOLD_PX) {\n pan.moved = true;\n try {\n ctx.hostEl.setPointerCapture(e.pointerId);\n } catch {\n /* pointer may already be released */\n }\n }\n if (!pan.moved) return;\n if (pan.elementDrag) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const ddx = snap(cur[0] - pan.elementDrag.startSvg[0]);\n const ddy = snap(cur[1] - pan.elementDrag.startSvg[1]);\n for (const [id, orig] of pan.elementDrag.originals) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (!node) continue;\n const next: ResolvedPlacement = {\n ...orig,\n at: [orig.at[0] + ddx, orig.at[1] + ddy],\n };\n node.setAttribute('transform', transformAttr(next));\n }\n for (const id of pan.elementDrag.busOriginals.keys()) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (!node) continue;\n node.setAttribute('transform', `translate(${ddx} ${ddy})`);\n }\n return;\n }\n ctx.viewport.setViewport({ tx: pan.startTx + dx, ty: pan.startTy + dy });\n },\n\n onPointerUp(e, ctx) {\n if (!pan || e.pointerId !== pan.pointerId) return;\n if (ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n }\n ctx.hostEl.style.cursor = 'grab';\n\n if (pan.elementDrag && pan.moved) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const ddx = snap(cur[0] - pan.elementDrag.startSvg[0]);\n const ddy = snap(cur[1] - pan.elementDrag.startSvg[1]);\n if (ddx !== 0 || ddy !== 0) {\n const deltas = new Map<ElementId, [number, number]>();\n for (const id of pan.elementDrag.originals.keys()) {\n deltas.set(id, [ddx, ddy]);\n }\n for (const id of pan.elementDrag.busOriginals.keys()) {\n deltas.set(id, [ddx, ddy]);\n }\n useEditorStore.getState().moveElements(deltas);\n }\n // Clear bus preview transforms — store update repaints at the new at.\n for (const id of pan.elementDrag.busOriginals.keys()) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (node) node.removeAttribute('transform');\n }\n } else if (!pan.moved) {\n handlePanTap(pan.startTarget);\n }\n pan = null;\n },\n\n onPointerCancel(_e, ctx) {\n if (pan?.elementDrag) {\n // Roll back the live preview transforms — store wasn't mutated yet.\n for (const [id, orig] of pan.elementDrag.originals) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (node) node.setAttribute('transform', transformAttr(orig));\n }\n for (const id of pan.elementDrag.busOriginals.keys()) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (node) node.removeAttribute('transform');\n }\n }\n pan = null;\n },\n\n onDeactivate() {\n pan = null;\n },\n};\n\nfunction handlePanTap(target: EventTarget | null) {\n if (!target) return;\n const store = useEditorStore.getState();\n const annId = hitAnnotation(target);\n if (annId) {\n store.setSelectedAnnotation(annId);\n return;\n }\n const id = hitElement(target);\n if (id) {\n store.setSelection([id]);\n return;\n }\n const nodeId = hitNode(target);\n if (nodeId) {\n store.setSelectedNode(nodeId);\n return;\n }\n store.clearSelection();\n}\n\nfunction cssEscape(s: string): string {\n return s.replace(/([\"\\\\])/g, '\\\\$1');\n}\n","/**\n * Editor responsiveness tier: types, breakpoints, helpers, hook.\n *\n * Provider component lives in the sibling `.tsx` file so React Fast Refresh\n * stays clean (a single .tsx file mixing components and constants warns).\n *\n * Tiers are monotonic — each higher tier subsumes the lower ones. Component\n * code should use `atLeast(t, 'compact')` instead of `t === 'compact'`.\n */\n\nimport {\n createContext,\n useContext,\n useLayoutEffect,\n useState,\n type RefObject,\n} from 'react';\n\nexport type Tier = 'full' | 'tight' | 'compact' | 'dense' | 'mini';\n\n/**\n * Width thresholds. The key is the *next-tier-down* boundary: at or above\n * `tight` (900) the layout is `full`; below 900 it's `tight`, etc. Names line\n * up with what each tier collapses:\n * - `tight`: FloatingToolbar tool labels off and ViewToolbar's zoom-% pill\n * hides. The centered main toolbar (≈ 510px wide with labels)\n * otherwise collides with the right-anchored ViewToolbar\n * anywhere below ~880px.\n * - `compact`: outline tab also goes icon-only.\n * - `dense`: ToolHint pill hidden; ViewToolbar collapses to one popover.\n * - `mini`: FloatingToolbar's [Undo/Redo/Layout] group collapses too.\n */\nexport const BREAKPOINTS = {\n tight: 1024,\n compact: 720,\n dense: 520,\n mini: 380,\n} as const;\n\nconst RANK: Record<Tier, number> = {\n full: 0,\n tight: 1,\n compact: 2,\n dense: 3,\n mini: 4,\n};\n\nexport function atLeast(t: Tier, min: Tier): boolean {\n return RANK[t] >= RANK[min];\n}\n\nexport function tierForWidth(w: number): Tier {\n if (w >= BREAKPOINTS.tight) return 'full';\n if (w >= BREAKPOINTS.compact) return 'tight';\n if (w >= BREAKPOINTS.dense) return 'compact';\n if (w >= BREAKPOINTS.mini) return 'dense';\n return 'mini';\n}\n\nexport const TierContext = createContext<Tier>('full');\n\nexport function useEditorTier(): Tier {\n return useContext(TierContext);\n}\n\n/**\n * Track the `clientWidth` of an element via ResizeObserver. Lives where the\n * ref does (e.g., directly in `EditorShell`) — the layout effect needs the\n * ref to be already attached, which it is in the same component but isn't\n * yet when a child reads it. Returns `null` until the first measurement.\n */\nexport function useObservedWidth(\n ref: RefObject<HTMLElement | null>,\n): number | null {\n const [width, setWidth] = useState<number | null>(null);\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const apply = () => {\n const w = el.clientWidth;\n setWidth((prev) => (prev === w ? prev : w));\n };\n apply();\n if (typeof ResizeObserver === 'undefined') return;\n const ro = new ResizeObserver(apply);\n ro.observe(el);\n return () => ro.disconnect();\n }, [ref]);\n return width;\n}\n","/**\n * Phone-class UX helpers shared by the drawing tools (place / wire / busbar /\n * text). On a narrow coarse-pointer viewport the user expects a \"one-shot\"\n * gesture: pick a tool, place / wire / etc. once, and snap back to the\n * default pan tool. Desktop and tablet keep the sticky-tool behavior since\n * the keyboard / stylus makes re-entry cheap and multi-place is common.\n *\n * The viewport-width gate keeps tablet (iPad ≈ 768px portrait, also a\n * coarse pointer) on the desktop-style flow — the unified bottom bar /\n * full-screen library are only the phone form factor.\n */\n\nimport { useEditorStore } from '../store';\nimport { BREAKPOINTS } from '../hooks/editor-tier';\n\nfunction isPhoneUx(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n if (!window.matchMedia('(pointer: coarse)').matches) return false;\n } catch {\n return false;\n }\n return window.innerWidth < BREAKPOINTS.dense;\n}\n\nexport function exitToPanOnPhone(): void {\n if (!isPhoneUx()) return;\n useEditorStore.getState().setActiveTool('pan');\n}\n\n/**\n * On a phone-class viewport, drop the currently armed place kind without\n * leaving place mode. PlaceTool calls this after each successful placement\n * so the LibraryPopover (hidden while armed on mobile) reappears for the\n * next pick. Sticky `lastPlaceKind` is preserved by `setPlaceKind(null)`.\n */\nexport function disarmPlaceOnPhone(): void {\n if (!isPhoneUx()) return;\n useEditorStore.getState().setPlaceKind(null);\n}\n","/**\n * Wire tool: press on a terminal, drag to another terminal, release to commit.\n * Releasing on empty space (or the same terminal) cancels. Esc also cancels\n * via the global keyboard hook.\n *\n * Activating the tool sets `.tool-wire` on the canvas root, which the CSS\n * uses to reveal terminals and turn on their pointer-events so the drag-end\n * hit-test resolves to a terminal.\n *\n * During the drag we publish the *current* candidate target via\n * `wire-target-bus`; `WirePreview` paints a marker so the user sees where a\n * release would land — including the bus virtual-tap projection when the\n * cursor is over a bus body.\n */\n\nimport { useEditorStore } from '../../store';\nimport { hitTerminal } from '../hit-test';\nimport { resolveWireTarget } from '../resolve-wire-target';\nimport { exitToPanOnPhone } from '../touch';\nimport { publishWireTarget } from '../wire-target-bus';\nimport type { Tool } from './types';\n\nexport const WireTool: Tool = {\n id: 'wire',\n cursor: 'crosshair',\n\n onActivate(ctx) {\n ctx.hostEl.classList.add('tool-wire');\n },\n onDeactivate(ctx) {\n ctx.hostEl.classList.remove('tool-wire');\n const store = useEditorStore.getState();\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n },\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n const ref = hitTerminal(e.target);\n if (!ref) return;\n e.preventDefault();\n e.stopPropagation();\n\n // Touch pointers get implicit capture on pointerdown — release it so the\n // pointerup hit-test resolves to the terminal under the finger, not the\n // origin terminal.\n if (e.target instanceof Element && e.target.hasPointerCapture?.(e.pointerId)) {\n e.target.releasePointerCapture(e.pointerId);\n }\n\n const store = useEditorStore.getState();\n store.setWireFromTerminal(ref);\n store.setCursorSvg(ctx.viewport.screenToSvg(e.clientX, e.clientY));\n },\n\n onPointerMove(e, ctx) {\n const sf = useEditorStore.getState().wireFromTerminal;\n if (!sf) return;\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n useEditorStore.getState().setCursorSvg(pt);\n\n // Pointer capture pins `e.target` to the start terminal — sample what's\n // *actually* under the cursor instead.\n const under =\n typeof document !== 'undefined'\n ? document.elementFromPoint(e.clientX, e.clientY)\n : null;\n const ref = under ? hitTerminal(under) : null;\n if (!ref || ref === sf) {\n publishWireTarget(null);\n return;\n }\n publishWireTarget(resolveWireTarget(ref, pt));\n },\n\n onPointerUp(e) {\n const store = useEditorStore.getState();\n const from = store.wireFromTerminal;\n if (!from) return;\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n\n const ref = hitTerminal(e.target);\n if (!ref || ref === from) return;\n store.addWire(from, ref);\n exitToPanOnPhone();\n },\n\n onPointerLeave() {\n const store = useEditorStore.getState();\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n },\n};\n","/**\n * Place tool: click anywhere on canvas to drop the chosen kind. The kind is\n * picked from the palette (LeftPanel single-click) or set programmatically\n * via `setActiveTool('place', { placeKind })`.\n *\n * Two interaction paths:\n * 1. Press on empty space (or near a bus body) → drops at cursor; near-bus\n * auto-tap via `dropElement`.\n * 2. Press on an existing terminal (incl. busbar virtual `tap`) → drag-place.\n * Ghost follows the cursor with a dashed wire previewing the connection\n * back to the source terminal. On release we create the element and add\n * the connection in a single undo step via `dropElementFromTerminal`.\n *\n * Activating the tool sets `.tool-place` on the canvas root, which the CSS\n * uses to reveal terminals so users can see drag-from targets.\n *\n * Stays in place mode after dropping so the user can drop multiples; press\n * Esc or switch tools to leave.\n */\n\nimport { useEditorStore } from '../../store';\nimport { dropElement, dropElementFromTerminal } from '../drop-on-bus';\nimport { hitTerminal } from '../hit-test';\nimport { disarmPlaceOnPhone } from '../touch';\nimport type { Tool } from './types';\n\nconst GRID = 10;\n\n// On touch, the click-to-drop path commits in onPointerDown. Disarming\n// `placeKind` there reopens the LibraryPopover mid-gesture, and the\n// synthesized click event for the same tap then hit-tests against the\n// freshly-rendered library item — arming a different kind. Defer the\n// disarm to a macrotask after pointerup so the click dispatches to the\n// canvas first.\nlet disarmOnUp = false;\nfunction scheduleDisarm(): void {\n setTimeout(() => disarmPlaceOnPhone(), 0);\n}\n\nexport const PlaceTool: Tool = {\n id: 'place',\n cursor: 'copy',\n\n onActivate(ctx) {\n ctx.hostEl.classList.add('tool-place');\n },\n onDeactivate(ctx) {\n ctx.hostEl.classList.remove('tool-place');\n const store = useEditorStore.getState();\n store.setPlaceFromTerminal(null);\n store.setCursorSvg(null);\n disarmOnUp = false;\n },\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n const { placeKind } = useEditorStore.getState();\n if (!placeKind) return;\n e.preventDefault();\n\n const ref = hitTerminal(e.target);\n if (ref) {\n // Drag-from-terminal mode: defer creation until pointerup so the user\n // can cancel by releasing outside or pressing Esc.\n e.stopPropagation();\n\n // Touch pointers get implicit capture on pointerdown — release it so\n // pointermove/up reflect the actual cursor target, mirroring WireTool.\n if (e.target instanceof Element && e.target.hasPointerCapture?.(e.pointerId)) {\n e.target.releasePointerCapture(e.pointerId);\n }\n\n const store = useEditorStore.getState();\n store.setPlaceFromTerminal(ref);\n store.setCursorSvg(ctx.viewport.screenToSvg(e.clientX, e.clientY));\n return;\n }\n\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n dropElement(placeKind, pt);\n disarmOnUp = true;\n },\n\n onPointerMove(e, ctx) {\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n useEditorStore.getState().setCursorSvg([snap(pt[0]), snap(pt[1])]);\n },\n\n onPointerUp(e, ctx) {\n const store = useEditorStore.getState();\n const from = store.placeFromTerminal;\n if (from) {\n store.setPlaceFromTerminal(null);\n const { placeKind } = store;\n if (!placeKind) return;\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n dropElementFromTerminal(placeKind, from, pt);\n scheduleDisarm();\n return;\n }\n if (disarmOnUp) {\n disarmOnUp = false;\n scheduleDisarm();\n }\n },\n\n onPointerLeave() {\n const store = useEditorStore.getState();\n store.setPlaceFromTerminal(null);\n store.setCursorSvg(null);\n },\n\n onPointerCancel() {\n // Pinch-zoom hijack interrupted the drag-place; drop the staged source\n // terminal without committing a placement at the (likely synthetic)\n // pointer-cancel coordinates.\n const store = useEditorStore.getState();\n store.setPlaceFromTerminal(null);\n store.setCursorSvg(null);\n disarmOnUp = false;\n },\n};\n\nfunction snap(v: number): number {\n return Math.round(v / GRID) * GRID;\n}\n","/**\n * Busbar tool: click-and-drag to draw a horizontal or vertical bus segment.\n *\n * Unlike the place tool (drop a fixed-size element on click), the bus needs\n * an explicit length and orientation per instance. The tool snaps the drawn\n * line to the dominant axis (horizontal or vertical) so that downstream\n * stretching, tap-routing and connectivity all stay aligned to the grid.\n *\n * Live preview: `busbarDrawStart` in the store holds the press point;\n * `cursorSvg` holds the current cursor. `BusbarPreview` reads both and\n * renders the snapped line in real time.\n *\n * UX: pointerdown sets the start; pointerup commits. Esc cancels via the\n * global keyboard hook (re-activates select).\n */\n\nimport { useEditorStore } from '../../store';\nimport { exitToPanOnPhone } from '../touch';\nimport type { Tool } from './types';\n\nconst GRID = 10;\nconst MIN_LEN = 20;\n\nfunction snap(v: number): number {\n return Math.round(v / GRID) * GRID;\n}\n\nexport const BusbarTool: Tool = {\n id: 'busbar',\n cursor: 'crosshair',\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n e.preventDefault();\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const start: [number, number] = [snap(pt[0]), snap(pt[1])];\n useEditorStore.getState().setBusbarDrawStart(start);\n useEditorStore.getState().setCursorSvg(start);\n },\n\n onPointerMove(e, ctx) {\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n useEditorStore.getState().setCursorSvg([snap(pt[0]), snap(pt[1])]);\n },\n\n onPointerUp(e, ctx) {\n const start = useEditorStore.getState().busbarDrawStart;\n useEditorStore.getState().setBusbarDrawStart(null);\n if (!start) return;\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const endX = snap(pt[0]);\n const endY = snap(pt[1]);\n const dx = endX - start[0];\n const dy = endY - start[1];\n const horizontal = Math.abs(dx) >= Math.abs(dy);\n\n let rot: 0 | 90;\n let span: number;\n let at: [number, number];\n\n if (horizontal) {\n span = Math.abs(dx);\n if (span < MIN_LEN) return;\n rot = 0;\n at = [(start[0] + endX) / 2, start[1]];\n } else {\n span = Math.abs(dy);\n if (span < MIN_LEN) return;\n rot = 90;\n at = [start[0], (start[1] + endY) / 2];\n }\n\n const store = useEditorStore.getState();\n store.addBus(at, span, rot);\n exitToPanOnPhone();\n },\n\n onPointerLeave() {\n const store = useEditorStore.getState();\n store.setBusbarDrawStart(null);\n store.setCursorSvg(null);\n },\n\n onPointerCancel() {\n // Pinch-zoom hijack interrupted the draw; abandon the in-progress busbar\n // rather than committing one at the synthetic cancel coordinates.\n const store = useEditorStore.getState();\n store.setBusbarDrawStart(null);\n store.setCursorSvg(null);\n },\n\n onDeactivate() {\n const store = useEditorStore.getState();\n store.setBusbarDrawStart(null);\n store.setCursorSvg(null);\n },\n};\n","/**\n * Text tool: click anywhere on empty canvas to drop a free text annotation\n * at the cursor and immediately enter inline-edit mode. After committing\n * (Enter / blur), control returns to the select tool with the annotation\n * still selected so users can keep moving / resizing it.\n *\n * Clicking on an existing annotation focuses it for re-edit instead of\n * dropping a new one.\n */\n\nimport { useEditorStore } from '../../store';\nimport { hitAnnotation } from '../hit-test';\nimport { exitToPanOnPhone } from '../touch';\nimport type { Tool } from './types';\n\nexport const TextTool: Tool = {\n id: 'text',\n cursor: 'text',\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n const store = useEditorStore.getState();\n\n // Clicking an existing annotation in text mode just selects it under\n // the regular select tool — editing is reserved for double-click so\n // single clicks don't accidentally trash content while repositioning.\n const existing = hitAnnotation(e.target);\n if (existing) {\n e.preventDefault();\n e.stopPropagation();\n store.setActiveTool('select');\n store.setSelectedAnnotation(existing);\n return;\n }\n\n e.preventDefault();\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const id = store.addAnnotation([pt[0], pt[1]], '');\n store.setEditingAnnotation(id);\n exitToPanOnPhone();\n },\n};\n","import type { Tool, ToolId } from './types';\nimport { SelectTool } from './SelectTool';\nimport { PanTool } from './PanTool';\nimport { WireTool } from './WireTool';\nimport { PlaceTool } from './PlaceTool';\nimport { BusbarTool } from './BusbarTool';\nimport { TextTool } from './TextTool';\n\nexport const TOOLS: Record<ToolId, Tool> = {\n select: SelectTool,\n pan: PanTool,\n wire: WireTool,\n place: PlaceTool,\n busbar: BusbarTool,\n text: TextTool,\n};\n\nexport type { Tool, ToolContext, ToolId } from './types';\n","/**\n * Wires the active tool's pointer/key handlers onto the canvas host. Re-runs\n * on tool change to call `onDeactivate` for the old and `onActivate` for the\n * new — that's where tools install/remove their per-mode state (e.g. WireTool\n * adding `.tool-wire` to reveal terminals).\n */\n\nimport { useEffect, type RefObject } from 'react';\nimport { useEditorStore } from '../store';\nimport { TOOLS } from './tools';\nimport type { ToolContext } from './tools';\nimport type { ViewportApi } from './useViewport';\n\nexport function useTools(\n hostRef: RefObject<HTMLDivElement | null>,\n viewport: ViewportApi,\n): void {\n const activeTool = useEditorStore((s) => s.activeTool);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const tool = TOOLS[activeTool];\n const ctx: ToolContext = { viewport, hostEl: host };\n\n tool.onActivate?.(ctx);\n if (tool.cursor) host.style.cursor = tool.cursor;\n\n const onDown = (e: PointerEvent) => tool.onPointerDown?.(e, ctx);\n const onMove = (e: PointerEvent) => tool.onPointerMove?.(e, ctx);\n const onUp = (e: PointerEvent) => tool.onPointerUp?.(e, ctx);\n // Pointercancel: if the tool defines its own cancel hook, use it (so it\n // can roll back without committing the gesture). Otherwise treat it as\n // a normal pointerup — the existing tools already handle that case.\n const onCancel = (e: PointerEvent) =>\n tool.onPointerCancel ? tool.onPointerCancel(e, ctx) : tool.onPointerUp?.(e, ctx);\n const onLeave = (e: PointerEvent) => tool.onPointerLeave?.(e, ctx);\n const onDbl = (e: MouseEvent) => tool.onDoubleClick?.(e, ctx);\n\n host.addEventListener('pointerdown', onDown);\n host.addEventListener('pointermove', onMove);\n host.addEventListener('pointerup', onUp);\n host.addEventListener('pointercancel', onCancel);\n host.addEventListener('pointerleave', onLeave);\n host.addEventListener('dblclick', onDbl);\n\n return () => {\n host.removeEventListener('pointerdown', onDown);\n host.removeEventListener('pointermove', onMove);\n host.removeEventListener('pointerup', onUp);\n host.removeEventListener('pointercancel', onCancel);\n host.removeEventListener('pointerleave', onLeave);\n host.removeEventListener('dblclick', onDbl);\n tool.onDeactivate?.(ctx);\n host.style.cursor = '';\n };\n }, [activeTool, hostRef, viewport]);\n}\n","/**\n * Tiny pub/sub for the live viewport scale. Lets chrome (TopBar zoom %) read\n * the value without forcing the gesture path through React state. Updated\n * by `useViewport` after every transform change.\n */\n\ntype Listener = (scale: number) => void;\n\nlet current = 1;\nconst listeners = new Set<Listener>();\n\nexport function publishScale(scale: number): void {\n if (scale === current) return;\n current = scale;\n for (const l of listeners) l(scale);\n}\n\nexport function getScale(): number {\n return current;\n}\n\nexport function subscribeScale(fn: Listener): () => void {\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n","/**\n * Pan/zoom viewport. State lives on refs and is pushed straight to the SVG\n * `<g transform>` and the parent's `--canvas-scale` CSS variable; React is\n * deliberately not involved during gestures so we don't re-render on every\n * wheel tick or pointer move.\n *\n * Exposes `screenToSvg()` so future tools (select, wire, place) can convert\n * pointer events to canvas coordinates without owning their own viewport.\n */\n\nimport { useEffect, useRef, type RefObject } from 'react';\nimport { dispatchSyntheticPointerCancel } from './synthetic-pointer-cancel';\nimport { publishScale } from './zoom-bus';\n\nexport interface Viewport {\n tx: number;\n ty: number;\n scale: number;\n}\n\nexport interface ViewportApi {\n /** Convert a clientX/Y (CSS pixels relative to the viewport) → SVG coords. */\n screenToSvg(clientX: number, clientY: number): [number, number];\n /** Read-only snapshot of the current transform. */\n getViewport(): Viewport;\n /** Update one or more viewport fields. */\n setViewport(patch: Partial<Viewport>): void;\n /** Subscribe to viewport changes; returns an unsubscribe fn. */\n subscribe(listener: (vp: Viewport) => void): () => void;\n}\n\nconst MIN_SCALE = 0.1;\nconst MAX_SCALE = 8;\n// Mouse wheel events on macOS arrive with |deltaY| ≈ 100 per click, so a\n// small factor still produces a comfortable per-click zoom. Trackpad pinch\n// (Chrome/Safari synthesize wheel events with ctrlKey + small deltaY,\n// typically 1–10) needs a much larger factor or it crawls vs. native apps.\nconst ZOOM_FACTOR_WHEEL = 1.0015;\nconst ZOOM_FACTOR_PINCH = 1.02;\n\nexport function useViewport(\n hostRef: RefObject<HTMLDivElement | null>,\n groupRef: RefObject<SVGGElement | null>,\n initial: Viewport = { tx: 0, ty: 0, scale: 1 },\n): ViewportApi {\n const vp = useRef<Viewport>({ ...initial });\n const listeners = useRef(new Set<(vp: Viewport) => void>());\n\n // Apply transform on the SVG group + expose --canvas-scale for stroke\n // compensation in CSS, then notify subscribers.\n const apply = () => {\n const g = groupRef.current;\n const host = hostRef.current;\n if (g) {\n g.setAttribute(\n 'transform',\n `translate(${vp.current.tx} ${vp.current.ty}) scale(${vp.current.scale})`,\n );\n }\n if (host) {\n host.style.setProperty('--canvas-scale', String(vp.current.scale));\n }\n publishScale(vp.current.scale);\n if (listeners.current.size > 0) {\n const snapshot = { ...vp.current };\n for (const fn of listeners.current) fn(snapshot);\n }\n };\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n\n let panning = false;\n let panPointerId = -1;\n let panStartX = 0;\n let panStartY = 0;\n let panStartTx = 0;\n let panStartTy = 0;\n let spaceDown = false;\n\n // ---- Multi-touch pinch / two-finger pan -----------------------------\n // iPad/iPhone have no wheel events, so pinch-zoom + two-finger pan are\n // the only way to navigate the canvas. We track every active touch\n // pointer; once two are down we hijack all touch events (capture phase\n // + stopPropagation) so the active tool stops receiving them and the\n // viewport handles pan/zoom directly. Hijack lasts until all touches\n // lift, so the trailing finger of a pinch never accidentally restarts\n // a tool gesture.\n const touches = new Map<number, { x: number; y: number }>();\n interface PinchState {\n startDist: number;\n startScale: number;\n startTx: number;\n startTy: number;\n startMidX: number;\n startMidY: number;\n }\n let pinch: PinchState | null = null;\n let touchHijack = false;\n\n const recomputePinchBaseline = () => {\n if (touches.size < 2) {\n pinch = null;\n return;\n }\n const pts = [...touches.values()];\n const dx = pts[1].x - pts[0].x;\n const dy = pts[1].y - pts[0].y;\n const dist = Math.hypot(dx, dy) || 1;\n const rect = host.getBoundingClientRect();\n pinch = {\n startDist: dist,\n startScale: vp.current.scale,\n startTx: vp.current.tx,\n startTy: vp.current.ty,\n startMidX: (pts[0].x + pts[1].x) / 2 - rect.left,\n startMidY: (pts[0].y + pts[1].y) / 2 - rect.top,\n };\n };\n\n const onTouchPointerDownCap = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') return;\n touches.set(e.pointerId, { x: e.clientX, y: e.clientY });\n if (touches.size >= 2 && !touchHijack) {\n touchHijack = true;\n // Cancel any in-progress single-touch tool gesture (drag, marquee,\n // wire, etc.) so it doesn't keep mutating state while we pinch.\n // Synthetic pointercancel fires the tool's existing cleanup path.\n for (const id of touches.keys()) {\n if (id === e.pointerId) continue;\n dispatchSyntheticPointerCancel(host, id);\n }\n recomputePinchBaseline();\n }\n if (touchHijack) {\n e.stopPropagation();\n e.preventDefault();\n try {\n host.setPointerCapture(e.pointerId);\n } catch {\n /* capture may fail if the pointer was already released */\n }\n }\n };\n\n const onTouchPointerMoveCap = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') return;\n if (!touches.has(e.pointerId)) return;\n touches.set(e.pointerId, { x: e.clientX, y: e.clientY });\n if (!touchHijack || !pinch) return;\n e.stopPropagation();\n const pts = [...touches.values()];\n if (pts.length < 2) return;\n const dx = pts[1].x - pts[0].x;\n const dy = pts[1].y - pts[0].y;\n const dist = Math.hypot(dx, dy) || 1;\n const rect = host.getBoundingClientRect();\n const midX = (pts[0].x + pts[1].x) / 2 - rect.left;\n const midY = (pts[0].y + pts[1].y) / 2 - rect.top;\n const ratio = dist / pinch.startDist;\n const next = clamp(pinch.startScale * ratio, MIN_SCALE, MAX_SCALE);\n const k = next / pinch.startScale;\n // Anchor zoom at the initial midpoint, then add the midpoint drift\n // so the pinch also pans.\n vp.current.tx =\n pinch.startMidX - (pinch.startMidX - pinch.startTx) * k + (midX - pinch.startMidX);\n vp.current.ty =\n pinch.startMidY - (pinch.startMidY - pinch.startTy) * k + (midY - pinch.startMidY);\n vp.current.scale = next;\n apply();\n };\n\n const onTouchPointerUpCap = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') return;\n if (!touches.has(e.pointerId)) return;\n touches.delete(e.pointerId);\n if (touchHijack) {\n e.stopPropagation();\n if (host.hasPointerCapture?.(e.pointerId)) {\n try {\n host.releasePointerCapture(e.pointerId);\n } catch {\n /* ignore */\n }\n }\n // If a finger lifted but more than one is still down, recompute\n // the pinch baseline so the next move continues smoothly.\n if (touches.size >= 2) {\n recomputePinchBaseline();\n } else {\n pinch = null;\n }\n if (touches.size === 0) {\n touchHijack = false;\n }\n }\n };\n\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n const rect = host.getBoundingClientRect();\n const cx = e.clientX - rect.left;\n const cy = e.clientY - rect.top;\n\n // CAD-style: any pure-vertical wheel event zooms (mouse wheel on macOS\n // can have |deltaY| < 30 — earlier threshold-based heuristic let those\n // slip into the pan branch, producing a \"wobble\" during zoom).\n // Pinch (ctrl/meta) zooms regardless of axis. Only deltaX-bearing\n // events without a modifier are treated as trackpad pan.\n const isPinch = e.ctrlKey || e.metaKey;\n const isZoom = e.deltaX === 0 || isPinch;\n\n if (isZoom) {\n const factor = isPinch ? ZOOM_FACTOR_PINCH : ZOOM_FACTOR_WHEEL;\n const k = Math.pow(factor, -e.deltaY);\n const next = clamp(vp.current.scale * k, MIN_SCALE, MAX_SCALE);\n // Keep cursor anchored.\n const ratio = next / vp.current.scale;\n vp.current.tx = cx - (cx - vp.current.tx) * ratio;\n vp.current.ty = cy - (cy - vp.current.ty) * ratio;\n vp.current.scale = next;\n } else {\n vp.current.tx -= e.deltaX;\n vp.current.ty -= e.deltaY;\n }\n apply();\n };\n\n const onPointerDown = (e: PointerEvent) => {\n // Middle-click pan, or space-held + left-click pan.\n const isMiddle = e.button === 1;\n const isSpaceLeft = spaceDown && e.button === 0;\n if (!isMiddle && !isSpaceLeft) return;\n e.preventDefault();\n panning = true;\n panPointerId = e.pointerId;\n panStartX = e.clientX;\n panStartY = e.clientY;\n panStartTx = vp.current.tx;\n panStartTy = vp.current.ty;\n host.setPointerCapture(e.pointerId);\n host.style.cursor = 'grabbing';\n };\n const onPointerMove = (e: PointerEvent) => {\n if (!panning || e.pointerId !== panPointerId) return;\n vp.current.tx = panStartTx + (e.clientX - panStartX);\n vp.current.ty = panStartTy + (e.clientY - panStartY);\n apply();\n };\n const onPointerUp = (e: PointerEvent) => {\n if (panning && e.pointerId === panPointerId) {\n panning = false;\n host.releasePointerCapture(e.pointerId);\n host.style.cursor = spaceDown ? 'grab' : '';\n }\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.code === 'Space' && !spaceDown) {\n // Don't hijack typing into a future input element.\n const target = e.target as HTMLElement | null;\n if (target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable)) return;\n spaceDown = true;\n host.style.cursor = 'grab';\n e.preventDefault();\n }\n };\n const onKeyUp = (e: KeyboardEvent) => {\n if (e.code === 'Space') {\n spaceDown = false;\n if (!panning) host.style.cursor = '';\n }\n };\n\n host.addEventListener('wheel', onWheel, { passive: false });\n host.addEventListener('pointerdown', onPointerDown);\n host.addEventListener('pointermove', onPointerMove);\n host.addEventListener('pointerup', onPointerUp);\n host.addEventListener('pointercancel', onPointerUp);\n // Touch handlers run in the capture phase so they can stopPropagation()\n // and prevent the active tool from receiving the events while pinch is\n // in progress.\n host.addEventListener('pointerdown', onTouchPointerDownCap, { capture: true });\n host.addEventListener('pointermove', onTouchPointerMoveCap, { capture: true });\n host.addEventListener('pointerup', onTouchPointerUpCap, { capture: true });\n host.addEventListener('pointercancel', onTouchPointerUpCap, { capture: true });\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n\n apply();\n\n return () => {\n host.removeEventListener('wheel', onWheel);\n host.removeEventListener('pointerdown', onPointerDown);\n host.removeEventListener('pointermove', onPointerMove);\n host.removeEventListener('pointerup', onPointerUp);\n host.removeEventListener('pointercancel', onPointerUp);\n host.removeEventListener('pointerdown', onTouchPointerDownCap, { capture: true });\n host.removeEventListener('pointermove', onTouchPointerMoveCap, { capture: true });\n host.removeEventListener('pointerup', onTouchPointerUpCap, { capture: true });\n host.removeEventListener('pointercancel', onTouchPointerUpCap, { capture: true });\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return {\n screenToSvg(clientX: number, clientY: number) {\n const host = hostRef.current;\n if (!host) return [clientX, clientY];\n const rect = host.getBoundingClientRect();\n const x = (clientX - rect.left - vp.current.tx) / vp.current.scale;\n const y = (clientY - rect.top - vp.current.ty) / vp.current.scale;\n return [x, y];\n },\n getViewport() {\n return { ...vp.current };\n },\n setViewport(patch: Partial<Viewport>) {\n if (patch.tx !== undefined) vp.current.tx = patch.tx;\n if (patch.ty !== undefined) vp.current.ty = patch.ty;\n if (patch.scale !== undefined)\n vp.current.scale = clamp(patch.scale, MIN_SCALE, MAX_SCALE);\n apply();\n },\n subscribe(listener) {\n listeners.current.add(listener);\n return () => {\n listeners.current.delete(listener);\n };\n },\n };\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n","/**\n * Top-level canvas SVG. Owns the pan/zoom viewport `<g>`, the static grid\n * background, and the active-tool dispatcher. Layers (wires, elements,\n * selection, terminals, previews) are children of the viewport so they\n * pan/zoom together.\n *\n * Z-order (back to front): grid → wires → elements → selection → terminals\n * → wire preview → place ghost.\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\nimport {\n BoxSelect,\n Clipboard,\n Copy,\n FlipHorizontal,\n Redo2,\n RotateCw,\n Scissors,\n Trash2,\n Undo2,\n} from 'lucide-react';\nimport { useContextMenu, type ContextMenuEntry } from '../components/ContextMenu';\nimport { useT } from '../i18n';\nimport { useEditorStore } from '../store';\nimport { setViewportApi } from './viewport-bus';\nimport { dropElement } from './drop-on-bus';\nimport { AnnotationLayer } from './AnnotationLayer';\nimport { FreeAnnotationLayer } from './FreeAnnotationLayer';\nimport { BusHandles } from './BusHandles';\nimport { BusLayer } from './BusLayer';\nimport { BusbarPreview } from './BusbarPreview';\nimport { ElementLayer } from './ElementLayer';\nimport { MarqueeOverlay } from './MarqueeOverlay';\nimport { PlaceGhost } from './PlaceGhost';\nimport { SelectionOverlay } from './SelectionOverlay';\nimport { TerminalLayer } from './TerminalLayer';\nimport { WireLayer } from './WireLayer';\nimport { WirePreview } from './WirePreview';\nimport { hitElement, hitNode } from './hit-test';\nimport { dispatchSyntheticPointerCancel } from './synthetic-pointer-cancel';\nimport { exitDrawingState } from './useKeyboardShortcuts';\nimport { useHoverHighlight } from './useHoverHighlight';\nimport { useTools } from './useTools';\nimport { useViewport } from './useViewport';\n\nconst IS_MAC =\n typeof navigator !== 'undefined' && /Mac|iP(ad|hone|od)/.test(navigator.platform);\nconst MOD = IS_MAC ? '⌘' : 'Ctrl+';\nconst SHIFT = IS_MAC ? '⇧' : 'Shift+';\n\n/**\n * Pick a world-space grid step (in snap units) so the rendered tile is at\n * least ~18 screen px. Steps are multiples of the snap step (10) along a\n * 1-2-5 series so every dot still lands on a snappable position.\n */\nconst GRID_STEPS = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000];\nconst MIN_SCREEN_STEP = 18;\nfunction pickGridStep(scale: number): number {\n for (const w of GRID_STEPS) {\n if (w * scale >= MIN_SCREEN_STEP) return w;\n }\n return GRID_STEPS[GRID_STEPS.length - 1];\n}\n\nexport function CanvasSvg() {\n const t = useT();\n const hostRef = useRef<HTMLDivElement | null>(null);\n const groupRef = useRef<SVGGElement | null>(null);\n const gridPatternRef = useRef<SVGPatternElement | null>(null);\n const viewport = useViewport(hostRef, groupRef);\n useTools(hostRef, viewport);\n useHoverHighlight(hostRef);\n useEffect(() => {\n setViewportApi(viewport);\n return () => setViewportApi(null);\n }, [viewport]);\n // Dot grid: stays locked to world coordinates (so dots line up with snap\n // targets) but the *visible* spacing adapts to zoom. Picking a world-step\n // that's a multiple of the snap step (10) and large enough to render\n // ≥ MIN_SCREEN_STEP screen pixels keeps the grid readable from 0.1× to 8×\n // without dots either piling into a haze or growing into giant blobs.\n useEffect(() => {\n const sync = (vp: { tx: number; ty: number; scale: number }) => {\n const el = gridPatternRef.current;\n if (!el) return;\n const worldStep = pickGridStep(vp.scale);\n const screenStep = worldStep * vp.scale;\n el.setAttribute('width', String(screenStep));\n el.setAttribute('height', String(screenStep));\n el.setAttribute('patternTransform', `translate(${vp.tx} ${vp.ty})`);\n };\n sync(viewport.getViewport());\n return viewport.subscribe(sync);\n }, [viewport]);\n const contextMenu = useContextMenu();\n\n // Open the contextual menu at a screen point, hit-testing the given target\n // so the menu's selection-aware items (cut/copy/rotate/etc.) reflect what\n // the user is pointing at. Shared by mouse right-click and touch long-press.\n const openContextMenuAt = useCallback(\n (clientX: number, clientY: number, target: EventTarget | null) => {\n const store = useEditorStore.getState();\n const tool = store.activeTool;\n if (tool === 'wire' || tool === 'busbar' || tool === 'place') {\n exitDrawingState();\n return;\n }\n const elementId = hitElement(target);\n if (elementId) {\n if (!store.selection.includes(elementId)) {\n store.setSelection([elementId]);\n }\n } else {\n const nodeId = hitNode(target);\n if (nodeId && store.selectedNode !== nodeId) {\n store.setSelectedNode(nodeId);\n }\n }\n\n const s = useEditorStore.getState();\n const hasSelection = s.selection.length > 0;\n const hasNodeSelection = s.selectedNode != null;\n const hasClipboard = !!s.clipboard;\n const hasAnyElement = s.diagram.elements.length > 0;\n const items: ContextMenuEntry[] = [\n {\n label: t('menu.undo'),\n shortcut: `${MOD}Z`,\n icon: Undo2,\n onSelect: () => useEditorStore.getState().undo(),\n disabled: s.past.length === 0,\n },\n {\n label: t('menu.redo'),\n shortcut: `${MOD}${SHIFT}Z`,\n icon: Redo2,\n onSelect: () => useEditorStore.getState().redo(),\n disabled: s.future.length === 0,\n },\n { type: 'separator' },\n {\n label: t('menu.cut'),\n shortcut: `${MOD}X`,\n icon: Scissors,\n onSelect: () => useEditorStore.getState().cutSelection(),\n disabled: !hasSelection,\n },\n {\n label: t('menu.copy'),\n shortcut: `${MOD}C`,\n icon: Copy,\n onSelect: () => useEditorStore.getState().copySelection(),\n disabled: !hasSelection,\n },\n {\n label: t('menu.paste'),\n shortcut: `${MOD}V`,\n icon: Clipboard,\n onSelect: () => useEditorStore.getState().pasteClipboard(),\n disabled: !hasClipboard,\n },\n { type: 'separator' },\n {\n label: t('menu.rotate'),\n shortcut: 'R',\n icon: RotateCw,\n onSelect: () => useEditorStore.getState().rotateSelection(90),\n disabled: !hasSelection,\n },\n {\n label: t('menu.mirror'),\n shortcut: 'M',\n icon: FlipHorizontal,\n onSelect: () => useEditorStore.getState().mirrorSelection(),\n disabled: !hasSelection,\n },\n { type: 'separator' },\n {\n label: t('menu.selectAll'),\n shortcut: `${MOD}A`,\n icon: BoxSelect,\n onSelect: () => {\n const st = useEditorStore.getState();\n st.setSelection(st.diagram.elements.map((x) => x.id));\n },\n disabled: !hasAnyElement,\n },\n { type: 'separator' },\n {\n label: hasNodeSelection && !hasSelection ? t('menu.disconnect') : t('menu.delete'),\n shortcut: 'Del',\n icon: Trash2,\n destructive: true,\n onSelect: () =>\n hasNodeSelection && !hasSelection\n ? useEditorStore.getState().deleteSelectedNode()\n : useEditorStore.getState().deleteSelection(),\n disabled: !hasSelection && !hasNodeSelection,\n },\n ];\n contextMenu.open(clientX, clientY, items);\n },\n [contextMenu, t],\n );\n\n // Long-press → context menu (touch-only equivalent of right-click). On\n // touch devices there is no right button, so we open the same menu after\n // the user holds a single finger still for ~700ms. The movement threshold\n // matches PanTool's tap threshold so a slow pan can't accidentally hover\n // long enough to fire the menu mid-drag. A second touch (pinch) cancels\n // via the synthetic pointercancel from useViewport.\n //\n // Listeners are native (not React-synthetic) so they fire deterministically\n // alongside the tool's native pointer handlers in `useTools`. React's\n // synthetic dispatch was racing with selection re-renders triggered by\n // PanTool's tap-to-select, occasionally dropping the pointerup that should\n // have cancelled the timer.\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const LONG_PRESS_MS = 700;\n const LONG_PRESS_MOVE_PX = 4;\n let timer: number | undefined;\n let data: { pointerId: number; x: number; y: number; target: EventTarget | null } | null = null;\n const cancel = () => {\n if (timer !== undefined) window.clearTimeout(timer);\n timer = undefined;\n data = null;\n };\n const onDown = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') return;\n cancel();\n data = {\n pointerId: e.pointerId,\n x: e.clientX,\n y: e.clientY,\n target: e.target,\n };\n timer = window.setTimeout(() => {\n const d = data;\n data = null;\n timer = undefined;\n if (!d) return;\n // Cancel the active tool's in-progress gesture so the long-press\n // doesn't double as a drag commit when the user releases.\n dispatchSyntheticPointerCancel(host, d.pointerId);\n openContextMenuAt(d.x, d.y, d.target);\n }, LONG_PRESS_MS);\n };\n const onMove = (e: PointerEvent) => {\n if (!data || e.pointerId !== data.pointerId) return;\n const dx = e.clientX - data.x;\n const dy = e.clientY - data.y;\n if (Math.hypot(dx, dy) > LONG_PRESS_MOVE_PX) cancel();\n };\n const onEnd = (e: PointerEvent) => {\n if (!data || e.pointerId !== data.pointerId) return;\n cancel();\n };\n host.addEventListener('pointerdown', onDown);\n host.addEventListener('pointermove', onMove);\n host.addEventListener('pointerup', onEnd);\n host.addEventListener('pointercancel', onEnd);\n return () => {\n cancel();\n host.removeEventListener('pointerdown', onDown);\n host.removeEventListener('pointermove', onMove);\n host.removeEventListener('pointerup', onEnd);\n host.removeEventListener('pointercancel', onEnd);\n };\n }, [openContextMenuAt]);\n\n const onDragOver = (e: React.DragEvent) => {\n if (e.dataTransfer.types.includes('application/x-oneline-kind')) {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n }\n };\n\n const onDrop = (e: React.DragEvent) => {\n const kind = e.dataTransfer.getData('application/x-oneline-kind');\n if (!kind) return;\n e.preventDefault();\n const pt = viewport.screenToSvg(e.clientX, e.clientY);\n dropElement(kind, pt);\n };\n\n const onContextMenu = (e: React.MouseEvent) => {\n e.preventDefault();\n openContextMenuAt(e.clientX, e.clientY, e.target);\n };\n\n return (\n <div\n ref={hostRef}\n className=\"ole-canvas-root absolute inset-0 overflow-hidden\"\n onDragOver={onDragOver}\n onDrop={onDrop}\n onContextMenu={onContextMenu}\n >\n <svg\n className=\"ole-canvas-svg block h-full w-full\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <pattern\n ref={gridPatternRef}\n id=\"ole-grid-dots\"\n width={20}\n height={20}\n patternUnits=\"userSpaceOnUse\"\n >\n {/* Dot at the cell corner so every visible dot lands on a snap\n position (snap step = 10, pattern step = 20 → every dot is on\n a multiple-of-20 snap point). */}\n <circle cx={0} cy={0} r={2} fill=\"var(--canvas-grid-strong)\" />\n </pattern>\n </defs>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#ole-grid-dots)\" />\n <g ref={groupRef} className=\"ole-viewport\">\n <BusLayer />\n <WireLayer />\n <ElementLayer />\n <AnnotationLayer />\n <FreeAnnotationLayer />\n <SelectionOverlay />\n <BusHandles />\n <TerminalLayer />\n <WirePreview />\n <BusbarPreview />\n <PlaceGhost />\n <MarqueeOverlay />\n </g>\n </svg>\n </div>\n );\n}\n","/**\n * Fit-to-content viewport reset, shared by the explicit \"fit\" button in\n * ViewToolbar and the automatic reset that fires on first mount / after\n * loading a file.\n *\n * Element bboxes come from the live DOM (`data-element-id` nodes), so the\n * canvas must already have rendered the diagram. `fitToContentSoon` defers\n * via rAF until that's true (typical use: store update → next frame fit).\n */\n\nimport { getViewportApi } from './viewport-bus';\n\nconst FIT_PADDING_PX = 60;\nconst MIN_SCALE = 0.1;\nconst MAX_SCALE = 8;\nconst READY_RETRY_FRAMES = 8;\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n\nfunction getCanvasRoot(): HTMLElement | null {\n return document.querySelector('.ole-canvas-root');\n}\n\n/**\n * Fit all rendered elements to the viewport with padding. Falls back to a\n * centered 100% reset when the canvas is empty. Returns false if the\n * viewport / canvas isn't ready yet.\n */\nexport function fitToContent(): boolean {\n const api = getViewportApi();\n const root = getCanvasRoot();\n if (!api || !root) return false;\n const rect = root.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return false;\n const nodes = root.querySelectorAll('[data-element-id]');\n if (nodes.length === 0) {\n api.setViewport({ tx: rect.width / 2, ty: rect.height / 2, scale: 1 });\n return true;\n }\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const n of nodes) {\n const r = (n as Element).getBoundingClientRect();\n if (r.width === 0 && r.height === 0) continue;\n if (r.left < minX) minX = r.left;\n if (r.top < minY) minY = r.top;\n if (r.right > maxX) maxX = r.right;\n if (r.bottom > maxY) maxY = r.bottom;\n }\n if (minX === Infinity) return false;\n const [ax, ay] = api.screenToSvg(minX, minY);\n const [bx, by] = api.screenToSvg(maxX, maxY);\n const contentW = Math.max(bx - ax, 1);\n const contentH = Math.max(by - ay, 1);\n const targetScale = clamp(\n Math.min(\n (rect.width - FIT_PADDING_PX * 2) / contentW,\n (rect.height - FIT_PADDING_PX * 2) / contentH,\n ),\n MIN_SCALE,\n MAX_SCALE,\n );\n const cx = (ax + bx) / 2;\n const cy = (ay + by) / 2;\n api.setViewport({\n tx: rect.width / 2 - targetScale * cx,\n ty: rect.height / 2 - targetScale * cy,\n scale: targetScale,\n });\n return true;\n}\n\n/**\n * Run `fitToContent` after the next paint, retrying for a few frames in case\n * the canvas hasn't mounted yet (initial mount race) or the diagram has\n * just been swapped and the new DOM nodes aren't yet attached.\n */\nexport function fitToContentSoon(): void {\n let frames = READY_RETRY_FRAMES;\n const tick = () => {\n if (fitToContent()) return;\n if (--frames > 0) requestAnimationFrame(tick);\n };\n requestAnimationFrame(tick);\n}\n","/**\n * Floating name tag that follows the hovered element on the canvas. Reads\n * the hover signal published by `useHoverHighlight` and locates the\n * element's `<g>` via the DOM (so it tracks pan, zoom, and live drags\n * without re-rendering React). Shows `name (kind)` or just `id` for\n * unnamed elements; portals to body so it isn't clipped.\n */\n\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { libraryById } from '../element-library';\nimport { useEditorStore } from '../store';\nimport type { ElementId } from '../model';\nimport { getHoverElement, subscribeHoverElement } from './hover-bus';\n\ninterface Anchor {\n top: number;\n left: number;\n}\n\nconst GAP_PX = 10;\nconst SHOW_DELAY_MS = 100;\n\n// Coarse-pointer / no-hover devices (touch) get no hover tooltip — there's\n// no equivalent gesture for \"hover an element to see its name\" on touch.\nfunction isCoarsePointer(): boolean {\n if (typeof window === 'undefined' || !window.matchMedia) return false;\n return window.matchMedia('(hover: none), (pointer: coarse)').matches;\n}\n\nexport function ElementHoverLabel() {\n const [hoverId, setHoverId] = useState<ElementId | null>(getHoverElement());\n const [shown, setShown] = useState(false);\n const [anchor, setAnchor] = useState<Anchor | null>(null);\n const labelRef = useRef<HTMLDivElement>(null);\n const showTimer = useRef<number | undefined>(undefined);\n const [coarse] = useState(isCoarsePointer);\n\n // The hover signal can flicker as the cursor crosses element edges. The\n // delayed-show smooths that out without making the tooltip feel laggy on\n // a steady hover.\n useEffect(() => {\n return subscribeHoverElement((id) => setHoverId(id));\n }, []);\n\n useEffect(() => {\n window.clearTimeout(showTimer.current);\n // Hide first whenever the target changes — keeps the tooltip from\n // teleporting between elements during fast cursor sweeps. The new label\n // re-appears only after the cursor settles on `hoverId` for SHOW_DELAY_MS.\n setShown(false);\n setAnchor(null);\n if (!hoverId) return;\n showTimer.current = window.setTimeout(() => setShown(true), SHOW_DELAY_MS);\n return () => window.clearTimeout(showTimer.current);\n }, [hoverId]);\n\n // Look up the element name + kind for the current hover.\n const elementName = useEditorStore((s) => {\n if (!hoverId) return null;\n return s.diagram.elements.find((e) => e.id === hoverId) ?? null;\n });\n\n // Reposition each frame while shown — handles pan/zoom/drag without React.\n useLayoutEffect(() => {\n if (!shown || !hoverId) return;\n let raf = 0;\n let lastTop = -1;\n let lastLeft = -1;\n const tick = () => {\n const node = document.querySelector(\n `[data-element-id=\"${cssEscape(hoverId)}\"]`,\n );\n const tip = labelRef.current;\n if (node && tip) {\n const r = node.getBoundingClientRect();\n // Default below so we don't collide with the contextual toolbar\n // (which prefers above the selection); flip up only when there's\n // no room below.\n let top = r.bottom + GAP_PX;\n if (top + tip.offsetHeight > window.innerHeight - 4) {\n top = r.top - tip.offsetHeight - GAP_PX;\n }\n let left = r.left + r.width / 2 - tip.offsetWidth / 2;\n left = Math.max(4, Math.min(left, window.innerWidth - tip.offsetWidth - 4));\n if (top !== lastTop || left !== lastLeft) {\n setAnchor({ top, left });\n lastTop = top;\n lastLeft = left;\n }\n }\n raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n }, [shown, hoverId]);\n\n if (coarse) return null;\n if (!shown || !hoverId || !elementName) return null;\n const lib = libraryById[elementName.kind];\n const display = elementName.name ?? elementName.id;\n const subtitle = lib?.name ?? elementName.kind;\n const showId = elementName.name && elementName.name !== elementName.id;\n\n if (typeof document === 'undefined') return null;\n return createPortal(\n <div\n ref={labelRef}\n role=\"tooltip\"\n className=\"ole-root ole-glass pointer-events-none fixed z-[100] flex items-center gap-1.5 rounded-md border border-border px-2 py-1 text-[11px] leading-snug shadow-md\"\n style={{\n top: anchor?.top ?? -9999,\n left: anchor?.left ?? -9999,\n opacity: anchor ? 1 : 0,\n transition: 'opacity 80ms ease-out',\n }}\n >\n <span className=\"font-medium text-foreground\">{display}</span>\n {showId && (\n <span className=\"font-mono text-[10px] text-muted-foreground\">\n {elementName.id}\n </span>\n )}\n <span className=\"text-muted-foreground/80\">·</span>\n <span className=\"text-muted-foreground\">{subtitle}</span>\n </div>,\n document.body,\n );\n}\n\nfunction cssEscape(s: string): string {\n return s.replace(/([\"\\\\])/g, '\\\\$1');\n}\n","/**\n * Editor tier provider — wraps the editor's chrome with a context value\n * derived from a width supplied by the parent. The parent is the only one\n * that holds the DOM ref, so we keep the ResizeObserver there and just\n * push the resolved tier down through context.\n *\n * Pure helpers / hook live in `./editor-tier`.\n */\n\nimport type { ReactNode } from 'react';\nimport { TierContext, tierForWidth } from './editor-tier';\n\nexport function EditorTierProvider({\n width,\n children,\n}: {\n width: number | null;\n children: ReactNode;\n}) {\n const tier = width == null ? 'full' : tierForWidth(width);\n return <TierContext.Provider value={tier}>{children}</TierContext.Provider>;\n}\n","// packages/react/compose-refs/src/compose-refs.tsx\nimport * as React from \"react\";\nfunction setRef(ref, value) {\n if (typeof ref === \"function\") {\n return ref(value);\n } else if (ref !== null && ref !== void 0) {\n ref.current = value;\n }\n}\nfunction composeRefs(...refs) {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup == \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup == \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\nfunction useComposedRefs(...refs) {\n return React.useCallback(composeRefs(...refs), refs);\n}\nexport {\n composeRefs,\n useComposedRefs\n};\n//# sourceMappingURL=index.mjs.map\n","// src/slot.tsx\nimport * as React from \"react\";\nimport { composeRefs } from \"@radix-ui/react-compose-refs\";\nimport { Fragment as Fragment2, jsx } from \"react/jsx-runtime\";\nvar REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\nvar use = React[\" use \".trim().toString()];\nfunction isPromiseLike(value) {\n return typeof value === \"object\" && value !== null && \"then\" in value;\n}\nfunction isLazyComponent(element) {\n return element != null && typeof element === \"object\" && \"$$typeof\" in element && element.$$typeof === REACT_LAZY_TYPE && \"_payload\" in element && isPromiseLike(element._payload);\n}\n// @__NO_SIDE_EFFECTS__\nfunction createSlot(ownerName) {\n const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);\n const Slot2 = React.forwardRef((props, forwardedRef) => {\n let { children, ...slotProps } = props;\n if (isLazyComponent(children) && typeof use === \"function\") {\n children = use(children._payload);\n }\n const childrenArray = React.Children.toArray(children);\n const slottable = childrenArray.find(isSlottable);\n if (slottable) {\n const newElement = slottable.props.children;\n const newChildren = childrenArray.map((child) => {\n if (child === slottable) {\n if (React.Children.count(newElement) > 1) return React.Children.only(null);\n return React.isValidElement(newElement) ? newElement.props.children : null;\n } else {\n return child;\n }\n });\n return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React.isValidElement(newElement) ? React.cloneElement(newElement, void 0, newChildren) : null });\n }\n return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });\n });\n Slot2.displayName = `${ownerName}.Slot`;\n return Slot2;\n}\nvar Slot = /* @__PURE__ */ createSlot(\"Slot\");\n// @__NO_SIDE_EFFECTS__\nfunction createSlotClone(ownerName) {\n const SlotClone = React.forwardRef((props, forwardedRef) => {\n let { children, ...slotProps } = props;\n if (isLazyComponent(children) && typeof use === \"function\") {\n children = use(children._payload);\n }\n if (React.isValidElement(children)) {\n const childrenRef = getElementRef(children);\n const props2 = mergeProps(slotProps, children.props);\n if (children.type !== React.Fragment) {\n props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;\n }\n return React.cloneElement(children, props2);\n }\n return React.Children.count(children) > 1 ? React.Children.only(null) : null;\n });\n SlotClone.displayName = `${ownerName}.SlotClone`;\n return SlotClone;\n}\nvar SLOTTABLE_IDENTIFIER = Symbol(\"radix.slottable\");\n// @__NO_SIDE_EFFECTS__\nfunction createSlottable(ownerName) {\n const Slottable2 = ({ children }) => {\n return /* @__PURE__ */ jsx(Fragment2, { children });\n };\n Slottable2.displayName = `${ownerName}.Slottable`;\n Slottable2.__radixId = SLOTTABLE_IDENTIFIER;\n return Slottable2;\n}\nvar Slottable = /* @__PURE__ */ createSlottable(\"Slottable\");\nfunction isSlottable(child) {\n return React.isValidElement(child) && typeof child.type === \"function\" && \"__radixId\" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;\n}\nfunction mergeProps(slotProps, childProps) {\n const overrideProps = { ...childProps };\n for (const propName in childProps) {\n const slotPropValue = slotProps[propName];\n const childPropValue = childProps[propName];\n const isHandler = /^on[A-Z]/.test(propName);\n if (isHandler) {\n if (slotPropValue && childPropValue) {\n overrideProps[propName] = (...args) => {\n const result = childPropValue(...args);\n slotPropValue(...args);\n return result;\n };\n } else if (slotPropValue) {\n overrideProps[propName] = slotPropValue;\n }\n } else if (propName === \"style\") {\n overrideProps[propName] = { ...slotPropValue, ...childPropValue };\n } else if (propName === \"className\") {\n overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(\" \");\n }\n }\n return { ...slotProps, ...overrideProps };\n}\nfunction getElementRef(element) {\n let getter = Object.getOwnPropertyDescriptor(element.props, \"ref\")?.get;\n let mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.ref;\n }\n getter = Object.getOwnPropertyDescriptor(element, \"ref\")?.get;\n mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.props.ref;\n }\n return element.props.ref || element.ref;\n}\nexport {\n Slot as Root,\n Slot,\n Slottable,\n createSlot,\n createSlottable\n};\n//# sourceMappingURL=index.mjs.map\n","/**\n * Copyright 2022 Joe Bell. All rights reserved.\n *\n * This file is licensed to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with the\n * License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */ import { clsx } from \"clsx\";\nconst falsyToString = (value)=>typeof value === \"boolean\" ? `${value}` : value === 0 ? \"0\" : value;\nexport const cx = clsx;\nexport const cva = (base, config)=>(props)=>{\n var _config_compoundVariants;\n if ((config === null || config === void 0 ? void 0 : config.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);\n const { variants, defaultVariants } = config;\n const getVariantClassNames = Object.keys(variants).map((variant)=>{\n const variantProp = props === null || props === void 0 ? void 0 : props[variant];\n const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];\n if (variantProp === null) return null;\n const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);\n return variants[variant][variantKey];\n });\n const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param)=>{\n let [key, value] = param;\n if (value === undefined) {\n return acc;\n }\n acc[key] = value;\n return acc;\n }, {});\n const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (_config_compoundVariants = config.compoundVariants) === null || _config_compoundVariants === void 0 ? void 0 : _config_compoundVariants.reduce((acc, param)=>{\n let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param;\n return Object.entries(compoundVariantOptions).every((param)=>{\n let [key, value] = param;\n return Array.isArray(value) ? value.includes({\n ...defaultVariants,\n ...propsWithoutUndefined\n }[key]) : ({\n ...defaultVariants,\n ...propsWithoutUndefined\n })[key] === value;\n }) ? [\n ...acc,\n cvClass,\n cvClassName\n ] : acc;\n }, []);\n return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);\n };\n\n","import * as React from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '../../lib/utils';\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n outline:\n 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = 'Button';\n\nexport { buttonVariants };\n","/**\n * Lightweight tooltip — no Radix dependency. Shows content after a short\n * hover delay, portals to body so it isn't clipped by the floating panel,\n * and auto-flips above/below based on viewport space.\n *\n * Usage:\n * <Tooltip content=\"Hide grid (G)\">\n * <Button>...</Button>\n * </Tooltip>\n *\n * The trigger MUST be a single React element accepting a ref; we attach\n * pointer/focus listeners on it without prop-drilling.\n */\n\nimport {\n cloneElement,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nconst SHOW_DELAY_MS = 350;\n\ninterface Anchor {\n top: number;\n left: number;\n side: 'top' | 'bottom';\n}\n\nexport interface TooltipProps {\n content: ReactNode;\n children: ReactElement<{\n ref?: React.Ref<HTMLElement>;\n onPointerEnter?: (e: React.PointerEvent) => void;\n onPointerLeave?: (e: React.PointerEvent) => void;\n onFocus?: (e: React.FocusEvent) => void;\n onBlur?: (e: React.FocusEvent) => void;\n 'aria-describedby'?: string;\n }>;\n /** Force-disable (e.g. when the trigger is disabled). */\n disabled?: boolean;\n /** Override the default 350ms hover delay. */\n delayMs?: number;\n}\n\nexport function Tooltip({\n content,\n children,\n disabled,\n delayMs = SHOW_DELAY_MS,\n}: TooltipProps) {\n const triggerRef = useRef<HTMLElement | null>(null);\n const tooltipRef = useRef<HTMLDivElement | null>(null);\n const [open, setOpen] = useState(false);\n const [anchor, setAnchor] = useState<Anchor | null>(null);\n const id = useId();\n const timer = useRef<number | undefined>(undefined);\n\n const scheduleShow = () => {\n if (disabled) return;\n window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => setOpen(true), delayMs);\n };\n\n const cancelShow = () => {\n window.clearTimeout(timer.current);\n setOpen(false);\n };\n\n // Recompute anchor position when open changes or content changes.\n useLayoutEffect(() => {\n if (!open || !triggerRef.current || !tooltipRef.current) return;\n const t = triggerRef.current.getBoundingClientRect();\n const tip = tooltipRef.current.getBoundingClientRect();\n const margin = 8;\n let side: 'top' | 'bottom' = 'top';\n let top = t.top - tip.height - margin;\n if (top < 4) {\n side = 'bottom';\n top = t.bottom + margin;\n }\n let left = t.left + t.width / 2 - tip.width / 2;\n left = Math.max(4, Math.min(left, window.innerWidth - tip.width - 4));\n setAnchor({ top, left, side });\n }, [open, content]);\n\n // Cleanup on unmount.\n useEffect(() => () => window.clearTimeout(timer.current), []);\n\n // Hide on Escape and on scroll/resize.\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n const onScroll = () => setOpen(false);\n window.addEventListener('keydown', onKey);\n window.addEventListener('scroll', onScroll, true);\n window.addEventListener('resize', onScroll);\n return () => {\n window.removeEventListener('keydown', onKey);\n window.removeEventListener('scroll', onScroll, true);\n window.removeEventListener('resize', onScroll);\n };\n }, [open]);\n\n // We attach our handlers on top of any existing ones on the trigger.\n const child = children;\n const childProps = child.props;\n const wrappedTrigger = cloneElement(child, {\n ref: (node: HTMLElement | null) => {\n triggerRef.current = node;\n const orig = (child as { ref?: React.Ref<HTMLElement> }).ref;\n if (typeof orig === 'function') orig(node);\n else if (orig && typeof orig === 'object') {\n (orig as React.MutableRefObject<HTMLElement | null>).current = node;\n }\n },\n onPointerEnter: (e: React.PointerEvent) => {\n childProps.onPointerEnter?.(e);\n scheduleShow();\n },\n onPointerLeave: (e: React.PointerEvent) => {\n childProps.onPointerLeave?.(e);\n cancelShow();\n },\n onFocus: (e: React.FocusEvent) => {\n childProps.onFocus?.(e);\n scheduleShow();\n },\n onBlur: (e: React.FocusEvent) => {\n childProps.onBlur?.(e);\n cancelShow();\n },\n 'aria-describedby': open ? id : childProps['aria-describedby'],\n });\n\n return (\n <>\n {wrappedTrigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n <div\n ref={tooltipRef}\n id={id}\n role=\"tooltip\"\n data-side={anchor?.side ?? 'top'}\n className=\"ole-root ole-glass pointer-events-none fixed z-[100] max-w-[280px] rounded-md border border-border px-2 py-1 text-[11px] leading-snug text-foreground shadow-md\"\n style={{\n top: anchor?.top ?? -9999,\n left: anchor?.left ?? -9999,\n opacity: anchor ? 1 : 0,\n transition: 'opacity 80ms ease-out',\n }}\n >\n {content}\n </div>,\n document.body,\n )}\n </>\n );\n}\n","/**\n * Canva-style contextual floating toolbar that follows the selected element\n * (or selection bbox) — and the selected wire/node, since v0.4. Renders the\n * relevant primary actions (rotate / mirror / delete for elements, delete\n * for nodes) right next to the work, so the eye doesn't need to travel.\n *\n * Position is updated each frame via rAF + DOM transform — no React state in\n * the hot loop. The toolbar reads from the canvas DOM each frame which means\n * it tracks pan, zoom, and element/wire moves \"for free\".\n */\n\nimport { useEffect, useRef } from 'react';\nimport { FlipHorizontal, RotateCw, Trash2 } from 'lucide-react';\nimport { Button } from './ui/button';\nimport { Tooltip } from './ui/tooltip';\nimport { useT } from '../i18n';\nimport { useEditorStore } from '../store';\n\nconst GAP_PX = 12;\nconst TOP_FLIP_THRESHOLD_PX = 56;\n\nexport function ContextualToolbar() {\n const t = useT();\n const selection = useEditorStore((s) => s.selection);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const selectedWire = useEditorStore((s) => s.selectedWire);\n const activeTool = useEditorStore((s) => s.activeTool);\n const rotate = useEditorStore((s) => s.rotateSelection);\n const mirror = useEditorStore((s) => s.mirrorSelection);\n const del = useEditorStore((s) => s.deleteSelection);\n const delNode = useEditorStore((s) => s.deleteSelectedNode);\n const delWire = useEditorStore((s) => s.deleteSelectedWire);\n\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const isElementMode = selection.length > 0;\n const isWireMode = !isElementMode && selectedWire != null;\n const isNodeMode = !isElementMode && !isWireMode && selectedNode != null;\n const visible =\n (isElementMode || isWireMode || isNodeMode) &&\n (activeTool === 'select' || activeTool === 'pan');\n if (!visible) {\n el.style.display = 'none';\n return;\n }\n el.style.display = 'flex';\n\n let raf = 0;\n let lastTransform = '';\n const tick = () => {\n let left = Infinity;\n let right = -Infinity;\n let top = Infinity;\n let bottom = -Infinity;\n let any = false;\n const accept = (r: DOMRect) => {\n if (r.width === 0 && r.height === 0) return;\n if (r.left < left) left = r.left;\n if (r.right > right) right = r.right;\n if (r.top < top) top = r.top;\n if (r.bottom > bottom) bottom = r.bottom;\n any = true;\n };\n if (isElementMode) {\n for (const id of selection) {\n const node = document.querySelector(\n `[data-element-id=\"${CSS.escape(id)}\"]`,\n );\n if (node) accept(node.getBoundingClientRect());\n }\n } else if (isWireMode && selectedWire) {\n const w = document.querySelector(\n `polyline.ole-wire[data-wire-id=\"${CSS.escape(selectedWire)}\"]`,\n );\n if (w) accept((w as Element).getBoundingClientRect());\n } else if (isNodeMode && selectedNode) {\n const wires = document.querySelectorAll(\n `polyline.ole-wire[data-node-id=\"${CSS.escape(selectedNode)}\"]`,\n );\n for (const w of wires) accept((w as Element).getBoundingClientRect());\n }\n if (any) {\n const cx = (left + right) / 2;\n let ty = top - GAP_PX;\n let translateY = '-100%';\n // Flip below if there's no room above.\n if (ty < TOP_FLIP_THRESHOLD_PX) {\n ty = bottom + GAP_PX;\n translateY = '0%';\n }\n const transform = `translate3d(${cx}px, ${ty}px, 0) translate(-50%, ${translateY})`;\n if (transform !== lastTransform) {\n el.style.transform = transform;\n lastTransform = transform;\n }\n }\n raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n }, [selection, selectedNode, selectedWire, activeTool]);\n\n const isWireMode = selection.length === 0 && selectedWire != null;\n const isNodeMode = selection.length === 0 && !isWireMode && selectedNode != null;\n const hideTransform = isNodeMode || isWireMode;\n\n return (\n <div\n ref={ref}\n role=\"toolbar\"\n aria-label={\n isWireMode\n ? t('ctx.ariaWire')\n : isNodeMode\n ? t('ctx.ariaNode')\n : t('ctx.ariaElement')\n }\n className=\"ole-glass pointer-events-auto fixed left-0 top-0 z-30 hidden items-center gap-0.5 rounded-2xl border border-border p-1 shadow-md\"\n >\n {!hideTransform && (\n <>\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">{t('ctx.rotate')}</span>\n <span className=\"ml-1.5 text-muted-foreground\">R</span>\n </div>\n <div className=\"text-muted-foreground\">{t('ctx.rotateHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n onClick={() => rotate(90)}\n aria-label={t('ctx.rotate')}\n >\n <RotateCw />\n </Button>\n </Tooltip>\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">{t('ctx.mirror')}</span>\n <span className=\"ml-1.5 text-muted-foreground\">M</span>\n </div>\n <div className=\"text-muted-foreground\">{t('ctx.mirrorHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n onClick={() => mirror()}\n aria-label={t('ctx.mirrorTitle')}\n >\n <FlipHorizontal />\n </Button>\n </Tooltip>\n <div aria-hidden className=\"mx-0.5 h-4 w-px bg-border\" />\n </>\n )}\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">{t('ctx.delete')}</span>\n <span className=\"ml-1.5 text-muted-foreground\">Del</span>\n </div>\n <div className=\"text-muted-foreground\">\n {isWireMode\n ? t('ctx.deleteHintWire')\n : isNodeMode\n ? t('ctx.deleteHintNode')\n : t('ctx.deleteHintElement')}\n </div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7 text-destructive hover:text-destructive\"\n onClick={() =>\n isWireMode ? delWire() : isNodeMode ? delNode() : del()\n }\n aria-label={t('ctx.delete')}\n >\n <Trash2 />\n </Button>\n </Tooltip>\n </div>\n );\n}\n","/**\n * Anchored popover that opens upward — used by the bottom-anchored\n * FloatingToolbar / ViewToolbar where a downward-opening menu would clip\n * below the viewport. Closes on outside click and Esc.\n */\n\nimport { useEffect, useRef, type ReactNode } from 'react';\n\nexport function UpwardPopover({\n open,\n onOpenChange,\n trigger,\n children,\n}: {\n open: boolean;\n onOpenChange: (next: boolean) => void;\n trigger: ReactNode;\n children: ReactNode;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) onOpenChange(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onOpenChange(false);\n };\n window.addEventListener('mousedown', onClick);\n window.addEventListener('keydown', onKey);\n return () => {\n window.removeEventListener('mousedown', onClick);\n window.removeEventListener('keydown', onKey);\n };\n }, [open, onOpenChange]);\n return (\n <div ref={ref} className=\"relative\">\n {trigger}\n {open && (\n <div\n role=\"menu\"\n className=\"ole-glass absolute bottom-full right-0 mb-1.5 min-w-52 rounded-md border border-border p-1 shadow-md\"\n >\n {children}\n </div>\n )}\n </div>\n );\n}\n","/**\n * Tiny Zustand store for cross-component panel open/closed state.\n *\n * The outline panel toggle lives at bottom-left and persists across reloads.\n * The library popover is no longer tracked here — it follows the editor's\n * active tool (`activeTool === 'place'`) so the toolbar button behaves like\n * any other mutually-exclusive tool.\n */\n\nimport { create } from 'zustand';\n\nconst STORAGE_KEY = 'ole-panel-open';\n\ninterface Persisted {\n outline: boolean;\n}\n\ninterface PanelState {\n outlineOpen: boolean;\n setOutlineOpen: (open: boolean) => void;\n toggleOutline: () => void;\n}\n\nfunction readInitial(): Pick<PanelState, 'outlineOpen'> {\n if (typeof window === 'undefined') return { outlineOpen: false };\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return { outlineOpen: false };\n const obj = JSON.parse(raw) as unknown;\n if (typeof obj !== 'object' || obj === null) return { outlineOpen: false };\n const o = obj as Record<string, unknown>;\n return { outlineOpen: o.outline === true };\n } catch {\n return { outlineOpen: false };\n }\n}\n\nfunction persist(s: { outlineOpen: boolean }): void {\n try {\n const data: Persisted = { outline: s.outlineOpen };\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n } catch {\n // ignore quota / disabled storage\n }\n}\n\nexport const usePanels = create<PanelState>((set, get) => ({\n ...readInitial(),\n setOutlineOpen: (outlineOpen) => {\n set({ outlineOpen });\n persist(get());\n },\n toggleOutline: () => {\n set((s) => ({ outlineOpen: !s.outlineOpen }));\n persist(get());\n },\n}));\n","import { useEffect, useState } from 'react';\nimport {\n Grid2x2,\n Maximize2,\n Minus,\n MoreHorizontal,\n Plus,\n Type,\n} from 'lucide-react';\nimport { Button } from './ui/button';\nimport { Tooltip } from './ui/tooltip';\nimport { UpwardPopover } from './ui/upward-popover';\nimport {\n fitToContent,\n getViewportApi,\n getScale,\n subscribeScale,\n} from '../canvas';\nimport { atLeast, useEditorTier, type Tier } from '../hooks/editor-tier';\nimport { useT } from '../i18n';\nimport { cn } from '../lib/utils';\nimport { useEditorStore } from '../store';\nimport type { LabelMode } from '../model';\n\nconst ZOOM_STEPS = [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4, 6, 8] as const;\nconst MIN_SCALE = 0.1;\nconst MAX_SCALE = 8;\n\nconst GRID_STORAGE_KEY = 'ole-grid';\n\nfunction readGrid(): boolean {\n try {\n const v = window.localStorage.getItem(GRID_STORAGE_KEY);\n return v == null ? true : v === '1';\n } catch {\n return true;\n }\n}\nfunction writeGrid(v: boolean): void {\n try {\n window.localStorage.setItem(GRID_STORAGE_KEY, v ? '1' : '0');\n } catch {\n // ignore\n }\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n\nfunction getCanvasRoot(): HTMLElement | null {\n return document.querySelector('.ole-canvas-root');\n}\n\n/** Apply a target scale, anchored at the canvas viewport center. */\nfunction zoomTo(target: number): void {\n const api = getViewportApi();\n const root = getCanvasRoot();\n if (!api || !root) return;\n const rect = root.getBoundingClientRect();\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n const vp = api.getViewport();\n const next = clamp(target, MIN_SCALE, MAX_SCALE);\n const ratio = next / vp.scale;\n api.setViewport({\n tx: cx - (cx - vp.tx) * ratio,\n ty: cy - (cy - vp.ty) * ratio,\n scale: next,\n });\n}\n\nfunction zoomIn(): void {\n const api = getViewportApi();\n if (!api) return;\n const cur = api.getViewport().scale;\n const next = ZOOM_STEPS.find((z) => z > cur + 1e-6) ?? MAX_SCALE;\n zoomTo(next);\n}\n\nfunction zoomOut(): void {\n const api = getViewportApi();\n if (!api) return;\n const cur = api.getViewport().scale;\n let next = MIN_SCALE;\n for (let i = ZOOM_STEPS.length - 1; i >= 0; i--) {\n if (ZOOM_STEPS[i] < cur - 1e-6) {\n next = ZOOM_STEPS[i];\n break;\n }\n }\n zoomTo(next);\n}\n\nconst LABEL_CYCLE: Record<LabelMode, LabelMode> = {\n off: 'id',\n id: 'all',\n all: 'off',\n};\n\nfunction cycleLabelMode(): void {\n const store = useEditorStore.getState();\n const cur = store.diagram.meta?.labelMode ?? 'all';\n const next = LABEL_CYCLE[cur];\n store.dispatch((d) => {\n const meta = { ...(d.meta ?? {}), labelMode: next };\n return { ...d, meta };\n });\n}\n\n/**\n * Grid state + side effects. Lives wherever the view menu is mounted (the\n * standalone ViewToolbar at wider widths, or the embedded ViewMenuButton at\n * dense+). Owns the keyboard `G` shortcut so it works regardless of whether\n * the popover happens to be open.\n */\nfunction useGridState(): [boolean, React.Dispatch<React.SetStateAction<boolean>>] {\n const [grid, setGrid] = useState<boolean>(() => readGrid());\n\n useEffect(() => {\n const root = getCanvasRoot();\n root?.classList.toggle('hide-grid', !grid);\n writeGrid(grid);\n }, [grid]);\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.metaKey || e.ctrlKey || e.altKey) return;\n if (e.key !== 'g' && e.key !== 'G') return;\n const target = e.target as HTMLElement | null;\n if (\n target &&\n (target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.isContentEditable)\n ) {\n return;\n }\n e.preventDefault();\n setGrid((v) => !v);\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n return [grid, setGrid];\n}\n\nfunction ZoomOutBtn() {\n const t = useT();\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.zoomOut')}</div>\n <div className=\"text-muted-foreground\">{t('view.zoomOutHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={zoomOut}\n aria-label={t('view.zoomOut')}\n >\n <Minus />\n </Button>\n </Tooltip>\n );\n}\n\nfunction ZoomInBtn() {\n const t = useT();\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.zoomIn')}</div>\n <div className=\"text-muted-foreground\">{t('view.zoomInHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={zoomIn}\n aria-label={t('view.zoomIn')}\n >\n <Plus />\n </Button>\n </Tooltip>\n );\n}\n\nfunction ZoomDisplayBtn() {\n const t = useT();\n const [scale, setScale] = useState(getScale);\n useEffect(() => subscribeScale(setScale), []);\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.reset')}</div>\n <div className=\"text-muted-foreground\">\n {t('view.current', { z: Math.round(scale * 100) })}\n </div>\n </div>\n }\n >\n <button\n type=\"button\"\n onClick={() => zoomTo(1)}\n className=\"min-w-12 rounded-md px-2 py-1 text-center text-xs tabular-nums text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n aria-label={t('view.reset')}\n >\n {Math.round(scale * 100)}%\n </button>\n </Tooltip>\n );\n}\n\nfunction FitBtn() {\n const t = useT();\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.fit')}</div>\n <div className=\"text-muted-foreground\">{t('view.fitHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={fitToContent}\n aria-label={t('view.fit')}\n >\n <Maximize2 />\n </Button>\n </Tooltip>\n );\n}\n\nfunction GridBtn({\n grid,\n setGrid,\n}: {\n grid: boolean;\n setGrid: React.Dispatch<React.SetStateAction<boolean>>;\n}) {\n const t = useT();\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">\n {grid ? t('view.gridHide') : t('view.gridShow')}\n </span>\n <span className=\"ml-1.5 text-muted-foreground\">\n {t('view.gridHotkey')}\n </span>\n </div>\n <div className=\"text-muted-foreground\">\n {grid ? t('view.gridHideHint') : t('view.gridShowHint')}\n </div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setGrid((v) => !v)}\n aria-label={grid ? t('view.gridHideAria') : t('view.gridShowAria')}\n aria-pressed={grid}\n className={cn(!grid && 'text-muted-foreground/60')}\n >\n <Grid2x2 />\n </Button>\n </Tooltip>\n );\n}\n\nfunction LabelBtn() {\n const t = useT();\n const labelMode: LabelMode = useEditorStore(\n (s) => s.diagram.meta?.labelMode ?? 'all',\n );\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">\n {labelMode === 'off'\n ? t('view.labelOff')\n : labelMode === 'id'\n ? t('view.labelId')\n : t('view.labelAll')}\n </div>\n <div className=\"text-muted-foreground\">{t('view.labelHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={cycleLabelMode}\n aria-label={t('view.label')}\n aria-pressed={labelMode !== 'off'}\n className={cn(labelMode === 'off' && 'text-muted-foreground/60')}\n >\n <Type />\n </Button>\n </Tooltip>\n );\n}\n\n/**\n * View menu collapsed into a single popover trigger. Designed to be embedded\n * inline inside another bar (no outer positioning). Used by FloatingToolbar\n * at `dense` and below, where it stands in for the standalone ViewToolbar.\n *\n * `stacked` switches the trigger to the unified-bar's tab-bar look (icon on\n * top, \"视图\" label below) so it matches the other phone-class buttons.\n */\nexport function ViewMenuButton({ stacked }: { stacked?: boolean } = {}) {\n const t = useT();\n const [menuOpen, setMenuOpen] = useState(false);\n const [grid, setGrid] = useGridState();\n const tipContent = (\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.menu')}</div>\n <div className=\"text-muted-foreground\">{t('view.menuHint')}</div>\n </div>\n );\n const triggerBtn = stacked ? (\n <Tooltip content={tipContent}>\n <button\n type=\"button\"\n onClick={() => setMenuOpen((v) => !v)}\n aria-label={t('view.menu')}\n aria-pressed={menuOpen}\n className={cn(\n 'flex h-12 w-12 flex-col items-center justify-center gap-0.5 rounded-md text-[10px] font-medium leading-tight transition-colors',\n menuOpen\n ? 'bg-primary text-primary-foreground'\n : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n )}\n >\n <MoreHorizontal className=\"size-4\" />\n <span className=\"max-w-full truncate\">{t('view.menu')}</span>\n </button>\n </Tooltip>\n ) : (\n <Tooltip content={tipContent}>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setMenuOpen((v) => !v)}\n aria-label={t('view.menu')}\n aria-pressed={menuOpen}\n >\n <MoreHorizontal />\n </Button>\n </Tooltip>\n );\n return (\n <UpwardPopover\n open={menuOpen}\n onOpenChange={setMenuOpen}\n trigger={triggerBtn}\n >\n <div className=\"flex flex-col gap-0.5\">\n <ZoomDisplayBtn />\n <div className=\"flex items-center gap-0.5\">\n <ZoomOutBtn />\n <ZoomInBtn />\n </div>\n <div aria-hidden className=\"my-1 h-px bg-border\" />\n <div className=\"flex items-center gap-0.5\">\n <FitBtn />\n <GridBtn grid={grid} setGrid={setGrid} />\n <LabelBtn />\n </div>\n </div>\n </UpwardPopover>\n );\n}\n\n/**\n * Bottom-right view toolbar. Above `dense` (>520px) it renders an expanded\n * row with explicit zoom controls. At `dense` and below it returns null —\n * its content is rendered as an embedded ViewMenuButton inside the unified\n * FloatingToolbar bottom bar so the chrome stays on a single line.\n */\nexport function ViewToolbar() {\n const tier = useEditorTier();\n if (atLeast(tier, 'dense')) return null;\n return <ViewToolbarExpanded tier={tier} />;\n}\n\nfunction ViewToolbarExpanded({ tier }: { tier: Tier }) {\n // Hide the zoom-% pill from `tight` (≥720 < 900) onward — that's where the\n // centered FloatingToolbar starts colliding with this right-anchored bar.\n const hidePercentPill = atLeast(tier, 'tight');\n const [grid, setGrid] = useGridState();\n\n return (\n <div\n className=\"absolute z-20\"\n style={{\n bottom: 'calc(0.75rem + var(--ole-bottom-inset, 0px))',\n right: 'calc(0.75rem + env(safe-area-inset-right, 0px))',\n }}\n >\n <div className=\"ole-glass flex items-center gap-0.5 rounded-2xl border border-border p-1.5 shadow-sm\">\n <ZoomOutBtn />\n {!hidePercentPill && <ZoomDisplayBtn />}\n <ZoomInBtn />\n <div aria-hidden className=\"mx-1 h-4 w-px bg-border\" />\n <FitBtn />\n <GridBtn grid={grid} setGrid={setGrid} />\n <LabelBtn />\n </div>\n </div>\n );\n}\n","import { Fragment, useState } from 'react';\nimport {\n Cable,\n Clipboard,\n Copy,\n Hand,\n LayoutGrid,\n ListTree,\n Minus,\n MoreHorizontal,\n MousePointer2,\n Redo2,\n Scissors,\n Shapes,\n Type,\n Undo2,\n Wand2,\n} from 'lucide-react';\nimport { Tooltip } from './ui/tooltip';\nimport { UpwardPopover } from './ui/upward-popover';\nimport { atLeast, useEditorTier } from '../hooks/editor-tier';\nimport { usePanels } from '../hooks/use-panels';\nimport { useT, type LocaleKey } from '../i18n';\nimport { cn } from '../lib/utils';\nimport { useEditorStore, type ToolId } from '../store';\nimport { ViewMenuButton } from './ViewToolbar';\n\ninterface ToolDef {\n id: string;\n labelKey: LocaleKey;\n hotkey: string;\n descriptionKey: LocaleKey;\n icon: React.ComponentType<{ className?: string }>;\n /** Render a divider after this tool (visually groups the toolbar). */\n groupBreakAfter?: boolean;\n /** Tool action: switch active tool (with optional placeKind preset). */\n switchTo: ToolId;\n /**\n * `undefined` = keep current placeKind; `null` = clear; string = preset.\n */\n presetPlaceKind?: string | null;\n /** Icon-only render (label still goes to aria-label / tooltip). */\n iconOnly?: boolean;\n}\n\nconst TOOLS: ToolDef[] = [\n {\n id: 'select',\n labelKey: 'tool.select',\n hotkey: 'V',\n descriptionKey: 'tool.selectHint',\n icon: MousePointer2,\n switchTo: 'select',\n iconOnly: true,\n },\n {\n id: 'pan',\n labelKey: 'tool.pan',\n hotkey: 'H',\n descriptionKey: 'tool.panHint',\n icon: Hand,\n switchTo: 'pan',\n groupBreakAfter: true,\n iconOnly: true,\n },\n {\n id: 'busbar',\n labelKey: 'tool.bus',\n hotkey: 'B',\n descriptionKey: 'tool.busHint',\n icon: Minus,\n switchTo: 'busbar',\n },\n {\n id: 'place',\n labelKey: 'tool.place',\n hotkey: 'P',\n descriptionKey: 'tool.placeHint',\n icon: Shapes,\n switchTo: 'place',\n },\n {\n id: 'wire',\n labelKey: 'tool.wire',\n hotkey: 'W',\n descriptionKey: 'tool.wireHint',\n icon: Cable,\n switchTo: 'wire',\n },\n {\n id: 'text',\n labelKey: 'tool.text',\n hotkey: 'T',\n descriptionKey: 'tool.textHint',\n icon: Type,\n switchTo: 'text',\n iconOnly: true,\n },\n];\n\n/**\n * Short usage hint shown above the toolbar for whichever tool is active.\n * Keeps users oriented without forcing them to discover a tooltip — most\n * tools have a non-obvious gesture and the hint paid off in usability tests.\n */\nfunction ToolHint() {\n const t = useT();\n const active = useEditorStore((s) => s.activeTool);\n const placeKind = useEditorStore((s) => s.placeKind);\n const placeFrom = useEditorStore((s) => s.placeFromTerminal);\n const wireFrom = useEditorStore((s) => s.wireFromTerminal);\n const busbarStart = useEditorStore((s) => s.busbarDrawStart);\n const hasSelection = useEditorStore(\n (s) => s.selection.length > 0 || s.selectedNode != null,\n );\n\n let text: string | null = null;\n let cancelHint = false;\n switch (active) {\n case 'select':\n text = hasSelection\n ? t('mode.selectWithSel')\n : t('mode.selectEmpty');\n if (hasSelection) cancelHint = true;\n break;\n case 'pan':\n text = t('mode.pan');\n break;\n case 'wire':\n text = wireFrom ? t('mode.wireDragging') : t('mode.wireInit');\n cancelHint = true;\n break;\n case 'busbar':\n text = busbarStart ? t('mode.busDragging') : t('mode.busInit');\n cancelHint = true;\n break;\n case 'place':\n if (!placeKind) text = t('mode.placeNoKind');\n else if (placeFrom) text = t('mode.placeFromTerm');\n else text = t('mode.placeNormal');\n cancelHint = true;\n break;\n case 'text':\n text = t('mode.text');\n cancelHint = true;\n break;\n }\n if (!text) return null;\n // In select mode right-click opens the context menu rather than cancelling,\n // so only Esc clears the selection. In drawing tools right-click also cancels.\n const cancelText = active === 'select' ? t('mode.escSelect') : t('mode.escOther');\n return (\n <div className=\"ole-glass pointer-events-none flex items-center gap-2 rounded-full border border-border px-3 py-1 text-xs text-muted-foreground shadow-sm\">\n <span>{text}</span>\n {cancelHint && <span className=\"text-muted-foreground/70\">· {cancelText}</span>}\n </div>\n );\n}\n\nexport function FloatingToolbar() {\n const t = useT();\n const active = useEditorStore((s) => s.activeTool);\n const placeKind = useEditorStore((s) => s.placeKind);\n const setTool = useEditorStore((s) => s.setActiveTool);\n const past = useEditorStore((s) => s.past.length);\n const future = useEditorStore((s) => s.future.length);\n const undo = useEditorStore((s) => s.undo);\n const redo = useEditorStore((s) => s.redo);\n const tier = useEditorTier();\n // Drop labels from `tight` (≥720 < 900) so the centered main toolbar stops\n // colliding with the right-anchored ViewToolbar. The outline tab on the\n // left still has room for its label until `compact`.\n const forceIconOnly = atLeast(tier, 'tight');\n const showHint = !atLeast(tier, 'dense');\n // Phone-class layout (`dense` and below): the outline tab and the view\n // toolbar disappear and their entry points are embedded directly into this\n // pill as a tab-bar-style row, so the whole bottom chrome stays on a single\n // visual row. The [Undo/Redo/Layout] group also collapses into one overflow\n // button to keep the bar narrow. Select and text are dropped from the main\n // bar — Pan is the default on touch and absorbs single-tap selection (see\n // PanTool), and text annotation is rare enough on a phone to hide.\n const unifiedBar = atLeast(tier, 'dense');\n const visibleTools = unifiedBar\n ? TOOLS.filter((def) => def.id !== 'select' && def.id !== 'text')\n : TOOLS;\n\n const isToolActive = (def: ToolDef): boolean => active === def.switchTo;\n\n return (\n <div\n className=\"absolute left-1/2 z-20 flex -translate-x-1/2 flex-col items-center gap-1.5\"\n style={{ bottom: 'calc(0.75rem + var(--ole-bottom-inset, 0px))' }}\n >\n {showHint && <ToolHint />}\n <div\n className={cn(\n 'ole-glass flex flex-row items-center rounded-2xl border border-border shadow-sm',\n unifiedBar ? 'gap-0.5 p-1' : 'gap-0.5 p-1.5',\n )}\n >\n {unifiedBar && <OutlineToggleButton stacked />}\n {visibleTools.map((def) => {\n const Icon = def.icon;\n const isActive = isToolActive(def);\n const tip =\n def.id === 'place' && isActive && placeKind == null\n ? t('tool.placeNoKindTooltip')\n : t(def.descriptionKey);\n return (\n <Fragment key={def.id}>\n <ToolbarButton\n icon={Icon}\n label={t(def.labelKey)}\n hotkey={def.hotkey}\n active={isActive}\n iconOnly={!unifiedBar && (def.iconOnly || forceIconOnly)}\n stacked={unifiedBar}\n description={tip}\n onClick={() => {\n setTool(def.switchTo, {\n placeKind:\n def.presetPlaceKind !== undefined ? def.presetPlaceKind : undefined,\n });\n }}\n />\n {def.groupBreakAfter && !unifiedBar && (\n <div aria-hidden className=\"mx-1 h-5 w-px bg-border\" />\n )}\n </Fragment>\n );\n })}\n {!unifiedBar && (\n <div aria-hidden className=\"mx-1 h-5 w-px bg-border\" />\n )}\n {unifiedBar ? (\n <OverflowMenuButton stacked />\n ) : (\n <>\n <ToolbarButton\n icon={Undo2}\n label={t('tool.undo')}\n hotkey=\"⌘Z\"\n description={t('tool.undoHint')}\n iconOnly\n disabled={past === 0}\n onClick={undo}\n />\n <ToolbarButton\n icon={Redo2}\n label={t('tool.redo')}\n hotkey=\"⌘⇧Z\"\n description={t('tool.redoHint')}\n iconOnly\n disabled={future === 0}\n onClick={redo}\n />\n <div aria-hidden className=\"mx-1 h-5 w-px bg-border\" />\n <LayoutMenuButton iconOnly={forceIconOnly} />\n </>\n )}\n {unifiedBar && <ViewMenuButton stacked />}\n </div>\n </div>\n );\n}\n\n/**\n * Embedded outline-toggle entry point used by the unified bottom bar at\n * `dense` and below. Mirrors the floating LeftPanel tab's role (toggles the\n * outline panel), but renders inline inside the FloatingToolbar pill so the\n * bottom chrome stays on one row at phone widths.\n */\nfunction OutlineToggleButton({ stacked }: { stacked?: boolean }) {\n const t = useT();\n const open = usePanels((s) => s.outlineOpen);\n const toggle = usePanels((s) => s.toggleOutline);\n return (\n <ToolbarButton\n icon={ListTree}\n label={t('outline.title')}\n active={open}\n iconOnly\n stacked={stacked}\n onClick={toggle}\n />\n );\n}\n\n/**\n * Toolbar button: icon + label, with a small hotkey hint pinned to the\n * top-left corner. Active = filled (primary). Disabled = dimmed.\n *\n * `stacked` is the phone-class variant — icon on top, label underneath,\n * no hotkey badge (touch users don't have a keyboard). Used by the unified\n * bottom bar at `dense` and below to look like an iOS/Material tab bar.\n */\nfunction ToolbarButton({\n icon: Icon,\n label,\n hotkey,\n active,\n disabled,\n iconOnly,\n stacked,\n onClick,\n description,\n}: {\n icon: React.ComponentType<{ className?: string }>;\n label: string;\n hotkey?: string;\n active?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n stacked?: boolean;\n onClick: () => void;\n description?: React.ReactNode;\n}) {\n const tipContent = (\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">{label}</span>\n {hotkey && (\n <span className=\"ml-1.5 text-muted-foreground\">{hotkey}</span>\n )}\n </div>\n {description && <div className=\"text-muted-foreground\">{description}</div>}\n </div>\n );\n return (\n <Tooltip content={tipContent} disabled={disabled}>\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n aria-label={label}\n aria-pressed={active}\n className={cn(\n 'rounded-md font-medium transition-colors',\n stacked\n ? 'flex h-12 w-12 flex-col items-center justify-center gap-0.5 text-[10px] leading-tight'\n : 'flex h-9 items-center gap-1.5 text-xs',\n !stacked && (iconOnly ? 'w-9 justify-center' : 'px-2.5'),\n active\n ? 'bg-primary text-primary-foreground'\n : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n disabled && 'pointer-events-none opacity-40',\n )}\n >\n <span className=\"relative inline-flex shrink-0\">\n <Icon className=\"size-4\" />\n {hotkey && !stacked && (\n <span\n aria-hidden\n className={cn(\n 'pointer-events-none absolute -right-1.5 -top-1.5 rounded-sm px-1 font-mono text-[8px] leading-[1.1]',\n active\n ? 'bg-primary-foreground/20 text-primary-foreground/85'\n : 'bg-foreground/10 text-muted-foreground',\n )}\n >\n {hotkey}\n </span>\n )}\n </span>\n {stacked ? (\n <span className=\"max-w-full truncate\">{label}</span>\n ) : (\n !iconOnly && <span>{label}</span>\n )}\n </button>\n </Tooltip>\n );\n}\n\nfunction useLayoutActions() {\n const elements = useEditorStore((s) => s.diagram.elements);\n const layout = useEditorStore((s) => s.diagram.layout);\n const selection = useEditorStore((s) => s.selection);\n const explicit = layout ?? {};\n return {\n hasAnyElement: elements.length > 0,\n hasArrangedAny: Object.keys(explicit).length > 0,\n hasGapsAll: elements.some((el) => !explicit[el.id]),\n hasSelection: selection.length > 0,\n selectionHasArranged: selection.some((id) => !!explicit[id]),\n selectionHasGaps: selection.some((id) => !explicit[id]),\n };\n}\n\nfunction LayoutMenuButton({ iconOnly }: { iconOnly?: boolean }) {\n const t = useT();\n const [open, setOpen] = useState(false);\n // Subscribe at field-level so disabled state stays live while menu is open.\n const a = useLayoutActions();\n const run = (action: () => void) => () => {\n setOpen(false);\n action();\n };\n return (\n <UpwardPopover\n open={open}\n onOpenChange={setOpen}\n trigger={\n <ToolbarButton\n icon={Wand2}\n label={t('layout.label')}\n description={t('layout.hint')}\n active={open}\n iconOnly={iconOnly}\n onClick={() => setOpen((v) => !v)}\n />\n }\n >\n <PopoverItem\n onClick={run(() => useEditorStore.getState().autoArrangeAll())}\n icon={<Wand2 />}\n disabled={!a.hasAnyElement || !a.hasArrangedAny}\n >\n {t('layout.allAuto')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().autoArrangeSelection())}\n icon={<Wand2 />}\n disabled={!a.hasSelection || !a.selectionHasArranged}\n >\n {t('layout.selAuto')}\n </PopoverItem>\n <div aria-hidden className=\"my-1 h-px bg-border\" />\n <PopoverItem\n onClick={run(() => useEditorStore.getState().fillUnplacedAll())}\n icon={<LayoutGrid />}\n disabled={!a.hasGapsAll}\n >\n {t('layout.allFill')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().fillUnplacedSelection())}\n icon={<LayoutGrid />}\n disabled={!a.hasSelection || !a.selectionHasGaps}\n >\n {t('layout.selFill')}\n </PopoverItem>\n </UpwardPopover>\n );\n}\n\n/**\n * Mini-tier substitute for [Undo, Redo, Layout]: one icon button collapsing\n * those three groups into a single popover. Layout actions are inlined here\n * (not nested inside the popover via a sub-menu) so users only deal with one\n * level of overlay on a tiny screen.\n */\nfunction OverflowMenuButton({ stacked }: { stacked?: boolean }) {\n const t = useT();\n const [open, setOpen] = useState(false);\n const past = useEditorStore((s) => s.past.length);\n const future = useEditorStore((s) => s.future.length);\n const undo = useEditorStore((s) => s.undo);\n const redo = useEditorStore((s) => s.redo);\n const hasSelection = useEditorStore((s) => s.selection.length > 0);\n const hasClipboard = useEditorStore((s) => s.clipboard != null);\n const a = useLayoutActions();\n const run = (action: () => void) => () => {\n setOpen(false);\n action();\n };\n return (\n <UpwardPopover\n open={open}\n onOpenChange={setOpen}\n trigger={\n <ToolbarButton\n icon={MoreHorizontal}\n label={t('tool.more')}\n description={t('tool.moreHint')}\n active={open}\n iconOnly\n stacked={stacked}\n onClick={() => setOpen((v) => !v)}\n />\n }\n >\n <PopoverItem\n onClick={run(undo)}\n icon={<Undo2 />}\n disabled={past === 0}\n >\n {t('tool.undo')}\n </PopoverItem>\n <PopoverItem\n onClick={run(redo)}\n icon={<Redo2 />}\n disabled={future === 0}\n >\n {t('tool.redo')}\n </PopoverItem>\n <div aria-hidden className=\"my-1 h-px bg-border\" />\n <PopoverItem\n onClick={run(() => useEditorStore.getState().cutSelection())}\n icon={<Scissors />}\n disabled={!hasSelection}\n >\n {t('menu.cut')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().copySelection())}\n icon={<Copy />}\n disabled={!hasSelection}\n >\n {t('menu.copy')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().pasteClipboard())}\n icon={<Clipboard />}\n disabled={!hasClipboard}\n >\n {t('menu.paste')}\n </PopoverItem>\n <div aria-hidden className=\"my-1 h-px bg-border\" />\n <PopoverItem\n onClick={run(() => useEditorStore.getState().autoArrangeAll())}\n icon={<Wand2 />}\n disabled={!a.hasAnyElement || !a.hasArrangedAny}\n >\n {t('layout.allAuto')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().autoArrangeSelection())}\n icon={<Wand2 />}\n disabled={!a.hasSelection || !a.selectionHasArranged}\n >\n {t('layout.selAuto')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().fillUnplacedAll())}\n icon={<LayoutGrid />}\n disabled={!a.hasGapsAll}\n >\n {t('layout.allFill')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().fillUnplacedSelection())}\n icon={<LayoutGrid />}\n disabled={!a.hasSelection || !a.selectionHasGaps}\n >\n {t('layout.selFill')}\n </PopoverItem>\n </UpwardPopover>\n );\n}\n\nfunction PopoverItem({\n children,\n icon,\n onClick,\n disabled,\n}: {\n children: React.ReactNode;\n icon?: React.ReactNode;\n onClick: () => void;\n disabled?: boolean;\n}) {\n return (\n <button\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n onClick={onClick}\n className={cn(\n 'flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4',\n disabled &&\n 'pointer-events-none text-muted-foreground opacity-60 hover:bg-transparent',\n )}\n >\n {icon}\n <span className=\"flex-1\">{children}</span>\n </button>\n );\n}\n","import { ListTree, PanelBottomClose } from 'lucide-react';\nimport { libraryById } from '../element-library';\nimport { atLeast, useEditorTier } from '../hooks/editor-tier';\nimport { usePanels } from '../hooks/use-panels';\nimport { useT } from '../i18n';\nimport { cn } from '../lib/utils';\nimport { useEditorStore } from '../store';\nimport type { Element } from '../model';\n\nexport function LeftPanel() {\n const open = usePanels((s) => s.outlineOpen);\n const setOpen = usePanels((s) => s.setOutlineOpen);\n const tier = useEditorTier();\n const dense = atLeast(tier, 'dense');\n\n // At dense+ the collapsed tab is replaced by an outline button embedded\n // directly into the FloatingToolbar bottom bar. The outline panel itself\n // still lives here but switches to a full-width bottom sheet anchored just\n // above that bar so it doesn't compete for horizontal room with the canvas.\n if (dense) {\n if (!open) return null;\n return (\n <div\n className=\"absolute z-10\"\n style={{\n left: 'calc(0.75rem + var(--ole-left-inset, 0px))',\n right: 'calc(0.75rem + var(--ole-right-inset, 0px))',\n bottom: 'calc(4rem + var(--ole-bottom-inset, 0px) + 0.75rem)',\n }}\n >\n <OutlinePanel onClose={() => setOpen(false)} sheet />\n </div>\n );\n }\n\n return (\n <div\n className=\"absolute z-10 flex flex-col items-start\"\n style={{\n bottom: 'calc(0.75rem + var(--ole-bottom-inset, 0px))',\n left: 'calc(0.75rem + var(--ole-left-inset, 0px))',\n maxHeight: 'calc(100% - 1.5rem)',\n }}\n >\n {open ? (\n <OutlinePanel onClose={() => setOpen(false)} />\n ) : (\n <CollapsedTab onClick={() => setOpen(true)} />\n )}\n </div>\n );\n}\n\nfunction CollapsedTab({ onClick }: { onClick: () => void }) {\n const t = useT();\n const tier = useEditorTier();\n const compact = atLeast(tier, 'compact');\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={t('outline.title')}\n title={t('outline.title')}\n className={cn(\n 'ole-glass flex h-12 items-center rounded-2xl border border-border text-muted-foreground shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground',\n compact ? 'w-12 justify-center' : 'gap-2 px-3',\n )}\n >\n <ListTree className=\"size-4 shrink-0\" />\n {!compact && <span className=\"text-xs font-medium\">{t('outline.title')}</span>}\n </button>\n );\n}\n\nfunction OutlinePanel({\n onClose,\n sheet,\n}: {\n onClose: () => void;\n sheet?: boolean;\n}) {\n const t = useT();\n const elements = useEditorStore((s) => s.diagram.elements);\n const libraryOpen = useEditorStore((s) => s.activeTool === 'place');\n const tier = useEditorTier();\n const compact = atLeast(tier, 'compact');\n const dense = atLeast(tier, 'dense');\n // Use `height` (not `max-height`) so the panel always reserves space,\n // even when content is short. In sheet mode it sizes by the parent's\n // left/right anchor — we just cap the height so the canvas above stays\n // visible.\n const height = sheet\n ? 'min(50vh, calc(100vh - 9rem))'\n : libraryOpen\n ? 'min(40vh, calc(100vh - 200px))'\n : 'min(70vh, calc(100vh - 100px))';\n return (\n <aside\n className={cn(\n 'ole-glass flex flex-col overflow-hidden rounded-2xl border border-border shadow-sm',\n sheet ? 'w-full' : compact ? 'w-52' : 'w-64',\n )}\n style={{ height }}\n >\n <button\n type=\"button\"\n onClick={onClose}\n aria-label={t('outline.collapseAria')}\n title={t('outline.collapse')}\n className=\"flex items-center gap-1.5 border-b border-border/40 px-3 py-2 text-left transition-colors hover:bg-muted/40\"\n >\n <span className=\"flex-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n {t('outline.title')}\n </span>\n {!dense && <CountChip>{elements.length}</CountChip>}\n <PanelBottomClose className=\"size-3.5 text-muted-foreground\" />\n </button>\n <div className=\"flex-1 overflow-y-auto px-2 pb-2\">\n {elements.length === 0 ? (\n <p className=\"px-2 py-2 text-xs italic text-muted-foreground\">\n {t('outline.empty')}\n </p>\n ) : (\n <ul className=\"space-y-px\">\n {elements.map((el) => (\n <OutlineRow key={el.id} element={el} />\n ))}\n </ul>\n )}\n </div>\n </aside>\n );\n}\n\nfunction OutlineRow({ element }: { element: Element }) {\n const lib = libraryById[element.kind];\n const selected = useEditorStore((s) => s.selection.includes(element.id));\n const setSelection = useEditorStore((s) => s.setSelection);\n const toggleInSelection = useEditorStore((s) => s.toggleInSelection);\n const tier = useEditorTier();\n const showId = !atLeast(tier, 'compact');\n const onClick = (e: React.MouseEvent) => {\n if (e.shiftKey || e.metaKey || e.ctrlKey) toggleInSelection(element.id);\n else setSelection([element.id]);\n };\n return (\n <li\n className=\"group flex cursor-pointer items-center gap-2 rounded-md px-2 py-1 hover:bg-accent data-[selected=true]:bg-[color-mix(in_oklch,var(--selection)_18%,transparent)]\"\n title={element.note ?? `${element.name ?? element.id} (${element.kind})`}\n data-element-id={element.id}\n data-selected={selected ? 'true' : undefined}\n onClick={onClick}\n >\n <div className=\"flex h-4 w-6 shrink-0 items-center justify-center\">\n {lib && (\n <svg\n viewBox={lib.viewBox}\n className=\"ole-symbol size-full\"\n preserveAspectRatio=\"xMidYMid meet\"\n dangerouslySetInnerHTML={{ __html: lib.svg }}\n />\n )}\n </div>\n <span className=\"flex-1 truncate text-xs text-foreground/90 group-hover:text-accent-foreground\">\n {element.name ?? element.id}\n </span>\n {showId && (\n <span className=\"font-mono text-[10px] text-muted-foreground/80\">\n {element.id}\n </span>\n )}\n </li>\n );\n}\n\nfunction CountChip({ children }: { children: React.ReactNode }) {\n return (\n <span className=\"rounded bg-muted/50 px-1.5 py-0.5 font-mono text-[10px] tabular-nums text-muted-foreground/80\">\n {children}\n </span>\n );\n}\n","/**\n * Translation table for `LibraryEntry` user-facing strings: display name,\n * description, state labels, param labels.\n *\n * Kept separate from the strict `messages.ts` map because keys are derived\n * from runtime data (entry id + field name) and would balloon the typed\n * key union. Falls back to the JSON-defined value when no translation exists.\n *\n * Key shape: `<entryId>.name`, `<entryId>.desc`, `<entryId>.state.<name>`,\n * `<entryId>.param.<name>`.\n */\n\nimport { useLocale, type Locale } from './index';\n\ntype Table = Record<string, string>;\n\nconst zh: Table = {\n // Names — the JSON `name` field is already Chinese, so we only need them\n // here for symmetry / one-stop translation. English is the value-add.\n 'arc-suppression-coil.name': '消弧线圈',\n 'arrester.name': '避雷器 (FBL)',\n 'async-motor.name': '异步电动机',\n 'autotransformer.name': '自耦变压器',\n 'battery.name': '电池储能',\n 'breaker.name': '断路器 (QF)',\n 'busbar.name': '母线段',\n 'converter-bidir.name': '双向变流器 (PCS)',\n 'ct.name': '电流互感器 (CT)',\n 'disconnector.name': '隔离开关 (QS)',\n 'earth.name': '接地',\n 'earthing-switch.name': '接地刀闸 (QE)',\n 'fuse.name': '熔断器 (FU)',\n 'generator.name': '发电机 (G)',\n 'grid-source.name': '系统电源',\n 'grounding-transformer.name': '接地变 (Z形)',\n 'inverter.name': '逆变器 (DC→AC)',\n 'load-switch.name': '负荷开关',\n 'load.name': '负荷',\n 'ngr.name': '中性点电阻 (NGR)',\n 'pt.name': '电压互感器 (PT)',\n 'pv.name': '光伏组件',\n 'rectifier.name': '整流器 (AC→DC)',\n 'series-reactor.name': '串联电抗器',\n 'shunt-capacitor.name': '并联电容器',\n 'shunt-reactor.name': '并联电抗器',\n 'sync-motor.name': '同步电动机',\n 'transformer-2w.name': '双绕组变压器',\n 'transformer-3w.name': '三绕组变压器',\n 'wind-turbine.name': '风力发电机',\n // ---- v0.2 additions ----\n 'gfci-breaker.name': 'GFCI 断路器 (RCBO)',\n 'rcd.name': '剩余电流装置 (RCD)',\n 'recloser.name': '重合闸 (Recloser)',\n 'energy-meter.name': '电能表 (Wh)',\n 'voltmeter.name': '电压表 (V)',\n 'ammeter.name': '电流表 (A)',\n 'wattmeter.name': '功率表 (W)',\n 'frequency-meter.name': '频率表 (Hz)',\n 'contactor.name': '接触器 (KM)',\n 'motor-starter.name': '电机启动器',\n 'thermal-overload.name': '热过载继电器',\n 'vfd.name': '变频器 (VFD)',\n 'soft-starter.name': '软启动器',\n 'transfer-switch.name': '切换开关 (ATS)',\n 'dc-disconnector.name': '直流隔离开关',\n 'dc-combiner.name': '直流汇流箱',\n 'ev-charger.name': 'EV 充电桩',\n\n // Descriptions\n 'arc-suppression-coil.desc': '中性点谐振接地:电感线圈连接到地',\n 'busbar.desc': '可拉伸单母线段,多设备挂接',\n 'converter-bidir.desc': '储能变流器:双向 AC ↔ DC',\n 'earthing-switch.desc': '隔离开关 + 接地连接,单端口',\n 'grid-source.desc': '无穷大母线 / 外部电网',\n 'grounding-transformer.desc': '星-曲折接线变压器,中性点接地用',\n 'load.desc': '抽象负荷(电流流出箭头)',\n 'ngr.desc': '小电阻接地:连接变压器中性点到地',\n 'series-reactor.desc': '与并联电抗器同符号;通过用法区分',\n 'wind-turbine.desc': '风机:发电机 + 三叶轮标记',\n 'gfci-breaker.desc': '剩余电流断路器带过流保护 (UL943 / IEC 61009)。北美 GFCI / 欧洲 RCBO。',\n 'rcd.desc': '不带过流保护的剩余电流断路器 (IEC 61008)。',\n 'recloser.desc': '中压自动重合闸开关。',\n 'energy-meter.desc': '有功电能表 (kWh) — 服务入口 / 子表。',\n 'contactor.desc': '主回路接触器, 通常配热继电器和电机使用。',\n 'motor-starter.desc': '电机启动器 (IEC 60617 通用符号)。',\n 'thermal-overload.desc': '电机热过载保护继电器, 通常串接在接触器和电机之间。',\n 'vfd.desc': 'Variable Frequency Drive — 异步电动机调速。',\n 'soft-starter.desc': '电机软启动器 (晶闸管降压启动)。',\n 'transfer-switch.desc': '双源切换开关 (Automatic / Manual Transfer Switch)。两个电源输入 + 一个负荷输出, 互锁不并联。',\n 'dc-disconnector.desc': 'DC 隔离开关 — 光伏组串 / 储能 直流侧隔离。',\n 'dc-combiner.desc': '光伏组串汇流箱 (4 路输入示例)。',\n 'ev-charger.desc': '电动汽车充电站 / 充电桩。',\n\n // State labels\n 'breaker.state.open': '断开',\n 'disconnector.state.open': '断开',\n 'earthing-switch.state.open': '断开',\n 'fuse.state.blown': '熔断',\n 'load-switch.state.open': '断开',\n 'gfci-breaker.state.open': '断开',\n 'rcd.state.open': '断开',\n 'recloser.state.open': '断开',\n 'contactor.state.open': '断开',\n 'thermal-overload.state.tripped': '动作',\n 'transfer-switch.state.position': '位置 (normal/emergency/off)',\n 'dc-disconnector.state.open': '断开',\n\n // Param labels\n 'battery.param.E': '容量',\n 'busbar.param.Un': '额定电压',\n 'converter-bidir.param.S': '容量',\n 'load.param.P': '有功功率',\n 'load.param.cosphi': '功率因数',\n 'ngr.param.R': '电阻',\n 'shunt-capacitor.param.Q': '无功容量',\n 'shunt-capacitor.param.stages': '分组数',\n 'transformer-2w.param.S': '容量',\n 'transformer-2w.param.ratio': '变比',\n 'gfci-breaker.param.In': '额定电流',\n 'gfci-breaker.param.IDn': '剩余动作电流',\n 'rcd.param.IDn': '剩余动作电流',\n};\n\nconst en: Table = {\n 'arc-suppression-coil.name': 'Arc-suppression coil',\n 'arrester.name': 'Surge arrester (FBL)',\n 'async-motor.name': 'Asynchronous motor',\n 'autotransformer.name': 'Autotransformer',\n 'battery.name': 'Battery storage',\n 'breaker.name': 'Circuit breaker (QF)',\n 'busbar.name': 'Busbar segment',\n 'converter-bidir.name': 'Bidirectional converter (PCS)',\n 'ct.name': 'Current transformer (CT)',\n 'disconnector.name': 'Disconnector (QS)',\n 'earth.name': 'Earth',\n 'earthing-switch.name': 'Earthing switch (QE)',\n 'fuse.name': 'Fuse (FU)',\n 'generator.name': 'Generator (G)',\n 'grid-source.name': 'Grid source',\n 'grounding-transformer.name': 'Grounding transformer (zig-zag)',\n 'inverter.name': 'Inverter (DC→AC)',\n 'load-switch.name': 'Load break switch',\n 'load.name': 'Load',\n 'ngr.name': 'Neutral grounding resistor (NGR)',\n 'pt.name': 'Voltage transformer (PT)',\n 'pv.name': 'PV module',\n 'rectifier.name': 'Rectifier (AC→DC)',\n 'series-reactor.name': 'Series reactor',\n 'shunt-capacitor.name': 'Shunt capacitor',\n 'shunt-reactor.name': 'Shunt reactor',\n 'sync-motor.name': 'Synchronous motor',\n 'transformer-2w.name': 'Two-winding transformer',\n 'transformer-3w.name': 'Three-winding transformer',\n 'wind-turbine.name': 'Wind turbine',\n // ---- v0.2 additions ----\n 'gfci-breaker.name': 'GFCI breaker (RCBO)',\n 'rcd.name': 'Residual current device (RCD)',\n 'recloser.name': 'Recloser',\n 'energy-meter.name': 'Energy meter (Wh)',\n 'voltmeter.name': 'Voltmeter (V)',\n 'ammeter.name': 'Ammeter (A)',\n 'wattmeter.name': 'Wattmeter (W)',\n 'frequency-meter.name': 'Frequency meter (Hz)',\n 'contactor.name': 'Contactor (KM)',\n 'motor-starter.name': 'Motor starter',\n 'thermal-overload.name': 'Thermal overload relay',\n 'vfd.name': 'Variable frequency drive (VFD)',\n 'soft-starter.name': 'Soft starter',\n 'transfer-switch.name': 'Transfer switch (ATS)',\n 'dc-disconnector.name': 'DC disconnector',\n 'dc-combiner.name': 'DC combiner box',\n 'ev-charger.name': 'EV charger',\n\n 'arc-suppression-coil.desc': 'Resonant neutral grounding: inductor to earth',\n 'busbar.desc': 'Stretchable single-bus segment with multiple taps',\n 'converter-bidir.desc': 'Storage converter: bidirectional AC ↔ DC',\n 'earthing-switch.desc': 'Disconnector + earth connection, single port',\n 'grid-source.desc': 'Infinite bus / external grid',\n 'grounding-transformer.desc': 'Wye-zigzag transformer for neutral grounding',\n 'load.desc': 'Abstract load (current-out arrow)',\n 'ngr.desc': 'Low-resistance grounding: transformer neutral to earth',\n 'series-reactor.desc': 'Same symbol as shunt reactor; distinguished by usage',\n 'wind-turbine.desc': 'Wind turbine: generator + three-blade rotor mark',\n 'gfci-breaker.desc': 'Residual-current breaker with overcurrent (UL943 / IEC 61009). NA GFCI / EU RCBO.',\n 'rcd.desc': 'Residual-current breaker without overcurrent (IEC 61008).',\n 'recloser.desc': 'Medium-voltage automatic recloser.',\n 'energy-meter.desc': 'Active energy meter (kWh) — service entrance / submeter.',\n 'contactor.desc': 'Main-circuit contactor; typically used with a thermal overload and a motor.',\n 'motor-starter.desc': 'Motor starter (IEC 60617 general symbol).',\n 'thermal-overload.desc': 'Motor thermal-overload relay; sits between the contactor and the motor.',\n 'vfd.desc': 'Variable Frequency Drive for induction motor speed control.',\n 'soft-starter.desc': 'Motor soft-starter (thyristor-based reduced-voltage starting).',\n 'transfer-switch.desc': 'Two-source transfer switch (ATS / manual). Two source inputs + one load output, mechanically interlocked.',\n 'dc-disconnector.desc': 'DC isolating switch — PV string / battery DC-side isolation.',\n 'dc-combiner.desc': 'PV string combiner box (4-input example).',\n 'ev-charger.desc': 'Electric vehicle charging station.',\n\n 'breaker.state.open': 'Open',\n 'disconnector.state.open': 'Open',\n 'earthing-switch.state.open': 'Open',\n 'fuse.state.blown': 'Blown',\n 'load-switch.state.open': 'Open',\n 'gfci-breaker.state.open': 'Open',\n 'rcd.state.open': 'Open',\n 'recloser.state.open': 'Open',\n 'contactor.state.open': 'Open',\n 'thermal-overload.state.tripped': 'Tripped',\n 'transfer-switch.state.position': 'Position (normal/emergency/off)',\n 'dc-disconnector.state.open': 'Open',\n\n 'battery.param.E': 'Capacity',\n 'busbar.param.Un': 'Rated voltage',\n 'converter-bidir.param.S': 'Capacity',\n 'load.param.P': 'Active power',\n 'load.param.cosphi': 'Power factor',\n 'ngr.param.R': 'Resistance',\n 'shunt-capacitor.param.Q': 'Reactive capacity',\n 'shunt-capacitor.param.stages': 'Stages',\n 'transformer-2w.param.S': 'Capacity',\n 'transformer-2w.param.ratio': 'Ratio',\n 'gfci-breaker.param.In': 'Rated current',\n 'gfci-breaker.param.IDn': 'Residual operating current',\n 'rcd.param.IDn': 'Residual operating current',\n};\n\nconst tables: Record<Locale, Table> = { zh, en };\n\nfunction lookup(locale: Locale, key: string): string | undefined {\n return tables[locale][key] ?? tables.zh[key];\n}\n\n/** Returns a translator that re-renders on locale change. */\nexport function useLibT(): (key: string, fallback?: string) => string {\n const locale = useLocale((s) => s.locale);\n return (key, fallback) => lookup(locale, key) ?? fallback ?? key;\n}\n","/**\n * Element library popover. Visible whenever the place tool is active —\n * the FloatingToolbar's \"元件\" button toggles that tool, and picking an\n * entry here arms `placeKind`. Closing (X) returns to the select tool so\n * the place state and the popover stay in lockstep.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { ChevronDown, Search, X } from 'lucide-react';\nimport {\n CATEGORY_ORDER,\n libraryByCategory,\n} from '../element-library';\nimport { atLeast, useEditorTier } from '../hooks/editor-tier';\nimport { usePanels } from '../hooks/use-panels';\nimport { useT, type LocaleKey } from '../i18n';\nimport { useLibT } from '../i18n/library';\nimport { useEditorStore } from '../store';\nimport type { LibraryEntry } from '../model/library';\n\nconst PALETTE_COLLAPSE_STORAGE_KEY = 'ole-palette-collapsed';\n\n/**\n * Library entry IDs that should NOT appear in the palette. The bus is drawn\n * via the dedicated busbar tool (click + drag); having it in the element\n * grid would confuse users into trying to drop it like a fixed-size symbol.\n */\nconst PALETTE_HIDDEN_IDS = new Set<string>(['busbar']);\n\nconst PALETTE_BY_CATEGORY: Record<string, LibraryEntry[]> = (() => {\n const out: Record<string, LibraryEntry[]> = {};\n for (const [cat, entries] of Object.entries(libraryByCategory)) {\n const visible = entries.filter((e) => !PALETTE_HIDDEN_IDS.has(e.id));\n if (visible.length) out[cat] = visible;\n }\n return out;\n})();\n\nconst CATEGORY_IDS: readonly string[] = (() => {\n const known = new Set(CATEGORY_ORDER);\n const extras = Object.keys(PALETTE_BY_CATEGORY).filter((c) => !known.has(c));\n return [\n ...CATEGORY_ORDER.filter((c) => PALETTE_BY_CATEGORY[c]?.length),\n ...extras,\n ];\n})();\n\nfunction readPaletteCollapsed(): Set<string> {\n try {\n const raw = window.localStorage.getItem(PALETTE_COLLAPSE_STORAGE_KEY);\n if (!raw) return new Set();\n const arr = JSON.parse(raw) as unknown;\n return Array.isArray(arr)\n ? new Set(arr.filter((x) => typeof x === 'string'))\n : new Set();\n } catch {\n return new Set();\n }\n}\n\nfunction writePaletteCollapsed(s: Set<string>) {\n try {\n window.localStorage.setItem(\n PALETTE_COLLAPSE_STORAGE_KEY,\n JSON.stringify([...s]),\n );\n } catch {\n // ignore\n }\n}\n\nexport function LibraryPopover() {\n const t = useT();\n const open = useEditorStore((s) => s.activeTool === 'place');\n const placeKind = useEditorStore((s) => s.placeKind);\n const setTool = useEditorStore((s) => s.setActiveTool);\n const outlineOpen = usePanels((s) => s.outlineOpen);\n const tier = useEditorTier();\n const sheet = atLeast(tier, 'dense');\n // Insets so the popover never reaches the floating chrome:\n // - top: leave room for the TopBar (12px gutter + 48px toolbar + 8px margin)\n // - bottom: leave room for the bottom-toolbars / outline button\n // - when outline is expanded, leave room for the outline panel (max ~50vh)\n const TOP_INSET = 68;\n // Outline panel max-height (when library open) is `min(40vh, ...)`, anchored\n // at bottom-3, so reserved bottom space = 40vh + 12px (anchor) + 8px (gap).\n const BOTTOM_INSET = outlineOpen\n ? 'calc(40vh + 20px)'\n : '68px';\n const maxHeight = sheet\n ? undefined\n : `calc(100vh - ${TOP_INSET}px - ${BOTTOM_INSET})`;\n // Phone-class flow: the library is a full-canvas picker that pops up while\n // place mode is active *and* no element is armed yet. Picking an entry\n // arms `placeKind` and hides the picker so the canvas is clear for the\n // placement gesture; PlaceTool clears `placeKind` after each drop on\n // touch (`disarmPlaceOnPhone`), so the picker reappears for the next pick.\n if (!open) return null;\n if (sheet && placeKind != null) return null;\n // Phone-class layout: fill the canvas area between the top bar and the\n // unified bottom bar. Wider viewports keep the classic 288px left-anchored\n // dock.\n const wrapperStyle: React.CSSProperties = sheet\n ? {\n top: `calc(${TOP_INSET}px + var(--ole-top-inset, 0px))`,\n left: 'calc(0.75rem + var(--ole-left-inset, 0px))',\n right: 'calc(0.75rem + var(--ole-right-inset, 0px))',\n bottom: 'calc(4rem + var(--ole-bottom-inset, 0px) + 0.75rem)',\n }\n : { top: TOP_INSET };\n return (\n <div\n className={sheet ? 'absolute z-20' : 'absolute left-3 z-20'}\n style={wrapperStyle}\n role=\"dialog\"\n aria-label={t('library.title')}\n >\n <aside\n className={\n sheet\n ? 'ole-glass flex h-full w-full flex-col overflow-hidden rounded-2xl border border-border shadow-md'\n : 'ole-glass flex w-72 flex-col overflow-hidden rounded-2xl border border-border shadow-md'\n }\n style={maxHeight ? { maxHeight } : undefined}\n >\n <div className=\"flex items-center gap-1.5 border-b border-border/40 px-3 py-2\">\n <span className=\"flex-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n {t('library.title')}\n </span>\n <button\n type=\"button\"\n onClick={() => setTool(sheet ? 'pan' : 'select')}\n className=\"rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n aria-label={t('common.close')}\n title={t('common.close')}\n >\n <X className=\"size-3.5\" />\n </button>\n </div>\n <LibraryBody sheet={sheet} />\n </aside>\n </div>\n );\n}\n\nfunction LibraryBody({ sheet }: { sheet: boolean }) {\n const t = useT();\n const libT = useLibT();\n const [query, setQuery] = useState('');\n const [collapsed, setCollapsed] = useState<Set<string>>(() =>\n readPaletteCollapsed(),\n );\n\n const filteredByCat = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return PALETTE_BY_CATEGORY;\n const out: Record<string, LibraryEntry[]> = {};\n for (const [cat, entries] of Object.entries(PALETTE_BY_CATEGORY)) {\n const hits = entries.filter((e) => {\n const name = libT(`${e.id}.name`, e.name).toLowerCase();\n const desc = libT(`${e.id}.desc`, e.description ?? '').toLowerCase();\n return (\n name.includes(q) ||\n e.id.toLowerCase().includes(q) ||\n desc.includes(q)\n );\n });\n if (hits.length) out[cat] = hits;\n }\n return out;\n }, [query, libT]);\n\n const isSearching = query.trim().length > 0;\n const noMatch =\n isSearching && Object.values(filteredByCat).every((e) => !e?.length);\n\n const handleToggle = useCallback((catId: string, isOpen: boolean) => {\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (isOpen) next.delete(catId);\n else next.add(catId);\n writePaletteCollapsed(next);\n return next;\n });\n }, []);\n\n return (\n <>\n <div className=\"px-2 pb-1.5 pt-2\">\n <SearchBox value={query} onChange={setQuery} />\n </div>\n <div className=\"flex-1 overflow-y-auto px-2 pb-2\">\n {noMatch ? (\n <p className=\"px-3 py-6 text-center text-xs text-muted-foreground\">\n {t('library.empty')}\n </p>\n ) : (\n CATEGORY_IDS.map((catId) => {\n const entries = filteredByCat[catId];\n if (!entries?.length) return null;\n const total = PALETTE_BY_CATEGORY[catId]?.length ?? entries.length;\n const label = t(`cat.${catId}` as LocaleKey);\n const isOpen = isSearching || !collapsed.has(catId);\n return (\n <details\n key={catId}\n open={isOpen}\n className=\"group mb-2 last:mb-0\"\n onToggle={(e) => {\n if (isSearching) return;\n handleToggle(\n catId,\n (e.currentTarget as HTMLDetailsElement).open,\n );\n }}\n >\n <summary className=\"flex cursor-pointer select-none items-center gap-1.5 rounded-md px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground hover:bg-accent hover:text-accent-foreground\">\n <ChevronDown className=\"size-3 transition-transform [details:not([open])>summary>&]:-rotate-90\" />\n <span className=\"flex-1\">{label}</span>\n <CountChip>\n {isSearching && entries.length !== total\n ? `${entries.length}/${total}`\n : total}\n </CountChip>\n </summary>\n <ul className=\"mt-0.5 space-y-px\">\n {entries.map((entry) => (\n <ElementRow key={entry.id} entry={entry} sheet={sheet} />\n ))}\n </ul>\n </details>\n );\n })\n )}\n </div>\n </>\n );\n}\n\nfunction SearchBox({\n value,\n onChange,\n}: {\n value: string;\n onChange: (v: string) => void;\n}) {\n const t = useT();\n return (\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground\" />\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={t('library.searchPlaceholder')}\n className=\"h-7 w-full rounded-md border border-border/60 bg-background/50 pl-7 pr-7 text-xs placeholder:text-muted-foreground focus:border-border focus:outline-none focus:ring-1 focus:ring-ring\"\n aria-label={t('library.searchAria')}\n />\n {value && (\n <button\n type=\"button\"\n aria-label={t('library.clearSearch')}\n onClick={() => onChange('')}\n className=\"absolute right-1 top-1/2 -translate-y-1/2 rounded-sm p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n >\n <X className=\"size-3\" />\n </button>\n )}\n </div>\n );\n}\n\nfunction ElementRow({\n entry,\n sheet,\n}: {\n entry: LibraryEntry;\n sheet: boolean;\n}) {\n const t = useT();\n const libT = useLibT();\n const name = libT(`${entry.id}.name`, entry.name);\n const description = libT(`${entry.id}.desc`, entry.description ?? '');\n const setTool = useEditorStore((s) => s.setActiveTool);\n const armed = useEditorStore(\n (s) => s.activeTool === 'place' && s.placeKind === entry.id,\n );\n // On phone the library re-opens between every drop, so highlight the most\n // recently placed kind and scroll it into view — keeps \"drop another of\n // the same\" cheap without forcing the user to re-find it in the list.\n const recent = useEditorStore(\n (s) =>\n sheet &&\n s.activeTool === 'place' &&\n s.placeKind == null &&\n s.lastPlaceKind === entry.id,\n );\n const ref = useRef<HTMLLIElement | null>(null);\n useEffect(() => {\n if (recent) ref.current?.scrollIntoView({ block: 'nearest' });\n }, [recent]);\n\n const onDragStart = (e: React.DragEvent<HTMLLIElement>) => {\n e.dataTransfer.effectAllowed = 'copy';\n e.dataTransfer.setData('application/x-oneline-kind', entry.id);\n e.dataTransfer.setData('text/plain', entry.id);\n const ghost = document.createElement('div');\n ghost.className = 'ole-glass';\n ghost.style.cssText = [\n 'position:absolute',\n 'top:-9999px',\n 'left:-9999px',\n 'width:64px',\n 'height:64px',\n 'display:flex',\n 'align-items:center',\n 'justify-content:center',\n 'border-radius:12px',\n 'border:1px solid var(--border)',\n 'box-shadow:0 4px 12px rgba(0,0,0,0.12)',\n 'color:var(--foreground)',\n 'padding:8px',\n ].join(';');\n ghost.innerHTML = `<svg class=\"ole-symbol\" viewBox=\"${entry.viewBox}\" width=\"48\" height=\"48\" preserveAspectRatio=\"xMidYMid meet\">${entry.svg}</svg>`;\n document.body.appendChild(ghost);\n e.dataTransfer.setDragImage(ghost, 32, 32);\n setTimeout(() => ghost.remove(), 0);\n };\n\n return (\n <li\n ref={ref}\n className={`group flex cursor-grab items-center gap-2.5 rounded-md px-2 py-1.5 transition-colors hover:bg-accent active:cursor-grabbing ${\n armed\n ? 'bg-accent ring-1 ring-[var(--selection)]/60'\n : recent\n ? 'ring-1 ring-[var(--selection)]/30'\n : ''\n }`}\n draggable\n onDragStart={onDragStart}\n onClick={() => setTool('place', { placeKind: entry.id })}\n data-kind={entry.id}\n title={description ? `${name} — ${description}` : `${name} — ${t('library.itemHint')}`}\n >\n <div className=\"flex h-7 w-12 shrink-0 items-center justify-center\">\n <svg\n viewBox={entry.viewBox}\n className=\"ole-symbol size-full\"\n preserveAspectRatio=\"xMidYMid meet\"\n dangerouslySetInnerHTML={{ __html: entry.svg }}\n />\n </div>\n <span className=\"truncate text-xs text-foreground/80 group-hover:text-accent-foreground\">\n {name}\n </span>\n </li>\n );\n}\n\nfunction CountChip({ children }: { children: React.ReactNode }) {\n return (\n <span className=\"rounded bg-muted/50 px-1.5 py-0.5 font-mono text-[10px] tabular-nums text-muted-foreground/80\">\n {children}\n </span>\n );\n}\n","/**\n * One-shot onboarding-card dismissal flag, persisted to localStorage.\n *\n * Mirrors `usePanels` / `useTheme` patterns: a tiny Zustand store with a\n * boolean and a setter. Once dismissed, the card stays hidden across\n * reloads; clearing storage (or calling `reset`) brings it back.\n */\n\nimport { create } from 'zustand';\n\nconst STORAGE_KEY = 'ole-onboarding-dismissed';\n\nfunction readInitial(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return window.localStorage.getItem(STORAGE_KEY) === '1';\n } catch {\n return false;\n }\n}\n\nfunction persist(dismissed: boolean): void {\n try {\n if (dismissed) window.localStorage.setItem(STORAGE_KEY, '1');\n else window.localStorage.removeItem(STORAGE_KEY);\n } catch {\n // ignore quota / disabled storage\n }\n}\n\ninterface OnboardingState {\n dismissed: boolean;\n dismiss: () => void;\n reset: () => void;\n}\n\nexport const useOnboarding = create<OnboardingState>((set) => ({\n dismissed: readInitial(),\n dismiss: () => {\n persist(true);\n set({ dismissed: true });\n },\n reset: () => {\n persist(false);\n set({ dismissed: false });\n },\n}));\n","/**\n * First-visit onboarding card. Surfaces the canonical drawing flow:\n * busbar first → drag elements off the bus → chain from terminals.\n *\n * Visibility: shown until the user dismisses it (persisted to localStorage),\n * regardless of whether the canvas is empty — the card and the sample\n * diagram together form the first-impression. The wrapper is\n * `pointer-events: none` so users can press-and-drag right through it\n * (e.g., the busbar drag the card just told them to perform); only the\n * dismiss controls accept clicks.\n */\n\nimport { Cable, Minus, Shapes, X } from 'lucide-react';\nimport { useOnboarding } from '../hooks/use-onboarding';\nimport { useT } from '../i18n';\n\nexport function OnboardingCard() {\n const t = useT();\n const dismissed = useOnboarding((s) => s.dismissed);\n const dismiss = useOnboarding((s) => s.dismiss);\n if (dismissed) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-label={t('onboard.title')}\n className=\"ole-glass pointer-events-none absolute left-1/2 top-1/2 z-10 w-[min(420px,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 rounded-2xl border border-border p-5 shadow-md\"\n >\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold\">{t('onboard.title')}</h2>\n <button\n type=\"button\"\n onClick={dismiss}\n aria-label={t('onboard.dismiss')}\n className=\"pointer-events-auto rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n >\n <X className=\"size-3.5\" />\n </button>\n </div>\n <ol className=\"mt-3 space-y-2.5\">\n <Step\n n={1}\n icon={<Minus />}\n title={t('onboard.step1.title')}\n body={t('onboard.step1.body')}\n />\n <Step\n n={2}\n icon={<Shapes />}\n title={t('onboard.step2.title')}\n body={t('onboard.step2.body')}\n />\n <Step\n n={3}\n icon={<Cable />}\n title={t('onboard.step3.title')}\n body={t('onboard.step3.body')}\n />\n </ol>\n <button\n type=\"button\"\n onClick={dismiss}\n className=\"pointer-events-auto mt-4 w-full rounded-md bg-primary py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90\"\n >\n {t('onboard.dismiss')}\n </button>\n </div>\n );\n}\n\nfunction Step({\n n,\n icon,\n title,\n body,\n}: {\n n: number;\n icon: React.ReactNode;\n title: string;\n body: string;\n}) {\n return (\n <li className=\"flex items-start gap-2.5\">\n <span\n className=\"mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full bg-[color-mix(in_oklch,var(--selection)_18%,transparent)] font-mono text-[10px] font-semibold tabular-nums text-[var(--selection)]\"\n aria-hidden\n >\n {n}\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium\">\n <span className=\"text-muted-foreground [&>svg]:size-3.5\">{icon}</span>\n <span>{title}</span>\n </div>\n <p className=\"mt-0.5 text-[11px] leading-snug text-muted-foreground\">\n {body}\n </p>\n </div>\n </li>\n );\n}\n","/**\n * Right-panel property editor — minimal by design. Shows only what the user\n * needs to *configure* (name, note, kind-specific state). Transformations\n * (rotate/mirror/delete) live on the contextual floating toolbar; type label\n * lives in the panel header.\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport { libraryById } from '../element-library';\nimport { useT } from '../i18n';\nimport { useLibT } from '../i18n/library';\nimport { useEditorStore } from '../store';\nimport type {\n Bus,\n BusId,\n Element,\n ElementId,\n LibraryParamField,\n LibraryStateField,\n ParamValue,\n WireId,\n} from '../model';\nimport { cn } from '../lib/utils';\n\nexport function PropertyPanel() {\n const t = useT();\n const selection = useEditorStore((s) => s.selection);\n const elements = useEditorStore((s) => s.diagram.elements);\n const buses = useEditorStore((s) => s.diagram.buses);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const selectedWire = useEditorStore((s) => s.selectedWire);\n\n if (selectedWire) return <WirePanel wireId={selectedWire} />;\n if (selectedNode) return <NodePanel nodeId={selectedNode} />;\n\n if (selection.length === 0) {\n return (\n <div className=\"px-4 py-5 text-center text-xs text-muted-foreground\">\n {t('props.empty')}\n </div>\n );\n }\n\n if (selection.length > 1) {\n return (\n <div className=\"px-4 py-5 text-center text-xs text-muted-foreground\">\n {t('props.multi', { n: selection.length })}\n </div>\n );\n }\n\n const id = selection[0];\n const bus = (buses ?? []).find((b) => b.id === id);\n if (bus) return <BusInspector bus={bus} />;\n const element = elements.find((e) => e.id === id);\n if (!element) return null;\n const lib = libraryById[element.kind];\n\n return (\n <div className=\"flex flex-col gap-2.5 overflow-y-auto px-3 py-3 text-xs\">\n <TextRow\n label={t('props.name')}\n value={element.name ?? ''}\n placeholder={element.id}\n onCommit={(v) =>\n useEditorStore\n .getState()\n .updateElement(id, { name: v.trim() === '' ? undefined : v.trim() })\n }\n />\n <TextAreaRow\n label={t('props.note')}\n value={element.note ?? ''}\n onCommit={(v) =>\n useEditorStore\n .getState()\n .updateElement(id, { note: v.trim() === '' ? undefined : v.trim() })\n }\n />\n {lib?.state && lib.state.length > 0 && (\n <div className=\"mt-1 flex flex-col gap-1.5 border-t border-border/40 pt-2.5\">\n {lib.state.map((field) => (\n <StateField key={field.name} id={id} element={element} field={field} />\n ))}\n </div>\n )}\n <ParamsSection\n id={id}\n element={element}\n schema={lib?.params ?? []}\n />\n </div>\n );\n}\n\nfunction ParamsSection({\n id,\n element,\n schema,\n}: {\n id: ElementId;\n element: Element;\n schema: LibraryParamField[];\n}) {\n const schemaKeys = new Set(schema.map((p) => p.name));\n const extras = element.params\n ? Object.entries(element.params).filter(([k]) => !schemaKeys.has(k))\n : [];\n if (schema.length === 0 && extras.length === 0) return null;\n return (\n <div className=\"mt-1 flex flex-col gap-1.5 border-t border-border/40 pt-2.5\">\n {schema.map((field) => (\n <SchemaParamField\n key={field.name}\n id={id}\n element={element}\n field={field}\n />\n ))}\n {extras.map(([key, value]) => (\n <ParamField\n key={key}\n id={id}\n element={element}\n fieldKey={key}\n value={value}\n />\n ))}\n </div>\n );\n}\n\n/**\n * Schema-driven param row: uses the library entry's declared label / unit /\n * type / default.\n */\nfunction SchemaParamField({\n id,\n element,\n field,\n}: {\n id: ElementId;\n element: Element;\n field: LibraryParamField;\n}) {\n const t = useT();\n const libT = useLibT();\n const cur = element.params?.[field.name] ?? field.default;\n const label = libT(`${element.kind}.param.${field.name}`, field.label ?? field.name);\n const onCommit = (next: ParamValue | undefined) => {\n const params = { ...(element.params ?? {}) };\n if (next === undefined || next === field.default) delete params[field.name];\n else params[field.name] = next;\n useEditorStore.getState().updateElement(id, {\n params: Object.keys(params).length > 0 ? params : undefined,\n });\n };\n\n if (field.type === 'boolean') {\n return (\n <Field label={label}>\n <ToggleButton active={!!cur} onClick={() => onCommit(!cur)}>\n {cur ? t('common.yes') : t('common.no')}\n </ToggleButton>\n </Field>\n );\n }\n if (field.type === 'number') {\n return (\n <NumberRow\n label={label}\n value={typeof cur === 'number' ? cur : 0}\n unit={field.unit}\n onCommit={onCommit}\n />\n );\n }\n return (\n <TextRow\n label={label}\n value={typeof cur === 'string' ? cur : ''}\n unit={field.unit}\n onCommit={(v) => onCommit(v.trim() === '' ? undefined : v)}\n />\n );\n}\n\n/**\n * Param row driven purely by the stored value's type (no library schema\n * required). Number/boolean/string are each rendered with the right input;\n * empty strings clear the key so users don't leave dangling `\"\"` values.\n */\nfunction ParamField({\n id,\n element,\n fieldKey,\n value,\n}: {\n id: ElementId;\n element: Element;\n fieldKey: string;\n value: ParamValue;\n}) {\n const t = useT();\n const onCommit = (next: ParamValue | undefined) => {\n const params = { ...(element.params ?? {}) };\n if (next === undefined) delete params[fieldKey];\n else params[fieldKey] = next;\n useEditorStore.getState().updateElement(id, {\n params: Object.keys(params).length > 0 ? params : undefined,\n });\n };\n\n if (typeof value === 'boolean') {\n return (\n <Field label={fieldKey}>\n <ToggleButton active={value} onClick={() => onCommit(!value)}>\n {value ? t('common.yes') : t('common.no')}\n </ToggleButton>\n </Field>\n );\n }\n if (typeof value === 'number') {\n return (\n <NumberRow label={fieldKey} value={value} onCommit={onCommit} />\n );\n }\n return (\n <TextRow\n label={fieldKey}\n value={value}\n onCommit={(v) => onCommit(v.trim() === '' ? undefined : v)}\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// Bus inspector — selected bus shows name + Un + span (read-only span).\n// ---------------------------------------------------------------------------\n\nfunction BusInspector({ bus }: { bus: Bus }) {\n const t = useT();\n const id = bus.id;\n const onName = (v: string) => {\n const name = v.trim();\n updateBusEntry(id, { name: name === '' ? undefined : name });\n };\n return (\n <div className=\"flex flex-col gap-2.5 overflow-y-auto px-3 py-3 text-xs\">\n <TextRow\n label={t('props.name')}\n value={bus.name ?? ''}\n placeholder={bus.id}\n onCommit={onName}\n />\n <TextAreaRow\n label={t('props.note')}\n value={bus.note ?? ''}\n onCommit={(v) =>\n updateBusEntry(id, { note: v.trim() === '' ? undefined : v.trim() })\n }\n />\n <BusParams bus={bus} />\n </div>\n );\n}\n\nfunction BusParams({ bus }: { bus: Bus }) {\n const onCommit = (key: string, next: ParamValue | undefined) => {\n const params = { ...(bus.params ?? {}) };\n if (next === undefined || next === '') delete params[key];\n else params[key] = next;\n updateBusEntry(bus.id, {\n params: Object.keys(params).length > 0 ? params : undefined,\n });\n };\n const cur = bus.params ?? {};\n return (\n <div className=\"mt-1 flex flex-col gap-1.5 border-t border-border/40 pt-2.5\">\n <NumberRow\n label=\"Un\"\n value={typeof cur.Un === 'number' ? cur.Un : 0}\n unit=\"kV\"\n onCommit={(v) => onCommit('Un', v)}\n />\n </div>\n );\n}\n\nfunction updateBusEntry(id: BusId, patch: Partial<Bus>) {\n useEditorStore.getState().dispatch((d) => {\n const buses = (d.buses ?? []).map((b) => (b.id === id ? { ...b, ...patch } : b));\n return { ...d, buses };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Wire inspector — shows the two endpoints and a \"select whole node\" action.\n// ---------------------------------------------------------------------------\n\nfunction WirePanel({ wireId }: { wireId: WireId }) {\n const t = useT();\n const wires = useEditorStore((s) => s.diagram.wires);\n const elements = useEditorStore((s) => s.diagram.elements);\n const buses = useEditorStore((s) => s.diagram.buses);\n const terminalToNode = useEditorStore((s) => s.internal.terminalToNode);\n const setSelectedNode = useEditorStore((s) => s.setSelectedNode);\n const wire = (wires ?? []).find((w) => w.id === wireId);\n if (!wire) {\n return (\n <div className=\"px-4 py-5 text-center text-xs text-muted-foreground\">\n {t('props.wireNotFound', { id: wireId })}\n </div>\n );\n }\n const nodeId = terminalToNode.get(wire.ends[0]);\n const elemById = new Map(elements.map((e) => [e.id, e]));\n const busById = new Map((buses ?? []).map((b) => [b.id, b]));\n const describeEnd = (end: string): { id: string; label: string; pin?: string } => {\n if (!end.includes('.')) {\n const b = busById.get(end);\n return { id: end, label: b?.name ?? end };\n }\n const dot = end.indexOf('.');\n const elId = end.slice(0, dot);\n const pin = end.slice(dot + 1);\n const el = elemById.get(elId);\n return { id: elId, label: el?.name ?? elId, pin };\n };\n const a = describeEnd(wire.ends[0]);\n const b = describeEnd(wire.ends[1]);\n return (\n <div className=\"flex flex-col gap-3 px-3 py-3 text-xs\">\n <div className=\"space-y-1\">\n <div className=\"text-[11px] uppercase tracking-wide text-muted-foreground\">\n {t('props.wire')}\n </div>\n <div className=\"font-mono text-[12px]\">{wire.id}</div>\n </div>\n <ul className=\"space-y-0.5 border-t border-border/40 pt-2\">\n {[a, b].map((e, i) => (\n <li\n key={i}\n className=\"flex cursor-pointer items-center gap-2 rounded-md px-1.5 py-1 hover:bg-accent\"\n onClick={() => useEditorStore.getState().setSelection([e.id])}\n >\n <span className=\"flex-1 truncate font-mono text-[11px]\">{e.id}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\">{e.label}</span>\n {e.pin && (\n <span className=\"font-mono text-[10px] text-muted-foreground/80\">\n {e.pin}\n </span>\n )}\n </li>\n ))}\n </ul>\n {nodeId && (\n <button\n type=\"button\"\n className=\"self-start rounded-md border border-border/60 px-2 py-1 text-[11px] text-muted-foreground hover:bg-accent\"\n onClick={() => setSelectedNode(nodeId)}\n >\n {t('props.selectWholeNode')}\n </button>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Connectivity-node panel — shown when a wire is the selected target.\n// ---------------------------------------------------------------------------\n\nfunction NodePanel({ nodeId }: { nodeId: string }) {\n const t = useT();\n const node = useEditorStore((s) => s.internal.nodes.get(nodeId));\n const elements = useEditorStore((s) => s.diagram.elements);\n const setSelection = useEditorStore((s) => s.setSelection);\n\n if (!node) {\n return (\n <div className=\"px-4 py-5 text-center text-xs text-muted-foreground\">\n {t('props.nodeNotFound', { id: nodeId })}\n </div>\n );\n }\n\n // Group terminals by element so the list reads \"QF1: a, b\" rather than\n // a flat 1-per-row blob.\n const byElement = new Map<string, string[]>();\n for (const ref of node.terminals) {\n const dot = ref.indexOf('.');\n if (dot < 0) continue;\n const eId = ref.slice(0, dot);\n const pin = ref.slice(dot + 1);\n const arr = byElement.get(eId) ?? [];\n arr.push(pin);\n byElement.set(eId, arr);\n }\n\n const elById = new Map(elements.map((e) => [e.id, e]));\n\n return (\n <div className=\"flex flex-col gap-3 px-3 py-3 text-xs\">\n <div className=\"space-y-1\">\n <div className=\"text-[11px] uppercase tracking-wide text-muted-foreground\">\n {t('props.node')}\n </div>\n <div className=\"font-mono text-[12px]\">\n {node.id}\n </div>\n <div className=\"text-[11px] text-muted-foreground\">\n {t('props.nodeStats', {\n terminals: node.terminals.length,\n elements: byElement.size,\n })}\n </div>\n </div>\n\n <ul className=\"space-y-0.5 border-t border-border/40 pt-2\">\n {[...byElement.entries()].map(([eId, pins]) => {\n const el = elById.get(eId);\n return (\n <li\n key={eId}\n className=\"flex cursor-pointer items-center gap-2 rounded-md px-1.5 py-1 hover:bg-accent\"\n onClick={() => setSelection([eId])}\n title={t('props.selectElement', { label: eId })}\n >\n <span className=\"flex-1 truncate font-mono text-[11px]\">{eId}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\">\n {el?.name ?? ''}\n </span>\n <span className=\"font-mono text-[10px] text-muted-foreground/80\">\n {pins.join(', ')}\n </span>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Form bits\n// ---------------------------------------------------------------------------\n\nfunction Field({\n label,\n children,\n}: {\n label: string;\n children: React.ReactNode;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <label className=\"w-16 shrink-0 truncate text-[11px] text-muted-foreground\">\n {label}\n </label>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n}\n\nfunction TextRow({\n label,\n value,\n placeholder,\n unit,\n onCommit,\n}: {\n label: string;\n value: string;\n placeholder?: string;\n unit?: string;\n onCommit: (v: string) => void;\n}) {\n const [local, setLocal] = useState(value);\n const ref = useRef<HTMLInputElement>(null);\n useEffect(() => setLocal(value), [value]);\n return (\n <Field label={label}>\n <div className=\"relative\">\n <input\n ref={ref}\n type=\"text\"\n value={local}\n placeholder={placeholder}\n onChange={(e) => setLocal(e.target.value)}\n onBlur={() => {\n if (local !== value) onCommit(local);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') ref.current?.blur();\n if (e.key === 'Escape') {\n setLocal(value);\n ref.current?.blur();\n }\n }}\n className={cn(\n 'h-7 w-full rounded-md border border-border/60 bg-background/50 px-2 text-[11px] focus:border-border focus:outline-none focus:ring-1 focus:ring-ring',\n unit && 'pr-8',\n )}\n />\n {unit && (\n <span className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground\">\n {unit}\n </span>\n )}\n </div>\n </Field>\n );\n}\n\nfunction TextAreaRow({\n label,\n value,\n onCommit,\n}: {\n label: string;\n value: string;\n onCommit: (v: string) => void;\n}) {\n const [local, setLocal] = useState(value);\n useEffect(() => setLocal(value), [value]);\n return (\n <Field label={label}>\n <textarea\n rows={2}\n value={local}\n onChange={(e) => setLocal(e.target.value)}\n onBlur={() => {\n if (local !== value) onCommit(local);\n }}\n className=\"w-full resize-none rounded-md border border-border/60 bg-background/50 px-2 py-1 text-[11px] focus:border-border focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </Field>\n );\n}\n\nfunction NumberRow({\n label,\n value,\n min,\n unit,\n onCommit,\n}: {\n label: string;\n value: number;\n min?: number;\n unit?: string;\n onCommit: (v: number) => void;\n}) {\n const [local, setLocal] = useState(String(value));\n const ref = useRef<HTMLInputElement>(null);\n useEffect(() => setLocal(String(value)), [value]);\n return (\n <Field label={label}>\n <div className=\"relative\">\n <input\n ref={ref}\n type=\"number\"\n value={local}\n onChange={(e) => setLocal(e.target.value)}\n onBlur={() => {\n const n = Number(local);\n if (Number.isFinite(n) && n !== value) onCommit(n);\n else setLocal(String(value));\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') ref.current?.blur();\n if (e.key === 'Escape') {\n setLocal(String(value));\n ref.current?.blur();\n }\n }}\n min={min}\n className={cn(\n 'h-7 w-full rounded-md border border-border/60 bg-background/50 px-2 font-mono text-[11px] tabular-nums focus:border-border focus:outline-none focus:ring-1 focus:ring-ring',\n unit && 'pr-8',\n )}\n />\n {unit && (\n <span className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground\">\n {unit}\n </span>\n )}\n </div>\n </Field>\n );\n}\n\nfunction ToggleButton({\n active,\n onClick,\n children,\n}: {\n active: boolean;\n onClick: () => void;\n children: React.ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n 'flex h-6 w-full items-center justify-center gap-1.5 rounded border text-[10px] transition-colors',\n active\n ? 'border-[var(--selection)] bg-[var(--selection)]/15 text-foreground'\n : 'border-border/60 text-muted-foreground hover:bg-accent',\n )}\n aria-pressed={active}\n >\n {children}\n </button>\n );\n}\n\nfunction StateField({\n id,\n element,\n field,\n}: {\n id: ElementId;\n element: Element;\n field: LibraryStateField;\n}) {\n const t = useT();\n const libT = useLibT();\n const label = libT(`${element.kind}.state.${field.name}`, field.label ?? field.name);\n const cur = element.state?.[field.name] ?? field.default;\n const onCommit = (next: ParamValue | undefined) => {\n const state = { ...(element.state ?? {}) };\n if (next === undefined || next === field.default) delete state[field.name];\n else state[field.name] = next;\n useEditorStore\n .getState()\n .updateElement(id, {\n state: Object.keys(state).length > 0 ? state : undefined,\n });\n };\n\n if (field.type === 'boolean') {\n return (\n <Field label={label}>\n <ToggleButton active={!!cur} onClick={() => onCommit(!cur)}>\n {cur ? t('common.yes') : t('common.no')}\n </ToggleButton>\n </Field>\n );\n }\n if (field.type === 'number') {\n return (\n <NumberRow\n label={label}\n value={typeof cur === 'number' ? cur : 0}\n onCommit={onCommit}\n />\n );\n }\n return (\n <TextRow\n label={label}\n value={typeof cur === 'string' ? cur : ''}\n onCommit={(v) => onCommit(v.trim() === '' ? undefined : v)}\n />\n );\n}\n","import { libraryById } from '../element-library';\nimport { atLeast, useEditorTier } from '../hooks/editor-tier';\nimport { useT } from '../i18n';\nimport { useLibT } from '../i18n/library';\nimport { cn } from '../lib/utils';\nimport { useEditorStore } from '../store';\nimport { PropertyPanel } from './PropertyPanel';\n\nexport function RightPanel() {\n const t = useT();\n const libT = useLibT();\n const selection = useEditorStore((s) => s.selection);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const selectedWire = useEditorStore((s) => s.selectedWire);\n const elements = useEditorStore((s) => s.diagram.elements);\n const buses = useEditorStore((s) => s.diagram.buses);\n const tier = useEditorTier();\n const compactWidth = atLeast(tier, 'dense');\n\n if (selection.length === 0 && !selectedNode && !selectedWire) return null;\n\n let title = t('props.title');\n let count: number | null = null;\n if (selectedWire) {\n title = t('props.wire');\n } else if (selectedNode) {\n title = t('props.node');\n } else if (selection.length === 1) {\n const id = selection[0];\n const bus = (buses ?? []).find((b) => b.id === id);\n if (bus) {\n title = bus.name ?? t('props.bus');\n } else {\n const el = elements.find((e) => e.id === id);\n if (el) {\n const lib = libraryById[el.kind];\n title = lib ? libT(`${lib.id}.name`, lib.name) : el.kind;\n }\n }\n } else {\n count = selection.length;\n }\n\n return (\n <aside\n className={cn(\n 'ole-glass absolute z-10 flex flex-col overflow-hidden rounded-2xl border border-border shadow-sm',\n compactWidth ? 'w-48' : 'w-56',\n )}\n style={{\n top: `calc(${compactWidth ? '4.5rem' : '0.75rem'} + var(--ole-top-inset, 0px))`,\n right: 'calc(0.75rem + var(--ole-right-inset, 0px))',\n maxHeight: `calc(100% - ${compactWidth ? '5.25rem' : '1.5rem'} - var(--ole-top-inset, 0px) - var(--ole-bottom-inset, 0px) - 4.5rem)`,\n }}\n >\n <div className=\"flex items-center gap-1.5 border-b border-border/40 px-3 py-2\">\n <span className=\"flex-1 truncate text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n {title}\n </span>\n {count != null && (\n <span className=\"rounded bg-muted/50 px-1.5 py-0.5 font-mono text-[10px] tabular-nums text-muted-foreground/80\">\n {t('props.nSelected', { n: count })}\n </span>\n )}\n </div>\n <PropertyPanel />\n </aside>\n );\n}\n","import { useEffect, useRef } from 'react';\nimport { CanvasSvg } from '../canvas';\nimport { ElementHoverLabel } from '../canvas/ElementHoverLabel';\nimport { useObservedWidth } from '../hooks/editor-tier';\nimport { EditorTierProvider } from '../hooks/use-editor-tier';\nimport { ContextMenuHost } from './ContextMenu';\nimport { ContextualToolbar } from './ContextualToolbar';\nimport { FloatingToolbar } from './FloatingToolbar';\nimport { LeftPanel } from './LeftPanel';\nimport { LibraryPopover } from './LibraryPopover';\nimport { OnboardingCard } from './OnboardingCard';\nimport { RightPanel } from './RightPanel';\nimport { ViewToolbar } from './ViewToolbar';\n\n/**\n * Keep keyboard focus where shortcuts can reach it.\n *\n * Two failure modes this guards against:\n * 1. Clicking a chrome button leaves it focused → next Space press activates\n * the button instead of starting a pan, etc. Fix: preventDefault on\n * mousedown of chrome buttons so they never steal focus from the canvas.\n * 2. Tab navigation puts focus on a chrome button → user has no way to\n * reset short of clicking. Fix: clicking the canvas blurs the active\n * element, restoring the \"no focus\" baseline shortcuts expect.\n *\n * Tab still works for keyboard-only users who actually want to navigate the\n * chrome — only mouse interactions are made focus-neutral.\n */\nfunction useFocusGuards() {\n useEffect(() => {\n const onMouseDown = (e: MouseEvent) => {\n const t = e.target as HTMLElement | null;\n if (!t) return;\n // Don't steal text selection or input focus.\n if (\n t.tagName === 'INPUT' ||\n t.tagName === 'TEXTAREA' ||\n t.isContentEditable\n ) {\n return;\n }\n const btn = t.closest('button');\n if (btn && btn.closest('.ole-glass')) e.preventDefault();\n };\n const onCanvasPointerDown = (e: Event) => {\n const t = e.target as HTMLElement | null;\n if (!t) return;\n if (!t.closest('.ole-canvas-root')) return;\n const active = document.activeElement as HTMLElement | null;\n if (!active || active === document.body) return;\n // Leave inputs alone — clicking outside an input naturally blurs it\n // anyway, and we don't want to fight any deliberate focus.\n if (\n active.tagName === 'INPUT' ||\n active.tagName === 'TEXTAREA' ||\n active.isContentEditable\n ) {\n return;\n }\n active.blur();\n };\n window.addEventListener('mousedown', onMouseDown);\n window.addEventListener('pointerdown', onCanvasPointerDown, true);\n return () => {\n window.removeEventListener('mousedown', onMouseDown);\n window.removeEventListener('pointerdown', onCanvasPointerDown, true);\n };\n }, []);\n}\n\nexport function EditorShell() {\n useFocusGuards();\n const rootRef = useRef<HTMLDivElement>(null);\n // Measured here (where the ref lives) so the layout effect runs *after*\n // this component's own ref attaches. A child component's layout effect\n // would fire before the parent's ref is set, so the first read is null.\n const width = useObservedWidth(rootRef);\n return (\n <ContextMenuHost>\n <div\n ref={rootRef}\n className=\"relative h-full w-full overflow-hidden bg-background text-foreground\"\n >\n <EditorTierProvider width={width}>\n <CanvasSvg />\n <LeftPanel />\n <RightPanel />\n <FloatingToolbar />\n <ViewToolbar />\n <ContextualToolbar />\n <LibraryPopover />\n <OnboardingCard />\n <ElementHoverLabel />\n </EditorTierProvider>\n </div>\n </ContextMenuHost>\n );\n}\n","import { useCallback, useEffect, useState } from 'react';\n\nexport type Theme = 'light' | 'dark';\n\nconst STORAGE_KEY = 'ole-theme';\n\nfunction readStored(): Theme | null {\n try {\n const v = window.localStorage.getItem(STORAGE_KEY);\n return v === 'light' || v === 'dark' ? v : null;\n } catch {\n return null;\n }\n}\n\nfunction persist(theme: Theme): void {\n try {\n window.localStorage.setItem(STORAGE_KEY, theme);\n } catch {\n // ignore quota / disabled storage\n }\n}\n\nfunction systemPrefersDark(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-color-scheme: dark)').matches\n );\n}\n\n/**\n * Resolve the theme to apply at startup. Exported so that `src/demo/main.tsx`\n * can apply the class before React mounts and avoid FOUC.\n *\n * Falls back to the OS `prefers-color-scheme` when no stored preference exists.\n */\nexport function getInitialTheme(): Theme {\n if (typeof window === 'undefined') return 'light';\n return readStored() ?? (systemPrefersDark() ? 'dark' : 'light');\n}\n\n/** Reflect a `Theme` value onto `<html>`'s class list. */\nexport function applyTheme(theme: Theme): void {\n if (typeof document === 'undefined') return;\n document.documentElement.classList.toggle('dark', theme === 'dark');\n}\n\n/**\n * Theme hook.\n *\n * - First visit: matches `prefers-color-scheme`. Continues to follow OS changes\n * until the user explicitly toggles, after which the explicit choice is\n * persisted and \"owns\" the theme.\n * - `setTheme` / `toggle` always persist (they are explicit user actions).\n */\nexport function useTheme() {\n const [theme, setThemeState] = useState<Theme>(getInitialTheme);\n\n useEffect(() => {\n applyTheme(theme);\n }, [theme]);\n\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n const onChange = (e: MediaQueryListEvent) => {\n if (readStored() == null) {\n setThemeState(e.matches ? 'dark' : 'light');\n }\n };\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n\n const setTheme = useCallback((next: Theme) => {\n persist(next);\n setThemeState(next);\n }, []);\n\n const toggle = useCallback(() => {\n setThemeState((t) => {\n const next = t === 'light' ? 'dark' : 'light';\n persist(next);\n return next;\n });\n }, []);\n\n return { theme, setTheme, toggle };\n}\n","import { useEffect } from 'react';\nimport { EditorShell } from './components/EditorShell';\nimport { fitToContentSoon, useKeyboardShortcuts } from './canvas';\nimport type { DiagramFile } from './model';\nimport { useEditorStore } from './store';\nimport { useLocale, type Locale } from './i18n';\nimport { applyTheme, type Theme } from './hooks/use-theme';\n\nexport interface OneLineEditorProps {\n className?: string;\n /** Initial DiagramFile to render. Re-renders when this reference changes. */\n diagram?: DiagramFile;\n /**\n * Force the editor's UI language. When omitted, falls back to the user's\n * previous choice (localStorage) or the browser's locale. When set, the\n * embedder owns the language and any change to this prop is mirrored into\n * the locale store.\n */\n locale?: Locale;\n /**\n * Force the editor's color mode. When omitted, uses the user's previous\n * choice or OS `prefers-color-scheme`. Applied via the `dark` class on\n * `<html>` (the standard Tailwind pattern), so embedding hosts that share\n * the same documentElement will see the same class.\n */\n theme?: Theme;\n}\n\nexport function OneLineEditor({ className, diagram, locale, theme }: OneLineEditorProps) {\n useEffect(() => {\n if (!diagram) return;\n // Don't clobber persisted/in-progress work on remount or HMR. Only seed\n // the initial diagram if the store is empty (first visit / cleared\n // storage). Consumers wanting to force-replace can call setDiagram\n // imperatively.\n const current = useEditorStore.getState().diagram;\n if (current.elements.length === 0) {\n useEditorStore.getState().setDiagram(diagram);\n }\n }, [diagram]);\n\n useEffect(() => {\n if (locale) useLocale.getState().setLocale(locale);\n }, [locale]);\n\n useEffect(() => {\n if (theme) applyTheme(theme);\n }, [theme]);\n\n // Reset the viewport to fit the diagram on first mount — covers both the\n // fresh-seed path above and the case where persisted state rehydrated a\n // diagram from a previous session. `fitToContentSoon` waits a few frames\n // for the canvas DOM to attach.\n useEffect(() => {\n fitToContentSoon();\n }, []);\n\n useKeyboardShortcuts();\n\n return (\n <div className={`ole-root ${className ?? 'h-full w-full'}`}>\n <EditorShell />\n </div>\n );\n}\n","/**\n * Disk I/O for DiagramFile JSON documents.\n *\n * Uses the File System Access API where available so that \"save\" can write\n * back to the originally opened file; falls back to a hidden `<input>` /\n * download anchor in browsers without it.\n */\n\nimport { t } from '../i18n';\nimport type { DiagramFile } from '../model';\n\nconst ACCEPT: Record<string, string[]> = { 'application/json': ['.json'] };\n\n/** Tracks the currently associated on-disk file across open / save calls. */\nexport interface FileSession {\n /** Present only when the FS Access API is available; lets save() overwrite. */\n handle?: FileSystemFileHandle;\n /** Display name shown in the title bar / save dialog default. */\n name: string;\n}\n\nconst supportsFsa = (): boolean =>\n typeof window !== 'undefined' && typeof window.showOpenFilePicker === 'function';\n\nconst isAbort = (e: unknown): boolean =>\n e instanceof DOMException && e.name === 'AbortError';\n\nfunction parseDiagram(text: string): DiagramFile {\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (e) {\n throw new Error(t('io.parseFailed', { err: (e as Error).message }));\n }\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new Error(t('io.notObject'));\n }\n const obj = raw as Record<string, unknown>;\n if (obj.version !== '1') {\n throw new Error(t('io.versionMismatch', { actual: JSON.stringify(obj.version) }));\n }\n if (!Array.isArray(obj.elements)) {\n throw new Error(t('io.elementsMissing'));\n }\n return obj as unknown as DiagramFile;\n}\n\nfunction serialize(diagram: DiagramFile): string {\n return JSON.stringify(diagram, null, 2) + '\\n';\n}\n\n/**\n * Pop the OS file picker and load a DiagramFile. Resolves to `null` when\n * the user cancels.\n */\nexport async function openDiagram(): Promise<{\n diagram: DiagramFile;\n session: FileSession;\n} | null> {\n if (supportsFsa()) {\n let handle: FileSystemFileHandle;\n try {\n [handle] = await window.showOpenFilePicker!({\n multiple: false,\n types: [{ description: t('topbar.file.fileDescription'), accept: ACCEPT }],\n });\n } catch (e) {\n if (isAbort(e)) return null;\n throw e;\n }\n const file = await handle.getFile();\n return {\n diagram: parseDiagram(await file.text()),\n session: { handle, name: file.name },\n };\n }\n\n return new Promise((resolve, reject) => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = '.json,application/json';\n input.addEventListener('change', async () => {\n const file = input.files?.[0];\n if (!file) return resolve(null);\n try {\n resolve({\n diagram: parseDiagram(await file.text()),\n session: { name: file.name },\n });\n } catch (e) {\n reject(e);\n }\n });\n input.addEventListener('cancel', () => resolve(null));\n input.click();\n });\n}\n\n/**\n * Save a DiagramFile to disk. With an existing handle and `saveAs=false`,\n * overwrites in place; otherwise prompts for a destination (or downloads in\n * browsers without FS Access). Resolves to the new session, or `null` if\n * the user cancelled.\n */\nexport async function saveDiagram(\n diagram: DiagramFile,\n session: FileSession | null,\n options: { saveAs?: boolean } = {},\n): Promise<FileSession | null> {\n const text = serialize(diagram);\n\n if (!options.saveAs && session?.handle) {\n const writable = await session.handle.createWritable();\n await writable.write(text);\n await writable.close();\n return session;\n }\n\n if (supportsFsa()) {\n let handle: FileSystemFileHandle;\n try {\n handle = await window.showSaveFilePicker!({\n suggestedName: session?.name ?? 'diagram.json',\n types: [{ description: t('topbar.file.fileDescription'), accept: ACCEPT }],\n });\n } catch (e) {\n if (isAbort(e)) return null;\n throw e;\n }\n const writable = await handle.createWritable();\n await writable.write(text);\n await writable.close();\n return { handle, name: handle.name };\n }\n\n // Fallback: browser download. We can't track a real handle.\n const url = URL.createObjectURL(new Blob([text], { type: 'application/json' }));\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = session?.name ?? 'diagram.json';\n anchor.click();\n URL.revokeObjectURL(url);\n return session ?? { name: 'diagram.json' };\n}\n","/**\n * File menu — New / Open / Save / Save As, plus ⌘O / ⌘S / ⌘⇧S keyboard\n * shortcuts. Renders as a dropdown button. Self-contained: reads/writes the\n * editor store directly and prompts the OS file picker (FS Access API where\n * available, hidden input fallback otherwise).\n *\n * Exported from the library so that embedding apps that want a \"local file\"\n * mode without backend can drop it into their own toolbar.\n */\n\nimport {\n FilePlus,\n FolderOpen,\n Save,\n} from 'lucide-react';\nimport { useEffect, useRef, useState } from 'react';\nimport { fitToContentSoon } from '../canvas';\nimport { Button } from './ui/button';\nimport { useT } from '../i18n';\nimport { openDiagram, saveDiagram } from '../lib/file-io';\nimport { useEditorStore } from '../store';\n\nexport function FileMenu() {\n const t = useT();\n const fileSession = useEditorStore((s) => s.fileSession);\n const fileLabel = fileSession?.name ?? t('common.unnamed');\n const { onNew, onOpen, onSave, onSaveAs } = useFileActions();\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (!(e.metaKey || e.ctrlKey)) return;\n const k = e.key.toLowerCase();\n if (k === 'o') {\n e.preventDefault();\n onOpen();\n } else if (k === 's') {\n e.preventDefault();\n if (e.shiftKey) onSaveAs();\n else onSave();\n }\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [onOpen, onSave, onSaveAs]);\n\n useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n window.addEventListener('mousedown', onClick);\n window.addEventListener('keydown', onKey);\n return () => {\n window.removeEventListener('mousedown', onClick);\n window.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const run = (action: () => void) => () => {\n setOpen(false);\n action();\n };\n\n return (\n <div ref={ref} className=\"relative\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1.5\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n >\n <FolderOpen />\n {t('topbar.file.label')}\n </Button>\n {open && (\n <div\n role=\"menu\"\n className=\"ole-glass absolute left-0 top-full mt-1.5 min-w-44 rounded-md border border-border p-1 shadow-md\"\n >\n <div className=\"border-b border-border px-2 pb-1.5 pt-1 text-xs text-muted-foreground\">\n {fileLabel}\n </div>\n <MenuItem onClick={run(onNew)} icon={<FilePlus />}>\n {t('topbar.file.new')}\n </MenuItem>\n <MenuItem onClick={run(onOpen)} icon={<FolderOpen />} hint=\"⌘O\">\n {t('topbar.file.open')}\n </MenuItem>\n <MenuItem onClick={run(onSave)} icon={<Save />} hint=\"⌘S\">\n {t('topbar.file.save')}\n </MenuItem>\n <MenuItem onClick={run(onSaveAs)} icon={<Save />} hint=\"⌘⇧S\">\n {t('topbar.file.saveAs')}\n </MenuItem>\n </div>\n )}\n </div>\n );\n}\n\nfunction MenuItem({\n children,\n icon,\n hint,\n onClick,\n}: {\n children: React.ReactNode;\n icon?: React.ReactNode;\n hint?: string;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={onClick}\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4\"\n >\n {icon}\n <span className=\"flex-1\">{children}</span>\n {hint && (\n <span className=\"text-xs tabular-nums text-muted-foreground\">{hint}</span>\n )}\n </button>\n );\n}\n\nfunction useFileActions() {\n const t = useT();\n const loadDiagramFromFile = useEditorStore((s) => s.loadDiagramFromFile);\n const setFileSession = useEditorStore((s) => s.setFileSession);\n const setDiagram = useEditorStore((s) => s.setDiagram);\n\n const onNew = () => {\n const { diagram } = useEditorStore.getState();\n if (diagram.elements.length > 0) {\n const ok = confirm(t('topbar.file.newConfirm'));\n if (!ok) return;\n }\n setDiagram({ version: '1', elements: [] });\n setFileSession(null);\n };\n\n const onOpen = async () => {\n try {\n const result = await openDiagram();\n if (result) {\n loadDiagramFromFile(result.diagram, result.session);\n fitToContentSoon();\n }\n } catch (e) {\n alert(t('topbar.file.openFailed', { err: (e as Error).message }));\n }\n };\n\n const onSave = async () => {\n try {\n const { diagram, fileSession } = useEditorStore.getState();\n const session = await saveDiagram(diagram, fileSession);\n if (session) setFileSession(session);\n } catch (e) {\n alert(t('topbar.file.saveFailed', { err: (e as Error).message }));\n }\n };\n\n const onSaveAs = async () => {\n try {\n const { diagram, fileSession } = useEditorStore.getState();\n const session = await saveDiagram(diagram, fileSession, { saveAs: true });\n if (session) setFileSession(session);\n } catch (e) {\n alert(t('topbar.file.saveFailed', { err: (e as Error).message }));\n }\n };\n\n return { onNew, onOpen, onSave, onSaveAs };\n}\n","/**\n * Export the current diagram as an ASCII DXF (AutoCAD R12 / AC1009). Mirrors\n * `export-image.ts` in shape but emits native CAD entities so the output is\n * editable in AutoCAD/LibreCAD/etc.\n *\n * Mapping summary:\n * <line> → LINE\n * <polyline> → LWPOLYLINE (open)\n * <polygon> → LWPOLYLINE (closed)\n * <rect> → LWPOLYLINE (closed, 4 corners; rx/ry ignored)\n * <circle> → CIRCLE\n * <ellipse> → CIRCLE if rx≈ry, else sampled LWPOLYLINE (closed)\n * <path d=\"M..A..\">→ sampled LWPOLYLINE (open)\n * <text> → TEXT\n * wire route → LWPOLYLINE (open)\n * free annotation → TEXT (one per line)\n * element label → TEXT (one per line, ID + showOnCanvas params)\n *\n * Y is flipped to CAD convention (Y up). 4 layers: WIRES, ELEMENTS, LABELS,\n * ANNOTATIONS.\n */\n\nimport {\n transformPoint,\n type InternalModel,\n type ResolvedElement,\n type ResolvedPlacement,\n} from '../compiler';\nimport type {\n LabelMode,\n LibraryEntry,\n LibraryLabelAnchor,\n TextAnnotation,\n} from '../model';\n\nexport interface DxfExportOptions {\n /** Used as the $PROJECTNAME header value when present. */\n title?: string;\n /** Decimal places for coordinate output. Default 6. */\n precision?: number;\n /** Element label visibility. Mirrors `DiagramFile.meta.labelMode`. Default 'all'. */\n labelMode?: LabelMode;\n /** Free text annotations from `DiagramFile.annotations` — `InternalModel`\n * doesn't carry them, so the caller passes them through. */\n annotations?: TextAnnotation[];\n}\n\nconst LAYER_WIRES = 'WIRES';\nconst LAYER_ELEMENTS = 'ELEMENTS';\nconst LAYER_LABELS = 'LABELS';\nconst LAYER_ANNOTATIONS = 'ANNOTATIONS';\n\nconst ARC_SAMPLES = 32;\nconst ELLIPSE_SAMPLES = 64;\nconst LABEL_FONT_SIZE = 7;\nconst ANNOTATION_FONT_SIZE = 8;\nconst ANNOTATION_LINE_HEIGHT = 1.25;\nconst LABEL_LINE_HEIGHT = 9;\nconst TEXT_FONT_SIZE_DEFAULT = 6;\n\nexport function buildExportDxf(\n model: InternalModel,\n opts: DxfExportOptions = {},\n): string {\n const w = new DxfWriter(opts.precision ?? 6);\n\n w.header(opts.title);\n w.tables([\n { name: LAYER_WIRES, color: 7 },\n { name: LAYER_ELEMENTS, color: 7 },\n { name: LAYER_LABELS, color: 8 },\n { name: LAYER_ANNOTATIONS, color: 3 },\n ]);\n w.beginEntities();\n\n // Wires (already in world coordinates).\n for (const r of model.wireRenders.values()) {\n if (r.path.length < 2) continue;\n w.lwpolyline(LAYER_WIRES, r.path.map(worldToDxf), false);\n }\n\n // Buses (drawn after wires so the heavier bar sits on top).\n for (const { geometry } of model.buses.values()) {\n const { axis, at, span } = geometry;\n const half = span / 2;\n const a: [number, number] = axis === 'x' ? [at[0] - half, at[1]] : [at[0], at[1] - half];\n const b: [number, number] = axis === 'x' ? [at[0] + half, at[1]] : [at[0], at[1] + half];\n w.lwpolyline(LAYER_WIRES, [a, b].map(worldToDxf), false);\n }\n\n // Element symbols.\n for (const re of model.elements.values()) {\n const place = model.layout.get(re.element.id);\n const lib = re.libraryDef;\n if (!place || !lib) continue;\n emitLibrarySvg(w, lib.svg, place);\n }\n\n // Element structural labels (ID + showOnCanvas params).\n const mode: LabelMode = opts.labelMode ?? 'all';\n if (mode !== 'off') {\n for (const re of model.elements.values()) {\n const place = model.layout.get(re.element.id);\n if (!place || !re.libraryDef) continue;\n const lines = labelLines(re, mode);\n if (lines.length === 0) continue;\n const anchor = re.libraryDef.label ?? fallbackAnchor(re.libraryDef);\n const [ax, ay] = anchorWorld(anchor, place, re.libraryDef);\n // Lines stack downward in screen-space → upward separation in DXF Y-up\n // becomes negative spacing on the screen-Y, i.e. positive when flipped.\n for (let i = 0; i < lines.length; i++) {\n const [x, y] = worldToDxf([ax, ay + i * LABEL_LINE_HEIGHT]);\n w.text(LAYER_LABELS, [x, y], lines[i], LABEL_FONT_SIZE, 0, false);\n }\n }\n }\n\n // Free text annotations.\n for (const ann of opts.annotations ?? []) {\n if (!ann.text) continue;\n const fs = ann.fontSize ?? ANNOTATION_FONT_SIZE;\n const lines = ann.text.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const [x, y] = worldToDxf([\n ann.at[0],\n ann.at[1] + (i + 1) * fs * ANNOTATION_LINE_HEIGHT,\n ]);\n // SVG `<text y>` is the baseline; the canvas annotation layer paints\n // the first line at `at.y + fs` and steps by fs*1.25. We mimic that so\n // DXF placement matches what users see on the canvas.\n w.text(LAYER_ANNOTATIONS, [x, y], lines[i], fs, 0, false);\n }\n }\n\n w.endEntities();\n return w.toString();\n}\n\nexport async function downloadDxf(\n model: InternalModel,\n filename = 'diagram.dxf',\n opts?: DxfExportOptions,\n): Promise<void> {\n const dxf = buildExportDxf(model, opts);\n const url = URL.createObjectURL(\n new Blob([dxf], { type: 'application/dxf;charset=utf-8' }),\n );\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n\n// -----------------------------------------------------------------------------\n// SVG fragment → DXF entities\n// -----------------------------------------------------------------------------\n\nfunction emitLibrarySvg(\n w: DxfWriter,\n svg: string,\n place: ResolvedPlacement,\n): void {\n // Wrap so DOMParser sees a single root element.\n const wrapped = `<svg xmlns=\"http://www.w3.org/2000/svg\">${svg}</svg>`;\n const doc = new DOMParser().parseFromString(wrapped, 'image/svg+xml');\n const root = doc.documentElement;\n if (!root || root.querySelector('parsererror')) return;\n\n for (const el of Array.from(root.children)) {\n const tag = el.tagName.toLowerCase();\n switch (tag) {\n case 'line':\n emitLine(w, el, place);\n break;\n case 'polyline':\n emitPoly(w, el, place, false);\n break;\n case 'polygon':\n emitPoly(w, el, place, true);\n break;\n case 'rect':\n emitRect(w, el, place);\n break;\n case 'circle':\n emitCircle(w, el, place);\n break;\n case 'ellipse':\n emitEllipse(w, el, place);\n break;\n case 'path':\n emitPath(w, el, place);\n break;\n case 'text':\n emitText(w, el, place);\n break;\n default:\n break;\n }\n }\n}\n\nfunction emitLine(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const x1 = numAttr(el, 'x1');\n const y1 = numAttr(el, 'y1');\n const x2 = numAttr(el, 'x2');\n const y2 = numAttr(el, 'y2');\n const a = worldToDxf(localToWorld([x1, y1], place));\n const b = worldToDxf(localToWorld([x2, y2], place));\n w.line(LAYER_ELEMENTS, a, b);\n}\n\nfunction emitPoly(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n closed: boolean,\n): void {\n const pts = parsePoints(el.getAttribute('points') ?? '');\n if (pts.length < 2) return;\n const out = pts.map((p) => worldToDxf(localToWorld(p, place)));\n w.lwpolyline(LAYER_ELEMENTS, out, closed);\n}\n\nfunction emitRect(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const x = numAttr(el, 'x');\n const y = numAttr(el, 'y');\n const ww = numAttr(el, 'width');\n const hh = numAttr(el, 'height');\n const corners: [number, number][] = [\n [x, y],\n [x + ww, y],\n [x + ww, y + hh],\n [x, y + hh],\n ];\n const out = corners.map((p) => worldToDxf(localToWorld(p, place)));\n w.lwpolyline(LAYER_ELEMENTS, out, true);\n}\n\nfunction emitCircle(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const cx = numAttr(el, 'cx');\n const cy = numAttr(el, 'cy');\n const r = numAttr(el, 'r');\n const center = worldToDxf(localToWorld([cx, cy], place));\n w.circle(LAYER_ELEMENTS, center, r);\n}\n\nfunction emitEllipse(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const cx = numAttr(el, 'cx');\n const cy = numAttr(el, 'cy');\n const rx = numAttr(el, 'rx');\n const ry = numAttr(el, 'ry');\n if (Math.abs(rx - ry) < 1e-6) {\n emitCircleRaw(w, cx, cy, rx, place);\n return;\n }\n sampleEllipse(w, cx, cy, rx, ry, place);\n}\n\nfunction emitCircleRaw(\n w: DxfWriter,\n cx: number,\n cy: number,\n r: number,\n place: ResolvedPlacement,\n): void {\n const center = worldToDxf(localToWorld([cx, cy], place));\n w.circle(LAYER_ELEMENTS, center, r);\n}\n\nfunction sampleEllipse(\n w: DxfWriter,\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n place: ResolvedPlacement,\n): void {\n const pts: [number, number][] = [];\n for (let i = 0; i < ELLIPSE_SAMPLES; i++) {\n const t = (i / ELLIPSE_SAMPLES) * Math.PI * 2;\n pts.push(\n worldToDxf(\n localToWorld([cx + rx * Math.cos(t), cy + ry * Math.sin(t)], place),\n ),\n );\n }\n w.lwpolyline(LAYER_ELEMENTS, pts, true);\n}\n\nfunction emitText(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const x = numAttr(el, 'x');\n const y = numAttr(el, 'y');\n const fs = parseFloat(el.getAttribute('font-size') ?? '') || TEXT_FONT_SIZE_DEFAULT;\n const txt = (el.textContent ?? '').trim();\n if (!txt) return;\n const p = worldToDxf(localToWorld([x, y], place));\n // place.rot is CCW in math frame (see transforms.ts); after flipping Y we\n // are in DXF's CCW frame, so the same numeric angle maps directly.\n w.text(LAYER_ELEMENTS, p, txt, fs, place.rot, place.mirror);\n}\n\n// -----------------------------------------------------------------------------\n// SVG path (M / A subset) → sampled LWPOLYLINE\n// -----------------------------------------------------------------------------\n\nfunction emitPath(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const d = el.getAttribute('d') ?? '';\n const cmds = tokenizePath(d);\n if (cmds.length === 0) return;\n\n let pen: [number, number] | null = null;\n let buffer: [number, number][] = [];\n const flush = () => {\n if (buffer.length >= 2) {\n w.lwpolyline(\n LAYER_ELEMENTS,\n buffer.map((p) => worldToDxf(localToWorld(p, place))),\n false,\n );\n }\n buffer = [];\n };\n\n for (const c of cmds) {\n if (c.cmd === 'M') {\n flush();\n pen = [c.args[0], c.args[1]];\n buffer.push(pen);\n } else if (c.cmd === 'A' && pen) {\n const [rx, ry, , large, sweep, x2, y2] = c.args;\n const arc = arcEndpointToCenter(\n pen,\n [x2, y2],\n rx,\n ry,\n large !== 0,\n sweep !== 0,\n );\n if (arc) {\n // Skip the start point (already pushed by M or previous segment) and\n // sample the rest.\n for (let i = 1; i <= ARC_SAMPLES; i++) {\n const t = arc.theta1 + (arc.delta * i) / ARC_SAMPLES;\n buffer.push([\n arc.cx + rx * Math.cos(t),\n arc.cy + ry * Math.sin(t),\n ]);\n }\n } else {\n buffer.push([x2, y2]); // degenerate: straight line fallback\n }\n pen = [x2, y2];\n }\n }\n flush();\n}\n\ninterface PathCmd {\n cmd: 'M' | 'A';\n args: number[];\n}\n\nfunction tokenizePath(d: string): PathCmd[] {\n const out: PathCmd[] = [];\n // Split by command letter while preserving the letter.\n const re = /([MmAa])([^MmAa]*)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(d)) !== null) {\n const cmd = m[1].toUpperCase() as 'M' | 'A';\n const nums = m[2]\n .trim()\n .split(/[\\s,]+/)\n .filter((s) => s.length > 0)\n .map(Number);\n out.push({ cmd, args: nums });\n }\n return out;\n}\n\ninterface ArcCenter {\n cx: number;\n cy: number;\n theta1: number;\n delta: number;\n}\n\n/**\n * SVG endpoint → center parametrization (W3C SVG 1.1 §F.6.5). Assumes\n * x-axis-rotation = 0 (verified across the element library).\n */\nfunction arcEndpointToCenter(\n p1: [number, number],\n p2: [number, number],\n rx: number,\n ry: number,\n largeArc: boolean,\n sweep: boolean,\n): ArcCenter | null {\n if (rx <= 0 || ry <= 0) return null;\n const [x1, y1] = p1;\n const [x2, y2] = p2;\n if (x1 === x2 && y1 === y2) return null;\n\n const x1p = (x1 - x2) / 2;\n const y1p = (y1 - y2) / 2;\n\n let RX = Math.abs(rx);\n let RY = Math.abs(ry);\n const r2x = RX * RX;\n const r2y = RY * RY;\n const lambda = (x1p * x1p) / r2x + (y1p * y1p) / r2y;\n if (lambda > 1) {\n const s = Math.sqrt(lambda);\n RX *= s;\n RY *= s;\n }\n\n const sign = largeArc === sweep ? -1 : 1;\n const num = RX * RX * RY * RY - RX * RX * y1p * y1p - RY * RY * x1p * x1p;\n const den = RX * RX * y1p * y1p + RY * RY * x1p * x1p;\n const coef = sign * Math.sqrt(Math.max(0, num / den));\n\n const cxp = (coef * (RX * y1p)) / RY;\n const cyp = (coef * -(RY * x1p)) / RX;\n\n const cx = cxp + (x1 + x2) / 2;\n const cy = cyp + (y1 + y2) / 2;\n\n const angle = (ux: number, uy: number, vx: number, vy: number): number => {\n const dot = ux * vx + uy * vy;\n const len = Math.hypot(ux, uy) * Math.hypot(vx, vy);\n let a = Math.acos(Math.max(-1, Math.min(1, dot / len)));\n if (ux * vy - uy * vx < 0) a = -a;\n return a;\n };\n\n const theta1 = angle(1, 0, (x1p - cxp) / RX, (y1p - cyp) / RY);\n let delta = angle(\n (x1p - cxp) / RX,\n (y1p - cyp) / RY,\n (-x1p - cxp) / RX,\n (-y1p - cyp) / RY,\n );\n if (!sweep && delta > 0) delta -= 2 * Math.PI;\n else if (sweep && delta < 0) delta += 2 * Math.PI;\n\n return { cx, cy, theta1, delta };\n}\n\n// -----------------------------------------------------------------------------\n// Geometry helpers\n// -----------------------------------------------------------------------------\n\nfunction localToWorld(\n local: [number, number],\n place: ResolvedPlacement,\n): [number, number] {\n return transformPoint(local, place);\n}\n\nfunction worldToDxf(p: [number, number]): [number, number] {\n return [p[0], -p[1]];\n}\n\nfunction numAttr(el: Element, name: string): number {\n const v = parseFloat(el.getAttribute(name) ?? '');\n return Number.isFinite(v) ? v : 0;\n}\n\nfunction parsePoints(raw: string): [number, number][] {\n const nums = raw.trim().split(/[\\s,]+/).map(Number).filter((n) => Number.isFinite(n));\n const out: [number, number][] = [];\n for (let i = 0; i + 1 < nums.length; i += 2) out.push([nums[i], nums[i + 1]]);\n return out;\n}\n\n// -----------------------------------------------------------------------------\n// Element labels — mirrors AnnotationLayer.tsx so DXF text matches the canvas\n// -----------------------------------------------------------------------------\n\nfunction labelLines(re: ResolvedElement, mode: LabelMode): string[] {\n const lines: string[] = [];\n const head = re.element.name?.trim() || re.element.id;\n if (head) lines.push(head);\n if (mode !== 'all' || !re.libraryDef?.params) return lines;\n const params = re.element.params ?? {};\n for (const p of re.libraryDef.params) {\n if (!p.showOnCanvas) continue;\n const v = params[p.name];\n if (v === undefined || v === null || v === '') continue;\n lines.push(`${v}${p.unit ?? ''}`);\n }\n return lines;\n}\n\nfunction fallbackAnchor(lib: LibraryEntry): LibraryLabelAnchor {\n const vb = parseViewBox(lib.viewBox);\n if (!vb) return { x: 0, y: 0, anchor: 'start' };\n return { x: vb.x + vb.w + 2, y: vb.y + 4, anchor: 'start' };\n}\n\nfunction parseViewBox(s: string): { x: number; y: number; w: number; h: number } | null {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n\nfunction anchorWorld(\n anchor: LibraryLabelAnchor,\n place: ResolvedPlacement,\n _lib: LibraryEntry,\n): [number, number] {\n let x = anchor.x;\n let y = anchor.y;\n if (place.mirror) x = -x;\n switch (place.rot) {\n case 90:\n [x, y] = [-y, x];\n break;\n case 180:\n [x, y] = [-x, -y];\n break;\n case 270:\n [x, y] = [y, -x];\n break;\n default:\n break;\n }\n return [x + place.at[0], y + place.at[1]];\n}\n\n// -----------------------------------------------------------------------------\n// DXF writer — minimal ASCII (AC1009) emitter\n// -----------------------------------------------------------------------------\n\nclass DxfWriter {\n private out: string[] = [];\n constructor(private readonly precision: number) {}\n\n toString(): string {\n return this.out.join('');\n }\n\n private g(code: number, value: string | number): void {\n this.out.push(`${code}\\n${this.fmt(value)}\\n`);\n }\n\n private fmt(v: string | number): string {\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) return '0';\n if (Number.isInteger(v)) return String(v);\n return v.toFixed(this.precision);\n }\n return v;\n }\n\n header(title?: string): void {\n this.g(0, 'SECTION');\n this.g(2, 'HEADER');\n this.g(9, '$ACADVER');\n this.g(1, 'AC1009');\n this.g(9, '$INSUNITS');\n this.g(70, 0);\n if (title) {\n this.g(9, '$PROJECTNAME');\n this.g(1, sanitizeText(title));\n }\n this.g(0, 'ENDSEC');\n }\n\n tables(layers: { name: string; color: number }[]): void {\n this.g(0, 'SECTION');\n this.g(2, 'TABLES');\n this.g(0, 'TABLE');\n this.g(2, 'LAYER');\n this.g(70, layers.length);\n for (const l of layers) {\n this.g(0, 'LAYER');\n this.g(2, l.name);\n this.g(70, 0);\n this.g(62, l.color);\n this.g(6, 'CONTINUOUS');\n }\n this.g(0, 'ENDTAB');\n this.g(0, 'ENDSEC');\n }\n\n beginEntities(): void {\n this.g(0, 'SECTION');\n this.g(2, 'ENTITIES');\n }\n\n endEntities(): void {\n this.g(0, 'ENDSEC');\n this.g(0, 'EOF');\n }\n\n line(layer: string, p1: [number, number], p2: [number, number]): void {\n this.g(0, 'LINE');\n this.g(8, layer);\n this.g(10, p1[0]);\n this.g(20, p1[1]);\n this.g(30, 0);\n this.g(11, p2[0]);\n this.g(21, p2[1]);\n this.g(31, 0);\n }\n\n lwpolyline(layer: string, points: [number, number][], closed: boolean): void {\n if (points.length < 2) return;\n this.g(0, 'LWPOLYLINE');\n this.g(8, layer);\n this.g(90, points.length);\n this.g(70, closed ? 1 : 0);\n for (const [x, y] of points) {\n this.g(10, x);\n this.g(20, y);\n }\n }\n\n circle(layer: string, center: [number, number], radius: number): void {\n this.g(0, 'CIRCLE');\n this.g(8, layer);\n this.g(10, center[0]);\n this.g(20, center[1]);\n this.g(30, 0);\n this.g(40, radius);\n }\n\n text(\n layer: string,\n p: [number, number],\n text: string,\n height: number,\n rotationDeg: number,\n mirrorX: boolean,\n ): void {\n this.g(0, 'TEXT');\n this.g(8, layer);\n this.g(10, p[0]);\n this.g(20, p[1]);\n this.g(30, 0);\n this.g(40, height);\n this.g(1, sanitizeText(text));\n if (rotationDeg !== 0) this.g(50, rotationDeg);\n if (mirrorX) this.g(71, 2);\n }\n}\n\nfunction sanitizeText(s: string): string {\n // DXF group code 1 fields are line-delimited; strip newlines so a multi-line\n // annotation can't smuggle its own DXF directives. Also clamp length to\n // 250 chars (DXF R12 line limit) to be safe.\n return s.replace(/[\\r\\n]+/g, ' ').slice(0, 250);\n}\n","/**\n * Export the current diagram as a standalone SVG (or rasterized PNG). Builds\n * the SVG offline from `InternalModel` rather than scraping the live canvas\n * — this keeps UI chrome (selection halos, terminal hit rects, marquee,\n * etc.) out of the file and crops tightly around the actual content.\n */\n\nimport { transformAttr } from '../canvas/transform-attr';\nimport { transformPoint, type InternalModel } from '../compiler';\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\nconst PADDING = 24;\n\ninterface Bbox {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport interface ExportOptions {\n /** Title used as the suggested filename / SVG <title>. */\n title?: string;\n /** Background fill (`'transparent'` skips the rect). Default white. */\n background?: string;\n}\n\nexport function buildExportSvg(\n model: InternalModel,\n opts: ExportOptions = {},\n): string {\n const bbox = computeContentBbox(model);\n const x = Math.floor(bbox.minX - PADDING);\n const y = Math.floor(bbox.minY - PADDING);\n const w = Math.ceil(bbox.maxX + PADDING) - x;\n const h = Math.ceil(bbox.maxY + PADDING) - y;\n const bg = opts.background ?? '#FFFFFF';\n\n const out: string[] = [];\n out.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n out.push(\n `<svg xmlns=\"${SVG_NS}\" viewBox=\"${x} ${y} ${w} ${h}\" width=\"${w}\" height=\"${h}\">`,\n );\n if (opts.title) out.push(` <title>${escapeXml(opts.title)}</title>`);\n if (bg !== 'transparent') {\n out.push(\n ` <rect x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\" fill=\"${bg}\"/>`,\n );\n }\n\n // Wires first (rendered behind elements).\n out.push(' <g fill=\"none\" stroke=\"black\" stroke-width=\"1\">');\n for (const r of model.wireRenders.values()) {\n if (r.path.length < 2) continue;\n const pts = r.path.map(([px, py]) => `${px},${py}`).join(' ');\n out.push(` <polyline points=\"${pts}\"/>`);\n }\n out.push(' </g>');\n\n // Buses.\n for (const { bus, geometry } of model.buses.values()) {\n const { axis, at, span } = geometry;\n const half = span / 2;\n const x1 = axis === 'x' ? at[0] - half : at[0];\n const y1 = axis === 'x' ? at[1] : at[1] - half;\n const x2 = axis === 'x' ? at[0] + half : at[0];\n const y2 = axis === 'x' ? at[1] : at[1] + half;\n out.push(\n ` <line id=\"${escapeXml(bus.id)}\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"black\" stroke-width=\"3\" stroke-linecap=\"round\" fill=\"none\"/>`,\n );\n }\n\n // Devices.\n for (const re of model.elements.values()) {\n if (!re.libraryDef) continue;\n const place = model.layout.get(re.element.id);\n if (!place) continue;\n out.push(\n ` <g id=\"${escapeXml(re.element.id)}\" transform=\"${transformAttr(place)}\">`,\n );\n out.push(` ${re.libraryDef.svg}`);\n out.push(' </g>');\n }\n\n out.push('</svg>');\n return out.join('\\n');\n}\n\nfunction computeContentBbox(model: InternalModel): Bbox {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n const update = (x: number, y: number) => {\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n };\n\n for (const t of model.terminals.values()) update(t.world[0], t.world[1]);\n for (const re of model.elements.values()) {\n const place = model.layout.get(re.element.id);\n const lib = re.libraryDef;\n if (!place || !lib) continue;\n const vb = parseViewBox(lib.viewBox);\n if (!vb) {\n update(place.at[0], place.at[1]);\n continue;\n }\n const corners: Array<[number, number]> = [\n [vb.x, vb.y],\n [vb.x + vb.w, vb.y],\n [vb.x, vb.y + vb.h],\n [vb.x + vb.w, vb.y + vb.h],\n ];\n for (const c of corners) {\n const [wx, wy] = transformPoint(c, place);\n update(wx, wy);\n }\n }\n for (const { geometry } of model.buses.values()) {\n const { axis, at, span } = geometry;\n const half = span / 2;\n if (axis === 'x') {\n update(at[0] - half, at[1]);\n update(at[0] + half, at[1]);\n } else {\n update(at[0], at[1] - half);\n update(at[0], at[1] + half);\n }\n }\n for (const r of model.wireRenders.values()) {\n for (const [x, y] of r.path) update(x, y);\n }\n if (minX === Infinity) {\n minX = 0;\n minY = 0;\n maxX = 0;\n maxY = 0;\n }\n return { minX, minY, maxX, maxY };\n}\n\nfunction parseViewBox(\n s: string,\n): { x: number; y: number; w: number; h: number } | null {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n\nfunction escapeXml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nexport async function downloadSvg(\n model: InternalModel,\n filename = 'diagram.svg',\n opts?: ExportOptions,\n): Promise<void> {\n const xml = buildExportSvg(model, opts);\n triggerDownload(\n new Blob([xml], { type: 'image/svg+xml;charset=utf-8' }),\n filename,\n );\n}\n\nexport async function downloadPng(\n model: InternalModel,\n filename = 'diagram.png',\n opts?: ExportOptions & { scale?: number },\n): Promise<void> {\n const xml = buildExportSvg(model, opts);\n const scale = opts?.scale ?? 2;\n\n const url = URL.createObjectURL(\n new Blob([xml], { type: 'image/svg+xml;charset=utf-8' }),\n );\n try {\n const img = await loadImage(url);\n const canvas = document.createElement('canvas');\n canvas.width = Math.round(img.naturalWidth * scale);\n canvas.height = Math.round(img.naturalHeight * scale);\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('canvas 2d context unavailable');\n if (opts?.background && opts.background !== 'transparent') {\n ctx.fillStyle = opts.background;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n const blob: Blob = await new Promise((resolve, reject) => {\n canvas.toBlob((b) => (b ? resolve(b) : reject(new Error('toBlob failed'))), 'image/png');\n });\n triggerDownload(blob, filename);\n } finally {\n URL.revokeObjectURL(url);\n }\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error('failed to load SVG into image'));\n img.src = src;\n });\n}\n\nfunction triggerDownload(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n","/**\n * Export menu — render the current diagram to SVG or PNG and trigger a\n * download. Reads the InternalModel from the store so the file matches what\n * the canvas shows minus UI chrome (selection halos, terminal hit rects,\n * etc.). Exported alongside `FileMenu` for embedding apps.\n */\n\nimport { Download, FileBox, FileImage, FileType } from 'lucide-react';\nimport { useEffect, useRef, useState } from 'react';\nimport { Button } from './ui/button';\nimport { useT } from '../i18n';\nimport { downloadDxf } from '../lib/export-dxf';\nimport { downloadPng, downloadSvg } from '../lib/export-image';\nimport { useEditorStore } from '../store';\n\nexport function ExportMenu() {\n const t = useT();\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n window.addEventListener('mousedown', onClick);\n window.addEventListener('keydown', onKey);\n return () => {\n window.removeEventListener('mousedown', onClick);\n window.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const exportAs = (kind: 'svg' | 'png' | 'dxf') => () => {\n setOpen(false);\n const { internal, diagram, fileSession } = useEditorStore.getState();\n const baseName =\n fileSession?.name?.replace(/\\.json$/i, '') ?? diagram.meta?.title ?? 'diagram';\n const opts = { title: diagram.meta?.title };\n if (kind === 'svg') downloadSvg(internal, `${baseName}.svg`, opts);\n else if (kind === 'png')\n downloadPng(internal, `${baseName}.png`, { ...opts, scale: 2 }).catch((err) => {\n console.error(err);\n alert(t('topbar.export.pngFailed', { err: (err as Error).message }));\n });\n else\n downloadDxf(internal, `${baseName}.dxf`, {\n ...opts,\n labelMode: diagram.meta?.labelMode,\n annotations: diagram.annotations,\n }).catch((err) => {\n console.error(err);\n alert(t('topbar.export.dxfFailed', { err: (err as Error).message }));\n });\n };\n\n return (\n <div ref={ref} className=\"relative\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1.5\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n >\n <Download />\n {t('topbar.export.label')}\n </Button>\n {open && (\n <div\n role=\"menu\"\n className=\"ole-glass absolute left-0 top-full mt-1.5 min-w-40 rounded-md border border-border p-1 shadow-md\"\n >\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={exportAs('svg')}\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4\"\n >\n <FileType />\n <span className=\"flex-1\">SVG</span>\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={exportAs('png')}\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4\"\n >\n <FileImage />\n <span className=\"flex-1\">PNG (2×)</span>\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={exportAs('dxf')}\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4\"\n >\n <FileBox />\n <span className=\"flex-1\">DXF</span>\n </button>\n </div>\n )}\n </div>\n );\n}\n"],"names":["toKebabCase","string","mergeClasses","classes","className","index","array","defaultAttributes","Icon","forwardRef","color","size","strokeWidth","absoluteStrokeWidth","children","iconNode","rest","ref","createElement","tag","attrs","createLucideIcon","iconName","Component","props","Cable","ChevronDown","Clipboard","Copy","Download","Ellipsis","FileBox","FileImage","FilePlus","FileType","FlipHorizontal","FolderOpen","Grid2x2","Hand","LayoutGrid","ListTree","Maximize2","Minus","MousePointer2","PanelBottomClose","Plus","Redo2","RotateCw","Save","Scissors","Search","Shapes","SquareDashed","Trash2","Type","Undo2","WandSparkles","X","r","f","n","o","clsx","CLASS_PART_SEPARATOR","createClassGroupUtils","config","classMap","createClassMap","conflictingClassGroups","conflictingClassGroupModifiers","classParts","getGroupRecursive","getGroupIdForArbitraryProperty","classGroupId","hasPostfixModifier","conflicts","classPartObject","currentClassPart","nextClassPartObject","classGroupFromNextClassPart","classRest","_a","validator","arbitraryPropertyRegex","arbitraryPropertyClassName","property","theme","prefix","getPrefixedClassGroupEntries","classGroup","processClassesRecursively","classDefinition","classPartObjectToEdit","getPart","isThemeGetter","key","path","currentClassPartObject","pathPart","func","classGroupEntries","prefixedClassGroup","value","createLruCache","maxCacheSize","cacheSize","cache","previousCache","update","IMPORTANT_MODIFIER","createParseClassName","separator","experimentalParseClassName","isSeparatorSingleCharacter","firstSeparatorCharacter","separatorLength","parseClassName","modifiers","bracketDepth","modifierStart","postfixModifierPosition","currentCharacter","baseClassNameWithImportantModifier","hasImportantModifier","baseClassName","maybePostfixModifierPosition","sortModifiers","sortedModifiers","unsortedModifiers","modifier","createConfigUtils","SPLIT_CLASSES_REGEX","mergeClassList","classList","configUtils","getClassGroupId","getConflictingClassGroupIds","classGroupsInConflict","classNames","result","originalClassName","variantModifier","modifierId","classId","conflictGroups","i","group","twJoin","argument","resolvedValue","toValue","mix","k","createTailwindMerge","createConfigFirst","createConfigRest","cacheGet","cacheSet","functionToCall","initTailwindMerge","previousConfig","createConfigCurrent","tailwindMerge","cachedResult","fromTheme","themeGetter","arbitraryValueRegex","fractionRegex","stringLengths","tshirtUnitRegex","lengthUnitRegex","colorFunctionRegex","shadowRegex","imageRegex","isLength","isNumber","isArbitraryLength","getIsArbitraryValue","isLengthOnly","isArbitraryNumber","isInteger","isPercent","isArbitraryValue","isTshirtSize","sizeLabels","isArbitrarySize","isNever","isArbitraryPosition","imageLabels","isArbitraryImage","isImage","isArbitraryShadow","isShadow","isAny","label","testValue","getDefaultConfig","colors","spacing","blur","brightness","borderColor","borderRadius","borderSpacing","borderWidth","contrast","grayscale","hueRotate","invert","gap","gradientColorStops","gradientColorStopPositions","inset","margin","opacity","padding","saturate","scale","sepia","skew","space","translate","getOverscroll","getOverflow","getSpacingWithAutoAndArbitrary","getSpacingWithArbitrary","getLengthWithEmptyAndArbitrary","getNumberWithAutoAndArbitrary","getPositions","getLineStyles","getBlendModes","getAlign","getZeroAndEmpty","getBreaks","getNumberAndArbitrary","twMerge","cn","inputs","Ctx","createContext","useContextMenu","api","useContext","VIEWPORT_PAD","ContextMenuHost","state","setState","useState","clamped","setClamped","useRef","close","useCallback","s","open","x","y","items","useMemo","useLayoutEffect","left","top","useEffect","onPointerDown","e","onKey","onWheel","onBlur","jsxs","jsx","entry","createStoreImpl","createState","listeners","partial","replace","nextState","previousState","listener","getState","initialState","createStore","identity","arg","useStore","selector","slice","React","createImpl","useBoundStore","create","messages","STORAGE_KEY","readInitial","raw","persist","loc","useLocale","set","get","locale","next","format","tmpl","params","_","lookup","t","useT","createJSONStorage","getStorage","options","storage","name","parse","str2","str","newValue","toThenable","fn","input","onFulfilled","_onRejected","_onFulfilled","onRejected","persistImpl","baseOptions","persistedState","currentState","hasHydrated","hydrationVersion","hydrationListeners","finishHydrationListeners","args","setItem","savedSetState","configResult","stateFromStorage","hydrate","_b","currentVersion","cb","_a2","postRehydrationCallback","deserializedStorageValue","migration","migrationResult","migrated","migratedState","newOptions","emptyInternalModel","resolvePlacement","p","busAxisFromRot","rot","transformPoint","local","ROT_NEXT","MIRROR_X","transformOrientation","cur","steps","orientationVec","UnionFind","__publicField","gp","a","b","ra","rb","da","db","out","root","arr","ORIENT_CYCLE","OPPOSITE_ORIENT","rotationToAlignOrient","localO","worldO","li","BUS_X","BUS_Y0","MIN_BUS_GAP_Y","DEFAULT_BUS_SPAN","CHAIN_GAP","BUS_TAP_OFFSET","MIN_TAP_SPACING","GRID","FALLBACK_GRID_X0","FALLBACK_GRID_Y0","FALLBACK_GRID_DX","FALLBACK_GRID_DY","FALLBACK_GRID_COLS","SOURCE_CATEGORIES","autoLayout","elements","busList","wires","library","userLayout","userBusLayout","layout","busLayout","elementById","el","busById","libOf","id","busIds","isBus","end","uf","w","lib","bus","nodeGroups","members","pinToGroups","m","effectiveTaps","busMembers","busMember","others","tapsByElement","dot","elId","pin","busId","linkers","linkerIds","attachments","orientation","refAdj","addRefEdge","refs","j","myRefs","busesPerPin","startRef","startPin","forbidden","visited","queue","neighbors","nb","distinctBuses","buses","reachesSourceBypassing","startBusId","linkerId","linkerLib","blocked","elemId","cat","link","busesInLink","reachable","bid","busPerPin","nbDot","nbElemId","nbEl","nbLib","busLinks","ids","_c","isSourceKind","kind","rootBuses","otherId","otherEl","busLevel","bfsQ","lvl","links","childLevel","maxLvl","levelToBuses","sortedLevels","chainExtentToBus","linker","pinName","targetRef","parent","enqueue","other","addDist","dist","prev","head","d","headId","thisTerm","otherTerm","otherRef","g","isBusEdge","gapBetween","idA","idB","pinAName","pinBName","pinA","pinB","pinSpan","upperChain","lowerChain","linkerUpperRep","sortedAttachments","upperBusId","lowerBusId","upperPin","repElId","BUS_MIN_SPAN","busSpan","isLinkerLowerSide","l","otherBusAtt","myLvl","slotWidthFor","libWidth","rep","childSpan","computeSpan","visiting","tapRefs","aboveW","belowW","localTerm","slotW","span","linkerSlotX","tapPreferredX","tapEl","tapPin","tapLib","tapRef","startRefs","geom","distributeBusTaps","remaining","aboveSide","belowSide","sideTotalWidth","requiredSpan","finalGeom","distribute","offsetSign","prefByEl","px","ax","bx","aw","widths","totalW","usableSpan","slotGap","cursor","tapWorldY","tapWorldX","snap","placeLinker","placedAttachments","sorted","upperGeom","lowerPin","upperLocal","lowerLocal","upperLevel","upperSideAttachments","upperHeadXs","maxUpperExtent","att","headPlace","xCenter","upperPinWorldY","at","linkerPlace","upperPinWorld","upperWorldOrient","walkChainAlongAxis","startWorld","startExit","axisX","prevRef","prevWorld","prevExit","groups","nextRef","inTerm","exitVec","target","desiredOrient","rotatedInPin","outTerm","outRef","placement","placeHorizontalLinker","placed","heads","right","leftLocal","rightLocal","linkerY","SIBLING_X_GAP","prevLevelY","busIdsAtLevel","levelY","prevBusIds","maxGap","child","_d","nextSiblingX","busX","headXs","_e","parentPin","_f","ownSpan","isEndPlaced","progressed","safety","node","placedPins","unplacedByEl","unplacedUnique","votes","u","tref","anchor","best","v","anchorId","anchorPin","anchorLib","anchorPlace","anchorTerm","anchorWorld","anchorOrient","exit","perp","sum","slotCenter","rotatedPin","targetWorld","placedCount","col","row","routeWire","wire","model","aBus","bBus","otherWorld","endWorld","axis","half","clamp","orthogonalPath","bw","term","lo","hi","modules","__vite_glob_0_0","__vite_glob_0_1","__vite_glob_0_2","__vite_glob_0_3","__vite_glob_0_4","__vite_glob_0_5","__vite_glob_0_6","__vite_glob_0_7","__vite_glob_0_8","__vite_glob_0_9","__vite_glob_0_10","__vite_glob_0_11","__vite_glob_0_12","__vite_glob_0_13","__vite_glob_0_14","__vite_glob_0_15","__vite_glob_0_16","__vite_glob_0_17","__vite_glob_0_18","__vite_glob_0_19","__vite_glob_0_20","__vite_glob_0_21","__vite_glob_0_22","__vite_glob_0_23","__vite_glob_0_24","__vite_glob_0_25","__vite_glob_0_26","__vite_glob_0_27","__vite_glob_0_28","__vite_glob_0_29","__vite_glob_0_30","__vite_glob_0_31","__vite_glob_0_32","__vite_glob_0_33","__vite_glob_0_34","__vite_glob_0_35","__vite_glob_0_36","__vite_glob_0_37","__vite_glob_0_38","__vite_glob_0_39","__vite_glob_0_40","__vite_glob_0_41","__vite_glob_0_42","__vite_glob_0_43","__vite_glob_0_44","__vite_glob_0_45","__vite_glob_0_46","libraryEntries","libraryById","CATEGORY_ORDER","libraryByCategory","LIBRARY","getLibraryEntry","deterministicNodeId","text","h","compile","diagram","idx","libDef","validEnd","pointer","re","avail","validWires","layoutResult","place","lt","world","PREFIX","BUS_PREFIX","usedIds","newElementId","used","newBusId","newAnnotationId","wireIdFromEnds","EMPTY_DIAGRAM","HISTORY_LIMIT","PASTE_OFFSET","defaultTool","useEditorStore","fileSession","mutator","past","trimmed","future","tool","opts","placeKind","pt","dedupe","sel","nodeId","selection","internal","placements","explicit","resolved","compactPlacement","busLayouts","compactBusLayout","endOwner","clipboard","clipboardPasteIndex","step","dx","dy","idMap","working","newId","remapEnd","remapped","newElements","cloned","newBuses","newLayout","oldId","newWires","ends","mergeWires","hasDeviceLayout","hasBusLayout","_layout","_bl","bRest","drop","changed","additions","busesNeedLayout","busesPatch","deltas","busPatches","delta","base","selectedWire","selectedNode","memberSet","affectedElementIds","deltaDegrees","extra","newElement","existing","patch","nextPlacement","ann","list","seen","rp","current","setViewportApi","getViewportApi","GRID_SIZE","isSnapEnabled","PROXIMITY_PX","CLICK_SLOP_SQ","dropElement","store","nearestBus","cursorPin","pickPlaceCursorTerminal","placedAt","busAt","pickTapTerminal","tapLocal","dropX","dropY","newEnd","minX","maxX","minY","maxY","busAxis","resolvePlaceSource","cursorWorld","OPPOSITE","pickConnectTerminal","source","placeAt","wantOrient","opposites","pool","bestDist","termWorldDist","dropElementFromTerminal","sourceRef","cursorAt","treatAsClick","cursorPlaceAt","chosen","newPinRef","tieEnd","LINE_HEIGHT","AnnotationLayer","mode","editingElement","fallbackAnchor","textAnchor","NameEditor","lines","labelLines","line","EDITOR_W","EDITOR_FS","elementId","currentName","range","commit","onKeyDown","vb","parseViewBox","parts","_lib","DEFAULT_FONT_SIZE","FreeAnnotationLayer","annotations","selected","editing","EditingAnnotation","IdleAnnotation","isSelected","fs","widthGuess","heightGuess","MIN_SPAN","BusHandles","Handle","side","viewport","dragRef","onPointerMove","drag","dRaw","onPointerUp","STROKE_WIDTH","HIT_WIDTH","BusLayer","nodes","terminalToNode","selSet","nodeRelatedBuses","geometry","x1","y1","x2","y2","isNodeRelated","hitHalf","hx","hy","hw","hh","BusbarPreview","start","horizontal","endX","endY","transformAttr","HitRect","bb","ElementLayer","nodeRelated","publishMarquee","rect","getMarquee","subscribeMarquee","MarqueeOverlay","setRect","PlaceGhost","fromRef","connect","ghostX","ghostY","Fragment","SelectionOverlay","TerminalLayer","terminals","wireFrom","selectionSet","connected","isOrigin","onSelected","WireLayer","wireRenders","wireToNode","points","isWireSelected","isNodeSelected","publishWireTarget","getWireTarget","subscribeWireTarget","WirePreview","setTarget","fromWorld","ancestor","attr","hitElement","hitBus","hitTerminal","direct","hitNode","hitWire","hitAnnotation","dispatchSyntheticPointerCancel","host","pointerId","isEditing","exitDrawingState","ed","useKeyboardShortcuts","mod","publishHoverElement","getHoverElement","subscribeHoverElement","C_HOST","C_TERM","C_NODE","useHoverHighlight","hostRef","lastElement","lastNode","markedTerminals","markedNodeMembers","clearAndMark","cls","updateElementHover","cssEscape","terms","updateNodeHover","terminal","onPointerLeave","resolveWireTarget","MARQUEE_THRESHOLD","marquee","wireDrag","annDrag","SelectTool","ctx","annId","termRef","wireId","targets","originals","busOriginals","tid","under","orig","rectFromPoints","from","hit","elementsInRect","baseSet","hits","corners","transformLocalCorner","TAP_THRESHOLD_PX","pan","PanTool","vp","startId","elementDrag","ddx","ddy","handlePanTap","BREAKPOINTS","RANK","atLeast","min","tierForWidth","TierContext","useEditorTier","useObservedWidth","width","setWidth","apply","ro","isPhoneUx","exitToPanOnPhone","disarmPlaceOnPhone","WireTool","sf","disarmOnUp","scheduleDisarm","PlaceTool","MIN_LEN","BusbarTool","TextTool","TOOLS","useTools","activeTool","onDown","onMove","onUp","onCancel","onLeave","onDbl","publishScale","getScale","subscribeScale","MIN_SCALE","MAX_SCALE","ZOOM_FACTOR_WHEEL","ZOOM_FACTOR_PINCH","useViewport","groupRef","initial","snapshot","panning","panPointerId","panStartX","panStartY","panStartTx","panStartTy","spaceDown","touches","pinch","touchHijack","recomputePinchBaseline","pts","onTouchPointerDownCap","onTouchPointerMoveCap","midX","midY","ratio","onTouchPointerUpCap","cx","cy","isPinch","isMiddle","isSpaceLeft","onKeyUp","clientX","clientY","IS_MAC","MOD","SHIFT","GRID_STEPS","MIN_SCREEN_STEP","pickGridStep","CanvasSvg","gridPatternRef","sync","screenStep","contextMenu","openContextMenuAt","hasSelection","hasNodeSelection","hasClipboard","hasAnyElement","BoxSelect","st","LONG_PRESS_MS","LONG_PRESS_MOVE_PX","timer","data","cancel","onEnd","onDragOver","onDrop","onContextMenu","FIT_PADDING_PX","READY_RETRY_FRAMES","getCanvasRoot","fitToContent","ay","by","contentW","contentH","targetScale","fitToContentSoon","frames","tick","GAP_PX","SHOW_DELAY_MS","isCoarsePointer","ElementHoverLabel","hoverId","setHoverId","shown","setShown","setAnchor","labelRef","showTimer","coarse","elementName","raf","lastTop","lastLeft","tip","display","subtitle","showId","createPortal","EditorTierProvider","tier","setRef","composeRefs","hasCleanup","cleanups","cleanup","REACT_LAZY_TYPE","use","isPromiseLike","isLazyComponent","element","createSlot","ownerName","SlotClone","createSlotClone","Slot2","forwardedRef","slotProps","childrenArray","slottable","isSlottable","newChildren","Slot","childrenRef","getElementRef","props2","mergeProps","SLOTTABLE_IDENTIFIER","childProps","overrideProps","propName","slotPropValue","childPropValue","getter","mayWarn","falsyToString","cva","_config_compoundVariants","variants","defaultVariants","getVariantClassNames","variant","variantProp","defaultVariantProp","variantKey","propsWithoutUndefined","acc","param","getCompoundVariantClassNames","cvClass","cvClassName","compoundVariantOptions","buttonVariants","Button","asChild","Comp","Tooltip","content","disabled","delayMs","triggerRef","tooltipRef","setOpen","useId","scheduleShow","cancelShow","onScroll","wrappedTrigger","cloneElement","TOP_FLIP_THRESHOLD_PX","ContextualToolbar","rotate","mirror","del","delNode","delWire","isElementMode","isWireMode","isNodeMode","lastTransform","bottom","any","accept","ty","translateY","transform","hideTransform","UpwardPopover","onOpenChange","trigger","onClick","obj","usePanels","outlineOpen","ZOOM_STEPS","GRID_STORAGE_KEY","readGrid","writeGrid","zoomTo","zoomIn","z","zoomOut","LABEL_CYCLE","cycleLabelMode","meta","useGridState","grid","setGrid","ZoomOutBtn","ZoomInBtn","ZoomDisplayBtn","setScale","FitBtn","GridBtn","LabelBtn","labelMode","ViewMenuButton","stacked","menuOpen","setMenuOpen","tipContent","triggerBtn","MoreHorizontal","ViewToolbar","ViewToolbarExpanded","hidePercentPill","ToolHint","active","placeFrom","busbarStart","cancelHint","cancelText","FloatingToolbar","setTool","undo","redo","forceIconOnly","showHint","unifiedBar","visibleTools","def","isToolActive","OutlineToggleButton","isActive","ToolbarButton","OverflowMenuButton","LayoutMenuButton","toggle","hotkey","iconOnly","description","useLayoutActions","run","action","Wand2","PopoverItem","icon","LeftPanel","OutlinePanel","CollapsedTab","compact","onClose","sheet","libraryOpen","dense","height","CountChip","OutlineRow","setSelection","toggleInSelection","zh","en","tables","useLibT","fallback","PALETTE_COLLAPSE_STORAGE_KEY","PALETTE_HIDDEN_IDS","PALETTE_BY_CATEGORY","entries","visible","CATEGORY_IDS","known","extras","c","readPaletteCollapsed","writePaletteCollapsed","LibraryPopover","TOP_INSET","maxHeight","wrapperStyle","LibraryBody","libT","query","setQuery","collapsed","setCollapsed","filteredByCat","q","desc","isSearching","noMatch","handleToggle","catId","isOpen","SearchBox","total","ElementRow","onChange","armed","recent","onDragStart","ghost","dismissed","useOnboarding","OnboardingCard","dismiss","Step","title","body","PropertyPanel","WirePanel","NodePanel","BusInspector","TextRow","TextAreaRow","field","StateField","ParamsSection","schema","schemaKeys","SchemaParamField","ParamField","onCommit","Field","ToggleButton","NumberRow","fieldKey","onName","updateBusEntry","BusParams","setSelectedNode","elemById","describeEnd","byElement","eId","elById","pins","placeholder","unit","setLocal","RightPanel","compactWidth","count","useFocusGuards","onMouseDown","btn","onCanvasPointerDown","EditorShell","rootRef","readStored","systemPrefersDark","getInitialTheme","applyTheme","OneLineEditor","ACCEPT","supportsFsa","isAbort","parseDiagram","serialize","openDiagram","handle","file","resolve","reject","saveDiagram","session","writable","url","FileMenu","fileLabel","onNew","onOpen","onSave","onSaveAs","useFileActions","handler","MenuItem","hint","loadDiagramFromFile","setFileSession","setDiagram","LAYER_WIRES","LAYER_ELEMENTS","LAYER_LABELS","LAYER_ANNOTATIONS","ARC_SAMPLES","ELLIPSE_SAMPLES","LABEL_FONT_SIZE","ANNOTATION_FONT_SIZE","ANNOTATION_LINE_HEIGHT","LABEL_LINE_HEIGHT","TEXT_FONT_SIZE_DEFAULT","buildExportDxf","DxfWriter","worldToDxf","emitLibrarySvg","downloadDxf","filename","dxf","svg","wrapped","emitLine","emitPoly","emitRect","emitCircle","emitEllipse","emitPath","emitText","numAttr","localToWorld","closed","parsePoints","ww","center","rx","ry","emitCircleRaw","sampleEllipse","txt","cmds","tokenizePath","pen","buffer","flush","large","sweep","arc","arcEndpointToCenter","cmd","nums","p1","p2","largeArc","x1p","y1p","RX","RY","r2x","r2y","lambda","sign","num","den","coef","cxp","cyp","angle","ux","uy","vx","vy","len","theta1","precision","code","sanitizeText","layers","layer","radius","rotationDeg","mirrorX","SVG_NS","PADDING","buildExportSvg","bbox","computeContentBbox","bg","escapeXml","py","wx","wy","downloadSvg","xml","triggerDownload","downloadPng","img","loadImage","canvas","blob","src","ExportMenu","exportAs","baseName","err"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,41,42,45,96,97,98]}
1
+ {"version":3,"file":"sldeditor.cjs","sources":["../node_modules/lucide-react/dist/esm/shared/src/utils.js","../node_modules/lucide-react/dist/esm/defaultAttributes.js","../node_modules/lucide-react/dist/esm/Icon.js","../node_modules/lucide-react/dist/esm/createLucideIcon.js","../node_modules/lucide-react/dist/esm/icons/cable.js","../node_modules/lucide-react/dist/esm/icons/chevron-down.js","../node_modules/lucide-react/dist/esm/icons/clipboard.js","../node_modules/lucide-react/dist/esm/icons/copy.js","../node_modules/lucide-react/dist/esm/icons/download.js","../node_modules/lucide-react/dist/esm/icons/ellipsis.js","../node_modules/lucide-react/dist/esm/icons/file-box.js","../node_modules/lucide-react/dist/esm/icons/file-image.js","../node_modules/lucide-react/dist/esm/icons/file-plus.js","../node_modules/lucide-react/dist/esm/icons/file-type.js","../node_modules/lucide-react/dist/esm/icons/flip-horizontal.js","../node_modules/lucide-react/dist/esm/icons/folder-open.js","../node_modules/lucide-react/dist/esm/icons/grid-2x2.js","../node_modules/lucide-react/dist/esm/icons/hand.js","../node_modules/lucide-react/dist/esm/icons/layout-grid.js","../node_modules/lucide-react/dist/esm/icons/list-tree.js","../node_modules/lucide-react/dist/esm/icons/maximize-2.js","../node_modules/lucide-react/dist/esm/icons/minus.js","../node_modules/lucide-react/dist/esm/icons/mouse-pointer-2.js","../node_modules/lucide-react/dist/esm/icons/panel-bottom-close.js","../node_modules/lucide-react/dist/esm/icons/plus.js","../node_modules/lucide-react/dist/esm/icons/redo-2.js","../node_modules/lucide-react/dist/esm/icons/rotate-cw.js","../node_modules/lucide-react/dist/esm/icons/save.js","../node_modules/lucide-react/dist/esm/icons/scissors.js","../node_modules/lucide-react/dist/esm/icons/search.js","../node_modules/lucide-react/dist/esm/icons/shapes.js","../node_modules/lucide-react/dist/esm/icons/spline.js","../node_modules/lucide-react/dist/esm/icons/square-dashed.js","../node_modules/lucide-react/dist/esm/icons/trash-2.js","../node_modules/lucide-react/dist/esm/icons/type.js","../node_modules/lucide-react/dist/esm/icons/undo-2.js","../node_modules/lucide-react/dist/esm/icons/wand-sparkles.js","../node_modules/lucide-react/dist/esm/icons/x.js","../node_modules/clsx/dist/clsx.mjs","../node_modules/tailwind-merge/dist/bundle-mjs.mjs","../src/lib/utils.ts","../src/components/ContextMenu.tsx","../node_modules/zustand/esm/vanilla.mjs","../node_modules/zustand/esm/react.mjs","../src/i18n/messages.ts","../src/i18n/index.ts","../node_modules/zustand/esm/middleware.mjs","../src/model/wire-path.ts","../src/compiler/internal-model.ts","../src/compiler/transforms.ts","../src/compiler/union-find.ts","../src/compiler/auto-layout.ts","../src/compiler/auto-route.ts","../src/element-library/index.ts","../src/compiler/library-index.ts","../src/compiler/compile.ts","../src/store/id-allocator.ts","../src/store/store.ts","../src/canvas/viewport-bus.ts","../src/canvas/grid.ts","../src/canvas/drop-on-bus.ts","../src/lib/element-labels.ts","../src/canvas/AnnotationLayer.tsx","../src/canvas/FreeAnnotationLayer.tsx","../src/canvas/BusHandles.tsx","../src/canvas/WireHandles.tsx","../src/canvas/BusLayer.tsx","../src/canvas/BusbarPreview.tsx","../src/canvas/transform-attr.ts","../src/canvas/ElementLayer.tsx","../src/canvas/marquee-bus.ts","../src/canvas/MarqueeOverlay.tsx","../src/canvas/PlaceGhost.tsx","../src/canvas/SelectionOverlay.tsx","../src/canvas/TerminalLayer.tsx","../src/canvas/WireLayer.tsx","../src/canvas/wire-target-bus.ts","../src/canvas/WirePreview.tsx","../src/canvas/hit-test.ts","../src/canvas/synthetic-pointer-cancel.ts","../src/canvas/useKeyboardShortcuts.ts","../src/canvas/hover-bus.ts","../src/canvas/useHoverHighlight.ts","../src/canvas/resolve-wire-target.ts","../src/canvas/tools/SelectTool.ts","../src/canvas/tools/PanTool.ts","../src/hooks/editor-tier.ts","../src/canvas/touch.ts","../src/canvas/tools/WireTool.ts","../src/canvas/tools/PlaceTool.ts","../src/canvas/tools/BusbarTool.ts","../src/canvas/tools/TextTool.ts","../src/canvas/tools/index.ts","../src/canvas/useTools.ts","../src/canvas/zoom-bus.ts","../src/canvas/useViewport.ts","../src/canvas/CanvasSvg.tsx","../src/canvas/fit-to-content.ts","../src/canvas/ElementHoverLabel.tsx","../src/hooks/use-editor-tier.tsx","../node_modules/@radix-ui/react-compose-refs/dist/index.mjs","../node_modules/@radix-ui/react-slot/dist/index.mjs","../node_modules/class-variance-authority/dist/index.mjs","../src/components/ui/button.tsx","../src/components/ui/tooltip.tsx","../src/components/ContextualToolbar.tsx","../src/components/ui/upward-popover.tsx","../src/hooks/use-panels.ts","../src/components/ViewToolbar.tsx","../src/components/FloatingToolbar.tsx","../src/components/LeftPanel.tsx","../src/i18n/library.ts","../src/components/LibraryPopover.tsx","../src/hooks/use-onboarding.ts","../src/components/OnboardingCard.tsx","../src/components/PropertyPanel.tsx","../src/components/RightPanel.tsx","../src/components/EditorShell.tsx","../src/hooks/use-theme.ts","../src/OneLineEditor.tsx","../src/lib/file-io.ts","../src/components/FileMenu.tsx","../src/lib/export-dxf.ts","../src/lib/export-image.ts","../src/components/ExportMenu.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\n\nexport { mergeClasses, toKebabCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n ({\n color = \"currentColor\",\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = \"\",\n children,\n iconNode,\n ...rest\n }, ref) => {\n return createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: mergeClasses(\"lucide\", className),\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n );\n }\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(`lucide-${toKebabCase(iconName)}`, className),\n ...props\n })\n );\n Component.displayName = `${iconName}`;\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Cable = createLucideIcon(\"Cable\", [\n [\n \"path\",\n {\n d: \"M17 21v-2a1 1 0 0 1-1-1v-1a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v1a1 1 0 0 1-1 1\",\n key: \"10bnsj\"\n }\n ],\n [\"path\", { d: \"M19 15V6.5a1 1 0 0 0-7 0v11a1 1 0 0 1-7 0V9\", key: \"1eqmu1\" }],\n [\"path\", { d: \"M21 21v-2h-4\", key: \"14zm7j\" }],\n [\"path\", { d: \"M3 5h4V3\", key: \"z442eg\" }],\n [\n \"path\",\n { d: \"M7 5a1 1 0 0 1 1 1v1a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a1 1 0 0 1 1-1V3\", key: \"ebdjd7\" }\n ]\n]);\n\nexport { Cable as default };\n//# sourceMappingURL=cable.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ChevronDown = createLucideIcon(\"ChevronDown\", [\n [\"path\", { d: \"m6 9 6 6 6-6\", key: \"qrunsl\" }]\n]);\n\nexport { ChevronDown as default };\n//# sourceMappingURL=chevron-down.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Clipboard = createLucideIcon(\"Clipboard\", [\n [\"rect\", { width: \"8\", height: \"4\", x: \"8\", y: \"2\", rx: \"1\", ry: \"1\", key: \"tgr4d6\" }],\n [\n \"path\",\n {\n d: \"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\",\n key: \"116196\"\n }\n ]\n]);\n\nexport { Clipboard as default };\n//# sourceMappingURL=clipboard.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Copy = createLucideIcon(\"Copy\", [\n [\"rect\", { width: \"14\", height: \"14\", x: \"8\", y: \"8\", rx: \"2\", ry: \"2\", key: \"17jyea\" }],\n [\"path\", { d: \"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\", key: \"zix9uf\" }]\n]);\n\nexport { Copy as default };\n//# sourceMappingURL=copy.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Download = createLucideIcon(\"Download\", [\n [\"path\", { d: \"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\", key: \"ih7n3h\" }],\n [\"polyline\", { points: \"7 10 12 15 17 10\", key: \"2ggqvy\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"15\", y2: \"3\", key: \"1vk2je\" }]\n]);\n\nexport { Download as default };\n//# sourceMappingURL=download.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Ellipsis = createLucideIcon(\"Ellipsis\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n [\"circle\", { cx: \"19\", cy: \"12\", r: \"1\", key: \"1wjl8i\" }],\n [\"circle\", { cx: \"5\", cy: \"12\", r: \"1\", key: \"1pcz8c\" }]\n]);\n\nexport { Ellipsis as default };\n//# sourceMappingURL=ellipsis.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileBox = createLucideIcon(\"FileBox\", [\n [\"path\", { d: \"M14.5 22H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4\", key: \"16lz6z\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\n \"path\",\n {\n d: \"M3 13.1a2 2 0 0 0-1 1.76v3.24a2 2 0 0 0 .97 1.78L6 21.7a2 2 0 0 0 2.03.01L11 19.9a2 2 0 0 0 1-1.76V14.9a2 2 0 0 0-.97-1.78L8 11.3a2 2 0 0 0-2.03-.01Z\",\n key: \"99pj1s\"\n }\n ],\n [\"path\", { d: \"M7 17v5\", key: \"1yj1jh\" }],\n [\"path\", { d: \"M11.7 14.2 7 17l-4.7-2.8\", key: \"1yk8tc\" }]\n]);\n\nexport { FileBox as default };\n//# sourceMappingURL=file-box.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileImage = createLucideIcon(\"FileImage\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"circle\", { cx: \"10\", cy: \"12\", r: \"2\", key: \"737tya\" }],\n [\"path\", { d: \"m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22\", key: \"wt3hpn\" }]\n]);\n\nexport { FileImage as default };\n//# sourceMappingURL=file-image.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FilePlus = createLucideIcon(\"FilePlus\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M9 15h6\", key: \"cctwl0\" }],\n [\"path\", { d: \"M12 18v-6\", key: \"17g6i2\" }]\n]);\n\nexport { FilePlus as default };\n//# sourceMappingURL=file-plus.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileType = createLucideIcon(\"FileType\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M9 13v-1h6v1\", key: \"1bb014\" }],\n [\"path\", { d: \"M12 12v6\", key: \"3ahymv\" }],\n [\"path\", { d: \"M11 18h2\", key: \"12mj7e\" }]\n]);\n\nexport { FileType as default };\n//# sourceMappingURL=file-type.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FlipHorizontal = createLucideIcon(\"FlipHorizontal\", [\n [\"path\", { d: \"M8 3H5a2 2 0 0 0-2 2v14c0 1.1.9 2 2 2h3\", key: \"1i73f7\" }],\n [\"path\", { d: \"M16 3h3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-3\", key: \"saxlbk\" }],\n [\"path\", { d: \"M12 20v2\", key: \"1lh1kg\" }],\n [\"path\", { d: \"M12 14v2\", key: \"8jcxud\" }],\n [\"path\", { d: \"M12 8v2\", key: \"1woqiv\" }],\n [\"path\", { d: \"M12 2v2\", key: \"tus03m\" }]\n]);\n\nexport { FlipHorizontal as default };\n//# sourceMappingURL=flip-horizontal.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FolderOpen = createLucideIcon(\"FolderOpen\", [\n [\n \"path\",\n {\n d: \"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2\",\n key: \"usdka0\"\n }\n ]\n]);\n\nexport { FolderOpen as default };\n//# sourceMappingURL=folder-open.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Grid2x2 = createLucideIcon(\"Grid2x2\", [\n [\"path\", { d: \"M12 3v18\", key: \"108xh3\" }],\n [\"path\", { d: \"M3 12h18\", key: \"1i2n21\" }],\n [\"rect\", { x: \"3\", y: \"3\", width: \"18\", height: \"18\", rx: \"2\", key: \"h1oib\" }]\n]);\n\nexport { Grid2x2 as default };\n//# sourceMappingURL=grid-2x2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Hand = createLucideIcon(\"Hand\", [\n [\"path\", { d: \"M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2\", key: \"1fvzgz\" }],\n [\"path\", { d: \"M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2\", key: \"1kc0my\" }],\n [\"path\", { d: \"M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8\", key: \"10h0bg\" }],\n [\n \"path\",\n {\n d: \"M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15\",\n key: \"1s1gnw\"\n }\n ]\n]);\n\nexport { Hand as default };\n//# sourceMappingURL=hand.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst LayoutGrid = createLucideIcon(\"LayoutGrid\", [\n [\"rect\", { width: \"7\", height: \"7\", x: \"3\", y: \"3\", rx: \"1\", key: \"1g98yp\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"14\", y: \"3\", rx: \"1\", key: \"6d4xhi\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"14\", y: \"14\", rx: \"1\", key: \"nxv5o0\" }],\n [\"rect\", { width: \"7\", height: \"7\", x: \"3\", y: \"14\", rx: \"1\", key: \"1bb6yr\" }]\n]);\n\nexport { LayoutGrid as default };\n//# sourceMappingURL=layout-grid.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ListTree = createLucideIcon(\"ListTree\", [\n [\"path\", { d: \"M21 12h-8\", key: \"1bmf0i\" }],\n [\"path\", { d: \"M21 6H8\", key: \"1pqkrb\" }],\n [\"path\", { d: \"M21 18h-8\", key: \"1tm79t\" }],\n [\"path\", { d: \"M3 6v4c0 1.1.9 2 2 2h3\", key: \"1ywdgy\" }],\n [\"path\", { d: \"M3 10v6c0 1.1.9 2 2 2h3\", key: \"2wc746\" }]\n]);\n\nexport { ListTree as default };\n//# sourceMappingURL=list-tree.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Maximize2 = createLucideIcon(\"Maximize2\", [\n [\"polyline\", { points: \"15 3 21 3 21 9\", key: \"mznyad\" }],\n [\"polyline\", { points: \"9 21 3 21 3 15\", key: \"1avn1i\" }],\n [\"line\", { x1: \"21\", x2: \"14\", y1: \"3\", y2: \"10\", key: \"ota7mn\" }],\n [\"line\", { x1: \"3\", x2: \"10\", y1: \"21\", y2: \"14\", key: \"1atl0r\" }]\n]);\n\nexport { Maximize2 as default };\n//# sourceMappingURL=maximize-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Minus = createLucideIcon(\"Minus\", [[\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }]]);\n\nexport { Minus as default };\n//# sourceMappingURL=minus.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst MousePointer2 = createLucideIcon(\"MousePointer2\", [\n [\n \"path\",\n {\n d: \"M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z\",\n key: \"edeuup\"\n }\n ]\n]);\n\nexport { MousePointer2 as default };\n//# sourceMappingURL=mouse-pointer-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst PanelBottomClose = createLucideIcon(\"PanelBottomClose\", [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M3 15h18\", key: \"5xshup\" }],\n [\"path\", { d: \"m15 8-3 3-3-3\", key: \"1oxy1z\" }]\n]);\n\nexport { PanelBottomClose as default };\n//# sourceMappingURL=panel-bottom-close.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Plus = createLucideIcon(\"Plus\", [\n [\"path\", { d: \"M5 12h14\", key: \"1ays0h\" }],\n [\"path\", { d: \"M12 5v14\", key: \"s699le\" }]\n]);\n\nexport { Plus as default };\n//# sourceMappingURL=plus.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Redo2 = createLucideIcon(\"Redo2\", [\n [\"path\", { d: \"m15 14 5-5-5-5\", key: \"12vg1m\" }],\n [\"path\", { d: \"M20 9H9.5A5.5 5.5 0 0 0 4 14.5A5.5 5.5 0 0 0 9.5 20H13\", key: \"6uklza\" }]\n]);\n\nexport { Redo2 as default };\n//# sourceMappingURL=redo-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RotateCw = createLucideIcon(\"RotateCw\", [\n [\"path\", { d: \"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\", key: \"1p45f6\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }]\n]);\n\nexport { RotateCw as default };\n//# sourceMappingURL=rotate-cw.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Save = createLucideIcon(\"Save\", [\n [\n \"path\",\n {\n d: \"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\",\n key: \"1c8476\"\n }\n ],\n [\"path\", { d: \"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\", key: \"1ydtos\" }],\n [\"path\", { d: \"M7 3v4a1 1 0 0 0 1 1h7\", key: \"t51u73\" }]\n]);\n\nexport { Save as default };\n//# sourceMappingURL=save.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Scissors = createLucideIcon(\"Scissors\", [\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M8.12 8.12 12 12\", key: \"1alkpv\" }],\n [\"path\", { d: \"M20 4 8.12 15.88\", key: \"xgtan2\" }],\n [\"circle\", { cx: \"6\", cy: \"18\", r: \"3\", key: \"fqmcym\" }],\n [\"path\", { d: \"M14.8 14.8 20 20\", key: \"ptml3r\" }]\n]);\n\nexport { Scissors as default };\n//# sourceMappingURL=scissors.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Search = createLucideIcon(\"Search\", [\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }],\n [\"path\", { d: \"m21 21-4.3-4.3\", key: \"1qie3q\" }]\n]);\n\nexport { Search as default };\n//# sourceMappingURL=search.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Shapes = createLucideIcon(\"Shapes\", [\n [\n \"path\",\n {\n d: \"M8.3 10a.7.7 0 0 1-.626-1.079L11.4 3a.7.7 0 0 1 1.198-.043L16.3 8.9a.7.7 0 0 1-.572 1.1Z\",\n key: \"1bo67w\"\n }\n ],\n [\"rect\", { x: \"3\", y: \"14\", width: \"7\", height: \"7\", rx: \"1\", key: \"1bkyp8\" }],\n [\"circle\", { cx: \"17.5\", cy: \"17.5\", r: \"3.5\", key: \"w3z12y\" }]\n]);\n\nexport { Shapes as default };\n//# sourceMappingURL=shapes.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Spline = createLucideIcon(\"Spline\", [\n [\"circle\", { cx: \"19\", cy: \"5\", r: \"2\", key: \"mhkx31\" }],\n [\"circle\", { cx: \"5\", cy: \"19\", r: \"2\", key: \"v8kfzx\" }],\n [\"path\", { d: \"M5 17A12 12 0 0 1 17 5\", key: \"1okkup\" }]\n]);\n\nexport { Spline as default };\n//# sourceMappingURL=spline.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst SquareDashed = createLucideIcon(\"SquareDashed\", [\n [\"path\", { d: \"M5 3a2 2 0 0 0-2 2\", key: \"y57alp\" }],\n [\"path\", { d: \"M19 3a2 2 0 0 1 2 2\", key: \"18rm91\" }],\n [\"path\", { d: \"M21 19a2 2 0 0 1-2 2\", key: \"1j7049\" }],\n [\"path\", { d: \"M5 21a2 2 0 0 1-2-2\", key: \"sbafld\" }],\n [\"path\", { d: \"M9 3h1\", key: \"1yesri\" }],\n [\"path\", { d: \"M9 21h1\", key: \"15o7lz\" }],\n [\"path\", { d: \"M14 3h1\", key: \"1ec4yj\" }],\n [\"path\", { d: \"M14 21h1\", key: \"v9vybs\" }],\n [\"path\", { d: \"M3 9v1\", key: \"1r0deq\" }],\n [\"path\", { d: \"M21 9v1\", key: \"mxsmne\" }],\n [\"path\", { d: \"M3 14v1\", key: \"vnatye\" }],\n [\"path\", { d: \"M21 14v1\", key: \"169vum\" }]\n]);\n\nexport { SquareDashed as default };\n//# sourceMappingURL=square-dashed.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Trash2 = createLucideIcon(\"Trash2\", [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"11\", y2: \"17\", key: \"1uufr5\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"11\", y2: \"17\", key: \"xtxkd\" }]\n]);\n\nexport { Trash2 as default };\n//# sourceMappingURL=trash-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Type = createLucideIcon(\"Type\", [\n [\"polyline\", { points: \"4 7 4 4 20 4 20 7\", key: \"1nosan\" }],\n [\"line\", { x1: \"9\", x2: \"15\", y1: \"20\", y2: \"20\", key: \"swin9y\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"4\", y2: \"20\", key: \"1tx1rr\" }]\n]);\n\nexport { Type as default };\n//# sourceMappingURL=type.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Undo2 = createLucideIcon(\"Undo2\", [\n [\"path\", { d: \"M9 14 4 9l5-5\", key: \"102s5s\" }],\n [\"path\", { d: \"M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11\", key: \"f3b9sd\" }]\n]);\n\nexport { Undo2 as default };\n//# sourceMappingURL=undo-2.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst WandSparkles = createLucideIcon(\"WandSparkles\", [\n [\n \"path\",\n {\n d: \"m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72\",\n key: \"ul74o6\"\n }\n ],\n [\"path\", { d: \"m14 7 3 3\", key: \"1r5n42\" }],\n [\"path\", { d: \"M5 6v4\", key: \"ilb8ba\" }],\n [\"path\", { d: \"M19 14v4\", key: \"blhpug\" }],\n [\"path\", { d: \"M10 2v2\", key: \"7u0qdc\" }],\n [\"path\", { d: \"M7 8H3\", key: \"zfb6yr\" }],\n [\"path\", { d: \"M21 16h-4\", key: \"1cnmox\" }],\n [\"path\", { d: \"M11 3H9\", key: \"1obp7u\" }]\n]);\n\nexport { WandSparkles as default };\n//# sourceMappingURL=wand-sparkles.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst X = createLucideIcon(\"X\", [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n]);\n\nexport { X as default };\n//# sourceMappingURL=x.js.map\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","const CLASS_PART_SEPARATOR = '-';\nconst createClassGroupUtils = config => {\n const classMap = createClassMap(config);\n const {\n conflictingClassGroups,\n conflictingClassGroupModifiers\n } = config;\n const getClassGroupId = className => {\n const classParts = className.split(CLASS_PART_SEPARATOR);\n // Classes like `-inset-1` produce an empty string as first classPart. We assume that classes for negative values are used correctly and remove it from classParts.\n if (classParts[0] === '' && classParts.length !== 1) {\n classParts.shift();\n }\n return getGroupRecursive(classParts, classMap) || getGroupIdForArbitraryProperty(className);\n };\n const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {\n const conflicts = conflictingClassGroups[classGroupId] || [];\n if (hasPostfixModifier && conflictingClassGroupModifiers[classGroupId]) {\n return [...conflicts, ...conflictingClassGroupModifiers[classGroupId]];\n }\n return conflicts;\n };\n return {\n getClassGroupId,\n getConflictingClassGroupIds\n };\n};\nconst getGroupRecursive = (classParts, classPartObject) => {\n if (classParts.length === 0) {\n return classPartObject.classGroupId;\n }\n const currentClassPart = classParts[0];\n const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);\n const classGroupFromNextClassPart = nextClassPartObject ? getGroupRecursive(classParts.slice(1), nextClassPartObject) : undefined;\n if (classGroupFromNextClassPart) {\n return classGroupFromNextClassPart;\n }\n if (classPartObject.validators.length === 0) {\n return undefined;\n }\n const classRest = classParts.join(CLASS_PART_SEPARATOR);\n return classPartObject.validators.find(({\n validator\n }) => validator(classRest))?.classGroupId;\n};\nconst arbitraryPropertyRegex = /^\\[(.+)\\]$/;\nconst getGroupIdForArbitraryProperty = className => {\n if (arbitraryPropertyRegex.test(className)) {\n const arbitraryPropertyClassName = arbitraryPropertyRegex.exec(className)[1];\n const property = arbitraryPropertyClassName?.substring(0, arbitraryPropertyClassName.indexOf(':'));\n if (property) {\n // I use two dots here because one dot is used as prefix for class groups in plugins\n return 'arbitrary..' + property;\n }\n }\n};\n/**\n * Exported for testing only\n */\nconst createClassMap = config => {\n const {\n theme,\n prefix\n } = config;\n const classMap = {\n nextPart: new Map(),\n validators: []\n };\n const prefixedClassGroupEntries = getPrefixedClassGroupEntries(Object.entries(config.classGroups), prefix);\n prefixedClassGroupEntries.forEach(([classGroupId, classGroup]) => {\n processClassesRecursively(classGroup, classMap, classGroupId, theme);\n });\n return classMap;\n};\nconst processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {\n classGroup.forEach(classDefinition => {\n if (typeof classDefinition === 'string') {\n const classPartObjectToEdit = classDefinition === '' ? classPartObject : getPart(classPartObject, classDefinition);\n classPartObjectToEdit.classGroupId = classGroupId;\n return;\n }\n if (typeof classDefinition === 'function') {\n if (isThemeGetter(classDefinition)) {\n processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);\n return;\n }\n classPartObject.validators.push({\n validator: classDefinition,\n classGroupId\n });\n return;\n }\n Object.entries(classDefinition).forEach(([key, classGroup]) => {\n processClassesRecursively(classGroup, getPart(classPartObject, key), classGroupId, theme);\n });\n });\n};\nconst getPart = (classPartObject, path) => {\n let currentClassPartObject = classPartObject;\n path.split(CLASS_PART_SEPARATOR).forEach(pathPart => {\n if (!currentClassPartObject.nextPart.has(pathPart)) {\n currentClassPartObject.nextPart.set(pathPart, {\n nextPart: new Map(),\n validators: []\n });\n }\n currentClassPartObject = currentClassPartObject.nextPart.get(pathPart);\n });\n return currentClassPartObject;\n};\nconst isThemeGetter = func => func.isThemeGetter;\nconst getPrefixedClassGroupEntries = (classGroupEntries, prefix) => {\n if (!prefix) {\n return classGroupEntries;\n }\n return classGroupEntries.map(([classGroupId, classGroup]) => {\n const prefixedClassGroup = classGroup.map(classDefinition => {\n if (typeof classDefinition === 'string') {\n return prefix + classDefinition;\n }\n if (typeof classDefinition === 'object') {\n return Object.fromEntries(Object.entries(classDefinition).map(([key, value]) => [prefix + key, value]));\n }\n return classDefinition;\n });\n return [classGroupId, prefixedClassGroup];\n });\n};\n\n// LRU cache inspired from hashlru (https://github.com/dominictarr/hashlru/blob/v1.0.4/index.js) but object replaced with Map to improve performance\nconst createLruCache = maxCacheSize => {\n if (maxCacheSize < 1) {\n return {\n get: () => undefined,\n set: () => {}\n };\n }\n let cacheSize = 0;\n let cache = new Map();\n let previousCache = new Map();\n const update = (key, value) => {\n cache.set(key, value);\n cacheSize++;\n if (cacheSize > maxCacheSize) {\n cacheSize = 0;\n previousCache = cache;\n cache = new Map();\n }\n };\n return {\n get(key) {\n let value = cache.get(key);\n if (value !== undefined) {\n return value;\n }\n if ((value = previousCache.get(key)) !== undefined) {\n update(key, value);\n return value;\n }\n },\n set(key, value) {\n if (cache.has(key)) {\n cache.set(key, value);\n } else {\n update(key, value);\n }\n }\n };\n};\nconst IMPORTANT_MODIFIER = '!';\nconst createParseClassName = config => {\n const {\n separator,\n experimentalParseClassName\n } = config;\n const isSeparatorSingleCharacter = separator.length === 1;\n const firstSeparatorCharacter = separator[0];\n const separatorLength = separator.length;\n // parseClassName inspired by https://github.com/tailwindlabs/tailwindcss/blob/v3.2.2/src/util/splitAtTopLevelOnly.js\n const parseClassName = className => {\n const modifiers = [];\n let bracketDepth = 0;\n let modifierStart = 0;\n let postfixModifierPosition;\n for (let index = 0; index < className.length; index++) {\n let currentCharacter = className[index];\n if (bracketDepth === 0) {\n if (currentCharacter === firstSeparatorCharacter && (isSeparatorSingleCharacter || className.slice(index, index + separatorLength) === separator)) {\n modifiers.push(className.slice(modifierStart, index));\n modifierStart = index + separatorLength;\n continue;\n }\n if (currentCharacter === '/') {\n postfixModifierPosition = index;\n continue;\n }\n }\n if (currentCharacter === '[') {\n bracketDepth++;\n } else if (currentCharacter === ']') {\n bracketDepth--;\n }\n }\n const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.substring(modifierStart);\n const hasImportantModifier = baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER);\n const baseClassName = hasImportantModifier ? baseClassNameWithImportantModifier.substring(1) : baseClassNameWithImportantModifier;\n const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart : undefined;\n return {\n modifiers,\n hasImportantModifier,\n baseClassName,\n maybePostfixModifierPosition\n };\n };\n if (experimentalParseClassName) {\n return className => experimentalParseClassName({\n className,\n parseClassName\n });\n }\n return parseClassName;\n};\n/**\n * Sorts modifiers according to following schema:\n * - Predefined modifiers are sorted alphabetically\n * - When an arbitrary variant appears, it must be preserved which modifiers are before and after it\n */\nconst sortModifiers = modifiers => {\n if (modifiers.length <= 1) {\n return modifiers;\n }\n const sortedModifiers = [];\n let unsortedModifiers = [];\n modifiers.forEach(modifier => {\n const isArbitraryVariant = modifier[0] === '[';\n if (isArbitraryVariant) {\n sortedModifiers.push(...unsortedModifiers.sort(), modifier);\n unsortedModifiers = [];\n } else {\n unsortedModifiers.push(modifier);\n }\n });\n sortedModifiers.push(...unsortedModifiers.sort());\n return sortedModifiers;\n};\nconst createConfigUtils = config => ({\n cache: createLruCache(config.cacheSize),\n parseClassName: createParseClassName(config),\n ...createClassGroupUtils(config)\n});\nconst SPLIT_CLASSES_REGEX = /\\s+/;\nconst mergeClassList = (classList, configUtils) => {\n const {\n parseClassName,\n getClassGroupId,\n getConflictingClassGroupIds\n } = configUtils;\n /**\n * Set of classGroupIds in following format:\n * `{importantModifier}{variantModifiers}{classGroupId}`\n * @example 'float'\n * @example 'hover:focus:bg-color'\n * @example 'md:!pr'\n */\n const classGroupsInConflict = [];\n const classNames = classList.trim().split(SPLIT_CLASSES_REGEX);\n let result = '';\n for (let index = classNames.length - 1; index >= 0; index -= 1) {\n const originalClassName = classNames[index];\n const {\n modifiers,\n hasImportantModifier,\n baseClassName,\n maybePostfixModifierPosition\n } = parseClassName(originalClassName);\n let hasPostfixModifier = Boolean(maybePostfixModifierPosition);\n let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);\n if (!classGroupId) {\n if (!hasPostfixModifier) {\n // Not a Tailwind class\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n continue;\n }\n classGroupId = getClassGroupId(baseClassName);\n if (!classGroupId) {\n // Not a Tailwind class\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n continue;\n }\n hasPostfixModifier = false;\n }\n const variantModifier = sortModifiers(modifiers).join(':');\n const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER : variantModifier;\n const classId = modifierId + classGroupId;\n if (classGroupsInConflict.includes(classId)) {\n // Tailwind class omitted due to conflict\n continue;\n }\n classGroupsInConflict.push(classId);\n const conflictGroups = getConflictingClassGroupIds(classGroupId, hasPostfixModifier);\n for (let i = 0; i < conflictGroups.length; ++i) {\n const group = conflictGroups[i];\n classGroupsInConflict.push(modifierId + group);\n }\n // Tailwind class not in conflict\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n }\n return result;\n};\n\n/**\n * The code in this file is copied from https://github.com/lukeed/clsx and modified to suit the needs of tailwind-merge better.\n *\n * Specifically:\n * - Runtime code from https://github.com/lukeed/clsx/blob/v1.2.1/src/index.js\n * - TypeScript types from https://github.com/lukeed/clsx/blob/v1.2.1/clsx.d.ts\n *\n * Original code has MIT license: Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)\n */\nfunction twJoin() {\n let index = 0;\n let argument;\n let resolvedValue;\n let string = '';\n while (index < arguments.length) {\n if (argument = arguments[index++]) {\n if (resolvedValue = toValue(argument)) {\n string && (string += ' ');\n string += resolvedValue;\n }\n }\n }\n return string;\n}\nconst toValue = mix => {\n if (typeof mix === 'string') {\n return mix;\n }\n let resolvedValue;\n let string = '';\n for (let k = 0; k < mix.length; k++) {\n if (mix[k]) {\n if (resolvedValue = toValue(mix[k])) {\n string && (string += ' ');\n string += resolvedValue;\n }\n }\n }\n return string;\n};\nfunction createTailwindMerge(createConfigFirst, ...createConfigRest) {\n let configUtils;\n let cacheGet;\n let cacheSet;\n let functionToCall = initTailwindMerge;\n function initTailwindMerge(classList) {\n const config = createConfigRest.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst());\n configUtils = createConfigUtils(config);\n cacheGet = configUtils.cache.get;\n cacheSet = configUtils.cache.set;\n functionToCall = tailwindMerge;\n return tailwindMerge(classList);\n }\n function tailwindMerge(classList) {\n const cachedResult = cacheGet(classList);\n if (cachedResult) {\n return cachedResult;\n }\n const result = mergeClassList(classList, configUtils);\n cacheSet(classList, result);\n return result;\n }\n return function callTailwindMerge() {\n return functionToCall(twJoin.apply(null, arguments));\n };\n}\nconst fromTheme = key => {\n const themeGetter = theme => theme[key] || [];\n themeGetter.isThemeGetter = true;\n return themeGetter;\n};\nconst arbitraryValueRegex = /^\\[(?:([a-z-]+):)?(.+)\\]$/i;\nconst fractionRegex = /^\\d+\\/\\d+$/;\nconst stringLengths = /*#__PURE__*/new Set(['px', 'full', 'screen']);\nconst tshirtUnitRegex = /^(\\d+(\\.\\d+)?)?(xs|sm|md|lg|xl)$/;\nconst lengthUnitRegex = /\\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\\b(calc|min|max|clamp)\\(.+\\)|^0$/;\nconst colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\\(.+\\)$/;\n// Shadow always begins with x and y offset separated by underscore optionally prepended by inset\nconst shadowRegex = /^(inset_)?-?((\\d+)?\\.?(\\d+)[a-z]+|0)_-?((\\d+)?\\.?(\\d+)[a-z]+|0)/;\nconst imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\\(.+\\)$/;\nconst isLength = value => isNumber(value) || stringLengths.has(value) || fractionRegex.test(value);\nconst isArbitraryLength = value => getIsArbitraryValue(value, 'length', isLengthOnly);\nconst isNumber = value => Boolean(value) && !Number.isNaN(Number(value));\nconst isArbitraryNumber = value => getIsArbitraryValue(value, 'number', isNumber);\nconst isInteger = value => Boolean(value) && Number.isInteger(Number(value));\nconst isPercent = value => value.endsWith('%') && isNumber(value.slice(0, -1));\nconst isArbitraryValue = value => arbitraryValueRegex.test(value);\nconst isTshirtSize = value => tshirtUnitRegex.test(value);\nconst sizeLabels = /*#__PURE__*/new Set(['length', 'size', 'percentage']);\nconst isArbitrarySize = value => getIsArbitraryValue(value, sizeLabels, isNever);\nconst isArbitraryPosition = value => getIsArbitraryValue(value, 'position', isNever);\nconst imageLabels = /*#__PURE__*/new Set(['image', 'url']);\nconst isArbitraryImage = value => getIsArbitraryValue(value, imageLabels, isImage);\nconst isArbitraryShadow = value => getIsArbitraryValue(value, '', isShadow);\nconst isAny = () => true;\nconst getIsArbitraryValue = (value, label, testValue) => {\n const result = arbitraryValueRegex.exec(value);\n if (result) {\n if (result[1]) {\n return typeof label === 'string' ? result[1] === label : label.has(result[1]);\n }\n return testValue(result[2]);\n }\n return false;\n};\nconst isLengthOnly = value =>\n// `colorFunctionRegex` check is necessary because color functions can have percentages in them which which would be incorrectly classified as lengths.\n// For example, `hsl(0 0% 0%)` would be classified as a length without this check.\n// I could also use lookbehind assertion in `lengthUnitRegex` but that isn't supported widely enough.\nlengthUnitRegex.test(value) && !colorFunctionRegex.test(value);\nconst isNever = () => false;\nconst isShadow = value => shadowRegex.test(value);\nconst isImage = value => imageRegex.test(value);\nconst validators = /*#__PURE__*/Object.defineProperty({\n __proto__: null,\n isAny,\n isArbitraryImage,\n isArbitraryLength,\n isArbitraryNumber,\n isArbitraryPosition,\n isArbitraryShadow,\n isArbitrarySize,\n isArbitraryValue,\n isInteger,\n isLength,\n isNumber,\n isPercent,\n isTshirtSize\n}, Symbol.toStringTag, {\n value: 'Module'\n});\nconst getDefaultConfig = () => {\n const colors = fromTheme('colors');\n const spacing = fromTheme('spacing');\n const blur = fromTheme('blur');\n const brightness = fromTheme('brightness');\n const borderColor = fromTheme('borderColor');\n const borderRadius = fromTheme('borderRadius');\n const borderSpacing = fromTheme('borderSpacing');\n const borderWidth = fromTheme('borderWidth');\n const contrast = fromTheme('contrast');\n const grayscale = fromTheme('grayscale');\n const hueRotate = fromTheme('hueRotate');\n const invert = fromTheme('invert');\n const gap = fromTheme('gap');\n const gradientColorStops = fromTheme('gradientColorStops');\n const gradientColorStopPositions = fromTheme('gradientColorStopPositions');\n const inset = fromTheme('inset');\n const margin = fromTheme('margin');\n const opacity = fromTheme('opacity');\n const padding = fromTheme('padding');\n const saturate = fromTheme('saturate');\n const scale = fromTheme('scale');\n const sepia = fromTheme('sepia');\n const skew = fromTheme('skew');\n const space = fromTheme('space');\n const translate = fromTheme('translate');\n const getOverscroll = () => ['auto', 'contain', 'none'];\n const getOverflow = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'];\n const getSpacingWithAutoAndArbitrary = () => ['auto', isArbitraryValue, spacing];\n const getSpacingWithArbitrary = () => [isArbitraryValue, spacing];\n const getLengthWithEmptyAndArbitrary = () => ['', isLength, isArbitraryLength];\n const getNumberWithAutoAndArbitrary = () => ['auto', isNumber, isArbitraryValue];\n const getPositions = () => ['bottom', 'center', 'left', 'left-bottom', 'left-top', 'right', 'right-bottom', 'right-top', 'top'];\n const getLineStyles = () => ['solid', 'dashed', 'dotted', 'double', 'none'];\n const getBlendModes = () => ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'];\n const getAlign = () => ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch'];\n const getZeroAndEmpty = () => ['', '0', isArbitraryValue];\n const getBreaks = () => ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'];\n const getNumberAndArbitrary = () => [isNumber, isArbitraryValue];\n return {\n cacheSize: 500,\n separator: ':',\n theme: {\n colors: [isAny],\n spacing: [isLength, isArbitraryLength],\n blur: ['none', '', isTshirtSize, isArbitraryValue],\n brightness: getNumberAndArbitrary(),\n borderColor: [colors],\n borderRadius: ['none', '', 'full', isTshirtSize, isArbitraryValue],\n borderSpacing: getSpacingWithArbitrary(),\n borderWidth: getLengthWithEmptyAndArbitrary(),\n contrast: getNumberAndArbitrary(),\n grayscale: getZeroAndEmpty(),\n hueRotate: getNumberAndArbitrary(),\n invert: getZeroAndEmpty(),\n gap: getSpacingWithArbitrary(),\n gradientColorStops: [colors],\n gradientColorStopPositions: [isPercent, isArbitraryLength],\n inset: getSpacingWithAutoAndArbitrary(),\n margin: getSpacingWithAutoAndArbitrary(),\n opacity: getNumberAndArbitrary(),\n padding: getSpacingWithArbitrary(),\n saturate: getNumberAndArbitrary(),\n scale: getNumberAndArbitrary(),\n sepia: getZeroAndEmpty(),\n skew: getNumberAndArbitrary(),\n space: getSpacingWithArbitrary(),\n translate: getSpacingWithArbitrary()\n },\n classGroups: {\n // Layout\n /**\n * Aspect Ratio\n * @see https://tailwindcss.com/docs/aspect-ratio\n */\n aspect: [{\n aspect: ['auto', 'square', 'video', isArbitraryValue]\n }],\n /**\n * Container\n * @see https://tailwindcss.com/docs/container\n */\n container: ['container'],\n /**\n * Columns\n * @see https://tailwindcss.com/docs/columns\n */\n columns: [{\n columns: [isTshirtSize]\n }],\n /**\n * Break After\n * @see https://tailwindcss.com/docs/break-after\n */\n 'break-after': [{\n 'break-after': getBreaks()\n }],\n /**\n * Break Before\n * @see https://tailwindcss.com/docs/break-before\n */\n 'break-before': [{\n 'break-before': getBreaks()\n }],\n /**\n * Break Inside\n * @see https://tailwindcss.com/docs/break-inside\n */\n 'break-inside': [{\n 'break-inside': ['auto', 'avoid', 'avoid-page', 'avoid-column']\n }],\n /**\n * Box Decoration Break\n * @see https://tailwindcss.com/docs/box-decoration-break\n */\n 'box-decoration': [{\n 'box-decoration': ['slice', 'clone']\n }],\n /**\n * Box Sizing\n * @see https://tailwindcss.com/docs/box-sizing\n */\n box: [{\n box: ['border', 'content']\n }],\n /**\n * Display\n * @see https://tailwindcss.com/docs/display\n */\n display: ['block', 'inline-block', 'inline', 'flex', 'inline-flex', 'table', 'inline-table', 'table-caption', 'table-cell', 'table-column', 'table-column-group', 'table-footer-group', 'table-header-group', 'table-row-group', 'table-row', 'flow-root', 'grid', 'inline-grid', 'contents', 'list-item', 'hidden'],\n /**\n * Floats\n * @see https://tailwindcss.com/docs/float\n */\n float: [{\n float: ['right', 'left', 'none', 'start', 'end']\n }],\n /**\n * Clear\n * @see https://tailwindcss.com/docs/clear\n */\n clear: [{\n clear: ['left', 'right', 'both', 'none', 'start', 'end']\n }],\n /**\n * Isolation\n * @see https://tailwindcss.com/docs/isolation\n */\n isolation: ['isolate', 'isolation-auto'],\n /**\n * Object Fit\n * @see https://tailwindcss.com/docs/object-fit\n */\n 'object-fit': [{\n object: ['contain', 'cover', 'fill', 'none', 'scale-down']\n }],\n /**\n * Object Position\n * @see https://tailwindcss.com/docs/object-position\n */\n 'object-position': [{\n object: [...getPositions(), isArbitraryValue]\n }],\n /**\n * Overflow\n * @see https://tailwindcss.com/docs/overflow\n */\n overflow: [{\n overflow: getOverflow()\n }],\n /**\n * Overflow X\n * @see https://tailwindcss.com/docs/overflow\n */\n 'overflow-x': [{\n 'overflow-x': getOverflow()\n }],\n /**\n * Overflow Y\n * @see https://tailwindcss.com/docs/overflow\n */\n 'overflow-y': [{\n 'overflow-y': getOverflow()\n }],\n /**\n * Overscroll Behavior\n * @see https://tailwindcss.com/docs/overscroll-behavior\n */\n overscroll: [{\n overscroll: getOverscroll()\n }],\n /**\n * Overscroll Behavior X\n * @see https://tailwindcss.com/docs/overscroll-behavior\n */\n 'overscroll-x': [{\n 'overscroll-x': getOverscroll()\n }],\n /**\n * Overscroll Behavior Y\n * @see https://tailwindcss.com/docs/overscroll-behavior\n */\n 'overscroll-y': [{\n 'overscroll-y': getOverscroll()\n }],\n /**\n * Position\n * @see https://tailwindcss.com/docs/position\n */\n position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],\n /**\n * Top / Right / Bottom / Left\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n inset: [{\n inset: [inset]\n }],\n /**\n * Right / Left\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n 'inset-x': [{\n 'inset-x': [inset]\n }],\n /**\n * Top / Bottom\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n 'inset-y': [{\n 'inset-y': [inset]\n }],\n /**\n * Start\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n start: [{\n start: [inset]\n }],\n /**\n * End\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n end: [{\n end: [inset]\n }],\n /**\n * Top\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n top: [{\n top: [inset]\n }],\n /**\n * Right\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n right: [{\n right: [inset]\n }],\n /**\n * Bottom\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n bottom: [{\n bottom: [inset]\n }],\n /**\n * Left\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n left: [{\n left: [inset]\n }],\n /**\n * Visibility\n * @see https://tailwindcss.com/docs/visibility\n */\n visibility: ['visible', 'invisible', 'collapse'],\n /**\n * Z-Index\n * @see https://tailwindcss.com/docs/z-index\n */\n z: [{\n z: ['auto', isInteger, isArbitraryValue]\n }],\n // Flexbox and Grid\n /**\n * Flex Basis\n * @see https://tailwindcss.com/docs/flex-basis\n */\n basis: [{\n basis: getSpacingWithAutoAndArbitrary()\n }],\n /**\n * Flex Direction\n * @see https://tailwindcss.com/docs/flex-direction\n */\n 'flex-direction': [{\n flex: ['row', 'row-reverse', 'col', 'col-reverse']\n }],\n /**\n * Flex Wrap\n * @see https://tailwindcss.com/docs/flex-wrap\n */\n 'flex-wrap': [{\n flex: ['wrap', 'wrap-reverse', 'nowrap']\n }],\n /**\n * Flex\n * @see https://tailwindcss.com/docs/flex\n */\n flex: [{\n flex: ['1', 'auto', 'initial', 'none', isArbitraryValue]\n }],\n /**\n * Flex Grow\n * @see https://tailwindcss.com/docs/flex-grow\n */\n grow: [{\n grow: getZeroAndEmpty()\n }],\n /**\n * Flex Shrink\n * @see https://tailwindcss.com/docs/flex-shrink\n */\n shrink: [{\n shrink: getZeroAndEmpty()\n }],\n /**\n * Order\n * @see https://tailwindcss.com/docs/order\n */\n order: [{\n order: ['first', 'last', 'none', isInteger, isArbitraryValue]\n }],\n /**\n * Grid Template Columns\n * @see https://tailwindcss.com/docs/grid-template-columns\n */\n 'grid-cols': [{\n 'grid-cols': [isAny]\n }],\n /**\n * Grid Column Start / End\n * @see https://tailwindcss.com/docs/grid-column\n */\n 'col-start-end': [{\n col: ['auto', {\n span: ['full', isInteger, isArbitraryValue]\n }, isArbitraryValue]\n }],\n /**\n * Grid Column Start\n * @see https://tailwindcss.com/docs/grid-column\n */\n 'col-start': [{\n 'col-start': getNumberWithAutoAndArbitrary()\n }],\n /**\n * Grid Column End\n * @see https://tailwindcss.com/docs/grid-column\n */\n 'col-end': [{\n 'col-end': getNumberWithAutoAndArbitrary()\n }],\n /**\n * Grid Template Rows\n * @see https://tailwindcss.com/docs/grid-template-rows\n */\n 'grid-rows': [{\n 'grid-rows': [isAny]\n }],\n /**\n * Grid Row Start / End\n * @see https://tailwindcss.com/docs/grid-row\n */\n 'row-start-end': [{\n row: ['auto', {\n span: [isInteger, isArbitraryValue]\n }, isArbitraryValue]\n }],\n /**\n * Grid Row Start\n * @see https://tailwindcss.com/docs/grid-row\n */\n 'row-start': [{\n 'row-start': getNumberWithAutoAndArbitrary()\n }],\n /**\n * Grid Row End\n * @see https://tailwindcss.com/docs/grid-row\n */\n 'row-end': [{\n 'row-end': getNumberWithAutoAndArbitrary()\n }],\n /**\n * Grid Auto Flow\n * @see https://tailwindcss.com/docs/grid-auto-flow\n */\n 'grid-flow': [{\n 'grid-flow': ['row', 'col', 'dense', 'row-dense', 'col-dense']\n }],\n /**\n * Grid Auto Columns\n * @see https://tailwindcss.com/docs/grid-auto-columns\n */\n 'auto-cols': [{\n 'auto-cols': ['auto', 'min', 'max', 'fr', isArbitraryValue]\n }],\n /**\n * Grid Auto Rows\n * @see https://tailwindcss.com/docs/grid-auto-rows\n */\n 'auto-rows': [{\n 'auto-rows': ['auto', 'min', 'max', 'fr', isArbitraryValue]\n }],\n /**\n * Gap\n * @see https://tailwindcss.com/docs/gap\n */\n gap: [{\n gap: [gap]\n }],\n /**\n * Gap X\n * @see https://tailwindcss.com/docs/gap\n */\n 'gap-x': [{\n 'gap-x': [gap]\n }],\n /**\n * Gap Y\n * @see https://tailwindcss.com/docs/gap\n */\n 'gap-y': [{\n 'gap-y': [gap]\n }],\n /**\n * Justify Content\n * @see https://tailwindcss.com/docs/justify-content\n */\n 'justify-content': [{\n justify: ['normal', ...getAlign()]\n }],\n /**\n * Justify Items\n * @see https://tailwindcss.com/docs/justify-items\n */\n 'justify-items': [{\n 'justify-items': ['start', 'end', 'center', 'stretch']\n }],\n /**\n * Justify Self\n * @see https://tailwindcss.com/docs/justify-self\n */\n 'justify-self': [{\n 'justify-self': ['auto', 'start', 'end', 'center', 'stretch']\n }],\n /**\n * Align Content\n * @see https://tailwindcss.com/docs/align-content\n */\n 'align-content': [{\n content: ['normal', ...getAlign(), 'baseline']\n }],\n /**\n * Align Items\n * @see https://tailwindcss.com/docs/align-items\n */\n 'align-items': [{\n items: ['start', 'end', 'center', 'baseline', 'stretch']\n }],\n /**\n * Align Self\n * @see https://tailwindcss.com/docs/align-self\n */\n 'align-self': [{\n self: ['auto', 'start', 'end', 'center', 'stretch', 'baseline']\n }],\n /**\n * Place Content\n * @see https://tailwindcss.com/docs/place-content\n */\n 'place-content': [{\n 'place-content': [...getAlign(), 'baseline']\n }],\n /**\n * Place Items\n * @see https://tailwindcss.com/docs/place-items\n */\n 'place-items': [{\n 'place-items': ['start', 'end', 'center', 'baseline', 'stretch']\n }],\n /**\n * Place Self\n * @see https://tailwindcss.com/docs/place-self\n */\n 'place-self': [{\n 'place-self': ['auto', 'start', 'end', 'center', 'stretch']\n }],\n // Spacing\n /**\n * Padding\n * @see https://tailwindcss.com/docs/padding\n */\n p: [{\n p: [padding]\n }],\n /**\n * Padding X\n * @see https://tailwindcss.com/docs/padding\n */\n px: [{\n px: [padding]\n }],\n /**\n * Padding Y\n * @see https://tailwindcss.com/docs/padding\n */\n py: [{\n py: [padding]\n }],\n /**\n * Padding Start\n * @see https://tailwindcss.com/docs/padding\n */\n ps: [{\n ps: [padding]\n }],\n /**\n * Padding End\n * @see https://tailwindcss.com/docs/padding\n */\n pe: [{\n pe: [padding]\n }],\n /**\n * Padding Top\n * @see https://tailwindcss.com/docs/padding\n */\n pt: [{\n pt: [padding]\n }],\n /**\n * Padding Right\n * @see https://tailwindcss.com/docs/padding\n */\n pr: [{\n pr: [padding]\n }],\n /**\n * Padding Bottom\n * @see https://tailwindcss.com/docs/padding\n */\n pb: [{\n pb: [padding]\n }],\n /**\n * Padding Left\n * @see https://tailwindcss.com/docs/padding\n */\n pl: [{\n pl: [padding]\n }],\n /**\n * Margin\n * @see https://tailwindcss.com/docs/margin\n */\n m: [{\n m: [margin]\n }],\n /**\n * Margin X\n * @see https://tailwindcss.com/docs/margin\n */\n mx: [{\n mx: [margin]\n }],\n /**\n * Margin Y\n * @see https://tailwindcss.com/docs/margin\n */\n my: [{\n my: [margin]\n }],\n /**\n * Margin Start\n * @see https://tailwindcss.com/docs/margin\n */\n ms: [{\n ms: [margin]\n }],\n /**\n * Margin End\n * @see https://tailwindcss.com/docs/margin\n */\n me: [{\n me: [margin]\n }],\n /**\n * Margin Top\n * @see https://tailwindcss.com/docs/margin\n */\n mt: [{\n mt: [margin]\n }],\n /**\n * Margin Right\n * @see https://tailwindcss.com/docs/margin\n */\n mr: [{\n mr: [margin]\n }],\n /**\n * Margin Bottom\n * @see https://tailwindcss.com/docs/margin\n */\n mb: [{\n mb: [margin]\n }],\n /**\n * Margin Left\n * @see https://tailwindcss.com/docs/margin\n */\n ml: [{\n ml: [margin]\n }],\n /**\n * Space Between X\n * @see https://tailwindcss.com/docs/space\n */\n 'space-x': [{\n 'space-x': [space]\n }],\n /**\n * Space Between X Reverse\n * @see https://tailwindcss.com/docs/space\n */\n 'space-x-reverse': ['space-x-reverse'],\n /**\n * Space Between Y\n * @see https://tailwindcss.com/docs/space\n */\n 'space-y': [{\n 'space-y': [space]\n }],\n /**\n * Space Between Y Reverse\n * @see https://tailwindcss.com/docs/space\n */\n 'space-y-reverse': ['space-y-reverse'],\n // Sizing\n /**\n * Width\n * @see https://tailwindcss.com/docs/width\n */\n w: [{\n w: ['auto', 'min', 'max', 'fit', 'svw', 'lvw', 'dvw', isArbitraryValue, spacing]\n }],\n /**\n * Min-Width\n * @see https://tailwindcss.com/docs/min-width\n */\n 'min-w': [{\n 'min-w': [isArbitraryValue, spacing, 'min', 'max', 'fit']\n }],\n /**\n * Max-Width\n * @see https://tailwindcss.com/docs/max-width\n */\n 'max-w': [{\n 'max-w': [isArbitraryValue, spacing, 'none', 'full', 'min', 'max', 'fit', 'prose', {\n screen: [isTshirtSize]\n }, isTshirtSize]\n }],\n /**\n * Height\n * @see https://tailwindcss.com/docs/height\n */\n h: [{\n h: [isArbitraryValue, spacing, 'auto', 'min', 'max', 'fit', 'svh', 'lvh', 'dvh']\n }],\n /**\n * Min-Height\n * @see https://tailwindcss.com/docs/min-height\n */\n 'min-h': [{\n 'min-h': [isArbitraryValue, spacing, 'min', 'max', 'fit', 'svh', 'lvh', 'dvh']\n }],\n /**\n * Max-Height\n * @see https://tailwindcss.com/docs/max-height\n */\n 'max-h': [{\n 'max-h': [isArbitraryValue, spacing, 'min', 'max', 'fit', 'svh', 'lvh', 'dvh']\n }],\n /**\n * Size\n * @see https://tailwindcss.com/docs/size\n */\n size: [{\n size: [isArbitraryValue, spacing, 'auto', 'min', 'max', 'fit']\n }],\n // Typography\n /**\n * Font Size\n * @see https://tailwindcss.com/docs/font-size\n */\n 'font-size': [{\n text: ['base', isTshirtSize, isArbitraryLength]\n }],\n /**\n * Font Smoothing\n * @see https://tailwindcss.com/docs/font-smoothing\n */\n 'font-smoothing': ['antialiased', 'subpixel-antialiased'],\n /**\n * Font Style\n * @see https://tailwindcss.com/docs/font-style\n */\n 'font-style': ['italic', 'not-italic'],\n /**\n * Font Weight\n * @see https://tailwindcss.com/docs/font-weight\n */\n 'font-weight': [{\n font: ['thin', 'extralight', 'light', 'normal', 'medium', 'semibold', 'bold', 'extrabold', 'black', isArbitraryNumber]\n }],\n /**\n * Font Family\n * @see https://tailwindcss.com/docs/font-family\n */\n 'font-family': [{\n font: [isAny]\n }],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-normal': ['normal-nums'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-ordinal': ['ordinal'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-slashed-zero': ['slashed-zero'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-figure': ['lining-nums', 'oldstyle-nums'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-spacing': ['proportional-nums', 'tabular-nums'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-fraction': ['diagonal-fractions', 'stacked-fractions'],\n /**\n * Letter Spacing\n * @see https://tailwindcss.com/docs/letter-spacing\n */\n tracking: [{\n tracking: ['tighter', 'tight', 'normal', 'wide', 'wider', 'widest', isArbitraryValue]\n }],\n /**\n * Line Clamp\n * @see https://tailwindcss.com/docs/line-clamp\n */\n 'line-clamp': [{\n 'line-clamp': ['none', isNumber, isArbitraryNumber]\n }],\n /**\n * Line Height\n * @see https://tailwindcss.com/docs/line-height\n */\n leading: [{\n leading: ['none', 'tight', 'snug', 'normal', 'relaxed', 'loose', isLength, isArbitraryValue]\n }],\n /**\n * List Style Image\n * @see https://tailwindcss.com/docs/list-style-image\n */\n 'list-image': [{\n 'list-image': ['none', isArbitraryValue]\n }],\n /**\n * List Style Type\n * @see https://tailwindcss.com/docs/list-style-type\n */\n 'list-style-type': [{\n list: ['none', 'disc', 'decimal', isArbitraryValue]\n }],\n /**\n * List Style Position\n * @see https://tailwindcss.com/docs/list-style-position\n */\n 'list-style-position': [{\n list: ['inside', 'outside']\n }],\n /**\n * Placeholder Color\n * @deprecated since Tailwind CSS v3.0.0\n * @see https://tailwindcss.com/docs/placeholder-color\n */\n 'placeholder-color': [{\n placeholder: [colors]\n }],\n /**\n * Placeholder Opacity\n * @see https://tailwindcss.com/docs/placeholder-opacity\n */\n 'placeholder-opacity': [{\n 'placeholder-opacity': [opacity]\n }],\n /**\n * Text Alignment\n * @see https://tailwindcss.com/docs/text-align\n */\n 'text-alignment': [{\n text: ['left', 'center', 'right', 'justify', 'start', 'end']\n }],\n /**\n * Text Color\n * @see https://tailwindcss.com/docs/text-color\n */\n 'text-color': [{\n text: [colors]\n }],\n /**\n * Text Opacity\n * @see https://tailwindcss.com/docs/text-opacity\n */\n 'text-opacity': [{\n 'text-opacity': [opacity]\n }],\n /**\n * Text Decoration\n * @see https://tailwindcss.com/docs/text-decoration\n */\n 'text-decoration': ['underline', 'overline', 'line-through', 'no-underline'],\n /**\n * Text Decoration Style\n * @see https://tailwindcss.com/docs/text-decoration-style\n */\n 'text-decoration-style': [{\n decoration: [...getLineStyles(), 'wavy']\n }],\n /**\n * Text Decoration Thickness\n * @see https://tailwindcss.com/docs/text-decoration-thickness\n */\n 'text-decoration-thickness': [{\n decoration: ['auto', 'from-font', isLength, isArbitraryLength]\n }],\n /**\n * Text Underline Offset\n * @see https://tailwindcss.com/docs/text-underline-offset\n */\n 'underline-offset': [{\n 'underline-offset': ['auto', isLength, isArbitraryValue]\n }],\n /**\n * Text Decoration Color\n * @see https://tailwindcss.com/docs/text-decoration-color\n */\n 'text-decoration-color': [{\n decoration: [colors]\n }],\n /**\n * Text Transform\n * @see https://tailwindcss.com/docs/text-transform\n */\n 'text-transform': ['uppercase', 'lowercase', 'capitalize', 'normal-case'],\n /**\n * Text Overflow\n * @see https://tailwindcss.com/docs/text-overflow\n */\n 'text-overflow': ['truncate', 'text-ellipsis', 'text-clip'],\n /**\n * Text Wrap\n * @see https://tailwindcss.com/docs/text-wrap\n */\n 'text-wrap': [{\n text: ['wrap', 'nowrap', 'balance', 'pretty']\n }],\n /**\n * Text Indent\n * @see https://tailwindcss.com/docs/text-indent\n */\n indent: [{\n indent: getSpacingWithArbitrary()\n }],\n /**\n * Vertical Alignment\n * @see https://tailwindcss.com/docs/vertical-align\n */\n 'vertical-align': [{\n align: ['baseline', 'top', 'middle', 'bottom', 'text-top', 'text-bottom', 'sub', 'super', isArbitraryValue]\n }],\n /**\n * Whitespace\n * @see https://tailwindcss.com/docs/whitespace\n */\n whitespace: [{\n whitespace: ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'break-spaces']\n }],\n /**\n * Word Break\n * @see https://tailwindcss.com/docs/word-break\n */\n break: [{\n break: ['normal', 'words', 'all', 'keep']\n }],\n /**\n * Hyphens\n * @see https://tailwindcss.com/docs/hyphens\n */\n hyphens: [{\n hyphens: ['none', 'manual', 'auto']\n }],\n /**\n * Content\n * @see https://tailwindcss.com/docs/content\n */\n content: [{\n content: ['none', isArbitraryValue]\n }],\n // Backgrounds\n /**\n * Background Attachment\n * @see https://tailwindcss.com/docs/background-attachment\n */\n 'bg-attachment': [{\n bg: ['fixed', 'local', 'scroll']\n }],\n /**\n * Background Clip\n * @see https://tailwindcss.com/docs/background-clip\n */\n 'bg-clip': [{\n 'bg-clip': ['border', 'padding', 'content', 'text']\n }],\n /**\n * Background Opacity\n * @deprecated since Tailwind CSS v3.0.0\n * @see https://tailwindcss.com/docs/background-opacity\n */\n 'bg-opacity': [{\n 'bg-opacity': [opacity]\n }],\n /**\n * Background Origin\n * @see https://tailwindcss.com/docs/background-origin\n */\n 'bg-origin': [{\n 'bg-origin': ['border', 'padding', 'content']\n }],\n /**\n * Background Position\n * @see https://tailwindcss.com/docs/background-position\n */\n 'bg-position': [{\n bg: [...getPositions(), isArbitraryPosition]\n }],\n /**\n * Background Repeat\n * @see https://tailwindcss.com/docs/background-repeat\n */\n 'bg-repeat': [{\n bg: ['no-repeat', {\n repeat: ['', 'x', 'y', 'round', 'space']\n }]\n }],\n /**\n * Background Size\n * @see https://tailwindcss.com/docs/background-size\n */\n 'bg-size': [{\n bg: ['auto', 'cover', 'contain', isArbitrarySize]\n }],\n /**\n * Background Image\n * @see https://tailwindcss.com/docs/background-image\n */\n 'bg-image': [{\n bg: ['none', {\n 'gradient-to': ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl']\n }, isArbitraryImage]\n }],\n /**\n * Background Color\n * @see https://tailwindcss.com/docs/background-color\n */\n 'bg-color': [{\n bg: [colors]\n }],\n /**\n * Gradient Color Stops From Position\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-from-pos': [{\n from: [gradientColorStopPositions]\n }],\n /**\n * Gradient Color Stops Via Position\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-via-pos': [{\n via: [gradientColorStopPositions]\n }],\n /**\n * Gradient Color Stops To Position\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-to-pos': [{\n to: [gradientColorStopPositions]\n }],\n /**\n * Gradient Color Stops From\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-from': [{\n from: [gradientColorStops]\n }],\n /**\n * Gradient Color Stops Via\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-via': [{\n via: [gradientColorStops]\n }],\n /**\n * Gradient Color Stops To\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-to': [{\n to: [gradientColorStops]\n }],\n // Borders\n /**\n * Border Radius\n * @see https://tailwindcss.com/docs/border-radius\n */\n rounded: [{\n rounded: [borderRadius]\n }],\n /**\n * Border Radius Start\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-s': [{\n 'rounded-s': [borderRadius]\n }],\n /**\n * Border Radius End\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-e': [{\n 'rounded-e': [borderRadius]\n }],\n /**\n * Border Radius Top\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-t': [{\n 'rounded-t': [borderRadius]\n }],\n /**\n * Border Radius Right\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-r': [{\n 'rounded-r': [borderRadius]\n }],\n /**\n * Border Radius Bottom\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-b': [{\n 'rounded-b': [borderRadius]\n }],\n /**\n * Border Radius Left\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-l': [{\n 'rounded-l': [borderRadius]\n }],\n /**\n * Border Radius Start Start\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-ss': [{\n 'rounded-ss': [borderRadius]\n }],\n /**\n * Border Radius Start End\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-se': [{\n 'rounded-se': [borderRadius]\n }],\n /**\n * Border Radius End End\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-ee': [{\n 'rounded-ee': [borderRadius]\n }],\n /**\n * Border Radius End Start\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-es': [{\n 'rounded-es': [borderRadius]\n }],\n /**\n * Border Radius Top Left\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-tl': [{\n 'rounded-tl': [borderRadius]\n }],\n /**\n * Border Radius Top Right\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-tr': [{\n 'rounded-tr': [borderRadius]\n }],\n /**\n * Border Radius Bottom Right\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-br': [{\n 'rounded-br': [borderRadius]\n }],\n /**\n * Border Radius Bottom Left\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-bl': [{\n 'rounded-bl': [borderRadius]\n }],\n /**\n * Border Width\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w': [{\n border: [borderWidth]\n }],\n /**\n * Border Width X\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-x': [{\n 'border-x': [borderWidth]\n }],\n /**\n * Border Width Y\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-y': [{\n 'border-y': [borderWidth]\n }],\n /**\n * Border Width Start\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-s': [{\n 'border-s': [borderWidth]\n }],\n /**\n * Border Width End\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-e': [{\n 'border-e': [borderWidth]\n }],\n /**\n * Border Width Top\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-t': [{\n 'border-t': [borderWidth]\n }],\n /**\n * Border Width Right\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-r': [{\n 'border-r': [borderWidth]\n }],\n /**\n * Border Width Bottom\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-b': [{\n 'border-b': [borderWidth]\n }],\n /**\n * Border Width Left\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-l': [{\n 'border-l': [borderWidth]\n }],\n /**\n * Border Opacity\n * @see https://tailwindcss.com/docs/border-opacity\n */\n 'border-opacity': [{\n 'border-opacity': [opacity]\n }],\n /**\n * Border Style\n * @see https://tailwindcss.com/docs/border-style\n */\n 'border-style': [{\n border: [...getLineStyles(), 'hidden']\n }],\n /**\n * Divide Width X\n * @see https://tailwindcss.com/docs/divide-width\n */\n 'divide-x': [{\n 'divide-x': [borderWidth]\n }],\n /**\n * Divide Width X Reverse\n * @see https://tailwindcss.com/docs/divide-width\n */\n 'divide-x-reverse': ['divide-x-reverse'],\n /**\n * Divide Width Y\n * @see https://tailwindcss.com/docs/divide-width\n */\n 'divide-y': [{\n 'divide-y': [borderWidth]\n }],\n /**\n * Divide Width Y Reverse\n * @see https://tailwindcss.com/docs/divide-width\n */\n 'divide-y-reverse': ['divide-y-reverse'],\n /**\n * Divide Opacity\n * @see https://tailwindcss.com/docs/divide-opacity\n */\n 'divide-opacity': [{\n 'divide-opacity': [opacity]\n }],\n /**\n * Divide Style\n * @see https://tailwindcss.com/docs/divide-style\n */\n 'divide-style': [{\n divide: getLineStyles()\n }],\n /**\n * Border Color\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color': [{\n border: [borderColor]\n }],\n /**\n * Border Color X\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-x': [{\n 'border-x': [borderColor]\n }],\n /**\n * Border Color Y\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-y': [{\n 'border-y': [borderColor]\n }],\n /**\n * Border Color S\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-s': [{\n 'border-s': [borderColor]\n }],\n /**\n * Border Color E\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-e': [{\n 'border-e': [borderColor]\n }],\n /**\n * Border Color Top\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-t': [{\n 'border-t': [borderColor]\n }],\n /**\n * Border Color Right\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-r': [{\n 'border-r': [borderColor]\n }],\n /**\n * Border Color Bottom\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-b': [{\n 'border-b': [borderColor]\n }],\n /**\n * Border Color Left\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-l': [{\n 'border-l': [borderColor]\n }],\n /**\n * Divide Color\n * @see https://tailwindcss.com/docs/divide-color\n */\n 'divide-color': [{\n divide: [borderColor]\n }],\n /**\n * Outline Style\n * @see https://tailwindcss.com/docs/outline-style\n */\n 'outline-style': [{\n outline: ['', ...getLineStyles()]\n }],\n /**\n * Outline Offset\n * @see https://tailwindcss.com/docs/outline-offset\n */\n 'outline-offset': [{\n 'outline-offset': [isLength, isArbitraryValue]\n }],\n /**\n * Outline Width\n * @see https://tailwindcss.com/docs/outline-width\n */\n 'outline-w': [{\n outline: [isLength, isArbitraryLength]\n }],\n /**\n * Outline Color\n * @see https://tailwindcss.com/docs/outline-color\n */\n 'outline-color': [{\n outline: [colors]\n }],\n /**\n * Ring Width\n * @see https://tailwindcss.com/docs/ring-width\n */\n 'ring-w': [{\n ring: getLengthWithEmptyAndArbitrary()\n }],\n /**\n * Ring Width Inset\n * @see https://tailwindcss.com/docs/ring-width\n */\n 'ring-w-inset': ['ring-inset'],\n /**\n * Ring Color\n * @see https://tailwindcss.com/docs/ring-color\n */\n 'ring-color': [{\n ring: [colors]\n }],\n /**\n * Ring Opacity\n * @see https://tailwindcss.com/docs/ring-opacity\n */\n 'ring-opacity': [{\n 'ring-opacity': [opacity]\n }],\n /**\n * Ring Offset Width\n * @see https://tailwindcss.com/docs/ring-offset-width\n */\n 'ring-offset-w': [{\n 'ring-offset': [isLength, isArbitraryLength]\n }],\n /**\n * Ring Offset Color\n * @see https://tailwindcss.com/docs/ring-offset-color\n */\n 'ring-offset-color': [{\n 'ring-offset': [colors]\n }],\n // Effects\n /**\n * Box Shadow\n * @see https://tailwindcss.com/docs/box-shadow\n */\n shadow: [{\n shadow: ['', 'inner', 'none', isTshirtSize, isArbitraryShadow]\n }],\n /**\n * Box Shadow Color\n * @see https://tailwindcss.com/docs/box-shadow-color\n */\n 'shadow-color': [{\n shadow: [isAny]\n }],\n /**\n * Opacity\n * @see https://tailwindcss.com/docs/opacity\n */\n opacity: [{\n opacity: [opacity]\n }],\n /**\n * Mix Blend Mode\n * @see https://tailwindcss.com/docs/mix-blend-mode\n */\n 'mix-blend': [{\n 'mix-blend': [...getBlendModes(), 'plus-lighter', 'plus-darker']\n }],\n /**\n * Background Blend Mode\n * @see https://tailwindcss.com/docs/background-blend-mode\n */\n 'bg-blend': [{\n 'bg-blend': getBlendModes()\n }],\n // Filters\n /**\n * Filter\n * @deprecated since Tailwind CSS v3.0.0\n * @see https://tailwindcss.com/docs/filter\n */\n filter: [{\n filter: ['', 'none']\n }],\n /**\n * Blur\n * @see https://tailwindcss.com/docs/blur\n */\n blur: [{\n blur: [blur]\n }],\n /**\n * Brightness\n * @see https://tailwindcss.com/docs/brightness\n */\n brightness: [{\n brightness: [brightness]\n }],\n /**\n * Contrast\n * @see https://tailwindcss.com/docs/contrast\n */\n contrast: [{\n contrast: [contrast]\n }],\n /**\n * Drop Shadow\n * @see https://tailwindcss.com/docs/drop-shadow\n */\n 'drop-shadow': [{\n 'drop-shadow': ['', 'none', isTshirtSize, isArbitraryValue]\n }],\n /**\n * Grayscale\n * @see https://tailwindcss.com/docs/grayscale\n */\n grayscale: [{\n grayscale: [grayscale]\n }],\n /**\n * Hue Rotate\n * @see https://tailwindcss.com/docs/hue-rotate\n */\n 'hue-rotate': [{\n 'hue-rotate': [hueRotate]\n }],\n /**\n * Invert\n * @see https://tailwindcss.com/docs/invert\n */\n invert: [{\n invert: [invert]\n }],\n /**\n * Saturate\n * @see https://tailwindcss.com/docs/saturate\n */\n saturate: [{\n saturate: [saturate]\n }],\n /**\n * Sepia\n * @see https://tailwindcss.com/docs/sepia\n */\n sepia: [{\n sepia: [sepia]\n }],\n /**\n * Backdrop Filter\n * @deprecated since Tailwind CSS v3.0.0\n * @see https://tailwindcss.com/docs/backdrop-filter\n */\n 'backdrop-filter': [{\n 'backdrop-filter': ['', 'none']\n }],\n /**\n * Backdrop Blur\n * @see https://tailwindcss.com/docs/backdrop-blur\n */\n 'backdrop-blur': [{\n 'backdrop-blur': [blur]\n }],\n /**\n * Backdrop Brightness\n * @see https://tailwindcss.com/docs/backdrop-brightness\n */\n 'backdrop-brightness': [{\n 'backdrop-brightness': [brightness]\n }],\n /**\n * Backdrop Contrast\n * @see https://tailwindcss.com/docs/backdrop-contrast\n */\n 'backdrop-contrast': [{\n 'backdrop-contrast': [contrast]\n }],\n /**\n * Backdrop Grayscale\n * @see https://tailwindcss.com/docs/backdrop-grayscale\n */\n 'backdrop-grayscale': [{\n 'backdrop-grayscale': [grayscale]\n }],\n /**\n * Backdrop Hue Rotate\n * @see https://tailwindcss.com/docs/backdrop-hue-rotate\n */\n 'backdrop-hue-rotate': [{\n 'backdrop-hue-rotate': [hueRotate]\n }],\n /**\n * Backdrop Invert\n * @see https://tailwindcss.com/docs/backdrop-invert\n */\n 'backdrop-invert': [{\n 'backdrop-invert': [invert]\n }],\n /**\n * Backdrop Opacity\n * @see https://tailwindcss.com/docs/backdrop-opacity\n */\n 'backdrop-opacity': [{\n 'backdrop-opacity': [opacity]\n }],\n /**\n * Backdrop Saturate\n * @see https://tailwindcss.com/docs/backdrop-saturate\n */\n 'backdrop-saturate': [{\n 'backdrop-saturate': [saturate]\n }],\n /**\n * Backdrop Sepia\n * @see https://tailwindcss.com/docs/backdrop-sepia\n */\n 'backdrop-sepia': [{\n 'backdrop-sepia': [sepia]\n }],\n // Tables\n /**\n * Border Collapse\n * @see https://tailwindcss.com/docs/border-collapse\n */\n 'border-collapse': [{\n border: ['collapse', 'separate']\n }],\n /**\n * Border Spacing\n * @see https://tailwindcss.com/docs/border-spacing\n */\n 'border-spacing': [{\n 'border-spacing': [borderSpacing]\n }],\n /**\n * Border Spacing X\n * @see https://tailwindcss.com/docs/border-spacing\n */\n 'border-spacing-x': [{\n 'border-spacing-x': [borderSpacing]\n }],\n /**\n * Border Spacing Y\n * @see https://tailwindcss.com/docs/border-spacing\n */\n 'border-spacing-y': [{\n 'border-spacing-y': [borderSpacing]\n }],\n /**\n * Table Layout\n * @see https://tailwindcss.com/docs/table-layout\n */\n 'table-layout': [{\n table: ['auto', 'fixed']\n }],\n /**\n * Caption Side\n * @see https://tailwindcss.com/docs/caption-side\n */\n caption: [{\n caption: ['top', 'bottom']\n }],\n // Transitions and Animation\n /**\n * Tranisition Property\n * @see https://tailwindcss.com/docs/transition-property\n */\n transition: [{\n transition: ['none', 'all', '', 'colors', 'opacity', 'shadow', 'transform', isArbitraryValue]\n }],\n /**\n * Transition Duration\n * @see https://tailwindcss.com/docs/transition-duration\n */\n duration: [{\n duration: getNumberAndArbitrary()\n }],\n /**\n * Transition Timing Function\n * @see https://tailwindcss.com/docs/transition-timing-function\n */\n ease: [{\n ease: ['linear', 'in', 'out', 'in-out', isArbitraryValue]\n }],\n /**\n * Transition Delay\n * @see https://tailwindcss.com/docs/transition-delay\n */\n delay: [{\n delay: getNumberAndArbitrary()\n }],\n /**\n * Animation\n * @see https://tailwindcss.com/docs/animation\n */\n animate: [{\n animate: ['none', 'spin', 'ping', 'pulse', 'bounce', isArbitraryValue]\n }],\n // Transforms\n /**\n * Transform\n * @see https://tailwindcss.com/docs/transform\n */\n transform: [{\n transform: ['', 'gpu', 'none']\n }],\n /**\n * Scale\n * @see https://tailwindcss.com/docs/scale\n */\n scale: [{\n scale: [scale]\n }],\n /**\n * Scale X\n * @see https://tailwindcss.com/docs/scale\n */\n 'scale-x': [{\n 'scale-x': [scale]\n }],\n /**\n * Scale Y\n * @see https://tailwindcss.com/docs/scale\n */\n 'scale-y': [{\n 'scale-y': [scale]\n }],\n /**\n * Rotate\n * @see https://tailwindcss.com/docs/rotate\n */\n rotate: [{\n rotate: [isInteger, isArbitraryValue]\n }],\n /**\n * Translate X\n * @see https://tailwindcss.com/docs/translate\n */\n 'translate-x': [{\n 'translate-x': [translate]\n }],\n /**\n * Translate Y\n * @see https://tailwindcss.com/docs/translate\n */\n 'translate-y': [{\n 'translate-y': [translate]\n }],\n /**\n * Skew X\n * @see https://tailwindcss.com/docs/skew\n */\n 'skew-x': [{\n 'skew-x': [skew]\n }],\n /**\n * Skew Y\n * @see https://tailwindcss.com/docs/skew\n */\n 'skew-y': [{\n 'skew-y': [skew]\n }],\n /**\n * Transform Origin\n * @see https://tailwindcss.com/docs/transform-origin\n */\n 'transform-origin': [{\n origin: ['center', 'top', 'top-right', 'right', 'bottom-right', 'bottom', 'bottom-left', 'left', 'top-left', isArbitraryValue]\n }],\n // Interactivity\n /**\n * Accent Color\n * @see https://tailwindcss.com/docs/accent-color\n */\n accent: [{\n accent: ['auto', colors]\n }],\n /**\n * Appearance\n * @see https://tailwindcss.com/docs/appearance\n */\n appearance: [{\n appearance: ['none', 'auto']\n }],\n /**\n * Cursor\n * @see https://tailwindcss.com/docs/cursor\n */\n cursor: [{\n cursor: ['auto', 'default', 'pointer', 'wait', 'text', 'move', 'help', 'not-allowed', 'none', 'context-menu', 'progress', 'cell', 'crosshair', 'vertical-text', 'alias', 'copy', 'no-drop', 'grab', 'grabbing', 'all-scroll', 'col-resize', 'row-resize', 'n-resize', 'e-resize', 's-resize', 'w-resize', 'ne-resize', 'nw-resize', 'se-resize', 'sw-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out', isArbitraryValue]\n }],\n /**\n * Caret Color\n * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities\n */\n 'caret-color': [{\n caret: [colors]\n }],\n /**\n * Pointer Events\n * @see https://tailwindcss.com/docs/pointer-events\n */\n 'pointer-events': [{\n 'pointer-events': ['none', 'auto']\n }],\n /**\n * Resize\n * @see https://tailwindcss.com/docs/resize\n */\n resize: [{\n resize: ['none', 'y', 'x', '']\n }],\n /**\n * Scroll Behavior\n * @see https://tailwindcss.com/docs/scroll-behavior\n */\n 'scroll-behavior': [{\n scroll: ['auto', 'smooth']\n }],\n /**\n * Scroll Margin\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-m': [{\n 'scroll-m': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin X\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mx': [{\n 'scroll-mx': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Y\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-my': [{\n 'scroll-my': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Start\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-ms': [{\n 'scroll-ms': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin End\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-me': [{\n 'scroll-me': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Top\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mt': [{\n 'scroll-mt': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Right\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mr': [{\n 'scroll-mr': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Bottom\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mb': [{\n 'scroll-mb': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Margin Left\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-ml': [{\n 'scroll-ml': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-p': [{\n 'scroll-p': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding X\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-px': [{\n 'scroll-px': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Y\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-py': [{\n 'scroll-py': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Start\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-ps': [{\n 'scroll-ps': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding End\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pe': [{\n 'scroll-pe': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Top\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pt': [{\n 'scroll-pt': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Right\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pr': [{\n 'scroll-pr': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Bottom\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pb': [{\n 'scroll-pb': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Padding Left\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pl': [{\n 'scroll-pl': getSpacingWithArbitrary()\n }],\n /**\n * Scroll Snap Align\n * @see https://tailwindcss.com/docs/scroll-snap-align\n */\n 'snap-align': [{\n snap: ['start', 'end', 'center', 'align-none']\n }],\n /**\n * Scroll Snap Stop\n * @see https://tailwindcss.com/docs/scroll-snap-stop\n */\n 'snap-stop': [{\n snap: ['normal', 'always']\n }],\n /**\n * Scroll Snap Type\n * @see https://tailwindcss.com/docs/scroll-snap-type\n */\n 'snap-type': [{\n snap: ['none', 'x', 'y', 'both']\n }],\n /**\n * Scroll Snap Type Strictness\n * @see https://tailwindcss.com/docs/scroll-snap-type\n */\n 'snap-strictness': [{\n snap: ['mandatory', 'proximity']\n }],\n /**\n * Touch Action\n * @see https://tailwindcss.com/docs/touch-action\n */\n touch: [{\n touch: ['auto', 'none', 'manipulation']\n }],\n /**\n * Touch Action X\n * @see https://tailwindcss.com/docs/touch-action\n */\n 'touch-x': [{\n 'touch-pan': ['x', 'left', 'right']\n }],\n /**\n * Touch Action Y\n * @see https://tailwindcss.com/docs/touch-action\n */\n 'touch-y': [{\n 'touch-pan': ['y', 'up', 'down']\n }],\n /**\n * Touch Action Pinch Zoom\n * @see https://tailwindcss.com/docs/touch-action\n */\n 'touch-pz': ['touch-pinch-zoom'],\n /**\n * User Select\n * @see https://tailwindcss.com/docs/user-select\n */\n select: [{\n select: ['none', 'text', 'all', 'auto']\n }],\n /**\n * Will Change\n * @see https://tailwindcss.com/docs/will-change\n */\n 'will-change': [{\n 'will-change': ['auto', 'scroll', 'contents', 'transform', isArbitraryValue]\n }],\n // SVG\n /**\n * Fill\n * @see https://tailwindcss.com/docs/fill\n */\n fill: [{\n fill: [colors, 'none']\n }],\n /**\n * Stroke Width\n * @see https://tailwindcss.com/docs/stroke-width\n */\n 'stroke-w': [{\n stroke: [isLength, isArbitraryLength, isArbitraryNumber]\n }],\n /**\n * Stroke\n * @see https://tailwindcss.com/docs/stroke\n */\n stroke: [{\n stroke: [colors, 'none']\n }],\n // Accessibility\n /**\n * Screen Readers\n * @see https://tailwindcss.com/docs/screen-readers\n */\n sr: ['sr-only', 'not-sr-only'],\n /**\n * Forced Color Adjust\n * @see https://tailwindcss.com/docs/forced-color-adjust\n */\n 'forced-color-adjust': [{\n 'forced-color-adjust': ['auto', 'none']\n }]\n },\n conflictingClassGroups: {\n overflow: ['overflow-x', 'overflow-y'],\n overscroll: ['overscroll-x', 'overscroll-y'],\n inset: ['inset-x', 'inset-y', 'start', 'end', 'top', 'right', 'bottom', 'left'],\n 'inset-x': ['right', 'left'],\n 'inset-y': ['top', 'bottom'],\n flex: ['basis', 'grow', 'shrink'],\n gap: ['gap-x', 'gap-y'],\n p: ['px', 'py', 'ps', 'pe', 'pt', 'pr', 'pb', 'pl'],\n px: ['pr', 'pl'],\n py: ['pt', 'pb'],\n m: ['mx', 'my', 'ms', 'me', 'mt', 'mr', 'mb', 'ml'],\n mx: ['mr', 'ml'],\n my: ['mt', 'mb'],\n size: ['w', 'h'],\n 'font-size': ['leading'],\n 'fvn-normal': ['fvn-ordinal', 'fvn-slashed-zero', 'fvn-figure', 'fvn-spacing', 'fvn-fraction'],\n 'fvn-ordinal': ['fvn-normal'],\n 'fvn-slashed-zero': ['fvn-normal'],\n 'fvn-figure': ['fvn-normal'],\n 'fvn-spacing': ['fvn-normal'],\n 'fvn-fraction': ['fvn-normal'],\n 'line-clamp': ['display', 'overflow'],\n rounded: ['rounded-s', 'rounded-e', 'rounded-t', 'rounded-r', 'rounded-b', 'rounded-l', 'rounded-ss', 'rounded-se', 'rounded-ee', 'rounded-es', 'rounded-tl', 'rounded-tr', 'rounded-br', 'rounded-bl'],\n 'rounded-s': ['rounded-ss', 'rounded-es'],\n 'rounded-e': ['rounded-se', 'rounded-ee'],\n 'rounded-t': ['rounded-tl', 'rounded-tr'],\n 'rounded-r': ['rounded-tr', 'rounded-br'],\n 'rounded-b': ['rounded-br', 'rounded-bl'],\n 'rounded-l': ['rounded-tl', 'rounded-bl'],\n 'border-spacing': ['border-spacing-x', 'border-spacing-y'],\n 'border-w': ['border-w-s', 'border-w-e', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],\n 'border-w-x': ['border-w-r', 'border-w-l'],\n 'border-w-y': ['border-w-t', 'border-w-b'],\n 'border-color': ['border-color-s', 'border-color-e', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],\n 'border-color-x': ['border-color-r', 'border-color-l'],\n 'border-color-y': ['border-color-t', 'border-color-b'],\n 'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],\n 'scroll-mx': ['scroll-mr', 'scroll-ml'],\n 'scroll-my': ['scroll-mt', 'scroll-mb'],\n 'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],\n 'scroll-px': ['scroll-pr', 'scroll-pl'],\n 'scroll-py': ['scroll-pt', 'scroll-pb'],\n touch: ['touch-x', 'touch-y', 'touch-pz'],\n 'touch-x': ['touch'],\n 'touch-y': ['touch'],\n 'touch-pz': ['touch']\n },\n conflictingClassGroupModifiers: {\n 'font-size': ['leading']\n }\n };\n};\n\n/**\n * @param baseConfig Config where other config will be merged into. This object will be mutated.\n * @param configExtension Partial config to merge into the `baseConfig`.\n */\nconst mergeConfigs = (baseConfig, {\n cacheSize,\n prefix,\n separator,\n experimentalParseClassName,\n extend = {},\n override = {}\n}) => {\n overrideProperty(baseConfig, 'cacheSize', cacheSize);\n overrideProperty(baseConfig, 'prefix', prefix);\n overrideProperty(baseConfig, 'separator', separator);\n overrideProperty(baseConfig, 'experimentalParseClassName', experimentalParseClassName);\n for (const configKey in override) {\n overrideConfigProperties(baseConfig[configKey], override[configKey]);\n }\n for (const key in extend) {\n mergeConfigProperties(baseConfig[key], extend[key]);\n }\n return baseConfig;\n};\nconst overrideProperty = (baseObject, overrideKey, overrideValue) => {\n if (overrideValue !== undefined) {\n baseObject[overrideKey] = overrideValue;\n }\n};\nconst overrideConfigProperties = (baseObject, overrideObject) => {\n if (overrideObject) {\n for (const key in overrideObject) {\n overrideProperty(baseObject, key, overrideObject[key]);\n }\n }\n};\nconst mergeConfigProperties = (baseObject, mergeObject) => {\n if (mergeObject) {\n for (const key in mergeObject) {\n const mergeValue = mergeObject[key];\n if (mergeValue !== undefined) {\n baseObject[key] = (baseObject[key] || []).concat(mergeValue);\n }\n }\n }\n};\nconst extendTailwindMerge = (configExtension, ...createConfig) => typeof configExtension === 'function' ? createTailwindMerge(getDefaultConfig, configExtension, ...createConfig) : createTailwindMerge(() => mergeConfigs(getDefaultConfig(), configExtension), ...createConfig);\nconst twMerge = /*#__PURE__*/createTailwindMerge(getDefaultConfig);\nexport { createTailwindMerge, extendTailwindMerge, fromTheme, getDefaultConfig, mergeConfigs, twJoin, twMerge, validators };\n//# sourceMappingURL=bundle-mjs.mjs.map\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","/**\n * Lightweight right-click menu. Self-contained (no Radix popper) — items are\n * built on demand by the caller and passed via `useContextMenu().open()`.\n *\n * Position-flips by measuring the rendered menu in a layout effect, so the\n * first frame is hidden until the clamp is applied. Dismisses on outside\n * click, Esc, scroll, and window blur.\n */\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { cn } from '../lib/utils';\n\nexport interface ContextMenuItem {\n type?: 'item';\n label: string;\n shortcut?: string;\n icon?: React.ComponentType<{ className?: string }>;\n onSelect: () => void;\n disabled?: boolean;\n destructive?: boolean;\n}\nexport interface ContextMenuSeparator {\n type: 'separator';\n}\nexport type ContextMenuEntry = ContextMenuItem | ContextMenuSeparator;\n\ninterface ContextMenuApi {\n open: (x: number, y: number, items: ContextMenuEntry[]) => void;\n close: () => void;\n}\n\nconst Ctx = createContext<ContextMenuApi | null>(null);\n\nexport function useContextMenu(): ContextMenuApi {\n const api = useContext(Ctx);\n if (!api) {\n throw new Error('useContextMenu must be used inside <ContextMenuHost>');\n }\n return api;\n}\n\ninterface MenuState {\n open: boolean;\n x: number;\n y: number;\n items: ContextMenuEntry[];\n}\n\nconst VIEWPORT_PAD = 8;\n\nexport function ContextMenuHost({ children }: { children: ReactNode }) {\n const [state, setState] = useState<MenuState>({\n open: false,\n x: 0,\n y: 0,\n items: [],\n });\n const [clamped, setClamped] = useState<{ left: number; top: number } | null>(\n null,\n );\n const ref = useRef<HTMLDivElement>(null);\n\n const close = useCallback(() => {\n setState((s) => (s.open ? { ...s, open: false } : s));\n }, []);\n\n const open = useCallback(\n (x: number, y: number, items: ContextMenuEntry[]) => {\n setClamped(null);\n setState({ open: true, x, y, items });\n },\n [],\n );\n\n const api = useMemo<ContextMenuApi>(() => ({ open, close }), [open, close]);\n\n useLayoutEffect(() => {\n if (!state.open || !ref.current) return;\n const r = ref.current.getBoundingClientRect();\n let left = state.x;\n let top = state.y;\n // Flip to the opposite side if the menu would overflow.\n if (left + r.width > window.innerWidth - VIEWPORT_PAD) {\n left = Math.max(VIEWPORT_PAD, state.x - r.width);\n }\n if (top + r.height > window.innerHeight - VIEWPORT_PAD) {\n top = Math.max(VIEWPORT_PAD, state.y - r.height);\n }\n setClamped({ left, top });\n }, [state]);\n\n useEffect(() => {\n if (!state.open) return;\n const onPointerDown = (e: PointerEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) close();\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n };\n const onWheel = () => close();\n const onBlur = () => close();\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('keydown', onKey, true);\n window.addEventListener('wheel', onWheel, { passive: true });\n window.addEventListener('blur', onBlur);\n return () => {\n document.removeEventListener('pointerdown', onPointerDown, true);\n document.removeEventListener('keydown', onKey, true);\n window.removeEventListener('wheel', onWheel);\n window.removeEventListener('blur', onBlur);\n };\n }, [state.open, close]);\n\n return (\n <Ctx.Provider value={api}>\n {children}\n {state.open && (\n <div\n ref={ref}\n role=\"menu\"\n aria-orientation=\"vertical\"\n className=\"ole-glass fixed z-50 min-w-[200px] rounded-md border border-border p-1 text-sm shadow-md\"\n style={{\n left: clamped?.left ?? state.x,\n top: clamped?.top ?? state.y,\n visibility: clamped ? 'visible' : 'hidden',\n }}\n onContextMenu={(e) => e.preventDefault()}\n >\n {state.items.map((entry, i) => {\n if (entry.type === 'separator') {\n return (\n <div\n key={`sep-${i}`}\n role=\"separator\"\n className=\"my-1 h-px bg-border\"\n />\n );\n }\n const Icon = entry.icon;\n return (\n <button\n key={`${entry.label}-${i}`}\n type=\"button\"\n role=\"menuitem\"\n disabled={entry.disabled}\n className={cn(\n 'flex w-full items-center justify-between gap-3 rounded-sm px-2 py-1.5 text-left',\n 'hover:bg-accent hover:text-accent-foreground',\n 'focus-visible:bg-accent focus-visible:text-accent-foreground focus-visible:outline-none',\n entry.destructive &&\n 'text-destructive hover:bg-destructive/10 hover:text-destructive',\n entry.disabled &&\n 'pointer-events-none text-muted-foreground opacity-60',\n )}\n onClick={() => {\n close();\n entry.onSelect();\n }}\n >\n <span className=\"flex items-center gap-2\">\n {Icon ? <Icon className=\"size-4\" /> : null}\n <span>{entry.label}</span>\n </span>\n {entry.shortcut ? (\n <span className=\"text-xs text-muted-foreground\">\n {entry.shortcut}\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n )}\n </Ctx.Provider>\n );\n}\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n","import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n","/**\n * Flat translation table keyed by dot-namespaced ids.\n *\n * Both locales must define the same key set — TypeScript enforces this via\n * the `LocaleKey` type derived from `messages.zh`. Placeholder syntax is\n * `{name}` and is substituted by the `t()` helper.\n */\n\nexport const messages = {\n zh: {\n 'common.unnamed': '未命名',\n 'common.close': '关闭',\n 'common.yes': '是',\n 'common.no': '否',\n\n 'topbar.theme.toLight': '切换到亮色',\n 'topbar.theme.toDark': '切换到暗色',\n 'topbar.theme.currentDark': '当前:暗色主题',\n 'topbar.theme.currentLight': '当前:亮色主题',\n 'topbar.lang.toEnglish': 'Switch to English',\n 'topbar.lang.toChinese': '切换到中文',\n 'topbar.lang.currentEnglish': 'Current: English',\n 'topbar.lang.currentChinese': '当前:中文',\n\n 'topbar.export.label': '导出',\n 'topbar.export.tooltip': 'SVG 矢量(可编辑)、PNG 位图(2× 高清)或 DXF(CAD)',\n 'topbar.export.pngFailed': '导出 PNG 失败:{err}',\n 'topbar.export.dxfFailed': '导出 DXF 失败:{err}',\n\n 'topbar.file.label': '文件',\n 'topbar.file.tooltip': '打开本地 .json 图、保存、或另存为',\n 'topbar.file.current': '当前:{name}',\n 'topbar.file.new': '新建',\n 'topbar.file.open': '打开…',\n 'topbar.file.save': '保存',\n 'topbar.file.saveAs': '另存为…',\n 'topbar.file.newConfirm': '新建会清空当前未保存的内容,是否继续?',\n 'topbar.file.openFailed': '打开失败:{err}',\n 'topbar.file.saveFailed': '保存失败:{err}',\n 'topbar.file.fileDescription': 'OneLineEditor 图纸',\n\n 'outline.title': '大纲',\n 'outline.collapse': '折叠',\n 'outline.collapseAria': '折叠大纲',\n 'outline.empty': '(无设备 — 从元件库拖入开始)',\n\n 'props.title': '属性',\n 'props.node': '电气节点',\n 'props.wire': '连线',\n 'props.bus': '母线',\n 'props.nSelected': '{n} 选中',\n 'props.empty': '未选中',\n 'props.multi': '已选中 {n} 个元件',\n 'props.name': '名称',\n 'props.note': '备注',\n 'props.nodeNotFound': '电气节点 {id} 不存在',\n 'props.wireNotFound': '连线 {id} 不存在',\n 'props.nodeStats': '{terminals} 个端子 · {elements} 个元件',\n 'props.selectElement': '选中 {label}',\n 'props.selectWholeNode': '选中整个电气节点',\n\n 'view.zoomOut': '缩小',\n 'view.zoomOutHint': '按预设档位缩小;也可滚轮 ↓ 或 ⌘−',\n 'view.reset': '重置到 100%',\n 'view.current': '当前 {z}%',\n 'view.zoomIn': '放大',\n 'view.zoomInHint': '按预设档位放大;也可滚轮 ↑ 或 ⌘+',\n 'view.fit': '适配视图',\n 'view.fitHint': '自动缩放并居中所有元件',\n 'view.gridHide': '隐藏网格',\n 'view.gridShow': '显示网格',\n 'view.gridHotkey': 'G',\n 'view.gridHideHint': '同时关闭对齐吸附(拖动可自由放置)',\n 'view.gridShowHint': '同时开启对齐吸附(拖动会贴到 10px 网格)',\n 'view.gridHideAria': '隐藏网格并关闭吸附',\n 'view.gridShowAria': '显示网格并开启吸附',\n 'view.label': '标签',\n 'view.labelOff': '关闭标签',\n 'view.labelId': '仅显示 ID',\n 'view.labelAll': 'ID + 参数',\n 'view.labelHint': '点击循环切换:关闭 → 仅 ID → ID + 参数',\n\n 'library.title': '元件库',\n 'library.empty': '没有匹配的元件',\n 'library.searchPlaceholder': '搜索元件…',\n 'library.searchAria': '搜索元件',\n 'library.clearSearch': '清除搜索',\n 'library.itemHint': '单击进入放置模式或拖到画布',\n\n 'tool.select': '选择',\n 'tool.selectHint': '点选元件,框选多个,或右键打开菜单',\n 'tool.pan': '平移',\n 'tool.panHint': '拖动画布;空格键可临时切换',\n 'tool.wire': '连线',\n 'tool.wireHint': '从一个端子拖动到另一个端子完成连线',\n 'tool.bus': '母线',\n 'tool.busHint': '画布上拖动一段母线,按下定起点、释放定终点',\n 'tool.place': '元件',\n 'tool.placeHint': '点击画布放置;或从端子/母线拖出,同时放置并连接',\n 'tool.text': '文字',\n 'tool.textHint': '点击画布放置一段文字注释;双击文字可重新编辑',\n\n 'mode.selectWithSel': '拖动元件移动 · 拖端子连线 · 右键打开菜单',\n 'mode.selectEmpty': '点选元件 · 拖动移动 · 框选多个 · 右键打开菜单',\n 'mode.pan': '拖动画布 · 滚轮缩放 · 按住空格可在其他工具下临时平移',\n 'mode.wireDragging': '拖到另一个端子或母线上释放完成连线',\n 'mode.wireInit': '从端子按下,拖动到另一个端子或母线上释放',\n 'mode.busDragging': '拖动决定母线方向,释放定终点',\n 'mode.busInit': '在画布按下定起点,拖动后释放定终点',\n 'mode.placeNoKind': '从左侧元件库选择一种元件',\n 'mode.placeFromTerm': '拖到目标位置释放,新元件将连接到起点端子',\n 'mode.placeNormal': '点击空白放置;或从已有端子 / 母线拖出,同时放置并连接',\n 'mode.text': '点击画布放置文字;双击已有文字可编辑;选中后可拖动 / 删除',\n 'mode.escSelect': 'Esc 清除选择',\n 'mode.escOther': '右键 / Esc 取消',\n\n 'tool.placeNoKindTooltip': '从左侧元件库选择一个元件后点击画布放置',\n 'tool.undo': '撤销',\n 'tool.undoHint': '撤销上一次编辑(移动 / 旋转 / 删除等)',\n 'tool.redo': '重做',\n 'tool.redoHint': '重做被撤销的操作',\n\n 'layout.label': '布局',\n 'layout.hint': '自动排版整个图或仅选中范围,并填补空缺',\n 'layout.allAuto': '重新自动布局',\n 'layout.selAuto': '重新自动布局选区',\n 'layout.allFill': '填补未排版位置',\n 'layout.selFill': '填补未排版选区',\n\n 'tool.more': '更多',\n 'tool.moreHint': '撤销 / 重做 / 布局',\n 'view.menu': '视图',\n 'view.menuHint': '缩放、适配、网格',\n\n 'ctx.ariaNode': '选中节点操作',\n 'ctx.ariaWire': '选中连线操作',\n 'ctx.ariaElement': '选中元件操作',\n 'ctx.rotate': '旋转 90°',\n 'ctx.rotateHint': '顺时针旋转选中元件,连线随端子自动重排',\n 'ctx.mirror': '水平镜像',\n 'ctx.mirrorTitle': '镜像',\n 'ctx.mirrorHint': '左右翻转选中元件',\n 'ctx.delete': '删除',\n 'ctx.deleteHintNode': '断开此电气节点上的所有连接(保留元件)',\n 'ctx.deleteHintWire': '移除这一根连线(其它同节点连线保留)',\n 'ctx.deleteHintElement': '移除选中元件及其连接的连线',\n 'ctx.resetWirePath': '恢复自动走线',\n 'ctx.resetWirePathHint': '清除手动调整的拐点,让连线回到自动路由',\n\n 'menu.undo': '撤销',\n 'menu.redo': '重做',\n 'menu.cut': '剪切',\n 'menu.copy': '复制',\n 'menu.paste': '粘贴',\n 'menu.rotate': '旋转 90°',\n 'menu.mirror': '镜像',\n 'menu.selectAll': '全选',\n 'menu.disconnect': '断开此连线',\n 'menu.delete': '删除',\n\n 'io.parseFailed': 'JSON 解析失败:{err}',\n 'io.notObject': '文件不是 JSON 对象',\n 'io.versionMismatch': '版本不兼容:期望 \"1\",实际 {actual}',\n 'io.elementsMissing': 'elements 字段缺失或不是数组',\n\n 'compile.duplicateId': '元件 ID 重复:\"{id}\"',\n 'compile.unknownKind': '未知元件类型 kind=\"{kind}\"',\n 'compile.invalidTermRef': '非法端子引用 \"{ref}\"',\n 'compile.elementMissing': '引用了不存在的元件 \"{id}\"',\n 'compile.missingPin': '元件 \"{id}\" (kind={kind}) 没有引脚 \"{pin}\",可用引脚: {available}',\n 'compile.singleTerminal': '节点只包含一个端子,已忽略',\n 'compile.layoutMissingElement': 'layout 键 \"{id}\" 引用了不存在的元件',\n 'compile.elementUnconnected': '元件 \"{id}\" 没有任何连接',\n\n 'cat.busbar': '母线 / 接线',\n 'cat.switching': '开关',\n 'cat.protection': '保护',\n 'cat.motor-control': '电机控制',\n 'cat.transformer': '变压器',\n 'cat.instrument-transformer': '互感器',\n 'cat.measurement': '测量仪表',\n 'cat.source': '电源',\n 'cat.load': '负荷',\n 'cat.storage': '储能',\n 'cat.compensation': '无功补偿',\n 'cat.grounding': '中性点接地',\n 'cat.renewable': '新能源 / 电力电子',\n\n 'onboard.title': '上手三步',\n 'onboard.step1.title': '画母线',\n 'onboard.step1.body': '选择 母线 工具(B),在画布上按下拖动',\n 'onboard.step2.title': '从母线拖出元件',\n 'onboard.step2.body': '切到 元件(P)选一种,按住母线拖到目标位置 — 自动连接',\n 'onboard.step3.title': '继续串接',\n 'onboard.step3.body': '从任意端子拖出,落到目标即与该端子相连',\n 'onboard.dismiss': '知道了',\n },\n en: {\n 'common.unnamed': 'Untitled',\n 'common.close': 'Close',\n 'common.yes': 'Yes',\n 'common.no': 'No',\n\n 'topbar.theme.toLight': 'Switch to light',\n 'topbar.theme.toDark': 'Switch to dark',\n 'topbar.theme.currentDark': 'Current: dark theme',\n 'topbar.theme.currentLight': 'Current: light theme',\n 'topbar.lang.toEnglish': 'Switch to English',\n 'topbar.lang.toChinese': '切换到中文',\n 'topbar.lang.currentEnglish': 'Current: English',\n 'topbar.lang.currentChinese': 'Current: Chinese',\n\n 'topbar.export.label': 'Export',\n 'topbar.export.tooltip': 'SVG vector (editable), PNG bitmap (2× HiDPI), or DXF (CAD)',\n 'topbar.export.pngFailed': 'PNG export failed: {err}',\n 'topbar.export.dxfFailed': 'DXF export failed: {err}',\n\n 'topbar.file.label': 'File',\n 'topbar.file.tooltip': 'Open a local .json diagram, save, or save as',\n 'topbar.file.current': 'Current: {name}',\n 'topbar.file.new': 'New',\n 'topbar.file.open': 'Open…',\n 'topbar.file.save': 'Save',\n 'topbar.file.saveAs': 'Save as…',\n 'topbar.file.newConfirm': 'New will discard any unsaved changes. Continue?',\n 'topbar.file.openFailed': 'Open failed: {err}',\n 'topbar.file.saveFailed': 'Save failed: {err}',\n 'topbar.file.fileDescription': 'OneLineEditor diagram',\n\n 'outline.title': 'Outline',\n 'outline.collapse': 'Collapse',\n 'outline.collapseAria': 'Collapse outline',\n 'outline.empty': '(No elements — drag from the library to start)',\n\n 'props.title': 'Properties',\n 'props.node': 'Electrical node',\n 'props.wire': 'Wire',\n 'props.bus': 'Bus',\n 'props.nSelected': '{n} selected',\n 'props.empty': 'Nothing selected',\n 'props.multi': '{n} elements selected',\n 'props.name': 'Name',\n 'props.note': 'Note',\n 'props.nodeNotFound': 'Electrical node {id} not found',\n 'props.wireNotFound': 'Wire {id} not found',\n 'props.nodeStats': '{terminals} terminals · {elements} elements',\n 'props.selectElement': 'Select {label}',\n 'props.selectWholeNode': 'Select whole electrical node',\n\n 'view.zoomOut': 'Zoom out',\n 'view.zoomOutHint': 'Step zoom out; also wheel ↓ or ⌘−',\n 'view.reset': 'Reset to 100%',\n 'view.current': 'Current {z}%',\n 'view.zoomIn': 'Zoom in',\n 'view.zoomInHint': 'Step zoom in; also wheel ↑ or ⌘+',\n 'view.fit': 'Fit view',\n 'view.fitHint': 'Auto-zoom and center all elements',\n 'view.gridHide': 'Hide grid',\n 'view.gridShow': 'Show grid',\n 'view.gridHotkey': 'G',\n 'view.gridHideHint': 'Also disables snap-to-grid (free placement)',\n 'view.gridShowHint': 'Also enables snap-to-grid (snaps to 10px on drag)',\n 'view.gridHideAria': 'Hide grid and disable snap',\n 'view.gridShowAria': 'Show grid and enable snap',\n 'view.label': 'Labels',\n 'view.labelOff': 'Hide labels',\n 'view.labelId': 'ID only',\n 'view.labelAll': 'ID + params',\n 'view.labelHint': 'Cycle: off → ID → ID + params',\n\n 'library.title': 'Library',\n 'library.empty': 'No matching elements',\n 'library.searchPlaceholder': 'Search elements…',\n 'library.searchAria': 'Search elements',\n 'library.clearSearch': 'Clear search',\n 'library.itemHint': 'Click to enter place mode, or drag onto the canvas',\n\n 'tool.select': 'Select',\n 'tool.selectHint': 'Click to pick, marquee for multiple, right-click for menu',\n 'tool.pan': 'Pan',\n 'tool.panHint': 'Drag the canvas; Space toggles temporarily',\n 'tool.wire': 'Wire',\n 'tool.wireHint': 'Drag from one terminal to another to wire',\n 'tool.bus': 'Busbar',\n 'tool.busHint': 'Drag on the canvas — press to set start, release to set end',\n 'tool.place': 'Place',\n 'tool.placeHint': 'Click to place; or drag from a terminal/bus to place and connect',\n 'tool.text': 'Text',\n 'tool.textHint': 'Click the canvas to drop a text note; double-click an existing one to edit',\n\n 'mode.selectWithSel': 'Drag elements · drag terminals to wire · right-click for menu',\n 'mode.selectEmpty': 'Click to pick · drag to move · marquee for multiple · right-click for menu',\n 'mode.pan': 'Drag the canvas · scroll to zoom · hold Space to pan in any tool',\n 'mode.wireDragging': 'Release on another terminal or busbar to complete the wire',\n 'mode.wireInit': 'Press on a terminal, drag to another terminal or busbar, release',\n 'mode.busDragging': 'Drag sets bus direction; release sets the end',\n 'mode.busInit': 'Press on the canvas to set start, drag, release to set end',\n 'mode.placeNoKind': 'Pick an element kind from the library on the left',\n 'mode.placeFromTerm': 'Release at the target — the new element will connect back to the source terminal',\n 'mode.placeNormal': 'Click empty space to place; or drag from a terminal / bus to place and connect',\n 'mode.text': 'Click to drop text · double-click to edit · drag selected to move · Del to remove',\n 'mode.escSelect': 'Esc clears selection',\n 'mode.escOther': 'Right-click / Esc to cancel',\n\n 'tool.placeNoKindTooltip': 'Pick a kind in the library on the left, then click the canvas',\n 'tool.undo': 'Undo',\n 'tool.undoHint': 'Undo the last edit (move / rotate / delete, etc.)',\n 'tool.redo': 'Redo',\n 'tool.redoHint': 'Redo the last undone edit',\n\n 'layout.label': 'Layout',\n 'layout.hint': 'Auto-layout the whole diagram or just the selection, fill gaps',\n 'layout.allAuto': 'Auto-layout all',\n 'layout.selAuto': 'Auto-layout selection',\n 'layout.allFill': 'Fill unplaced',\n 'layout.selFill': 'Fill unplaced in selection',\n\n 'tool.more': 'More',\n 'tool.moreHint': 'Undo / redo / layout',\n 'view.menu': 'View',\n 'view.menuHint': 'Zoom, fit, grid',\n\n 'ctx.ariaNode': 'Node actions',\n 'ctx.ariaWire': 'Wire actions',\n 'ctx.ariaElement': 'Element actions',\n 'ctx.rotate': 'Rotate 90°',\n 'ctx.rotateHint': 'Rotate selection clockwise; wires re-route through new terminals',\n 'ctx.mirror': 'Mirror horizontally',\n 'ctx.mirrorTitle': 'Mirror',\n 'ctx.mirrorHint': 'Flip selection left-right',\n 'ctx.delete': 'Delete',\n 'ctx.deleteHintNode': 'Disconnect every wire on this node (elements stay)',\n 'ctx.deleteHintWire': 'Remove only this wire (siblings on the same node stay)',\n 'ctx.deleteHintElement': 'Remove the selection and its wires',\n 'ctx.resetWirePath': 'Reset to auto-route',\n 'ctx.resetWirePathHint': 'Drop manual corners and let the router re-draw this wire',\n\n 'menu.undo': 'Undo',\n 'menu.redo': 'Redo',\n 'menu.cut': 'Cut',\n 'menu.copy': 'Copy',\n 'menu.paste': 'Paste',\n 'menu.rotate': 'Rotate 90°',\n 'menu.mirror': 'Mirror',\n 'menu.selectAll': 'Select all',\n 'menu.disconnect': 'Disconnect this wire',\n 'menu.delete': 'Delete',\n\n 'io.parseFailed': 'JSON parse failed: {err}',\n 'io.notObject': 'File is not a JSON object',\n 'io.versionMismatch': 'Version mismatch: expected \"1\", got {actual}',\n 'io.elementsMissing': '`elements` is missing or not an array',\n\n 'compile.duplicateId': 'Duplicate element id: \"{id}\"',\n 'compile.unknownKind': 'Unknown element kind=\"{kind}\"',\n 'compile.invalidTermRef': 'Invalid terminal reference \"{ref}\"',\n 'compile.elementMissing': 'Reference to unknown element \"{id}\"',\n 'compile.missingPin': 'Element \"{id}\" (kind={kind}) has no pin \"{pin}\"; available: {available}',\n 'compile.singleTerminal': 'Node has only one terminal — ignored',\n 'compile.layoutMissingElement': 'layout key \"{id}\" references an unknown element',\n 'compile.elementUnconnected': 'Element \"{id}\" has no connections',\n\n 'cat.busbar': 'Busbar / wiring',\n 'cat.switching': 'Switching',\n 'cat.protection': 'Protection',\n 'cat.motor-control': 'Motor control',\n 'cat.transformer': 'Transformer',\n 'cat.instrument-transformer': 'Instrument transformer',\n 'cat.measurement': 'Measurement',\n 'cat.source': 'Source',\n 'cat.load': 'Load',\n 'cat.storage': 'Storage',\n 'cat.compensation': 'Compensation',\n 'cat.grounding': 'Grounding',\n 'cat.renewable': 'Renewables / power electronics',\n\n 'onboard.title': 'Quick start',\n 'onboard.step1.title': 'Draw a busbar',\n 'onboard.step1.body': 'Pick the busbar tool (B), then press and drag on the canvas',\n 'onboard.step2.title': 'Drag elements from the bus',\n 'onboard.step2.body': 'Switch to Place (P), pick a kind, then drag from the bus — it auto-connects',\n 'onboard.step3.title': 'Chain the next one',\n 'onboard.step3.body': 'Drag from any terminal — the new element drops pre-connected',\n 'onboard.dismiss': 'Got it',\n },\n} as const;\n\nexport type Locale = keyof typeof messages;\nexport type LocaleKey = keyof (typeof messages)['zh'];\n","/**\n * Tiny i18n primitive — Zustand-backed locale + key-based translation.\n *\n * Mirrors `usePanels` / `useTheme` patterns: a single store, localStorage\n * persistence, and a `useT()` hook for components plus a non-hook `t()`\n * for code outside React (compiler/file-io error messages).\n *\n * Substitution: `{name}` in a template is replaced with `params[name]`.\n */\n\nimport { create } from 'zustand';\nimport { messages, type Locale, type LocaleKey } from './messages';\n\nexport type { Locale, LocaleKey };\n\nconst STORAGE_KEY = 'ole-locale';\n\nfunction readInitial(): Locale {\n if (typeof window === 'undefined') return 'zh';\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (raw === 'zh' || raw === 'en') return raw;\n } catch {\n // ignore\n }\n if (typeof navigator !== 'undefined' && typeof navigator.language === 'string') {\n return navigator.language.toLowerCase().startsWith('zh') ? 'zh' : 'en';\n }\n return 'zh';\n}\n\nfunction persist(loc: Locale): void {\n try {\n window.localStorage.setItem(STORAGE_KEY, loc);\n } catch {\n // ignore quota / disabled storage\n }\n}\n\ninterface LocaleState {\n locale: Locale;\n setLocale: (loc: Locale) => void;\n toggle: () => void;\n}\n\nexport const useLocale = create<LocaleState>((set, get) => ({\n locale: readInitial(),\n setLocale: (locale) => {\n persist(locale);\n set({ locale });\n },\n toggle: () => {\n const next = get().locale === 'zh' ? 'en' : 'zh';\n persist(next);\n set({ locale: next });\n },\n}));\n\ntype Params = Record<string, string | number>;\n\nfunction format(tmpl: string, params?: Params): string {\n if (!params) return tmpl;\n return tmpl.replace(/\\{(\\w+)\\}/g, (_, k: string) =>\n params[k] !== undefined ? String(params[k]) : `{${k}}`,\n );\n}\n\nfunction lookup(locale: Locale, key: LocaleKey): string {\n return messages[locale][key] ?? messages.zh[key] ?? key;\n}\n\n/** Translate from a non-React context. Reads the current locale from the store. */\nexport function t(key: LocaleKey, params?: Params): string {\n return format(lookup(useLocale.getState().locale, key), params);\n}\n\n/** Hook for components: returns a translator bound to the current locale. */\nexport function useT(): (key: LocaleKey, params?: Params) => string {\n const locale = useLocale((s) => s.locale);\n return (key, params) => format(lookup(locale, key), params);\n}\n","const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...args) => api.dispatch(...args), ...initial };\n};\nconst redux = reduxImpl;\n\nconst shouldDispatchFromDevtools = (api) => !!api.dispatchFromDevtools && typeof api.dispatch === \"function\";\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api) return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst removeStoreFromTrackedConnections = (name, store) => {\n if (store === void 0) return;\n const connectionInfo = trackedConnections.get(name);\n if (!connectionInfo) return;\n delete connectionInfo.stores[store];\n if (Object.keys(connectionInfo.stores).length === 0) {\n trackedConnections.delete(name);\n }\n};\nconst v8StackLineRe = /.+ (.+) .+/;\nconst geckoStackLineRe = /^([^@]+)@/;\nfunction findCallerName(stack) {\n var _a, _b, _c;\n if (!stack) return void 0;\n const traceLines = stack.split(\"\\n\");\n const apiSetStateLineIndex = traceLines.findIndex(\n (traceLine) => traceLine.includes(\"api.setState\")\n );\n if (apiSetStateLineIndex < 0) return void 0;\n const callerLine = ((_a = traceLines[apiSetStateLineIndex + 1]) == null ? void 0 : _a.trim()) || \"\";\n return ((_b = v8StackLineRe.exec(callerLine)) == null ? void 0 : _b[1]) || ((_c = geckoStackLineRe.exec(callerLine)) == null ? void 0 : _c[1]);\n}\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = ((state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording) return r;\n const action = nameOrAction === void 0 ? {\n type: anonymousActionType || findCallerName(new Error().stack) || \"anonymous\"\n } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n });\n api.devtools = {\n cleanup: () => {\n if (connection && typeof connection.unsubscribe === \"function\") {\n connection.unsubscribe();\n }\n removeStoreFromTrackedConnections(options.name, store);\n }\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (shouldDispatchFromDevtools(api)) {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...args) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && args[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...args);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format.\n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (shouldDispatchFromDevtools(api)) {\n api.dispatch(action);\n }\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState) return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, fn) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0) fn(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = ((selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n });\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nfunction combine(initialState, create) {\n return (...args) => Object.assign({}, initialState, create(...args));\n}\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(name, JSON.stringify(newValue, options == null ? void 0 : options.replacer)),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst persistImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => window.localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n let hydrationVersion = 0;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n return setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n return setItem();\n },\n get,\n api\n );\n api.getInitialState = () => configResult;\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage) return;\n const currentVersion = ++hydrationVersion;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n const migration = options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n if (migration instanceof Promise) {\n return migration.then((result) => [true, result]);\n }\n return [true, migration];\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return [false, deserializedStorageValue.state];\n }\n }\n return [false, void 0];\n }).then((migrationResult) => {\n var _a2;\n if (currentVersion !== hydrationVersion) {\n return;\n }\n const [migrated, migratedState] = migrationResult;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n if (migrated) {\n return setItem();\n }\n }).then(() => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(get(), void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n if (currentVersion !== hydrationVersion) {\n return;\n }\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persist = persistImpl;\n\nfunction ssrSafe(config, isSSR = typeof window === \"undefined\") {\n return (set, get, api) => {\n if (!isSSR) {\n return config(set, get, api);\n }\n const ssrSet = () => {\n throw new Error(\"Cannot set state of Zustand store in SSR\");\n };\n api.setState = ssrSet;\n return config(ssrSet, get, api);\n };\n}\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector, ssrSafe as unstable_ssrSafe };\n","/**\n * Wire path normalization. The Wire.path field accepts any polyline, but\n * the editor's invariants assume the path is orthogonal (segments are H or V)\n * and free of redundant points. This module enforces those invariants.\n *\n * normalizePath is called from `store.updateWirePath` (so user edits stay\n * clean) and from the compiler when materializing a Wire.path into a\n * WireRender (so legacy / persisted dirty paths render correctly).\n *\n * Operations:\n * - drop consecutive duplicates\n * - insert an L-corner on any diagonal segment (vertical-first, matching\n * the auto-router's convention)\n * - collapse collinear interior points (three points sharing an x or y)\n */\n\ntype Pt = [number, number];\n\nconst EPS = 0.5;\n\nexport function normalizePath(path: readonly Pt[]): Pt[] {\n if (path.length < 2) return path.map((p) => [p[0], p[1]] as Pt);\n\n // Step 1: dedupe consecutive coincident points.\n const dedup: Pt[] = [[path[0][0], path[0][1]]];\n for (let i = 1; i < path.length; i++) {\n const last = dedup[dedup.length - 1];\n if (Math.abs(last[0] - path[i][0]) < EPS && Math.abs(last[1] - path[i][1]) < EPS) continue;\n dedup.push([path[i][0], path[i][1]]);\n }\n if (dedup.length < 2) return dedup;\n\n // Step 2: turn any diagonal segment into an L-corner. The first leg goes\n // along the prior axis (so corners feel like continuations of the\n // previous segment); fall back to vertical-first when there's no prior\n // segment (matches `auto-route.ts:orthogonalPath`).\n const orthog: Pt[] = [dedup[0]];\n for (let i = 1; i < dedup.length; i++) {\n const prev = orthog[orthog.length - 1];\n const cur = dedup[i];\n const dx = Math.abs(prev[0] - cur[0]);\n const dy = Math.abs(prev[1] - cur[1]);\n if (dx > EPS && dy > EPS) {\n const priorAxis: 'h' | 'v' | null =\n orthog.length >= 2\n ? Math.abs(orthog[orthog.length - 2][1] - prev[1]) < EPS\n ? 'h'\n : 'v'\n : null;\n const corner: Pt =\n priorAxis === 'h' ? [cur[0], prev[1]] : [prev[0], cur[1]];\n orthog.push(corner);\n }\n orthog.push(cur);\n }\n\n // Step 3: drop interior points that lie on the line between their\n // neighbors (same x for both neighbor segments, or same y).\n const out: Pt[] = [orthog[0]];\n for (let i = 1; i < orthog.length - 1; i++) {\n const prev = out[out.length - 1];\n const cur = orthog[i];\n const next = orthog[i + 1];\n const sameX = Math.abs(prev[0] - cur[0]) < EPS && Math.abs(cur[0] - next[0]) < EPS;\n const sameY = Math.abs(prev[1] - cur[1]) < EPS && Math.abs(cur[1] - next[1]) < EPS;\n if (sameX || sameY) continue;\n out.push(cur);\n }\n out.push(orthog[orthog.length - 1]);\n return out;\n}\n","/**\n * Runtime-only model (`InternalModel`) — what the renderer consumes. Compiled\n * from `DiagramFile`; never serialized. Indexed for O(1) per-element lookup.\n */\n\nimport type {\n Bus,\n BusId,\n Element,\n ElementId,\n LibraryEntry,\n NodeId,\n Orientation,\n Placement,\n TerminalRef,\n WireEnd,\n} from '../model';\n\n/** Element + the resolved library record for its `kind`. */\nexport interface ResolvedElement {\n element: Element;\n /** Undefined if `kind` is unknown to the library — render as placeholder. */\n libraryDef?: LibraryEntry;\n}\n\n/** Placement after defaults applied (rot=0, mirror=false). Devices only. */\nexport interface ResolvedPlacement {\n at: [number, number];\n rot: 0 | 90 | 180 | 270;\n mirror: boolean;\n}\n\n/** Bus geometry resolved at compile time. `axis` derived from `rot`. */\nexport interface BusGeometry {\n at: [number, number];\n span: number;\n rot: 0 | 90 | 180 | 270;\n axis: 'x' | 'y';\n}\n\nexport interface ResolvedBus {\n bus: Bus;\n geometry: BusGeometry;\n}\n\nexport interface TerminalGeometry {\n ref: TerminalRef;\n elementId: ElementId;\n pin: string;\n /** Canvas coordinates (after rot/mirror/translate). */\n world: [number, number];\n /** Cardinal direction the terminal exits in canvas frame. */\n orientation: Orientation;\n}\n\nexport interface ConnectivityNode {\n id: NodeId;\n /** Mixed: device terminal refs (`X.Y`) and bare bus ids (`X`). */\n terminals: WireEnd[];\n}\n\n/** Compile-time issue. Non-fatal; renderer keeps drawing. */\nexport interface Diagnostic {\n /** Stable code (`E001`..`W999`). */\n code: string;\n severity: 'error' | 'warning';\n message: string;\n /** JSON Pointer pointing into the source DiagramFile, when applicable. */\n pointer?: string;\n}\n\n/**\n * Per-wire rendered path. One polyline per visible wire in the diagram.\n * Selection / hit-test / user-route override all key on `wireId`.\n */\nexport interface WireRender {\n wireId: import('../model').WireId;\n path: [number, number][];\n /** True if this came from `Wire.path` (user-edited); false = auto-routed. */\n userEdited?: boolean;\n}\n\nexport interface InternalModel {\n elements: Map<ElementId, ResolvedElement>;\n buses: Map<BusId, ResolvedBus>;\n terminals: Map<TerminalRef, TerminalGeometry>;\n nodes: Map<NodeId, ConnectivityNode>;\n layout: Map<ElementId, ResolvedPlacement>;\n /** Rendered polyline per wire id. */\n wireRenders: Map<import('../model').WireId, WireRender>;\n terminalToNode: Map<WireEnd, NodeId>;\n elementToTerminals: Map<ElementId, TerminalRef[]>;\n diagnostics: Diagnostic[];\n}\n\nexport function emptyInternalModel(): InternalModel {\n return {\n elements: new Map(),\n buses: new Map(),\n terminals: new Map(),\n nodes: new Map(),\n layout: new Map(),\n wireRenders: new Map(),\n terminalToNode: new Map(),\n elementToTerminals: new Map(),\n diagnostics: [],\n };\n}\n\nexport function resolvePlacement(p?: Placement): ResolvedPlacement {\n return {\n at: p?.at ?? [0, 0],\n rot: p?.rot ?? 0,\n mirror: p?.mirror ?? false,\n };\n}\n\nexport function busAxisFromRot(rot: 0 | 90 | 180 | 270): 'x' | 'y' {\n return rot === 90 || rot === 270 ? 'y' : 'x';\n}\n","/**\n * Geometric transforms for placing library-local coordinates onto the canvas.\n * Order applied to a local point: mirror (about y-axis) → rotate → translate.\n * The same convention drives ElementLayer's SVG `transform` attribute, so\n * SVG output and computed terminal coords stay in sync.\n */\n\nimport type { Orientation } from '../model';\nimport type { ResolvedPlacement } from './internal-model';\n\nexport function transformPoint(\n local: [number, number],\n p: ResolvedPlacement,\n): [number, number] {\n let [x, y] = local;\n if (p.mirror) x = -x;\n switch (p.rot) {\n case 0:\n break;\n case 90:\n [x, y] = [-y, x];\n break;\n case 180:\n [x, y] = [-x, -y];\n break;\n case 270:\n [x, y] = [y, -x];\n break;\n }\n return [x + p.at[0], y + p.at[1]];\n}\n\nconst ROT_NEXT: Record<Orientation, Orientation> = {\n n: 'e',\n e: 's',\n s: 'w',\n w: 'n',\n};\n\nconst MIRROR_X: Record<Orientation, Orientation> = {\n n: 'n',\n s: 's',\n e: 'w',\n w: 'e',\n};\n\nexport function transformOrientation(\n o: Orientation,\n p: ResolvedPlacement,\n): Orientation {\n let cur: Orientation = p.mirror ? MIRROR_X[o] : o;\n const steps = (p.rot / 90) | 0;\n for (let i = 0; i < steps; i++) cur = ROT_NEXT[cur];\n return cur;\n}\n\n/** Unit vector pointing the way an exit-line should leave a terminal. */\nexport function orientationVec(o: Orientation): [number, number] {\n switch (o) {\n case 'n':\n return [0, -1];\n case 's':\n return [0, 1];\n case 'e':\n return [1, 0];\n case 'w':\n return [-1, 0];\n }\n}\n","/**\n * Tiny Union-Find (disjoint set) keyed by string. Used to merge `connections`\n * into ConnectivityNode equivalence classes.\n */\nexport class UnionFind<K> {\n private parent = new Map<K, K>();\n private rank = new Map<K, number>();\n\n add(k: K): void {\n if (!this.parent.has(k)) {\n this.parent.set(k, k);\n this.rank.set(k, 0);\n }\n }\n\n find(k: K): K {\n this.add(k);\n let cur = k;\n while (this.parent.get(cur) !== cur) {\n const p = this.parent.get(cur)!;\n const gp = this.parent.get(p)!;\n this.parent.set(cur, gp);\n cur = gp;\n }\n return cur;\n }\n\n union(a: K, b: K): void {\n const ra = this.find(a);\n const rb = this.find(b);\n if (ra === rb) return;\n const da = this.rank.get(ra)!;\n const db = this.rank.get(rb)!;\n if (da < db) this.parent.set(ra, rb);\n else if (da > db) this.parent.set(rb, ra);\n else {\n this.parent.set(rb, ra);\n this.rank.set(ra, da + 1);\n }\n }\n\n /** Group all known keys by their representative. Insertion order preserved. */\n groups(): Map<K, K[]> {\n const out = new Map<K, K[]>();\n for (const k of this.parent.keys()) {\n const root = this.find(k);\n const arr = out.get(root);\n if (arr) arr.push(k);\n else out.set(root, [k]);\n }\n return out;\n }\n}\n","/**\n * Best-effort placement for elements lacking a `Placement` in the diagram.\n *\n * Strategy (hierarchy-aware):\n * 1. Identify \"linkers\" — elements connecting ≥2 distinct buses. Three\n * passes: (a) direct bus tap (the element is an electrical-node co-\n * member of ≥2 buses); (b) transitive BFS for category='transformer'\n * elements wired through chains of switches — the BFS finds *all*\n * reachable buses, so a transformer feeding two parallel HV bars\n * (BI + BII via a Y of disconnectors) registers as a 3-bus linker;\n * (c) breakers that bridge two buses through chains with no\n * transformer in path are flagged as horizontal linkers (bus\n * ties / couplers).\n * 2. Tier assignment via BFS from source-tapped buses. Vertical linkers\n * (transformers) step a level; horizontal linkers (bus ties) keep\n * the level unchanged so same-voltage buses share a Y. Disconnected\n * buses fall into an orphan tier at the bottom.\n * 3. Bottom-up bus span propagation. Each bus's span = max(BUS_MIN_SPAN,\n * total slot width + edge margin). Tap slots that stand in for a\n * downstream bus (vertical linker chain head, or the linker itself\n * for direct-tap) claim the child bus's span + spacing.\n * 4. Tier-walking placement: at each level pick the Y from previous\n * level + max parent-child gap; pick each bus's X (root → default\n * or sibling-spread; non-root → midpoint of all parent linkers'\n * chain-head X, so a 3-bus child naturally lands between its\n * upstream parents); distribute the bus's taps with slot ordering\n * biased by `tapPreferredX`; place vertical linkers (anchored to\n * the upper-side chain heads' midpoint, with Y-junction chain\n * alignment so the chain between merge node and linker sits cleanly\n * on the linker's column); place horizontal linkers (rotated\n * 90°/270° between the two same-level buses).\n * 5. Resolve electrical nodes via union-find. For each node with placed\n * and unplaced members, vote on an anchor (placed pin most directly\n * co-referenced) and lay out the remaining elements as parallel\n * branches perpendicular to the anchor's exit. Iterate to a fixpoint\n * so multi-step chains terminate on a real anchor instead of being\n * routed back across a bus.\n * 6. Anything still unplaced falls back to a grid in the lower-right.\n *\n * All resolved positions are snapped to a 10px grid so subsequent user\n * drags don't introduce sub-grid jitter.\n */\n\nimport type {\n Bus,\n BusId,\n Element,\n ElementId,\n LibraryEntry,\n Orientation,\n TerminalRef,\n Wire,\n WireEnd,\n} from '../model';\nimport {\n busAxisFromRot,\n type BusGeometry,\n type ResolvedPlacement,\n} from './internal-model';\nimport { orientationVec, transformOrientation, transformPoint } from './transforms';\nimport { UnionFind } from './union-find';\n\nconst ORIENT_CYCLE: readonly Orientation[] = ['n', 'e', 's', 'w'];\nconst OPPOSITE_ORIENT: Record<Orientation, Orientation> = {\n n: 's',\n s: 'n',\n e: 'w',\n w: 'e',\n};\n\nfunction rotationToAlignOrient(\n localO: Orientation,\n worldO: Orientation,\n): 0 | 90 | 180 | 270 {\n const li = ORIENT_CYCLE.indexOf(localO);\n const wi = ORIENT_CYCLE.indexOf(worldO);\n const steps = ((wi - li) % 4 + 4) % 4;\n return [0, 90, 180, 270][steps] as 0 | 90 | 180 | 270;\n}\n\ninterface AutoLayoutInput {\n /** Devices only. Buses are in `buses`. */\n elements: Element[];\n buses: Bus[];\n wires: Wire[];\n library: ReadonlyMap<string, LibraryEntry>;\n userLayout: ReadonlyMap<ElementId, ResolvedPlacement>;\n userBusLayout: ReadonlyMap<BusId, BusGeometry>;\n}\n\nexport interface AutoLayoutOutput {\n devices: Map<ElementId, ResolvedPlacement>;\n buses: Map<BusId, BusGeometry>;\n}\n\nconst BUS_X = 320;\nconst BUS_Y0 = 220;\nconst MIN_BUS_GAP_Y = 260;\nconst DEFAULT_BUS_SPAN = 720;\nconst CHAIN_GAP = 30;\n// Distance from a bus line to the first chain element's pin.\nconst BUS_TAP_OFFSET = 30;\nconst MIN_TAP_SPACING = 80;\nconst GRID = 10;\nconst FALLBACK_GRID_X0 = 60;\nconst FALLBACK_GRID_Y0 = 520;\nconst FALLBACK_GRID_DX = 80;\nconst FALLBACK_GRID_DY = 80;\nconst FALLBACK_GRID_COLS = 8;\n\nconst SOURCE_CATEGORIES = new Set(['source', 'renewable']);\n\ninterface BusAttachment {\n busId: BusId;\n pin: string;\n}\n\ninterface LinkerInfo {\n elementId: ElementId;\n attachments: BusAttachment[];\n orientation: 'vertical' | 'horizontal';\n}\n\nexport function autoLayout(input: AutoLayoutInput): AutoLayoutOutput {\n const { elements, buses: busList, wires, library, userLayout, userBusLayout } = input;\n\n const layout = new Map<ElementId, ResolvedPlacement>(userLayout);\n const busLayout = new Map<BusId, BusGeometry>(userBusLayout);\n\n const elementById = new Map<ElementId, Element>();\n for (const el of elements) elementById.set(el.id, el);\n const busById = new Map<BusId, Bus>();\n for (const b of busList) busById.set(b.id, b);\n\n const libOf = (id: ElementId): LibraryEntry | undefined => {\n const el = elementById.get(id);\n if (!el) return undefined;\n return library.get(el.kind);\n };\n\n const busIds = new Set<BusId>(busList.map((b) => b.id));\n const isBus = (end: WireEnd): boolean => busIds.has(end);\n\n // ---- 0. Union-find on wires → electrical nodes ------------------------\n // Members of a node are a mix of `TerminalRef` (\"X.Y\", device pins) and\n // bare bus ids (\"X\", hyperedge nodes).\n const uf = new UnionFind<WireEnd>();\n for (const w of wires) {\n uf.add(w.ends[0]);\n uf.add(w.ends[1]);\n uf.union(w.ends[0], w.ends[1]);\n }\n for (const el of elements) {\n const lib = library.get(el.kind);\n if (!lib) continue;\n for (const t of lib.terminals) uf.add(`${el.id}.${t.id}` as TerminalRef);\n }\n for (const bus of busList) uf.add(bus.id);\n\n const nodeGroups: WireEnd[][] = [];\n for (const [, members] of uf.groups()) {\n if (members.length >= 2) nodeGroups.push(members);\n }\n\n // For each end, the single node it belongs to (wrapped in the outer\n // array so iteration shape matches the legacy `[][]` form). `g.length\n // >= 3` then means \"merge node\" exactly as before.\n const pinToGroups = new Map<WireEnd, WireEnd[][]>();\n for (const group of nodeGroups) {\n for (const m of group) pinToGroups.set(m, [group]);\n }\n\n // Per-bus tap list: for each bus, the other members of its electrical\n // node. Picked up by stage 1 (linker detection), stage 4 (root buses),\n // and the bus-span / tap-distribution passes.\n const effectiveTaps = new Map<BusId, WireEnd[]>();\n for (const group of nodeGroups) {\n const busMembers = group.filter(isBus);\n if (busMembers.length === 0) continue;\n for (const busMember of busMembers) {\n const others = group.filter((m) => m !== busMember);\n const arr = effectiveTaps.get(busMember) ?? [];\n arr.push(...others);\n effectiveTaps.set(busMember, arr);\n }\n }\n\n // ---- 1. Detect linker elements (in node-co-membership with ≥2 buses) ---\n const tapsByElement = new Map<ElementId, BusAttachment[]>();\n for (const group of nodeGroups) {\n const busMembers = group.filter(isBus);\n if (busMembers.length === 0) continue;\n for (const end of group) {\n if (isBus(end)) continue;\n const dot = end.indexOf('.');\n if (dot < 0) continue;\n const elId = end.slice(0, dot);\n const pin = end.slice(dot + 1);\n const arr = tapsByElement.get(elId) ?? [];\n for (const busId of busMembers) {\n if (!arr.some((a) => a.busId === busId && a.pin === pin)) {\n arr.push({ busId, pin });\n }\n }\n tapsByElement.set(elId, arr);\n }\n }\n const linkers: LinkerInfo[] = [];\n // `linkerIds` holds only vertical linkers — those with explicit cross-tier\n // placement in stage 5. Horizontal linkers (bus ties) flow through stage\n // 4/6 like any chain element and stay out of this set so stage 6 picks\n // them up as regular branches.\n const linkerIds = new Set<ElementId>();\n for (const [elId, attachments] of tapsByElement) {\n const distinctBuses = new Set(attachments.map((a) => a.busId));\n if (distinctBuses.size >= 2) {\n const orientation: 'vertical' | 'horizontal' =\n library.get(elementById.get(elId)?.kind ?? '')?.category === 'transformer'\n ? 'vertical'\n : 'horizontal';\n linkers.push({ elementId: elId, attachments, orientation });\n if (orientation === 'vertical') linkerIds.add(elId);\n }\n }\n\n // ---- 1b. Transitive linker detection for transformer-family elements ---\n // The direct check above only catches elements *directly* sharing a node\n // with two buses. Most fixtures actually wire transformers through a\n // chain of switches/breakers (T1.t1 → QF → QS → B1), so T1 looks like a\n // single-bus device. We rebuild a per-end connection graph and BFS from\n // each terminal of a candidate transformer, checking reachability to ≥2\n // buses.\n const refAdj = new Map<WireEnd, Set<WireEnd>>();\n const addRefEdge = (a: WireEnd, b: WireEnd) => {\n if (a === b) return;\n if (!refAdj.has(a)) refAdj.set(a, new Set());\n if (!refAdj.has(b)) refAdj.set(b, new Set());\n refAdj.get(a)!.add(b);\n refAdj.get(b)!.add(a);\n };\n for (const w of wires) {\n addRefEdge(w.ends[0], w.ends[1]);\n }\n // Treat each device as a passthrough between its terminals so BFS can\n // walk QF.t1 → QF.t2 (different wires but same physical device) on its\n // way to the next bus.\n for (const el of elements) {\n const lib = library.get(el.kind);\n if (!lib || lib.terminals.length < 2) continue;\n const refs = lib.terminals.map(\n (t) => `${el.id}.${t.id}` as TerminalRef,\n );\n for (let i = 0; i < refs.length; i++) {\n for (let j = i + 1; j < refs.length; j++) {\n addRefEdge(refs[i], refs[j]);\n }\n }\n }\n\n for (const el of elements) {\n if (linkerIds.has(el.id)) continue;\n const lib = library.get(el.kind);\n if (!lib || lib.category !== 'transformer') continue;\n if (lib.terminals.length < 2) continue;\n\n const myRefs = lib.terminals.map(\n (t) => `${el.id}.${t.id}` as TerminalRef,\n );\n // pin -> ALL reachable buses (not just first). Crucial for 3-bus\n // configurations like a transformer whose HV side reaches two parallel\n // 220 kV bars (BI + BII) through a Y of disconnectors.\n const busesPerPin = new Map<string, Set<BusId>>();\n for (const startRef of myRefs) {\n const startPin = startRef.slice(el.id.length + 1);\n busesPerPin.set(startPin, new Set());\n const forbidden = new Set<WireEnd>(myRefs.filter((r) => r !== startRef));\n const visited = new Set<WireEnd>([startRef]);\n const queue: WireEnd[] = [startRef];\n while (queue.length > 0) {\n const cur = queue.shift()!;\n if (isBus(cur)) {\n busesPerPin.get(startPin)!.add(cur);\n // Don't expand bus further — every bus reachable, not other taps.\n continue;\n }\n const neighbors = refAdj.get(cur);\n if (!neighbors) continue;\n for (const nb of neighbors) {\n if (visited.has(nb) || forbidden.has(nb)) continue;\n visited.add(nb);\n queue.push(nb);\n }\n }\n }\n const distinctBuses = new Set<BusId>();\n for (const buses of busesPerPin.values()) {\n for (const b of buses) distinctBuses.add(b);\n }\n if (distinctBuses.size >= 2) {\n const attachments: BusAttachment[] = [];\n for (const [pin, buses] of busesPerPin) {\n for (const busId of buses) attachments.push({ busId, pin });\n }\n linkers.push({ elementId: el.id, attachments, orientation: 'vertical' });\n linkerIds.add(el.id);\n }\n }\n\n // ---- 1b'. Reclassify direct-tap horizontal linkers as vertical --------\n // Stage 1 defaults non-transformer direct-tap linkers to 'horizontal',\n // which suits a true bus tie between same-voltage bars. But the same\n // structure appears in the common main-panel-feeding-subpanel case (a\n // breaker directly tapped to both the main bus and the subpanel bus),\n // where the relationship is hierarchical, not lateral.\n //\n // Heuristic: if exactly one of the linker's buses can reach a source\n // element WITHOUT traversing this linker, the linker is a feeder\n // (vertical) — the stranded bus is downstream. If both sides are\n // independently sourced, it's a real bus tie and stays horizontal.\n const reachesSourceBypassing = (\n startBusId: BusId,\n linkerId: ElementId,\n ): boolean => {\n const linkerLib = libOf(linkerId);\n const blocked: WireEnd[] = linkerLib\n ? linkerLib.terminals.map((t) => `${linkerId}.${t.id}` as TerminalRef)\n : [];\n const startRef = startBusId as WireEnd;\n const visited = new Set<WireEnd>([startRef, ...blocked]);\n const queue: WireEnd[] = [startRef];\n while (queue.length > 0) {\n const cur = queue.shift()!;\n const dot = cur.indexOf('.');\n if (dot > 0) {\n const elemId = cur.slice(0, dot);\n const el = elementById.get(elemId);\n if (el) {\n const cat = library.get(el.kind)?.category;\n if (cat && SOURCE_CATEGORIES.has(cat)) return true;\n }\n }\n const neighbors = refAdj.get(cur);\n if (!neighbors) continue;\n for (const nb of neighbors) {\n if (visited.has(nb)) continue;\n visited.add(nb);\n queue.push(nb);\n }\n }\n return false;\n };\n\n for (const link of linkers) {\n if (link.orientation !== 'horizontal') continue;\n const busesInLink = new Set(link.attachments.map((a) => a.busId));\n let reachable = 0;\n for (const bid of busesInLink) {\n if (reachesSourceBypassing(bid, link.elementId)) reachable++;\n }\n if (reachable === 1) {\n link.orientation = 'vertical';\n linkerIds.add(link.elementId);\n }\n }\n\n // ---- 1c. Transitive horizontal-linker detection (bus-tie breakers) -----\n // A breaker bridging two buses through chains on each side — without a\n // transformer in either chain — is a bus tie / bus coupler. Detection is\n // restricted to kind='breaker' to avoid flooding the linker set with every\n // disconnector in a chain.\n for (const el of elements) {\n if (linkerIds.has(el.id)) continue;\n if (el.kind !== 'breaker') continue;\n const lib = library.get(el.kind);\n if (!lib || lib.terminals.length !== 2) continue;\n\n const myRefs = lib.terminals.map(\n (t) => `${el.id}.${t.id}` as TerminalRef,\n );\n const busPerPin = new Map<string, BusId>();\n\n for (const startRef of myRefs) {\n const startPin = startRef.slice(el.id.length + 1);\n const forbidden = new Set<WireEnd>(myRefs.filter((r) => r !== startRef));\n const visited = new Set<WireEnd>([startRef]);\n const queue: WireEnd[] = [startRef];\n while (queue.length > 0) {\n const cur = queue.shift()!;\n if (isBus(cur)) {\n busPerPin.set(startPin, cur);\n break;\n }\n const neighbors = refAdj.get(cur);\n if (!neighbors) continue;\n for (const nb of neighbors) {\n if (visited.has(nb) || forbidden.has(nb)) continue;\n // Block passthrough through transformers — transformer paths are\n // vertical linkers and don't make this candidate a bus tie.\n const nbDot = nb.indexOf('.');\n if (nbDot > 0) {\n const nbElemId = nb.slice(0, nbDot);\n if (nbElemId !== el.id) {\n const nbEl = elementById.get(nbElemId);\n const nbLib = nbEl ? library.get(nbEl.kind) : undefined;\n if (nbLib?.category === 'transformer') continue;\n }\n }\n visited.add(nb);\n queue.push(nb);\n }\n }\n }\n const distinctBuses = new Set(busPerPin.values());\n if (distinctBuses.size >= 2) {\n const attachments: BusAttachment[] = [];\n for (const [pin, busId] of busPerPin) {\n attachments.push({ busId, pin });\n }\n linkers.push({\n elementId: el.id,\n attachments,\n orientation: 'horizontal',\n });\n // Don't add to linkerIds — horizontal linkers don't have explicit\n // placement; they go through stage 4/6 as ordinary chain elements.\n }\n }\n\n // ---- 2. Topo-order buses ----------------------------------------------\n const busLinks = new Map<BusId, Map<BusId, LinkerInfo>>();\n for (const b of busList) busLinks.set(b.id, new Map());\n for (const link of linkers) {\n const ids = Array.from(new Set(link.attachments.map((a) => a.busId)));\n for (const a of ids) {\n for (const b of ids) {\n if (a !== b) busLinks.get(a)?.set(b, link);\n }\n }\n }\n\n const isSourceKind = (kind: string): boolean => {\n const cat = library.get(kind)?.category;\n return cat ? SOURCE_CATEGORIES.has(cat) : false;\n };\n\n const rootBuses: BusId[] = [];\n for (const bus of busList) {\n const refs = effectiveTaps.get(bus.id);\n if (!refs) continue;\n for (const ref of refs) {\n if (isBus(ref)) continue;\n const dot = ref.indexOf('.');\n if (dot < 0) continue;\n const otherId = ref.slice(0, dot);\n const otherEl = elementById.get(otherId);\n if (otherEl && isSourceKind(otherEl.kind)) {\n rootBuses.push(bus.id);\n break;\n }\n }\n }\n if (rootBuses.length === 0 && busList.length > 0) rootBuses.push(busList[0].id);\n\n const busLevel = new Map<BusId, number>();\n for (const r of rootBuses) busLevel.set(r, 0);\n {\n const bfsQ: BusId[] = [...rootBuses];\n while (bfsQ.length > 0) {\n const id = bfsQ.shift()!;\n const lvl = busLevel.get(id)!;\n const links = busLinks.get(id);\n if (!links) continue;\n for (const [otherId, link] of links) {\n if (busLevel.has(otherId)) continue;\n const childLevel =\n link.orientation === 'horizontal' ? lvl : lvl + 1;\n busLevel.set(otherId, childLevel);\n bfsQ.push(otherId);\n }\n }\n }\n for (const bus of busList) {\n if (busLevel.has(bus.id)) continue;\n const maxLvl = busLevel.size === 0\n ? -1\n : Math.max(...Array.from(busLevel.values()));\n busLevel.set(bus.id, maxLvl + 1);\n }\n const levelToBuses = new Map<number, BusId[]>();\n for (const bus of busList) {\n const lvl = busLevel.get(bus.id)!;\n const arr = levelToBuses.get(lvl) ?? [];\n arr.push(bus.id);\n levelToBuses.set(lvl, arr);\n }\n const sortedLevels = [...levelToBuses.keys()].sort((a, b) => a - b);\n\n // ---- 3. Chain-extent helper -------------------------------------------\n interface ChainResult {\n extent: number;\n /** The chain element directly tapped to the bus (for X-alignment). */\n head?: ElementId;\n }\n const chainExtentToBus = (\n linker: LinkerInfo,\n busId: BusId,\n pinName: string,\n ): ChainResult => {\n const startRef = `${linker.elementId}.${pinName}` as TerminalRef;\n const targetRef = busId as WireEnd;\n const linkerLib = libOf(linker.elementId);\n const forbidden = new Set<WireEnd>();\n if (linkerLib) {\n for (const t of linkerLib.terminals) {\n if (t.id === pinName) continue;\n forbidden.add(`${linker.elementId}.${t.id}` as TerminalRef);\n }\n }\n const visited = new Set<WireEnd>([startRef]);\n const queue: { ref: WireEnd; dist: number }[] = [\n { ref: startRef, dist: 0 },\n ];\n const parent = new Map<WireEnd, WireEnd>();\n const enqueue = (other: WireEnd, ref: WireEnd, addDist: number, dist: number) => {\n visited.add(other);\n parent.set(other, ref);\n queue.push({ ref: other, dist: dist + addDist });\n };\n while (queue.length > 0) {\n const { ref, dist } = queue.shift()!;\n if (ref === targetRef) {\n const prev = parent.get(targetRef);\n let head: ElementId | undefined;\n if (prev) {\n const d = prev.indexOf('.');\n if (d > 0) {\n const headId = prev.slice(0, d);\n // Direct-tap linker: skip self-as-head so callers fall through\n // to the slot-based fallback (linkerSlotX).\n if (headId !== linker.elementId) head = headId;\n }\n }\n return { extent: dist, head };\n }\n const dot = ref.indexOf('.');\n if (dot < 0) {\n // Bare bus id reached (not the target): don't expand through it.\n continue;\n }\n const elId = ref.slice(0, dot);\n const pin = ref.slice(dot + 1);\n // Passthrough through a non-bus, non-linker element: enqueue its other\n // terminals with the local pin-to-pin distance added.\n if (!isBus(elId) && !linkerIds.has(elId)) {\n const lib = libOf(elId);\n const thisTerm = lib?.terminals.find((t) => t.id === pin);\n if (lib && thisTerm) {\n for (const otherTerm of lib.terminals) {\n if (otherTerm.id === pin) continue;\n const otherRef = `${elId}.${otherTerm.id}` as TerminalRef;\n if (visited.has(otherRef) || forbidden.has(otherRef)) continue;\n enqueue(otherRef, ref, Math.abs(thisTerm.y - otherTerm.y), dist);\n }\n }\n }\n // Cross to other ends via electrical-node membership. Edges incident\n // to a bus end contribute BUS_TAP_OFFSET (the wire stub between bus\n // line and the tap pin); inter-element edges contribute CHAIN_GAP.\n for (const g of pinToGroups.get(ref) ?? []) {\n for (const other of g) {\n if (other === ref) continue;\n if (visited.has(other) || forbidden.has(other)) continue;\n const isBusEdge = isBus(ref) || isBus(other);\n enqueue(other, ref, isBusEdge ? BUS_TAP_OFFSET : CHAIN_GAP, dist);\n }\n }\n }\n return { extent: 0 };\n };\n\n const gapBetween = (idA: BusId, idB: BusId): number => {\n const link = busLinks.get(idA)?.get(idB);\n if (!link || link.orientation === 'horizontal') return MIN_BUS_GAP_Y;\n const linkerLib = libOf(link.elementId);\n if (!linkerLib) return MIN_BUS_GAP_Y;\n const pinAName = link.attachments.find((a) => a.busId === idA)?.pin;\n const pinBName = link.attachments.find((a) => a.busId === idB)?.pin;\n if (!pinAName || !pinBName) return MIN_BUS_GAP_Y;\n const pinA = linkerLib.terminals.find((t) => t.id === pinAName);\n const pinB = linkerLib.terminals.find((t) => t.id === pinBName);\n if (!pinA || !pinB) return MIN_BUS_GAP_Y;\n const pinSpan = Math.abs(pinB.y - pinA.y);\n const upperChain = chainExtentToBus(link, idA, pinAName).extent;\n const lowerChain = chainExtentToBus(link, idB, pinBName).extent;\n return upperChain + pinSpan + lowerChain;\n };\n\n // ---- Linker → upper-bus tap representative ----------------------------\n interface LinkerRep {\n lowerBusId: BusId;\n }\n const linkerUpperRep = new Map<ElementId, LinkerRep>();\n for (const link of linkers) {\n if (link.orientation !== 'vertical') continue;\n const sortedAttachments = link.attachments\n .slice()\n .sort(\n (a, b) => (busLevel.get(a.busId) ?? 0) - (busLevel.get(b.busId) ?? 0),\n );\n if (sortedAttachments.length < 2) continue;\n const upperBusId = sortedAttachments[0].busId;\n const lowerBusId = sortedAttachments[1].busId;\n const upperPin = sortedAttachments[0].pin;\n const result = chainExtentToBus(link, upperBusId, upperPin);\n const repElId = result.head ?? link.elementId;\n linkerUpperRep.set(repElId, { lowerBusId });\n }\n\n // ---- Bottom-up bus span computation -----------------------------------\n const BUS_MIN_SPAN = 320;\n const busSpan = new Map<BusId, number>();\n const isLinkerLowerSide = (\n elId: ElementId,\n busId: BusId,\n ): boolean => {\n if (!linkerIds.has(elId)) return false;\n const link = linkers.find((l) => l.elementId === elId);\n const otherBusAtt = link?.attachments.find((a) => a.busId !== busId);\n if (!otherBusAtt) return false;\n const myLvl = busLevel.get(busId) ?? 0;\n const otherLvl = busLevel.get(otherBusAtt.busId) ?? 0;\n return otherLvl < myLvl;\n };\n const slotWidthFor = (\n elId: ElementId,\n libWidth: number,\n ): number => {\n const rep = linkerUpperRep.get(elId);\n if (rep) {\n const childSpan = busSpan.get(rep.lowerBusId);\n if (childSpan !== undefined) {\n return Math.max(libWidth, childSpan + MIN_TAP_SPACING);\n }\n }\n return Math.max(libWidth, MIN_TAP_SPACING);\n };\n const computeSpan = (busId: BusId, visiting: Set<BusId>): number => {\n if (busSpan.has(busId)) return busSpan.get(busId)!;\n if (visiting.has(busId)) return BUS_MIN_SPAN; // cycle guard\n visiting.add(busId);\n const tapRefs = effectiveTaps.get(busId) ?? [];\n let aboveW = 0;\n let belowW = 0;\n for (const ref of tapRefs) {\n if (isBus(ref)) continue;\n const dot = ref.indexOf('.');\n if (dot < 0) continue;\n const elId = ref.slice(0, dot);\n const pin = ref.slice(dot + 1);\n if (isLinkerLowerSide(elId, busId)) continue;\n const lib = libOf(elId);\n if (!lib) continue;\n const localTerm = lib.terminals.find((t) => t.id === pin);\n if (!localTerm) continue;\n const rep = linkerUpperRep.get(elId);\n if (rep) {\n computeSpan(rep.lowerBusId, visiting);\n }\n const slotW = slotWidthFor(elId, lib.width);\n if (localTerm.y > 0) aboveW += slotW;\n else belowW += slotW;\n }\n const span = Math.max(\n BUS_MIN_SPAN,\n Math.max(aboveW, belowW) + MIN_TAP_SPACING,\n );\n busSpan.set(busId, span);\n visiting.delete(busId);\n return span;\n };\n for (const bus of busList) computeSpan(bus.id, new Set());\n\n // ---- 3-5. Tier-based bus / tap / linker placement ---------------------\n const linkerSlotX = new Map<ElementId, number>();\n\n interface TapEntry {\n elId: ElementId;\n lib: LibraryEntry;\n localTerm: { id: string; x: number; y: number; orientation: Orientation };\n isLinker: boolean;\n }\n\n // Find the X of the closest other-bus that this tap reaches via the\n // electrical-node graph. Returned only if that bus has already been\n // placed.\n const tapPreferredX = (\n busId: BusId,\n tapEl: ElementId,\n tapPin: string,\n ): number | undefined => {\n const tapLib = libOf(tapEl);\n if (!tapLib) return undefined;\n const tapRef = `${tapEl}.${tapPin}` as TerminalRef;\n const startRefs = tapLib.terminals\n .filter((t) => t.id !== tapPin)\n .map((t) => `${tapEl}.${t.id}` as TerminalRef);\n if (startRefs.length === 0) return undefined;\n const visited = new Set<WireEnd>([tapRef, ...startRefs]);\n const queue: WireEnd[] = startRefs.slice();\n while (queue.length > 0) {\n const cur = queue.shift()!;\n if (isBus(cur) && cur !== busId) {\n const geom = busLayout.get(cur);\n return geom ? geom.at[0] : undefined;\n }\n for (const g of pinToGroups.get(cur) ?? []) {\n for (const other of g) {\n if (other === cur || visited.has(other)) continue;\n visited.add(other);\n queue.push(other);\n }\n }\n const dot = cur.indexOf('.');\n if (dot > 0) {\n const elemId = cur.slice(0, dot);\n if (!isBus(elemId)) {\n const lib = libOf(elemId);\n if (lib) {\n for (const t of lib.terminals) {\n const otherRef = `${elemId}.${t.id}` as TerminalRef;\n if (visited.has(otherRef)) continue;\n visited.add(otherRef);\n queue.push(otherRef);\n }\n }\n }\n }\n }\n return undefined;\n };\n\n const distributeBusTaps = (busId: BusId): void => {\n const tapRefs = effectiveTaps.get(busId);\n if (!tapRefs || tapRefs.length === 0) return;\n const geom = busLayout.get(busId);\n if (!geom) return;\n\n const remaining: TapEntry[] = tapRefs.flatMap((ref): TapEntry[] => {\n if (isBus(ref)) return [];\n const dot = ref.indexOf('.');\n if (dot < 0) return [];\n const elId = ref.slice(0, dot);\n const pin = ref.slice(dot + 1);\n if (layout.has(elId)) return [];\n if (isLinkerLowerSide(elId, busId)) return [];\n const lib = libOf(elId);\n if (!lib) return [];\n const localTerm = lib.terminals.find((t) => t.id === pin);\n if (!localTerm) return [];\n return [{ elId, lib, localTerm, isLinker: linkerIds.has(elId) }];\n });\n if (remaining.length === 0) return;\n\n const aboveSide: TapEntry[] = [];\n const belowSide: TapEntry[] = [];\n for (const r of remaining) {\n if (r.localTerm.y > 0) aboveSide.push(r);\n else belowSide.push(r);\n }\n\n const sideTotalWidth = (group: TapEntry[]): number =>\n group.reduce((s, r) => s + slotWidthFor(r.elId, r.lib.width), 0);\n const requiredSpan =\n Math.max(sideTotalWidth(aboveSide), sideTotalWidth(belowSide)) +\n MIN_TAP_SPACING;\n const span = Math.max(geom.span, requiredSpan);\n if (span !== geom.span) {\n busLayout.set(busId, { ...geom, span });\n }\n const finalGeom = busLayout.get(busId)!;\n\n const distribute = (group: TapEntry[], offsetSign: -1 | 1): void => {\n if (group.length === 0) return;\n const prefByEl = new Map<ElementId, number>();\n for (const r of group) {\n const px = tapPreferredX(busId, r.elId, r.localTerm.id);\n if (px !== undefined) prefByEl.set(r.elId, px);\n }\n group.sort((a, b) => {\n const ax = prefByEl.get(a.elId) ?? finalGeom.at[0];\n const bx = prefByEl.get(b.elId) ?? finalGeom.at[0];\n if (ax !== bx) return ax - bx;\n // Same-preference taps: wider slots toward bus center, narrow ones\n // pushed to the extreme. Lets a small bus-tie disconnector land on\n // the actual edge even when a wide transformer-feeding slot wants\n // the same side.\n const aw = slotWidthFor(a.elId, a.lib.width);\n const bw = slotWidthFor(b.elId, b.lib.width);\n return bw - aw;\n });\n const widths = group.map((r) => slotWidthFor(r.elId, r.lib.width));\n const totalW = widths.reduce((s, w) => s + w, 0);\n const usableSpan = Math.max(span, totalW);\n const slotGap = (usableSpan - totalW) / (group.length + 1);\n let cursor = finalGeom.at[0] - usableSpan / 2 + slotGap;\n const tapWorldY = finalGeom.at[1] + offsetSign * BUS_TAP_OFFSET;\n for (let i = 0; i < group.length; i++) {\n const r = group[i];\n const slotW = widths[i];\n const tapWorldX = cursor + slotW / 2;\n if (r.isLinker) {\n if (!linkerSlotX.has(r.elId)) linkerSlotX.set(r.elId, tapWorldX);\n } else {\n layout.set(r.elId, {\n at: [snap(tapWorldX - r.localTerm.x), snap(tapWorldY - r.localTerm.y)],\n rot: 0,\n mirror: false,\n });\n }\n cursor += slotW + slotGap;\n }\n };\n distribute(aboveSide, -1);\n distribute(belowSide, +1);\n };\n\n const placeLinker = (link: LinkerInfo): void => {\n if (layout.has(link.elementId)) return;\n if (link.orientation === 'horizontal') return;\n const linkerLib = libOf(link.elementId);\n if (!linkerLib) return;\n\n const placedAttachments = link.attachments.filter((a) =>\n busLayout.has(a.busId),\n );\n if (placedAttachments.length < 2) return;\n const sorted = placedAttachments.slice().sort(\n (a, b) =>\n (busLevel.get(a.busId) ?? 0) - (busLevel.get(b.busId) ?? 0),\n );\n const upperBusId = sorted[0].busId;\n const upperGeom = busLayout.get(upperBusId)!;\n\n const upperPin = sorted[0].pin;\n const lowerPin = sorted[sorted.length - 1].pin;\n const upperLocal = linkerLib.terminals.find((t) => t.id === upperPin);\n const lowerLocal = linkerLib.terminals.find((t) => t.id === lowerPin);\n if (!upperLocal || !lowerLocal) return;\n\n const rot: 0 | 180 = upperLocal.y <= lowerLocal.y ? 0 : 180;\n\n const upperLevel = busLevel.get(upperBusId) ?? 0;\n const upperSideAttachments = placedAttachments.filter(\n (a) => (busLevel.get(a.busId) ?? 0) === upperLevel,\n );\n const upperHeadXs: number[] = [];\n let maxUpperExtent = 0;\n for (const att of upperSideAttachments) {\n const result = chainExtentToBus(link, att.busId, att.pin);\n maxUpperExtent = Math.max(maxUpperExtent, result.extent);\n const headPlace = result.head ? layout.get(result.head) : undefined;\n if (headPlace) {\n upperHeadXs.push(headPlace.at[0]);\n } else if (linkerSlotX.has(link.elementId)) {\n // Direct-tap linker (no intermediate chain head): use the slot X\n // allocated for it by the upper bus's tap distribution.\n upperHeadXs.push(linkerSlotX.get(link.elementId)!);\n } else {\n upperHeadXs.push(busLayout.get(att.busId)!.at[0]);\n }\n }\n let xCenter: number;\n if (upperHeadXs.length > 0) {\n xCenter =\n upperHeadXs.reduce((s, x) => s + x, 0) / upperHeadXs.length;\n } else if (linkerSlotX.has(link.elementId)) {\n xCenter = linkerSlotX.get(link.elementId)!;\n } else {\n xCenter = upperGeom.at[0];\n }\n const upperPinWorldY = upperGeom.at[1] + maxUpperExtent;\n\n const at: [number, number] =\n rot === 0\n ? [snap(xCenter - upperLocal.x), snap(upperPinWorldY - upperLocal.y)]\n : [snap(xCenter + upperLocal.x), snap(upperPinWorldY + upperLocal.y)];\n layout.set(link.elementId, { at, rot, mirror: false });\n\n if (upperSideAttachments.length > 1) {\n const linkerPlace = layout.get(link.elementId)!;\n const upperPinWorld = transformPoint(\n [upperLocal.x, upperLocal.y],\n linkerPlace,\n );\n const upperWorldOrient = transformOrientation(\n upperLocal.orientation,\n linkerPlace,\n );\n walkChainAlongAxis(\n `${link.elementId}.${upperPin}` as TerminalRef,\n upperPinWorld,\n upperWorldOrient,\n xCenter,\n );\n }\n };\n\n // Walk a single-pin chain starting from `startRef`, heading in the world\n // `startExit` direction. Stops at a merge node (electrical node with 3+\n // members), a bus, a linker, an already-placed element, or no neighbour.\n const walkChainAlongAxis = (\n startRef: TerminalRef,\n startWorld: [number, number],\n startExit: Orientation,\n axisX: number,\n ): void => {\n const visited = new Set<WireEnd>([startRef]);\n let prevRef: WireEnd = startRef;\n let prevWorld = startWorld;\n let prevExit = startExit;\n while (true) {\n const groups = pinToGroups.get(prevRef) ?? [];\n let nextRef: WireEnd | undefined;\n let blocked = false;\n for (const g of groups) {\n if (g.length >= 3) {\n // Multi-pin merge — stop and let auto-route draw the rake.\n blocked = true;\n break;\n }\n const other = g.find((r) => r !== prevRef);\n if (!other || visited.has(other)) continue;\n if (isBus(other)) {\n blocked = true;\n break;\n }\n nextRef = other;\n break;\n }\n if (blocked || !nextRef) break;\n const dot = nextRef.indexOf('.');\n if (dot < 0) break;\n const elId = nextRef.slice(0, dot);\n const pinName = nextRef.slice(dot + 1);\n if (isBus(elId) || linkerIds.has(elId)) break;\n if (layout.has(elId)) break;\n const lib = libOf(elId);\n if (!lib) break;\n const inTerm = lib.terminals.find((t) => t.id === pinName);\n if (!inTerm) break;\n\n const exitVec = orientationVec(prevExit);\n const target: [number, number] = [\n prevWorld[0] + exitVec[0] * CHAIN_GAP,\n prevWorld[1] + exitVec[1] * CHAIN_GAP,\n ];\n const desiredOrient = OPPOSITE_ORIENT[prevExit];\n const rot = rotationToAlignOrient(inTerm.orientation, desiredOrient);\n const rotatedInPin = transformPoint([inTerm.x, inTerm.y], {\n at: [0, 0],\n rot,\n mirror: false,\n });\n const at: [number, number] = [\n snap(axisX - rotatedInPin[0]),\n snap(target[1] - rotatedInPin[1]),\n ];\n layout.set(elId, { at, rot, mirror: false });\n visited.add(nextRef);\n\n const outTerm = lib.terminals.find((t) => t.id !== pinName);\n if (!outTerm) break;\n const outRef = `${elId}.${outTerm.id}` as TerminalRef;\n visited.add(outRef);\n const placement = { at, rot, mirror: false };\n prevWorld = transformPoint([outTerm.x, outTerm.y], placement);\n prevExit = transformOrientation(outTerm.orientation, placement);\n prevRef = outRef;\n }\n };\n\n const placeHorizontalLinker = (link: LinkerInfo): void => {\n if (layout.has(link.elementId)) return;\n if (link.orientation !== 'horizontal') return;\n const linkerLib = libOf(link.elementId);\n if (!linkerLib) return;\n const placed = link.attachments.filter((a) => busLayout.has(a.busId));\n if (placed.length < 2) return;\n\n interface HeadInfo {\n att: BusAttachment;\n x: number;\n extent: number;\n }\n const heads: HeadInfo[] = placed.map((att) => {\n const result = chainExtentToBus(link, att.busId, att.pin);\n const headPlace = result.head ? layout.get(result.head) : undefined;\n const x = headPlace\n ? headPlace.at[0]\n : busLayout.get(att.busId)!.at[0];\n return { att, x, extent: result.extent };\n });\n heads.sort((a, b) => a.x - b.x);\n const left = heads[0];\n const right = heads[heads.length - 1];\n const leftLocal = linkerLib.terminals.find((t) => t.id === left.att.pin);\n const rightLocal = linkerLib.terminals.find((t) => t.id === right.att.pin);\n if (!leftLocal || !rightLocal) return;\n\n const rot: 90 | 270 = leftLocal.y <= rightLocal.y ? 270 : 90;\n\n const xCenter = (left.x + right.x) / 2;\n const busY = busLayout.get(left.att.busId)!.at[1];\n const linkerY = busY + Math.max(left.extent, right.extent);\n\n layout.set(link.elementId, {\n at: [snap(xCenter), snap(linkerY)],\n rot,\n mirror: false,\n });\n };\n\n const SIBLING_X_GAP = 100;\n\n let prevLevelY = BUS_Y0;\n for (let li = 0; li < sortedLevels.length; li++) {\n const lvl = sortedLevels[li];\n const busIdsAtLevel = levelToBuses.get(lvl)!;\n\n let levelY: number;\n if (li === 0) {\n levelY = BUS_Y0;\n } else {\n const prevBusIds = levelToBuses.get(sortedLevels[li - 1])!;\n let maxGap = 0;\n for (const parent of prevBusIds) {\n for (const child of busIdsAtLevel) {\n if (busLinks.get(parent)?.get(child)) {\n maxGap = Math.max(maxGap, gapBetween(parent, child));\n }\n }\n }\n if (maxGap === 0) maxGap = MIN_BUS_GAP_Y;\n levelY = prevLevelY + maxGap;\n }\n prevLevelY = levelY;\n\n let nextSiblingX = BUS_X;\n for (const busId of busIdsAtLevel) {\n if (busLayout.has(busId)) {\n prevLevelY = Math.max(prevLevelY, busLayout.get(busId)!.at[1]);\n continue;\n }\n let busX: number | undefined;\n if (li > 0) {\n const prevBusIds = levelToBuses.get(sortedLevels[li - 1])!;\n const headXs: number[] = [];\n for (const parent of prevBusIds) {\n const link = busLinks.get(parent)?.get(busId);\n if (!link || link.orientation !== 'vertical') continue;\n const parentPin = link.attachments.find(\n (a) => a.busId === parent,\n )?.pin;\n if (!parentPin) continue;\n const result = chainExtentToBus(link, parent, parentPin);\n if (result.head && layout.has(result.head)) {\n headXs.push(layout.get(result.head)!.at[0]);\n } else if (linkerSlotX.has(link.elementId)) {\n headXs.push(linkerSlotX.get(link.elementId)!);\n } else {\n headXs.push(busLayout.get(parent)!.at[0]);\n }\n }\n if (headXs.length > 0) {\n busX = headXs.reduce((s, x) => s + x, 0) / headXs.length;\n }\n }\n if (busX === undefined) {\n const ownSpan = busSpan.get(busId) ?? DEFAULT_BUS_SPAN;\n busX = nextSiblingX + ownSpan / 2;\n nextSiblingX += ownSpan + SIBLING_X_GAP;\n }\n const span = busSpan.get(busId) ?? DEFAULT_BUS_SPAN;\n busLayout.set(busId, {\n at: [snap(busX), snap(levelY)],\n rot: 0,\n span,\n axis: busAxisFromRot(0),\n });\n }\n\n for (const busId of busIdsAtLevel) {\n distributeBusTaps(busId);\n }\n\n if (li > 0) {\n for (const link of linkers) {\n if (layout.has(link.elementId)) continue;\n const involvesThisLevel = link.attachments.some((a) =>\n busIdsAtLevel.includes(a.busId),\n );\n if (!involvesThisLevel) continue;\n placeLinker(link);\n }\n }\n\n for (const link of linkers) {\n if (link.orientation !== 'horizontal') continue;\n if (layout.has(link.elementId)) continue;\n const allHere = link.attachments.every((a) =>\n busIdsAtLevel.includes(a.busId),\n );\n if (!allHere) continue;\n placeHorizontalLinker(link);\n }\n }\n\n // ---- 6. Node-based parallel-branch placement --------------------------\n // For each electrical node with placed and unplaced members, pick the\n // anchor pin by voting on direct co-occurrence with the unplaced cluster,\n // and lay out the remaining elements as parallel branches perpendicular\n // to the anchor's exit. Iterate to a fixpoint so newly-placed elements\n // can anchor further chains.\n const isEndPlaced = (end: WireEnd): boolean => {\n if (isBus(end)) return busLayout.has(end);\n const dot = end.indexOf('.');\n if (dot < 0) return false;\n return layout.has(end.slice(0, dot));\n };\n\n let progressed = true;\n let safety = elements.length + 4;\n while (progressed && safety-- > 0) {\n progressed = false;\n\n for (const node of nodeGroups) {\n if (node.length < 2) continue;\n\n interface UnplacedPinInfo {\n ref: TerminalRef;\n elId: ElementId;\n lib: LibraryEntry;\n localTerm: {\n id: string;\n x: number;\n y: number;\n orientation: Orientation;\n };\n }\n const placedPins: TerminalRef[] = [];\n const unplacedByEl = new Map<ElementId, UnplacedPinInfo>();\n\n for (const end of node) {\n if (isBus(end)) {\n // Bus is a hyperedge node, not an anchor candidate.\n continue;\n }\n const dot = end.indexOf('.');\n if (dot < 0) continue;\n const id = end.slice(0, dot);\n const pinName = end.slice(dot + 1);\n if (layout.has(id)) {\n placedPins.push(end as TerminalRef);\n continue;\n }\n if (linkerIds.has(id)) continue;\n if (unplacedByEl.has(id)) continue;\n const lib = libOf(id);\n if (!lib) continue;\n const localTerm = lib.terminals.find((t) => t.id === pinName);\n if (!localTerm) continue;\n unplacedByEl.set(id, {\n ref: end as TerminalRef,\n elId: id,\n lib,\n localTerm,\n });\n }\n if (unplacedByEl.size === 0 || placedPins.length === 0) continue;\n const unplacedUnique = [...unplacedByEl.values()];\n\n // Vote on anchor: each unplaced pin contributes a vote to every other\n // placed non-bus pin in the same node. Strong winner = the placed pin\n // most directly connected to the unplaced cluster.\n const votes = new Map<TerminalRef, number>();\n for (const u of unplacedUnique) {\n for (const g of pinToGroups.get(u.ref) ?? []) {\n for (const p of g) {\n if (p === u.ref) continue;\n if (isBus(p)) continue;\n if (!isEndPlaced(p)) continue;\n const tref = p as TerminalRef;\n votes.set(tref, (votes.get(tref) ?? 0) + 1);\n }\n }\n }\n\n let anchor: TerminalRef | undefined;\n if (votes.size > 0) {\n let best = -1;\n for (const [p, v] of votes) {\n if (v > best || (v === best && (anchor === undefined || p < anchor))) {\n best = v;\n anchor = p;\n }\n }\n }\n if (!anchor) {\n anchor = [...placedPins].sort()[0];\n }\n if (!anchor) continue;\n\n const dot = anchor.indexOf('.');\n const anchorId = anchor.slice(0, dot);\n const anchorPin = anchor.slice(dot + 1);\n const anchorLib = libOf(anchorId);\n const anchorPlace = layout.get(anchorId);\n if (!anchorLib || !anchorPlace) continue;\n const anchorTerm = anchorLib.terminals.find((t) => t.id === anchorPin);\n if (!anchorTerm) continue;\n\n const anchorWorld = transformPoint(\n [anchorTerm.x, anchorTerm.y],\n anchorPlace,\n );\n const anchorOrient = transformOrientation(\n anchorTerm.orientation,\n anchorPlace,\n );\n const exit = orientationVec(anchorOrient);\n const perp: [number, number] = [-exit[1], exit[0]];\n\n unplacedUnique.sort((a, b) => a.elId.localeCompare(b.elId));\n const widths = unplacedUnique.map((u) =>\n Math.max(u.lib.width, MIN_TAP_SPACING),\n );\n const totalW = widths.reduce((sum, w) => sum + w, 0);\n let cursor = -totalW / 2;\n\n for (let i = 0; i < unplacedUnique.length; i++) {\n const u = unplacedUnique[i];\n const slotW = widths[i];\n const slotCenter = cursor + slotW / 2;\n cursor += slotW;\n\n const desiredOrient = OPPOSITE_ORIENT[anchorOrient];\n const rot = rotationToAlignOrient(\n u.localTerm.orientation,\n desiredOrient,\n );\n const rotatedPin = transformPoint(\n [u.localTerm.x, u.localTerm.y],\n { at: [0, 0], rot, mirror: false },\n );\n const targetWorld: [number, number] = [\n anchorWorld[0] + exit[0] * CHAIN_GAP + perp[0] * slotCenter,\n anchorWorld[1] + exit[1] * CHAIN_GAP + perp[1] * slotCenter,\n ];\n const at: [number, number] = [\n snap(targetWorld[0] - rotatedPin[0]),\n snap(targetWorld[1] - rotatedPin[1]),\n ];\n layout.set(u.elId, { at, rot, mirror: false });\n progressed = true;\n }\n }\n }\n\n // ---- 7. Fallback grid for orphans -------------------------------------\n let placedCount = 0;\n for (const el of elements) {\n if (layout.has(el.id)) continue;\n const col = placedCount % FALLBACK_GRID_COLS;\n const row = Math.floor(placedCount / FALLBACK_GRID_COLS);\n layout.set(el.id, {\n at: [\n snap(FALLBACK_GRID_X0 + col * FALLBACK_GRID_DX),\n snap(FALLBACK_GRID_Y0 + row * FALLBACK_GRID_DY),\n ],\n rot: 0,\n mirror: false,\n });\n placedCount++;\n }\n\n return { devices: layout, buses: busLayout };\n}\n\nfunction snap(v: number): number {\n return Math.round(v / GRID) * GRID;\n}\n","/**\n * Best-effort orthogonal routing per Wire. Each visible polyline maps 1-to-1\n * to a Wire, so selecting / deleting at the wire level just works.\n *\n * Routing rules per wire `[a, b]`:\n * - If one end is a bus: project the other end onto the bus axis, L-shape\n * to that point.\n * - Otherwise: simple L-shape between the two terminal world coords.\n */\n\nimport type { Wire, WireEnd, WireId } from '../model';\nimport type { InternalModel } from './internal-model';\n\ntype Pt = [number, number];\n\nexport interface WireRoute {\n wireId: WireId;\n path: Pt[];\n}\n\nexport function routeWire(wire: Wire, model: InternalModel): WireRoute | null {\n const a = wire.ends[0];\n const b = wire.ends[1];\n const aBus = isBus(a, model);\n const bBus = isBus(b, model);\n // Bus end → project the other end onto the bus axis.\n if (aBus || bBus) {\n const bus = aBus ? a : b;\n const other = aBus ? b : a;\n const otherWorld = endWorld(other, model);\n if (!otherWorld) return null;\n const rb = model.buses.get(bus);\n if (!rb) return null;\n const { axis, at, span } = rb.geometry;\n const half = span / 2;\n let target: Pt;\n if (axis === 'x') {\n const x = clamp(otherWorld[0], at[0] - half, at[0] + half);\n target = [x, at[1]];\n } else {\n const y = clamp(otherWorld[1], at[1] - half, at[1] + half);\n target = [at[0], y];\n }\n return { wireId: wire.id, path: orthogonalPath(otherWorld, target) };\n }\n const aw = endWorld(a, model);\n const bw = endWorld(b, model);\n if (!aw || !bw) return null;\n return { wireId: wire.id, path: orthogonalPath(aw, bw) };\n}\n\nfunction isBus(end: WireEnd, model: InternalModel): boolean {\n return !end.includes('.') && model.buses.has(end);\n}\n\nfunction endWorld(end: WireEnd, model: InternalModel): Pt | null {\n if (!end.includes('.')) {\n const rb = model.buses.get(end);\n return rb ? (rb.geometry.at as Pt) : null;\n }\n const term = model.terminals.get(end as `${string}.${string}`);\n return term ? (term.world as Pt) : null;\n}\n\n/**\n * Resolve the current world coordinate of a wire endpoint.\n *\n * For terminal ends this is just the terminal's world position. For bus\n * ends it's the projection of `approach` onto the bus axis (clamped to\n * the bus span) — `approach` is the nearby interior point that indicates\n * where the user wants the wire to meet the bus. With no approach, the\n * bus center is returned.\n *\n * Used by `compile.ts` to rebase the first/last point of a user-edited\n * `Wire.path` whenever the connected element has moved.\n */\nexport function wireEndWorld(\n end: WireEnd,\n approach: Pt | null,\n model: InternalModel,\n): Pt | null {\n if (!end.includes('.')) {\n const rb = model.buses.get(end);\n if (!rb) return null;\n const { axis, at, span } = rb.geometry;\n if (!approach) return [at[0], at[1]] as Pt;\n const half = span / 2;\n if (axis === 'x') {\n const x = clamp(approach[0], at[0] - half, at[0] + half);\n return [x, at[1]];\n }\n const y = clamp(approach[1], at[1] - half, at[1] + half);\n return [at[0], y];\n }\n const term = model.terminals.get(end as `${string}.${string}`);\n return term ? ([term.world[0], term.world[1]] as Pt) : null;\n}\n\nfunction orthogonalPath(a: Pt, b: Pt): Pt[] {\n if (a[0] === b[0] || a[1] === b[1]) return [a, b];\n return [a, [a[0], b[1]], b];\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n","import type { LibraryEntry } from '../model/library';\n\nconst modules = import.meta.glob<{ default: LibraryEntry }>('./*.json', {\n eager: true,\n});\n\n/** All library entries, in filesystem order. */\nexport const libraryEntries: LibraryEntry[] = Object.values(modules).map(\n (m) => m.default,\n);\n\n/** O(1) lookup by `LibraryEntry.id`. */\nexport const libraryById: Record<string, LibraryEntry> = Object.fromEntries(\n libraryEntries.map((e) => [e.id, e]),\n);\n\n/**\n * Display order and Chinese labels for palette categories.\n * Categories not listed here fall through to the end with their raw id.\n */\nexport const CATEGORY_ORDER: readonly string[] = [\n 'busbar',\n 'switching',\n 'protection',\n 'motor-control',\n 'transformer',\n 'instrument-transformer',\n 'measurement',\n 'source',\n 'load',\n 'storage',\n 'compensation',\n 'grounding',\n 'renewable',\n];\n\nexport const CATEGORY_LABELS: Record<string, string> = {\n busbar: '母线 / 接线',\n switching: '开关',\n protection: '保护',\n 'motor-control': '电机控制',\n transformer: '变压器',\n 'instrument-transformer': '互感器',\n measurement: '测量仪表',\n source: '电源',\n load: '负荷',\n storage: '储能',\n compensation: '无功补偿',\n grounding: '中性点接地',\n renewable: '新能源 / 电力电子',\n};\n\n/** Entries grouped by category, preserving filesystem order within each group. */\nexport const libraryByCategory: Record<string, LibraryEntry[]> = (() => {\n const groups: Record<string, LibraryEntry[]> = {};\n for (const entry of libraryEntries) {\n (groups[entry.category] ??= []).push(entry);\n }\n return groups;\n})();\n","/**\n * Re-export the element library indexed by `LibraryEntry.id` for use in the\n * compile pipeline. The actual library is loaded once in\n * `src/element-library/index.ts`.\n */\n\nimport { libraryById } from '../element-library';\nimport type { LibraryEntry } from '../model';\n\nexport const LIBRARY: ReadonlyMap<string, LibraryEntry> = new Map(\n Object.entries(libraryById),\n);\n\nexport function getLibraryEntry(kind: string): LibraryEntry | undefined {\n return libraryById[kind];\n}\n","/**\n * DiagramFile → InternalModel. Pipeline:\n *\n * 1. Resolve elements + library\n * 2. Resolve buses (geometry from `Bus.layout` or auto-layout below)\n * 3. Validate wire endpoints (errors → diagnostics; pipeline keeps going)\n * 4. Auto-layout for devices without `Placement` and buses without layout\n * 5. Compute world-frame terminal geometry\n * 6. Union-find on wires → ConnectivityNode set with deterministic ids\n * (sorted endpoints hashed) so `routes[nodeId]` keys stay stable\n * across saves\n * 7. Auto-route each ConnectivityNode unless the user supplied a path\n */\n\nimport { t } from '../i18n';\nimport type {\n Bus,\n BusId,\n DiagramFile,\n Element,\n ElementId,\n NodeId,\n TerminalRef,\n Wire,\n WireEnd,\n} from '../model';\nimport { normalizePath } from '../model/wire-path';\nimport { autoLayout } from './auto-layout';\nimport { routeWire, wireEndWorld } from './auto-route';\nimport { LIBRARY } from './library-index';\nimport {\n emptyInternalModel,\n resolvePlacement,\n busAxisFromRot,\n type BusGeometry,\n type InternalModel,\n type ResolvedPlacement,\n} from './internal-model';\nimport { transformOrientation, transformPoint } from './transforms';\nimport { UnionFind } from './union-find';\n\n/**\n * Stable, content-derived node id. Same set of endpoints always maps to the\n * same NodeId across compile runs and across save/load cycles, so user-edited\n * `routes[nodeId]` overrides stay attached after reload.\n */\nfunction deterministicNodeId(members: WireEnd[]): NodeId {\n // FNV-1a 32-bit on the sorted, joined refs. Plenty of entropy for typical\n // diagram sizes (<10k nodes); collisions only cause a route override to\n // attach to the wrong node, never wrong electrical behavior.\n const sorted = [...members].sort();\n const text = sorted.join('|');\n let h = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return `n_${(h >>> 0).toString(36)}`;\n}\n\nconst DEFAULT_BUS_SPAN = 320;\n\nexport function compile(diagram: DiagramFile): InternalModel {\n const m = emptyInternalModel();\n\n // ---- 1. Resolve elements + library ------------------------------------\n const elementById = new Map<ElementId, Element>();\n diagram.elements.forEach((el, idx) => {\n if (elementById.has(el.id)) {\n m.diagnostics.push({\n code: 'E001',\n severity: 'error',\n message: t('compile.duplicateId', { id: el.id }),\n pointer: `/elements/${idx}`,\n });\n return;\n }\n elementById.set(el.id, el);\n const libDef = LIBRARY.get(el.kind);\n if (!libDef) {\n m.diagnostics.push({\n code: 'E003',\n severity: 'error',\n message: `${t('compile.unknownKind', { kind: el.kind })} (id=${el.id})`,\n pointer: `/elements/${idx}`,\n });\n }\n m.elements.set(el.id, { element: el, libraryDef: libDef });\n });\n\n // ---- 2. Resolve buses (preliminary; layout filled by auto-layout) -----\n const busById = new Map<BusId, Bus>();\n const userBusLayout = new Map<BusId, BusGeometry>();\n (diagram.buses ?? []).forEach((bus, idx) => {\n if (elementById.has(bus.id) || busById.has(bus.id)) {\n m.diagnostics.push({\n code: 'E001',\n severity: 'error',\n message: t('compile.duplicateId', { id: bus.id }),\n pointer: `/buses/${idx}`,\n });\n return;\n }\n busById.set(bus.id, bus);\n if (bus.layout) {\n const rot = bus.layout.rot ?? 0;\n userBusLayout.set(bus.id, {\n at: bus.layout.at,\n span: bus.layout.span,\n rot,\n axis: busAxisFromRot(rot),\n });\n }\n });\n\n // ---- 3. Validate wire endpoints ---------------------------------------\n const isBus = (end: WireEnd): boolean => !end.includes('.') && busById.has(end);\n const validEnd = (end: WireEnd, pointer: string): boolean => {\n if (isBus(end)) return true;\n const dot = end.indexOf('.');\n if (dot <= 0) {\n m.diagnostics.push({\n code: 'E003',\n severity: 'error',\n message: t('compile.invalidTermRef', { ref: end }),\n pointer,\n });\n return false;\n }\n const elemId = end.slice(0, dot);\n const pin = end.slice(dot + 1);\n const re = m.elements.get(elemId);\n if (!re) {\n m.diagnostics.push({\n code: 'E002',\n severity: 'error',\n message: t('compile.elementMissing', { id: elemId }),\n pointer,\n });\n return false;\n }\n if (!re.libraryDef) return false;\n if (!re.libraryDef.terminals.find((term) => term.id === pin)) {\n const avail = re.libraryDef.terminals.map((term) => term.id).join(', ');\n m.diagnostics.push({\n code: 'E003',\n severity: 'error',\n message: t('compile.missingPin', {\n id: elemId,\n kind: re.element.kind,\n pin,\n available: avail,\n }),\n pointer,\n });\n return false;\n }\n return true;\n };\n\n const validWires: Wire[] = [];\n (diagram.wires ?? []).forEach((w, i) => {\n const pointer = `/wires/${i}`;\n const a = validEnd(w.ends[0], pointer);\n const b = validEnd(w.ends[1], pointer);\n if (a && b) validWires.push(w);\n });\n\n // ---- 4. Auto-layout ----------------------------------------------------\n const userLayout = new Map<ElementId, ResolvedPlacement>();\n if (diagram.layout) {\n for (const [id, p] of Object.entries(diagram.layout)) {\n if (m.elements.has(id)) userLayout.set(id, resolvePlacement(p));\n else\n m.diagnostics.push({\n code: 'E004',\n severity: 'error',\n message: t('compile.layoutMissingElement', { id }),\n pointer: `/layout/${id}`,\n });\n }\n }\n const layoutResult = autoLayout({\n elements: diagram.elements,\n buses: diagram.buses ?? [],\n wires: validWires,\n library: LIBRARY,\n userLayout,\n userBusLayout,\n });\n m.layout = layoutResult.devices;\n for (const [busId, geom] of layoutResult.buses) {\n const bus = busById.get(busId);\n if (!bus) continue;\n m.buses.set(busId, { bus, geometry: geom });\n }\n // Any bus that still has no geometry (auto-layout couldn't position it)\n // gets a default. Defensive — shouldn't happen with non-empty wires.\n for (const [busId, bus] of busById) {\n if (m.buses.has(busId)) continue;\n m.buses.set(busId, {\n bus,\n geometry: {\n at: bus.layout?.at ?? [0, 0],\n span: bus.layout?.span ?? DEFAULT_BUS_SPAN,\n rot: bus.layout?.rot ?? 0,\n axis: busAxisFromRot(bus.layout?.rot ?? 0),\n },\n });\n }\n\n // ---- 5. Compute terminal geometry --------------------------------------\n for (const re of m.elements.values()) {\n if (!re.libraryDef) continue;\n const place = m.layout.get(re.element.id);\n if (!place) continue;\n const refs: TerminalRef[] = [];\n for (const lt of re.libraryDef.terminals) {\n const ref = `${re.element.id}.${lt.id}` as TerminalRef;\n const world = transformPoint([lt.x, lt.y], place);\n const orientation = transformOrientation(lt.orientation, place);\n m.terminals.set(ref, {\n ref,\n elementId: re.element.id,\n pin: lt.id,\n world,\n orientation,\n });\n refs.push(ref);\n }\n m.elementToTerminals.set(re.element.id, refs);\n }\n\n // ---- 6. Union-find over wires -----------------------------------------\n const uf = new UnionFind<WireEnd>();\n for (const w of validWires) {\n uf.add(w.ends[0]);\n uf.add(w.ends[1]);\n uf.union(w.ends[0], w.ends[1]);\n }\n for (const [, members] of uf.groups()) {\n const id = deterministicNodeId(members);\n m.nodes.set(id, { id, terminals: members });\n for (const end of members) m.terminalToNode.set(end, id);\n }\n\n // Warn about isolated elements / buses (no terminal in any node).\n for (const re of m.elements.values()) {\n const refs = m.elementToTerminals.get(re.element.id) ?? [];\n if (refs.length === 0) continue;\n const anyConnected = refs.some((r) => m.terminalToNode.has(r));\n if (!anyConnected) {\n m.diagnostics.push({\n code: 'W001',\n severity: 'warning',\n message: t('compile.elementUnconnected', { id: re.element.id }),\n });\n }\n }\n for (const busId of m.buses.keys()) {\n if (!m.terminalToNode.has(busId)) {\n m.diagnostics.push({\n code: 'W001',\n severity: 'warning',\n message: t('compile.elementUnconnected', { id: busId }),\n });\n }\n }\n\n // ---- 7. Per-wire rendering (Wire.path override; otherwise routeWire) ---\n for (const w of validWires) {\n if (w.path && w.path.length >= 2) {\n // Rebase endpoints to current terminal / bus positions so the wire\n // tracks its connected elements when they move. Any diagonal that\n // appears as a result is fixed by normalizePath (inserts L-corner).\n const stored = w.path;\n const approachA = stored.length >= 2 ? (stored[1] as [number, number]) : null;\n const approachB = stored.length >= 2 ? (stored[stored.length - 2] as [number, number]) : null;\n const endA = wireEndWorld(w.ends[0], approachA, m);\n const endB = wireEndWorld(w.ends[1], approachB, m);\n if (endA && endB) {\n const rebased: [number, number][] = [\n [endA[0], endA[1]],\n ...stored.slice(1, -1).map((p) => [p[0], p[1]] as [number, number]),\n [endB[0], endB[1]],\n ];\n const cleaned = normalizePath(rebased);\n if (cleaned.length >= 2) {\n m.wireRenders.set(w.id, { wireId: w.id, path: cleaned, userEdited: true });\n continue;\n }\n }\n // Endpoint resolution failed; fall back to auto-route below.\n }\n const r = routeWire(w, m);\n if (r) m.wireRenders.set(w.id, r);\n }\n\n return m;\n}\n","/**\n * ID minting for new elements / buses / annotations / wires. Element and bus\n * prefixes follow real-schematic conventions; wires use a deterministic\n * content hash so the same pair of endpoints always maps to the same id.\n */\n\nimport type { DiagramFile, ElementId, WireEnd, WireId } from '../model';\n\nconst PREFIX: Record<string, string> = {\n earth: 'GND',\n breaker: 'QF',\n disconnector: 'QS',\n 'earthing-switch': 'QE',\n 'load-switch': 'QL',\n fuse: 'FU',\n 'transformer-2w': 'T',\n 'transformer-3w': 'T',\n autotransformer: 'AT',\n ct: 'CT',\n pt: 'PT',\n generator: 'G',\n 'sync-motor': 'M',\n 'async-motor': 'M',\n 'grid-source': 'L',\n load: 'L',\n battery: 'BAT',\n 'shunt-reactor': 'LR',\n 'series-reactor': 'LR',\n 'shunt-capacitor': 'C',\n arrester: 'FBL',\n 'grounding-transformer': 'TG',\n ngr: 'NGR',\n 'arc-suppression-coil': 'ASC',\n pv: 'PV',\n 'wind-turbine': 'WT',\n rectifier: 'RT',\n inverter: 'INV',\n 'converter-bidir': 'PCS',\n};\n\nconst BUS_PREFIX = 'B';\n\nfunction usedIds(diagram: DiagramFile): Set<string> {\n return new Set([\n ...diagram.elements.map((e) => e.id),\n ...(diagram.buses ?? []).map((b) => b.id),\n ]);\n}\n\nexport function newElementId(diagram: DiagramFile, kind: string): ElementId {\n const prefix = PREFIX[kind] ?? kind;\n const used = usedIds(diagram);\n let n = 1;\n while (used.has(`${prefix}${n}`)) n++;\n return `${prefix}${n}`;\n}\n\nexport function newBusId(diagram: DiagramFile): ElementId {\n const used = usedIds(diagram);\n let n = 1;\n while (used.has(`${BUS_PREFIX}${n}`)) n++;\n return `${BUS_PREFIX}${n}`;\n}\n\nexport function newAnnotationId(diagram: DiagramFile): string {\n const used = new Set((diagram.annotations ?? []).map((a) => a.id));\n let n = 1;\n while (used.has(`a${n}`)) n++;\n return `a${n}`;\n}\n\n/**\n * Content-hashed wire id. Two wires with the same pair of endpoints collide\n * intentionally — duplicate `addWire` is a no-op, and migration / save\n * round-trips produce stable diffs.\n */\nexport function wireIdFromEnds(a: WireEnd, b: WireEnd): WireId {\n const sorted = [a, b].sort();\n const text = `${sorted[0]}|${sorted[1]}`;\n let h = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return `w_${(h >>> 0).toString(36)}`;\n}\n","/**\n * Zustand store — the single source of truth for the editor.\n *\n * Mutation rule: the only way to change `diagram` is `dispatch(mutator)`.\n * `dispatch` snapshots the previous diagram onto an undo stack, applies the\n * mutation, recompiles, and clears the redo stack. Targeted helpers\n * (`moveElements`, `addWire`, …) are thin wrappers around `dispatch`.\n *\n * Selection / tool / cursor state lives in the store too, but does *not*\n * participate in the undo stack — Figma convention: ephemeral UI state\n * doesn't pollute history.\n *\n * Viewport (pan/zoom) is deliberately *not* in the store: it lives on a DOM\n * ref to avoid React re-renders during gesture loops.\n */\n\nimport { create } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\nimport {\n compile,\n type InternalModel,\n type ResolvedPlacement,\n type BusGeometry,\n} from '../compiler';\nimport type { FileSession } from '../lib/file-io';\nimport type {\n AnnotationId,\n Bus,\n BusId,\n BusLayout,\n DiagramFile,\n Element,\n ElementId,\n NodeId,\n Placement,\n TextAnnotation,\n Wire,\n WireEnd,\n WireId,\n} from '../model';\nimport {\n newAnnotationId,\n newBusId,\n newElementId,\n wireIdFromEnds,\n} from './id-allocator';\nimport { normalizePath } from '../model/wire-path';\n\nconst EMPTY_DIAGRAM: DiagramFile = { version: '1', elements: [] };\nconst HISTORY_LIMIT = 100;\nconst PASTE_OFFSET = 20;\n\nfunction defaultTool(): ToolId {\n if (typeof window === 'undefined') return 'select';\n try {\n return window.matchMedia('(pointer: coarse)').matches ? 'pan' : 'select';\n } catch {\n return 'select';\n }\n}\n\n/**\n * Self-contained snapshot of a copied selection. Placements are pre-resolved\n * (auto-layout positions baked in) so paste survives later edits to the\n * source diagram. Wires only include those whose endpoints are all within\n * the selection.\n */\nexport interface ClipboardData {\n elements: Element[];\n buses: Bus[];\n placements: Record<ElementId, Placement>;\n busLayouts: Record<BusId, BusLayout>;\n wires: Wire[];\n}\n\nexport type ToolId = 'select' | 'pan' | 'wire' | 'place' | 'busbar' | 'text';\n\nexport interface EditorState {\n // ---- Document --------------------------------------------------------\n diagram: DiagramFile;\n internal: InternalModel;\n fileSession: FileSession | null;\n\n // ---- Ephemeral UI state ---------------------------------------------\n activeTool: ToolId;\n placeKind: string | null;\n lastPlaceKind: string | null;\n wireFromTerminal: WireEnd | null;\n placeFromTerminal: WireEnd | null;\n busbarDrawStart: [number, number] | null;\n cursorSvg: [number, number] | null;\n /** Selected devices and/or buses (shared id namespace). */\n selection: ElementId[];\n /** Selected single wire (mutually exclusive with selection/selectedNode). */\n selectedWire: WireId | null;\n /** Selected ConnectivityNode — used for \"select the whole electrical\n * node\" operations. Mutually exclusive with the others. */\n selectedNode: NodeId | null;\n selectedAnnotation: AnnotationId | null;\n editingAnnotation: AnnotationId | null;\n editingElement: ElementId | null;\n\n // ---- History ---------------------------------------------------------\n past: DiagramFile[];\n future: DiagramFile[];\n\n // ---- Clipboard (ephemeral, not in history) --------------------------\n clipboard: ClipboardData | null;\n clipboardPasteIndex: number;\n\n // ---- Mutation API ----------------------------------------------------\n setDiagram: (diagram: DiagramFile) => void;\n setFileSession: (session: FileSession | null) => void;\n loadDiagramFromFile: (diagram: DiagramFile, session: FileSession) => void;\n\n dispatch: (mutator: (d: DiagramFile) => DiagramFile, label?: string) => void;\n undo: () => void;\n redo: () => void;\n\n // ---- UI actions ------------------------------------------------------\n setActiveTool: (tool: ToolId, opts?: { placeKind?: string | null }) => void;\n setPlaceKind: (kind: string | null) => void;\n setWireFromTerminal: (ref: WireEnd | null) => void;\n setPlaceFromTerminal: (ref: WireEnd | null) => void;\n setBusbarDrawStart: (pt: [number, number] | null) => void;\n setCursorSvg: (pt: [number, number] | null) => void;\n\n setSelection: (ids: ElementId[]) => void;\n toggleInSelection: (id: ElementId) => void;\n clearSelection: () => void;\n setSelectedWire: (id: WireId | null) => void;\n setSelectedNode: (nodeId: NodeId | null) => void;\n setSelectedAnnotation: (id: AnnotationId | null) => void;\n setEditingAnnotation: (id: AnnotationId | null) => void;\n setEditingElement: (id: ElementId | null) => void;\n\n // ---- Clipboard actions ----------------------------------------------\n copySelection: () => void;\n cutSelection: () => void;\n pasteClipboard: () => void;\n\n // ---- Auto-layout actions --------------------------------------------\n autoArrangeAll: () => void;\n autoArrangeSelection: () => void;\n fillUnplacedAll: () => void;\n fillUnplacedSelection: () => void;\n\n // ---- Document edit shortcuts ----------------------------------------\n moveElements: (deltas: Map<ElementId, [number, number]>) => void;\n deleteSelection: () => void;\n /** Drop a single wire by id. */\n deleteSelectedWire: () => void;\n /** Drop every wire touching the currently selected ConnectivityNode. */\n deleteSelectedNode: () => void;\n rotateSelection: (deltaDegrees: 90 | -90 | 180) => void;\n mirrorSelection: () => void;\n addElement: (\n kind: string,\n at: [number, number],\n extra?: Partial<Element>,\n ) => ElementId;\n addBus: (\n at: [number, number],\n span: number,\n rot?: 0 | 90 | 180 | 270,\n ) => BusId;\n /** Append a wire between two endpoints (idempotent — duplicate is a no-op). */\n addWire: (a: WireEnd, b: WireEnd) => void;\n /** Replace a wire's manual route. `null` clears it → back to auto-route. */\n updateWirePath: (id: WireId, path: [number, number][] | null) => void;\n /** Clear a wire's manual route (alias for `updateWirePath(id, null)`). */\n resetWirePath: (id: WireId) => void;\n updateElement: (id: ElementId, patch: Partial<Element>) => void;\n updatePlacement: (id: ElementId, patch: Partial<Placement>) => void;\n updateBus: (id: BusId, patch: Partial<BusLayout>) => void;\n addAnnotation: (at: [number, number], text?: string) => AnnotationId;\n updateAnnotation: (id: AnnotationId, patch: Partial<TextAnnotation>) => void;\n deleteAnnotation: (id: AnnotationId) => void;\n}\n\nexport const useEditorStore = create<EditorState>()(\n persist(\n (set, get) => ({\n diagram: EMPTY_DIAGRAM,\n internal: compile(EMPTY_DIAGRAM),\n fileSession: null,\n\n activeTool: defaultTool(),\n placeKind: null,\n lastPlaceKind: null,\n wireFromTerminal: null,\n placeFromTerminal: null,\n busbarDrawStart: null,\n cursorSvg: null,\n selection: [],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n editingAnnotation: null,\n editingElement: null,\n\n past: [],\n future: [],\n\n clipboard: null,\n clipboardPasteIndex: 0,\n\n setDiagram: (diagram) =>\n set({\n diagram,\n internal: compile(diagram),\n past: [],\n future: [],\n selection: [],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n editingAnnotation: null,\n editingElement: null,\n wireFromTerminal: null,\n placeFromTerminal: null,\n }),\n\n setFileSession: (fileSession) => set({ fileSession }),\n\n loadDiagramFromFile: (diagram, fileSession) =>\n set({\n diagram,\n internal: compile(diagram),\n fileSession,\n past: [],\n future: [],\n selection: [],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n editingAnnotation: null,\n editingElement: null,\n wireFromTerminal: null,\n placeFromTerminal: null,\n }),\n\n dispatch: (mutator) => {\n const { diagram, past } = get();\n const next = mutator(diagram);\n if (next === diagram) return;\n const trimmed = past.length >= HISTORY_LIMIT ? past.slice(1) : past;\n set({\n diagram: next,\n internal: compile(next),\n past: [...trimmed, diagram],\n future: [],\n });\n },\n\n undo: () => {\n const { past, future, diagram } = get();\n if (past.length === 0) return;\n const prev = past[past.length - 1];\n set({\n diagram: prev,\n internal: compile(prev),\n past: past.slice(0, -1),\n future: [...future, diagram],\n wireFromTerminal: null,\n placeFromTerminal: null,\n });\n },\n\n redo: () => {\n const { past, future, diagram } = get();\n if (future.length === 0) return;\n const next = future[future.length - 1];\n set({\n diagram: next,\n internal: compile(next),\n past: [...past, diagram],\n future: future.slice(0, -1),\n wireFromTerminal: null,\n placeFromTerminal: null,\n });\n },\n\n setActiveTool: (tool, opts) => {\n const cur = get();\n let placeKind: string | null;\n if (opts?.placeKind !== undefined) placeKind = opts.placeKind;\n else if (tool === 'place') placeKind = cur.placeKind ?? cur.lastPlaceKind;\n else placeKind = null;\n set({\n activeTool: tool,\n placeKind,\n lastPlaceKind: placeKind ?? cur.lastPlaceKind,\n wireFromTerminal: tool === 'wire' ? cur.wireFromTerminal : null,\n placeFromTerminal: tool === 'place' ? cur.placeFromTerminal : null,\n });\n },\n setPlaceKind: (kind) =>\n set((s) => ({\n placeKind: kind,\n lastPlaceKind: kind ?? s.lastPlaceKind,\n })),\n setWireFromTerminal: (ref) => set({ wireFromTerminal: ref }),\n setPlaceFromTerminal: (ref) => set({ placeFromTerminal: ref }),\n setBusbarDrawStart: (pt) => set({ busbarDrawStart: pt }),\n setCursorSvg: (pt) => set({ cursorSvg: pt }),\n\n setSelection: (ids) =>\n set({\n selection: dedupe(ids),\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: ids.length ? null : get().selectedAnnotation,\n }),\n toggleInSelection: (id) => {\n const sel = get().selection;\n set({\n selection: sel.includes(id) ? sel.filter((x) => x !== id) : [...sel, id],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n });\n },\n clearSelection: () =>\n set({\n selection: [],\n selectedWire: null,\n selectedNode: null,\n selectedAnnotation: null,\n editingAnnotation: null,\n editingElement: null,\n }),\n setSelectedWire: (id) =>\n set({\n selectedWire: id,\n selection: id ? [] : get().selection,\n selectedNode: null,\n selectedAnnotation: id ? null : get().selectedAnnotation,\n }),\n setSelectedNode: (nodeId) =>\n set({\n selectedNode: nodeId,\n selection: nodeId ? [] : get().selection,\n selectedWire: null,\n selectedAnnotation: nodeId ? null : get().selectedAnnotation,\n }),\n setSelectedAnnotation: (id) =>\n set({\n selectedAnnotation: id,\n selection: id ? [] : get().selection,\n selectedWire: id ? null : get().selectedWire,\n selectedNode: id ? null : get().selectedNode,\n editingAnnotation: id ? get().editingAnnotation : null,\n }),\n setEditingAnnotation: (id) =>\n set({\n editingAnnotation: id,\n selectedAnnotation: id ?? get().selectedAnnotation,\n editingElement: id ? null : get().editingElement,\n }),\n setEditingElement: (id) =>\n set({\n editingElement: id,\n selection: id ? [id] : get().selection,\n editingAnnotation: id ? null : get().editingAnnotation,\n selectedAnnotation: id ? null : get().selectedAnnotation,\n selectedWire: id ? null : get().selectedWire,\n selectedNode: id ? null : get().selectedNode,\n }),\n\n copySelection: () => {\n const { selection, diagram, internal } = get();\n if (selection.length === 0) return;\n const sel = new Set(selection);\n\n const elements = diagram.elements\n .filter((e) => sel.has(e.id))\n .map((e) => structuredClone(e));\n\n const buses = (diagram.buses ?? [])\n .filter((b) => sel.has(b.id))\n .map((b) => structuredClone(b));\n\n const placements: Record<ElementId, Placement> = {};\n for (const id of selection) {\n if (sel.has(id) && !internal.buses.has(id)) {\n const explicit = diagram.layout?.[id];\n if (explicit) {\n placements[id] = structuredClone(explicit);\n continue;\n }\n const resolved = internal.layout.get(id);\n if (resolved) placements[id] = compactPlacement(resolved);\n }\n }\n\n const busLayouts: Record<BusId, BusLayout> = {};\n for (const id of selection) {\n const rb = internal.buses.get(id);\n if (!rb) continue;\n busLayouts[id] = compactBusLayout(rb.geometry);\n }\n\n const wires = (diagram.wires ?? [])\n .filter((w) =>\n w.ends.every((e) => sel.has(endOwner(e))),\n )\n .map((w) => structuredClone(w));\n\n set({\n clipboard: { elements, buses, placements, busLayouts, wires },\n clipboardPasteIndex: 0,\n });\n },\n\n cutSelection: () => {\n const { selection } = get();\n if (selection.length === 0) return;\n get().copySelection();\n get().deleteSelection();\n },\n\n pasteClipboard: () => {\n const { clipboard, clipboardPasteIndex, diagram } = get();\n if (!clipboard) return;\n if (clipboard.elements.length === 0 && clipboard.buses.length === 0) return;\n const step = clipboardPasteIndex + 1;\n const dx = PASTE_OFFSET * step;\n const dy = PASTE_OFFSET * step;\n\n const idMap = new Map<ElementId, ElementId>();\n let working = diagram;\n for (const el of clipboard.elements) {\n const newId = newElementId(working, el.kind);\n idMap.set(el.id, newId);\n working = {\n ...working,\n elements: [...working.elements, { id: newId, kind: el.kind }],\n };\n }\n for (const bus of clipboard.buses) {\n const newId = newBusId(working);\n idMap.set(bus.id, newId);\n working = {\n ...working,\n buses: [...(working.buses ?? []), { id: newId }],\n };\n }\n\n const remapEnd = (end: WireEnd): WireEnd => {\n const dot = end.indexOf('.');\n const head = dot < 0 ? end : end.slice(0, dot);\n const remapped = idMap.get(head);\n if (!remapped) return end;\n return (dot < 0 ? remapped : `${remapped}${end.slice(dot)}`) as WireEnd;\n };\n\n get().dispatch((d) => {\n const newElements: Element[] = clipboard.elements.map((e) => {\n const cloned = structuredClone(e);\n cloned.id = idMap.get(e.id)!;\n return cloned;\n });\n\n const newBuses: Bus[] = clipboard.buses.map((b) => {\n const cloned = structuredClone(b);\n cloned.id = idMap.get(b.id)!;\n const layout = clipboard.busLayouts[b.id];\n if (layout) {\n cloned.layout = {\n ...layout,\n at: [layout.at[0] + dx, layout.at[1] + dy],\n };\n }\n return cloned;\n });\n\n const newLayout: Record<ElementId, Placement> = { ...(d.layout ?? {}) };\n for (const [oldId, newId] of idMap) {\n const p = clipboard.placements[oldId];\n if (!p) continue;\n newLayout[newId] = {\n ...p,\n at: [p.at[0] + dx, p.at[1] + dy],\n };\n }\n\n const newWires: Wire[] = clipboard.wires.map((w) => {\n const ends: [WireEnd, WireEnd] = [\n remapEnd(w.ends[0]),\n remapEnd(w.ends[1]),\n ];\n return { id: wireIdFromEnds(ends[0], ends[1]), ends };\n });\n\n const wires = mergeWires(d.wires ?? [], newWires);\n\n return {\n ...d,\n elements: [...d.elements, ...newElements],\n buses: newBuses.length\n ? [...(d.buses ?? []), ...newBuses]\n : d.buses,\n wires: wires.length ? wires : undefined,\n layout: Object.keys(newLayout).length ? newLayout : undefined,\n };\n });\n\n set({\n selection: Array.from(idMap.values()),\n clipboardPasteIndex: step,\n });\n },\n\n autoArrangeAll: () => {\n get().dispatch((d) => {\n const hasDeviceLayout = d.layout && Object.keys(d.layout).length > 0;\n const hasBusLayout = (d.buses ?? []).some((b) => b.layout);\n if (!hasDeviceLayout && !hasBusLayout) return d;\n const { layout: _layout, ...rest } = d;\n void _layout;\n const buses = d.buses?.map((b) => {\n const { layout: _bl, ...bRest } = b;\n void _bl;\n return bRest;\n });\n return { ...rest, buses };\n });\n },\n\n autoArrangeSelection: () => {\n const { selection } = get();\n if (selection.length === 0) return;\n const drop = new Set(selection);\n get().dispatch((d) => {\n let changed = false;\n let layout = d.layout;\n if (layout) {\n const next: Record<ElementId, Placement> = {};\n for (const [id, p] of Object.entries(layout)) {\n if (drop.has(id)) {\n changed = true;\n continue;\n }\n next[id] = p;\n }\n if (changed) layout = Object.keys(next).length ? next : undefined;\n }\n let buses = d.buses;\n if (buses) {\n const next = buses.map((b) => {\n if (drop.has(b.id) && b.layout) {\n changed = true;\n const { layout: _bl, ...rest } = b;\n void _bl;\n return rest;\n }\n return b;\n });\n if (changed) buses = next;\n }\n if (!changed) return d;\n return { ...d, layout, buses };\n });\n },\n\n fillUnplacedAll: () => {\n const internal = get().internal;\n get().dispatch((d) => {\n const explicit = d.layout ?? {};\n const additions: Record<ElementId, Placement> = {};\n for (const el of d.elements) {\n if (explicit[el.id]) continue;\n const resolved = internal.layout.get(el.id);\n if (resolved) additions[el.id] = compactPlacement(resolved);\n }\n const busesNeedLayout: { idx: number; bus: Bus }[] = [];\n (d.buses ?? []).forEach((b, idx) => {\n if (b.layout) return;\n if (internal.buses.has(b.id)) busesNeedLayout.push({ idx, bus: b });\n });\n if (\n Object.keys(additions).length === 0 &&\n busesNeedLayout.length === 0\n ) {\n return d;\n }\n let buses = d.buses;\n if (busesNeedLayout.length > 0 && buses) {\n buses = buses.map((b) => {\n const rb = internal.buses.get(b.id);\n if (!b.layout && rb) {\n return { ...b, layout: compactBusLayout(rb.geometry) };\n }\n return b;\n });\n }\n return {\n ...d,\n layout: { ...explicit, ...additions },\n buses,\n };\n });\n },\n\n fillUnplacedSelection: () => {\n const { selection, internal } = get();\n if (selection.length === 0) return;\n get().dispatch((d) => {\n const explicit = d.layout ?? {};\n const additions: Record<ElementId, Placement> = {};\n const busesPatch = new Map<BusId, BusLayout>();\n for (const id of selection) {\n if (internal.buses.has(id)) {\n const rb = internal.buses.get(id)!;\n if (!d.buses?.find((b) => b.id === id && b.layout)) {\n busesPatch.set(id, compactBusLayout(rb.geometry));\n }\n } else {\n if (explicit[id]) continue;\n const resolved = internal.layout.get(id);\n if (resolved) additions[id] = compactPlacement(resolved);\n }\n }\n if (Object.keys(additions).length === 0 && busesPatch.size === 0) {\n return d;\n }\n let buses = d.buses;\n if (busesPatch.size > 0 && buses) {\n buses = buses.map((b) =>\n busesPatch.has(b.id) ? { ...b, layout: busesPatch.get(b.id)! } : b,\n );\n }\n return {\n ...d,\n layout: { ...explicit, ...additions },\n buses,\n };\n });\n },\n\n moveElements: (deltas) => {\n if (deltas.size === 0) return;\n const internal = get().internal;\n get().dispatch((d) => {\n const layout = { ...(d.layout ?? {}) };\n const busPatches = new Map<BusId, [number, number]>();\n for (const [id, delta] of deltas) {\n if (internal.buses.has(id)) {\n busPatches.set(id, delta);\n continue;\n }\n const resolved = internal.layout.get(id);\n const base: Placement =\n layout[id] ?? (resolved ? compactPlacement(resolved) : { at: [0, 0] });\n layout[id] = {\n ...base,\n at: [base.at[0] + delta[0], base.at[1] + delta[1]],\n };\n }\n let buses = d.buses;\n if (busPatches.size > 0) {\n buses = (d.buses ?? []).map((b) => {\n const delta = busPatches.get(b.id);\n if (!delta) return b;\n const cur =\n b.layout ?? compactBusLayout(internal.buses.get(b.id)!.geometry);\n return {\n ...b,\n layout: {\n ...cur,\n at: [cur.at[0] + delta[0], cur.at[1] + delta[1]],\n },\n };\n });\n }\n return { ...d, layout, buses };\n });\n },\n\n deleteSelection: () => {\n const { selection } = get();\n if (selection.length === 0) return;\n const ids = new Set(selection);\n get().dispatch((d) => {\n const elements = d.elements.filter((e) => !ids.has(e.id));\n const buses = (d.buses ?? []).filter((b) => !ids.has(b.id));\n const wires = (d.wires ?? []).filter(\n (w) => !ids.has(endOwner(w.ends[0])) && !ids.has(endOwner(w.ends[1])),\n );\n const layout = d.layout\n ? Object.fromEntries(\n Object.entries(d.layout).filter(([k]) => !ids.has(k)),\n )\n : undefined;\n return {\n ...d,\n elements,\n buses: buses.length ? buses : undefined,\n wires: wires.length ? wires : undefined,\n layout: layout && Object.keys(layout).length ? layout : undefined,\n };\n });\n set({ selection: [] });\n },\n\n deleteSelectedWire: () => {\n const { selectedWire, internal } = get();\n if (!selectedWire) return;\n\n // Collect non-bus elements touching this wire so we can freeze their\n // current auto-layout positions into `diagram.layout`. Otherwise the\n // next compile re-runs auto-layout without the wire's anchor and the\n // element \"flies\" to a different spot.\n const wireObj = (get().diagram.wires ?? []).find((w) => w.id === selectedWire);\n const affectedElementIds = new Set<ElementId>();\n if (wireObj) {\n for (const end of wireObj.ends) {\n const dot = end.indexOf('.');\n if (dot > 0) affectedElementIds.add(end.slice(0, dot));\n }\n }\n\n get().dispatch((d) => {\n const wires = (d.wires ?? []).filter((w) => w.id !== selectedWire);\n if (wires.length === (d.wires ?? []).length) return d;\n\n const layout = { ...(d.layout ?? {}) };\n for (const id of affectedElementIds) {\n if (layout[id]) continue;\n const resolved = internal.layout.get(id);\n if (!resolved) continue;\n const placement: Placement = { at: resolved.at };\n if (resolved.rot) placement.rot = resolved.rot;\n if (resolved.mirror) placement.mirror = resolved.mirror;\n layout[id] = placement;\n }\n\n return {\n ...d,\n wires: wires.length ? wires : undefined,\n layout: Object.keys(layout).length ? layout : undefined,\n };\n });\n set({ selectedWire: null });\n },\n\n deleteSelectedNode: () => {\n const { selectedNode, internal } = get();\n if (!selectedNode) return;\n const node = internal.nodes.get(selectedNode);\n if (!node) return;\n const memberSet = new Set<WireEnd>(node.terminals);\n\n const affectedElementIds = new Set<ElementId>();\n for (const end of node.terminals) {\n const dot = end.indexOf('.');\n if (dot > 0) affectedElementIds.add(end.slice(0, dot));\n }\n\n get().dispatch((d) => {\n const layout = { ...(d.layout ?? {}) };\n for (const id of affectedElementIds) {\n if (layout[id]) continue;\n const resolved = internal.layout.get(id);\n if (!resolved) continue;\n const placement: Placement = { at: resolved.at };\n if (resolved.rot) placement.rot = resolved.rot;\n if (resolved.mirror) placement.mirror = resolved.mirror;\n layout[id] = placement;\n }\n\n const wires = (d.wires ?? []).filter(\n (w) => !memberSet.has(w.ends[0]) && !memberSet.has(w.ends[1]),\n );\n return {\n ...d,\n wires: wires.length ? wires : undefined,\n layout: Object.keys(layout).length ? layout : undefined,\n };\n });\n set({ selectedNode: null });\n },\n\n rotateSelection: (deltaDegrees) => {\n const { selection, internal } = get();\n if (selection.length === 0) return;\n get().dispatch((d) => {\n const layout = { ...(d.layout ?? {}) };\n const busPatches = new Map<BusId, 0 | 90 | 180 | 270>();\n for (const id of selection) {\n if (internal.buses.has(id)) {\n const rb = internal.buses.get(id)!;\n const cur =\n d.buses?.find((b) => b.id === id)?.layout?.rot ?? rb.geometry.rot;\n const next = (((cur ?? 0) + deltaDegrees) % 360 + 360) % 360;\n busPatches.set(id, next as 0 | 90 | 180 | 270);\n continue;\n }\n const cur = layout[id] ?? { at: internal.layout.get(id)?.at ?? [0, 0] };\n const next = (((cur.rot ?? 0) + deltaDegrees) % 360 + 360) % 360;\n layout[id] = { ...cur, rot: next as 0 | 90 | 180 | 270 };\n }\n let buses = d.buses;\n if (busPatches.size > 0) {\n buses = (d.buses ?? []).map((b) => {\n if (!busPatches.has(b.id)) return b;\n const cur =\n b.layout ?? compactBusLayout(internal.buses.get(b.id)!.geometry);\n return { ...b, layout: { ...cur, rot: busPatches.get(b.id)! } };\n });\n }\n return { ...d, layout, buses };\n });\n },\n\n mirrorSelection: () => {\n const { selection, internal } = get();\n if (selection.length === 0) return;\n get().dispatch((d) => {\n const layout = { ...(d.layout ?? {}) };\n for (const id of selection) {\n if (internal.buses.has(id)) continue; // buses don't mirror\n const cur = layout[id] ?? { at: internal.layout.get(id)?.at ?? [0, 0] };\n layout[id] = { ...cur, mirror: !(cur.mirror ?? false) };\n }\n return { ...d, layout };\n });\n },\n\n addElement: (kind, at, extra) => {\n if (kind === 'busbar') {\n return get().addBus(at, 320);\n }\n const id = newElementId(get().diagram, kind);\n get().dispatch((d) => {\n const newElement: Element = { id, kind, ...(extra ?? {}) };\n return {\n ...d,\n elements: [...d.elements, newElement],\n layout: { ...(d.layout ?? {}), [id]: { at } },\n };\n });\n set({ selection: [id] });\n return id;\n },\n\n addBus: (at, span, rot) => {\n const id = newBusId(get().diagram);\n get().dispatch((d) => {\n const bus: Bus = {\n id,\n layout: rot !== undefined ? { at, span, rot } : { at, span },\n };\n return {\n ...d,\n buses: [...(d.buses ?? []), bus],\n };\n });\n set({ selection: [id] });\n return id;\n },\n\n addWire: (a, b) => {\n if (a === b) return;\n const id = wireIdFromEnds(a, b);\n get().dispatch((d) => {\n const existing = d.wires ?? [];\n if (existing.some((w) => w.id === id)) return d;\n return {\n ...d,\n wires: [...existing, { id, ends: [a, b] }],\n };\n });\n },\n\n updateWirePath: (id, path) => {\n get().dispatch((d) => {\n const wires = d.wires ?? [];\n if (!wires.some((w) => w.id === id)) return d;\n const cleaned = path && path.length >= 2 ? normalizePath(path) : null;\n const valid = cleaned && cleaned.length >= 2 ? cleaned : null;\n const nextWires = wires.map((w) => {\n if (w.id !== id) return w;\n if (valid) return { ...w, path: valid };\n const { path: _drop, ...rest } = w;\n return rest as Wire;\n });\n return { ...d, wires: nextWires };\n });\n },\n\n resetWirePath: (id) => {\n get().updateWirePath(id, null);\n },\n\n updateElement: (id, patch) => {\n get().dispatch((d) => ({\n ...d,\n elements: d.elements.map((e) => (e.id === id ? { ...e, ...patch } : e)),\n }));\n },\n\n updatePlacement: (id, patch) => {\n get().dispatch((d) => {\n const cur = d.layout?.[id] ?? get().internal.layout.get(id);\n const nextPlacement: Placement = {\n at: patch.at ?? cur?.at ?? [0, 0],\n ...(patch.rot !== undefined ? { rot: patch.rot } : cur?.rot ? { rot: cur.rot } : {}),\n ...(patch.mirror !== undefined\n ? { mirror: patch.mirror }\n : cur?.mirror ? { mirror: cur.mirror } : {}),\n };\n return {\n ...d,\n layout: { ...(d.layout ?? {}), [id]: nextPlacement },\n };\n });\n },\n\n updateBus: (id, patch) => {\n get().dispatch((d) => {\n const buses = (d.buses ?? []).map((b) => {\n if (b.id !== id) return b;\n const internal = get().internal;\n const cur =\n b.layout ?? (internal.buses.has(id)\n ? compactBusLayout(internal.buses.get(id)!.geometry)\n : { at: [0, 0] as [number, number], span: 320 });\n const next: BusLayout = {\n at: patch.at ?? cur.at,\n span: patch.span ?? cur.span,\n ...(patch.rot !== undefined\n ? { rot: patch.rot }\n : cur.rot ? { rot: cur.rot } : {}),\n };\n return { ...b, layout: next };\n });\n return { ...d, buses };\n });\n },\n\n addAnnotation: (at, text = '') => {\n const id = newAnnotationId(get().diagram);\n get().dispatch((d) => {\n const ann: TextAnnotation = { id, at, text };\n return { ...d, annotations: [...(d.annotations ?? []), ann] };\n });\n return id;\n },\n updateAnnotation: (id, patch) => {\n get().dispatch((d) => {\n const list = d.annotations ?? [];\n let changed = false;\n const next = list.map((a) => {\n if (a.id !== id) return a;\n changed = true;\n return { ...a, ...patch, id: a.id };\n });\n if (!changed) return d;\n return { ...d, annotations: next };\n });\n },\n deleteAnnotation: (id) => {\n get().dispatch((d) => {\n const list = d.annotations ?? [];\n const next = list.filter((a) => a.id !== id);\n if (next.length === list.length) return d;\n return {\n ...d,\n annotations: next.length ? next : undefined,\n };\n });\n if (get().selectedAnnotation === id) {\n set({ selectedAnnotation: null, editingAnnotation: null });\n }\n },\n }),\n {\n name: 'ole-editor',\n version: 2,\n storage: createJSONStorage(() => localStorage),\n partialize: (s) => ({\n diagram: s.diagram,\n activeTool: s.activeTool,\n placeKind: s.placeKind,\n lastPlaceKind: s.lastPlaceKind,\n }),\n onRehydrateStorage: () => (state) => {\n if (state?.diagram) state.internal = compile(state.diagram);\n },\n },\n ),\n);\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction dedupe<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n}\n\nfunction endOwner(end: WireEnd): ElementId {\n const dot = end.indexOf('.');\n return dot < 0 ? end : end.slice(0, dot);\n}\n\n/** Concatenate two wire lists, dropping duplicates (by content-hash id). */\nfunction mergeWires(a: Wire[], b: Wire[]): Wire[] {\n const seen = new Set<WireId>(a.map((w) => w.id));\n const out = a.slice();\n for (const w of b) {\n if (seen.has(w.id)) continue;\n seen.add(w.id);\n out.push(w);\n }\n return out;\n}\n\n/**\n * `ResolvedPlacement` always carries `rot`/`mirror` (with 0/false defaults).\n * `Placement` (the file format) omits defaults — keep diagram JSON tight and\n * round-trip-stable.\n */\nfunction compactPlacement(rp: ResolvedPlacement): Placement {\n return {\n at: [rp.at[0], rp.at[1]],\n ...(rp.rot ? { rot: rp.rot } : {}),\n ...(rp.mirror ? { mirror: rp.mirror } : {}),\n };\n}\n\nfunction compactBusLayout(g: BusGeometry): BusLayout {\n return {\n at: [g.at[0], g.at[1]],\n span: g.span,\n ...(g.rot ? { rot: g.rot } : {}),\n };\n}\n","/**\n * Module-level singleton for the active viewport API. `CanvasSvg` registers\n * itself on mount; chrome (e.g. `ViewToolbar`) reads via `getViewportApi()`\n * and calls imperatively. Pairs with `zoom-bus` (which carries reactive\n * scale notifications) — this one is for command dispatch, not subscription.\n */\n\nimport type { ViewportApi } from './useViewport';\n\nlet current: ViewportApi | null = null;\n\nexport function setViewportApi(api: ViewportApi | null): void {\n current = api;\n}\n\nexport function getViewportApi(): ViewportApi | null {\n return current;\n}\n","/**\n * Grid snap helpers. Snapping is bound to the visual grid: when the user\n * hides the grid (ViewToolbar / `G`), `.hide-grid` lands on the canvas\n * root and snap() returns the value untouched. So \"show grid\" and \"snap to\n * grid\" are one switch.\n *\n * Used by: SelectTool drag move, BusHandles span resize, drop-on-bus\n * placement, drag-drop from palette.\n */\n\nexport const GRID_SIZE = 10;\n\nexport function isSnapEnabled(): boolean {\n if (typeof document === 'undefined') return true;\n const root = document.querySelector('.ole-canvas-root');\n return !!root && !root.classList.contains('hide-grid');\n}\n\nexport function snap(v: number): number {\n return isSnapEnabled() ? Math.round(v / GRID_SIZE) * GRID_SIZE : v;\n}\n\nexport function snapPoint(p: [number, number]): [number, number] {\n return [snap(p[0]), snap(p[1])];\n}\n","/**\n * Drop / place near-a-bus auto-tap helper. When the user drops a palette item\n * within reach of an existing bus, attach the new element's \"tap-side\"\n * terminal to that bus via a `Wire` — instead of just dropping the element\n * in free space.\n *\n * Tap-side picking: the element's terminal closest to the bus axis (smallest\n * |y - bus.y| in canvas coords for horizontal buses), so the body extends\n * away from the bus naturally.\n */\n\nimport { libraryById } from '../element-library';\nimport type {\n BusId,\n DiagramFile,\n Element,\n ElementId,\n LibraryEntry,\n LibraryTerminal,\n Orientation,\n Placement,\n TerminalRef,\n Wire,\n WireEnd,\n} from '../model';\nimport { newElementId, useEditorStore, wireIdFromEnds } from '../store';\nimport { snap } from './grid';\n\nconst PROXIMITY_PX = 30;\nconst CLICK_SLOP_SQ = 12 * 12;\n\nexport interface DropResult {\n newElementId: ElementId;\n attachedToBus: boolean;\n}\n\nexport function dropElement(kind: string, at: [number, number]): DropResult {\n const lib = libraryById[kind];\n const store = useEditorStore.getState();\n const diagram = store.diagram;\n\n // Busbar drops are handled by BusbarTool directly. Bus-on-bus = nonsense.\n if (!lib || kind === 'busbar') {\n const id = store.addElement(kind, at);\n return { newElementId: id, attachedToBus: false };\n }\n\n const target = nearestBus(diagram, at);\n if (!target) {\n const cursorPin = pickPlaceCursorTerminal(lib);\n const placedAt: [number, number] = cursorPin\n ? [snap(at[0]) - cursorPin.x, snap(at[1]) - cursorPin.y]\n : [snap(at[0]), snap(at[1])];\n const id = store.addElement(kind, placedAt);\n return { newElementId: id, attachedToBus: false };\n }\n\n const { busId, busAt, axis } = target;\n const tapPin = pickTapTerminal(lib, axis);\n const newId = newElementId(diagram, kind);\n\n const tapLocal = lib.terminals.find((t) => t.id === tapPin);\n const dropX = axis === 'x' ? at[0] : busAt[0];\n const dropY = axis === 'y' ? at[1] : busAt[1];\n const placedAt: [number, number] = tapLocal\n ? [snap(dropX) - tapLocal.x, snap(dropY) - tapLocal.y]\n : [snap(at[0]), snap(at[1])];\n\n store.dispatch((d) => {\n const newElement: Element = { id: newId, kind };\n const placement: Placement = { at: placedAt };\n const newEnd = `${newId}.${tapPin}` as TerminalRef;\n const wire: Wire = {\n id: wireIdFromEnds(busId, newEnd),\n ends: [busId, newEnd],\n };\n return {\n ...d,\n elements: [...d.elements, newElement],\n wires: [...(d.wires ?? []), wire],\n layout: { ...(d.layout ?? {}), [newId]: placement },\n };\n });\n\n store.setSelection([newId]);\n return { newElementId: newId, attachedToBus: true };\n}\n\ninterface NearestBus {\n busId: BusId;\n busAt: [number, number];\n axis: 'x' | 'y';\n}\n\nfunction nearestBus(d: DiagramFile, at: [number, number]): NearestBus | null {\n const internal = useEditorStore.getState().internal;\n let best: NearestBus & { dist: number } | null = null;\n for (const bus of d.buses ?? []) {\n const rb = internal.buses.get(bus.id);\n if (!rb) continue;\n const { axis, at: busAt, span } = rb.geometry;\n let dist: number;\n if (axis === 'x') {\n const minX = busAt[0] - span / 2;\n const maxX = busAt[0] + span / 2;\n const dx = at[0] < minX ? minX - at[0] : at[0] > maxX ? at[0] - maxX : 0;\n const dy = Math.abs(at[1] - busAt[1]);\n dist = Math.sqrt(dx * dx + dy * dy);\n } else {\n const minY = busAt[1] - span / 2;\n const maxY = busAt[1] + span / 2;\n const dy = at[1] < minY ? minY - at[1] : at[1] > maxY ? at[1] - maxY : 0;\n const dx = Math.abs(at[0] - busAt[0]);\n dist = Math.sqrt(dx * dx + dy * dy);\n }\n if (dist <= PROXIMITY_PX && (!best || dist < best.dist)) {\n best = { busId: bus.id, busAt: [busAt[0], busAt[1]], axis, dist };\n }\n }\n if (!best) return null;\n return { busId: best.busId, busAt: best.busAt, axis: best.axis };\n}\n\nfunction pickTapTerminal(lib: LibraryEntry, busAxis: 'x' | 'y'): string {\n if (lib.terminals.length === 0) return 't';\n const sorted = [...lib.terminals].sort((a, b) =>\n busAxis === 'x' ? a.y - b.y : a.x - b.x,\n );\n return sorted[0].id;\n}\n\n/**\n * The library terminal that should sit at the cursor while a free placement\n * is in progress — same \"tap-side\" rule as `pickTapTerminal`, returned as a\n * full terminal so callers can offset placement (or the place ghost) so the\n * cursor visually holds that pin instead of the element's hotspot.\n *\n * Stretchable kinds don't have a meaningful tap; returns null and callers\n * use the element's hotspot.\n */\nexport function pickPlaceCursorTerminal(\n lib: LibraryEntry,\n): LibraryTerminal | null {\n if (!lib || lib.stretchable || lib.terminals.length === 0) return null;\n const sorted = [...lib.terminals].sort((a, b) => a.y - b.y);\n return sorted[0];\n}\n\n/**\n * Resolved place-source: world coords + orientation of the terminal we're\n * dragging from. Handles both real device terminals and a bare bus id\n * (projected onto the bus axis at the cursor point, with orientation flipped\n * to point toward the drag side so the new element body extends away).\n */\nexport interface PlaceSource {\n ref: WireEnd;\n world: [number, number];\n orientation: Orientation;\n /** True iff `ref` is a bus id (bare, no dot). */\n isBus: boolean;\n /** Set when isBus. */\n busId?: BusId;\n}\n\nexport function resolvePlaceSource(\n ref: WireEnd,\n cursorWorld: [number, number],\n): PlaceSource | null {\n const internal = useEditorStore.getState().internal;\n if (!ref.includes('.') && internal.buses.has(ref)) {\n const rb = internal.buses.get(ref)!;\n const { axis, at, span } = rb.geometry;\n if (axis === 'x') {\n const minX = at[0] - span / 2;\n const maxX = at[0] + span / 2;\n const x = Math.max(minX, Math.min(maxX, cursorWorld[0]));\n const y = at[1];\n const orientation: Orientation = cursorWorld[1] >= y ? 's' : 'n';\n return { ref, world: [x, y], orientation, isBus: true, busId: ref };\n }\n const minY = at[1] - span / 2;\n const maxY = at[1] + span / 2;\n const y = Math.max(minY, Math.min(maxY, cursorWorld[1]));\n const x = at[0];\n const orientation: Orientation = cursorWorld[0] >= x ? 'e' : 'w';\n return { ref, world: [x, y], orientation, isBus: true, busId: ref };\n }\n const term = internal.terminals.get(ref as `${string}.${string}`);\n if (term) {\n return {\n ref,\n world: term.world,\n orientation: term.orientation,\n isBus: false,\n };\n }\n return null;\n}\n\nconst OPPOSITE: Record<Orientation, Orientation> = {\n n: 's',\n s: 'n',\n e: 'w',\n w: 'e',\n};\n\n/**\n * Pick which terminal of the new element should connect to the source.\n * Prefer a terminal whose orientation is opposite to the source's (so the\n * body extends naturally *away* from the source). Tie-break by world\n * distance to source.\n */\nexport function pickConnectTerminal(\n lib: LibraryEntry,\n source: PlaceSource,\n placeAt: [number, number],\n): LibraryTerminal {\n if (lib.terminals.length === 0) {\n return { id: 't', x: 0, y: 0, orientation: 'n' };\n }\n const wantOrient = OPPOSITE[source.orientation];\n const opposites = lib.terminals.filter((t) => t.orientation === wantOrient);\n const pool = opposites.length > 0 ? opposites : lib.terminals;\n let best = pool[0];\n let bestDist = termWorldDist(best, placeAt, source.world);\n for (let i = 1; i < pool.length; i++) {\n const t = pool[i];\n const d = termWorldDist(t, placeAt, source.world);\n if (d < bestDist) {\n bestDist = d;\n best = t;\n }\n }\n return best;\n}\n\nfunction termWorldDist(\n t: LibraryTerminal,\n placeAt: [number, number],\n source: [number, number],\n): number {\n const dx = placeAt[0] + t.x - source[0];\n const dy = placeAt[1] + t.y - source[1];\n return dx * dx + dy * dy;\n}\n\n/**\n * Place a new element with one of its terminals connected to `sourceRef` in\n * a single undo step.\n */\nexport function dropElementFromTerminal(\n kind: string,\n sourceRef: WireEnd,\n cursorAt: [number, number],\n): DropResult | null {\n const lib = libraryById[kind];\n const store = useEditorStore.getState();\n const diagram = store.diagram;\n if (!lib) return null;\n\n const source = resolvePlaceSource(sourceRef, cursorAt);\n if (!source) return null;\n\n const dx = cursorAt[0] - source.world[0];\n const dy = cursorAt[1] - source.world[1];\n const treatAsClick = dx * dx + dy * dy <= CLICK_SLOP_SQ;\n const cursorPlaceAt: [number, number] = [snap(cursorAt[0]), snap(cursorAt[1])];\n const chosen = pickConnectTerminal(lib, source, cursorPlaceAt);\n // The chosen pin lands at the anchor — `source.world` for a tap (so the\n // pin meets the source terminal) or the cursor for a drag (so the visible\n // PlaceGhost, which already anchors the chosen pin to the cursor, matches\n // where the element actually lands).\n const anchor = treatAsClick ? source.world : cursorPlaceAt;\n const placedAt: [number, number] = [\n snap(anchor[0] - chosen.x),\n snap(anchor[1] - chosen.y),\n ];\n const newId = newElementId(diagram, kind);\n\n store.dispatch((d) => {\n const newElement: Element = { id: newId, kind };\n const placement: Placement = { at: placedAt };\n const newPinRef = `${newId}.${chosen.id}` as TerminalRef;\n const tieEnd: WireEnd = source.isBus && source.busId ? source.busId : sourceRef;\n const wire: Wire = {\n id: wireIdFromEnds(tieEnd, newPinRef),\n ends: [tieEnd, newPinRef],\n };\n return {\n ...d,\n elements: [...d.elements, newElement],\n wires: [...(d.wires ?? []), wire],\n layout: { ...(d.layout ?? {}), [newId]: placement },\n };\n });\n\n store.setSelection([newId]);\n return { newElementId: newId, attachedToBus: source.isBus };\n}\n","/**\n * Structural label helpers shared by the canvas annotation layer and the\n * SVG / DXF exporters. Keeping these in one place ensures the three surfaces\n * stay byte-identical: what the user sees on the canvas is what lands in the\n * exported file.\n */\n\nimport type { ResolvedElement, ResolvedPlacement } from '../compiler';\nimport type { LabelMode, LibraryEntry, LibraryLabelAnchor } from '../model';\n\n/** Vertical step between stacked label lines, in canvas units. */\nexport const LABEL_LINE_HEIGHT = 9;\n\n/** Font size used for element structural labels, in canvas units. */\nexport const LABEL_FONT_SIZE = 7;\n\nexport function labelLines(re: ResolvedElement, mode: LabelMode): string[] {\n const lines: string[] = [];\n const head = re.element.name?.trim() || re.element.id;\n if (head) lines.push(head);\n if (mode !== 'all' || !re.libraryDef?.params) return lines;\n const params = re.element.params ?? {};\n for (const p of re.libraryDef.params) {\n if (!p.showOnCanvas) continue;\n const v = params[p.name];\n if (v === undefined || v === null || v === '') continue;\n lines.push(`${v}${p.unit ?? ''}`);\n }\n return lines;\n}\n\nexport function fallbackAnchor(lib: LibraryEntry): LibraryLabelAnchor {\n const vb = parseViewBox(lib.viewBox);\n if (!vb) return { x: 0, y: 0, anchor: 'start' };\n return { x: vb.x + vb.w + 2, y: vb.y + 4, anchor: 'start' };\n}\n\n/**\n * Project the library-local anchor through the element's placement so the\n * label lands next to the symbol regardless of rotation/mirror, but the text\n * itself stays upright (we never rotate the label group).\n */\nexport function anchorWorld(\n anchor: LibraryLabelAnchor,\n place: ResolvedPlacement,\n): [number, number] {\n let x = anchor.x;\n let y = anchor.y;\n if (place.mirror) x = -x;\n switch (place.rot) {\n case 90:\n [x, y] = [-y, x];\n break;\n case 180:\n [x, y] = [-x, -y];\n break;\n case 270:\n [x, y] = [y, -x];\n break;\n default:\n break;\n }\n return [x + place.at[0], y + place.at[1]];\n}\n\nfunction parseViewBox(\n s: string,\n): { x: number; y: number; w: number; h: number } | null {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n","/**\n * Renders structural labels (element ID + showOnCanvas params) next to each\n * element. Labels are derived purely from `Element` data and the library\n * schema — they do not live in the diagram's serialized form.\n *\n * The label block is positioned at the world projection of the element's\n * `LibraryEntry.label` anchor (or a viewBox-derived fallback). Element\n * rotation moves the anchor accordingly, but the text itself is rendered\n * upright (no rotate on the text group) so labels stay readable.\n *\n * Visibility is governed by `DiagramFile.meta.labelMode`:\n * - 'off' → no labels.\n * - 'id' → element name/ID only.\n * - 'all' → ID plus each library param marked `showOnCanvas: true`.\n * Default when unset: 'all'.\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useEditorStore } from '../store';\nimport type { LabelMode } from '../model';\nimport {\n LABEL_LINE_HEIGHT as LINE_HEIGHT,\n anchorWorld,\n fallbackAnchor,\n labelLines,\n} from '../lib/element-labels';\n\nexport function AnnotationLayer() {\n const elements = useEditorStore((s) => s.internal.elements);\n const layout = useEditorStore((s) => s.internal.layout);\n const mode: LabelMode = useEditorStore(\n (s) => s.diagram.meta?.labelMode ?? 'all',\n );\n const editingElement = useEditorStore((s) => s.editingElement);\n\n return (\n <g className=\"ole-annotation-layer\" pointerEvents=\"none\">\n {Array.from(elements.values()).map((re) => {\n const place = layout.get(re.element.id);\n if (!place || !re.libraryDef) return null;\n const anchor = re.libraryDef.label ?? fallbackAnchor(re.libraryDef);\n const world = anchorWorld(anchor, place);\n const textAnchor = anchor.anchor ?? 'start';\n if (editingElement === re.element.id) {\n return (\n <NameEditor\n key={re.element.id}\n elementId={re.element.id}\n currentName={re.element.name?.trim() || re.element.id}\n world={world}\n anchor={textAnchor}\n />\n );\n }\n if (mode === 'off') return null;\n const lines = labelLines(re, mode);\n if (lines.length === 0) return null;\n return (\n <g\n key={re.element.id}\n className=\"ole-annotation\"\n transform={`translate(${world[0]} ${world[1]})`}\n >\n {lines.map((line, i) => (\n <text\n key={i}\n x={0}\n y={i * LINE_HEIGHT}\n textAnchor={textAnchor}\n className=\"ole-annotation-text\"\n >\n {line}\n </text>\n ))}\n </g>\n );\n })}\n </g>\n );\n}\n\nconst EDITOR_W = 200;\nconst EDITOR_FS = 9;\n\n/**\n * In-place editor for an element's `name`. Mounted at the same anchor as\n * the structural label so the inline edit happens where the user expects\n * to see the name. Empty content clears the override (label falls back to\n * the element's ID); non-empty content sets `Element.name`.\n */\nfunction NameEditor({\n elementId,\n currentName,\n world,\n anchor,\n}: {\n elementId: string;\n currentName: string;\n world: [number, number];\n anchor: 'start' | 'middle' | 'end';\n}) {\n const ref = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n el.focus();\n const range = document.createRange();\n range.selectNodeContents(el);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n }, [elementId]);\n\n function commit(): void {\n const store = useEditorStore.getState();\n const el = store.diagram.elements.find((x) => x.id === elementId);\n if (!el) {\n store.setEditingElement(null);\n return;\n }\n const text = (ref.current?.innerText ?? '').replace(/\\u00a0/g, ' ').trim();\n // Empty text clears the override; the structural label falls back to ID.\n const next = text === '' || text === elementId ? undefined : text;\n if (next !== el.name) store.updateElement(elementId, { name: next });\n store.setEditingElement(null);\n }\n\n function onKeyDown(e: React.KeyboardEvent<HTMLDivElement>): void {\n if (e.key === 'Escape' || (e.key === 'Enter' && !e.shiftKey)) {\n e.preventDefault();\n commit();\n return;\n }\n e.stopPropagation();\n }\n\n // Position the foreignObject so the contentEditable's left edge matches\n // the requested SVG text-anchor — text-anchor is glyph-relative, but our\n // editor is a div without that semantic, so we translate by hand.\n let x = world[0];\n if (anchor === 'middle') x -= EDITOR_W / 2;\n else if (anchor === 'end') x -= EDITOR_W;\n\n return (\n <foreignObject\n x={x}\n y={world[1] - EDITOR_FS}\n width={EDITOR_W}\n height={EDITOR_FS * 2.2}\n className=\"ole-element-name-editor\"\n >\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={commit}\n onKeyDown={onKeyDown}\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n style={{\n fontSize: `${EDITOR_FS}px`,\n fontFamily: 'ui-sans-serif, system-ui, sans-serif',\n color: 'var(--foreground)',\n background: 'var(--canvas-bg)',\n outline: '1px dashed var(--selection)',\n padding: '0 2px',\n display: 'inline-block',\n minWidth: '20px',\n lineHeight: 1.1,\n textAlign:\n anchor === 'middle' ? 'center' : anchor === 'end' ? 'right' : 'left',\n whiteSpace: 'nowrap',\n cursor: 'text',\n }}\n >\n {currentName}\n </div>\n </foreignObject>\n );\n}\n\n","/**\n * Renders user-created free text annotations from `diagram.annotations`.\n * Each annotation is a draggable, editable note unattached to any element.\n *\n * Three render states per annotation:\n * 1. Idle → `<text>` painted at its position.\n * 2. Selected (idle) → text plus a dashed bbox halo (matches element halo).\n * 3. Editing → `<foreignObject>` hosting a contentEditable div;\n * autoselects content on entry, commits on Enter or\n * blur, drops empty content on commit (auto-cleanup\n * of empty annotations created by the text tool).\n *\n * Hit-testing carries the annotation's id via `data-annotation-id` so tools\n * can route the gesture without React state lookups, mirroring how elements\n * use `data-element-id`.\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useEditorStore } from '../store';\nimport type { TextAnnotation } from '../model';\n\nconst DEFAULT_FONT_SIZE = 8;\nconst LINE_HEIGHT = 1.25;\n\nexport function FreeAnnotationLayer() {\n const annotations = useEditorStore((s) => s.diagram.annotations);\n const selected = useEditorStore((s) => s.selectedAnnotation);\n const editing = useEditorStore((s) => s.editingAnnotation);\n\n if (!annotations || annotations.length === 0) return null;\n\n return (\n <g className=\"ole-free-annotation-layer\">\n {annotations.map((a) =>\n editing === a.id ? (\n <EditingAnnotation key={a.id} ann={a} />\n ) : (\n <IdleAnnotation\n key={a.id}\n ann={a}\n isSelected={selected === a.id}\n />\n ),\n )}\n </g>\n );\n}\n\nfunction IdleAnnotation({\n ann,\n isSelected,\n}: {\n ann: TextAnnotation;\n isSelected: boolean;\n}) {\n const fs = ann.fontSize ?? DEFAULT_FONT_SIZE;\n const lines = ann.text === '' ? [''] : ann.text.split('\\n');\n // Reasonable bbox estimate purely for the selection halo. Width is heuristic\n // (avg ~0.55 em per char); the actual click hit is on the text glyphs.\n const widthGuess = Math.max(\n 20,\n ...lines.map((l) => l.length * fs * 0.55),\n );\n const heightGuess = lines.length * fs * LINE_HEIGHT;\n return (\n <g\n data-annotation-id={ann.id}\n className=\"ole-free-annotation\"\n data-selected={isSelected ? 'true' : undefined}\n >\n {/* Invisible hit-rect for easier dragging on whitespace within the text block. */}\n <rect\n x={ann.at[0] - 1}\n y={ann.at[1] - 1}\n width={widthGuess + 2}\n height={heightGuess + 2}\n fill=\"transparent\"\n className=\"ole-free-annotation-hit\"\n />\n {isSelected && (\n <rect\n x={ann.at[0] - 1}\n y={ann.at[1] - 1}\n width={widthGuess + 2}\n height={heightGuess + 2}\n className=\"ole-free-annotation-halo\"\n />\n )}\n {lines.map((line, i) => (\n <text\n key={i}\n x={ann.at[0]}\n y={ann.at[1] + fs * 0.85 + i * fs * LINE_HEIGHT}\n fontSize={fs}\n className=\"ole-free-annotation-text\"\n >\n {line}\n </text>\n ))}\n </g>\n );\n}\n\nfunction EditingAnnotation({ ann }: { ann: TextAnnotation }) {\n const ref = useRef<HTMLDivElement | null>(null);\n const fs = ann.fontSize ?? DEFAULT_FONT_SIZE;\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n el.focus();\n // Place caret at end and select-all so users can immediately type to\n // replace placeholder content (matches Figma / Keynote text-tool flow).\n const range = document.createRange();\n range.selectNodeContents(el);\n const sel = window.getSelection();\n sel?.removeAllRanges();\n sel?.addRange(range);\n }, [ann.id]);\n\n function commit(): void {\n const store = useEditorStore.getState();\n const text = (ref.current?.innerText ?? '').replace(/\\u00a0/g, ' ').trimEnd();\n if (text === '') {\n store.deleteAnnotation(ann.id);\n } else if (text !== ann.text) {\n store.updateAnnotation(ann.id, { text });\n }\n store.setEditingAnnotation(null);\n if (text !== '') store.setSelectedAnnotation(ann.id);\n // Hand control back to the select tool — text mode is for one-off drops.\n if (store.activeTool === 'text') store.setActiveTool('select');\n }\n\n function onKeyDown(e: React.KeyboardEvent<HTMLDivElement>): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n commit();\n return;\n }\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n commit();\n return;\n }\n // Keep typing keys from leaking to global hotkeys (e.g. Delete deleting\n // the selection while the user is editing text).\n e.stopPropagation();\n }\n\n // foreignObject must be sized in canvas units; pick a generous box so the\n // editor can grow without clipping.\n const W = 320;\n const H = 200;\n return (\n <foreignObject\n x={ann.at[0]}\n y={ann.at[1]}\n width={W}\n height={H}\n data-annotation-id={ann.id}\n className=\"ole-free-annotation-edit-fo\"\n >\n <div\n ref={ref}\n contentEditable\n suppressContentEditableWarning\n onBlur={commit}\n onKeyDown={onKeyDown}\n // The pointer events handler in useTools captures pointerdown on the\n // host before this; stop it here so clicks inside the editor don't\n // commit and re-enter unexpectedly.\n onPointerDown={(e) => e.stopPropagation()}\n onMouseDown={(e) => e.stopPropagation()}\n style={{\n fontSize: `${fs}px`,\n lineHeight: LINE_HEIGHT,\n fontFamily: 'ui-sans-serif, system-ui, sans-serif',\n color: 'var(--foreground)',\n background: 'var(--canvas-bg)',\n outline: '1px dashed var(--selection)',\n padding: '0 2px',\n minWidth: `${fs}px`,\n minHeight: `${fs * LINE_HEIGHT}px`,\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n cursor: 'text',\n }}\n >\n {ann.text}\n </div>\n </foreignObject>\n );\n}\n","/**\n * Stretch handles for the selected bus. Two `<circle>` grips at the bus's\n * endpoints. Dragging a grip updates the bus's `span`, and — for the\n * trailing grip — shifts `at` so the opposite end stays fixed visually.\n *\n * Handles capture pointer events themselves; SelectTool sees the drag start\n * on a non-element target and won't try to also move the bus body.\n */\n\nimport { useRef } from 'react';\nimport { useEditorStore } from '../store';\nimport type { BusId } from '../model';\nimport { getViewportApi } from './viewport-bus';\nimport { isSnapEnabled, GRID_SIZE } from './grid';\n\nconst MIN_SPAN = 20;\n\nexport function BusHandles() {\n const selection = useEditorStore((s) => s.selection);\n const internal = useEditorStore((s) => s.internal);\n\n if (selection.length !== 1) return null;\n const id = selection[0];\n const rb = internal.buses.get(id);\n if (!rb) return null;\n\n const { axis, at, span } = rb.geometry;\n const half = span / 2;\n const startWorld: [number, number] =\n axis === 'x' ? [at[0] - half, at[1]] : [at[0], at[1] - half];\n const endWorld: [number, number] =\n axis === 'x' ? [at[0] + half, at[1]] : [at[0], at[1] + half];\n\n return (\n <g className=\"ole-bus-handles\" pointerEvents=\"auto\">\n <Handle\n x={startWorld[0]}\n y={startWorld[1]}\n busId={id}\n side=\"start\"\n axis={axis}\n />\n <Handle\n x={endWorld[0]}\n y={endWorld[1]}\n busId={id}\n side=\"end\"\n axis={axis}\n />\n </g>\n );\n}\n\nfunction Handle({\n x,\n y,\n busId,\n side,\n axis,\n}: {\n x: number;\n y: number;\n busId: BusId;\n side: 'start' | 'end';\n axis: 'x' | 'y';\n}) {\n const viewport = getViewportApi();\n const dragRef = useRef<{\n pointerId: number;\n startSpan: number;\n startAt: [number, number];\n startSvg: [number, number];\n } | null>(null);\n\n const onPointerDown = (e: React.PointerEvent<SVGCircleElement>) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n if (!viewport) return;\n const rb = useEditorStore.getState().internal.buses.get(busId);\n if (!rb) return;\n dragRef.current = {\n pointerId: e.pointerId,\n startSpan: rb.geometry.span,\n startAt: [...rb.geometry.at],\n startSvg: viewport.screenToSvg(e.clientX, e.clientY),\n };\n (e.target as SVGCircleElement).setPointerCapture(e.pointerId);\n };\n\n const onPointerMove = (e: React.PointerEvent<SVGCircleElement>) => {\n const drag = dragRef.current;\n if (!drag || e.pointerId !== drag.pointerId || !viewport) return;\n const cur = viewport.screenToSvg(e.clientX, e.clientY);\n const dRaw = axis === 'x' ? cur[0] - drag.startSvg[0] : cur[1] - drag.startSvg[1];\n const d = isSnapEnabled() ? Math.round(dRaw / GRID_SIZE) * GRID_SIZE : dRaw;\n\n const span = drag.startSpan + (side === 'end' ? d : -d);\n if (span < MIN_SPAN) return;\n const at: [number, number] =\n axis === 'x'\n ? [drag.startAt[0] + d / 2, drag.startAt[1]]\n : [drag.startAt[0], drag.startAt[1] + d / 2];\n\n useEditorStore.getState().updateBus(busId, { span, at });\n };\n\n const onPointerUp = (e: React.PointerEvent<SVGCircleElement>) => {\n const drag = dragRef.current;\n if (!drag || e.pointerId !== drag.pointerId) return;\n if ((e.target as SVGCircleElement).hasPointerCapture(e.pointerId)) {\n (e.target as SVGCircleElement).releasePointerCapture(e.pointerId);\n }\n dragRef.current = null;\n };\n\n return (\n <circle\n className=\"ole-bus-handle\"\n cx={x}\n cy={y}\n r={5}\n data-handle={side}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n onPointerCancel={onPointerUp}\n />\n );\n}\n","/**\n * Edit affordances for the selected wire's polyline path.\n *\n * Two handle kinds:\n * - Vertex handle (filled): drag a corner; adjacent segments are\n * synced to stay axis-aligned (H stays H, V stays V).\n * - Midpoint handle (hollow): drag a segment perpendicular to its\n * axis; inserts two new corners so the segment shifts in parallel.\n *\n * Endpoints (path[0], path[n-1]) are not draggable — they're locked to\n * terminals / bus anchors. A vertex with no remaining degree of freedom\n * (both neighbors are endpoint-adjacent on perpendicular axes — i.e.\n * the corner of a pure L) gets no handle: use the midpoint to add bends.\n *\n * The drag source is `internal.wireRenders[id].path` (works for both\n * manual paths and auto-routed paths — first edit materializes the\n * auto-routed path into `Wire.path`).\n */\n\nimport { useRef } from 'react';\nimport { useEditorStore } from '../store';\nimport type { WireId } from '../model';\nimport { getViewportApi } from './viewport-bus';\nimport { snap } from './grid';\n\ntype Pt = [number, number];\ntype Axis = 'h' | 'v';\n\nconst EPS = 0.5;\n\nfunction segAxis(a: Pt, b: Pt): Axis {\n return Math.abs(a[1] - b[1]) < EPS ? 'h' : 'v';\n}\n\nexport function WireHandles() {\n const selectedWire = useEditorStore((s) => s.selectedWire);\n const wireRenders = useEditorStore((s) => s.internal.wireRenders);\n\n if (!selectedWire) return null;\n const render = wireRenders.get(selectedWire);\n if (!render || render.path.length < 2) return null;\n\n const path = render.path;\n const n = path.length;\n\n // Interior vertex handles — only when at least one axis is free.\n const vertexHandles = [];\n for (let i = 1; i < n - 1; i++) {\n const prevAxis = segAxis(path[i - 1], path[i]);\n const nextAxis = segAxis(path[i], path[i + 1]);\n const prevEndpoint = i - 1 === 0;\n const nextEndpoint = i + 1 === n - 1;\n // A coordinate is locked when an endpoint-adjacent segment anchors it.\n // Horizontal segment to a fixed endpoint locks y; vertical locks x.\n const xLocked =\n (prevEndpoint && prevAxis === 'v') || (nextEndpoint && nextAxis === 'v');\n const yLocked =\n (prevEndpoint && prevAxis === 'h') || (nextEndpoint && nextAxis === 'h');\n if (xLocked && yLocked) continue;\n vertexHandles.push(\n <VertexHandle\n key={`v-${i}`}\n wireId={selectedWire}\n index={i}\n xLocked={xLocked}\n yLocked={yLocked}\n />,\n );\n }\n\n // Segment midpoint handles — one per segment.\n const midHandles = [];\n for (let s = 0; s < n - 1; s++) {\n const a = path[s];\n const b = path[s + 1];\n if (Math.abs(a[0] - b[0]) < EPS && Math.abs(a[1] - b[1]) < EPS) continue;\n midHandles.push(\n <MidpointHandle\n key={`m-${s}`}\n wireId={selectedWire}\n segIndex={s}\n axis={segAxis(a, b)}\n />,\n );\n }\n\n return (\n <g className=\"ole-wire-handles\" pointerEvents=\"auto\">\n {midHandles}\n {vertexHandles}\n </g>\n );\n}\n\nfunction VertexHandle({\n wireId,\n index,\n xLocked,\n yLocked,\n}: {\n wireId: WireId;\n index: number;\n xLocked: boolean;\n yLocked: boolean;\n}) {\n const viewport = getViewportApi();\n // dragRef snapshots the bits that pointermove needs. We deliberately do\n // NOT re-read them from props — the path mutates during the drag and a\n // re-render with shifted props would make subsequent moves contradict\n // the earlier moves (the H↔V oscillation the user reported).\n const dragRef = useRef<{\n pointerId: number;\n startPath: Pt[];\n startSvg: Pt;\n index: number;\n xLocked: boolean;\n yLocked: boolean;\n } | null>(null);\n\n const path = useEditorStore((s) => s.internal.wireRenders.get(wireId)?.path);\n if (!path || index <= 0 || index >= path.length - 1) return null;\n const [cx, cy] = path[index];\n\n const cursor = xLocked && !yLocked ? 'ns-resize' : !xLocked && yLocked ? 'ew-resize' : 'move';\n\n const onPointerDown = (e: React.PointerEvent<SVGCircleElement>) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n if (!viewport) return;\n const cur = useEditorStore.getState().internal.wireRenders.get(wireId);\n if (!cur) return;\n dragRef.current = {\n pointerId: e.pointerId,\n startPath: cur.path.map((p) => [p[0], p[1]] as Pt),\n startSvg: viewport.screenToSvg(e.clientX, e.clientY),\n index,\n xLocked,\n yLocked,\n };\n document.body.style.cursor = cursor;\n (e.target as SVGCircleElement).setPointerCapture(e.pointerId);\n };\n\n const onPointerMove = (e: React.PointerEvent<SVGCircleElement>) => {\n const drag = dragRef.current;\n if (!drag || e.pointerId !== drag.pointerId || !viewport) return;\n const cur = viewport.screenToSvg(e.clientX, e.clientY);\n const sp = drag.startPath;\n const idx = drag.index;\n if (idx <= 0 || idx >= sp.length - 1) return;\n const orig = sp[idx];\n const newPos: Pt = [\n drag.xLocked ? orig[0] : snap(orig[0] + (cur[0] - drag.startSvg[0])),\n drag.yLocked ? orig[1] : snap(orig[1] + (cur[1] - drag.startSvg[1])),\n ];\n if (newPos[0] === orig[0] && newPos[1] === orig[1]) return;\n\n const next = sp.map((p) => [p[0], p[1]] as Pt);\n next[idx] = newPos;\n const prevAxis = segAxis(sp[idx - 1], sp[idx]);\n if (idx - 1 > 0) {\n if (prevAxis === 'h') next[idx - 1] = [sp[idx - 1][0], newPos[1]];\n else next[idx - 1] = [newPos[0], sp[idx - 1][1]];\n }\n const nextAxis = segAxis(sp[idx], sp[idx + 1]);\n if (idx + 1 < sp.length - 1) {\n if (nextAxis === 'h') next[idx + 1] = [sp[idx + 1][0], newPos[1]];\n else next[idx + 1] = [newPos[0], sp[idx + 1][1]];\n }\n useEditorStore.getState().updateWirePath(wireId, next);\n };\n\n const finishDrag = (e: React.PointerEvent<SVGCircleElement>) => {\n const drag = dragRef.current;\n if (!drag || e.pointerId !== drag.pointerId) return;\n if ((e.target as SVGCircleElement).hasPointerCapture(e.pointerId)) {\n (e.target as SVGCircleElement).releasePointerCapture(e.pointerId);\n }\n dragRef.current = null;\n document.body.style.cursor = '';\n };\n\n const onDoubleClick = (e: React.MouseEvent<SVGCircleElement>) => {\n e.stopPropagation();\n e.preventDefault();\n const cur = useEditorStore.getState().internal.wireRenders.get(wireId);\n if (!cur || cur.path.length <= 2) return;\n if (index <= 0 || index >= cur.path.length - 1) return;\n const removed = cur.path.filter((_, i) => i !== index);\n useEditorStore.getState().updateWirePath(wireId, removed);\n };\n\n return (\n <circle\n className=\"ole-wire-handle ole-wire-vertex\"\n cx={cx}\n cy={cy}\n r={5}\n style={{ cursor }}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={finishDrag}\n onPointerCancel={finishDrag}\n onDoubleClick={onDoubleClick}\n />\n );\n}\n\nfunction MidpointHandle({\n wireId,\n segIndex,\n axis,\n}: {\n wireId: WireId;\n segIndex: number;\n axis: Axis;\n}) {\n const viewport = getViewportApi();\n // dragRef pins axis + segIndex for the lifetime of the gesture. After the\n // first move splits the segment, the *live* prop `axis` flips H↔V on the\n // next render — if we re-read it here, the gesture would oscillate\n // between two shapes every frame.\n const dragRef = useRef<{\n pointerId: number;\n startPath: Pt[];\n startSvg: Pt;\n axis: Axis;\n segIndex: number;\n } | null>(null);\n\n const path = useEditorStore((s) => s.internal.wireRenders.get(wireId)?.path);\n if (!path || segIndex < 0 || segIndex >= path.length - 1) return null;\n const a = path[segIndex];\n const b = path[segIndex + 1];\n const cx = (a[0] + b[0]) / 2;\n const cy = (a[1] + b[1]) / 2;\n\n const cursor = axis === 'h' ? 'ns-resize' : 'ew-resize';\n\n const onPointerDown = (e: React.PointerEvent<SVGElement>) => {\n if (e.button !== 0) return;\n e.stopPropagation();\n e.preventDefault();\n if (!viewport) return;\n const cur = useEditorStore.getState().internal.wireRenders.get(wireId);\n if (!cur) return;\n dragRef.current = {\n pointerId: e.pointerId,\n startPath: cur.path.map((p) => [p[0], p[1]] as Pt),\n startSvg: viewport.screenToSvg(e.clientX, e.clientY),\n axis,\n segIndex,\n };\n document.body.style.cursor = cursor;\n (e.currentTarget as SVGElement).setPointerCapture(e.pointerId);\n };\n\n const onPointerMove = (e: React.PointerEvent<SVGElement>) => {\n const drag = dragRef.current;\n if (!drag || e.pointerId !== drag.pointerId || !viewport) return;\n const cur = viewport.screenToSvg(e.clientX, e.clientY);\n const sp = drag.startPath;\n const seg = drag.segIndex;\n if (seg >= sp.length - 1) return;\n const segA = sp[seg];\n const segB = sp[seg + 1];\n const built: Pt[] = [];\n for (let i = 0; i <= seg; i++) built.push(sp[i]);\n if (drag.axis === 'h') {\n const newY = snap(segA[1] + (cur[1] - drag.startSvg[1]));\n built.push([segA[0], newY]);\n built.push([segB[0], newY]);\n } else {\n const newX = snap(segA[0] + (cur[0] - drag.startSvg[0]));\n built.push([newX, segA[1]]);\n built.push([newX, segB[1]]);\n }\n for (let i = seg + 1; i < sp.length; i++) built.push(sp[i]);\n useEditorStore.getState().updateWirePath(wireId, built);\n };\n\n const finishDrag = (e: React.PointerEvent<SVGElement>) => {\n const drag = dragRef.current;\n if (!drag || e.pointerId !== drag.pointerId) return;\n const t = e.currentTarget;\n if (t.hasPointerCapture(e.pointerId)) t.releasePointerCapture(e.pointerId);\n dragRef.current = null;\n document.body.style.cursor = '';\n };\n\n // Render at the true midpoint (no grid snap) so the handle sits exactly\n // on top of the visible wire — otherwise on diagonal or off-grid\n // segments the handle drifts away from where the user expects to click.\n return (\n <g\n className=\"ole-wire-handle ole-wire-midpoint-group\"\n style={{ cursor }}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={finishDrag}\n onPointerCancel={finishDrag}\n >\n {/* Invisible wider hit ring catches near-misses; the visible dot is\n smaller for visual polish. */}\n <circle\n className=\"ole-wire-midpoint-hit\"\n cx={cx}\n cy={cy}\n r={8}\n />\n <circle\n className=\"ole-wire-handle ole-wire-midpoint\"\n cx={cx}\n cy={cy}\n r={3.5}\n />\n </g>\n );\n}\n","/**\n * Renders one `<g>` per bus. Each bus is a horizontal or vertical line\n * segment whose length is `geometry.span` and direction is given by\n * `geometry.axis` (x → horizontal, y → vertical). Tagged with `data-bus-id`\n * so hit-test can identify clicks on the bus body.\n */\n\nimport { useEditorStore } from '../store';\n\nconst STROKE_WIDTH = 3;\n/** Invisible click target wider than the visible stroke, mirroring\n * ElementLayer's `HitRect`. */\nconst HIT_WIDTH = 12;\n\nexport function BusLayer() {\n const buses = useEditorStore((s) => s.internal.buses);\n const selection = useEditorStore((s) => s.selection);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const nodes = useEditorStore((s) => s.internal.nodes);\n const terminalToNode = useEditorStore((s) => s.internal.terminalToNode);\n const selSet = new Set(selection);\n\n // Buses whose ConnectivityNode is selected get a halo.\n const nodeRelatedBuses = new Set<string>();\n if (selectedNode) {\n const node = nodes.get(selectedNode);\n if (node) {\n for (const end of node.terminals) {\n if (!end.includes('.')) nodeRelatedBuses.add(end);\n }\n }\n }\n\n return (\n <g className=\"ole-bus-layer\">\n {Array.from(buses.values()).map(({ bus, geometry }) => {\n const { axis, at, span } = geometry;\n const half = span / 2;\n const x1 = axis === 'x' ? at[0] - half : at[0];\n const y1 = axis === 'x' ? at[1] : at[1] - half;\n const x2 = axis === 'x' ? at[0] + half : at[0];\n const y2 = axis === 'x' ? at[1] : at[1] + half;\n const isSelected = selSet.has(bus.id);\n const isNodeRelated = nodeRelatedBuses.has(bus.id);\n // Use the wire end's node id (if any) for `data-node-id` so a click\n // on the bus body resolves to its electrical node, mirroring the\n // wire layer's tagging convention.\n const nodeId = terminalToNode.get(bus.id) ?? undefined;\n // Wide invisible rect along the bus axis — gives a comfortable\n // click target without thickening the visible line.\n const hitHalf = HIT_WIDTH / 2;\n const hx = axis === 'x' ? at[0] - half : at[0] - hitHalf;\n const hy = axis === 'x' ? at[1] - hitHalf : at[1] - half;\n const hw = axis === 'x' ? span : HIT_WIDTH;\n const hh = axis === 'x' ? HIT_WIDTH : span;\n return (\n <g\n key={bus.id}\n data-bus-id={bus.id}\n data-element-id={bus.id}\n data-node-id={nodeId}\n data-selected={isSelected ? 'true' : undefined}\n data-node-related={isNodeRelated ? 'true' : undefined}\n className=\"ole-bus\"\n >\n <rect\n x={hx}\n y={hy}\n width={hw}\n height={hh}\n fill=\"transparent\"\n className=\"ole-bus-hit\"\n />\n <line\n x1={x1}\n y1={y1}\n x2={x2}\n y2={y2}\n stroke=\"black\"\n strokeWidth={STROKE_WIDTH}\n strokeLinecap=\"round\"\n fill=\"none\"\n />\n </g>\n );\n })}\n </g>\n );\n}\n","/**\n * Live preview for the busbar tool. Snaps the cursor to the dominant axis\n * (horizontal or vertical) so users see exactly the line that will be\n * created on pointerup.\n */\n\nimport { useEditorStore } from '../store';\n\nexport function BusbarPreview() {\n const start = useEditorStore((s) => s.busbarDrawStart);\n const cursor = useEditorStore((s) => s.cursorSvg);\n\n if (!start || !cursor) return null;\n\n const dx = cursor[0] - start[0];\n const dy = cursor[1] - start[1];\n const horizontal = Math.abs(dx) >= Math.abs(dy);\n const endX = horizontal ? cursor[0] : start[0];\n const endY = horizontal ? start[1] : cursor[1];\n\n return (\n <g className=\"ole-busbar-preview\" pointerEvents=\"none\">\n <line\n x1={start[0]}\n y1={start[1]}\n x2={endX}\n y2={endY}\n className=\"ole-busbar-preview-line\"\n />\n <circle\n cx={start[0]}\n cy={start[1]}\n r={3.5}\n className=\"ole-busbar-preview-anchor\"\n />\n <circle\n cx={endX}\n cy={endY}\n r={3.5}\n className=\"ole-busbar-preview-anchor\"\n />\n </g>\n );\n}\n","/**\n * Build the SVG `transform` string for a device placement. Buses are\n * rendered separately by `BusLayer` and don't go through this helper.\n *\n * Composition (SVG applies left-to-right, parent-frame first):\n * translate(at) → rotate(rot) → scale(mirror?-1:1, 1)\n */\n\nimport type { ResolvedPlacement } from '../compiler';\n\nexport function transformAttr(p: ResolvedPlacement): string {\n const parts = [`translate(${p.at[0]} ${p.at[1]})`];\n if (p.rot) parts.push(`rotate(${p.rot})`);\n if (p.mirror) parts.push(`scale(-1 1)`);\n return parts.join(' ');\n}\n","/**\n * Renders one `<g>` per element. The library SVG fragment is inlined verbatim\n * via `dangerouslySetInnerHTML` — the library JSON is build-time content\n * (see `scripts/build-element-library.mjs`), not user input.\n *\n * Each `<g>` carries `data-element-id` so tools can hit-test via\n * `event.target.closest('[data-element-id]')` without React state. Selection\n * state is reflected as `data-selected=\"true\"` so CSS / overlays can react\n * without re-rendering this layer's children.\n *\n * To make every element comfortable to click — not just its thin strokes —\n * we paint an invisible `<rect>` covering the library's viewBox before the\n * symbol. `fill=\"transparent\"` is hittable (unlike `none`); the visual lines\n * still draw on top because they're added after.\n */\n\nimport { useEditorStore } from '../store';\nimport type { LibraryEntry } from '../model';\nimport { transformAttr } from './transform-attr';\n\ninterface BBox {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nfunction parseViewBox(s: string): BBox | null {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n\nfunction HitRect({ lib }: { lib: LibraryEntry }) {\n const bb = parseViewBox(lib.viewBox);\n if (!bb) return null;\n return (\n <rect\n className=\"ole-element-hit\"\n x={bb.x}\n y={bb.y}\n width={bb.w}\n height={bb.h}\n />\n );\n}\n\nexport function ElementLayer() {\n const elements = useEditorStore((s) => s.internal.elements);\n const layout = useEditorStore((s) => s.internal.layout);\n const selection = useEditorStore((s) => s.selection);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const nodes = useEditorStore((s) => s.internal.nodes);\n const selSet = new Set(selection);\n\n // Elements that have at least one terminal in the selected ConnectivityNode\n // get a halo to show \"this is what the wire connects\".\n const nodeRelated = new Set<string>();\n if (selectedNode) {\n const node = nodes.get(selectedNode);\n if (node) {\n for (const ref of node.terminals) {\n const dot = ref.indexOf('.');\n if (dot > 0) nodeRelated.add(ref.slice(0, dot));\n }\n }\n }\n\n return (\n <g className=\"ole-element-layer\">\n {Array.from(elements.values()).map((re) => {\n const place = layout.get(re.element.id);\n if (!place) return null;\n const isSelected = selSet.has(re.element.id);\n const isNodeRelated = nodeRelated.has(re.element.id);\n\n if (!re.libraryDef) {\n // Unknown kind → small red placeholder square.\n return (\n <g\n key={re.element.id}\n data-element-id={re.element.id}\n data-selected={isSelected ? 'true' : undefined}\n data-node-related={isNodeRelated ? 'true' : undefined}\n transform={transformAttr(place)}\n className=\"ole-element ole-element--unknown\"\n >\n <rect\n x={-10}\n y={-10}\n width={20}\n height={20}\n fill=\"none\"\n stroke=\"#EF4444\"\n strokeWidth={1}\n strokeDasharray=\"2 2\"\n />\n <text\n x={0}\n y={4}\n fontSize={8}\n fill=\"#EF4444\"\n textAnchor=\"middle\"\n fontFamily=\"system-ui, sans-serif\"\n >\n ?\n </text>\n </g>\n );\n }\n\n return (\n <g\n key={re.element.id}\n data-element-id={re.element.id}\n data-selected={isSelected ? 'true' : undefined}\n data-node-related={isNodeRelated ? 'true' : undefined}\n transform={transformAttr(place)}\n className=\"ole-element\"\n >\n <HitRect lib={re.libraryDef} />\n <g dangerouslySetInnerHTML={{ __html: re.libraryDef.svg }} />\n </g>\n );\n })}\n </g>\n );\n}\n","/**\n * Tiny pub/sub for the marquee selection rect (in SVG coords). Used by\n * SelectTool to publish rect updates and by `<MarqueeOverlay>` to render\n * without bouncing through the editor store.\n */\n\nexport interface MarqueeRect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\ntype Listener = (rect: MarqueeRect | null) => void;\n\nlet current: MarqueeRect | null = null;\nconst listeners = new Set<Listener>();\n\nexport function publishMarquee(rect: MarqueeRect | null): void {\n current = rect;\n for (const l of listeners) l(rect);\n}\n\nexport function getMarquee(): MarqueeRect | null {\n return current;\n}\n\nexport function subscribeMarquee(fn: Listener): () => void {\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n","/**\n * Renders the in-progress marquee selection rect. Subscribes directly to\n * `marquee-bus` to avoid going through React state for every pointermove.\n */\n\nimport { useEffect, useState } from 'react';\nimport { getMarquee, subscribeMarquee, type MarqueeRect } from './marquee-bus';\n\nexport function MarqueeOverlay() {\n const [rect, setRect] = useState<MarqueeRect | null>(getMarquee());\n useEffect(() => subscribeMarquee(setRect), []);\n\n if (!rect || (rect.w === 0 && rect.h === 0)) return null;\n return (\n <rect\n className=\"ole-marquee\"\n x={rect.x}\n y={rect.y}\n width={rect.w}\n height={rect.h}\n pointerEvents=\"none\"\n />\n );\n}\n","/**\n * Half-transparent preview of the kind being placed, following the cursor\n * during the place tool.\n *\n * The cursor \"carries\" one of the new element's terminals (the tap-side\n * pin — same one `dropElement` snaps to a bus, and the same one used for\n * free-placement). Visually this means the pointer touches the pin you'd\n * expect to drop onto a wire/bus, not the element's centroid.\n *\n * In drag-from-terminal mode (`placeFromTerminal != null`) we additionally\n * draw a dashed wire from the source terminal to whichever pin of the ghost\n * is closest — same visual language as `WirePreview`, so the user sees the\n * connection that will be committed on release.\n */\n\nimport { useEditorStore } from '../store';\nimport { getLibraryEntry } from '../compiler';\nimport {\n pickConnectTerminal,\n pickPlaceCursorTerminal,\n resolvePlaceSource,\n} from './drop-on-bus';\n\nexport function PlaceGhost() {\n const tool = useEditorStore((s) => s.activeTool);\n const placeKind = useEditorStore((s) => s.placeKind);\n const cursor = useEditorStore((s) => s.cursorSvg);\n const fromRef = useEditorStore((s) => s.placeFromTerminal);\n\n if (tool !== 'place' || !placeKind || !cursor) return null;\n const lib = getLibraryEntry(placeKind);\n if (!lib) return null;\n\n // Anchor: cursor always carries one of the ghost's pins, so the visual\n // pointer-to-pin alignment stays continuous across the press → drag →\n // release sequence. Free-place uses the tap-side pin; drag-from-terminal\n // uses the pin that will connect back to the source, which also keeps\n // the dashed wire taut from source to cursor.\n let cursorPin: { x: number; y: number } | null = null;\n let connect: { source: [number, number]; pin: [number, number] } | null = null;\n if (fromRef) {\n const source = resolvePlaceSource(fromRef, cursor);\n if (source) {\n const chosen = pickConnectTerminal(lib, source, cursor);\n cursorPin = chosen;\n connect = { source: source.world, pin: cursor };\n }\n } else {\n cursorPin = pickPlaceCursorTerminal(lib);\n }\n const ghostX = cursor[0] - (cursorPin?.x ?? 0);\n const ghostY = cursor[1] - (cursorPin?.y ?? 0);\n\n return (\n <g className=\"ole-place-ghost-group\" pointerEvents=\"none\">\n {connect && (\n <>\n <line\n x1={connect.source[0]}\n y1={connect.source[1]}\n x2={connect.pin[0]}\n y2={connect.pin[1]}\n className=\"ole-wire-preview-line\"\n />\n <circle\n cx={connect.source[0]}\n cy={connect.source[1]}\n r={4}\n className=\"ole-wire-preview-anchor\"\n />\n </>\n )}\n <g\n className=\"ole-place-ghost\"\n transform={`translate(${ghostX} ${ghostY})`}\n opacity={0.5}\n >\n <g dangerouslySetInnerHTML={{ __html: lib.svg }} />\n </g>\n </g>\n );\n}\n","/**\n * Renders a non-scaling stroke rect around every selected element / bus\n * using the library viewBox (devices) or BusGeometry (buses) as the base\n * bbox, then applying the same transform.\n */\n\nimport { useEditorStore } from '../store';\nimport { transformAttr } from './transform-attr';\n\nexport function SelectionOverlay() {\n const selection = useEditorStore((s) => s.selection);\n const elements = useEditorStore((s) => s.internal.elements);\n const layout = useEditorStore((s) => s.internal.layout);\n const buses = useEditorStore((s) => s.internal.buses);\n\n if (selection.length === 0) return null;\n\n return (\n <g className=\"ole-selection-overlay\" pointerEvents=\"none\">\n {selection.map((id) => {\n const rb = buses.get(id);\n if (rb) {\n const { axis, at, span } = rb.geometry;\n const half = span / 2;\n const x = axis === 'x' ? at[0] - half : at[0] - 4;\n const y = axis === 'x' ? at[1] - 4 : at[1] - half;\n const w = axis === 'x' ? span : 8;\n const h = axis === 'x' ? 8 : span;\n return (\n <rect\n key={id}\n x={x}\n y={y}\n width={w}\n height={h}\n fill=\"none\"\n className=\"ole-selection-rect\"\n />\n );\n }\n const re = elements.get(id);\n const place = layout.get(id);\n if (!re?.libraryDef || !place) return null;\n const bb = parseViewBox(re.libraryDef.viewBox);\n if (!bb) return null;\n return (\n <rect\n key={id}\n x={bb.x}\n y={bb.y}\n width={bb.w}\n height={bb.h}\n fill=\"none\"\n className=\"ole-selection-rect\"\n transform={transformAttr(place)}\n />\n );\n })}\n </g>\n );\n}\n\nfunction parseViewBox(s: string): { x: number; y: number; w: number; h: number } | null {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n","/**\n * Renders a `<circle>` per terminal at its world coords. Hidden by default;\n * the wire tool reveals them via the `.tool-wire` class on the canvas root.\n * In select mode, terminals on currently-selected elements are also revealed\n * so the user can grab one to drag-connect without switching tools.\n * `data-connected` distinguishes solid (connected) from hollow (dangling).\n *\n * Selected stretchable elements (e.g. busbar) get their terminals suppressed\n * here because `BusHandles` already draws a larger grip at the same world\n * coords — showing both produces visible \"double\" control points.\n */\n\nimport { useEditorStore } from '../store';\n\nexport function TerminalLayer() {\n const terminals = useEditorStore((s) => s.internal.terminals);\n const terminalToNode = useEditorStore((s) => s.internal.terminalToNode);\n const wireFrom = useEditorStore((s) => s.wireFromTerminal);\n const selection = useEditorStore((s) => s.selection);\n\n const selectionSet = new Set<string>(selection);\n\n return (\n <g className=\"ole-terminal-layer\">\n {Array.from(terminals.values()).map((t) => {\n const nodeId = terminalToNode.get(t.ref);\n const connected = nodeId !== undefined;\n const isOrigin = wireFrom === t.ref;\n const onSelected = selectionSet.has(t.elementId);\n return (\n <circle\n key={t.ref}\n cx={t.world[0]}\n cy={t.world[1]}\n r={3}\n data-element-id={t.elementId}\n data-terminal-id={t.ref}\n data-node-id={nodeId}\n data-connected={connected ? 'true' : 'false'}\n data-active={isOrigin ? 'true' : undefined}\n data-on-selected={onSelected ? 'true' : undefined}\n className=\"ole-terminal\"\n />\n );\n })}\n </g>\n );\n}\n","/**\n * Renders one polyline per Wire. Each polyline carries `data-wire-id` so\n * hit-test resolves to the specific wire (not the whole electrical node)\n * and `data-node-id` for \"select-whole-node\" affordances.\n *\n * Each visible wire is paired with a wider invisible hit polyline. A 1px\n * wire is too thin to comfortably click; the hit poly catches pointer\n * events within ~8px of the line and carries the same data attributes.\n */\n\nimport { useEditorStore } from '../store';\n\nexport function WireLayer() {\n const wireRenders = useEditorStore((s) => s.internal.wireRenders);\n const terminalToNode = useEditorStore((s) => s.internal.terminalToNode);\n const wires = useEditorStore((s) => s.diagram.wires);\n const selectedWire = useEditorStore((s) => s.selectedWire);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n\n // Build a quick wireId → nodeId lookup so each rendered polyline knows\n // its containing electrical node.\n const wireToNode = new Map<string, string>();\n for (const w of wires ?? []) {\n const node = terminalToNode.get(w.ends[0]);\n if (node) wireToNode.set(w.id, node);\n }\n\n return (\n <g className=\"ole-wire-layer\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1}>\n {Array.from(wireRenders.values()).flatMap((r) => {\n const path = r.path;\n if (path.length < 2) return [];\n const points = path.map((p) => `${p[0]},${p[1]}`).join(' ');\n const nodeId = wireToNode.get(r.wireId);\n const isWireSelected = selectedWire === r.wireId;\n const isNodeSelected = selectedNode != null && selectedNode === nodeId;\n return [\n <polyline\n key={`hit-${r.wireId}`}\n data-wire-id={r.wireId}\n data-node-id={nodeId}\n className=\"ole-wire-hit\"\n points={points}\n />,\n <polyline\n key={r.wireId}\n data-wire-id={r.wireId}\n data-node-id={nodeId}\n data-manual={r.userEdited ? 'true' : undefined}\n data-selected={isWireSelected || isNodeSelected ? 'true' : undefined}\n className=\"ole-wire\"\n points={points}\n />,\n ];\n })}\n </g>\n );\n}\n","/**\n * Pub/sub for the in-progress wire target. WireTool publishes the current\n * candidate (a real terminal or a bus body projection); WirePreview\n * subscribes and renders an indicator so the user sees *where* a release\n * would land before they release.\n */\n\nimport type { WireEnd } from '../model';\n\nexport interface WireTarget {\n ref: WireEnd;\n /** World-frame coords of where the connection will physically attach. */\n world: [number, number];\n /** True when the target is a bare bus id. */\n isBus: boolean;\n}\n\ntype Listener = (target: WireTarget | null) => void;\n\nlet current: WireTarget | null = null;\nconst listeners = new Set<Listener>();\n\nexport function publishWireTarget(t: WireTarget | null): void {\n if (\n (t === null && current === null) ||\n (t &&\n current &&\n t.ref === current.ref &&\n t.world[0] === current.world[0] &&\n t.world[1] === current.world[1])\n ) {\n return;\n }\n current = t;\n for (const l of listeners) l(t);\n}\n\nexport function getWireTarget(): WireTarget | null {\n return current;\n}\n\nexport function subscribeWireTarget(fn: Listener): () => void {\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n","/**\n * Dashed line from the chosen first terminal to the current cursor position\n * while the wire tool is mid-drag. When the cursor is over a valid drop\n * target (a terminal or a bus body), an additional ring + dot marks the\n * exact landing point so the user can release with confidence.\n */\n\nimport { useEffect, useState } from 'react';\nimport { useEditorStore } from '../store';\nimport {\n getWireTarget,\n subscribeWireTarget,\n type WireTarget,\n} from './wire-target-bus';\n\nexport function WirePreview() {\n const fromRef = useEditorStore((s) => s.wireFromTerminal);\n const cursor = useEditorStore((s) => s.cursorSvg);\n const terminals = useEditorStore((s) => s.internal.terminals);\n const [target, setTarget] = useState<WireTarget | null>(getWireTarget());\n\n useEffect(() => subscribeWireTarget(setTarget), []);\n\n const buses = useEditorStore((s) => s.internal.buses);\n if (!fromRef || !cursor) return null;\n // `fromRef` may be a real terminal or a bare bus id — resolve world coords\n // from whichever map matches.\n let fromWorld: [number, number] | undefined;\n if (fromRef.includes('.')) {\n fromWorld = terminals.get(fromRef as `${string}.${string}`)?.world;\n } else {\n fromWorld = buses.get(fromRef)?.geometry.at;\n }\n if (!fromWorld) return null;\n\n // If we have a valid target, end the dashed line on it (snaps preview to\n // the actual landing point). Otherwise follow the raw cursor.\n const endX = target?.world[0] ?? cursor[0];\n const endY = target?.world[1] ?? cursor[1];\n\n return (\n <g className=\"ole-wire-preview\" pointerEvents=\"none\">\n <line\n x1={fromWorld[0]}\n y1={fromWorld[1]}\n x2={endX}\n y2={endY}\n className=\"ole-wire-preview-line\"\n />\n <circle\n cx={fromWorld[0]}\n cy={fromWorld[1]}\n r={4}\n className=\"ole-wire-preview-anchor\"\n />\n {target && (\n <>\n <circle\n cx={target.world[0]}\n cy={target.world[1]}\n r={target.isBus ? 7 : 8}\n className=\"ole-wire-preview-target-ring\"\n />\n <circle\n cx={target.world[0]}\n cy={target.world[1]}\n r={target.isBus ? 3 : 4}\n className=\"ole-wire-preview-target-dot\"\n />\n </>\n )}\n </g>\n );\n}\n","/**\n * DOM-based hit testing. The renderer tags every interactive node with a\n * `data-*` attribute (data-element-id, data-bus-id, data-terminal-id,\n * data-node-id, data-wire-id) so tools can locate the model they belong to\n * without React state lookups.\n */\n\nimport type {\n AnnotationId,\n BusId,\n ElementId,\n NodeId,\n TerminalRef,\n WireEnd,\n WireId,\n} from '../model';\n\nfunction ancestor(target: EventTarget | null, attr: string): Element | null {\n if (!(target instanceof Element)) return null;\n return target.closest(`[${attr}]`);\n}\n\nexport function hitElement(target: EventTarget | null): ElementId | null {\n return ancestor(target, 'data-element-id')?.getAttribute('data-element-id') ?? null;\n}\n\nexport function hitBus(target: EventTarget | null): BusId | null {\n return ancestor(target, 'data-bus-id')?.getAttribute('data-bus-id') ?? null;\n}\n\n/**\n * Returns either a device terminal ref (\"X.Y\") or a bare bus id under the\n * cursor. Direct hit on a `data-terminal-id` node wins; otherwise if the\n * click landed on a bus body fall back to the bus id so the wire tool can\n * attach anywhere along the bus.\n */\nexport function hitTerminal(target: EventTarget | null): WireEnd | null {\n const direct = ancestor(target, 'data-terminal-id')?.getAttribute('data-terminal-id');\n if (direct) return direct as TerminalRef;\n const busId = hitBus(target);\n if (busId) return busId;\n return null;\n}\n\nexport function hitNode(target: EventTarget | null): NodeId | null {\n return ancestor(target, 'data-node-id')?.getAttribute('data-node-id') ?? null;\n}\n\nexport function hitWire(target: EventTarget | null): WireId | null {\n return ancestor(target, 'data-wire-id')?.getAttribute('data-wire-id') ?? null;\n}\n\nexport function hitAnnotation(target: EventTarget | null): AnnotationId | null {\n return (\n ancestor(target, 'data-annotation-id')?.getAttribute('data-annotation-id') ??\n null\n );\n}\n","/**\n * Dispatch a synthetic `pointercancel` on the canvas host. Used by the\n * pinch-zoom hijack (useViewport) and the long-press → context-menu path\n * (CanvasSvg) to interrupt the active tool's in-progress gesture so it\n * runs its cancel cleanup instead of committing on the next pointerup.\n *\n * Best-effort: the `PointerEvent` constructor is missing on some older\n * touch browsers; failing silently is fine because the only downside is\n * the tool gesture lingering until the user lifts the finger naturally.\n */\nexport function dispatchSyntheticPointerCancel(\n host: EventTarget,\n pointerId: number,\n): void {\n try {\n host.dispatchEvent(\n new PointerEvent('pointercancel', {\n pointerId,\n bubbles: true,\n cancelable: true,\n pointerType: 'touch',\n }),\n );\n } catch {\n /* PointerEvent constructor unsupported — leave the gesture to time out */\n }\n}\n","/**\n * Global editor shortcuts. Runs once via the OneLineEditor root component\n * and reads/writes the store via `getState`. Shortcuts are inert when\n * focus is in an editable input/textarea so the property panel doesn't\n * eat the user's typing.\n */\n\nimport { useEffect } from 'react';\nimport { useEditorStore } from '../store';\n\nfunction isEditing(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n return (\n tag === 'INPUT' ||\n tag === 'TEXTAREA' ||\n tag === 'SELECT' ||\n target.isContentEditable\n );\n}\n\n/**\n * Step out of drawing state. Wire/busbar tools always return to select.\n * Place tool clears its placeKind first; if no kind is selected, returns to\n * select. For non-drawing tools, falls back to clearing selection. Shared\n * between Esc and the canvas right-click handler.\n */\nexport function exitDrawingState(): void {\n const store = useEditorStore.getState();\n const tool = store.activeTool;\n if (store.editingAnnotation || store.editingElement) {\n // Inline edit in progress: blur the contentEditable so its onBlur commits.\n if (typeof document !== 'undefined') {\n const ed = document.querySelector(\n '.ole-free-annotation-edit-fo div[contenteditable], .ole-element-name-editor div[contenteditable]',\n ) as HTMLElement | null;\n ed?.blur();\n }\n store.setEditingAnnotation(null);\n store.setEditingElement(null);\n return;\n }\n if (tool === 'wire' || tool === 'busbar' || tool === 'text') {\n store.setActiveTool('select');\n return;\n }\n if (tool === 'place') {\n if (store.placeFromTerminal) store.setPlaceFromTerminal(null);\n else if (store.placeKind) store.setPlaceKind(null);\n else store.setActiveTool('select');\n return;\n }\n if (\n store.selectedNode ||\n store.selectedWire ||\n store.selection.length > 0 ||\n store.selectedAnnotation\n ) {\n store.clearSelection();\n }\n}\n\n\nexport function useKeyboardShortcuts(): void {\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n if (isEditing(e.target)) return;\n\n const mod = e.metaKey || e.ctrlKey;\n const store = useEditorStore.getState();\n\n // Cmd+Z / Cmd+Shift+Z — undo / redo. Save shortcut handled in TopBar.\n if (mod && e.key.toLowerCase() === 'z') {\n e.preventDefault();\n if (e.shiftKey) store.redo();\n else store.undo();\n return;\n }\n // Cmd+Y — redo (Windows convention)\n if (mod && !e.shiftKey && e.key.toLowerCase() === 'y') {\n e.preventDefault();\n store.redo();\n return;\n }\n // Cmd+A — select all elements\n if (mod && e.key.toLowerCase() === 'a') {\n e.preventDefault();\n const ids = useEditorStore.getState().diagram.elements.map((x) => x.id);\n store.setSelection(ids);\n return;\n }\n // Cmd+C / Cmd+X / Cmd+V — copy / cut / paste\n if (mod && !e.shiftKey && !e.altKey) {\n const k = e.key.toLowerCase();\n if (k === 'c') {\n if (store.selection.length === 0) return;\n e.preventDefault();\n store.copySelection();\n return;\n }\n if (k === 'x') {\n if (store.selection.length === 0) return;\n e.preventDefault();\n store.cutSelection();\n return;\n }\n if (k === 'v') {\n if (!store.clipboard) return;\n e.preventDefault();\n store.pasteClipboard();\n return;\n }\n }\n if (mod) return; // ignore other modified keys\n\n switch (e.key) {\n case 'v':\n case 'V':\n store.setActiveTool('select');\n return;\n case 'h':\n case 'H':\n store.setActiveTool('pan');\n return;\n case 'w':\n case 'W':\n store.setActiveTool('wire');\n return;\n case 'b':\n case 'B':\n store.setActiveTool('busbar');\n return;\n case 'p':\n case 'P':\n store.setActiveTool('place');\n return;\n case 't':\n case 'T':\n store.setActiveTool('text');\n return;\n case 'r':\n case 'R':\n if (store.selection.length > 0) {\n e.preventDefault();\n store.rotateSelection(90);\n }\n return;\n case 'm':\n case 'M':\n if (store.selection.length > 0) {\n e.preventDefault();\n store.mirrorSelection();\n }\n return;\n case 'Delete':\n case 'Backspace':\n if (store.selectedAnnotation) {\n e.preventDefault();\n store.deleteAnnotation(store.selectedAnnotation);\n } else if (store.selectedWire) {\n e.preventDefault();\n store.deleteSelectedWire();\n } else if (store.selectedNode) {\n e.preventDefault();\n store.deleteSelectedNode();\n } else if (store.selection.length > 0) {\n e.preventDefault();\n store.deleteSelection();\n }\n return;\n case 'Escape':\n exitDrawingState();\n return;\n }\n };\n\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, []);\n}\n","/**\n * Pub/sub for the cursor's hover target on the canvas. `useHoverHighlight`\n * publishes the current `data-element-id` (or null when leaving an element);\n * `ElementHoverLabel` subscribes to render a small floating name tag.\n */\n\nimport type { ElementId } from '../model';\n\ntype Listener = (id: ElementId | null) => void;\n\nlet current: ElementId | null = null;\nconst listeners = new Set<Listener>();\n\nexport function publishHoverElement(id: ElementId | null): void {\n if (id === current) return;\n current = id;\n for (const l of listeners) l(id);\n}\n\nexport function getHoverElement(): ElementId | null {\n return current;\n}\n\nexport function subscribeHoverElement(fn: Listener): () => void {\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n","/**\n * Tracks which element / connectivity-node the cursor is over and toggles\n * marker classes on the affected DOM nodes. CSS reads those classes to\n * drive visual highlights without re-rendering React.\n *\n * Markers (added/removed by this hook):\n * .ole-hover-element-host — the element whose body the cursor is over;\n * its sibling terminals are also marked\n * .ole-hover-terminal-on — terminals belonging to the hovered element\n * (revealed regardless of tool, per ui-design §2.1)\n * .ole-hover-node-on — wires/terminals on the hovered ConnectivityNode\n * (highlighted, with non-members dimmed via root attr)\n */\n\nimport { useEffect, type RefObject } from 'react';\nimport { useEditorStore } from '../store';\nimport { hitElement, hitNode, hitTerminal } from './hit-test';\nimport { publishHoverElement } from './hover-bus';\n\nconst C_HOST = 'ole-hover-element-host';\nconst C_TERM = 'ole-hover-terminal-on';\nconst C_NODE = 'ole-hover-node-on';\n\nexport function useHoverHighlight(\n hostRef: RefObject<HTMLDivElement | null>,\n): void {\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n\n let lastElement: string | null = null;\n let lastNode: string | null = null;\n const markedTerminals = new Set<Element>();\n const markedNodeMembers = new Set<Element>();\n\n const clearAndMark = (\n pool: Set<Element>,\n next: Element[],\n cls: string,\n ) => {\n for (const el of pool) el.classList.remove(cls);\n pool.clear();\n for (const el of next) {\n el.classList.add(cls);\n pool.add(el);\n }\n };\n\n const updateElementHover = (id: string | null) => {\n if (id === lastElement) return;\n // Clear previous host class\n if (lastElement) {\n host\n .querySelector(`[data-element-id=\"${cssEscape(lastElement)}\"]`)\n ?.classList.remove(C_HOST);\n }\n // Set new host class\n if (id) {\n host\n .querySelector(`[data-element-id=\"${cssEscape(id)}\"]`)\n ?.classList.add(C_HOST);\n }\n // Mark terminals belonging to the hovered element\n const terms = id\n ? Array.from(\n host.querySelectorAll<SVGCircleElement>(\n `.ole-terminal[data-element-id=\"${cssEscape(id)}\"]`,\n ),\n )\n : [];\n clearAndMark(markedTerminals, terms, C_TERM);\n lastElement = id;\n // Mirror to root attr so CSS can distinguish \"any element hovered\" state\n if (id) host.setAttribute('data-hover-element', '');\n else host.removeAttribute('data-hover-element');\n publishHoverElement(id);\n };\n\n const updateNodeHover = (nodeId: string | null) => {\n if (nodeId === lastNode) return;\n const members = nodeId\n ? Array.from(\n host.querySelectorAll<Element>(\n `[data-node-id=\"${cssEscape(nodeId)}\"]`,\n ),\n )\n : [];\n clearAndMark(markedNodeMembers, members, C_NODE);\n lastNode = nodeId;\n if (nodeId) host.setAttribute('data-hover-node', '');\n else host.removeAttribute('data-hover-node');\n };\n\n const onPointerMove = (e: PointerEvent) => {\n updateElementHover(hitElement(e.target));\n\n const terminal = hitTerminal(e.target);\n let nodeId: string | null = null;\n if (terminal) {\n nodeId =\n useEditorStore.getState().internal.terminalToNode.get(terminal) ?? null;\n } else {\n nodeId = hitNode(e.target);\n }\n updateNodeHover(nodeId);\n };\n\n const onPointerLeave = () => {\n updateElementHover(null);\n updateNodeHover(null);\n };\n\n host.addEventListener('pointermove', onPointerMove);\n host.addEventListener('pointerleave', onPointerLeave);\n return () => {\n host.removeEventListener('pointermove', onPointerMove);\n host.removeEventListener('pointerleave', onPointerLeave);\n updateElementHover(null);\n updateNodeHover(null);\n };\n }, [hostRef]);\n}\n\nfunction cssEscape(s: string): string {\n // Avoid CSS.escape (not always typed in lib.dom); IDs may contain dots.\n return s.replace(/([\"\\\\])/g, '\\\\$1');\n}\n","/**\n * Resolve a WireEnd under the cursor into a concrete world-coord target,\n * including the bus body case. The wire tool drags toward terminals — but\n * for buses we accept a hit on the body itself and project the cursor onto\n * the bus axis to get a connection point.\n */\n\nimport { useEditorStore } from '../store';\nimport type { WireEnd } from '../model';\nimport type { WireTarget } from './wire-target-bus';\n\nexport function resolveWireTarget(\n ref: WireEnd,\n cursorWorld: [number, number],\n): WireTarget | null {\n const internal = useEditorStore.getState().internal;\n // Bare bus id: project cursor onto bus axis.\n if (!ref.includes('.')) {\n const rb = internal.buses.get(ref);\n if (!rb) return null;\n const { axis, at, span } = rb.geometry;\n if (axis === 'x') {\n const minX = at[0] - span / 2;\n const maxX = at[0] + span / 2;\n const x = Math.max(minX, Math.min(maxX, cursorWorld[0]));\n return { ref, world: [x, at[1]], isBus: true };\n }\n const minY = at[1] - span / 2;\n const maxY = at[1] + span / 2;\n const y = Math.max(minY, Math.min(maxY, cursorWorld[1]));\n return { ref, world: [at[0], y], isBus: true };\n }\n // Real device terminal.\n const term = internal.terminals.get(ref as `${string}.${string}`);\n if (term) {\n return { ref, world: term.world, isBus: false };\n }\n return null;\n}\n","/**\n * Select tool: click to select, shift-click to add/remove from selection,\n * drag a selected element (or one just clicked) to move all selected\n * elements together. Drag in *empty space* draws a marquee box and selects\n * every element whose bbox intersects the box (replace, or add with shift).\n *\n * Movement uses DOM-direct mutation (`setAttribute('transform')`) during\n * the drag and dispatches a single `moveElements` action on pointer-up.\n * This keeps the drag at 60fps even for diagrams that would otherwise\n * recompile on every pointermove.\n */\n\nimport { useEditorStore } from '../../store';\nimport type { ResolvedPlacement } from '../../compiler';\nimport type { AnnotationId, ElementId, WireEnd } from '../../model';\nimport { snap } from '../grid';\nimport { hitAnnotation, hitElement, hitNode, hitTerminal, hitWire } from '../hit-test';\nimport { publishMarquee, type MarqueeRect } from '../marquee-bus';\nimport { resolveWireTarget } from '../resolve-wire-target';\nimport { transformAttr } from '../transform-attr';\nimport { publishWireTarget } from '../wire-target-bus';\nimport type { Tool } from './types';\n\nconst MARQUEE_THRESHOLD = 3;\n\ninterface DragState {\n pointerId: number;\n startSvg: [number, number];\n /** Original placements of every dragged element. */\n originals: Map<ElementId, ResolvedPlacement>;\n moved: boolean;\n}\n\ninterface MarqueeState {\n pointerId: number;\n startSvg: [number, number];\n shiftKey: boolean;\n /** Selection at gesture start; used as the base when shift-extending. */\n baseSelection: ElementId[];\n}\n\ninterface WireDragState {\n pointerId: number;\n fromRef: WireEnd;\n}\n\ninterface AnnotationDragState {\n pointerId: number;\n id: AnnotationId;\n startSvg: [number, number];\n origin: [number, number];\n moved: boolean;\n}\n\nlet drag: DragState | null = null;\nlet marquee: MarqueeState | null = null;\nlet wireDrag: WireDragState | null = null;\nlet annDrag: AnnotationDragState | null = null;\n\nexport const SelectTool: Tool = {\n id: 'select',\n cursor: 'default',\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return; // ignore middle/right\n\n // Bus stretch + wire path handles are *inside* the canvas host but\n // their React handlers run after the host's native bubble phase\n // (React 17+ root delegation). Ignoring handle hits here keeps\n // SelectTool from clearing the very selection that owns those handles.\n if (\n e.target instanceof Element &&\n e.target.closest('.ole-bus-handle, .ole-wire-handle')\n ) {\n return;\n }\n\n const store = useEditorStore.getState();\n\n // Free text annotation: takes priority over element / terminal because\n // the annotation rect can overlap them visually. Click selects + arms\n // a drag; double-click (separate handler) enters edit mode.\n const annId = hitAnnotation(e.target);\n if (annId) {\n e.preventDefault();\n e.stopPropagation();\n const ann = store.diagram.annotations?.find((a) => a.id === annId);\n if (!ann) return;\n store.setSelectedAnnotation(annId);\n annDrag = {\n pointerId: e.pointerId,\n id: annId,\n startSvg: ctx.viewport.screenToSvg(e.clientX, e.clientY),\n origin: [ann.at[0], ann.at[1]],\n moved: false,\n };\n // Capture deferred to first real movement (see element-drag note).\n return;\n }\n\n // If the user clicked a terminal on a currently-selected element, start a\n // wire drag — same gesture as the wire tool, but available without\n // switching modes. The selection set is the gating affordance. We only\n // accept *direct* terminal hits (`data-terminal-id` ancestor); the\n // busbar-body fallback in `hitTerminal` is excluded so dragging the bus\n // body still moves the bus instead of starting a wire.\n const directTerm =\n e.target instanceof Element\n ? e.target.closest('[data-terminal-id]')?.getAttribute('data-terminal-id')\n : null;\n const termRef = directTerm ? hitTerminal(e.target) : null;\n if (termRef) {\n const dot = termRef.indexOf('.');\n const elemId = dot > 0 ? termRef.slice(0, dot) : '';\n if (elemId && store.selection.includes(elemId)) {\n e.preventDefault();\n e.stopPropagation();\n if (\n e.target instanceof Element &&\n e.target.hasPointerCapture?.(e.pointerId)\n ) {\n e.target.releasePointerCapture(e.pointerId);\n }\n ctx.hostEl.classList.add('tool-wire');\n store.setWireFromTerminal(termRef);\n store.setCursorSvg(ctx.viewport.screenToSvg(e.clientX, e.clientY));\n wireDrag = { pointerId: e.pointerId, fromRef: termRef };\n return;\n }\n }\n\n const id = hitElement(e.target);\n\n if (!id) {\n // Click on a wire → select that single Wire. Alt-click selects the\n // whole electrical node (every wire sharing the same potential).\n const wireId = hitWire(e.target);\n if (wireId) {\n e.preventDefault();\n if (e.altKey) {\n const nodeId = hitNode(e.target);\n if (nodeId) {\n store.setSelectedNode(nodeId);\n return;\n }\n }\n store.setSelectedWire(wireId);\n return;\n }\n\n // Empty-space click → start marquee. The selection only changes on\n // pointerup; leaves selection unchanged for plain shift+drag.\n if (!e.shiftKey) store.clearSelection();\n marquee = {\n pointerId: e.pointerId,\n startSvg: ctx.viewport.screenToSvg(e.clientX, e.clientY),\n shiftKey: e.shiftKey,\n baseSelection: e.shiftKey ? store.selection.slice() : [],\n };\n ctx.hostEl.setPointerCapture(e.pointerId);\n e.preventDefault();\n return;\n }\n\n // Update selection.\n const sel = store.selection;\n if (e.shiftKey) {\n store.toggleInSelection(id);\n } else if (!sel.includes(id)) {\n store.setSelection([id]);\n }\n\n // Begin drag with the post-click selection.\n const targets = e.shiftKey\n ? useEditorStore.getState().selection\n : sel.includes(id)\n ? sel\n : [id];\n if (targets.length === 0) return;\n\n const internal = useEditorStore.getState().internal;\n const originals = new Map<ElementId, ResolvedPlacement>();\n for (const tid of targets) {\n const p = internal.layout.get(tid);\n if (p) originals.set(tid, { ...p });\n }\n if (originals.size === 0) return;\n\n drag = {\n pointerId: e.pointerId,\n startSvg: ctx.viewport.screenToSvg(e.clientX, e.clientY),\n originals,\n moved: false,\n };\n // Defer pointer capture until the user actually starts moving (in\n // onPointerMove) — capturing on pointerdown can interfere with the\n // browser synthesizing `dblclick` from a click pair on the same target.\n e.preventDefault();\n },\n\n onPointerMove(e, ctx) {\n if (annDrag && e.pointerId === annDrag.pointerId) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const dx = snap(cur[0] - annDrag.startSvg[0]);\n const dy = snap(cur[1] - annDrag.startSvg[1]);\n if (!annDrag.moved && (dx !== 0 || dy !== 0)) {\n annDrag.moved = true;\n if (!ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.setPointerCapture(e.pointerId);\n }\n }\n // DOM-direct preview: update the wrapper group's transform so the\n // drag stays smooth. The store mutation lands once on pointerup.\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-annotation-id=\"${cssEscape(annDrag.id)}\"]`,\n );\n if (node) node.setAttribute('transform', `translate(${dx} ${dy})`);\n return;\n }\n\n if (wireDrag && e.pointerId === wireDrag.pointerId) {\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n useEditorStore.getState().setCursorSvg(pt);\n // Pointer capture would pin `e.target` to the origin terminal — sample\n // what's actually under the cursor for the live drop-target marker.\n const under =\n typeof document !== 'undefined'\n ? document.elementFromPoint(e.clientX, e.clientY)\n : null;\n const ref = under ? hitTerminal(under) : null;\n if (!ref || ref === wireDrag.fromRef) {\n publishWireTarget(null);\n return;\n }\n publishWireTarget(resolveWireTarget(ref, pt));\n return;\n }\n\n if (drag && e.pointerId === drag.pointerId) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const dx = snap(cur[0] - drag.startSvg[0]);\n const dy = snap(cur[1] - drag.startSvg[1]);\n if (!drag.moved && (dx !== 0 || dy !== 0)) {\n drag.moved = true;\n if (!ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.setPointerCapture(e.pointerId);\n }\n }\n\n for (const [id, orig] of drag.originals) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (!node) continue;\n const next: ResolvedPlacement = {\n ...orig,\n at: [orig.at[0] + dx, orig.at[1] + dy],\n };\n node.setAttribute('transform', transformAttr(next));\n }\n return;\n }\n\n if (marquee && e.pointerId === marquee.pointerId) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n publishMarquee(rectFromPoints(marquee.startSvg, cur));\n return;\n }\n },\n\n onPointerUp(e, ctx) {\n if (annDrag && e.pointerId === annDrag.pointerId) {\n if (ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n }\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const dx = snap(cur[0] - annDrag.startSvg[0]);\n const dy = snap(cur[1] - annDrag.startSvg[1]);\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-annotation-id=\"${cssEscape(annDrag.id)}\"]`,\n );\n // Reset the preview transform — store update will repaint at the new at.\n if (node) node.removeAttribute('transform');\n if (annDrag.moved && (dx !== 0 || dy !== 0)) {\n useEditorStore.getState().updateAnnotation(annDrag.id, {\n at: [annDrag.origin[0] + dx, annDrag.origin[1] + dy],\n });\n }\n annDrag = null;\n return;\n }\n\n if (wireDrag && e.pointerId === wireDrag.pointerId) {\n const store = useEditorStore.getState();\n const from = wireDrag.fromRef;\n wireDrag = null;\n ctx.hostEl.classList.remove('tool-wire');\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n const ref = hitTerminal(e.target);\n if (ref && ref !== from) store.addWire(from, ref);\n return;\n }\n\n if (drag && e.pointerId === drag.pointerId) {\n if (ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n }\n if (drag.moved) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const dx = snap(cur[0] - drag.startSvg[0]);\n const dy = snap(cur[1] - drag.startSvg[1]);\n if (dx !== 0 || dy !== 0) {\n const deltas = new Map<ElementId, [number, number]>();\n for (const id of drag.originals.keys()) deltas.set(id, [dx, dy]);\n useEditorStore.getState().moveElements(deltas);\n }\n }\n drag = null;\n return;\n }\n\n if (marquee && e.pointerId === marquee.pointerId) {\n if (ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n }\n const end = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const rect = rectFromPoints(marquee.startSvg, end);\n // Only treat as a real marquee if the user actually dragged.\n if (rect.w >= MARQUEE_THRESHOLD || rect.h >= MARQUEE_THRESHOLD) {\n const hit = elementsInRect(rect);\n if (marquee.shiftKey) {\n // Shift-marquee toggles each hit element's membership.\n const baseSet = new Set(marquee.baseSelection);\n for (const id of hit) {\n if (baseSet.has(id)) baseSet.delete(id);\n else baseSet.add(id);\n }\n useEditorStore.getState().setSelection([...baseSet]);\n } else {\n useEditorStore.getState().setSelection(hit);\n }\n }\n publishMarquee(null);\n marquee = null;\n }\n },\n\n onPointerCancel(e, ctx) {\n // Pinch-zoom hijack interrupted the gesture. Cleanly drop any in-flight\n // drag/marquee/wire/annotation state without committing — we don't want\n // to apply a move/marquee at the synthetic cancel coordinates.\n if (annDrag && e.pointerId === annDrag.pointerId) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-annotation-id=\"${cssEscape(annDrag.id)}\"]`,\n );\n if (node) node.removeAttribute('transform');\n if (ctx.hostEl.hasPointerCapture?.(e.pointerId)) {\n try {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n } catch {\n /* ignore */\n }\n }\n annDrag = null;\n }\n if (drag && e.pointerId === drag.pointerId) {\n // Reset the live preview transforms so the elements snap back to\n // their pre-drag placements (the store wasn't mutated yet).\n for (const [id, orig] of drag.originals) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (!node) continue;\n node.setAttribute('transform', transformAttr(orig));\n }\n if (ctx.hostEl.hasPointerCapture?.(e.pointerId)) {\n try {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n } catch {\n /* ignore */\n }\n }\n drag = null;\n }\n if (wireDrag && e.pointerId === wireDrag.pointerId) {\n ctx.hostEl.classList.remove('tool-wire');\n const store = useEditorStore.getState();\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n wireDrag = null;\n }\n if (marquee && e.pointerId === marquee.pointerId) {\n if (ctx.hostEl.hasPointerCapture?.(e.pointerId)) {\n try {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n } catch {\n /* ignore */\n }\n }\n publishMarquee(null);\n marquee = null;\n }\n },\n\n onDoubleClick(e) {\n const store = useEditorStore.getState();\n const annId = hitAnnotation(e.target);\n if (annId) {\n e.preventDefault();\n e.stopPropagation();\n store.setEditingAnnotation(annId);\n return;\n }\n const id = hitElement(e.target);\n if (id) {\n e.preventDefault();\n e.stopPropagation();\n store.setEditingElement(id);\n }\n },\n\n onDeactivate(ctx) {\n drag = null;\n marquee = null;\n annDrag = null;\n if (wireDrag) {\n ctx.hostEl.classList.remove('tool-wire');\n const store = useEditorStore.getState();\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n wireDrag = null;\n }\n publishMarquee(null);\n },\n};\n\nfunction rectFromPoints(a: [number, number], b: [number, number]): MarqueeRect {\n const x = Math.min(a[0], b[0]);\n const y = Math.min(a[1], b[1]);\n const w = Math.abs(b[0] - a[0]);\n const h = Math.abs(b[1] - a[1]);\n return { x, y, w, h };\n}\n\n/**\n * Pick all element IDs whose library viewBox (transformed to world coords)\n * intersects the marquee rect. We approximate with the axis-aligned bbox of\n * the four corners after applying placement.\n */\nfunction elementsInRect(rect: MarqueeRect): ElementId[] {\n const { internal } = useEditorStore.getState();\n const hits: ElementId[] = [];\n for (const re of internal.elements.values()) {\n if (!re.libraryDef) continue;\n const place = internal.layout.get(re.element.id);\n if (!place) continue;\n const vb = parseViewBox(re.libraryDef.viewBox);\n if (!vb) continue;\n const corners: [number, number][] = [\n [vb.x, vb.y],\n [vb.x + vb.w, vb.y],\n [vb.x, vb.y + vb.h],\n [vb.x + vb.w, vb.y + vb.h],\n ].map(([x, y]) => transformLocalCorner([x, y], place));\n\n let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;\n for (const [x, y] of corners) {\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n if (\n maxX >= rect.x &&\n minX <= rect.x + rect.w &&\n maxY >= rect.y &&\n minY <= rect.y + rect.h\n ) {\n hits.push(re.element.id);\n }\n }\n // Buses: a horizontal/vertical segment is a tight rect.\n for (const { bus, geometry } of internal.buses.values()) {\n const { axis, at, span } = geometry;\n const half = span / 2;\n const minX = axis === 'x' ? at[0] - half : at[0];\n const maxX = axis === 'x' ? at[0] + half : at[0];\n const minY = axis === 'x' ? at[1] : at[1] - half;\n const maxY = axis === 'x' ? at[1] : at[1] + half;\n if (\n maxX >= rect.x &&\n minX <= rect.x + rect.w &&\n maxY >= rect.y &&\n minY <= rect.y + rect.h\n ) {\n hits.push(bus.id);\n }\n }\n return hits;\n}\n\nfunction transformLocalCorner(\n pt: [number, number],\n p: ResolvedPlacement,\n): [number, number] {\n let [x, y] = pt;\n if (p.mirror) x = -x;\n switch (p.rot) {\n case 0:\n break;\n case 90:\n [x, y] = [-y, x];\n break;\n case 180:\n [x, y] = [-x, -y];\n break;\n case 270:\n [x, y] = [y, -x];\n break;\n }\n return [x + p.at[0], y + p.at[1]];\n}\n\nfunction parseViewBox(s: string) {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n\nfunction cssEscape(s: string): string {\n return s.replace(/([\"\\\\])/g, '\\\\$1');\n}\n","/**\n * Pan tool: doubles as the touch-default tool. Three gestures off a single\n * finger:\n * - Tap on canvas → single-select (annotation > element > wire-node)\n * or clearSelection on empty space.\n * - Drag from selected → move the selected element(s) (DOM-direct preview,\n * element committed on pointerup via moveElements).\n * - Drag from elsewhere → pan the viewport.\n *\n * The drag-to-move path lets a phone user reposition elements without\n * switching tools — Pan is the everything-tool on touch, similar to how a\n * map app handles pins.\n */\n\nimport type { ResolvedPlacement } from '../../compiler';\nimport type { ElementId } from '../../model';\nimport { useEditorStore } from '../../store';\nimport { snap } from '../grid';\nimport { hitAnnotation, hitElement, hitNode } from '../hit-test';\nimport { transformAttr } from '../transform-attr';\nimport type { Tool } from './types';\n\nconst TAP_THRESHOLD_PX = 4;\n\ninterface PanState {\n pointerId: number;\n startX: number;\n startY: number;\n startTx: number;\n startTy: number;\n startTarget: EventTarget | null;\n moved: boolean;\n /** If set, the gesture started on these selected elements — drag = move\n * instead of pan. Stores each target's original placement so we can\n * preview via DOM transform and commit a delta on pointerup. */\n elementDrag: {\n startSvg: [number, number];\n originals: Map<ElementId, ResolvedPlacement>;\n } | null;\n}\n\nlet pan: PanState | null = null;\n\nexport const PanTool: Tool = {\n id: 'pan',\n cursor: 'grab',\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n const vp = ctx.viewport.getViewport();\n\n // If the gesture starts on a currently-selected element, set up an\n // element drag so the same finger can move it instead of panning.\n const startId = hitElement(e.target);\n let elementDrag: PanState['elementDrag'] = null;\n if (startId) {\n const store = useEditorStore.getState();\n // If the user pressed on an unselected element, treat as a fresh\n // single-selection so the upcoming drag operates on that element.\n // The tap-without-move path also commits this selection on release.\n if (!store.selection.includes(startId)) {\n store.setSelection([startId]);\n }\n const sel = useEditorStore.getState().selection;\n const internal = useEditorStore.getState().internal;\n const originals = new Map<ElementId, ResolvedPlacement>();\n for (const id of sel) {\n const p = internal.layout.get(id);\n if (p) originals.set(id, { ...p });\n }\n if (originals.size > 0) {\n elementDrag = {\n startSvg: ctx.viewport.screenToSvg(e.clientX, e.clientY),\n originals,\n };\n }\n }\n\n pan = {\n pointerId: e.pointerId,\n startX: e.clientX,\n startY: e.clientY,\n startTx: vp.tx,\n startTy: vp.ty,\n startTarget: e.target,\n moved: false,\n elementDrag,\n };\n // Defer pointer capture until the gesture actually moves so a quick tap\n // keeps its original target for the tap-select hit-test.\n ctx.hostEl.style.cursor = 'grabbing';\n e.preventDefault();\n },\n\n onPointerMove(e, ctx) {\n if (!pan || e.pointerId !== pan.pointerId) return;\n const dx = e.clientX - pan.startX;\n const dy = e.clientY - pan.startY;\n if (!pan.moved && Math.hypot(dx, dy) > TAP_THRESHOLD_PX) {\n pan.moved = true;\n try {\n ctx.hostEl.setPointerCapture(e.pointerId);\n } catch {\n /* pointer may already be released */\n }\n }\n if (!pan.moved) return;\n if (pan.elementDrag) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const ddx = snap(cur[0] - pan.elementDrag.startSvg[0]);\n const ddy = snap(cur[1] - pan.elementDrag.startSvg[1]);\n for (const [id, orig] of pan.elementDrag.originals) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (!node) continue;\n const next: ResolvedPlacement = {\n ...orig,\n at: [orig.at[0] + ddx, orig.at[1] + ddy],\n };\n node.setAttribute('transform', transformAttr(next));\n }\n return;\n }\n ctx.viewport.setViewport({ tx: pan.startTx + dx, ty: pan.startTy + dy });\n },\n\n onPointerUp(e, ctx) {\n if (!pan || e.pointerId !== pan.pointerId) return;\n if (ctx.hostEl.hasPointerCapture(e.pointerId)) {\n ctx.hostEl.releasePointerCapture(e.pointerId);\n }\n ctx.hostEl.style.cursor = 'grab';\n\n if (pan.elementDrag && pan.moved) {\n const cur = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const ddx = snap(cur[0] - pan.elementDrag.startSvg[0]);\n const ddy = snap(cur[1] - pan.elementDrag.startSvg[1]);\n if (ddx !== 0 || ddy !== 0) {\n const deltas = new Map<ElementId, [number, number]>();\n for (const id of pan.elementDrag.originals.keys()) {\n deltas.set(id, [ddx, ddy]);\n }\n useEditorStore.getState().moveElements(deltas);\n }\n } else if (!pan.moved) {\n handlePanTap(pan.startTarget);\n }\n pan = null;\n },\n\n onPointerCancel(_e, ctx) {\n if (pan?.elementDrag) {\n // Roll back the live preview transforms — store wasn't mutated yet.\n for (const [id, orig] of pan.elementDrag.originals) {\n const node = ctx.hostEl.querySelector<SVGGElement>(\n `[data-element-id=\"${cssEscape(id)}\"]`,\n );\n if (node) node.setAttribute('transform', transformAttr(orig));\n }\n }\n pan = null;\n },\n\n onDeactivate() {\n pan = null;\n },\n};\n\nfunction handlePanTap(target: EventTarget | null) {\n if (!target) return;\n const store = useEditorStore.getState();\n const annId = hitAnnotation(target);\n if (annId) {\n store.setSelectedAnnotation(annId);\n return;\n }\n const id = hitElement(target);\n if (id) {\n store.setSelection([id]);\n return;\n }\n const nodeId = hitNode(target);\n if (nodeId) {\n store.setSelectedNode(nodeId);\n return;\n }\n store.clearSelection();\n}\n\nfunction cssEscape(s: string): string {\n return s.replace(/([\"\\\\])/g, '\\\\$1');\n}\n","/**\n * Editor responsiveness tier: types, breakpoints, helpers, hook.\n *\n * Provider component lives in the sibling `.tsx` file so React Fast Refresh\n * stays clean (a single .tsx file mixing components and constants warns).\n *\n * Tiers are monotonic — each higher tier subsumes the lower ones. Component\n * code should use `atLeast(t, 'compact')` instead of `t === 'compact'`.\n */\n\nimport {\n createContext,\n useContext,\n useLayoutEffect,\n useState,\n type RefObject,\n} from 'react';\n\nexport type Tier = 'full' | 'tight' | 'compact' | 'dense' | 'mini';\n\n/**\n * Width thresholds. The key is the *next-tier-down* boundary: at or above\n * `tight` (900) the layout is `full`; below 900 it's `tight`, etc. Names line\n * up with what each tier collapses:\n * - `tight`: FloatingToolbar tool labels off and ViewToolbar's zoom-% pill\n * hides. The centered main toolbar (≈ 510px wide with labels)\n * otherwise collides with the right-anchored ViewToolbar\n * anywhere below ~880px.\n * - `compact`: outline tab also goes icon-only.\n * - `dense`: ToolHint pill hidden; ViewToolbar collapses to one popover.\n * - `mini`: FloatingToolbar's [Undo/Redo/Layout] group collapses too.\n */\nexport const BREAKPOINTS = {\n tight: 1024,\n compact: 720,\n dense: 520,\n mini: 380,\n} as const;\n\nconst RANK: Record<Tier, number> = {\n full: 0,\n tight: 1,\n compact: 2,\n dense: 3,\n mini: 4,\n};\n\nexport function atLeast(t: Tier, min: Tier): boolean {\n return RANK[t] >= RANK[min];\n}\n\nexport function tierForWidth(w: number): Tier {\n if (w >= BREAKPOINTS.tight) return 'full';\n if (w >= BREAKPOINTS.compact) return 'tight';\n if (w >= BREAKPOINTS.dense) return 'compact';\n if (w >= BREAKPOINTS.mini) return 'dense';\n return 'mini';\n}\n\nexport const TierContext = createContext<Tier>('full');\n\nexport function useEditorTier(): Tier {\n return useContext(TierContext);\n}\n\n/**\n * Track the `clientWidth` of an element via ResizeObserver. Lives where the\n * ref does (e.g., directly in `EditorShell`) — the layout effect needs the\n * ref to be already attached, which it is in the same component but isn't\n * yet when a child reads it. Returns `null` until the first measurement.\n */\nexport function useObservedWidth(\n ref: RefObject<HTMLElement | null>,\n): number | null {\n const [width, setWidth] = useState<number | null>(null);\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const apply = () => {\n const w = el.clientWidth;\n setWidth((prev) => (prev === w ? prev : w));\n };\n apply();\n if (typeof ResizeObserver === 'undefined') return;\n const ro = new ResizeObserver(apply);\n ro.observe(el);\n return () => ro.disconnect();\n }, [ref]);\n return width;\n}\n","/**\n * Phone-class UX helpers shared by the drawing tools (place / wire / busbar /\n * text). On a narrow coarse-pointer viewport the user expects a \"one-shot\"\n * gesture: pick a tool, place / wire / etc. once, and snap back to the\n * default pan tool. Desktop and tablet keep the sticky-tool behavior since\n * the keyboard / stylus makes re-entry cheap and multi-place is common.\n *\n * The viewport-width gate keeps tablet (iPad ≈ 768px portrait, also a\n * coarse pointer) on the desktop-style flow — the unified bottom bar /\n * full-screen library are only the phone form factor.\n */\n\nimport { useEditorStore } from '../store';\nimport { BREAKPOINTS } from '../hooks/editor-tier';\n\nfunction isPhoneUx(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n if (!window.matchMedia('(pointer: coarse)').matches) return false;\n } catch {\n return false;\n }\n return window.innerWidth < BREAKPOINTS.dense;\n}\n\nexport function exitToPanOnPhone(): void {\n if (!isPhoneUx()) return;\n useEditorStore.getState().setActiveTool('pan');\n}\n\n/**\n * On a phone-class viewport, drop the currently armed place kind without\n * leaving place mode. PlaceTool calls this after each successful placement\n * so the LibraryPopover (hidden while armed on mobile) reappears for the\n * next pick. Sticky `lastPlaceKind` is preserved by `setPlaceKind(null)`.\n */\nexport function disarmPlaceOnPhone(): void {\n if (!isPhoneUx()) return;\n useEditorStore.getState().setPlaceKind(null);\n}\n","/**\n * Wire tool: press on a terminal, drag to another terminal, release to commit.\n * Releasing on empty space (or the same terminal) cancels. Esc also cancels\n * via the global keyboard hook.\n *\n * Activating the tool sets `.tool-wire` on the canvas root, which the CSS\n * uses to reveal terminals and turn on their pointer-events so the drag-end\n * hit-test resolves to a terminal.\n *\n * During the drag we publish the *current* candidate target via\n * `wire-target-bus`; `WirePreview` paints a marker so the user sees where a\n * release would land — including the bus virtual-tap projection when the\n * cursor is over a bus body.\n */\n\nimport { useEditorStore } from '../../store';\nimport { hitTerminal } from '../hit-test';\nimport { resolveWireTarget } from '../resolve-wire-target';\nimport { exitToPanOnPhone } from '../touch';\nimport { publishWireTarget } from '../wire-target-bus';\nimport type { Tool } from './types';\n\nexport const WireTool: Tool = {\n id: 'wire',\n cursor: 'crosshair',\n\n onActivate(ctx) {\n ctx.hostEl.classList.add('tool-wire');\n },\n onDeactivate(ctx) {\n ctx.hostEl.classList.remove('tool-wire');\n const store = useEditorStore.getState();\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n },\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n const ref = hitTerminal(e.target);\n if (!ref) return;\n e.preventDefault();\n e.stopPropagation();\n\n // Touch pointers get implicit capture on pointerdown — release it so the\n // pointerup hit-test resolves to the terminal under the finger, not the\n // origin terminal.\n if (e.target instanceof Element && e.target.hasPointerCapture?.(e.pointerId)) {\n e.target.releasePointerCapture(e.pointerId);\n }\n\n const store = useEditorStore.getState();\n store.setWireFromTerminal(ref);\n store.setCursorSvg(ctx.viewport.screenToSvg(e.clientX, e.clientY));\n },\n\n onPointerMove(e, ctx) {\n const sf = useEditorStore.getState().wireFromTerminal;\n if (!sf) return;\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n useEditorStore.getState().setCursorSvg(pt);\n\n // Pointer capture pins `e.target` to the start terminal — sample what's\n // *actually* under the cursor instead.\n const under =\n typeof document !== 'undefined'\n ? document.elementFromPoint(e.clientX, e.clientY)\n : null;\n const ref = under ? hitTerminal(under) : null;\n if (!ref || ref === sf) {\n publishWireTarget(null);\n return;\n }\n publishWireTarget(resolveWireTarget(ref, pt));\n },\n\n onPointerUp(e) {\n const store = useEditorStore.getState();\n const from = store.wireFromTerminal;\n if (!from) return;\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n\n const ref = hitTerminal(e.target);\n if (!ref || ref === from) return;\n store.addWire(from, ref);\n exitToPanOnPhone();\n },\n\n onPointerLeave() {\n const store = useEditorStore.getState();\n store.setWireFromTerminal(null);\n store.setCursorSvg(null);\n publishWireTarget(null);\n },\n};\n","/**\n * Place tool: click anywhere on canvas to drop the chosen kind. The kind is\n * picked from the palette (LeftPanel single-click) or set programmatically\n * via `setActiveTool('place', { placeKind })`.\n *\n * Two interaction paths:\n * 1. Press on empty space (or near a bus body) → drops at cursor; near-bus\n * auto-tap via `dropElement`.\n * 2. Press on an existing terminal (incl. busbar virtual `tap`) → drag-place.\n * Ghost follows the cursor with a dashed wire previewing the connection\n * back to the source terminal. On release we create the element and add\n * the connection in a single undo step via `dropElementFromTerminal`.\n *\n * Activating the tool sets `.tool-place` on the canvas root, which the CSS\n * uses to reveal terminals so users can see drag-from targets.\n *\n * Stays in place mode after dropping so the user can drop multiples; press\n * Esc or switch tools to leave.\n */\n\nimport { useEditorStore } from '../../store';\nimport { dropElement, dropElementFromTerminal } from '../drop-on-bus';\nimport { hitTerminal } from '../hit-test';\nimport { disarmPlaceOnPhone } from '../touch';\nimport type { Tool } from './types';\n\nconst GRID = 10;\n\n// On touch, the click-to-drop path commits in onPointerDown. Disarming\n// `placeKind` there reopens the LibraryPopover mid-gesture, and the\n// synthesized click event for the same tap then hit-tests against the\n// freshly-rendered library item — arming a different kind. Defer the\n// disarm to a macrotask after pointerup so the click dispatches to the\n// canvas first.\nlet disarmOnUp = false;\nfunction scheduleDisarm(): void {\n setTimeout(() => disarmPlaceOnPhone(), 0);\n}\n\nexport const PlaceTool: Tool = {\n id: 'place',\n cursor: 'copy',\n\n onActivate(ctx) {\n ctx.hostEl.classList.add('tool-place');\n },\n onDeactivate(ctx) {\n ctx.hostEl.classList.remove('tool-place');\n const store = useEditorStore.getState();\n store.setPlaceFromTerminal(null);\n store.setCursorSvg(null);\n disarmOnUp = false;\n },\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n const { placeKind } = useEditorStore.getState();\n if (!placeKind) return;\n e.preventDefault();\n\n const ref = hitTerminal(e.target);\n if (ref) {\n // Drag-from-terminal mode: defer creation until pointerup so the user\n // can cancel by releasing outside or pressing Esc.\n e.stopPropagation();\n\n // Touch pointers get implicit capture on pointerdown — release it so\n // pointermove/up reflect the actual cursor target, mirroring WireTool.\n if (e.target instanceof Element && e.target.hasPointerCapture?.(e.pointerId)) {\n e.target.releasePointerCapture(e.pointerId);\n }\n\n const store = useEditorStore.getState();\n store.setPlaceFromTerminal(ref);\n store.setCursorSvg(ctx.viewport.screenToSvg(e.clientX, e.clientY));\n return;\n }\n\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n dropElement(placeKind, pt);\n disarmOnUp = true;\n },\n\n onPointerMove(e, ctx) {\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n useEditorStore.getState().setCursorSvg([snap(pt[0]), snap(pt[1])]);\n },\n\n onPointerUp(e, ctx) {\n const store = useEditorStore.getState();\n const from = store.placeFromTerminal;\n if (from) {\n store.setPlaceFromTerminal(null);\n const { placeKind } = store;\n if (!placeKind) return;\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n dropElementFromTerminal(placeKind, from, pt);\n scheduleDisarm();\n return;\n }\n if (disarmOnUp) {\n disarmOnUp = false;\n scheduleDisarm();\n }\n },\n\n onPointerLeave() {\n const store = useEditorStore.getState();\n store.setPlaceFromTerminal(null);\n store.setCursorSvg(null);\n },\n\n onPointerCancel() {\n // Pinch-zoom hijack interrupted the drag-place; drop the staged source\n // terminal without committing a placement at the (likely synthetic)\n // pointer-cancel coordinates.\n const store = useEditorStore.getState();\n store.setPlaceFromTerminal(null);\n store.setCursorSvg(null);\n disarmOnUp = false;\n },\n};\n\nfunction snap(v: number): number {\n return Math.round(v / GRID) * GRID;\n}\n","/**\n * Busbar tool: click-and-drag to draw a horizontal or vertical bus segment.\n *\n * Unlike the place tool (drop a fixed-size element on click), the bus needs\n * an explicit length and orientation per instance. The tool snaps the drawn\n * line to the dominant axis (horizontal or vertical) so that downstream\n * stretching, tap-routing and connectivity all stay aligned to the grid.\n *\n * Live preview: `busbarDrawStart` in the store holds the press point;\n * `cursorSvg` holds the current cursor. `BusbarPreview` reads both and\n * renders the snapped line in real time.\n *\n * UX: pointerdown sets the start; pointerup commits. Esc cancels via the\n * global keyboard hook (re-activates select).\n */\n\nimport { useEditorStore } from '../../store';\nimport { exitToPanOnPhone } from '../touch';\nimport type { Tool } from './types';\n\nconst GRID = 10;\nconst MIN_LEN = 20;\n\nfunction snap(v: number): number {\n return Math.round(v / GRID) * GRID;\n}\n\nexport const BusbarTool: Tool = {\n id: 'busbar',\n cursor: 'crosshair',\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n e.preventDefault();\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const start: [number, number] = [snap(pt[0]), snap(pt[1])];\n useEditorStore.getState().setBusbarDrawStart(start);\n useEditorStore.getState().setCursorSvg(start);\n },\n\n onPointerMove(e, ctx) {\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n useEditorStore.getState().setCursorSvg([snap(pt[0]), snap(pt[1])]);\n },\n\n onPointerUp(e, ctx) {\n const start = useEditorStore.getState().busbarDrawStart;\n useEditorStore.getState().setBusbarDrawStart(null);\n if (!start) return;\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const endX = snap(pt[0]);\n const endY = snap(pt[1]);\n const dx = endX - start[0];\n const dy = endY - start[1];\n const horizontal = Math.abs(dx) >= Math.abs(dy);\n\n let rot: 0 | 90;\n let span: number;\n let at: [number, number];\n\n if (horizontal) {\n span = Math.abs(dx);\n if (span < MIN_LEN) return;\n rot = 0;\n at = [(start[0] + endX) / 2, start[1]];\n } else {\n span = Math.abs(dy);\n if (span < MIN_LEN) return;\n rot = 90;\n at = [start[0], (start[1] + endY) / 2];\n }\n\n const store = useEditorStore.getState();\n store.addBus(at, span, rot);\n exitToPanOnPhone();\n },\n\n onPointerLeave() {\n const store = useEditorStore.getState();\n store.setBusbarDrawStart(null);\n store.setCursorSvg(null);\n },\n\n onPointerCancel() {\n // Pinch-zoom hijack interrupted the draw; abandon the in-progress busbar\n // rather than committing one at the synthetic cancel coordinates.\n const store = useEditorStore.getState();\n store.setBusbarDrawStart(null);\n store.setCursorSvg(null);\n },\n\n onDeactivate() {\n const store = useEditorStore.getState();\n store.setBusbarDrawStart(null);\n store.setCursorSvg(null);\n },\n};\n","/**\n * Text tool: click anywhere on empty canvas to drop a free text annotation\n * at the cursor and immediately enter inline-edit mode. After committing\n * (Enter / blur), control returns to the select tool with the annotation\n * still selected so users can keep moving / resizing it.\n *\n * Clicking on an existing annotation focuses it for re-edit instead of\n * dropping a new one.\n */\n\nimport { useEditorStore } from '../../store';\nimport { hitAnnotation } from '../hit-test';\nimport { exitToPanOnPhone } from '../touch';\nimport type { Tool } from './types';\n\nexport const TextTool: Tool = {\n id: 'text',\n cursor: 'text',\n\n onPointerDown(e, ctx) {\n if (e.button !== 0) return;\n const store = useEditorStore.getState();\n\n // Clicking an existing annotation in text mode just selects it under\n // the regular select tool — editing is reserved for double-click so\n // single clicks don't accidentally trash content while repositioning.\n const existing = hitAnnotation(e.target);\n if (existing) {\n e.preventDefault();\n e.stopPropagation();\n store.setActiveTool('select');\n store.setSelectedAnnotation(existing);\n return;\n }\n\n e.preventDefault();\n const pt = ctx.viewport.screenToSvg(e.clientX, e.clientY);\n const id = store.addAnnotation([pt[0], pt[1]], '');\n store.setEditingAnnotation(id);\n exitToPanOnPhone();\n },\n};\n","import type { Tool, ToolId } from './types';\nimport { SelectTool } from './SelectTool';\nimport { PanTool } from './PanTool';\nimport { WireTool } from './WireTool';\nimport { PlaceTool } from './PlaceTool';\nimport { BusbarTool } from './BusbarTool';\nimport { TextTool } from './TextTool';\n\nexport const TOOLS: Record<ToolId, Tool> = {\n select: SelectTool,\n pan: PanTool,\n wire: WireTool,\n place: PlaceTool,\n busbar: BusbarTool,\n text: TextTool,\n};\n\nexport type { Tool, ToolContext, ToolId } from './types';\n","/**\n * Wires the active tool's pointer/key handlers onto the canvas host. Re-runs\n * on tool change to call `onDeactivate` for the old and `onActivate` for the\n * new — that's where tools install/remove their per-mode state (e.g. WireTool\n * adding `.tool-wire` to reveal terminals).\n */\n\nimport { useEffect, type RefObject } from 'react';\nimport { useEditorStore } from '../store';\nimport { TOOLS } from './tools';\nimport type { ToolContext } from './tools';\nimport type { ViewportApi } from './useViewport';\n\nexport function useTools(\n hostRef: RefObject<HTMLDivElement | null>,\n viewport: ViewportApi,\n): void {\n const activeTool = useEditorStore((s) => s.activeTool);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const tool = TOOLS[activeTool];\n const ctx: ToolContext = { viewport, hostEl: host };\n\n tool.onActivate?.(ctx);\n if (tool.cursor) host.style.cursor = tool.cursor;\n\n const onDown = (e: PointerEvent) => tool.onPointerDown?.(e, ctx);\n const onMove = (e: PointerEvent) => tool.onPointerMove?.(e, ctx);\n const onUp = (e: PointerEvent) => tool.onPointerUp?.(e, ctx);\n // Pointercancel: if the tool defines its own cancel hook, use it (so it\n // can roll back without committing the gesture). Otherwise treat it as\n // a normal pointerup — the existing tools already handle that case.\n const onCancel = (e: PointerEvent) =>\n tool.onPointerCancel ? tool.onPointerCancel(e, ctx) : tool.onPointerUp?.(e, ctx);\n const onLeave = (e: PointerEvent) => tool.onPointerLeave?.(e, ctx);\n const onDbl = (e: MouseEvent) => tool.onDoubleClick?.(e, ctx);\n\n host.addEventListener('pointerdown', onDown);\n host.addEventListener('pointermove', onMove);\n host.addEventListener('pointerup', onUp);\n host.addEventListener('pointercancel', onCancel);\n host.addEventListener('pointerleave', onLeave);\n host.addEventListener('dblclick', onDbl);\n\n return () => {\n host.removeEventListener('pointerdown', onDown);\n host.removeEventListener('pointermove', onMove);\n host.removeEventListener('pointerup', onUp);\n host.removeEventListener('pointercancel', onCancel);\n host.removeEventListener('pointerleave', onLeave);\n host.removeEventListener('dblclick', onDbl);\n tool.onDeactivate?.(ctx);\n host.style.cursor = '';\n };\n }, [activeTool, hostRef, viewport]);\n}\n","/**\n * Tiny pub/sub for the live viewport scale. Lets chrome (TopBar zoom %) read\n * the value without forcing the gesture path through React state. Updated\n * by `useViewport` after every transform change.\n */\n\ntype Listener = (scale: number) => void;\n\nlet current = 1;\nconst listeners = new Set<Listener>();\n\nexport function publishScale(scale: number): void {\n if (scale === current) return;\n current = scale;\n for (const l of listeners) l(scale);\n}\n\nexport function getScale(): number {\n return current;\n}\n\nexport function subscribeScale(fn: Listener): () => void {\n listeners.add(fn);\n return () => {\n listeners.delete(fn);\n };\n}\n","/**\n * Pan/zoom viewport. State lives on refs and is pushed straight to the SVG\n * `<g transform>` and the parent's `--canvas-scale` CSS variable; React is\n * deliberately not involved during gestures so we don't re-render on every\n * wheel tick or pointer move.\n *\n * Exposes `screenToSvg()` so future tools (select, wire, place) can convert\n * pointer events to canvas coordinates without owning their own viewport.\n */\n\nimport { useEffect, useRef, type RefObject } from 'react';\nimport { dispatchSyntheticPointerCancel } from './synthetic-pointer-cancel';\nimport { publishScale } from './zoom-bus';\n\nexport interface Viewport {\n tx: number;\n ty: number;\n scale: number;\n}\n\nexport interface ViewportApi {\n /** Convert a clientX/Y (CSS pixels relative to the viewport) → SVG coords. */\n screenToSvg(clientX: number, clientY: number): [number, number];\n /** Read-only snapshot of the current transform. */\n getViewport(): Viewport;\n /** Update one or more viewport fields. */\n setViewport(patch: Partial<Viewport>): void;\n /** Subscribe to viewport changes; returns an unsubscribe fn. */\n subscribe(listener: (vp: Viewport) => void): () => void;\n}\n\nconst MIN_SCALE = 0.1;\nconst MAX_SCALE = 8;\n// Mouse wheel events on macOS arrive with |deltaY| ≈ 100 per click, so a\n// small factor still produces a comfortable per-click zoom. Trackpad pinch\n// (Chrome/Safari synthesize wheel events with ctrlKey + small deltaY,\n// typically 1–10) needs a much larger factor or it crawls vs. native apps.\nconst ZOOM_FACTOR_WHEEL = 1.0015;\nconst ZOOM_FACTOR_PINCH = 1.02;\n\nexport function useViewport(\n hostRef: RefObject<HTMLDivElement | null>,\n groupRef: RefObject<SVGGElement | null>,\n initial: Viewport = { tx: 0, ty: 0, scale: 1 },\n): ViewportApi {\n const vp = useRef<Viewport>({ ...initial });\n const listeners = useRef(new Set<(vp: Viewport) => void>());\n\n // Apply transform on the SVG group + expose --canvas-scale for stroke\n // compensation in CSS, then notify subscribers.\n const apply = () => {\n const g = groupRef.current;\n const host = hostRef.current;\n if (g) {\n g.setAttribute(\n 'transform',\n `translate(${vp.current.tx} ${vp.current.ty}) scale(${vp.current.scale})`,\n );\n }\n if (host) {\n host.style.setProperty('--canvas-scale', String(vp.current.scale));\n }\n publishScale(vp.current.scale);\n if (listeners.current.size > 0) {\n const snapshot = { ...vp.current };\n for (const fn of listeners.current) fn(snapshot);\n }\n };\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n\n let panning = false;\n let panPointerId = -1;\n let panStartX = 0;\n let panStartY = 0;\n let panStartTx = 0;\n let panStartTy = 0;\n let spaceDown = false;\n\n // ---- Multi-touch pinch / two-finger pan -----------------------------\n // iPad/iPhone have no wheel events, so pinch-zoom + two-finger pan are\n // the only way to navigate the canvas. We track every active touch\n // pointer; once two are down we hijack all touch events (capture phase\n // + stopPropagation) so the active tool stops receiving them and the\n // viewport handles pan/zoom directly. Hijack lasts until all touches\n // lift, so the trailing finger of a pinch never accidentally restarts\n // a tool gesture.\n const touches = new Map<number, { x: number; y: number }>();\n interface PinchState {\n startDist: number;\n startScale: number;\n startTx: number;\n startTy: number;\n startMidX: number;\n startMidY: number;\n }\n let pinch: PinchState | null = null;\n let touchHijack = false;\n\n const recomputePinchBaseline = () => {\n if (touches.size < 2) {\n pinch = null;\n return;\n }\n const pts = [...touches.values()];\n const dx = pts[1].x - pts[0].x;\n const dy = pts[1].y - pts[0].y;\n const dist = Math.hypot(dx, dy) || 1;\n const rect = host.getBoundingClientRect();\n pinch = {\n startDist: dist,\n startScale: vp.current.scale,\n startTx: vp.current.tx,\n startTy: vp.current.ty,\n startMidX: (pts[0].x + pts[1].x) / 2 - rect.left,\n startMidY: (pts[0].y + pts[1].y) / 2 - rect.top,\n };\n };\n\n const onTouchPointerDownCap = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') return;\n touches.set(e.pointerId, { x: e.clientX, y: e.clientY });\n if (touches.size >= 2 && !touchHijack) {\n touchHijack = true;\n // Cancel any in-progress single-touch tool gesture (drag, marquee,\n // wire, etc.) so it doesn't keep mutating state while we pinch.\n // Synthetic pointercancel fires the tool's existing cleanup path.\n for (const id of touches.keys()) {\n if (id === e.pointerId) continue;\n dispatchSyntheticPointerCancel(host, id);\n }\n recomputePinchBaseline();\n }\n if (touchHijack) {\n e.stopPropagation();\n e.preventDefault();\n try {\n host.setPointerCapture(e.pointerId);\n } catch {\n /* capture may fail if the pointer was already released */\n }\n }\n };\n\n const onTouchPointerMoveCap = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') return;\n if (!touches.has(e.pointerId)) return;\n touches.set(e.pointerId, { x: e.clientX, y: e.clientY });\n if (!touchHijack || !pinch) return;\n e.stopPropagation();\n const pts = [...touches.values()];\n if (pts.length < 2) return;\n const dx = pts[1].x - pts[0].x;\n const dy = pts[1].y - pts[0].y;\n const dist = Math.hypot(dx, dy) || 1;\n const rect = host.getBoundingClientRect();\n const midX = (pts[0].x + pts[1].x) / 2 - rect.left;\n const midY = (pts[0].y + pts[1].y) / 2 - rect.top;\n const ratio = dist / pinch.startDist;\n const next = clamp(pinch.startScale * ratio, MIN_SCALE, MAX_SCALE);\n const k = next / pinch.startScale;\n // Anchor zoom at the initial midpoint, then add the midpoint drift\n // so the pinch also pans.\n vp.current.tx =\n pinch.startMidX - (pinch.startMidX - pinch.startTx) * k + (midX - pinch.startMidX);\n vp.current.ty =\n pinch.startMidY - (pinch.startMidY - pinch.startTy) * k + (midY - pinch.startMidY);\n vp.current.scale = next;\n apply();\n };\n\n const onTouchPointerUpCap = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') return;\n if (!touches.has(e.pointerId)) return;\n touches.delete(e.pointerId);\n if (touchHijack) {\n e.stopPropagation();\n if (host.hasPointerCapture?.(e.pointerId)) {\n try {\n host.releasePointerCapture(e.pointerId);\n } catch {\n /* ignore */\n }\n }\n // If a finger lifted but more than one is still down, recompute\n // the pinch baseline so the next move continues smoothly.\n if (touches.size >= 2) {\n recomputePinchBaseline();\n } else {\n pinch = null;\n }\n if (touches.size === 0) {\n touchHijack = false;\n }\n }\n };\n\n const onWheel = (e: WheelEvent) => {\n e.preventDefault();\n const rect = host.getBoundingClientRect();\n const cx = e.clientX - rect.left;\n const cy = e.clientY - rect.top;\n\n // CAD-style: any pure-vertical wheel event zooms (mouse wheel on macOS\n // can have |deltaY| < 30 — earlier threshold-based heuristic let those\n // slip into the pan branch, producing a \"wobble\" during zoom).\n // Pinch (ctrl/meta) zooms regardless of axis. Only deltaX-bearing\n // events without a modifier are treated as trackpad pan.\n const isPinch = e.ctrlKey || e.metaKey;\n const isZoom = e.deltaX === 0 || isPinch;\n\n if (isZoom) {\n const factor = isPinch ? ZOOM_FACTOR_PINCH : ZOOM_FACTOR_WHEEL;\n const k = Math.pow(factor, -e.deltaY);\n const next = clamp(vp.current.scale * k, MIN_SCALE, MAX_SCALE);\n // Keep cursor anchored.\n const ratio = next / vp.current.scale;\n vp.current.tx = cx - (cx - vp.current.tx) * ratio;\n vp.current.ty = cy - (cy - vp.current.ty) * ratio;\n vp.current.scale = next;\n } else {\n vp.current.tx -= e.deltaX;\n vp.current.ty -= e.deltaY;\n }\n apply();\n };\n\n const onPointerDown = (e: PointerEvent) => {\n // Middle-click pan, or space-held + left-click pan.\n const isMiddle = e.button === 1;\n const isSpaceLeft = spaceDown && e.button === 0;\n if (!isMiddle && !isSpaceLeft) return;\n e.preventDefault();\n panning = true;\n panPointerId = e.pointerId;\n panStartX = e.clientX;\n panStartY = e.clientY;\n panStartTx = vp.current.tx;\n panStartTy = vp.current.ty;\n host.setPointerCapture(e.pointerId);\n host.style.cursor = 'grabbing';\n };\n const onPointerMove = (e: PointerEvent) => {\n if (!panning || e.pointerId !== panPointerId) return;\n vp.current.tx = panStartTx + (e.clientX - panStartX);\n vp.current.ty = panStartTy + (e.clientY - panStartY);\n apply();\n };\n const onPointerUp = (e: PointerEvent) => {\n if (panning && e.pointerId === panPointerId) {\n panning = false;\n host.releasePointerCapture(e.pointerId);\n host.style.cursor = spaceDown ? 'grab' : '';\n }\n };\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.code === 'Space' && !spaceDown) {\n // Don't hijack typing into a future input element.\n const target = e.target as HTMLElement | null;\n if (target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable)) return;\n spaceDown = true;\n host.style.cursor = 'grab';\n e.preventDefault();\n }\n };\n const onKeyUp = (e: KeyboardEvent) => {\n if (e.code === 'Space') {\n spaceDown = false;\n if (!panning) host.style.cursor = '';\n }\n };\n\n host.addEventListener('wheel', onWheel, { passive: false });\n host.addEventListener('pointerdown', onPointerDown);\n host.addEventListener('pointermove', onPointerMove);\n host.addEventListener('pointerup', onPointerUp);\n host.addEventListener('pointercancel', onPointerUp);\n // Touch handlers run in the capture phase so they can stopPropagation()\n // and prevent the active tool from receiving the events while pinch is\n // in progress.\n host.addEventListener('pointerdown', onTouchPointerDownCap, { capture: true });\n host.addEventListener('pointermove', onTouchPointerMoveCap, { capture: true });\n host.addEventListener('pointerup', onTouchPointerUpCap, { capture: true });\n host.addEventListener('pointercancel', onTouchPointerUpCap, { capture: true });\n window.addEventListener('keydown', onKeyDown);\n window.addEventListener('keyup', onKeyUp);\n\n apply();\n\n return () => {\n host.removeEventListener('wheel', onWheel);\n host.removeEventListener('pointerdown', onPointerDown);\n host.removeEventListener('pointermove', onPointerMove);\n host.removeEventListener('pointerup', onPointerUp);\n host.removeEventListener('pointercancel', onPointerUp);\n host.removeEventListener('pointerdown', onTouchPointerDownCap, { capture: true });\n host.removeEventListener('pointermove', onTouchPointerMoveCap, { capture: true });\n host.removeEventListener('pointerup', onTouchPointerUpCap, { capture: true });\n host.removeEventListener('pointercancel', onTouchPointerUpCap, { capture: true });\n window.removeEventListener('keydown', onKeyDown);\n window.removeEventListener('keyup', onKeyUp);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return {\n screenToSvg(clientX: number, clientY: number) {\n const host = hostRef.current;\n if (!host) return [clientX, clientY];\n const rect = host.getBoundingClientRect();\n const x = (clientX - rect.left - vp.current.tx) / vp.current.scale;\n const y = (clientY - rect.top - vp.current.ty) / vp.current.scale;\n return [x, y];\n },\n getViewport() {\n return { ...vp.current };\n },\n setViewport(patch: Partial<Viewport>) {\n if (patch.tx !== undefined) vp.current.tx = patch.tx;\n if (patch.ty !== undefined) vp.current.ty = patch.ty;\n if (patch.scale !== undefined)\n vp.current.scale = clamp(patch.scale, MIN_SCALE, MAX_SCALE);\n apply();\n },\n subscribe(listener) {\n listeners.current.add(listener);\n return () => {\n listeners.current.delete(listener);\n };\n },\n };\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n","/**\n * Top-level canvas SVG. Owns the pan/zoom viewport `<g>`, the static grid\n * background, and the active-tool dispatcher. Layers (wires, elements,\n * selection, terminals, previews) are children of the viewport so they\n * pan/zoom together.\n *\n * Z-order (back to front): grid → wires → elements → selection → terminals\n * → wire preview → place ghost.\n */\n\nimport { useCallback, useEffect, useRef } from 'react';\nimport {\n BoxSelect,\n Clipboard,\n Copy,\n FlipHorizontal,\n Redo2,\n RotateCw,\n Scissors,\n Trash2,\n Undo2,\n} from 'lucide-react';\nimport { useContextMenu, type ContextMenuEntry } from '../components/ContextMenu';\nimport { useT } from '../i18n';\nimport { useEditorStore } from '../store';\nimport { setViewportApi } from './viewport-bus';\nimport { dropElement } from './drop-on-bus';\nimport { AnnotationLayer } from './AnnotationLayer';\nimport { FreeAnnotationLayer } from './FreeAnnotationLayer';\nimport { BusHandles } from './BusHandles';\nimport { WireHandles } from './WireHandles';\nimport { BusLayer } from './BusLayer';\nimport { BusbarPreview } from './BusbarPreview';\nimport { ElementLayer } from './ElementLayer';\nimport { MarqueeOverlay } from './MarqueeOverlay';\nimport { PlaceGhost } from './PlaceGhost';\nimport { SelectionOverlay } from './SelectionOverlay';\nimport { TerminalLayer } from './TerminalLayer';\nimport { WireLayer } from './WireLayer';\nimport { WirePreview } from './WirePreview';\nimport { hitElement, hitNode } from './hit-test';\nimport { dispatchSyntheticPointerCancel } from './synthetic-pointer-cancel';\nimport { exitDrawingState } from './useKeyboardShortcuts';\nimport { useHoverHighlight } from './useHoverHighlight';\nimport { useTools } from './useTools';\nimport { useViewport } from './useViewport';\n\nconst IS_MAC =\n typeof navigator !== 'undefined' && /Mac|iP(ad|hone|od)/.test(navigator.platform);\nconst MOD = IS_MAC ? '⌘' : 'Ctrl+';\nconst SHIFT = IS_MAC ? '⇧' : 'Shift+';\n\n/**\n * Pick a world-space grid step (in snap units) so the rendered tile is at\n * least ~18 screen px. Steps are multiples of the snap step (10) along a\n * 1-2-5 series so every dot still lands on a snappable position.\n */\nconst GRID_STEPS = [10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000];\nconst MIN_SCREEN_STEP = 18;\nfunction pickGridStep(scale: number): number {\n for (const w of GRID_STEPS) {\n if (w * scale >= MIN_SCREEN_STEP) return w;\n }\n return GRID_STEPS[GRID_STEPS.length - 1];\n}\n\nexport function CanvasSvg() {\n const t = useT();\n const hostRef = useRef<HTMLDivElement | null>(null);\n const groupRef = useRef<SVGGElement | null>(null);\n const gridPatternRef = useRef<SVGPatternElement | null>(null);\n const viewport = useViewport(hostRef, groupRef);\n useTools(hostRef, viewport);\n useHoverHighlight(hostRef);\n useEffect(() => {\n setViewportApi(viewport);\n return () => setViewportApi(null);\n }, [viewport]);\n // Dot grid: stays locked to world coordinates (so dots line up with snap\n // targets) but the *visible* spacing adapts to zoom. Picking a world-step\n // that's a multiple of the snap step (10) and large enough to render\n // ≥ MIN_SCREEN_STEP screen pixels keeps the grid readable from 0.1× to 8×\n // without dots either piling into a haze or growing into giant blobs.\n useEffect(() => {\n const sync = (vp: { tx: number; ty: number; scale: number }) => {\n const el = gridPatternRef.current;\n if (!el) return;\n const worldStep = pickGridStep(vp.scale);\n const screenStep = worldStep * vp.scale;\n el.setAttribute('width', String(screenStep));\n el.setAttribute('height', String(screenStep));\n el.setAttribute('patternTransform', `translate(${vp.tx} ${vp.ty})`);\n };\n sync(viewport.getViewport());\n return viewport.subscribe(sync);\n }, [viewport]);\n const contextMenu = useContextMenu();\n\n // Open the contextual menu at a screen point, hit-testing the given target\n // so the menu's selection-aware items (cut/copy/rotate/etc.) reflect what\n // the user is pointing at. Shared by mouse right-click and touch long-press.\n const openContextMenuAt = useCallback(\n (clientX: number, clientY: number, target: EventTarget | null) => {\n const store = useEditorStore.getState();\n const tool = store.activeTool;\n if (tool === 'wire' || tool === 'busbar' || tool === 'place') {\n exitDrawingState();\n return;\n }\n const elementId = hitElement(target);\n if (elementId) {\n if (!store.selection.includes(elementId)) {\n store.setSelection([elementId]);\n }\n } else {\n const nodeId = hitNode(target);\n if (nodeId && store.selectedNode !== nodeId) {\n store.setSelectedNode(nodeId);\n }\n }\n\n const s = useEditorStore.getState();\n const hasSelection = s.selection.length > 0;\n const hasNodeSelection = s.selectedNode != null;\n const hasClipboard = !!s.clipboard;\n const hasAnyElement = s.diagram.elements.length > 0;\n const items: ContextMenuEntry[] = [\n {\n label: t('menu.undo'),\n shortcut: `${MOD}Z`,\n icon: Undo2,\n onSelect: () => useEditorStore.getState().undo(),\n disabled: s.past.length === 0,\n },\n {\n label: t('menu.redo'),\n shortcut: `${MOD}${SHIFT}Z`,\n icon: Redo2,\n onSelect: () => useEditorStore.getState().redo(),\n disabled: s.future.length === 0,\n },\n { type: 'separator' },\n {\n label: t('menu.cut'),\n shortcut: `${MOD}X`,\n icon: Scissors,\n onSelect: () => useEditorStore.getState().cutSelection(),\n disabled: !hasSelection,\n },\n {\n label: t('menu.copy'),\n shortcut: `${MOD}C`,\n icon: Copy,\n onSelect: () => useEditorStore.getState().copySelection(),\n disabled: !hasSelection,\n },\n {\n label: t('menu.paste'),\n shortcut: `${MOD}V`,\n icon: Clipboard,\n onSelect: () => useEditorStore.getState().pasteClipboard(),\n disabled: !hasClipboard,\n },\n { type: 'separator' },\n {\n label: t('menu.rotate'),\n shortcut: 'R',\n icon: RotateCw,\n onSelect: () => useEditorStore.getState().rotateSelection(90),\n disabled: !hasSelection,\n },\n {\n label: t('menu.mirror'),\n shortcut: 'M',\n icon: FlipHorizontal,\n onSelect: () => useEditorStore.getState().mirrorSelection(),\n disabled: !hasSelection,\n },\n { type: 'separator' },\n {\n label: t('menu.selectAll'),\n shortcut: `${MOD}A`,\n icon: BoxSelect,\n onSelect: () => {\n const st = useEditorStore.getState();\n st.setSelection(st.diagram.elements.map((x) => x.id));\n },\n disabled: !hasAnyElement,\n },\n { type: 'separator' },\n {\n label: hasNodeSelection && !hasSelection ? t('menu.disconnect') : t('menu.delete'),\n shortcut: 'Del',\n icon: Trash2,\n destructive: true,\n onSelect: () =>\n hasNodeSelection && !hasSelection\n ? useEditorStore.getState().deleteSelectedNode()\n : useEditorStore.getState().deleteSelection(),\n disabled: !hasSelection && !hasNodeSelection,\n },\n ];\n contextMenu.open(clientX, clientY, items);\n },\n [contextMenu, t],\n );\n\n // Long-press → context menu (touch-only equivalent of right-click). On\n // touch devices there is no right button, so we open the same menu after\n // the user holds a single finger still for ~700ms. The movement threshold\n // matches PanTool's tap threshold so a slow pan can't accidentally hover\n // long enough to fire the menu mid-drag. A second touch (pinch) cancels\n // via the synthetic pointercancel from useViewport.\n //\n // Listeners are native (not React-synthetic) so they fire deterministically\n // alongside the tool's native pointer handlers in `useTools`. React's\n // synthetic dispatch was racing with selection re-renders triggered by\n // PanTool's tap-to-select, occasionally dropping the pointerup that should\n // have cancelled the timer.\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const LONG_PRESS_MS = 700;\n const LONG_PRESS_MOVE_PX = 4;\n let timer: number | undefined;\n let data: { pointerId: number; x: number; y: number; target: EventTarget | null } | null = null;\n const cancel = () => {\n if (timer !== undefined) window.clearTimeout(timer);\n timer = undefined;\n data = null;\n };\n const onDown = (e: PointerEvent) => {\n if (e.pointerType !== 'touch') return;\n cancel();\n data = {\n pointerId: e.pointerId,\n x: e.clientX,\n y: e.clientY,\n target: e.target,\n };\n timer = window.setTimeout(() => {\n const d = data;\n data = null;\n timer = undefined;\n if (!d) return;\n // Cancel the active tool's in-progress gesture so the long-press\n // doesn't double as a drag commit when the user releases.\n dispatchSyntheticPointerCancel(host, d.pointerId);\n openContextMenuAt(d.x, d.y, d.target);\n }, LONG_PRESS_MS);\n };\n const onMove = (e: PointerEvent) => {\n if (!data || e.pointerId !== data.pointerId) return;\n const dx = e.clientX - data.x;\n const dy = e.clientY - data.y;\n if (Math.hypot(dx, dy) > LONG_PRESS_MOVE_PX) cancel();\n };\n const onEnd = (e: PointerEvent) => {\n if (!data || e.pointerId !== data.pointerId) return;\n cancel();\n };\n host.addEventListener('pointerdown', onDown);\n host.addEventListener('pointermove', onMove);\n host.addEventListener('pointerup', onEnd);\n host.addEventListener('pointercancel', onEnd);\n return () => {\n cancel();\n host.removeEventListener('pointerdown', onDown);\n host.removeEventListener('pointermove', onMove);\n host.removeEventListener('pointerup', onEnd);\n host.removeEventListener('pointercancel', onEnd);\n };\n }, [openContextMenuAt]);\n\n const onDragOver = (e: React.DragEvent) => {\n if (e.dataTransfer.types.includes('application/x-oneline-kind')) {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'copy';\n }\n };\n\n const onDrop = (e: React.DragEvent) => {\n const kind = e.dataTransfer.getData('application/x-oneline-kind');\n if (!kind) return;\n e.preventDefault();\n const pt = viewport.screenToSvg(e.clientX, e.clientY);\n dropElement(kind, pt);\n };\n\n const onContextMenu = (e: React.MouseEvent) => {\n e.preventDefault();\n openContextMenuAt(e.clientX, e.clientY, e.target);\n };\n\n return (\n <div\n ref={hostRef}\n className=\"ole-canvas-root absolute inset-0 overflow-hidden\"\n onDragOver={onDragOver}\n onDrop={onDrop}\n onContextMenu={onContextMenu}\n >\n <svg\n className=\"ole-canvas-svg block h-full w-full\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <defs>\n <pattern\n ref={gridPatternRef}\n id=\"ole-grid-dots\"\n width={20}\n height={20}\n patternUnits=\"userSpaceOnUse\"\n >\n {/* Dot at the cell corner so every visible dot lands on a snap\n position (snap step = 10, pattern step = 20 → every dot is on\n a multiple-of-20 snap point). */}\n <circle cx={0} cy={0} r={2} fill=\"var(--canvas-grid-strong)\" />\n </pattern>\n </defs>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#ole-grid-dots)\" />\n <g ref={groupRef} className=\"ole-viewport\">\n <BusLayer />\n <WireLayer />\n <ElementLayer />\n <AnnotationLayer />\n <FreeAnnotationLayer />\n <SelectionOverlay />\n <BusHandles />\n <WireHandles />\n <TerminalLayer />\n <WirePreview />\n <BusbarPreview />\n <PlaceGhost />\n <MarqueeOverlay />\n </g>\n </svg>\n </div>\n );\n}\n","/**\n * Fit-to-content viewport reset, shared by the explicit \"fit\" button in\n * ViewToolbar and the automatic reset that fires on first mount / after\n * loading a file.\n *\n * Element bboxes come from the live DOM (`data-element-id` nodes), so the\n * canvas must already have rendered the diagram. `fitToContentSoon` defers\n * via rAF until that's true (typical use: store update → next frame fit).\n */\n\nimport { getViewportApi } from './viewport-bus';\n\nconst FIT_PADDING_PX = 60;\nconst MIN_SCALE = 0.1;\nconst MAX_SCALE = 8;\nconst READY_RETRY_FRAMES = 8;\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n\nfunction getCanvasRoot(): HTMLElement | null {\n return document.querySelector('.ole-canvas-root');\n}\n\n/**\n * Fit all rendered elements to the viewport with padding. Falls back to a\n * centered 100% reset when the canvas is empty. Returns false if the\n * viewport / canvas isn't ready yet.\n */\nexport function fitToContent(): boolean {\n const api = getViewportApi();\n const root = getCanvasRoot();\n if (!api || !root) return false;\n const rect = root.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return false;\n const nodes = root.querySelectorAll('[data-element-id]');\n if (nodes.length === 0) {\n api.setViewport({ tx: rect.width / 2, ty: rect.height / 2, scale: 1 });\n return true;\n }\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const n of nodes) {\n const r = (n as Element).getBoundingClientRect();\n if (r.width === 0 && r.height === 0) continue;\n if (r.left < minX) minX = r.left;\n if (r.top < minY) minY = r.top;\n if (r.right > maxX) maxX = r.right;\n if (r.bottom > maxY) maxY = r.bottom;\n }\n if (minX === Infinity) return false;\n const [ax, ay] = api.screenToSvg(minX, minY);\n const [bx, by] = api.screenToSvg(maxX, maxY);\n const contentW = Math.max(bx - ax, 1);\n const contentH = Math.max(by - ay, 1);\n const targetScale = clamp(\n Math.min(\n (rect.width - FIT_PADDING_PX * 2) / contentW,\n (rect.height - FIT_PADDING_PX * 2) / contentH,\n ),\n MIN_SCALE,\n MAX_SCALE,\n );\n const cx = (ax + bx) / 2;\n const cy = (ay + by) / 2;\n api.setViewport({\n tx: rect.width / 2 - targetScale * cx,\n ty: rect.height / 2 - targetScale * cy,\n scale: targetScale,\n });\n return true;\n}\n\n/**\n * Run `fitToContent` after the next paint, retrying for a few frames in case\n * the canvas hasn't mounted yet (initial mount race) or the diagram has\n * just been swapped and the new DOM nodes aren't yet attached.\n */\nexport function fitToContentSoon(): void {\n let frames = READY_RETRY_FRAMES;\n const tick = () => {\n if (fitToContent()) return;\n if (--frames > 0) requestAnimationFrame(tick);\n };\n requestAnimationFrame(tick);\n}\n","/**\n * Floating name tag that follows the hovered element on the canvas. Reads\n * the hover signal published by `useHoverHighlight` and locates the\n * element's `<g>` via the DOM (so it tracks pan, zoom, and live drags\n * without re-rendering React). Shows `name (kind)` or just `id` for\n * unnamed elements; portals to body so it isn't clipped.\n */\n\nimport { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { libraryById } from '../element-library';\nimport { useEditorStore } from '../store';\nimport type { ElementId } from '../model';\nimport { getHoverElement, subscribeHoverElement } from './hover-bus';\n\ninterface Anchor {\n top: number;\n left: number;\n}\n\nconst GAP_PX = 10;\nconst SHOW_DELAY_MS = 100;\n\n// Coarse-pointer / no-hover devices (touch) get no hover tooltip — there's\n// no equivalent gesture for \"hover an element to see its name\" on touch.\nfunction isCoarsePointer(): boolean {\n if (typeof window === 'undefined' || !window.matchMedia) return false;\n return window.matchMedia('(hover: none), (pointer: coarse)').matches;\n}\n\nexport function ElementHoverLabel() {\n const [hoverId, setHoverId] = useState<ElementId | null>(getHoverElement());\n const [shown, setShown] = useState(false);\n const [anchor, setAnchor] = useState<Anchor | null>(null);\n const labelRef = useRef<HTMLDivElement>(null);\n const showTimer = useRef<number | undefined>(undefined);\n const [coarse] = useState(isCoarsePointer);\n\n // The hover signal can flicker as the cursor crosses element edges. The\n // delayed-show smooths that out without making the tooltip feel laggy on\n // a steady hover.\n useEffect(() => {\n return subscribeHoverElement((id) => setHoverId(id));\n }, []);\n\n useEffect(() => {\n window.clearTimeout(showTimer.current);\n // Hide first whenever the target changes — keeps the tooltip from\n // teleporting between elements during fast cursor sweeps. The new label\n // re-appears only after the cursor settles on `hoverId` for SHOW_DELAY_MS.\n setShown(false);\n setAnchor(null);\n if (!hoverId) return;\n showTimer.current = window.setTimeout(() => setShown(true), SHOW_DELAY_MS);\n return () => window.clearTimeout(showTimer.current);\n }, [hoverId]);\n\n // Look up the element name + kind for the current hover.\n const elementName = useEditorStore((s) => {\n if (!hoverId) return null;\n return s.diagram.elements.find((e) => e.id === hoverId) ?? null;\n });\n\n // Reposition each frame while shown — handles pan/zoom/drag without React.\n useLayoutEffect(() => {\n if (!shown || !hoverId) return;\n let raf = 0;\n let lastTop = -1;\n let lastLeft = -1;\n const tick = () => {\n const node = document.querySelector(\n `[data-element-id=\"${cssEscape(hoverId)}\"]`,\n );\n const tip = labelRef.current;\n if (node && tip) {\n const r = node.getBoundingClientRect();\n // Default below so we don't collide with the contextual toolbar\n // (which prefers above the selection); flip up only when there's\n // no room below.\n let top = r.bottom + GAP_PX;\n if (top + tip.offsetHeight > window.innerHeight - 4) {\n top = r.top - tip.offsetHeight - GAP_PX;\n }\n let left = r.left + r.width / 2 - tip.offsetWidth / 2;\n left = Math.max(4, Math.min(left, window.innerWidth - tip.offsetWidth - 4));\n if (top !== lastTop || left !== lastLeft) {\n setAnchor({ top, left });\n lastTop = top;\n lastLeft = left;\n }\n }\n raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n }, [shown, hoverId]);\n\n if (coarse) return null;\n if (!shown || !hoverId || !elementName) return null;\n const lib = libraryById[elementName.kind];\n const display = elementName.name ?? elementName.id;\n const subtitle = lib?.name ?? elementName.kind;\n const showId = elementName.name && elementName.name !== elementName.id;\n\n if (typeof document === 'undefined') return null;\n return createPortal(\n <div\n ref={labelRef}\n role=\"tooltip\"\n className=\"ole-root ole-glass pointer-events-none fixed z-[100] flex items-center gap-1.5 rounded-md border border-border px-2 py-1 text-[11px] leading-snug shadow-md\"\n style={{\n top: anchor?.top ?? -9999,\n left: anchor?.left ?? -9999,\n opacity: anchor ? 1 : 0,\n transition: 'opacity 80ms ease-out',\n }}\n >\n <span className=\"font-medium text-foreground\">{display}</span>\n {showId && (\n <span className=\"font-mono text-[10px] text-muted-foreground\">\n {elementName.id}\n </span>\n )}\n <span className=\"text-muted-foreground/80\">·</span>\n <span className=\"text-muted-foreground\">{subtitle}</span>\n </div>,\n document.body,\n );\n}\n\nfunction cssEscape(s: string): string {\n return s.replace(/([\"\\\\])/g, '\\\\$1');\n}\n","/**\n * Editor tier provider — wraps the editor's chrome with a context value\n * derived from a width supplied by the parent. The parent is the only one\n * that holds the DOM ref, so we keep the ResizeObserver there and just\n * push the resolved tier down through context.\n *\n * Pure helpers / hook live in `./editor-tier`.\n */\n\nimport type { ReactNode } from 'react';\nimport { TierContext, tierForWidth } from './editor-tier';\n\nexport function EditorTierProvider({\n width,\n children,\n}: {\n width: number | null;\n children: ReactNode;\n}) {\n const tier = width == null ? 'full' : tierForWidth(width);\n return <TierContext.Provider value={tier}>{children}</TierContext.Provider>;\n}\n","// packages/react/compose-refs/src/compose-refs.tsx\nimport * as React from \"react\";\nfunction setRef(ref, value) {\n if (typeof ref === \"function\") {\n return ref(value);\n } else if (ref !== null && ref !== void 0) {\n ref.current = value;\n }\n}\nfunction composeRefs(...refs) {\n return (node) => {\n let hasCleanup = false;\n const cleanups = refs.map((ref) => {\n const cleanup = setRef(ref, node);\n if (!hasCleanup && typeof cleanup == \"function\") {\n hasCleanup = true;\n }\n return cleanup;\n });\n if (hasCleanup) {\n return () => {\n for (let i = 0; i < cleanups.length; i++) {\n const cleanup = cleanups[i];\n if (typeof cleanup == \"function\") {\n cleanup();\n } else {\n setRef(refs[i], null);\n }\n }\n };\n }\n };\n}\nfunction useComposedRefs(...refs) {\n return React.useCallback(composeRefs(...refs), refs);\n}\nexport {\n composeRefs,\n useComposedRefs\n};\n//# sourceMappingURL=index.mjs.map\n","// src/slot.tsx\nimport * as React from \"react\";\nimport { composeRefs } from \"@radix-ui/react-compose-refs\";\nimport { Fragment as Fragment2, jsx } from \"react/jsx-runtime\";\nvar REACT_LAZY_TYPE = Symbol.for(\"react.lazy\");\nvar use = React[\" use \".trim().toString()];\nfunction isPromiseLike(value) {\n return typeof value === \"object\" && value !== null && \"then\" in value;\n}\nfunction isLazyComponent(element) {\n return element != null && typeof element === \"object\" && \"$$typeof\" in element && element.$$typeof === REACT_LAZY_TYPE && \"_payload\" in element && isPromiseLike(element._payload);\n}\n// @__NO_SIDE_EFFECTS__\nfunction createSlot(ownerName) {\n const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);\n const Slot2 = React.forwardRef((props, forwardedRef) => {\n let { children, ...slotProps } = props;\n if (isLazyComponent(children) && typeof use === \"function\") {\n children = use(children._payload);\n }\n const childrenArray = React.Children.toArray(children);\n const slottable = childrenArray.find(isSlottable);\n if (slottable) {\n const newElement = slottable.props.children;\n const newChildren = childrenArray.map((child) => {\n if (child === slottable) {\n if (React.Children.count(newElement) > 1) return React.Children.only(null);\n return React.isValidElement(newElement) ? newElement.props.children : null;\n } else {\n return child;\n }\n });\n return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React.isValidElement(newElement) ? React.cloneElement(newElement, void 0, newChildren) : null });\n }\n return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });\n });\n Slot2.displayName = `${ownerName}.Slot`;\n return Slot2;\n}\nvar Slot = /* @__PURE__ */ createSlot(\"Slot\");\n// @__NO_SIDE_EFFECTS__\nfunction createSlotClone(ownerName) {\n const SlotClone = React.forwardRef((props, forwardedRef) => {\n let { children, ...slotProps } = props;\n if (isLazyComponent(children) && typeof use === \"function\") {\n children = use(children._payload);\n }\n if (React.isValidElement(children)) {\n const childrenRef = getElementRef(children);\n const props2 = mergeProps(slotProps, children.props);\n if (children.type !== React.Fragment) {\n props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;\n }\n return React.cloneElement(children, props2);\n }\n return React.Children.count(children) > 1 ? React.Children.only(null) : null;\n });\n SlotClone.displayName = `${ownerName}.SlotClone`;\n return SlotClone;\n}\nvar SLOTTABLE_IDENTIFIER = Symbol(\"radix.slottable\");\n// @__NO_SIDE_EFFECTS__\nfunction createSlottable(ownerName) {\n const Slottable2 = ({ children }) => {\n return /* @__PURE__ */ jsx(Fragment2, { children });\n };\n Slottable2.displayName = `${ownerName}.Slottable`;\n Slottable2.__radixId = SLOTTABLE_IDENTIFIER;\n return Slottable2;\n}\nvar Slottable = /* @__PURE__ */ createSlottable(\"Slottable\");\nfunction isSlottable(child) {\n return React.isValidElement(child) && typeof child.type === \"function\" && \"__radixId\" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;\n}\nfunction mergeProps(slotProps, childProps) {\n const overrideProps = { ...childProps };\n for (const propName in childProps) {\n const slotPropValue = slotProps[propName];\n const childPropValue = childProps[propName];\n const isHandler = /^on[A-Z]/.test(propName);\n if (isHandler) {\n if (slotPropValue && childPropValue) {\n overrideProps[propName] = (...args) => {\n const result = childPropValue(...args);\n slotPropValue(...args);\n return result;\n };\n } else if (slotPropValue) {\n overrideProps[propName] = slotPropValue;\n }\n } else if (propName === \"style\") {\n overrideProps[propName] = { ...slotPropValue, ...childPropValue };\n } else if (propName === \"className\") {\n overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(\" \");\n }\n }\n return { ...slotProps, ...overrideProps };\n}\nfunction getElementRef(element) {\n let getter = Object.getOwnPropertyDescriptor(element.props, \"ref\")?.get;\n let mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.ref;\n }\n getter = Object.getOwnPropertyDescriptor(element, \"ref\")?.get;\n mayWarn = getter && \"isReactWarning\" in getter && getter.isReactWarning;\n if (mayWarn) {\n return element.props.ref;\n }\n return element.props.ref || element.ref;\n}\nexport {\n Slot as Root,\n Slot,\n Slottable,\n createSlot,\n createSlottable\n};\n//# sourceMappingURL=index.mjs.map\n","/**\n * Copyright 2022 Joe Bell. All rights reserved.\n *\n * This file is licensed to you under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with the\n * License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n * WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations under\n * the License.\n */ import { clsx } from \"clsx\";\nconst falsyToString = (value)=>typeof value === \"boolean\" ? `${value}` : value === 0 ? \"0\" : value;\nexport const cx = clsx;\nexport const cva = (base, config)=>(props)=>{\n var _config_compoundVariants;\n if ((config === null || config === void 0 ? void 0 : config.variants) == null) return cx(base, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);\n const { variants, defaultVariants } = config;\n const getVariantClassNames = Object.keys(variants).map((variant)=>{\n const variantProp = props === null || props === void 0 ? void 0 : props[variant];\n const defaultVariantProp = defaultVariants === null || defaultVariants === void 0 ? void 0 : defaultVariants[variant];\n if (variantProp === null) return null;\n const variantKey = falsyToString(variantProp) || falsyToString(defaultVariantProp);\n return variants[variant][variantKey];\n });\n const propsWithoutUndefined = props && Object.entries(props).reduce((acc, param)=>{\n let [key, value] = param;\n if (value === undefined) {\n return acc;\n }\n acc[key] = value;\n return acc;\n }, {});\n const getCompoundVariantClassNames = config === null || config === void 0 ? void 0 : (_config_compoundVariants = config.compoundVariants) === null || _config_compoundVariants === void 0 ? void 0 : _config_compoundVariants.reduce((acc, param)=>{\n let { class: cvClass, className: cvClassName, ...compoundVariantOptions } = param;\n return Object.entries(compoundVariantOptions).every((param)=>{\n let [key, value] = param;\n return Array.isArray(value) ? value.includes({\n ...defaultVariants,\n ...propsWithoutUndefined\n }[key]) : ({\n ...defaultVariants,\n ...propsWithoutUndefined\n })[key] === value;\n }) ? [\n ...acc,\n cvClass,\n cvClassName\n ] : acc;\n }, []);\n return cx(base, getVariantClassNames, getCompoundVariantClassNames, props === null || props === void 0 ? void 0 : props.class, props === null || props === void 0 ? void 0 : props.className);\n };\n\n","import * as React from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '../../lib/utils';\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground shadow hover:bg-primary/90',\n destructive:\n 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',\n outline:\n 'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',\n secondary:\n 'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = 'Button';\n\nexport { buttonVariants };\n","/**\n * Lightweight tooltip — no Radix dependency. Shows content after a short\n * hover delay, portals to body so it isn't clipped by the floating panel,\n * and auto-flips above/below based on viewport space.\n *\n * Usage:\n * <Tooltip content=\"Hide grid (G)\">\n * <Button>...</Button>\n * </Tooltip>\n *\n * The trigger MUST be a single React element accepting a ref; we attach\n * pointer/focus listeners on it without prop-drilling.\n */\n\nimport {\n cloneElement,\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\nconst SHOW_DELAY_MS = 350;\n\ninterface Anchor {\n top: number;\n left: number;\n side: 'top' | 'bottom';\n}\n\nexport interface TooltipProps {\n content: ReactNode;\n children: ReactElement<{\n ref?: React.Ref<HTMLElement>;\n onPointerEnter?: (e: React.PointerEvent) => void;\n onPointerLeave?: (e: React.PointerEvent) => void;\n onFocus?: (e: React.FocusEvent) => void;\n onBlur?: (e: React.FocusEvent) => void;\n 'aria-describedby'?: string;\n }>;\n /** Force-disable (e.g. when the trigger is disabled). */\n disabled?: boolean;\n /** Override the default 350ms hover delay. */\n delayMs?: number;\n}\n\nexport function Tooltip({\n content,\n children,\n disabled,\n delayMs = SHOW_DELAY_MS,\n}: TooltipProps) {\n const triggerRef = useRef<HTMLElement | null>(null);\n const tooltipRef = useRef<HTMLDivElement | null>(null);\n const [open, setOpen] = useState(false);\n const [anchor, setAnchor] = useState<Anchor | null>(null);\n const id = useId();\n const timer = useRef<number | undefined>(undefined);\n\n const scheduleShow = () => {\n if (disabled) return;\n window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => setOpen(true), delayMs);\n };\n\n const cancelShow = () => {\n window.clearTimeout(timer.current);\n setOpen(false);\n };\n\n // Recompute anchor position when open changes or content changes.\n useLayoutEffect(() => {\n if (!open || !triggerRef.current || !tooltipRef.current) return;\n const t = triggerRef.current.getBoundingClientRect();\n const tip = tooltipRef.current.getBoundingClientRect();\n const margin = 8;\n let side: 'top' | 'bottom' = 'top';\n let top = t.top - tip.height - margin;\n if (top < 4) {\n side = 'bottom';\n top = t.bottom + margin;\n }\n let left = t.left + t.width / 2 - tip.width / 2;\n left = Math.max(4, Math.min(left, window.innerWidth - tip.width - 4));\n setAnchor({ top, left, side });\n }, [open, content]);\n\n // Cleanup on unmount.\n useEffect(() => () => window.clearTimeout(timer.current), []);\n\n // Hide on Escape and on scroll/resize.\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n const onScroll = () => setOpen(false);\n window.addEventListener('keydown', onKey);\n window.addEventListener('scroll', onScroll, true);\n window.addEventListener('resize', onScroll);\n return () => {\n window.removeEventListener('keydown', onKey);\n window.removeEventListener('scroll', onScroll, true);\n window.removeEventListener('resize', onScroll);\n };\n }, [open]);\n\n // We attach our handlers on top of any existing ones on the trigger.\n const child = children;\n const childProps = child.props;\n const wrappedTrigger = cloneElement(child, {\n ref: (node: HTMLElement | null) => {\n triggerRef.current = node;\n const orig = (child as { ref?: React.Ref<HTMLElement> }).ref;\n if (typeof orig === 'function') orig(node);\n else if (orig && typeof orig === 'object') {\n (orig as React.MutableRefObject<HTMLElement | null>).current = node;\n }\n },\n onPointerEnter: (e: React.PointerEvent) => {\n childProps.onPointerEnter?.(e);\n scheduleShow();\n },\n onPointerLeave: (e: React.PointerEvent) => {\n childProps.onPointerLeave?.(e);\n cancelShow();\n },\n onFocus: (e: React.FocusEvent) => {\n childProps.onFocus?.(e);\n scheduleShow();\n },\n onBlur: (e: React.FocusEvent) => {\n childProps.onBlur?.(e);\n cancelShow();\n },\n 'aria-describedby': open ? id : childProps['aria-describedby'],\n });\n\n return (\n <>\n {wrappedTrigger}\n {open &&\n typeof document !== 'undefined' &&\n createPortal(\n <div\n ref={tooltipRef}\n id={id}\n role=\"tooltip\"\n data-side={anchor?.side ?? 'top'}\n className=\"ole-root ole-glass pointer-events-none fixed z-[100] max-w-[280px] rounded-md border border-border px-2 py-1 text-[11px] leading-snug text-foreground shadow-md\"\n style={{\n top: anchor?.top ?? -9999,\n left: anchor?.left ?? -9999,\n opacity: anchor ? 1 : 0,\n transition: 'opacity 80ms ease-out',\n }}\n >\n {content}\n </div>,\n document.body,\n )}\n </>\n );\n}\n","/**\n * Canva-style contextual floating toolbar that follows the selected element\n * (or selection bbox) — and the selected wire/node, since v0.4. Renders the\n * relevant primary actions (rotate / mirror / delete for elements, delete\n * for nodes) right next to the work, so the eye doesn't need to travel.\n *\n * Position is updated each frame via rAF + DOM transform — no React state in\n * the hot loop. The toolbar reads from the canvas DOM each frame which means\n * it tracks pan, zoom, and element/wire moves \"for free\".\n */\n\nimport { useEffect, useRef } from 'react';\nimport { FlipHorizontal, RotateCw, Spline, Trash2 } from 'lucide-react';\nimport { Button } from './ui/button';\nimport { Tooltip } from './ui/tooltip';\nimport { useT } from '../i18n';\nimport { useEditorStore } from '../store';\n\nconst GAP_PX = 12;\nconst TOP_FLIP_THRESHOLD_PX = 56;\n\nexport function ContextualToolbar() {\n const t = useT();\n const selection = useEditorStore((s) => s.selection);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const selectedWire = useEditorStore((s) => s.selectedWire);\n const activeTool = useEditorStore((s) => s.activeTool);\n const rotate = useEditorStore((s) => s.rotateSelection);\n const mirror = useEditorStore((s) => s.mirrorSelection);\n const del = useEditorStore((s) => s.deleteSelection);\n const delNode = useEditorStore((s) => s.deleteSelectedNode);\n const delWire = useEditorStore((s) => s.deleteSelectedWire);\n const resetWirePath = useEditorStore((s) => s.resetWirePath);\n const wireRenders = useEditorStore((s) => s.internal.wireRenders);\n const wireIsManual =\n selectedWire != null && wireRenders.get(selectedWire)?.userEdited === true;\n\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n\n const isElementMode = selection.length > 0;\n const isWireMode = !isElementMode && selectedWire != null;\n const isNodeMode = !isElementMode && !isWireMode && selectedNode != null;\n const visible =\n (isElementMode || isWireMode || isNodeMode) &&\n (activeTool === 'select' || activeTool === 'pan');\n if (!visible) {\n el.style.display = 'none';\n return;\n }\n el.style.display = 'flex';\n\n let raf = 0;\n let lastTransform = '';\n const tick = () => {\n let left = Infinity;\n let right = -Infinity;\n let top = Infinity;\n let bottom = -Infinity;\n let any = false;\n const accept = (r: DOMRect) => {\n if (r.width === 0 && r.height === 0) return;\n if (r.left < left) left = r.left;\n if (r.right > right) right = r.right;\n if (r.top < top) top = r.top;\n if (r.bottom > bottom) bottom = r.bottom;\n any = true;\n };\n if (isElementMode) {\n for (const id of selection) {\n const node = document.querySelector(\n `[data-element-id=\"${CSS.escape(id)}\"]`,\n );\n if (node) accept(node.getBoundingClientRect());\n }\n } else if (isWireMode && selectedWire) {\n const w = document.querySelector(\n `polyline.ole-wire[data-wire-id=\"${CSS.escape(selectedWire)}\"]`,\n );\n if (w) accept((w as Element).getBoundingClientRect());\n } else if (isNodeMode && selectedNode) {\n const wires = document.querySelectorAll(\n `polyline.ole-wire[data-node-id=\"${CSS.escape(selectedNode)}\"]`,\n );\n for (const w of wires) accept((w as Element).getBoundingClientRect());\n }\n if (any) {\n const cx = (left + right) / 2;\n let ty = top - GAP_PX;\n let translateY = '-100%';\n // Flip below if there's no room above.\n if (ty < TOP_FLIP_THRESHOLD_PX) {\n ty = bottom + GAP_PX;\n translateY = '0%';\n }\n const transform = `translate3d(${cx}px, ${ty}px, 0) translate(-50%, ${translateY})`;\n if (transform !== lastTransform) {\n el.style.transform = transform;\n lastTransform = transform;\n }\n }\n raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(raf);\n }, [selection, selectedNode, selectedWire, activeTool]);\n\n const isWireMode = selection.length === 0 && selectedWire != null;\n const isNodeMode = selection.length === 0 && !isWireMode && selectedNode != null;\n const hideTransform = isNodeMode || isWireMode;\n\n return (\n <div\n ref={ref}\n role=\"toolbar\"\n aria-label={\n isWireMode\n ? t('ctx.ariaWire')\n : isNodeMode\n ? t('ctx.ariaNode')\n : t('ctx.ariaElement')\n }\n className=\"ole-glass pointer-events-auto fixed left-0 top-0 z-30 hidden items-center gap-0.5 rounded-2xl border border-border p-1 shadow-md\"\n >\n {isWireMode && wireIsManual && selectedWire && (\n <>\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">{t('ctx.resetWirePath')}</span>\n </div>\n <div className=\"text-muted-foreground\">\n {t('ctx.resetWirePathHint')}\n </div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n onClick={() => resetWirePath(selectedWire)}\n aria-label={t('ctx.resetWirePath')}\n >\n <Spline />\n </Button>\n </Tooltip>\n <div aria-hidden className=\"mx-0.5 h-4 w-px bg-border\" />\n </>\n )}\n {!hideTransform && (\n <>\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">{t('ctx.rotate')}</span>\n <span className=\"ml-1.5 text-muted-foreground\">R</span>\n </div>\n <div className=\"text-muted-foreground\">{t('ctx.rotateHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n onClick={() => rotate(90)}\n aria-label={t('ctx.rotate')}\n >\n <RotateCw />\n </Button>\n </Tooltip>\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">{t('ctx.mirror')}</span>\n <span className=\"ml-1.5 text-muted-foreground\">M</span>\n </div>\n <div className=\"text-muted-foreground\">{t('ctx.mirrorHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7\"\n onClick={() => mirror()}\n aria-label={t('ctx.mirrorTitle')}\n >\n <FlipHorizontal />\n </Button>\n </Tooltip>\n <div aria-hidden className=\"mx-0.5 h-4 w-px bg-border\" />\n </>\n )}\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">{t('ctx.delete')}</span>\n <span className=\"ml-1.5 text-muted-foreground\">Del</span>\n </div>\n <div className=\"text-muted-foreground\">\n {isWireMode\n ? t('ctx.deleteHintWire')\n : isNodeMode\n ? t('ctx.deleteHintNode')\n : t('ctx.deleteHintElement')}\n </div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7 text-destructive hover:text-destructive\"\n onClick={() =>\n isWireMode ? delWire() : isNodeMode ? delNode() : del()\n }\n aria-label={t('ctx.delete')}\n >\n <Trash2 />\n </Button>\n </Tooltip>\n </div>\n );\n}\n","/**\n * Anchored popover that opens upward — used by the bottom-anchored\n * FloatingToolbar / ViewToolbar where a downward-opening menu would clip\n * below the viewport. Closes on outside click and Esc.\n */\n\nimport { useEffect, useRef, type ReactNode } from 'react';\n\nexport function UpwardPopover({\n open,\n onOpenChange,\n trigger,\n children,\n}: {\n open: boolean;\n onOpenChange: (next: boolean) => void;\n trigger: ReactNode;\n children: ReactNode;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) onOpenChange(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onOpenChange(false);\n };\n window.addEventListener('mousedown', onClick);\n window.addEventListener('keydown', onKey);\n return () => {\n window.removeEventListener('mousedown', onClick);\n window.removeEventListener('keydown', onKey);\n };\n }, [open, onOpenChange]);\n return (\n <div ref={ref} className=\"relative\">\n {trigger}\n {open && (\n <div\n role=\"menu\"\n className=\"ole-glass absolute bottom-full right-0 mb-1.5 min-w-52 rounded-md border border-border p-1 shadow-md\"\n >\n {children}\n </div>\n )}\n </div>\n );\n}\n","/**\n * Tiny Zustand store for cross-component panel open/closed state.\n *\n * The outline panel toggle lives at bottom-left and persists across reloads.\n * The library popover is no longer tracked here — it follows the editor's\n * active tool (`activeTool === 'place'`) so the toolbar button behaves like\n * any other mutually-exclusive tool.\n */\n\nimport { create } from 'zustand';\n\nconst STORAGE_KEY = 'ole-panel-open';\n\ninterface Persisted {\n outline: boolean;\n}\n\ninterface PanelState {\n outlineOpen: boolean;\n setOutlineOpen: (open: boolean) => void;\n toggleOutline: () => void;\n}\n\nfunction readInitial(): Pick<PanelState, 'outlineOpen'> {\n if (typeof window === 'undefined') return { outlineOpen: false };\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return { outlineOpen: false };\n const obj = JSON.parse(raw) as unknown;\n if (typeof obj !== 'object' || obj === null) return { outlineOpen: false };\n const o = obj as Record<string, unknown>;\n return { outlineOpen: o.outline === true };\n } catch {\n return { outlineOpen: false };\n }\n}\n\nfunction persist(s: { outlineOpen: boolean }): void {\n try {\n const data: Persisted = { outline: s.outlineOpen };\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(data));\n } catch {\n // ignore quota / disabled storage\n }\n}\n\nexport const usePanels = create<PanelState>((set, get) => ({\n ...readInitial(),\n setOutlineOpen: (outlineOpen) => {\n set({ outlineOpen });\n persist(get());\n },\n toggleOutline: () => {\n set((s) => ({ outlineOpen: !s.outlineOpen }));\n persist(get());\n },\n}));\n","import { useEffect, useState } from 'react';\nimport {\n Grid2x2,\n Maximize2,\n Minus,\n MoreHorizontal,\n Plus,\n Type,\n} from 'lucide-react';\nimport { Button } from './ui/button';\nimport { Tooltip } from './ui/tooltip';\nimport { UpwardPopover } from './ui/upward-popover';\nimport {\n fitToContent,\n getViewportApi,\n getScale,\n subscribeScale,\n} from '../canvas';\nimport { atLeast, useEditorTier, type Tier } from '../hooks/editor-tier';\nimport { useT } from '../i18n';\nimport { cn } from '../lib/utils';\nimport { useEditorStore } from '../store';\nimport type { LabelMode } from '../model';\n\nconst ZOOM_STEPS = [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 3, 4, 6, 8] as const;\nconst MIN_SCALE = 0.1;\nconst MAX_SCALE = 8;\n\nconst GRID_STORAGE_KEY = 'ole-grid';\n\nfunction readGrid(): boolean {\n try {\n const v = window.localStorage.getItem(GRID_STORAGE_KEY);\n return v == null ? true : v === '1';\n } catch {\n return true;\n }\n}\nfunction writeGrid(v: boolean): void {\n try {\n window.localStorage.setItem(GRID_STORAGE_KEY, v ? '1' : '0');\n } catch {\n // ignore\n }\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n\nfunction getCanvasRoot(): HTMLElement | null {\n return document.querySelector('.ole-canvas-root');\n}\n\n/** Apply a target scale, anchored at the canvas viewport center. */\nfunction zoomTo(target: number): void {\n const api = getViewportApi();\n const root = getCanvasRoot();\n if (!api || !root) return;\n const rect = root.getBoundingClientRect();\n const cx = rect.width / 2;\n const cy = rect.height / 2;\n const vp = api.getViewport();\n const next = clamp(target, MIN_SCALE, MAX_SCALE);\n const ratio = next / vp.scale;\n api.setViewport({\n tx: cx - (cx - vp.tx) * ratio,\n ty: cy - (cy - vp.ty) * ratio,\n scale: next,\n });\n}\n\nfunction zoomIn(): void {\n const api = getViewportApi();\n if (!api) return;\n const cur = api.getViewport().scale;\n const next = ZOOM_STEPS.find((z) => z > cur + 1e-6) ?? MAX_SCALE;\n zoomTo(next);\n}\n\nfunction zoomOut(): void {\n const api = getViewportApi();\n if (!api) return;\n const cur = api.getViewport().scale;\n let next = MIN_SCALE;\n for (let i = ZOOM_STEPS.length - 1; i >= 0; i--) {\n if (ZOOM_STEPS[i] < cur - 1e-6) {\n next = ZOOM_STEPS[i];\n break;\n }\n }\n zoomTo(next);\n}\n\nconst LABEL_CYCLE: Record<LabelMode, LabelMode> = {\n off: 'id',\n id: 'all',\n all: 'off',\n};\n\nfunction cycleLabelMode(): void {\n const store = useEditorStore.getState();\n const cur = store.diagram.meta?.labelMode ?? 'all';\n const next = LABEL_CYCLE[cur];\n store.dispatch((d) => {\n const meta = { ...(d.meta ?? {}), labelMode: next };\n return { ...d, meta };\n });\n}\n\n/**\n * Grid state + side effects. Lives wherever the view menu is mounted (the\n * standalone ViewToolbar at wider widths, or the embedded ViewMenuButton at\n * dense+). Owns the keyboard `G` shortcut so it works regardless of whether\n * the popover happens to be open.\n */\nfunction useGridState(): [boolean, React.Dispatch<React.SetStateAction<boolean>>] {\n const [grid, setGrid] = useState<boolean>(() => readGrid());\n\n useEffect(() => {\n const root = getCanvasRoot();\n root?.classList.toggle('hide-grid', !grid);\n writeGrid(grid);\n }, [grid]);\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.metaKey || e.ctrlKey || e.altKey) return;\n if (e.key !== 'g' && e.key !== 'G') return;\n const target = e.target as HTMLElement | null;\n if (\n target &&\n (target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.isContentEditable)\n ) {\n return;\n }\n e.preventDefault();\n setGrid((v) => !v);\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n return [grid, setGrid];\n}\n\nfunction ZoomOutBtn() {\n const t = useT();\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.zoomOut')}</div>\n <div className=\"text-muted-foreground\">{t('view.zoomOutHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={zoomOut}\n aria-label={t('view.zoomOut')}\n >\n <Minus />\n </Button>\n </Tooltip>\n );\n}\n\nfunction ZoomInBtn() {\n const t = useT();\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.zoomIn')}</div>\n <div className=\"text-muted-foreground\">{t('view.zoomInHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={zoomIn}\n aria-label={t('view.zoomIn')}\n >\n <Plus />\n </Button>\n </Tooltip>\n );\n}\n\nfunction ZoomDisplayBtn() {\n const t = useT();\n const [scale, setScale] = useState(getScale);\n useEffect(() => subscribeScale(setScale), []);\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.reset')}</div>\n <div className=\"text-muted-foreground\">\n {t('view.current', { z: Math.round(scale * 100) })}\n </div>\n </div>\n }\n >\n <button\n type=\"button\"\n onClick={() => zoomTo(1)}\n className=\"min-w-12 rounded-md px-2 py-1 text-center text-xs tabular-nums text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n aria-label={t('view.reset')}\n >\n {Math.round(scale * 100)}%\n </button>\n </Tooltip>\n );\n}\n\nfunction FitBtn() {\n const t = useT();\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.fit')}</div>\n <div className=\"text-muted-foreground\">{t('view.fitHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={fitToContent}\n aria-label={t('view.fit')}\n >\n <Maximize2 />\n </Button>\n </Tooltip>\n );\n}\n\nfunction GridBtn({\n grid,\n setGrid,\n}: {\n grid: boolean;\n setGrid: React.Dispatch<React.SetStateAction<boolean>>;\n}) {\n const t = useT();\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">\n {grid ? t('view.gridHide') : t('view.gridShow')}\n </span>\n <span className=\"ml-1.5 text-muted-foreground\">\n {t('view.gridHotkey')}\n </span>\n </div>\n <div className=\"text-muted-foreground\">\n {grid ? t('view.gridHideHint') : t('view.gridShowHint')}\n </div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setGrid((v) => !v)}\n aria-label={grid ? t('view.gridHideAria') : t('view.gridShowAria')}\n aria-pressed={grid}\n className={cn(!grid && 'text-muted-foreground/60')}\n >\n <Grid2x2 />\n </Button>\n </Tooltip>\n );\n}\n\nfunction LabelBtn() {\n const t = useT();\n const labelMode: LabelMode = useEditorStore(\n (s) => s.diagram.meta?.labelMode ?? 'all',\n );\n return (\n <Tooltip\n content={\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">\n {labelMode === 'off'\n ? t('view.labelOff')\n : labelMode === 'id'\n ? t('view.labelId')\n : t('view.labelAll')}\n </div>\n <div className=\"text-muted-foreground\">{t('view.labelHint')}</div>\n </div>\n }\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={cycleLabelMode}\n aria-label={t('view.label')}\n aria-pressed={labelMode !== 'off'}\n className={cn(labelMode === 'off' && 'text-muted-foreground/60')}\n >\n <Type />\n </Button>\n </Tooltip>\n );\n}\n\n/**\n * View menu collapsed into a single popover trigger. Designed to be embedded\n * inline inside another bar (no outer positioning). Used by FloatingToolbar\n * at `dense` and below, where it stands in for the standalone ViewToolbar.\n *\n * `stacked` switches the trigger to the unified-bar's tab-bar look (icon on\n * top, \"视图\" label below) so it matches the other phone-class buttons.\n */\nexport function ViewMenuButton({ stacked }: { stacked?: boolean } = {}) {\n const t = useT();\n const [menuOpen, setMenuOpen] = useState(false);\n const [grid, setGrid] = useGridState();\n const tipContent = (\n <div className=\"space-y-0.5\">\n <div className=\"font-medium\">{t('view.menu')}</div>\n <div className=\"text-muted-foreground\">{t('view.menuHint')}</div>\n </div>\n );\n const triggerBtn = stacked ? (\n <Tooltip content={tipContent}>\n <button\n type=\"button\"\n onClick={() => setMenuOpen((v) => !v)}\n aria-label={t('view.menu')}\n aria-pressed={menuOpen}\n className={cn(\n 'flex h-12 w-12 flex-col items-center justify-center gap-0.5 rounded-md text-[10px] font-medium leading-tight transition-colors',\n menuOpen\n ? 'bg-primary text-primary-foreground'\n : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n )}\n >\n <MoreHorizontal className=\"size-4\" />\n <span className=\"max-w-full truncate\">{t('view.menu')}</span>\n </button>\n </Tooltip>\n ) : (\n <Tooltip content={tipContent}>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setMenuOpen((v) => !v)}\n aria-label={t('view.menu')}\n aria-pressed={menuOpen}\n >\n <MoreHorizontal />\n </Button>\n </Tooltip>\n );\n return (\n <UpwardPopover\n open={menuOpen}\n onOpenChange={setMenuOpen}\n trigger={triggerBtn}\n >\n <div className=\"flex flex-col gap-0.5\">\n <ZoomDisplayBtn />\n <div className=\"flex items-center gap-0.5\">\n <ZoomOutBtn />\n <ZoomInBtn />\n </div>\n <div aria-hidden className=\"my-1 h-px bg-border\" />\n <div className=\"flex items-center gap-0.5\">\n <FitBtn />\n <GridBtn grid={grid} setGrid={setGrid} />\n <LabelBtn />\n </div>\n </div>\n </UpwardPopover>\n );\n}\n\n/**\n * Bottom-right view toolbar. Above `dense` (>520px) it renders an expanded\n * row with explicit zoom controls. At `dense` and below it returns null —\n * its content is rendered as an embedded ViewMenuButton inside the unified\n * FloatingToolbar bottom bar so the chrome stays on a single line.\n */\nexport function ViewToolbar() {\n const tier = useEditorTier();\n if (atLeast(tier, 'dense')) return null;\n return <ViewToolbarExpanded tier={tier} />;\n}\n\nfunction ViewToolbarExpanded({ tier }: { tier: Tier }) {\n // Hide the zoom-% pill from `tight` (≥720 < 900) onward — that's where the\n // centered FloatingToolbar starts colliding with this right-anchored bar.\n const hidePercentPill = atLeast(tier, 'tight');\n const [grid, setGrid] = useGridState();\n\n return (\n <div\n className=\"absolute z-20\"\n style={{\n bottom: 'calc(0.75rem + var(--ole-bottom-inset, 0px))',\n right: 'calc(0.75rem + env(safe-area-inset-right, 0px))',\n }}\n >\n <div className=\"ole-glass flex items-center gap-0.5 rounded-2xl border border-border p-1.5 shadow-sm\">\n <ZoomOutBtn />\n {!hidePercentPill && <ZoomDisplayBtn />}\n <ZoomInBtn />\n <div aria-hidden className=\"mx-1 h-4 w-px bg-border\" />\n <FitBtn />\n <GridBtn grid={grid} setGrid={setGrid} />\n <LabelBtn />\n </div>\n </div>\n );\n}\n","import { Fragment, useState } from 'react';\nimport {\n Cable,\n Clipboard,\n Copy,\n Hand,\n LayoutGrid,\n ListTree,\n Minus,\n MoreHorizontal,\n MousePointer2,\n Redo2,\n Scissors,\n Shapes,\n Type,\n Undo2,\n Wand2,\n} from 'lucide-react';\nimport { Tooltip } from './ui/tooltip';\nimport { UpwardPopover } from './ui/upward-popover';\nimport { atLeast, useEditorTier } from '../hooks/editor-tier';\nimport { usePanels } from '../hooks/use-panels';\nimport { useT, type LocaleKey } from '../i18n';\nimport { cn } from '../lib/utils';\nimport { useEditorStore, type ToolId } from '../store';\nimport { ViewMenuButton } from './ViewToolbar';\n\ninterface ToolDef {\n id: string;\n labelKey: LocaleKey;\n hotkey: string;\n descriptionKey: LocaleKey;\n icon: React.ComponentType<{ className?: string }>;\n /** Render a divider after this tool (visually groups the toolbar). */\n groupBreakAfter?: boolean;\n /** Tool action: switch active tool (with optional placeKind preset). */\n switchTo: ToolId;\n /**\n * `undefined` = keep current placeKind; `null` = clear; string = preset.\n */\n presetPlaceKind?: string | null;\n /** Icon-only render (label still goes to aria-label / tooltip). */\n iconOnly?: boolean;\n}\n\nconst TOOLS: ToolDef[] = [\n {\n id: 'select',\n labelKey: 'tool.select',\n hotkey: 'V',\n descriptionKey: 'tool.selectHint',\n icon: MousePointer2,\n switchTo: 'select',\n iconOnly: true,\n },\n {\n id: 'pan',\n labelKey: 'tool.pan',\n hotkey: 'H',\n descriptionKey: 'tool.panHint',\n icon: Hand,\n switchTo: 'pan',\n groupBreakAfter: true,\n iconOnly: true,\n },\n {\n id: 'busbar',\n labelKey: 'tool.bus',\n hotkey: 'B',\n descriptionKey: 'tool.busHint',\n icon: Minus,\n switchTo: 'busbar',\n },\n {\n id: 'place',\n labelKey: 'tool.place',\n hotkey: 'P',\n descriptionKey: 'tool.placeHint',\n icon: Shapes,\n switchTo: 'place',\n },\n {\n id: 'wire',\n labelKey: 'tool.wire',\n hotkey: 'W',\n descriptionKey: 'tool.wireHint',\n icon: Cable,\n switchTo: 'wire',\n },\n {\n id: 'text',\n labelKey: 'tool.text',\n hotkey: 'T',\n descriptionKey: 'tool.textHint',\n icon: Type,\n switchTo: 'text',\n iconOnly: true,\n },\n];\n\n/**\n * Short usage hint shown above the toolbar for whichever tool is active.\n * Keeps users oriented without forcing them to discover a tooltip — most\n * tools have a non-obvious gesture and the hint paid off in usability tests.\n */\nfunction ToolHint() {\n const t = useT();\n const active = useEditorStore((s) => s.activeTool);\n const placeKind = useEditorStore((s) => s.placeKind);\n const placeFrom = useEditorStore((s) => s.placeFromTerminal);\n const wireFrom = useEditorStore((s) => s.wireFromTerminal);\n const busbarStart = useEditorStore((s) => s.busbarDrawStart);\n const hasSelection = useEditorStore(\n (s) => s.selection.length > 0 || s.selectedNode != null,\n );\n\n let text: string | null = null;\n let cancelHint = false;\n switch (active) {\n case 'select':\n text = hasSelection\n ? t('mode.selectWithSel')\n : t('mode.selectEmpty');\n if (hasSelection) cancelHint = true;\n break;\n case 'pan':\n text = t('mode.pan');\n break;\n case 'wire':\n text = wireFrom ? t('mode.wireDragging') : t('mode.wireInit');\n cancelHint = true;\n break;\n case 'busbar':\n text = busbarStart ? t('mode.busDragging') : t('mode.busInit');\n cancelHint = true;\n break;\n case 'place':\n if (!placeKind) text = t('mode.placeNoKind');\n else if (placeFrom) text = t('mode.placeFromTerm');\n else text = t('mode.placeNormal');\n cancelHint = true;\n break;\n case 'text':\n text = t('mode.text');\n cancelHint = true;\n break;\n }\n if (!text) return null;\n // In select mode right-click opens the context menu rather than cancelling,\n // so only Esc clears the selection. In drawing tools right-click also cancels.\n const cancelText = active === 'select' ? t('mode.escSelect') : t('mode.escOther');\n return (\n <div className=\"ole-glass pointer-events-none flex items-center gap-2 rounded-full border border-border px-3 py-1 text-xs text-muted-foreground shadow-sm\">\n <span>{text}</span>\n {cancelHint && <span className=\"text-muted-foreground/70\">· {cancelText}</span>}\n </div>\n );\n}\n\nexport function FloatingToolbar() {\n const t = useT();\n const active = useEditorStore((s) => s.activeTool);\n const placeKind = useEditorStore((s) => s.placeKind);\n const setTool = useEditorStore((s) => s.setActiveTool);\n const past = useEditorStore((s) => s.past.length);\n const future = useEditorStore((s) => s.future.length);\n const undo = useEditorStore((s) => s.undo);\n const redo = useEditorStore((s) => s.redo);\n const tier = useEditorTier();\n // Drop labels from `tight` (≥720 < 900) so the centered main toolbar stops\n // colliding with the right-anchored ViewToolbar. The outline tab on the\n // left still has room for its label until `compact`.\n const forceIconOnly = atLeast(tier, 'tight');\n const showHint = !atLeast(tier, 'dense');\n // Phone-class layout (`dense` and below): the outline tab and the view\n // toolbar disappear and their entry points are embedded directly into this\n // pill as a tab-bar-style row, so the whole bottom chrome stays on a single\n // visual row. The [Undo/Redo/Layout] group also collapses into one overflow\n // button to keep the bar narrow. Select and text are dropped from the main\n // bar — Pan is the default on touch and absorbs single-tap selection (see\n // PanTool), and text annotation is rare enough on a phone to hide.\n const unifiedBar = atLeast(tier, 'dense');\n const visibleTools = unifiedBar\n ? TOOLS.filter((def) => def.id !== 'select' && def.id !== 'text')\n : TOOLS;\n\n const isToolActive = (def: ToolDef): boolean => active === def.switchTo;\n\n return (\n <div\n className=\"absolute left-1/2 z-20 flex -translate-x-1/2 flex-col items-center gap-1.5\"\n style={{ bottom: 'calc(0.75rem + var(--ole-bottom-inset, 0px))' }}\n >\n {showHint && <ToolHint />}\n <div\n className={cn(\n 'ole-glass flex flex-row items-center rounded-2xl border border-border shadow-sm',\n unifiedBar ? 'gap-0.5 p-1' : 'gap-0.5 p-1.5',\n )}\n >\n {unifiedBar && <OutlineToggleButton stacked />}\n {visibleTools.map((def) => {\n const Icon = def.icon;\n const isActive = isToolActive(def);\n const tip =\n def.id === 'place' && isActive && placeKind == null\n ? t('tool.placeNoKindTooltip')\n : t(def.descriptionKey);\n return (\n <Fragment key={def.id}>\n <ToolbarButton\n icon={Icon}\n label={t(def.labelKey)}\n hotkey={def.hotkey}\n active={isActive}\n iconOnly={!unifiedBar && (def.iconOnly || forceIconOnly)}\n stacked={unifiedBar}\n description={tip}\n onClick={() => {\n setTool(def.switchTo, {\n placeKind:\n def.presetPlaceKind !== undefined ? def.presetPlaceKind : undefined,\n });\n }}\n />\n {def.groupBreakAfter && !unifiedBar && (\n <div aria-hidden className=\"mx-1 h-5 w-px bg-border\" />\n )}\n </Fragment>\n );\n })}\n {!unifiedBar && (\n <div aria-hidden className=\"mx-1 h-5 w-px bg-border\" />\n )}\n {unifiedBar ? (\n <OverflowMenuButton stacked />\n ) : (\n <>\n <ToolbarButton\n icon={Undo2}\n label={t('tool.undo')}\n hotkey=\"⌘Z\"\n description={t('tool.undoHint')}\n iconOnly\n disabled={past === 0}\n onClick={undo}\n />\n <ToolbarButton\n icon={Redo2}\n label={t('tool.redo')}\n hotkey=\"⌘⇧Z\"\n description={t('tool.redoHint')}\n iconOnly\n disabled={future === 0}\n onClick={redo}\n />\n <div aria-hidden className=\"mx-1 h-5 w-px bg-border\" />\n <LayoutMenuButton iconOnly={forceIconOnly} />\n </>\n )}\n {unifiedBar && <ViewMenuButton stacked />}\n </div>\n </div>\n );\n}\n\n/**\n * Embedded outline-toggle entry point used by the unified bottom bar at\n * `dense` and below. Mirrors the floating LeftPanel tab's role (toggles the\n * outline panel), but renders inline inside the FloatingToolbar pill so the\n * bottom chrome stays on one row at phone widths.\n */\nfunction OutlineToggleButton({ stacked }: { stacked?: boolean }) {\n const t = useT();\n const open = usePanels((s) => s.outlineOpen);\n const toggle = usePanels((s) => s.toggleOutline);\n return (\n <ToolbarButton\n icon={ListTree}\n label={t('outline.title')}\n active={open}\n iconOnly\n stacked={stacked}\n onClick={toggle}\n />\n );\n}\n\n/**\n * Toolbar button: icon + label, with a small hotkey hint pinned to the\n * top-left corner. Active = filled (primary). Disabled = dimmed.\n *\n * `stacked` is the phone-class variant — icon on top, label underneath,\n * no hotkey badge (touch users don't have a keyboard). Used by the unified\n * bottom bar at `dense` and below to look like an iOS/Material tab bar.\n */\nfunction ToolbarButton({\n icon: Icon,\n label,\n hotkey,\n active,\n disabled,\n iconOnly,\n stacked,\n onClick,\n description,\n}: {\n icon: React.ComponentType<{ className?: string }>;\n label: string;\n hotkey?: string;\n active?: boolean;\n disabled?: boolean;\n iconOnly?: boolean;\n stacked?: boolean;\n onClick: () => void;\n description?: React.ReactNode;\n}) {\n const tipContent = (\n <div className=\"space-y-0.5\">\n <div>\n <span className=\"font-medium\">{label}</span>\n {hotkey && (\n <span className=\"ml-1.5 text-muted-foreground\">{hotkey}</span>\n )}\n </div>\n {description && <div className=\"text-muted-foreground\">{description}</div>}\n </div>\n );\n return (\n <Tooltip content={tipContent} disabled={disabled}>\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n aria-label={label}\n aria-pressed={active}\n className={cn(\n 'rounded-md font-medium transition-colors',\n stacked\n ? 'flex h-12 w-12 flex-col items-center justify-center gap-0.5 text-[10px] leading-tight'\n : 'flex h-9 items-center gap-1.5 text-xs',\n !stacked && (iconOnly ? 'w-9 justify-center' : 'px-2.5'),\n active\n ? 'bg-primary text-primary-foreground'\n : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n disabled && 'pointer-events-none opacity-40',\n )}\n >\n <span className=\"relative inline-flex shrink-0\">\n <Icon className=\"size-4\" />\n {hotkey && !stacked && (\n <span\n aria-hidden\n className={cn(\n 'pointer-events-none absolute -right-1.5 -top-1.5 rounded-sm px-1 font-mono text-[8px] leading-[1.1]',\n active\n ? 'bg-primary-foreground/20 text-primary-foreground/85'\n : 'bg-foreground/10 text-muted-foreground',\n )}\n >\n {hotkey}\n </span>\n )}\n </span>\n {stacked ? (\n <span className=\"max-w-full truncate\">{label}</span>\n ) : (\n !iconOnly && <span>{label}</span>\n )}\n </button>\n </Tooltip>\n );\n}\n\nfunction useLayoutActions() {\n const elements = useEditorStore((s) => s.diagram.elements);\n const layout = useEditorStore((s) => s.diagram.layout);\n const selection = useEditorStore((s) => s.selection);\n const explicit = layout ?? {};\n return {\n hasAnyElement: elements.length > 0,\n hasArrangedAny: Object.keys(explicit).length > 0,\n hasGapsAll: elements.some((el) => !explicit[el.id]),\n hasSelection: selection.length > 0,\n selectionHasArranged: selection.some((id) => !!explicit[id]),\n selectionHasGaps: selection.some((id) => !explicit[id]),\n };\n}\n\nfunction LayoutMenuButton({ iconOnly }: { iconOnly?: boolean }) {\n const t = useT();\n const [open, setOpen] = useState(false);\n // Subscribe at field-level so disabled state stays live while menu is open.\n const a = useLayoutActions();\n const run = (action: () => void) => () => {\n setOpen(false);\n action();\n };\n return (\n <UpwardPopover\n open={open}\n onOpenChange={setOpen}\n trigger={\n <ToolbarButton\n icon={Wand2}\n label={t('layout.label')}\n description={t('layout.hint')}\n active={open}\n iconOnly={iconOnly}\n onClick={() => setOpen((v) => !v)}\n />\n }\n >\n <PopoverItem\n onClick={run(() => useEditorStore.getState().autoArrangeAll())}\n icon={<Wand2 />}\n disabled={!a.hasAnyElement || !a.hasArrangedAny}\n >\n {t('layout.allAuto')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().autoArrangeSelection())}\n icon={<Wand2 />}\n disabled={!a.hasSelection || !a.selectionHasArranged}\n >\n {t('layout.selAuto')}\n </PopoverItem>\n <div aria-hidden className=\"my-1 h-px bg-border\" />\n <PopoverItem\n onClick={run(() => useEditorStore.getState().fillUnplacedAll())}\n icon={<LayoutGrid />}\n disabled={!a.hasGapsAll}\n >\n {t('layout.allFill')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().fillUnplacedSelection())}\n icon={<LayoutGrid />}\n disabled={!a.hasSelection || !a.selectionHasGaps}\n >\n {t('layout.selFill')}\n </PopoverItem>\n </UpwardPopover>\n );\n}\n\n/**\n * Mini-tier substitute for [Undo, Redo, Layout]: one icon button collapsing\n * those three groups into a single popover. Layout actions are inlined here\n * (not nested inside the popover via a sub-menu) so users only deal with one\n * level of overlay on a tiny screen.\n */\nfunction OverflowMenuButton({ stacked }: { stacked?: boolean }) {\n const t = useT();\n const [open, setOpen] = useState(false);\n const past = useEditorStore((s) => s.past.length);\n const future = useEditorStore((s) => s.future.length);\n const undo = useEditorStore((s) => s.undo);\n const redo = useEditorStore((s) => s.redo);\n const hasSelection = useEditorStore((s) => s.selection.length > 0);\n const hasClipboard = useEditorStore((s) => s.clipboard != null);\n const a = useLayoutActions();\n const run = (action: () => void) => () => {\n setOpen(false);\n action();\n };\n return (\n <UpwardPopover\n open={open}\n onOpenChange={setOpen}\n trigger={\n <ToolbarButton\n icon={MoreHorizontal}\n label={t('tool.more')}\n description={t('tool.moreHint')}\n active={open}\n iconOnly\n stacked={stacked}\n onClick={() => setOpen((v) => !v)}\n />\n }\n >\n <PopoverItem\n onClick={run(undo)}\n icon={<Undo2 />}\n disabled={past === 0}\n >\n {t('tool.undo')}\n </PopoverItem>\n <PopoverItem\n onClick={run(redo)}\n icon={<Redo2 />}\n disabled={future === 0}\n >\n {t('tool.redo')}\n </PopoverItem>\n <div aria-hidden className=\"my-1 h-px bg-border\" />\n <PopoverItem\n onClick={run(() => useEditorStore.getState().cutSelection())}\n icon={<Scissors />}\n disabled={!hasSelection}\n >\n {t('menu.cut')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().copySelection())}\n icon={<Copy />}\n disabled={!hasSelection}\n >\n {t('menu.copy')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().pasteClipboard())}\n icon={<Clipboard />}\n disabled={!hasClipboard}\n >\n {t('menu.paste')}\n </PopoverItem>\n <div aria-hidden className=\"my-1 h-px bg-border\" />\n <PopoverItem\n onClick={run(() => useEditorStore.getState().autoArrangeAll())}\n icon={<Wand2 />}\n disabled={!a.hasAnyElement || !a.hasArrangedAny}\n >\n {t('layout.allAuto')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().autoArrangeSelection())}\n icon={<Wand2 />}\n disabled={!a.hasSelection || !a.selectionHasArranged}\n >\n {t('layout.selAuto')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().fillUnplacedAll())}\n icon={<LayoutGrid />}\n disabled={!a.hasGapsAll}\n >\n {t('layout.allFill')}\n </PopoverItem>\n <PopoverItem\n onClick={run(() => useEditorStore.getState().fillUnplacedSelection())}\n icon={<LayoutGrid />}\n disabled={!a.hasSelection || !a.selectionHasGaps}\n >\n {t('layout.selFill')}\n </PopoverItem>\n </UpwardPopover>\n );\n}\n\nfunction PopoverItem({\n children,\n icon,\n onClick,\n disabled,\n}: {\n children: React.ReactNode;\n icon?: React.ReactNode;\n onClick: () => void;\n disabled?: boolean;\n}) {\n return (\n <button\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n onClick={onClick}\n className={cn(\n 'flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4',\n disabled &&\n 'pointer-events-none text-muted-foreground opacity-60 hover:bg-transparent',\n )}\n >\n {icon}\n <span className=\"flex-1\">{children}</span>\n </button>\n );\n}\n","import { ListTree, PanelBottomClose } from 'lucide-react';\nimport { libraryById } from '../element-library';\nimport { atLeast, useEditorTier } from '../hooks/editor-tier';\nimport { usePanels } from '../hooks/use-panels';\nimport { useT } from '../i18n';\nimport { cn } from '../lib/utils';\nimport { useEditorStore } from '../store';\nimport type { Element } from '../model';\n\nexport function LeftPanel() {\n const open = usePanels((s) => s.outlineOpen);\n const setOpen = usePanels((s) => s.setOutlineOpen);\n const tier = useEditorTier();\n const dense = atLeast(tier, 'dense');\n\n // At dense+ the collapsed tab is replaced by an outline button embedded\n // directly into the FloatingToolbar bottom bar. The outline panel itself\n // still lives here but switches to a full-width bottom sheet anchored just\n // above that bar so it doesn't compete for horizontal room with the canvas.\n if (dense) {\n if (!open) return null;\n return (\n <div\n className=\"absolute z-10\"\n style={{\n left: 'calc(0.75rem + var(--ole-left-inset, 0px))',\n right: 'calc(0.75rem + var(--ole-right-inset, 0px))',\n bottom: 'calc(4rem + var(--ole-bottom-inset, 0px) + 0.75rem)',\n }}\n >\n <OutlinePanel onClose={() => setOpen(false)} sheet />\n </div>\n );\n }\n\n return (\n <div\n className=\"absolute z-10 flex flex-col items-start\"\n style={{\n bottom: 'calc(0.75rem + var(--ole-bottom-inset, 0px))',\n left: 'calc(0.75rem + var(--ole-left-inset, 0px))',\n maxHeight: 'calc(100% - 1.5rem)',\n }}\n >\n {open ? (\n <OutlinePanel onClose={() => setOpen(false)} />\n ) : (\n <CollapsedTab onClick={() => setOpen(true)} />\n )}\n </div>\n );\n}\n\nfunction CollapsedTab({ onClick }: { onClick: () => void }) {\n const t = useT();\n const tier = useEditorTier();\n const compact = atLeast(tier, 'compact');\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={t('outline.title')}\n title={t('outline.title')}\n className={cn(\n 'ole-glass flex h-12 items-center rounded-2xl border border-border text-muted-foreground shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground',\n compact ? 'w-12 justify-center' : 'gap-2 px-3',\n )}\n >\n <ListTree className=\"size-4 shrink-0\" />\n {!compact && <span className=\"text-xs font-medium\">{t('outline.title')}</span>}\n </button>\n );\n}\n\nfunction OutlinePanel({\n onClose,\n sheet,\n}: {\n onClose: () => void;\n sheet?: boolean;\n}) {\n const t = useT();\n const elements = useEditorStore((s) => s.diagram.elements);\n const libraryOpen = useEditorStore((s) => s.activeTool === 'place');\n const tier = useEditorTier();\n const compact = atLeast(tier, 'compact');\n const dense = atLeast(tier, 'dense');\n // Use `height` (not `max-height`) so the panel always reserves space,\n // even when content is short. In sheet mode it sizes by the parent's\n // left/right anchor — we just cap the height so the canvas above stays\n // visible.\n const height = sheet\n ? 'min(50vh, calc(100vh - 9rem))'\n : libraryOpen\n ? 'min(40vh, calc(100vh - 200px))'\n : 'min(70vh, calc(100vh - 100px))';\n return (\n <aside\n className={cn(\n 'ole-glass flex flex-col overflow-hidden rounded-2xl border border-border shadow-sm',\n sheet ? 'w-full' : compact ? 'w-52' : 'w-64',\n )}\n style={{ height }}\n >\n <button\n type=\"button\"\n onClick={onClose}\n aria-label={t('outline.collapseAria')}\n title={t('outline.collapse')}\n className=\"flex items-center gap-1.5 border-b border-border/40 px-3 py-2 text-left transition-colors hover:bg-muted/40\"\n >\n <span className=\"flex-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n {t('outline.title')}\n </span>\n {!dense && <CountChip>{elements.length}</CountChip>}\n <PanelBottomClose className=\"size-3.5 text-muted-foreground\" />\n </button>\n <div className=\"flex-1 overflow-y-auto px-2 pb-2\">\n {elements.length === 0 ? (\n <p className=\"px-2 py-2 text-xs italic text-muted-foreground\">\n {t('outline.empty')}\n </p>\n ) : (\n <ul className=\"space-y-px\">\n {elements.map((el) => (\n <OutlineRow key={el.id} element={el} />\n ))}\n </ul>\n )}\n </div>\n </aside>\n );\n}\n\nfunction OutlineRow({ element }: { element: Element }) {\n const lib = libraryById[element.kind];\n const selected = useEditorStore((s) => s.selection.includes(element.id));\n const setSelection = useEditorStore((s) => s.setSelection);\n const toggleInSelection = useEditorStore((s) => s.toggleInSelection);\n const tier = useEditorTier();\n const showId = !atLeast(tier, 'compact');\n const onClick = (e: React.MouseEvent) => {\n if (e.shiftKey || e.metaKey || e.ctrlKey) toggleInSelection(element.id);\n else setSelection([element.id]);\n };\n return (\n <li\n className=\"group flex cursor-pointer items-center gap-2 rounded-md px-2 py-1 hover:bg-accent data-[selected=true]:bg-[color-mix(in_oklch,var(--selection)_18%,transparent)]\"\n title={element.note ?? `${element.name ?? element.id} (${element.kind})`}\n data-element-id={element.id}\n data-selected={selected ? 'true' : undefined}\n onClick={onClick}\n >\n <div className=\"flex h-4 w-6 shrink-0 items-center justify-center\">\n {lib && (\n <svg\n viewBox={lib.viewBox}\n className=\"ole-symbol size-full\"\n preserveAspectRatio=\"xMidYMid meet\"\n dangerouslySetInnerHTML={{ __html: lib.svg }}\n />\n )}\n </div>\n <span className=\"flex-1 truncate text-xs text-foreground/90 group-hover:text-accent-foreground\">\n {element.name ?? element.id}\n </span>\n {showId && (\n <span className=\"font-mono text-[10px] text-muted-foreground/80\">\n {element.id}\n </span>\n )}\n </li>\n );\n}\n\nfunction CountChip({ children }: { children: React.ReactNode }) {\n return (\n <span className=\"rounded bg-muted/50 px-1.5 py-0.5 font-mono text-[10px] tabular-nums text-muted-foreground/80\">\n {children}\n </span>\n );\n}\n","/**\n * Translation table for `LibraryEntry` user-facing strings: display name,\n * description, state labels, param labels.\n *\n * Kept separate from the strict `messages.ts` map because keys are derived\n * from runtime data (entry id + field name) and would balloon the typed\n * key union. Falls back to the JSON-defined value when no translation exists.\n *\n * Key shape: `<entryId>.name`, `<entryId>.desc`, `<entryId>.state.<name>`,\n * `<entryId>.param.<name>`.\n */\n\nimport { useLocale, type Locale } from './index';\n\ntype Table = Record<string, string>;\n\nconst zh: Table = {\n // Names — the JSON `name` field is already Chinese, so we only need them\n // here for symmetry / one-stop translation. English is the value-add.\n 'arc-suppression-coil.name': '消弧线圈',\n 'arrester.name': '避雷器 (FBL)',\n 'async-motor.name': '异步电动机',\n 'autotransformer.name': '自耦变压器',\n 'battery.name': '电池储能',\n 'breaker.name': '断路器 (QF)',\n 'busbar.name': '母线段',\n 'converter-bidir.name': '双向变流器 (PCS)',\n 'ct.name': '电流互感器 (CT)',\n 'disconnector.name': '隔离开关 (QS)',\n 'earth.name': '接地',\n 'earthing-switch.name': '接地刀闸 (QE)',\n 'fuse.name': '熔断器 (FU)',\n 'generator.name': '发电机 (G)',\n 'grid-source.name': '系统电源',\n 'grounding-transformer.name': '接地变 (Z形)',\n 'inverter.name': '逆变器 (DC→AC)',\n 'load-switch.name': '负荷开关',\n 'load.name': '负荷',\n 'ngr.name': '中性点电阻 (NGR)',\n 'pt.name': '电压互感器 (PT)',\n 'pv.name': '光伏组件',\n 'rectifier.name': '整流器 (AC→DC)',\n 'series-reactor.name': '串联电抗器',\n 'shunt-capacitor.name': '并联电容器',\n 'shunt-reactor.name': '并联电抗器',\n 'sync-motor.name': '同步电动机',\n 'transformer-2w.name': '双绕组变压器',\n 'transformer-3w.name': '三绕组变压器',\n 'wind-turbine.name': '风力发电机',\n // ---- v0.2 additions ----\n 'gfci-breaker.name': 'GFCI 断路器 (RCBO)',\n 'rcd.name': '剩余电流装置 (RCD)',\n 'recloser.name': '重合闸 (Recloser)',\n 'energy-meter.name': '电能表 (Wh)',\n 'voltmeter.name': '电压表 (V)',\n 'ammeter.name': '电流表 (A)',\n 'wattmeter.name': '功率表 (W)',\n 'frequency-meter.name': '频率表 (Hz)',\n 'contactor.name': '接触器 (KM)',\n 'motor-starter.name': '电机启动器',\n 'thermal-overload.name': '热过载继电器',\n 'vfd.name': '变频器 (VFD)',\n 'soft-starter.name': '软启动器',\n 'transfer-switch.name': '切换开关 (ATS)',\n 'dc-disconnector.name': '直流隔离开关',\n 'dc-combiner.name': '直流汇流箱',\n 'ev-charger.name': 'EV 充电桩',\n\n // Descriptions\n 'arc-suppression-coil.desc': '中性点谐振接地:电感线圈连接到地',\n 'busbar.desc': '可拉伸单母线段,多设备挂接',\n 'converter-bidir.desc': '储能变流器:双向 AC ↔ DC',\n 'earthing-switch.desc': '隔离开关 + 接地连接,单端口',\n 'grid-source.desc': '无穷大母线 / 外部电网',\n 'grounding-transformer.desc': '星-曲折接线变压器,中性点接地用',\n 'load.desc': '抽象负荷(电流流出箭头)',\n 'ngr.desc': '小电阻接地:连接变压器中性点到地',\n 'series-reactor.desc': '与并联电抗器同符号;通过用法区分',\n 'wind-turbine.desc': '风机:发电机 + 三叶轮标记',\n 'gfci-breaker.desc': '剩余电流断路器带过流保护 (UL943 / IEC 61009)。北美 GFCI / 欧洲 RCBO。',\n 'rcd.desc': '不带过流保护的剩余电流断路器 (IEC 61008)。',\n 'recloser.desc': '中压自动重合闸开关。',\n 'energy-meter.desc': '有功电能表 (kWh) — 服务入口 / 子表。',\n 'contactor.desc': '主回路接触器, 通常配热继电器和电机使用。',\n 'motor-starter.desc': '电机启动器 (IEC 60617 通用符号)。',\n 'thermal-overload.desc': '电机热过载保护继电器, 通常串接在接触器和电机之间。',\n 'vfd.desc': 'Variable Frequency Drive — 异步电动机调速。',\n 'soft-starter.desc': '电机软启动器 (晶闸管降压启动)。',\n 'transfer-switch.desc': '双源切换开关 (Automatic / Manual Transfer Switch)。两个电源输入 + 一个负荷输出, 互锁不并联。',\n 'dc-disconnector.desc': 'DC 隔离开关 — 光伏组串 / 储能 直流侧隔离。',\n 'dc-combiner.desc': '光伏组串汇流箱 (4 路输入示例)。',\n 'ev-charger.desc': '电动汽车充电站 / 充电桩。',\n\n // State labels\n 'breaker.state.open': '断开',\n 'disconnector.state.open': '断开',\n 'earthing-switch.state.open': '断开',\n 'fuse.state.blown': '熔断',\n 'load-switch.state.open': '断开',\n 'gfci-breaker.state.open': '断开',\n 'rcd.state.open': '断开',\n 'recloser.state.open': '断开',\n 'contactor.state.open': '断开',\n 'thermal-overload.state.tripped': '动作',\n 'transfer-switch.state.position': '位置 (normal/emergency/off)',\n 'dc-disconnector.state.open': '断开',\n\n // Param labels\n 'battery.param.E': '容量',\n 'busbar.param.Un': '额定电压',\n 'converter-bidir.param.S': '容量',\n 'load.param.P': '有功功率',\n 'load.param.cosphi': '功率因数',\n 'ngr.param.R': '电阻',\n 'shunt-capacitor.param.Q': '无功容量',\n 'shunt-capacitor.param.stages': '分组数',\n 'transformer-2w.param.S': '容量',\n 'transformer-2w.param.ratio': '变比',\n 'gfci-breaker.param.In': '额定电流',\n 'gfci-breaker.param.IDn': '剩余动作电流',\n 'rcd.param.IDn': '剩余动作电流',\n};\n\nconst en: Table = {\n 'arc-suppression-coil.name': 'Arc-suppression coil',\n 'arrester.name': 'Surge arrester (FBL)',\n 'async-motor.name': 'Asynchronous motor',\n 'autotransformer.name': 'Autotransformer',\n 'battery.name': 'Battery storage',\n 'breaker.name': 'Circuit breaker (QF)',\n 'busbar.name': 'Busbar segment',\n 'converter-bidir.name': 'Bidirectional converter (PCS)',\n 'ct.name': 'Current transformer (CT)',\n 'disconnector.name': 'Disconnector (QS)',\n 'earth.name': 'Earth',\n 'earthing-switch.name': 'Earthing switch (QE)',\n 'fuse.name': 'Fuse (FU)',\n 'generator.name': 'Generator (G)',\n 'grid-source.name': 'Grid source',\n 'grounding-transformer.name': 'Grounding transformer (zig-zag)',\n 'inverter.name': 'Inverter (DC→AC)',\n 'load-switch.name': 'Load break switch',\n 'load.name': 'Load',\n 'ngr.name': 'Neutral grounding resistor (NGR)',\n 'pt.name': 'Voltage transformer (PT)',\n 'pv.name': 'PV module',\n 'rectifier.name': 'Rectifier (AC→DC)',\n 'series-reactor.name': 'Series reactor',\n 'shunt-capacitor.name': 'Shunt capacitor',\n 'shunt-reactor.name': 'Shunt reactor',\n 'sync-motor.name': 'Synchronous motor',\n 'transformer-2w.name': 'Two-winding transformer',\n 'transformer-3w.name': 'Three-winding transformer',\n 'wind-turbine.name': 'Wind turbine',\n // ---- v0.2 additions ----\n 'gfci-breaker.name': 'GFCI breaker (RCBO)',\n 'rcd.name': 'Residual current device (RCD)',\n 'recloser.name': 'Recloser',\n 'energy-meter.name': 'Energy meter (Wh)',\n 'voltmeter.name': 'Voltmeter (V)',\n 'ammeter.name': 'Ammeter (A)',\n 'wattmeter.name': 'Wattmeter (W)',\n 'frequency-meter.name': 'Frequency meter (Hz)',\n 'contactor.name': 'Contactor (KM)',\n 'motor-starter.name': 'Motor starter',\n 'thermal-overload.name': 'Thermal overload relay',\n 'vfd.name': 'Variable frequency drive (VFD)',\n 'soft-starter.name': 'Soft starter',\n 'transfer-switch.name': 'Transfer switch (ATS)',\n 'dc-disconnector.name': 'DC disconnector',\n 'dc-combiner.name': 'DC combiner box',\n 'ev-charger.name': 'EV charger',\n\n 'arc-suppression-coil.desc': 'Resonant neutral grounding: inductor to earth',\n 'busbar.desc': 'Stretchable single-bus segment with multiple taps',\n 'converter-bidir.desc': 'Storage converter: bidirectional AC ↔ DC',\n 'earthing-switch.desc': 'Disconnector + earth connection, single port',\n 'grid-source.desc': 'Infinite bus / external grid',\n 'grounding-transformer.desc': 'Wye-zigzag transformer for neutral grounding',\n 'load.desc': 'Abstract load (current-out arrow)',\n 'ngr.desc': 'Low-resistance grounding: transformer neutral to earth',\n 'series-reactor.desc': 'Same symbol as shunt reactor; distinguished by usage',\n 'wind-turbine.desc': 'Wind turbine: generator + three-blade rotor mark',\n 'gfci-breaker.desc': 'Residual-current breaker with overcurrent (UL943 / IEC 61009). NA GFCI / EU RCBO.',\n 'rcd.desc': 'Residual-current breaker without overcurrent (IEC 61008).',\n 'recloser.desc': 'Medium-voltage automatic recloser.',\n 'energy-meter.desc': 'Active energy meter (kWh) — service entrance / submeter.',\n 'contactor.desc': 'Main-circuit contactor; typically used with a thermal overload and a motor.',\n 'motor-starter.desc': 'Motor starter (IEC 60617 general symbol).',\n 'thermal-overload.desc': 'Motor thermal-overload relay; sits between the contactor and the motor.',\n 'vfd.desc': 'Variable Frequency Drive for induction motor speed control.',\n 'soft-starter.desc': 'Motor soft-starter (thyristor-based reduced-voltage starting).',\n 'transfer-switch.desc': 'Two-source transfer switch (ATS / manual). Two source inputs + one load output, mechanically interlocked.',\n 'dc-disconnector.desc': 'DC isolating switch — PV string / battery DC-side isolation.',\n 'dc-combiner.desc': 'PV string combiner box (4-input example).',\n 'ev-charger.desc': 'Electric vehicle charging station.',\n\n 'breaker.state.open': 'Open',\n 'disconnector.state.open': 'Open',\n 'earthing-switch.state.open': 'Open',\n 'fuse.state.blown': 'Blown',\n 'load-switch.state.open': 'Open',\n 'gfci-breaker.state.open': 'Open',\n 'rcd.state.open': 'Open',\n 'recloser.state.open': 'Open',\n 'contactor.state.open': 'Open',\n 'thermal-overload.state.tripped': 'Tripped',\n 'transfer-switch.state.position': 'Position (normal/emergency/off)',\n 'dc-disconnector.state.open': 'Open',\n\n 'battery.param.E': 'Capacity',\n 'busbar.param.Un': 'Rated voltage',\n 'converter-bidir.param.S': 'Capacity',\n 'load.param.P': 'Active power',\n 'load.param.cosphi': 'Power factor',\n 'ngr.param.R': 'Resistance',\n 'shunt-capacitor.param.Q': 'Reactive capacity',\n 'shunt-capacitor.param.stages': 'Stages',\n 'transformer-2w.param.S': 'Capacity',\n 'transformer-2w.param.ratio': 'Ratio',\n 'gfci-breaker.param.In': 'Rated current',\n 'gfci-breaker.param.IDn': 'Residual operating current',\n 'rcd.param.IDn': 'Residual operating current',\n};\n\nconst tables: Record<Locale, Table> = { zh, en };\n\nfunction lookup(locale: Locale, key: string): string | undefined {\n return tables[locale][key] ?? tables.zh[key];\n}\n\n/** Returns a translator that re-renders on locale change. */\nexport function useLibT(): (key: string, fallback?: string) => string {\n const locale = useLocale((s) => s.locale);\n return (key, fallback) => lookup(locale, key) ?? fallback ?? key;\n}\n","/**\n * Element library popover. Visible whenever the place tool is active —\n * the FloatingToolbar's \"元件\" button toggles that tool, and picking an\n * entry here arms `placeKind`. Closing (X) returns to the select tool so\n * the place state and the popover stay in lockstep.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { ChevronDown, Search, X } from 'lucide-react';\nimport {\n CATEGORY_ORDER,\n libraryByCategory,\n} from '../element-library';\nimport { atLeast, useEditorTier } from '../hooks/editor-tier';\nimport { usePanels } from '../hooks/use-panels';\nimport { useT, type LocaleKey } from '../i18n';\nimport { useLibT } from '../i18n/library';\nimport { useEditorStore } from '../store';\nimport type { LibraryEntry } from '../model/library';\n\nconst PALETTE_COLLAPSE_STORAGE_KEY = 'ole-palette-collapsed';\n\n/**\n * Library entry IDs that should NOT appear in the palette. The bus is drawn\n * via the dedicated busbar tool (click + drag); having it in the element\n * grid would confuse users into trying to drop it like a fixed-size symbol.\n */\nconst PALETTE_HIDDEN_IDS = new Set<string>(['busbar']);\n\nconst PALETTE_BY_CATEGORY: Record<string, LibraryEntry[]> = (() => {\n const out: Record<string, LibraryEntry[]> = {};\n for (const [cat, entries] of Object.entries(libraryByCategory)) {\n const visible = entries.filter((e) => !PALETTE_HIDDEN_IDS.has(e.id));\n if (visible.length) out[cat] = visible;\n }\n return out;\n})();\n\nconst CATEGORY_IDS: readonly string[] = (() => {\n const known = new Set(CATEGORY_ORDER);\n const extras = Object.keys(PALETTE_BY_CATEGORY).filter((c) => !known.has(c));\n return [\n ...CATEGORY_ORDER.filter((c) => PALETTE_BY_CATEGORY[c]?.length),\n ...extras,\n ];\n})();\n\nfunction readPaletteCollapsed(): Set<string> {\n try {\n const raw = window.localStorage.getItem(PALETTE_COLLAPSE_STORAGE_KEY);\n if (!raw) return new Set();\n const arr = JSON.parse(raw) as unknown;\n return Array.isArray(arr)\n ? new Set(arr.filter((x) => typeof x === 'string'))\n : new Set();\n } catch {\n return new Set();\n }\n}\n\nfunction writePaletteCollapsed(s: Set<string>) {\n try {\n window.localStorage.setItem(\n PALETTE_COLLAPSE_STORAGE_KEY,\n JSON.stringify([...s]),\n );\n } catch {\n // ignore\n }\n}\n\nexport function LibraryPopover() {\n const t = useT();\n const open = useEditorStore((s) => s.activeTool === 'place');\n const placeKind = useEditorStore((s) => s.placeKind);\n const setTool = useEditorStore((s) => s.setActiveTool);\n const outlineOpen = usePanels((s) => s.outlineOpen);\n const tier = useEditorTier();\n const sheet = atLeast(tier, 'dense');\n // Insets so the popover never reaches the floating chrome:\n // - top: leave room for the TopBar (12px gutter + 48px toolbar + 8px margin)\n // - bottom: leave room for the bottom-toolbars / outline button\n // - when outline is expanded, leave room for the outline panel (max ~50vh)\n const TOP_INSET = 68;\n // Outline panel max-height (when library open) is `min(40vh, ...)`, anchored\n // at bottom-3, so reserved bottom space = 40vh + 12px (anchor) + 8px (gap).\n const BOTTOM_INSET = outlineOpen\n ? 'calc(40vh + 20px)'\n : '68px';\n const maxHeight = sheet\n ? undefined\n : `calc(100vh - ${TOP_INSET}px - ${BOTTOM_INSET})`;\n // Phone-class flow: the library is a full-canvas picker that pops up while\n // place mode is active *and* no element is armed yet. Picking an entry\n // arms `placeKind` and hides the picker so the canvas is clear for the\n // placement gesture; PlaceTool clears `placeKind` after each drop on\n // touch (`disarmPlaceOnPhone`), so the picker reappears for the next pick.\n if (!open) return null;\n if (sheet && placeKind != null) return null;\n // Phone-class layout: fill the canvas area between the top bar and the\n // unified bottom bar. Wider viewports keep the classic 288px left-anchored\n // dock.\n const wrapperStyle: React.CSSProperties = sheet\n ? {\n top: `calc(${TOP_INSET}px + var(--ole-top-inset, 0px))`,\n left: 'calc(0.75rem + var(--ole-left-inset, 0px))',\n right: 'calc(0.75rem + var(--ole-right-inset, 0px))',\n bottom: 'calc(4rem + var(--ole-bottom-inset, 0px) + 0.75rem)',\n }\n : { top: TOP_INSET };\n return (\n <div\n className={sheet ? 'absolute z-20' : 'absolute left-3 z-20'}\n style={wrapperStyle}\n role=\"dialog\"\n aria-label={t('library.title')}\n >\n <aside\n className={\n sheet\n ? 'ole-glass flex h-full w-full flex-col overflow-hidden rounded-2xl border border-border shadow-md'\n : 'ole-glass flex w-72 flex-col overflow-hidden rounded-2xl border border-border shadow-md'\n }\n style={maxHeight ? { maxHeight } : undefined}\n >\n <div className=\"flex items-center gap-1.5 border-b border-border/40 px-3 py-2\">\n <span className=\"flex-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n {t('library.title')}\n </span>\n <button\n type=\"button\"\n onClick={() => setTool(sheet ? 'pan' : 'select')}\n className=\"rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n aria-label={t('common.close')}\n title={t('common.close')}\n >\n <X className=\"size-3.5\" />\n </button>\n </div>\n <LibraryBody sheet={sheet} />\n </aside>\n </div>\n );\n}\n\nfunction LibraryBody({ sheet }: { sheet: boolean }) {\n const t = useT();\n const libT = useLibT();\n const [query, setQuery] = useState('');\n const [collapsed, setCollapsed] = useState<Set<string>>(() =>\n readPaletteCollapsed(),\n );\n\n const filteredByCat = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return PALETTE_BY_CATEGORY;\n const out: Record<string, LibraryEntry[]> = {};\n for (const [cat, entries] of Object.entries(PALETTE_BY_CATEGORY)) {\n const hits = entries.filter((e) => {\n const name = libT(`${e.id}.name`, e.name).toLowerCase();\n const desc = libT(`${e.id}.desc`, e.description ?? '').toLowerCase();\n return (\n name.includes(q) ||\n e.id.toLowerCase().includes(q) ||\n desc.includes(q)\n );\n });\n if (hits.length) out[cat] = hits;\n }\n return out;\n }, [query, libT]);\n\n const isSearching = query.trim().length > 0;\n const noMatch =\n isSearching && Object.values(filteredByCat).every((e) => !e?.length);\n\n const handleToggle = useCallback((catId: string, isOpen: boolean) => {\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (isOpen) next.delete(catId);\n else next.add(catId);\n writePaletteCollapsed(next);\n return next;\n });\n }, []);\n\n return (\n <>\n <div className=\"px-2 pb-1.5 pt-2\">\n <SearchBox value={query} onChange={setQuery} />\n </div>\n <div className=\"flex-1 overflow-y-auto px-2 pb-2\">\n {noMatch ? (\n <p className=\"px-3 py-6 text-center text-xs text-muted-foreground\">\n {t('library.empty')}\n </p>\n ) : (\n CATEGORY_IDS.map((catId) => {\n const entries = filteredByCat[catId];\n if (!entries?.length) return null;\n const total = PALETTE_BY_CATEGORY[catId]?.length ?? entries.length;\n const label = t(`cat.${catId}` as LocaleKey);\n const isOpen = isSearching || !collapsed.has(catId);\n return (\n <details\n key={catId}\n open={isOpen}\n className=\"group mb-2 last:mb-0\"\n onToggle={(e) => {\n if (isSearching) return;\n handleToggle(\n catId,\n (e.currentTarget as HTMLDetailsElement).open,\n );\n }}\n >\n <summary className=\"flex cursor-pointer select-none items-center gap-1.5 rounded-md px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground hover:bg-accent hover:text-accent-foreground\">\n <ChevronDown className=\"size-3 transition-transform [details:not([open])>summary>&]:-rotate-90\" />\n <span className=\"flex-1\">{label}</span>\n <CountChip>\n {isSearching && entries.length !== total\n ? `${entries.length}/${total}`\n : total}\n </CountChip>\n </summary>\n <ul className=\"mt-0.5 space-y-px\">\n {entries.map((entry) => (\n <ElementRow key={entry.id} entry={entry} sheet={sheet} />\n ))}\n </ul>\n </details>\n );\n })\n )}\n </div>\n </>\n );\n}\n\nfunction SearchBox({\n value,\n onChange,\n}: {\n value: string;\n onChange: (v: string) => void;\n}) {\n const t = useT();\n return (\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground\" />\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={t('library.searchPlaceholder')}\n className=\"h-7 w-full rounded-md border border-border/60 bg-background/50 pl-7 pr-7 text-xs placeholder:text-muted-foreground focus:border-border focus:outline-none focus:ring-1 focus:ring-ring\"\n aria-label={t('library.searchAria')}\n />\n {value && (\n <button\n type=\"button\"\n aria-label={t('library.clearSearch')}\n onClick={() => onChange('')}\n className=\"absolute right-1 top-1/2 -translate-y-1/2 rounded-sm p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n >\n <X className=\"size-3\" />\n </button>\n )}\n </div>\n );\n}\n\nfunction ElementRow({\n entry,\n sheet,\n}: {\n entry: LibraryEntry;\n sheet: boolean;\n}) {\n const t = useT();\n const libT = useLibT();\n const name = libT(`${entry.id}.name`, entry.name);\n const description = libT(`${entry.id}.desc`, entry.description ?? '');\n const setTool = useEditorStore((s) => s.setActiveTool);\n const armed = useEditorStore(\n (s) => s.activeTool === 'place' && s.placeKind === entry.id,\n );\n // On phone the library re-opens between every drop, so highlight the most\n // recently placed kind and scroll it into view — keeps \"drop another of\n // the same\" cheap without forcing the user to re-find it in the list.\n const recent = useEditorStore(\n (s) =>\n sheet &&\n s.activeTool === 'place' &&\n s.placeKind == null &&\n s.lastPlaceKind === entry.id,\n );\n const ref = useRef<HTMLLIElement | null>(null);\n useEffect(() => {\n if (recent) ref.current?.scrollIntoView({ block: 'nearest' });\n }, [recent]);\n\n const onDragStart = (e: React.DragEvent<HTMLLIElement>) => {\n e.dataTransfer.effectAllowed = 'copy';\n e.dataTransfer.setData('application/x-oneline-kind', entry.id);\n e.dataTransfer.setData('text/plain', entry.id);\n const ghost = document.createElement('div');\n ghost.className = 'ole-glass';\n ghost.style.cssText = [\n 'position:absolute',\n 'top:-9999px',\n 'left:-9999px',\n 'width:64px',\n 'height:64px',\n 'display:flex',\n 'align-items:center',\n 'justify-content:center',\n 'border-radius:12px',\n 'border:1px solid var(--border)',\n 'box-shadow:0 4px 12px rgba(0,0,0,0.12)',\n 'color:var(--foreground)',\n 'padding:8px',\n ].join(';');\n ghost.innerHTML = `<svg class=\"ole-symbol\" viewBox=\"${entry.viewBox}\" width=\"48\" height=\"48\" preserveAspectRatio=\"xMidYMid meet\">${entry.svg}</svg>`;\n document.body.appendChild(ghost);\n e.dataTransfer.setDragImage(ghost, 32, 32);\n setTimeout(() => ghost.remove(), 0);\n };\n\n return (\n <li\n ref={ref}\n className={`group flex cursor-grab items-center gap-2.5 rounded-md px-2 py-1.5 transition-colors hover:bg-accent active:cursor-grabbing ${\n armed\n ? 'bg-accent ring-1 ring-[var(--selection)]/60'\n : recent\n ? 'ring-1 ring-[var(--selection)]/30'\n : ''\n }`}\n draggable\n onDragStart={onDragStart}\n onClick={() => setTool('place', { placeKind: entry.id })}\n data-kind={entry.id}\n title={description ? `${name} — ${description}` : `${name} — ${t('library.itemHint')}`}\n >\n <div className=\"flex h-7 w-12 shrink-0 items-center justify-center\">\n <svg\n viewBox={entry.viewBox}\n className=\"ole-symbol size-full\"\n preserveAspectRatio=\"xMidYMid meet\"\n dangerouslySetInnerHTML={{ __html: entry.svg }}\n />\n </div>\n <span className=\"truncate text-xs text-foreground/80 group-hover:text-accent-foreground\">\n {name}\n </span>\n </li>\n );\n}\n\nfunction CountChip({ children }: { children: React.ReactNode }) {\n return (\n <span className=\"rounded bg-muted/50 px-1.5 py-0.5 font-mono text-[10px] tabular-nums text-muted-foreground/80\">\n {children}\n </span>\n );\n}\n","/**\n * One-shot onboarding-card dismissal flag, persisted to localStorage.\n *\n * Mirrors `usePanels` / `useTheme` patterns: a tiny Zustand store with a\n * boolean and a setter. Once dismissed, the card stays hidden across\n * reloads; clearing storage (or calling `reset`) brings it back.\n */\n\nimport { create } from 'zustand';\n\nconst STORAGE_KEY = 'ole-onboarding-dismissed';\n\nfunction readInitial(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return window.localStorage.getItem(STORAGE_KEY) === '1';\n } catch {\n return false;\n }\n}\n\nfunction persist(dismissed: boolean): void {\n try {\n if (dismissed) window.localStorage.setItem(STORAGE_KEY, '1');\n else window.localStorage.removeItem(STORAGE_KEY);\n } catch {\n // ignore quota / disabled storage\n }\n}\n\ninterface OnboardingState {\n dismissed: boolean;\n dismiss: () => void;\n reset: () => void;\n}\n\nexport const useOnboarding = create<OnboardingState>((set) => ({\n dismissed: readInitial(),\n dismiss: () => {\n persist(true);\n set({ dismissed: true });\n },\n reset: () => {\n persist(false);\n set({ dismissed: false });\n },\n}));\n","/**\n * First-visit onboarding card. Surfaces the canonical drawing flow:\n * busbar first → drag elements off the bus → chain from terminals.\n *\n * Visibility: shown until the user dismisses it (persisted to localStorage),\n * regardless of whether the canvas is empty — the card and the sample\n * diagram together form the first-impression. The wrapper is\n * `pointer-events: none` so users can press-and-drag right through it\n * (e.g., the busbar drag the card just told them to perform); only the\n * dismiss controls accept clicks.\n */\n\nimport { Cable, Minus, Shapes, X } from 'lucide-react';\nimport { useOnboarding } from '../hooks/use-onboarding';\nimport { useT } from '../i18n';\n\nexport function OnboardingCard() {\n const t = useT();\n const dismissed = useOnboarding((s) => s.dismissed);\n const dismiss = useOnboarding((s) => s.dismiss);\n if (dismissed) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-label={t('onboard.title')}\n className=\"ole-glass pointer-events-none absolute left-1/2 top-1/2 z-10 w-[min(420px,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 rounded-2xl border border-border p-5 shadow-md\"\n >\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold\">{t('onboard.title')}</h2>\n <button\n type=\"button\"\n onClick={dismiss}\n aria-label={t('onboard.dismiss')}\n className=\"pointer-events-auto rounded-md p-1 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n >\n <X className=\"size-3.5\" />\n </button>\n </div>\n <ol className=\"mt-3 space-y-2.5\">\n <Step\n n={1}\n icon={<Minus />}\n title={t('onboard.step1.title')}\n body={t('onboard.step1.body')}\n />\n <Step\n n={2}\n icon={<Shapes />}\n title={t('onboard.step2.title')}\n body={t('onboard.step2.body')}\n />\n <Step\n n={3}\n icon={<Cable />}\n title={t('onboard.step3.title')}\n body={t('onboard.step3.body')}\n />\n </ol>\n <button\n type=\"button\"\n onClick={dismiss}\n className=\"pointer-events-auto mt-4 w-full rounded-md bg-primary py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90\"\n >\n {t('onboard.dismiss')}\n </button>\n </div>\n );\n}\n\nfunction Step({\n n,\n icon,\n title,\n body,\n}: {\n n: number;\n icon: React.ReactNode;\n title: string;\n body: string;\n}) {\n return (\n <li className=\"flex items-start gap-2.5\">\n <span\n className=\"mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full bg-[color-mix(in_oklch,var(--selection)_18%,transparent)] font-mono text-[10px] font-semibold tabular-nums text-[var(--selection)]\"\n aria-hidden\n >\n {n}\n </span>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium\">\n <span className=\"text-muted-foreground [&>svg]:size-3.5\">{icon}</span>\n <span>{title}</span>\n </div>\n <p className=\"mt-0.5 text-[11px] leading-snug text-muted-foreground\">\n {body}\n </p>\n </div>\n </li>\n );\n}\n","/**\n * Right-panel property editor — minimal by design. Shows only what the user\n * needs to *configure* (name, note, kind-specific state). Transformations\n * (rotate/mirror/delete) live on the contextual floating toolbar; type label\n * lives in the panel header.\n */\n\nimport { useEffect, useRef, useState } from 'react';\nimport { libraryById } from '../element-library';\nimport { useT } from '../i18n';\nimport { useLibT } from '../i18n/library';\nimport { useEditorStore } from '../store';\nimport type {\n Bus,\n BusId,\n Element,\n ElementId,\n LibraryParamField,\n LibraryStateField,\n ParamValue,\n WireId,\n} from '../model';\nimport { cn } from '../lib/utils';\n\nexport function PropertyPanel() {\n const t = useT();\n const selection = useEditorStore((s) => s.selection);\n const elements = useEditorStore((s) => s.diagram.elements);\n const buses = useEditorStore((s) => s.diagram.buses);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const selectedWire = useEditorStore((s) => s.selectedWire);\n\n if (selectedWire) return <WirePanel wireId={selectedWire} />;\n if (selectedNode) return <NodePanel nodeId={selectedNode} />;\n\n if (selection.length === 0) {\n return (\n <div className=\"px-4 py-5 text-center text-xs text-muted-foreground\">\n {t('props.empty')}\n </div>\n );\n }\n\n if (selection.length > 1) {\n return (\n <div className=\"px-4 py-5 text-center text-xs text-muted-foreground\">\n {t('props.multi', { n: selection.length })}\n </div>\n );\n }\n\n const id = selection[0];\n const bus = (buses ?? []).find((b) => b.id === id);\n if (bus) return <BusInspector bus={bus} />;\n const element = elements.find((e) => e.id === id);\n if (!element) return null;\n const lib = libraryById[element.kind];\n\n return (\n <div className=\"flex flex-col gap-2.5 overflow-y-auto px-3 py-3 text-xs\">\n <TextRow\n label={t('props.name')}\n value={element.name ?? ''}\n placeholder={element.id}\n onCommit={(v) =>\n useEditorStore\n .getState()\n .updateElement(id, { name: v.trim() === '' ? undefined : v.trim() })\n }\n />\n <TextAreaRow\n label={t('props.note')}\n value={element.note ?? ''}\n onCommit={(v) =>\n useEditorStore\n .getState()\n .updateElement(id, { note: v.trim() === '' ? undefined : v.trim() })\n }\n />\n {lib?.state && lib.state.length > 0 && (\n <div className=\"mt-1 flex flex-col gap-1.5 border-t border-border/40 pt-2.5\">\n {lib.state.map((field) => (\n <StateField key={field.name} id={id} element={element} field={field} />\n ))}\n </div>\n )}\n <ParamsSection\n id={id}\n element={element}\n schema={lib?.params ?? []}\n />\n </div>\n );\n}\n\nfunction ParamsSection({\n id,\n element,\n schema,\n}: {\n id: ElementId;\n element: Element;\n schema: LibraryParamField[];\n}) {\n const schemaKeys = new Set(schema.map((p) => p.name));\n const extras = element.params\n ? Object.entries(element.params).filter(([k]) => !schemaKeys.has(k))\n : [];\n if (schema.length === 0 && extras.length === 0) return null;\n return (\n <div className=\"mt-1 flex flex-col gap-1.5 border-t border-border/40 pt-2.5\">\n {schema.map((field) => (\n <SchemaParamField\n key={field.name}\n id={id}\n element={element}\n field={field}\n />\n ))}\n {extras.map(([key, value]) => (\n <ParamField\n key={key}\n id={id}\n element={element}\n fieldKey={key}\n value={value}\n />\n ))}\n </div>\n );\n}\n\n/**\n * Schema-driven param row: uses the library entry's declared label / unit /\n * type / default.\n */\nfunction SchemaParamField({\n id,\n element,\n field,\n}: {\n id: ElementId;\n element: Element;\n field: LibraryParamField;\n}) {\n const t = useT();\n const libT = useLibT();\n const cur = element.params?.[field.name] ?? field.default;\n const label = libT(`${element.kind}.param.${field.name}`, field.label ?? field.name);\n const onCommit = (next: ParamValue | undefined) => {\n const params = { ...(element.params ?? {}) };\n if (next === undefined || next === field.default) delete params[field.name];\n else params[field.name] = next;\n useEditorStore.getState().updateElement(id, {\n params: Object.keys(params).length > 0 ? params : undefined,\n });\n };\n\n if (field.type === 'boolean') {\n return (\n <Field label={label}>\n <ToggleButton active={!!cur} onClick={() => onCommit(!cur)}>\n {cur ? t('common.yes') : t('common.no')}\n </ToggleButton>\n </Field>\n );\n }\n if (field.type === 'number') {\n return (\n <NumberRow\n label={label}\n value={typeof cur === 'number' ? cur : 0}\n unit={field.unit}\n onCommit={onCommit}\n />\n );\n }\n return (\n <TextRow\n label={label}\n value={typeof cur === 'string' ? cur : ''}\n unit={field.unit}\n onCommit={(v) => onCommit(v.trim() === '' ? undefined : v)}\n />\n );\n}\n\n/**\n * Param row driven purely by the stored value's type (no library schema\n * required). Number/boolean/string are each rendered with the right input;\n * empty strings clear the key so users don't leave dangling `\"\"` values.\n */\nfunction ParamField({\n id,\n element,\n fieldKey,\n value,\n}: {\n id: ElementId;\n element: Element;\n fieldKey: string;\n value: ParamValue;\n}) {\n const t = useT();\n const onCommit = (next: ParamValue | undefined) => {\n const params = { ...(element.params ?? {}) };\n if (next === undefined) delete params[fieldKey];\n else params[fieldKey] = next;\n useEditorStore.getState().updateElement(id, {\n params: Object.keys(params).length > 0 ? params : undefined,\n });\n };\n\n if (typeof value === 'boolean') {\n return (\n <Field label={fieldKey}>\n <ToggleButton active={value} onClick={() => onCommit(!value)}>\n {value ? t('common.yes') : t('common.no')}\n </ToggleButton>\n </Field>\n );\n }\n if (typeof value === 'number') {\n return (\n <NumberRow label={fieldKey} value={value} onCommit={onCommit} />\n );\n }\n return (\n <TextRow\n label={fieldKey}\n value={value}\n onCommit={(v) => onCommit(v.trim() === '' ? undefined : v)}\n />\n );\n}\n\n// ---------------------------------------------------------------------------\n// Bus inspector — selected bus shows name + Un + span (read-only span).\n// ---------------------------------------------------------------------------\n\nfunction BusInspector({ bus }: { bus: Bus }) {\n const t = useT();\n const id = bus.id;\n const onName = (v: string) => {\n const name = v.trim();\n updateBusEntry(id, { name: name === '' ? undefined : name });\n };\n return (\n <div className=\"flex flex-col gap-2.5 overflow-y-auto px-3 py-3 text-xs\">\n <TextRow\n label={t('props.name')}\n value={bus.name ?? ''}\n placeholder={bus.id}\n onCommit={onName}\n />\n <TextAreaRow\n label={t('props.note')}\n value={bus.note ?? ''}\n onCommit={(v) =>\n updateBusEntry(id, { note: v.trim() === '' ? undefined : v.trim() })\n }\n />\n <BusParams bus={bus} />\n </div>\n );\n}\n\nfunction BusParams({ bus }: { bus: Bus }) {\n const onCommit = (key: string, next: ParamValue | undefined) => {\n const params = { ...(bus.params ?? {}) };\n if (next === undefined || next === '') delete params[key];\n else params[key] = next;\n updateBusEntry(bus.id, {\n params: Object.keys(params).length > 0 ? params : undefined,\n });\n };\n const cur = bus.params ?? {};\n return (\n <div className=\"mt-1 flex flex-col gap-1.5 border-t border-border/40 pt-2.5\">\n <NumberRow\n label=\"Un\"\n value={typeof cur.Un === 'number' ? cur.Un : 0}\n unit=\"kV\"\n onCommit={(v) => onCommit('Un', v)}\n />\n </div>\n );\n}\n\nfunction updateBusEntry(id: BusId, patch: Partial<Bus>) {\n useEditorStore.getState().dispatch((d) => {\n const buses = (d.buses ?? []).map((b) => (b.id === id ? { ...b, ...patch } : b));\n return { ...d, buses };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Wire inspector — shows the two endpoints and a \"select whole node\" action.\n// ---------------------------------------------------------------------------\n\nfunction WirePanel({ wireId }: { wireId: WireId }) {\n const t = useT();\n const wires = useEditorStore((s) => s.diagram.wires);\n const elements = useEditorStore((s) => s.diagram.elements);\n const buses = useEditorStore((s) => s.diagram.buses);\n const terminalToNode = useEditorStore((s) => s.internal.terminalToNode);\n const setSelectedNode = useEditorStore((s) => s.setSelectedNode);\n const wire = (wires ?? []).find((w) => w.id === wireId);\n if (!wire) {\n return (\n <div className=\"px-4 py-5 text-center text-xs text-muted-foreground\">\n {t('props.wireNotFound', { id: wireId })}\n </div>\n );\n }\n const nodeId = terminalToNode.get(wire.ends[0]);\n const elemById = new Map(elements.map((e) => [e.id, e]));\n const busById = new Map((buses ?? []).map((b) => [b.id, b]));\n const describeEnd = (end: string): { id: string; label: string; pin?: string } => {\n if (!end.includes('.')) {\n const b = busById.get(end);\n return { id: end, label: b?.name ?? end };\n }\n const dot = end.indexOf('.');\n const elId = end.slice(0, dot);\n const pin = end.slice(dot + 1);\n const el = elemById.get(elId);\n return { id: elId, label: el?.name ?? elId, pin };\n };\n const a = describeEnd(wire.ends[0]);\n const b = describeEnd(wire.ends[1]);\n return (\n <div className=\"flex flex-col gap-3 px-3 py-3 text-xs\">\n <div className=\"space-y-1\">\n <div className=\"text-[11px] uppercase tracking-wide text-muted-foreground\">\n {t('props.wire')}\n </div>\n <div className=\"font-mono text-[12px]\">{wire.id}</div>\n </div>\n <ul className=\"space-y-0.5 border-t border-border/40 pt-2\">\n {[a, b].map((e, i) => (\n <li\n key={i}\n className=\"flex cursor-pointer items-center gap-2 rounded-md px-1.5 py-1 hover:bg-accent\"\n onClick={() => useEditorStore.getState().setSelection([e.id])}\n >\n <span className=\"flex-1 truncate font-mono text-[11px]\">{e.id}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\">{e.label}</span>\n {e.pin && (\n <span className=\"font-mono text-[10px] text-muted-foreground/80\">\n {e.pin}\n </span>\n )}\n </li>\n ))}\n </ul>\n {nodeId && (\n <button\n type=\"button\"\n className=\"self-start rounded-md border border-border/60 px-2 py-1 text-[11px] text-muted-foreground hover:bg-accent\"\n onClick={() => setSelectedNode(nodeId)}\n >\n {t('props.selectWholeNode')}\n </button>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Connectivity-node panel — shown when a wire is the selected target.\n// ---------------------------------------------------------------------------\n\nfunction NodePanel({ nodeId }: { nodeId: string }) {\n const t = useT();\n const node = useEditorStore((s) => s.internal.nodes.get(nodeId));\n const elements = useEditorStore((s) => s.diagram.elements);\n const setSelection = useEditorStore((s) => s.setSelection);\n\n if (!node) {\n return (\n <div className=\"px-4 py-5 text-center text-xs text-muted-foreground\">\n {t('props.nodeNotFound', { id: nodeId })}\n </div>\n );\n }\n\n // Group terminals by element so the list reads \"QF1: a, b\" rather than\n // a flat 1-per-row blob.\n const byElement = new Map<string, string[]>();\n for (const ref of node.terminals) {\n const dot = ref.indexOf('.');\n if (dot < 0) continue;\n const eId = ref.slice(0, dot);\n const pin = ref.slice(dot + 1);\n const arr = byElement.get(eId) ?? [];\n arr.push(pin);\n byElement.set(eId, arr);\n }\n\n const elById = new Map(elements.map((e) => [e.id, e]));\n\n return (\n <div className=\"flex flex-col gap-3 px-3 py-3 text-xs\">\n <div className=\"space-y-1\">\n <div className=\"text-[11px] uppercase tracking-wide text-muted-foreground\">\n {t('props.node')}\n </div>\n <div className=\"font-mono text-[12px]\">\n {node.id}\n </div>\n <div className=\"text-[11px] text-muted-foreground\">\n {t('props.nodeStats', {\n terminals: node.terminals.length,\n elements: byElement.size,\n })}\n </div>\n </div>\n\n <ul className=\"space-y-0.5 border-t border-border/40 pt-2\">\n {[...byElement.entries()].map(([eId, pins]) => {\n const el = elById.get(eId);\n return (\n <li\n key={eId}\n className=\"flex cursor-pointer items-center gap-2 rounded-md px-1.5 py-1 hover:bg-accent\"\n onClick={() => setSelection([eId])}\n title={t('props.selectElement', { label: eId })}\n >\n <span className=\"flex-1 truncate font-mono text-[11px]\">{eId}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\">\n {el?.name ?? ''}\n </span>\n <span className=\"font-mono text-[10px] text-muted-foreground/80\">\n {pins.join(', ')}\n </span>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Form bits\n// ---------------------------------------------------------------------------\n\nfunction Field({\n label,\n children,\n}: {\n label: string;\n children: React.ReactNode;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <label className=\"w-16 shrink-0 truncate text-[11px] text-muted-foreground\">\n {label}\n </label>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n}\n\nfunction TextRow({\n label,\n value,\n placeholder,\n unit,\n onCommit,\n}: {\n label: string;\n value: string;\n placeholder?: string;\n unit?: string;\n onCommit: (v: string) => void;\n}) {\n const [local, setLocal] = useState(value);\n const ref = useRef<HTMLInputElement>(null);\n useEffect(() => setLocal(value), [value]);\n return (\n <Field label={label}>\n <div className=\"relative\">\n <input\n ref={ref}\n type=\"text\"\n value={local}\n placeholder={placeholder}\n onChange={(e) => setLocal(e.target.value)}\n onBlur={() => {\n if (local !== value) onCommit(local);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') ref.current?.blur();\n if (e.key === 'Escape') {\n setLocal(value);\n ref.current?.blur();\n }\n }}\n className={cn(\n 'h-7 w-full rounded-md border border-border/60 bg-background/50 px-2 text-[11px] focus:border-border focus:outline-none focus:ring-1 focus:ring-ring',\n unit && 'pr-8',\n )}\n />\n {unit && (\n <span className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground\">\n {unit}\n </span>\n )}\n </div>\n </Field>\n );\n}\n\nfunction TextAreaRow({\n label,\n value,\n onCommit,\n}: {\n label: string;\n value: string;\n onCommit: (v: string) => void;\n}) {\n const [local, setLocal] = useState(value);\n useEffect(() => setLocal(value), [value]);\n return (\n <Field label={label}>\n <textarea\n rows={2}\n value={local}\n onChange={(e) => setLocal(e.target.value)}\n onBlur={() => {\n if (local !== value) onCommit(local);\n }}\n className=\"w-full resize-none rounded-md border border-border/60 bg-background/50 px-2 py-1 text-[11px] focus:border-border focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n </Field>\n );\n}\n\nfunction NumberRow({\n label,\n value,\n min,\n unit,\n onCommit,\n}: {\n label: string;\n value: number;\n min?: number;\n unit?: string;\n onCommit: (v: number) => void;\n}) {\n const [local, setLocal] = useState(String(value));\n const ref = useRef<HTMLInputElement>(null);\n useEffect(() => setLocal(String(value)), [value]);\n return (\n <Field label={label}>\n <div className=\"relative\">\n <input\n ref={ref}\n type=\"number\"\n value={local}\n onChange={(e) => setLocal(e.target.value)}\n onBlur={() => {\n const n = Number(local);\n if (Number.isFinite(n) && n !== value) onCommit(n);\n else setLocal(String(value));\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') ref.current?.blur();\n if (e.key === 'Escape') {\n setLocal(String(value));\n ref.current?.blur();\n }\n }}\n min={min}\n className={cn(\n 'h-7 w-full rounded-md border border-border/60 bg-background/50 px-2 font-mono text-[11px] tabular-nums focus:border-border focus:outline-none focus:ring-1 focus:ring-ring',\n unit && 'pr-8',\n )}\n />\n {unit && (\n <span className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground\">\n {unit}\n </span>\n )}\n </div>\n </Field>\n );\n}\n\nfunction ToggleButton({\n active,\n onClick,\n children,\n}: {\n active: boolean;\n onClick: () => void;\n children: React.ReactNode;\n}) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={cn(\n 'flex h-6 w-full items-center justify-center gap-1.5 rounded border text-[10px] transition-colors',\n active\n ? 'border-[var(--selection)] bg-[var(--selection)]/15 text-foreground'\n : 'border-border/60 text-muted-foreground hover:bg-accent',\n )}\n aria-pressed={active}\n >\n {children}\n </button>\n );\n}\n\nfunction StateField({\n id,\n element,\n field,\n}: {\n id: ElementId;\n element: Element;\n field: LibraryStateField;\n}) {\n const t = useT();\n const libT = useLibT();\n const label = libT(`${element.kind}.state.${field.name}`, field.label ?? field.name);\n const cur = element.state?.[field.name] ?? field.default;\n const onCommit = (next: ParamValue | undefined) => {\n const state = { ...(element.state ?? {}) };\n if (next === undefined || next === field.default) delete state[field.name];\n else state[field.name] = next;\n useEditorStore\n .getState()\n .updateElement(id, {\n state: Object.keys(state).length > 0 ? state : undefined,\n });\n };\n\n if (field.type === 'boolean') {\n return (\n <Field label={label}>\n <ToggleButton active={!!cur} onClick={() => onCommit(!cur)}>\n {cur ? t('common.yes') : t('common.no')}\n </ToggleButton>\n </Field>\n );\n }\n if (field.type === 'number') {\n return (\n <NumberRow\n label={label}\n value={typeof cur === 'number' ? cur : 0}\n onCommit={onCommit}\n />\n );\n }\n return (\n <TextRow\n label={label}\n value={typeof cur === 'string' ? cur : ''}\n onCommit={(v) => onCommit(v.trim() === '' ? undefined : v)}\n />\n );\n}\n","import { libraryById } from '../element-library';\nimport { atLeast, useEditorTier } from '../hooks/editor-tier';\nimport { useT } from '../i18n';\nimport { useLibT } from '../i18n/library';\nimport { cn } from '../lib/utils';\nimport { useEditorStore } from '../store';\nimport { PropertyPanel } from './PropertyPanel';\n\nexport function RightPanel() {\n const t = useT();\n const libT = useLibT();\n const selection = useEditorStore((s) => s.selection);\n const selectedNode = useEditorStore((s) => s.selectedNode);\n const selectedWire = useEditorStore((s) => s.selectedWire);\n const elements = useEditorStore((s) => s.diagram.elements);\n const buses = useEditorStore((s) => s.diagram.buses);\n const tier = useEditorTier();\n const compactWidth = atLeast(tier, 'dense');\n\n if (selection.length === 0 && !selectedNode && !selectedWire) return null;\n\n let title = t('props.title');\n let count: number | null = null;\n if (selectedWire) {\n title = t('props.wire');\n } else if (selectedNode) {\n title = t('props.node');\n } else if (selection.length === 1) {\n const id = selection[0];\n const bus = (buses ?? []).find((b) => b.id === id);\n if (bus) {\n title = bus.name ?? t('props.bus');\n } else {\n const el = elements.find((e) => e.id === id);\n if (el) {\n const lib = libraryById[el.kind];\n title = lib ? libT(`${lib.id}.name`, lib.name) : el.kind;\n }\n }\n } else {\n count = selection.length;\n }\n\n return (\n <aside\n className={cn(\n 'ole-glass absolute z-10 flex flex-col overflow-hidden rounded-2xl border border-border shadow-sm',\n compactWidth ? 'w-48' : 'w-56',\n )}\n style={{\n top: `calc(${compactWidth ? '4.5rem' : '0.75rem'} + var(--ole-top-inset, 0px))`,\n right: 'calc(0.75rem + var(--ole-right-inset, 0px))',\n maxHeight: `calc(100% - ${compactWidth ? '5.25rem' : '1.5rem'} - var(--ole-top-inset, 0px) - var(--ole-bottom-inset, 0px) - 4.5rem)`,\n }}\n >\n <div className=\"flex items-center gap-1.5 border-b border-border/40 px-3 py-2\">\n <span className=\"flex-1 truncate text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n {title}\n </span>\n {count != null && (\n <span className=\"rounded bg-muted/50 px-1.5 py-0.5 font-mono text-[10px] tabular-nums text-muted-foreground/80\">\n {t('props.nSelected', { n: count })}\n </span>\n )}\n </div>\n <PropertyPanel />\n </aside>\n );\n}\n","import { useEffect, useRef } from 'react';\nimport { CanvasSvg } from '../canvas';\nimport { ElementHoverLabel } from '../canvas/ElementHoverLabel';\nimport { useObservedWidth } from '../hooks/editor-tier';\nimport { EditorTierProvider } from '../hooks/use-editor-tier';\nimport { ContextMenuHost } from './ContextMenu';\nimport { ContextualToolbar } from './ContextualToolbar';\nimport { FloatingToolbar } from './FloatingToolbar';\nimport { LeftPanel } from './LeftPanel';\nimport { LibraryPopover } from './LibraryPopover';\nimport { OnboardingCard } from './OnboardingCard';\nimport { RightPanel } from './RightPanel';\nimport { ViewToolbar } from './ViewToolbar';\n\n/**\n * Keep keyboard focus where shortcuts can reach it.\n *\n * Two failure modes this guards against:\n * 1. Clicking a chrome button leaves it focused → next Space press activates\n * the button instead of starting a pan, etc. Fix: preventDefault on\n * mousedown of chrome buttons so they never steal focus from the canvas.\n * 2. Tab navigation puts focus on a chrome button → user has no way to\n * reset short of clicking. Fix: clicking the canvas blurs the active\n * element, restoring the \"no focus\" baseline shortcuts expect.\n *\n * Tab still works for keyboard-only users who actually want to navigate the\n * chrome — only mouse interactions are made focus-neutral.\n */\nfunction useFocusGuards() {\n useEffect(() => {\n const onMouseDown = (e: MouseEvent) => {\n const t = e.target as HTMLElement | null;\n if (!t) return;\n // Don't steal text selection or input focus.\n if (\n t.tagName === 'INPUT' ||\n t.tagName === 'TEXTAREA' ||\n t.isContentEditable\n ) {\n return;\n }\n const btn = t.closest('button');\n if (btn && btn.closest('.ole-glass')) e.preventDefault();\n };\n const onCanvasPointerDown = (e: Event) => {\n const t = e.target as HTMLElement | null;\n if (!t) return;\n if (!t.closest('.ole-canvas-root')) return;\n const active = document.activeElement as HTMLElement | null;\n if (!active || active === document.body) return;\n // Leave inputs alone — clicking outside an input naturally blurs it\n // anyway, and we don't want to fight any deliberate focus.\n if (\n active.tagName === 'INPUT' ||\n active.tagName === 'TEXTAREA' ||\n active.isContentEditable\n ) {\n return;\n }\n active.blur();\n };\n window.addEventListener('mousedown', onMouseDown);\n window.addEventListener('pointerdown', onCanvasPointerDown, true);\n return () => {\n window.removeEventListener('mousedown', onMouseDown);\n window.removeEventListener('pointerdown', onCanvasPointerDown, true);\n };\n }, []);\n}\n\nexport function EditorShell() {\n useFocusGuards();\n const rootRef = useRef<HTMLDivElement>(null);\n // Measured here (where the ref lives) so the layout effect runs *after*\n // this component's own ref attaches. A child component's layout effect\n // would fire before the parent's ref is set, so the first read is null.\n const width = useObservedWidth(rootRef);\n return (\n <ContextMenuHost>\n <div\n ref={rootRef}\n className=\"relative h-full w-full overflow-hidden bg-background text-foreground\"\n >\n <EditorTierProvider width={width}>\n <CanvasSvg />\n <LeftPanel />\n <RightPanel />\n <FloatingToolbar />\n <ViewToolbar />\n <ContextualToolbar />\n <LibraryPopover />\n <OnboardingCard />\n <ElementHoverLabel />\n </EditorTierProvider>\n </div>\n </ContextMenuHost>\n );\n}\n","import { useCallback, useEffect, useState } from 'react';\n\nexport type Theme = 'light' | 'dark';\n\nconst STORAGE_KEY = 'ole-theme';\n\nfunction readStored(): Theme | null {\n try {\n const v = window.localStorage.getItem(STORAGE_KEY);\n return v === 'light' || v === 'dark' ? v : null;\n } catch {\n return null;\n }\n}\n\nfunction persist(theme: Theme): void {\n try {\n window.localStorage.setItem(STORAGE_KEY, theme);\n } catch {\n // ignore quota / disabled storage\n }\n}\n\nfunction systemPrefersDark(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-color-scheme: dark)').matches\n );\n}\n\n/**\n * Resolve the theme to apply at startup. Exported so that `src/demo/main.tsx`\n * can apply the class before React mounts and avoid FOUC.\n *\n * Falls back to the OS `prefers-color-scheme` when no stored preference exists.\n */\nexport function getInitialTheme(): Theme {\n if (typeof window === 'undefined') return 'light';\n return readStored() ?? (systemPrefersDark() ? 'dark' : 'light');\n}\n\n/** Reflect a `Theme` value onto `<html>`'s class list. */\nexport function applyTheme(theme: Theme): void {\n if (typeof document === 'undefined') return;\n document.documentElement.classList.toggle('dark', theme === 'dark');\n}\n\n/**\n * Theme hook.\n *\n * - First visit: matches `prefers-color-scheme`. Continues to follow OS changes\n * until the user explicitly toggles, after which the explicit choice is\n * persisted and \"owns\" the theme.\n * - `setTheme` / `toggle` always persist (they are explicit user actions).\n */\nexport function useTheme() {\n const [theme, setThemeState] = useState<Theme>(getInitialTheme);\n\n useEffect(() => {\n applyTheme(theme);\n }, [theme]);\n\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return;\n }\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n const onChange = (e: MediaQueryListEvent) => {\n if (readStored() == null) {\n setThemeState(e.matches ? 'dark' : 'light');\n }\n };\n mq.addEventListener('change', onChange);\n return () => mq.removeEventListener('change', onChange);\n }, []);\n\n const setTheme = useCallback((next: Theme) => {\n persist(next);\n setThemeState(next);\n }, []);\n\n const toggle = useCallback(() => {\n setThemeState((t) => {\n const next = t === 'light' ? 'dark' : 'light';\n persist(next);\n return next;\n });\n }, []);\n\n return { theme, setTheme, toggle };\n}\n","import { useEffect } from 'react';\nimport { EditorShell } from './components/EditorShell';\nimport { fitToContentSoon, useKeyboardShortcuts } from './canvas';\nimport type { DiagramFile } from './model';\nimport { useEditorStore } from './store';\nimport { useLocale, type Locale } from './i18n';\nimport { applyTheme, type Theme } from './hooks/use-theme';\n\nexport interface OneLineEditorProps {\n className?: string;\n /** Initial DiagramFile to render. Re-renders when this reference changes. */\n diagram?: DiagramFile;\n /**\n * Force the editor's UI language. When omitted, falls back to the user's\n * previous choice (localStorage) or the browser's locale. When set, the\n * embedder owns the language and any change to this prop is mirrored into\n * the locale store.\n */\n locale?: Locale;\n /**\n * Force the editor's color mode. When omitted, uses the user's previous\n * choice or OS `prefers-color-scheme`. Applied via the `dark` class on\n * `<html>` (the standard Tailwind pattern), so embedding hosts that share\n * the same documentElement will see the same class.\n */\n theme?: Theme;\n}\n\nexport function OneLineEditor({ className, diagram, locale, theme }: OneLineEditorProps) {\n useEffect(() => {\n if (!diagram) return;\n // Don't clobber persisted/in-progress work on remount or HMR. Only seed\n // the initial diagram if the store is empty (first visit / cleared\n // storage). Consumers wanting to force-replace can call setDiagram\n // imperatively.\n const current = useEditorStore.getState().diagram;\n if (current.elements.length === 0) {\n useEditorStore.getState().setDiagram(diagram);\n }\n }, [diagram]);\n\n useEffect(() => {\n if (locale) useLocale.getState().setLocale(locale);\n }, [locale]);\n\n useEffect(() => {\n if (theme) applyTheme(theme);\n }, [theme]);\n\n // Reset the viewport to fit the diagram on first mount — covers both the\n // fresh-seed path above and the case where persisted state rehydrated a\n // diagram from a previous session. `fitToContentSoon` waits a few frames\n // for the canvas DOM to attach.\n useEffect(() => {\n fitToContentSoon();\n }, []);\n\n useKeyboardShortcuts();\n\n return (\n <div className={`ole-root ${className ?? 'h-full w-full'}`}>\n <EditorShell />\n </div>\n );\n}\n","/**\n * Disk I/O for DiagramFile JSON documents.\n *\n * Uses the File System Access API where available so that \"save\" can write\n * back to the originally opened file; falls back to a hidden `<input>` /\n * download anchor in browsers without it.\n */\n\nimport { t } from '../i18n';\nimport type { DiagramFile } from '../model';\n\nconst ACCEPT: Record<string, string[]> = { 'application/json': ['.json'] };\n\n/** Tracks the currently associated on-disk file across open / save calls. */\nexport interface FileSession {\n /** Present only when the FS Access API is available; lets save() overwrite. */\n handle?: FileSystemFileHandle;\n /** Display name shown in the title bar / save dialog default. */\n name: string;\n}\n\nconst supportsFsa = (): boolean =>\n typeof window !== 'undefined' && typeof window.showOpenFilePicker === 'function';\n\nconst isAbort = (e: unknown): boolean =>\n e instanceof DOMException && e.name === 'AbortError';\n\nfunction parseDiagram(text: string): DiagramFile {\n let raw: unknown;\n try {\n raw = JSON.parse(text);\n } catch (e) {\n throw new Error(t('io.parseFailed', { err: (e as Error).message }));\n }\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n throw new Error(t('io.notObject'));\n }\n const obj = raw as Record<string, unknown>;\n if (obj.version !== '1') {\n throw new Error(t('io.versionMismatch', { actual: JSON.stringify(obj.version) }));\n }\n if (!Array.isArray(obj.elements)) {\n throw new Error(t('io.elementsMissing'));\n }\n return obj as unknown as DiagramFile;\n}\n\nfunction serialize(diagram: DiagramFile): string {\n return JSON.stringify(diagram, null, 2) + '\\n';\n}\n\n/**\n * Pop the OS file picker and load a DiagramFile. Resolves to `null` when\n * the user cancels.\n */\nexport async function openDiagram(): Promise<{\n diagram: DiagramFile;\n session: FileSession;\n} | null> {\n if (supportsFsa()) {\n let handle: FileSystemFileHandle;\n try {\n [handle] = await window.showOpenFilePicker!({\n multiple: false,\n types: [{ description: t('topbar.file.fileDescription'), accept: ACCEPT }],\n });\n } catch (e) {\n if (isAbort(e)) return null;\n throw e;\n }\n const file = await handle.getFile();\n return {\n diagram: parseDiagram(await file.text()),\n session: { handle, name: file.name },\n };\n }\n\n return new Promise((resolve, reject) => {\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = '.json,application/json';\n input.addEventListener('change', async () => {\n const file = input.files?.[0];\n if (!file) return resolve(null);\n try {\n resolve({\n diagram: parseDiagram(await file.text()),\n session: { name: file.name },\n });\n } catch (e) {\n reject(e);\n }\n });\n input.addEventListener('cancel', () => resolve(null));\n input.click();\n });\n}\n\n/**\n * Save a DiagramFile to disk. With an existing handle and `saveAs=false`,\n * overwrites in place; otherwise prompts for a destination (or downloads in\n * browsers without FS Access). Resolves to the new session, or `null` if\n * the user cancelled.\n */\nexport async function saveDiagram(\n diagram: DiagramFile,\n session: FileSession | null,\n options: { saveAs?: boolean } = {},\n): Promise<FileSession | null> {\n const text = serialize(diagram);\n\n if (!options.saveAs && session?.handle) {\n const writable = await session.handle.createWritable();\n await writable.write(text);\n await writable.close();\n return session;\n }\n\n if (supportsFsa()) {\n let handle: FileSystemFileHandle;\n try {\n handle = await window.showSaveFilePicker!({\n suggestedName: session?.name ?? 'diagram.json',\n types: [{ description: t('topbar.file.fileDescription'), accept: ACCEPT }],\n });\n } catch (e) {\n if (isAbort(e)) return null;\n throw e;\n }\n const writable = await handle.createWritable();\n await writable.write(text);\n await writable.close();\n return { handle, name: handle.name };\n }\n\n // Fallback: browser download. We can't track a real handle.\n const url = URL.createObjectURL(new Blob([text], { type: 'application/json' }));\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = session?.name ?? 'diagram.json';\n anchor.click();\n URL.revokeObjectURL(url);\n return session ?? { name: 'diagram.json' };\n}\n","/**\n * File menu — New / Open / Save / Save As, plus ⌘O / ⌘S / ⌘⇧S keyboard\n * shortcuts. Renders as a dropdown button. Self-contained: reads/writes the\n * editor store directly and prompts the OS file picker (FS Access API where\n * available, hidden input fallback otherwise).\n *\n * Exported from the library so that embedding apps that want a \"local file\"\n * mode without backend can drop it into their own toolbar.\n */\n\nimport {\n FilePlus,\n FolderOpen,\n Save,\n} from 'lucide-react';\nimport { useEffect, useRef, useState } from 'react';\nimport { fitToContentSoon } from '../canvas';\nimport { Button } from './ui/button';\nimport { useT } from '../i18n';\nimport { openDiagram, saveDiagram } from '../lib/file-io';\nimport { useEditorStore } from '../store';\n\nexport function FileMenu() {\n const t = useT();\n const fileSession = useEditorStore((s) => s.fileSession);\n const fileLabel = fileSession?.name ?? t('common.unnamed');\n const { onNew, onOpen, onSave, onSaveAs } = useFileActions();\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: KeyboardEvent) => {\n if (!(e.metaKey || e.ctrlKey)) return;\n const k = e.key.toLowerCase();\n if (k === 'o') {\n e.preventDefault();\n onOpen();\n } else if (k === 's') {\n e.preventDefault();\n if (e.shiftKey) onSaveAs();\n else onSave();\n }\n };\n window.addEventListener('keydown', handler);\n return () => window.removeEventListener('keydown', handler);\n }, [onOpen, onSave, onSaveAs]);\n\n useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n window.addEventListener('mousedown', onClick);\n window.addEventListener('keydown', onKey);\n return () => {\n window.removeEventListener('mousedown', onClick);\n window.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const run = (action: () => void) => () => {\n setOpen(false);\n action();\n };\n\n return (\n <div ref={ref} className=\"relative\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1.5\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n >\n <FolderOpen />\n {t('topbar.file.label')}\n </Button>\n {open && (\n <div\n role=\"menu\"\n className=\"ole-glass absolute left-0 top-full mt-1.5 min-w-44 rounded-md border border-border p-1 shadow-md\"\n >\n <div className=\"border-b border-border px-2 pb-1.5 pt-1 text-xs text-muted-foreground\">\n {fileLabel}\n </div>\n <MenuItem onClick={run(onNew)} icon={<FilePlus />}>\n {t('topbar.file.new')}\n </MenuItem>\n <MenuItem onClick={run(onOpen)} icon={<FolderOpen />} hint=\"⌘O\">\n {t('topbar.file.open')}\n </MenuItem>\n <MenuItem onClick={run(onSave)} icon={<Save />} hint=\"⌘S\">\n {t('topbar.file.save')}\n </MenuItem>\n <MenuItem onClick={run(onSaveAs)} icon={<Save />} hint=\"⌘⇧S\">\n {t('topbar.file.saveAs')}\n </MenuItem>\n </div>\n )}\n </div>\n );\n}\n\nfunction MenuItem({\n children,\n icon,\n hint,\n onClick,\n}: {\n children: React.ReactNode;\n icon?: React.ReactNode;\n hint?: string;\n onClick: () => void;\n}) {\n return (\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={onClick}\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4\"\n >\n {icon}\n <span className=\"flex-1\">{children}</span>\n {hint && (\n <span className=\"text-xs tabular-nums text-muted-foreground\">{hint}</span>\n )}\n </button>\n );\n}\n\nfunction useFileActions() {\n const t = useT();\n const loadDiagramFromFile = useEditorStore((s) => s.loadDiagramFromFile);\n const setFileSession = useEditorStore((s) => s.setFileSession);\n const setDiagram = useEditorStore((s) => s.setDiagram);\n\n const onNew = () => {\n const { diagram } = useEditorStore.getState();\n if (diagram.elements.length > 0) {\n const ok = confirm(t('topbar.file.newConfirm'));\n if (!ok) return;\n }\n setDiagram({ version: '1', elements: [] });\n setFileSession(null);\n };\n\n const onOpen = async () => {\n try {\n const result = await openDiagram();\n if (result) {\n loadDiagramFromFile(result.diagram, result.session);\n fitToContentSoon();\n }\n } catch (e) {\n alert(t('topbar.file.openFailed', { err: (e as Error).message }));\n }\n };\n\n const onSave = async () => {\n try {\n const { diagram, fileSession } = useEditorStore.getState();\n const session = await saveDiagram(diagram, fileSession);\n if (session) setFileSession(session);\n } catch (e) {\n alert(t('topbar.file.saveFailed', { err: (e as Error).message }));\n }\n };\n\n const onSaveAs = async () => {\n try {\n const { diagram, fileSession } = useEditorStore.getState();\n const session = await saveDiagram(diagram, fileSession, { saveAs: true });\n if (session) setFileSession(session);\n } catch (e) {\n alert(t('topbar.file.saveFailed', { err: (e as Error).message }));\n }\n };\n\n return { onNew, onOpen, onSave, onSaveAs };\n}\n","/**\n * Export the current diagram as an ASCII DXF (AutoCAD R12 / AC1009). Mirrors\n * `export-image.ts` in shape but emits native CAD entities so the output is\n * editable in AutoCAD/LibreCAD/etc.\n *\n * Mapping summary:\n * <line> → LINE\n * <polyline> → LWPOLYLINE (open)\n * <polygon> → LWPOLYLINE (closed)\n * <rect> → LWPOLYLINE (closed, 4 corners; rx/ry ignored)\n * <circle> → CIRCLE\n * <ellipse> → CIRCLE if rx≈ry, else sampled LWPOLYLINE (closed)\n * <path d=\"M..A..\">→ sampled LWPOLYLINE (open)\n * <text> → TEXT\n * wire route → LWPOLYLINE (open)\n * free annotation → TEXT (one per line)\n * element label → TEXT (one per line, ID + showOnCanvas params)\n *\n * Y is flipped to CAD convention (Y up). 4 layers: WIRES, ELEMENTS, LABELS,\n * ANNOTATIONS.\n */\n\nimport {\n transformPoint,\n type InternalModel,\n type ResolvedPlacement,\n} from '../compiler';\nimport type { LabelMode, TextAnnotation } from '../model';\nimport {\n LABEL_FONT_SIZE,\n LABEL_LINE_HEIGHT,\n anchorWorld,\n fallbackAnchor,\n labelLines,\n} from './element-labels';\n\nexport interface DxfExportOptions {\n /** Used as the $PROJECTNAME header value when present. */\n title?: string;\n /** Decimal places for coordinate output. Default 6. */\n precision?: number;\n /** Element label visibility. Mirrors `DiagramFile.meta.labelMode`. Default 'all'. */\n labelMode?: LabelMode;\n /** Free text annotations from `DiagramFile.annotations` — `InternalModel`\n * doesn't carry them, so the caller passes them through. */\n annotations?: TextAnnotation[];\n}\n\nconst LAYER_WIRES = 'WIRES';\nconst LAYER_ELEMENTS = 'ELEMENTS';\nconst LAYER_LABELS = 'LABELS';\nconst LAYER_ANNOTATIONS = 'ANNOTATIONS';\n\nconst ARC_SAMPLES = 32;\nconst ELLIPSE_SAMPLES = 64;\nconst ANNOTATION_FONT_SIZE = 8;\nconst ANNOTATION_LINE_HEIGHT = 1.25;\nconst TEXT_FONT_SIZE_DEFAULT = 6;\n\nexport function buildExportDxf(\n model: InternalModel,\n opts: DxfExportOptions = {},\n): string {\n const w = new DxfWriter(opts.precision ?? 6);\n\n w.header(opts.title);\n w.tables([\n { name: LAYER_WIRES, color: 7 },\n { name: LAYER_ELEMENTS, color: 7 },\n { name: LAYER_LABELS, color: 8 },\n { name: LAYER_ANNOTATIONS, color: 3 },\n ]);\n w.beginEntities();\n\n // Wires (already in world coordinates).\n for (const r of model.wireRenders.values()) {\n if (r.path.length < 2) continue;\n w.lwpolyline(LAYER_WIRES, r.path.map(worldToDxf), false);\n }\n\n // Buses (drawn after wires so the heavier bar sits on top).\n for (const { geometry } of model.buses.values()) {\n const { axis, at, span } = geometry;\n const half = span / 2;\n const a: [number, number] = axis === 'x' ? [at[0] - half, at[1]] : [at[0], at[1] - half];\n const b: [number, number] = axis === 'x' ? [at[0] + half, at[1]] : [at[0], at[1] + half];\n w.lwpolyline(LAYER_WIRES, [a, b].map(worldToDxf), false);\n }\n\n // Element symbols.\n for (const re of model.elements.values()) {\n const place = model.layout.get(re.element.id);\n const lib = re.libraryDef;\n if (!place || !lib) continue;\n emitLibrarySvg(w, lib.svg, place);\n }\n\n // Element structural labels (ID + showOnCanvas params).\n const mode: LabelMode = opts.labelMode ?? 'all';\n if (mode !== 'off') {\n for (const re of model.elements.values()) {\n const place = model.layout.get(re.element.id);\n if (!place || !re.libraryDef) continue;\n const lines = labelLines(re, mode);\n if (lines.length === 0) continue;\n const anchor = re.libraryDef.label ?? fallbackAnchor(re.libraryDef);\n const [ax, ay] = anchorWorld(anchor, place);\n // Lines stack downward in screen-space → upward separation in DXF Y-up\n // becomes negative spacing on the screen-Y, i.e. positive when flipped.\n for (let i = 0; i < lines.length; i++) {\n const [x, y] = worldToDxf([ax, ay + i * LABEL_LINE_HEIGHT]);\n w.text(LAYER_LABELS, [x, y], lines[i], LABEL_FONT_SIZE, 0, false);\n }\n }\n }\n\n // Free text annotations.\n for (const ann of opts.annotations ?? []) {\n if (!ann.text) continue;\n const fs = ann.fontSize ?? ANNOTATION_FONT_SIZE;\n const lines = ann.text.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const [x, y] = worldToDxf([\n ann.at[0],\n ann.at[1] + (i + 1) * fs * ANNOTATION_LINE_HEIGHT,\n ]);\n // SVG `<text y>` is the baseline; the canvas annotation layer paints\n // the first line at `at.y + fs` and steps by fs*1.25. We mimic that so\n // DXF placement matches what users see on the canvas.\n w.text(LAYER_ANNOTATIONS, [x, y], lines[i], fs, 0, false);\n }\n }\n\n w.endEntities();\n return w.toString();\n}\n\nexport async function downloadDxf(\n model: InternalModel,\n filename = 'diagram.dxf',\n opts?: DxfExportOptions,\n): Promise<void> {\n const dxf = buildExportDxf(model, opts);\n const url = URL.createObjectURL(\n new Blob([dxf], { type: 'application/dxf;charset=utf-8' }),\n );\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n\n// -----------------------------------------------------------------------------\n// SVG fragment → DXF entities\n// -----------------------------------------------------------------------------\n\nfunction emitLibrarySvg(\n w: DxfWriter,\n svg: string,\n place: ResolvedPlacement,\n): void {\n // Wrap so DOMParser sees a single root element.\n const wrapped = `<svg xmlns=\"http://www.w3.org/2000/svg\">${svg}</svg>`;\n const doc = new DOMParser().parseFromString(wrapped, 'image/svg+xml');\n const root = doc.documentElement;\n if (!root || root.querySelector('parsererror')) return;\n\n for (const el of Array.from(root.children)) {\n const tag = el.tagName.toLowerCase();\n switch (tag) {\n case 'line':\n emitLine(w, el, place);\n break;\n case 'polyline':\n emitPoly(w, el, place, false);\n break;\n case 'polygon':\n emitPoly(w, el, place, true);\n break;\n case 'rect':\n emitRect(w, el, place);\n break;\n case 'circle':\n emitCircle(w, el, place);\n break;\n case 'ellipse':\n emitEllipse(w, el, place);\n break;\n case 'path':\n emitPath(w, el, place);\n break;\n case 'text':\n emitText(w, el, place);\n break;\n default:\n break;\n }\n }\n}\n\nfunction emitLine(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const x1 = numAttr(el, 'x1');\n const y1 = numAttr(el, 'y1');\n const x2 = numAttr(el, 'x2');\n const y2 = numAttr(el, 'y2');\n const a = worldToDxf(localToWorld([x1, y1], place));\n const b = worldToDxf(localToWorld([x2, y2], place));\n w.line(LAYER_ELEMENTS, a, b);\n}\n\nfunction emitPoly(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n closed: boolean,\n): void {\n const pts = parsePoints(el.getAttribute('points') ?? '');\n if (pts.length < 2) return;\n const out = pts.map((p) => worldToDxf(localToWorld(p, place)));\n w.lwpolyline(LAYER_ELEMENTS, out, closed);\n}\n\nfunction emitRect(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const x = numAttr(el, 'x');\n const y = numAttr(el, 'y');\n const ww = numAttr(el, 'width');\n const hh = numAttr(el, 'height');\n const corners: [number, number][] = [\n [x, y],\n [x + ww, y],\n [x + ww, y + hh],\n [x, y + hh],\n ];\n const out = corners.map((p) => worldToDxf(localToWorld(p, place)));\n w.lwpolyline(LAYER_ELEMENTS, out, true);\n}\n\nfunction emitCircle(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const cx = numAttr(el, 'cx');\n const cy = numAttr(el, 'cy');\n const r = numAttr(el, 'r');\n const center = worldToDxf(localToWorld([cx, cy], place));\n w.circle(LAYER_ELEMENTS, center, r);\n}\n\nfunction emitEllipse(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const cx = numAttr(el, 'cx');\n const cy = numAttr(el, 'cy');\n const rx = numAttr(el, 'rx');\n const ry = numAttr(el, 'ry');\n if (Math.abs(rx - ry) < 1e-6) {\n emitCircleRaw(w, cx, cy, rx, place);\n return;\n }\n sampleEllipse(w, cx, cy, rx, ry, place);\n}\n\nfunction emitCircleRaw(\n w: DxfWriter,\n cx: number,\n cy: number,\n r: number,\n place: ResolvedPlacement,\n): void {\n const center = worldToDxf(localToWorld([cx, cy], place));\n w.circle(LAYER_ELEMENTS, center, r);\n}\n\nfunction sampleEllipse(\n w: DxfWriter,\n cx: number,\n cy: number,\n rx: number,\n ry: number,\n place: ResolvedPlacement,\n): void {\n const pts: [number, number][] = [];\n for (let i = 0; i < ELLIPSE_SAMPLES; i++) {\n const t = (i / ELLIPSE_SAMPLES) * Math.PI * 2;\n pts.push(\n worldToDxf(\n localToWorld([cx + rx * Math.cos(t), cy + ry * Math.sin(t)], place),\n ),\n );\n }\n w.lwpolyline(LAYER_ELEMENTS, pts, true);\n}\n\nfunction emitText(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const x = numAttr(el, 'x');\n const y = numAttr(el, 'y');\n const fs = parseFloat(el.getAttribute('font-size') ?? '') || TEXT_FONT_SIZE_DEFAULT;\n const txt = (el.textContent ?? '').trim();\n if (!txt) return;\n const p = worldToDxf(localToWorld([x, y], place));\n // place.rot is CCW in math frame (see transforms.ts); after flipping Y we\n // are in DXF's CCW frame, so the same numeric angle maps directly.\n w.text(LAYER_ELEMENTS, p, txt, fs, place.rot, place.mirror);\n}\n\n// -----------------------------------------------------------------------------\n// SVG path (M / A subset) → sampled LWPOLYLINE\n// -----------------------------------------------------------------------------\n\nfunction emitPath(\n w: DxfWriter,\n el: Element,\n place: ResolvedPlacement,\n): void {\n const d = el.getAttribute('d') ?? '';\n const cmds = tokenizePath(d);\n if (cmds.length === 0) return;\n\n let pen: [number, number] | null = null;\n let buffer: [number, number][] = [];\n const flush = () => {\n if (buffer.length >= 2) {\n w.lwpolyline(\n LAYER_ELEMENTS,\n buffer.map((p) => worldToDxf(localToWorld(p, place))),\n false,\n );\n }\n buffer = [];\n };\n\n for (const c of cmds) {\n if (c.cmd === 'M') {\n flush();\n pen = [c.args[0], c.args[1]];\n buffer.push(pen);\n } else if (c.cmd === 'A' && pen) {\n const [rx, ry, , large, sweep, x2, y2] = c.args;\n const arc = arcEndpointToCenter(\n pen,\n [x2, y2],\n rx,\n ry,\n large !== 0,\n sweep !== 0,\n );\n if (arc) {\n // Skip the start point (already pushed by M or previous segment) and\n // sample the rest.\n for (let i = 1; i <= ARC_SAMPLES; i++) {\n const t = arc.theta1 + (arc.delta * i) / ARC_SAMPLES;\n buffer.push([\n arc.cx + rx * Math.cos(t),\n arc.cy + ry * Math.sin(t),\n ]);\n }\n } else {\n buffer.push([x2, y2]); // degenerate: straight line fallback\n }\n pen = [x2, y2];\n }\n }\n flush();\n}\n\ninterface PathCmd {\n cmd: 'M' | 'A';\n args: number[];\n}\n\nfunction tokenizePath(d: string): PathCmd[] {\n const out: PathCmd[] = [];\n // Split by command letter while preserving the letter.\n const re = /([MmAa])([^MmAa]*)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(d)) !== null) {\n const cmd = m[1].toUpperCase() as 'M' | 'A';\n const nums = m[2]\n .trim()\n .split(/[\\s,]+/)\n .filter((s) => s.length > 0)\n .map(Number);\n out.push({ cmd, args: nums });\n }\n return out;\n}\n\ninterface ArcCenter {\n cx: number;\n cy: number;\n theta1: number;\n delta: number;\n}\n\n/**\n * SVG endpoint → center parametrization (W3C SVG 1.1 §F.6.5). Assumes\n * x-axis-rotation = 0 (verified across the element library).\n */\nfunction arcEndpointToCenter(\n p1: [number, number],\n p2: [number, number],\n rx: number,\n ry: number,\n largeArc: boolean,\n sweep: boolean,\n): ArcCenter | null {\n if (rx <= 0 || ry <= 0) return null;\n const [x1, y1] = p1;\n const [x2, y2] = p2;\n if (x1 === x2 && y1 === y2) return null;\n\n const x1p = (x1 - x2) / 2;\n const y1p = (y1 - y2) / 2;\n\n let RX = Math.abs(rx);\n let RY = Math.abs(ry);\n const r2x = RX * RX;\n const r2y = RY * RY;\n const lambda = (x1p * x1p) / r2x + (y1p * y1p) / r2y;\n if (lambda > 1) {\n const s = Math.sqrt(lambda);\n RX *= s;\n RY *= s;\n }\n\n const sign = largeArc === sweep ? -1 : 1;\n const num = RX * RX * RY * RY - RX * RX * y1p * y1p - RY * RY * x1p * x1p;\n const den = RX * RX * y1p * y1p + RY * RY * x1p * x1p;\n const coef = sign * Math.sqrt(Math.max(0, num / den));\n\n const cxp = (coef * (RX * y1p)) / RY;\n const cyp = (coef * -(RY * x1p)) / RX;\n\n const cx = cxp + (x1 + x2) / 2;\n const cy = cyp + (y1 + y2) / 2;\n\n const angle = (ux: number, uy: number, vx: number, vy: number): number => {\n const dot = ux * vx + uy * vy;\n const len = Math.hypot(ux, uy) * Math.hypot(vx, vy);\n let a = Math.acos(Math.max(-1, Math.min(1, dot / len)));\n if (ux * vy - uy * vx < 0) a = -a;\n return a;\n };\n\n const theta1 = angle(1, 0, (x1p - cxp) / RX, (y1p - cyp) / RY);\n let delta = angle(\n (x1p - cxp) / RX,\n (y1p - cyp) / RY,\n (-x1p - cxp) / RX,\n (-y1p - cyp) / RY,\n );\n if (!sweep && delta > 0) delta -= 2 * Math.PI;\n else if (sweep && delta < 0) delta += 2 * Math.PI;\n\n return { cx, cy, theta1, delta };\n}\n\n// -----------------------------------------------------------------------------\n// Geometry helpers\n// -----------------------------------------------------------------------------\n\nfunction localToWorld(\n local: [number, number],\n place: ResolvedPlacement,\n): [number, number] {\n return transformPoint(local, place);\n}\n\nfunction worldToDxf(p: [number, number]): [number, number] {\n return [p[0], -p[1]];\n}\n\nfunction numAttr(el: Element, name: string): number {\n const v = parseFloat(el.getAttribute(name) ?? '');\n return Number.isFinite(v) ? v : 0;\n}\n\nfunction parsePoints(raw: string): [number, number][] {\n const nums = raw.trim().split(/[\\s,]+/).map(Number).filter((n) => Number.isFinite(n));\n const out: [number, number][] = [];\n for (let i = 0; i + 1 < nums.length; i += 2) out.push([nums[i], nums[i + 1]]);\n return out;\n}\n\n// -----------------------------------------------------------------------------\n// DXF writer — minimal ASCII (AC1009) emitter\n// -----------------------------------------------------------------------------\n\nclass DxfWriter {\n private out: string[] = [];\n // Explicit field + assignment rather than a constructor parameter\n // property — embedding consumers (load-survey) compile this file\n // through their own tsconfig with `erasableSyntaxOnly: true`, which\n // rejects non-erasable TS syntax like ``private readonly precision``.\n private readonly precision: number;\n\n constructor(precision: number) {\n this.precision = precision;\n }\n\n toString(): string {\n return this.out.join('');\n }\n\n private g(code: number, value: string | number): void {\n this.out.push(`${code}\\n${this.fmt(value)}\\n`);\n }\n\n private fmt(v: string | number): string {\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) return '0';\n if (Number.isInteger(v)) return String(v);\n return v.toFixed(this.precision);\n }\n return v;\n }\n\n header(title?: string): void {\n this.g(0, 'SECTION');\n this.g(2, 'HEADER');\n this.g(9, '$ACADVER');\n this.g(1, 'AC1009');\n this.g(9, '$INSUNITS');\n this.g(70, 0);\n if (title) {\n this.g(9, '$PROJECTNAME');\n this.g(1, sanitizeText(title));\n }\n this.g(0, 'ENDSEC');\n }\n\n tables(layers: { name: string; color: number }[]): void {\n this.g(0, 'SECTION');\n this.g(2, 'TABLES');\n this.g(0, 'TABLE');\n this.g(2, 'LAYER');\n this.g(70, layers.length);\n for (const l of layers) {\n this.g(0, 'LAYER');\n this.g(2, l.name);\n this.g(70, 0);\n this.g(62, l.color);\n this.g(6, 'CONTINUOUS');\n }\n this.g(0, 'ENDTAB');\n this.g(0, 'ENDSEC');\n }\n\n beginEntities(): void {\n this.g(0, 'SECTION');\n this.g(2, 'ENTITIES');\n }\n\n endEntities(): void {\n this.g(0, 'ENDSEC');\n this.g(0, 'EOF');\n }\n\n line(layer: string, p1: [number, number], p2: [number, number]): void {\n this.g(0, 'LINE');\n this.g(8, layer);\n this.g(10, p1[0]);\n this.g(20, p1[1]);\n this.g(30, 0);\n this.g(11, p2[0]);\n this.g(21, p2[1]);\n this.g(31, 0);\n }\n\n lwpolyline(layer: string, points: [number, number][], closed: boolean): void {\n if (points.length < 2) return;\n this.g(0, 'LWPOLYLINE');\n this.g(8, layer);\n this.g(90, points.length);\n this.g(70, closed ? 1 : 0);\n for (const [x, y] of points) {\n this.g(10, x);\n this.g(20, y);\n }\n }\n\n circle(layer: string, center: [number, number], radius: number): void {\n this.g(0, 'CIRCLE');\n this.g(8, layer);\n this.g(10, center[0]);\n this.g(20, center[1]);\n this.g(30, 0);\n this.g(40, radius);\n }\n\n text(\n layer: string,\n p: [number, number],\n text: string,\n height: number,\n rotationDeg: number,\n mirrorX: boolean,\n ): void {\n this.g(0, 'TEXT');\n this.g(8, layer);\n this.g(10, p[0]);\n this.g(20, p[1]);\n this.g(30, 0);\n this.g(40, height);\n this.g(1, sanitizeText(text));\n if (rotationDeg !== 0) this.g(50, rotationDeg);\n if (mirrorX) this.g(71, 2);\n }\n}\n\nfunction sanitizeText(s: string): string {\n // DXF group code 1 fields are line-delimited; strip newlines so a multi-line\n // annotation can't smuggle its own DXF directives. Also clamp length to\n // 250 chars (DXF R12 line limit) to be safe.\n return s.replace(/[\\r\\n]+/g, ' ').slice(0, 250);\n}\n","/**\n * Export the current diagram as a standalone SVG (or rasterized PNG). Builds\n * the SVG offline from `InternalModel` rather than scraping the live canvas\n * — this keeps UI chrome (selection halos, terminal hit rects, marquee,\n * etc.) out of the file and crops tightly around the actual content.\n */\n\nimport { transformAttr } from '../canvas/transform-attr';\nimport { transformPoint, type InternalModel } from '../compiler';\nimport type { LabelMode, TextAnnotation } from '../model';\nimport {\n LABEL_FONT_SIZE,\n LABEL_LINE_HEIGHT,\n anchorWorld,\n fallbackAnchor,\n labelLines,\n} from './element-labels';\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\nconst PADDING = 24;\nconst ANNOTATION_FONT_SIZE = 8;\nconst ANNOTATION_LINE_HEIGHT = 1.25;\n\ninterface Bbox {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport interface ExportOptions {\n /** Title used as the suggested filename / SVG <title>. */\n title?: string;\n /** Background fill (`'transparent'` skips the rect). Default white. */\n background?: string;\n /** Element label visibility. Mirrors `DiagramFile.meta.labelMode`. Default 'all'. */\n labelMode?: LabelMode;\n /** Free text annotations from `DiagramFile.annotations` — `InternalModel`\n * doesn't carry them, so the caller passes them through. */\n annotations?: TextAnnotation[];\n}\n\nexport function buildExportSvg(\n model: InternalModel,\n opts: ExportOptions = {},\n): string {\n const bbox = computeContentBbox(model, opts);\n const x = Math.floor(bbox.minX - PADDING);\n const y = Math.floor(bbox.minY - PADDING);\n const w = Math.ceil(bbox.maxX + PADDING) - x;\n const h = Math.ceil(bbox.maxY + PADDING) - y;\n const bg = opts.background ?? '#FFFFFF';\n\n const out: string[] = [];\n out.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n out.push(\n `<svg xmlns=\"${SVG_NS}\" viewBox=\"${x} ${y} ${w} ${h}\" width=\"${w}\" height=\"${h}\">`,\n );\n if (opts.title) out.push(` <title>${escapeXml(opts.title)}</title>`);\n if (bg !== 'transparent') {\n out.push(\n ` <rect x=\"${x}\" y=\"${y}\" width=\"${w}\" height=\"${h}\" fill=\"${bg}\"/>`,\n );\n }\n\n // Wires first (rendered behind elements).\n out.push(' <g fill=\"none\" stroke=\"black\" stroke-width=\"1\">');\n for (const r of model.wireRenders.values()) {\n if (r.path.length < 2) continue;\n const pts = r.path.map(([px, py]) => `${px},${py}`).join(' ');\n out.push(` <polyline points=\"${pts}\"/>`);\n }\n out.push(' </g>');\n\n // Buses.\n for (const { bus, geometry } of model.buses.values()) {\n const { axis, at, span } = geometry;\n const half = span / 2;\n const x1 = axis === 'x' ? at[0] - half : at[0];\n const y1 = axis === 'x' ? at[1] : at[1] - half;\n const x2 = axis === 'x' ? at[0] + half : at[0];\n const y2 = axis === 'x' ? at[1] : at[1] + half;\n out.push(\n ` <line id=\"${escapeXml(bus.id)}\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\" stroke=\"black\" stroke-width=\"3\" stroke-linecap=\"round\" fill=\"none\"/>`,\n );\n }\n\n // Devices.\n for (const re of model.elements.values()) {\n if (!re.libraryDef) continue;\n const place = model.layout.get(re.element.id);\n if (!place) continue;\n out.push(\n ` <g id=\"${escapeXml(re.element.id)}\" transform=\"${transformAttr(place)}\">`,\n );\n out.push(` ${re.libraryDef.svg}`);\n out.push(' </g>');\n }\n\n // Element structural labels (ID + showOnCanvas params). Matches\n // AnnotationLayer.tsx so the export reflects what users see on the canvas.\n // The halo (paint-order: stroke against the background color) keeps labels\n // readable when they cross wires or symbols.\n const labelMode: LabelMode = opts.labelMode ?? 'all';\n if (labelMode !== 'off') {\n const halo = bg === 'transparent' ? '#FFFFFF' : bg;\n out.push(\n ` <g fill=\"black\" font-family=\"ui-sans-serif, system-ui, sans-serif\" font-size=\"${LABEL_FONT_SIZE}\" paint-order=\"stroke\" stroke=\"${halo}\" stroke-width=\"2\" stroke-linejoin=\"round\">`,\n );\n for (const re of model.elements.values()) {\n const place = model.layout.get(re.element.id);\n if (!place || !re.libraryDef) continue;\n const lines = labelLines(re, labelMode);\n if (lines.length === 0) continue;\n const anchor = re.libraryDef.label ?? fallbackAnchor(re.libraryDef);\n const [ax, ay] = anchorWorld(anchor, place);\n const textAnchor = anchor.anchor ?? 'start';\n for (let i = 0; i < lines.length; i++) {\n out.push(\n ` <text x=\"${ax}\" y=\"${ay + i * LABEL_LINE_HEIGHT}\" text-anchor=\"${textAnchor}\">${escapeXml(lines[i])}</text>`,\n );\n }\n }\n out.push(' </g>');\n }\n\n // Free text annotations — independent notes the user dropped via the text\n // tool. Same positioning as FreeAnnotationLayer (baseline at at.y + fs*0.85,\n // step fs*LINE_HEIGHT per line).\n const anns = opts.annotations ?? [];\n if (anns.length > 0) {\n const halo = bg === 'transparent' ? '#FFFFFF' : bg;\n out.push(\n ` <g fill=\"black\" font-family=\"ui-sans-serif, system-ui, sans-serif\" paint-order=\"stroke\" stroke=\"${halo}\" stroke-width=\"2\" stroke-linejoin=\"round\">`,\n );\n for (const ann of anns) {\n if (!ann.text) continue;\n const fs = ann.fontSize ?? ANNOTATION_FONT_SIZE;\n const lines = ann.text.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const y = ann.at[1] + fs * 0.85 + i * fs * ANNOTATION_LINE_HEIGHT;\n out.push(\n ` <text x=\"${ann.at[0]}\" y=\"${y}\" font-size=\"${fs}\">${escapeXml(lines[i])}</text>`,\n );\n }\n }\n out.push(' </g>');\n }\n\n out.push('</svg>');\n return out.join('\\n');\n}\n\nfunction computeContentBbox(model: InternalModel, opts: ExportOptions): Bbox {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n const update = (x: number, y: number) => {\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n };\n\n for (const t of model.terminals.values()) update(t.world[0], t.world[1]);\n for (const re of model.elements.values()) {\n const place = model.layout.get(re.element.id);\n const lib = re.libraryDef;\n if (!place || !lib) continue;\n const vb = parseViewBox(lib.viewBox);\n if (!vb) {\n update(place.at[0], place.at[1]);\n continue;\n }\n const corners: Array<[number, number]> = [\n [vb.x, vb.y],\n [vb.x + vb.w, vb.y],\n [vb.x, vb.y + vb.h],\n [vb.x + vb.w, vb.y + vb.h],\n ];\n for (const c of corners) {\n const [wx, wy] = transformPoint(c, place);\n update(wx, wy);\n }\n }\n for (const { geometry } of model.buses.values()) {\n const { axis, at, span } = geometry;\n const half = span / 2;\n if (axis === 'x') {\n update(at[0] - half, at[1]);\n update(at[0] + half, at[1]);\n } else {\n update(at[0], at[1] - half);\n update(at[0], at[1] + half);\n }\n }\n for (const r of model.wireRenders.values()) {\n for (const [x, y] of r.path) update(x, y);\n }\n\n // Element labels — labels can extend past the symbol's viewBox, especially\n // multi-line ones with showOnCanvas params.\n const labelMode = opts.labelMode ?? 'all';\n if (labelMode !== 'off') {\n for (const re of model.elements.values()) {\n const place = model.layout.get(re.element.id);\n if (!place || !re.libraryDef) continue;\n const lines = labelLines(re, labelMode);\n if (lines.length === 0) continue;\n const anchor = re.libraryDef.label ?? fallbackAnchor(re.libraryDef);\n const [ax, ay] = anchorWorld(anchor, place);\n const w = textWidthGuess(lines, LABEL_FONT_SIZE);\n const h = lines.length * LABEL_LINE_HEIGHT;\n const align = anchor.anchor ?? 'start';\n const x0 = align === 'middle' ? ax - w / 2 : align === 'end' ? ax - w : ax;\n update(x0, ay - LABEL_FONT_SIZE);\n update(x0 + w, ay + h);\n }\n }\n\n // Free annotations — can sit anywhere on the canvas.\n for (const ann of opts.annotations ?? []) {\n if (!ann.text) continue;\n const fs = ann.fontSize ?? ANNOTATION_FONT_SIZE;\n const lines = ann.text.split('\\n');\n const w = textWidthGuess(lines, fs);\n const h = lines.length * fs * ANNOTATION_LINE_HEIGHT;\n update(ann.at[0], ann.at[1]);\n update(ann.at[0] + w, ann.at[1] + h);\n }\n\n if (minX === Infinity) {\n minX = 0;\n minY = 0;\n maxX = 0;\n maxY = 0;\n }\n return { minX, minY, maxX, maxY };\n}\n\nfunction textWidthGuess(lines: string[], fontSize: number): number {\n // Match the heuristic in FreeAnnotationLayer (~0.55em per char) so the\n // bbox tracks the on-screen selection halo.\n let max = 0;\n for (const l of lines) {\n const w = l.length * fontSize * 0.55;\n if (w > max) max = w;\n }\n return Math.max(20, max);\n}\n\nfunction parseViewBox(\n s: string,\n): { x: number; y: number; w: number; h: number } | null {\n const parts = s.trim().split(/\\s+/).map(Number);\n if (parts.length !== 4 || parts.some((n) => Number.isNaN(n))) return null;\n return { x: parts[0], y: parts[1], w: parts[2], h: parts[3] };\n}\n\nfunction escapeXml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\nexport async function downloadSvg(\n model: InternalModel,\n filename = 'diagram.svg',\n opts?: ExportOptions,\n): Promise<void> {\n const xml = buildExportSvg(model, opts);\n triggerDownload(\n new Blob([xml], { type: 'image/svg+xml;charset=utf-8' }),\n filename,\n );\n}\n\nexport async function downloadPng(\n model: InternalModel,\n filename = 'diagram.png',\n opts?: ExportOptions & { scale?: number },\n): Promise<void> {\n const xml = buildExportSvg(model, opts);\n const scale = opts?.scale ?? 2;\n\n const url = URL.createObjectURL(\n new Blob([xml], { type: 'image/svg+xml;charset=utf-8' }),\n );\n try {\n const img = await loadImage(url);\n const canvas = document.createElement('canvas');\n canvas.width = Math.round(img.naturalWidth * scale);\n canvas.height = Math.round(img.naturalHeight * scale);\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('canvas 2d context unavailable');\n if (opts?.background && opts.background !== 'transparent') {\n ctx.fillStyle = opts.background;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n const blob: Blob = await new Promise((resolve, reject) => {\n canvas.toBlob((b) => (b ? resolve(b) : reject(new Error('toBlob failed'))), 'image/png');\n });\n triggerDownload(blob, filename);\n } finally {\n URL.revokeObjectURL(url);\n }\n}\n\nfunction loadImage(src: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error('failed to load SVG into image'));\n img.src = src;\n });\n}\n\nfunction triggerDownload(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = filename;\n anchor.click();\n URL.revokeObjectURL(url);\n}\n","/**\n * Export menu — render the current diagram to SVG or PNG and trigger a\n * download. Reads the InternalModel from the store so the file matches what\n * the canvas shows minus UI chrome (selection halos, terminal hit rects,\n * etc.). Exported alongside `FileMenu` for embedding apps.\n */\n\nimport { Download, FileBox, FileImage, FileType } from 'lucide-react';\nimport { useEffect, useRef, useState } from 'react';\nimport { Button } from './ui/button';\nimport { useT } from '../i18n';\nimport { downloadDxf } from '../lib/export-dxf';\nimport { downloadPng, downloadSvg } from '../lib/export-image';\nimport { useEditorStore } from '../store';\n\nexport function ExportMenu() {\n const t = useT();\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\n const onClick = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false);\n };\n window.addEventListener('mousedown', onClick);\n window.addEventListener('keydown', onKey);\n return () => {\n window.removeEventListener('mousedown', onClick);\n window.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const exportAs = (kind: 'svg' | 'png' | 'dxf') => () => {\n setOpen(false);\n const { internal, diagram, fileSession } = useEditorStore.getState();\n const baseName =\n fileSession?.name?.replace(/\\.json$/i, '') ?? diagram.meta?.title ?? 'diagram';\n const opts = {\n title: diagram.meta?.title,\n labelMode: diagram.meta?.labelMode,\n annotations: diagram.annotations,\n };\n if (kind === 'svg') downloadSvg(internal, `${baseName}.svg`, opts);\n else if (kind === 'png')\n downloadPng(internal, `${baseName}.png`, { ...opts, scale: 2 }).catch((err) => {\n console.error(err);\n alert(t('topbar.export.pngFailed', { err: (err as Error).message }));\n });\n else\n downloadDxf(internal, `${baseName}.dxf`, opts).catch((err) => {\n console.error(err);\n alert(t('topbar.export.dxfFailed', { err: (err as Error).message }));\n });\n };\n\n return (\n <div ref={ref} className=\"relative\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1.5\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={() => setOpen((v) => !v)}\n >\n <Download />\n {t('topbar.export.label')}\n </Button>\n {open && (\n <div\n role=\"menu\"\n className=\"ole-glass absolute left-0 top-full mt-1.5 min-w-40 rounded-md border border-border p-1 shadow-md\"\n >\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={exportAs('svg')}\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4\"\n >\n <FileType />\n <span className=\"flex-1\">SVG</span>\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={exportAs('png')}\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4\"\n >\n <FileImage />\n <span className=\"flex-1\">PNG (2×)</span>\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n onClick={exportAs('dxf')}\n className=\"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent hover:text-accent-foreground [&>svg]:size-4\"\n >\n <FileBox />\n <span className=\"flex-1\">DXF</span>\n </button>\n </div>\n )}\n </div>\n );\n}\n"],"names":["toKebabCase","string","mergeClasses","classes","className","index","array","defaultAttributes","Icon","forwardRef","color","size","strokeWidth","absoluteStrokeWidth","children","iconNode","rest","ref","createElement","tag","attrs","createLucideIcon","iconName","Component","props","Cable","ChevronDown","Clipboard","Copy","Download","Ellipsis","FileBox","FileImage","FilePlus","FileType","FlipHorizontal","FolderOpen","Grid2x2","Hand","LayoutGrid","ListTree","Maximize2","Minus","MousePointer2","PanelBottomClose","Plus","Redo2","RotateCw","Save","Scissors","Search","Shapes","Spline","SquareDashed","Trash2","Type","Undo2","WandSparkles","X","r","f","n","o","clsx","CLASS_PART_SEPARATOR","createClassGroupUtils","config","classMap","createClassMap","conflictingClassGroups","conflictingClassGroupModifiers","classParts","getGroupRecursive","getGroupIdForArbitraryProperty","classGroupId","hasPostfixModifier","conflicts","classPartObject","currentClassPart","nextClassPartObject","classGroupFromNextClassPart","classRest","_a","validator","arbitraryPropertyRegex","arbitraryPropertyClassName","property","theme","prefix","getPrefixedClassGroupEntries","classGroup","processClassesRecursively","classDefinition","classPartObjectToEdit","getPart","isThemeGetter","key","path","currentClassPartObject","pathPart","func","classGroupEntries","prefixedClassGroup","value","createLruCache","maxCacheSize","cacheSize","cache","previousCache","update","IMPORTANT_MODIFIER","createParseClassName","separator","experimentalParseClassName","isSeparatorSingleCharacter","firstSeparatorCharacter","separatorLength","parseClassName","modifiers","bracketDepth","modifierStart","postfixModifierPosition","currentCharacter","baseClassNameWithImportantModifier","hasImportantModifier","baseClassName","maybePostfixModifierPosition","sortModifiers","sortedModifiers","unsortedModifiers","modifier","createConfigUtils","SPLIT_CLASSES_REGEX","mergeClassList","classList","configUtils","getClassGroupId","getConflictingClassGroupIds","classGroupsInConflict","classNames","result","originalClassName","variantModifier","modifierId","classId","conflictGroups","i","group","twJoin","argument","resolvedValue","toValue","mix","k","createTailwindMerge","createConfigFirst","createConfigRest","cacheGet","cacheSet","functionToCall","initTailwindMerge","previousConfig","createConfigCurrent","tailwindMerge","cachedResult","fromTheme","themeGetter","arbitraryValueRegex","fractionRegex","stringLengths","tshirtUnitRegex","lengthUnitRegex","colorFunctionRegex","shadowRegex","imageRegex","isLength","isNumber","isArbitraryLength","getIsArbitraryValue","isLengthOnly","isArbitraryNumber","isInteger","isPercent","isArbitraryValue","isTshirtSize","sizeLabels","isArbitrarySize","isNever","isArbitraryPosition","imageLabels","isArbitraryImage","isImage","isArbitraryShadow","isShadow","isAny","label","testValue","getDefaultConfig","colors","spacing","blur","brightness","borderColor","borderRadius","borderSpacing","borderWidth","contrast","grayscale","hueRotate","invert","gap","gradientColorStops","gradientColorStopPositions","inset","margin","opacity","padding","saturate","scale","sepia","skew","space","translate","getOverscroll","getOverflow","getSpacingWithAutoAndArbitrary","getSpacingWithArbitrary","getLengthWithEmptyAndArbitrary","getNumberWithAutoAndArbitrary","getPositions","getLineStyles","getBlendModes","getAlign","getZeroAndEmpty","getBreaks","getNumberAndArbitrary","twMerge","cn","inputs","Ctx","createContext","useContextMenu","api","useContext","VIEWPORT_PAD","ContextMenuHost","state","setState","useState","clamped","setClamped","useRef","close","useCallback","s","open","x","y","items","useMemo","useLayoutEffect","left","top","useEffect","onPointerDown","e","onKey","onWheel","onBlur","jsxs","jsx","entry","createStoreImpl","createState","listeners","partial","replace","nextState","previousState","listener","getState","initialState","createStore","identity","arg","useStore","selector","slice","React","createImpl","useBoundStore","create","messages","STORAGE_KEY","readInitial","raw","persist","loc","useLocale","set","get","locale","next","format","tmpl","params","_","lookup","t","useT","createJSONStorage","getStorage","options","storage","name","parse","str2","str","newValue","toThenable","fn","input","onFulfilled","_onRejected","_onFulfilled","onRejected","persistImpl","baseOptions","persistedState","currentState","hasHydrated","hydrationVersion","hydrationListeners","finishHydrationListeners","args","setItem","savedSetState","configResult","stateFromStorage","hydrate","_b","currentVersion","cb","_a2","postRehydrationCallback","deserializedStorageValue","migration","migrationResult","migrated","migratedState","newOptions","EPS","normalizePath","p","dedup","last","orthog","prev","cur","dx","dy","corner","out","sameX","sameY","emptyInternalModel","resolvePlacement","busAxisFromRot","rot","transformPoint","local","ROT_NEXT","MIRROR_X","transformOrientation","steps","orientationVec","UnionFind","__publicField","gp","a","b","ra","rb","da","db","root","arr","ORIENT_CYCLE","OPPOSITE_ORIENT","rotationToAlignOrient","localO","worldO","li","BUS_X","BUS_Y0","MIN_BUS_GAP_Y","DEFAULT_BUS_SPAN","CHAIN_GAP","BUS_TAP_OFFSET","MIN_TAP_SPACING","GRID","FALLBACK_GRID_X0","FALLBACK_GRID_Y0","FALLBACK_GRID_DX","FALLBACK_GRID_DY","FALLBACK_GRID_COLS","SOURCE_CATEGORIES","autoLayout","elements","busList","wires","library","userLayout","userBusLayout","layout","busLayout","elementById","el","busById","libOf","id","busIds","isBus","end","uf","lib","bus","nodeGroups","members","pinToGroups","m","effectiveTaps","busMembers","busMember","others","tapsByElement","dot","elId","pin","busId","linkers","linkerIds","attachments","orientation","refAdj","addRefEdge","refs","j","myRefs","busesPerPin","startRef","startPin","forbidden","visited","queue","neighbors","nb","distinctBuses","buses","reachesSourceBypassing","startBusId","linkerId","linkerLib","blocked","elemId","cat","link","busesInLink","reachable","bid","busPerPin","nbDot","nbElemId","nbEl","nbLib","busLinks","ids","_c","isSourceKind","kind","rootBuses","otherId","otherEl","busLevel","bfsQ","lvl","links","childLevel","maxLvl","levelToBuses","sortedLevels","chainExtentToBus","linker","pinName","targetRef","parent","enqueue","other","addDist","dist","head","d","headId","thisTerm","otherTerm","otherRef","g","isBusEdge","gapBetween","idA","idB","pinAName","pinBName","pinA","pinB","pinSpan","upperChain","lowerChain","linkerUpperRep","sortedAttachments","upperBusId","lowerBusId","upperPin","repElId","BUS_MIN_SPAN","busSpan","isLinkerLowerSide","l","otherBusAtt","myLvl","slotWidthFor","libWidth","rep","childSpan","computeSpan","visiting","tapRefs","aboveW","belowW","localTerm","slotW","span","linkerSlotX","tapPreferredX","tapEl","tapPin","tapLib","tapRef","startRefs","geom","distributeBusTaps","remaining","aboveSide","belowSide","sideTotalWidth","requiredSpan","finalGeom","distribute","offsetSign","prefByEl","px","ax","bx","aw","widths","totalW","w","usableSpan","slotGap","cursor","tapWorldY","tapWorldX","snap","placeLinker","placedAttachments","sorted","upperGeom","lowerPin","upperLocal","lowerLocal","upperLevel","upperSideAttachments","upperHeadXs","maxUpperExtent","att","headPlace","xCenter","upperPinWorldY","at","linkerPlace","upperPinWorld","upperWorldOrient","walkChainAlongAxis","startWorld","startExit","axisX","prevRef","prevWorld","prevExit","groups","nextRef","inTerm","exitVec","target","desiredOrient","rotatedInPin","outTerm","outRef","placement","placeHorizontalLinker","placed","heads","right","leftLocal","rightLocal","linkerY","SIBLING_X_GAP","prevLevelY","busIdsAtLevel","levelY","prevBusIds","maxGap","child","_d","nextSiblingX","busX","headXs","_e","parentPin","_f","ownSpan","isEndPlaced","progressed","safety","node","placedPins","unplacedByEl","unplacedUnique","votes","u","tref","anchor","best","v","anchorId","anchorPin","anchorLib","anchorPlace","anchorTerm","anchorWorld","anchorOrient","exit","perp","sum","slotCenter","rotatedPin","targetWorld","placedCount","col","row","routeWire","wire","model","aBus","bBus","otherWorld","endWorld","axis","half","clamp","orthogonalPath","bw","term","wireEndWorld","approach","lo","hi","modules","__vite_glob_0_0","__vite_glob_0_1","__vite_glob_0_2","__vite_glob_0_3","__vite_glob_0_4","__vite_glob_0_5","__vite_glob_0_6","__vite_glob_0_7","__vite_glob_0_8","__vite_glob_0_9","__vite_glob_0_10","__vite_glob_0_11","__vite_glob_0_12","__vite_glob_0_13","__vite_glob_0_14","__vite_glob_0_15","__vite_glob_0_16","__vite_glob_0_17","__vite_glob_0_18","__vite_glob_0_19","__vite_glob_0_20","__vite_glob_0_21","__vite_glob_0_22","__vite_glob_0_23","__vite_glob_0_24","__vite_glob_0_25","__vite_glob_0_26","__vite_glob_0_27","__vite_glob_0_28","__vite_glob_0_29","__vite_glob_0_30","__vite_glob_0_31","__vite_glob_0_32","__vite_glob_0_33","__vite_glob_0_34","__vite_glob_0_35","__vite_glob_0_36","__vite_glob_0_37","__vite_glob_0_38","__vite_glob_0_39","__vite_glob_0_40","__vite_glob_0_41","__vite_glob_0_42","__vite_glob_0_43","__vite_glob_0_44","__vite_glob_0_45","__vite_glob_0_46","libraryEntries","libraryById","CATEGORY_ORDER","libraryByCategory","LIBRARY","getLibraryEntry","deterministicNodeId","text","h","compile","diagram","idx","libDef","validEnd","pointer","re","avail","validWires","layoutResult","place","lt","world","stored","approachA","approachB","endA","endB","rebased","cleaned","PREFIX","BUS_PREFIX","usedIds","newElementId","used","newBusId","newAnnotationId","wireIdFromEnds","EMPTY_DIAGRAM","HISTORY_LIMIT","PASTE_OFFSET","defaultTool","useEditorStore","fileSession","mutator","past","trimmed","future","tool","opts","placeKind","pt","dedupe","sel","nodeId","selection","internal","placements","explicit","resolved","compactPlacement","busLayouts","compactBusLayout","endOwner","clipboard","clipboardPasteIndex","step","idMap","working","newId","remapEnd","remapped","newElements","cloned","newBuses","newLayout","oldId","newWires","ends","mergeWires","hasDeviceLayout","hasBusLayout","_layout","_bl","bRest","drop","changed","additions","busesNeedLayout","busesPatch","deltas","busPatches","delta","base","selectedWire","wireObj","affectedElementIds","selectedNode","memberSet","deltaDegrees","extra","newElement","existing","valid","nextWires","_drop","patch","nextPlacement","ann","list","seen","rp","current","setViewportApi","getViewportApi","GRID_SIZE","isSnapEnabled","PROXIMITY_PX","CLICK_SLOP_SQ","dropElement","store","nearestBus","cursorPin","pickPlaceCursorTerminal","placedAt","busAt","pickTapTerminal","tapLocal","dropX","dropY","newEnd","minX","maxX","minY","maxY","busAxis","resolvePlaceSource","cursorWorld","OPPOSITE","pickConnectTerminal","source","placeAt","wantOrient","opposites","pool","bestDist","termWorldDist","dropElementFromTerminal","sourceRef","cursorAt","treatAsClick","cursorPlaceAt","chosen","newPinRef","tieEnd","LABEL_LINE_HEIGHT","LABEL_FONT_SIZE","labelLines","mode","lines","fallbackAnchor","vb","parseViewBox","parts","AnnotationLayer","editingElement","textAnchor","NameEditor","line","LINE_HEIGHT","EDITOR_W","EDITOR_FS","elementId","currentName","range","commit","onKeyDown","DEFAULT_FONT_SIZE","FreeAnnotationLayer","annotations","selected","editing","EditingAnnotation","IdleAnnotation","isSelected","fs","widthGuess","heightGuess","MIN_SPAN","BusHandles","Handle","side","viewport","dragRef","onPointerMove","drag","dRaw","onPointerUp","segAxis","WireHandles","wireRenders","render","vertexHandles","prevAxis","nextAxis","prevEndpoint","nextEndpoint","xLocked","yLocked","VertexHandle","midHandles","MidpointHandle","wireId","cx","cy","sp","orig","newPos","finishDrag","onDoubleClick","removed","segIndex","seg","segA","segB","built","newY","newX","STROKE_WIDTH","HIT_WIDTH","BusLayer","nodes","terminalToNode","selSet","nodeRelatedBuses","geometry","x1","y1","x2","y2","isNodeRelated","hitHalf","hx","hy","hw","hh","BusbarPreview","start","horizontal","endX","endY","transformAttr","HitRect","bb","ElementLayer","nodeRelated","publishMarquee","rect","getMarquee","subscribeMarquee","MarqueeOverlay","setRect","PlaceGhost","fromRef","connect","ghostX","ghostY","Fragment","SelectionOverlay","TerminalLayer","terminals","wireFrom","selectionSet","connected","isOrigin","onSelected","WireLayer","wireToNode","points","isWireSelected","isNodeSelected","publishWireTarget","getWireTarget","subscribeWireTarget","WirePreview","setTarget","fromWorld","ancestor","attr","hitElement","hitBus","hitTerminal","direct","hitNode","hitWire","hitAnnotation","dispatchSyntheticPointerCancel","host","pointerId","isEditing","exitDrawingState","ed","useKeyboardShortcuts","mod","publishHoverElement","getHoverElement","subscribeHoverElement","C_HOST","C_TERM","C_NODE","useHoverHighlight","hostRef","lastElement","lastNode","markedTerminals","markedNodeMembers","clearAndMark","cls","updateElementHover","cssEscape","terms","updateNodeHover","terminal","onPointerLeave","resolveWireTarget","MARQUEE_THRESHOLD","marquee","wireDrag","annDrag","SelectTool","ctx","annId","termRef","targets","originals","tid","under","rectFromPoints","from","hit","elementsInRect","baseSet","hits","corners","transformLocalCorner","TAP_THRESHOLD_PX","pan","PanTool","vp","startId","elementDrag","ddx","ddy","handlePanTap","BREAKPOINTS","RANK","atLeast","min","tierForWidth","TierContext","useEditorTier","useObservedWidth","width","setWidth","apply","ro","isPhoneUx","exitToPanOnPhone","disarmPlaceOnPhone","WireTool","sf","disarmOnUp","scheduleDisarm","PlaceTool","MIN_LEN","BusbarTool","TextTool","TOOLS","useTools","activeTool","onDown","onMove","onUp","onCancel","onLeave","onDbl","publishScale","getScale","subscribeScale","MIN_SCALE","MAX_SCALE","ZOOM_FACTOR_WHEEL","ZOOM_FACTOR_PINCH","useViewport","groupRef","initial","snapshot","panning","panPointerId","panStartX","panStartY","panStartTx","panStartTy","spaceDown","touches","pinch","touchHijack","recomputePinchBaseline","pts","onTouchPointerDownCap","onTouchPointerMoveCap","midX","midY","ratio","onTouchPointerUpCap","isPinch","isMiddle","isSpaceLeft","onKeyUp","clientX","clientY","IS_MAC","MOD","SHIFT","GRID_STEPS","MIN_SCREEN_STEP","pickGridStep","CanvasSvg","gridPatternRef","sync","screenStep","contextMenu","openContextMenuAt","hasSelection","hasNodeSelection","hasClipboard","hasAnyElement","BoxSelect","st","LONG_PRESS_MS","LONG_PRESS_MOVE_PX","timer","data","cancel","onEnd","onDragOver","onDrop","onContextMenu","FIT_PADDING_PX","READY_RETRY_FRAMES","getCanvasRoot","fitToContent","ay","by","contentW","contentH","targetScale","fitToContentSoon","frames","tick","GAP_PX","SHOW_DELAY_MS","isCoarsePointer","ElementHoverLabel","hoverId","setHoverId","shown","setShown","setAnchor","labelRef","showTimer","coarse","elementName","raf","lastTop","lastLeft","tip","display","subtitle","showId","createPortal","EditorTierProvider","tier","setRef","composeRefs","hasCleanup","cleanups","cleanup","REACT_LAZY_TYPE","use","isPromiseLike","isLazyComponent","element","createSlot","ownerName","SlotClone","createSlotClone","Slot2","forwardedRef","slotProps","childrenArray","slottable","isSlottable","newChildren","Slot","childrenRef","getElementRef","props2","mergeProps","SLOTTABLE_IDENTIFIER","childProps","overrideProps","propName","slotPropValue","childPropValue","getter","mayWarn","falsyToString","cva","_config_compoundVariants","variants","defaultVariants","getVariantClassNames","variant","variantProp","defaultVariantProp","variantKey","propsWithoutUndefined","acc","param","getCompoundVariantClassNames","cvClass","cvClassName","compoundVariantOptions","buttonVariants","Button","asChild","Comp","Tooltip","content","disabled","delayMs","triggerRef","tooltipRef","setOpen","useId","scheduleShow","cancelShow","onScroll","wrappedTrigger","cloneElement","TOP_FLIP_THRESHOLD_PX","ContextualToolbar","rotate","mirror","del","delNode","delWire","resetWirePath","wireIsManual","isElementMode","isWireMode","isNodeMode","lastTransform","bottom","any","accept","ty","translateY","transform","hideTransform","UpwardPopover","onOpenChange","trigger","onClick","obj","usePanels","outlineOpen","ZOOM_STEPS","GRID_STORAGE_KEY","readGrid","writeGrid","zoomTo","zoomIn","z","zoomOut","LABEL_CYCLE","cycleLabelMode","meta","useGridState","grid","setGrid","ZoomOutBtn","ZoomInBtn","ZoomDisplayBtn","setScale","FitBtn","GridBtn","LabelBtn","labelMode","ViewMenuButton","stacked","menuOpen","setMenuOpen","tipContent","triggerBtn","MoreHorizontal","ViewToolbar","ViewToolbarExpanded","hidePercentPill","ToolHint","active","placeFrom","busbarStart","cancelHint","cancelText","FloatingToolbar","setTool","undo","redo","forceIconOnly","showHint","unifiedBar","visibleTools","def","isToolActive","OutlineToggleButton","isActive","ToolbarButton","OverflowMenuButton","LayoutMenuButton","toggle","hotkey","iconOnly","description","useLayoutActions","run","action","Wand2","PopoverItem","icon","LeftPanel","OutlinePanel","CollapsedTab","compact","onClose","sheet","libraryOpen","dense","height","CountChip","OutlineRow","setSelection","toggleInSelection","zh","en","tables","useLibT","fallback","PALETTE_COLLAPSE_STORAGE_KEY","PALETTE_HIDDEN_IDS","PALETTE_BY_CATEGORY","entries","visible","CATEGORY_IDS","known","extras","c","readPaletteCollapsed","writePaletteCollapsed","LibraryPopover","TOP_INSET","maxHeight","wrapperStyle","LibraryBody","libT","query","setQuery","collapsed","setCollapsed","filteredByCat","q","desc","isSearching","noMatch","handleToggle","catId","isOpen","SearchBox","total","ElementRow","onChange","armed","recent","onDragStart","ghost","dismissed","useOnboarding","OnboardingCard","dismiss","Step","title","body","PropertyPanel","WirePanel","NodePanel","BusInspector","TextRow","TextAreaRow","field","StateField","ParamsSection","schema","schemaKeys","SchemaParamField","ParamField","onCommit","Field","ToggleButton","NumberRow","fieldKey","onName","updateBusEntry","BusParams","setSelectedNode","elemById","describeEnd","byElement","eId","elById","pins","placeholder","unit","setLocal","RightPanel","compactWidth","count","useFocusGuards","onMouseDown","btn","onCanvasPointerDown","EditorShell","rootRef","readStored","systemPrefersDark","getInitialTheme","applyTheme","OneLineEditor","ACCEPT","supportsFsa","isAbort","parseDiagram","serialize","openDiagram","handle","file","resolve","reject","saveDiagram","session","writable","url","FileMenu","fileLabel","onNew","onOpen","onSave","onSaveAs","useFileActions","handler","MenuItem","hint","loadDiagramFromFile","setFileSession","setDiagram","LAYER_WIRES","LAYER_ELEMENTS","LAYER_LABELS","LAYER_ANNOTATIONS","ARC_SAMPLES","ELLIPSE_SAMPLES","ANNOTATION_FONT_SIZE","ANNOTATION_LINE_HEIGHT","TEXT_FONT_SIZE_DEFAULT","buildExportDxf","DxfWriter","worldToDxf","emitLibrarySvg","downloadDxf","filename","dxf","svg","wrapped","emitLine","emitPoly","emitRect","emitCircle","emitEllipse","emitPath","emitText","numAttr","localToWorld","closed","parsePoints","ww","center","rx","ry","emitCircleRaw","sampleEllipse","txt","cmds","tokenizePath","pen","buffer","flush","large","sweep","arc","arcEndpointToCenter","cmd","nums","p1","p2","largeArc","x1p","y1p","RX","RY","r2x","r2y","lambda","sign","num","den","coef","cxp","cyp","angle","ux","uy","vx","vy","len","theta1","precision","code","sanitizeText","layers","layer","radius","rotationDeg","mirrorX","SVG_NS","PADDING","buildExportSvg","bbox","computeContentBbox","bg","escapeXml","py","halo","anns","wx","wy","textWidthGuess","align","x0","fontSize","max","downloadSvg","xml","triggerDownload","downloadPng","img","loadImage","canvas","blob","src","ExportMenu","exportAs","baseName","err"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43,46,100,101,102]}