@coopcli/specplan 5.5.2 → 5.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.react-flow{--xy-edge-stroke-default:#b1b1b7;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#555;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#ffffff80;--xy-minimap-background-color-default:#fff;--xy-minimap-mask-background-color-default:#f0f0f099;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#e2e2e2;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:transparent;--xy-background-pattern-dots-color-default:#91919a;--xy-background-pattern-lines-color-default:#eee;--xy-background-pattern-cross-color-default:#e2e2e2;background-color:var(--xy-background-color,var(--xy-background-color-default));--xy-node-color-default:inherit;--xy-node-border-default:1px solid #1a192b;--xy-node-background-color-default:#fff;--xy-node-group-background-color-default:#f0f0f040;--xy-node-boxshadow-hover-default:0 1px 4px 1px #00000014;--xy-node-boxshadow-selected-default:0 0 0 .5px #1a192b;--xy-node-border-radius-default:3px;--xy-handle-background-color-default:#1a192b;--xy-handle-border-color-default:#fff;--xy-selection-background-color-default:#0059dc14;--xy-selection-border-default:1px dotted #0059dccc;--xy-controls-button-background-color-default:#fefefe;--xy-controls-button-background-color-hover-default:#f4f4f4;--xy-controls-button-color-default:inherit;--xy-controls-button-color-hover-default:inherit;--xy-controls-button-border-color-default:#eee;--xy-controls-box-shadow-default:0 0 2px 1px #00000014;--xy-edge-label-background-color-default:#fff;--xy-edge-label-color-default:inherit;--xy-resize-background-color-default:#3367d9;direction:ltr}.react-flow.dark{--xy-edge-stroke-default:#3e3e3e;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#727272;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#96969640;--xy-minimap-background-color-default:#141414;--xy-minimap-mask-background-color-default:#3c3c3c99;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#2b2b2b;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:#141414;--xy-background-pattern-dots-color-default:#555;--xy-background-pattern-lines-color-default:#333;--xy-background-pattern-cross-color-default:#333;--xy-node-color-default:#f8f8f8;--xy-node-border-default:1px solid #3c3c3c;--xy-node-background-color-default:#1e1e1e;--xy-node-group-background-color-default:#f0f0f040;--xy-node-boxshadow-hover-default:0 1px 4px 1px #ffffff14;--xy-node-boxshadow-selected-default:0 0 0 .5px #999;--xy-handle-background-color-default:#bebebe;--xy-handle-border-color-default:#1e1e1e;--xy-selection-background-color-default:#c8c8dc14;--xy-selection-border-default:1px dotted #c8c8dccc;--xy-controls-button-background-color-default:#2b2b2b;--xy-controls-button-background-color-hover-default:#3e3e3e;--xy-controls-button-color-default:#f8f8f8;--xy-controls-button-color-hover-default:#fff;--xy-controls-button-border-color-default:#5b5b5b;--xy-controls-box-shadow-default:0 0 2px 1px #00000014;--xy-edge-label-background-color-default:#141414;--xy-edge-label-color-default:#f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props,var(--xy-background-color,var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__pane{z-index:1;touch-action:none}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width,var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke,var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width,var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{pointer-events:none;position:absolute;overflow:visible}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:.5s linear infinite dashdraw}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected,var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:.5s linear infinite dashdraw}svg.react-flow__connectionline{z-index:1001;position:absolute;overflow:visible}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{-webkit-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default;position:absolute}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:0 0;pointer-events:none}.react-flow__nodesselection-rect{pointer-events:all;cursor:grab;position:absolute}.react-flow__handle{pointer-events:none;background-color:var(--xy-handle-background-color,var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color,var(--xy-handle-border-color-default));border-radius:100%;width:6px;min-width:5px;height:6px;min-height:5px;position:absolute}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;bottom:0;left:50%;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{z-index:5;margin:15px;position:absolute}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px)translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px)translateY(-50%)}.react-flow__attribution{background:var(--xy-attribution-background-color,var(--xy-attribution-background-color-default));margin:0;padding:2px 3px;font-size:10px}.react-flow__attribution a{color:#999;text-decoration:none}@keyframes dashdraw{0%{stroke-dashoffset:10px}}.react-flow__edgelabel-renderer{pointer-events:none;-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__viewport-portal{-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__minimap{background:var(--xy-minimap-background-color-props,var(--xy-minimap-background-color,var(--xy-minimap-background-color-default)))}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var(--xy-minimap-mask-background-color-props,var(--xy-minimap-mask-background-color,var(--xy-minimap-mask-background-color-default)));stroke:var(--xy-minimap-mask-stroke-color-props,var(--xy-minimap-mask-stroke-color,var(--xy-minimap-mask-stroke-color-default)));stroke-width:var(--xy-minimap-mask-stroke-width-props,var(--xy-minimap-mask-stroke-width,var(--xy-minimap-mask-stroke-width-default)))}.react-flow__minimap-node{fill:var(--xy-minimap-node-background-color-props,var(--xy-minimap-node-background-color,var(--xy-minimap-node-background-color-default)));stroke:var(--xy-minimap-node-stroke-color-props,var(--xy-minimap-node-stroke-color,var(--xy-minimap-node-stroke-color-default)));stroke-width:var(--xy-minimap-node-stroke-width-props,var(--xy-minimap-node-stroke-width,var(--xy-minimap-node-stroke-width-default)))}.react-flow__background-pattern.dots{fill:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-dots-color-default)))}.react-flow__background-pattern.lines{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-lines-color-default)))}.react-flow__background-pattern.cross{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-cross-color-default)))}.react-flow__controls{box-shadow:var(--xy-controls-box-shadow,var(--xy-controls-box-shadow-default));flex-direction:column;display:flex}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{background:var(--xy-controls-button-background-color,var(--xy-controls-button-background-color-default));border:none;border-bottom:1px solid var(--xy-controls-button-border-color-props,var(--xy-controls-button-border-color,var(--xy-controls-button-border-color-default)));width:26px;height:26px;color:var(--xy-controls-button-color-props,var(--xy-controls-button-color,var(--xy-controls-button-color-default)));cursor:pointer;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;padding:4px;display:flex}.react-flow__controls-button svg{fill:currentColor;width:100%;max-width:12px;max-height:12px}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{border-radius:var(--xy-node-border-radius,var(--xy-node-border-radius-default));width:150px;color:var(--xy-node-color,var(--xy-node-color-default));text-align:center;border:var(--xy-node-border,var(--xy-node-border-default));background-color:var(--xy-node-background-color,var(--xy-node-background-color-default));padding:10px;font-size:12px}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover,var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected,var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color,var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color,var(--xy-selection-background-color-default));border:var(--xy-selection-border,var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var(--xy-controls-button-border-color-props,var(--xy-controls-button-border-color,var(--xy-controls-button-border-color-default)))}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{background-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border:1px solid #fff;border-radius:1px;width:5px;height:5px;translate:-50% -50%}.react-flow__resize-control.handle.left{top:50%;left:0}.react-flow__resize-control.handle.right{top:50%;left:100%}.react-flow__resize-control.handle.top{top:0;left:50%}.react-flow__resize-control.handle.bottom{top:100%;left:50%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border-style:solid;border-width:0}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;height:100%;top:0;transform:translate(-50%)}.react-flow__resize-control.line.left{border-left-width:1px;left:0}.react-flow__resize-control.line.right{border-right-width:1px;left:100%}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{width:100%;height:1px;left:0;transform:translateY(-50%)}.react-flow__resize-control.line.top{border-top-width:1px;top:0}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color,var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color,var(--xy-edge-label-color-default))}:root{--bg:#0f0f0f;--panel:#1a1a1a;--border:#2a2a2a;--text:#e8e8e8;--muted:#888;--accent:#e8925b;--accent-hover:#f0a873;--accent-2:#28c840;--danger:#ff5f57;--ff-mono:"SF Mono", "Fira Code", "Cascadia Code", ui-monospace, Menlo, Consolas, monospace}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{font-family:var(--ff-mono);color:var(--text);background:var(--bg)}.app{flex-direction:column;height:100%;display:flex}.topbar{border-bottom:1px solid var(--border);background:var(--panel);justify-content:space-between;align-items:center;gap:16px;padding:10px 16px;display:flex}.brand{align-items:center;gap:12px;display:flex}.logo{color:var(--accent);font-size:26px}.brand h1{letter-spacing:.2px;margin:0;font-size:16px;font-weight:700}.brand-coop{color:var(--accent);font-weight:800}.brand p{color:var(--muted);margin:2px 0 0;font-size:12px}.actions{align-items:center;gap:10px;display:flex}.title-input{background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:8px;width:240px;padding:8px 12px;font-size:13px}.title-input:focus{border-color:var(--accent);outline:none}.model-select{background:var(--bg);border:1px solid var(--border);color:var(--muted);font-size:12px;font-family:var(--ff-mono);cursor:pointer;border-radius:8px;padding:8px 10px}.model-select:focus{border-color:var(--accent);color:var(--text);outline:none}.generate{background:var(--accent);color:var(--bg);cursor:pointer;border:none;border-radius:8px;padding:9px 16px;font-size:13px;font-weight:600}.generate:hover:not(:disabled){background:var(--accent-hover)}.generate:disabled{opacity:.6;cursor:default}.boot{height:100%;color:var(--muted);justify-content:center;align-items:center;font-size:14px;display:flex}.canvas-id{font-family:var(--ff-mono);color:var(--accent-2);font-size:11px}.view-toggle{border:1px solid var(--border);border-radius:8px;gap:0;display:flex;overflow:hidden}.toggle{color:var(--muted);cursor:pointer;background:0 0;border:none;padding:8px 18px;font-size:13px}.toggle.active{color:var(--text);background:#e8925b33}.toggle:disabled{opacity:.45;cursor:not-allowed}.copy-link{border:1px solid var(--border);color:var(--muted);cursor:pointer;white-space:nowrap;background:0 0;border-radius:8px;padding:8px 12px;font-size:12px}.copy-link:hover{color:var(--text);border-color:var(--accent)}.workspace,.spec-view{flex:1;min-height:0;display:flex}.tree{border-right:1px solid var(--border);background:var(--panel);width:320px;padding:12px;overflow-y:auto}.tree-head{border-bottom:1px solid var(--border);margin-bottom:12px;padding:4px 6px 12px}.tree-change{font-family:var(--ff-mono);color:var(--accent);font-size:13px;font-weight:600}.tree-summary{color:var(--muted);margin:8px 0 0;font-size:12px;line-height:1.5}.tree-group{margin-bottom:14px}.tree-group-name{text-transform:uppercase;letter-spacing:.08em;color:var(--muted);padding:4px 6px;font-size:11px}.tree-item{text-align:left;cursor:pointer;width:100%;color:var(--text);background:0 0;border:1px solid #0000;border-radius:6px;padding:6px 8px;display:block}.tree-item:hover{border-color:var(--border)}.tree-item.active{border-color:var(--accent);background:#e8925b26}.tree-label{font-family:var(--ff-mono);font-size:12px;display:block}.tree-path{color:var(--accent-2);font-size:10.5px;font-family:var(--ff-mono);text-overflow:ellipsis;white-space:nowrap;margin-top:2px;display:block;overflow:hidden}.reader{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.reader .artifact-body{max-width:900px}.canvas{flex:1;min-width:0;min-height:0;position:relative}.canvas :where(.excalidraw){height:100%}.panel{border-left:1px solid var(--border);background:var(--panel);flex-direction:column;width:420px;min-height:0;display:flex}.pane-collapse{border:none;border-bottom:2px solid #0000;border-left:1px solid var(--border);color:var(--muted);font-size:12px;font-family:var(--ff-mono);cursor:pointer;background:0 0;flex:none;padding:10px 12px}.pane-collapse:hover{color:var(--text)}.panel-reopen{border:none;border-left:1px solid var(--border);background:var(--panel);width:26px;color:var(--muted);font-size:12px;font-family:var(--ff-mono);cursor:pointer;flex:none;padding:0}.panel-reopen:hover{color:var(--text)}.empty{color:var(--muted);padding:24px;font-size:14px;line-height:1.5}.empty .hint{margin-top:12px;font-size:12px}.empty.error{color:var(--danger);white-space:pre-wrap}.tabs{border-bottom:1px solid var(--border);flex-wrap:wrap;gap:4px;padding:10px;display:flex}.tab{border:1px solid var(--border);color:var(--muted);font-size:11px;font-family:var(--ff-mono);cursor:pointer;background:0 0;border-radius:6px;padding:5px 9px}.tab.active{color:var(--text);border-color:var(--accent);background:#e8925b26}.artifact-head{justify-content:space-between;align-items:center;gap:8px;padding:10px 12px;display:flex}.path{color:var(--accent-2);font-size:11px;font-family:var(--ff-mono);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.copy{border:1px solid var(--border);color:var(--muted);cursor:pointer;background:0 0;border-radius:6px;flex-shrink:0;padding:4px 10px;font-size:11px}.artifact-body{white-space:pre-wrap;word-break:break-word;font-family:var(--ff-mono);color:var(--text);flex:1;margin:0;padding:0 16px 16px;font-size:12.5px;line-height:1.55;overflow:auto}.pane-nav{border-bottom:1px solid var(--border);background:var(--panel);flex-shrink:0;gap:0;display:flex}.pane-item{color:var(--muted);font-size:12px;font-family:var(--ff-mono);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-bottom:2px solid #0000;flex:1;padding:10px 12px}.pane-item:hover:not(:disabled){color:var(--text)}.pane-item.active{color:var(--text);border-bottom-color:var(--accent);background:#e8925b14}.pane-item:disabled{opacity:.45;cursor:not-allowed}.prompt-pane{flex-direction:column;flex:1;min-height:0;display:flex}.prompt-actions{flex-shrink:0;gap:6px;display:flex}.prompt-save:not(:disabled){color:var(--bg);background:var(--accent);border-color:var(--accent)}.prompt-save:disabled,.prompt-actions .copy:disabled{opacity:.45;cursor:default}.prompt-editor{background:var(--bg);border:1px solid var(--border);color:var(--text);font-size:12.5px;line-height:1.55;font-family:var(--ff-mono);resize:none;border-radius:8px;flex:1;min-height:0;margin:0 12px;padding:10px 12px}.prompt-editor:focus{border-color:var(--accent);outline:none}.prompt-hint{color:var(--muted);margin:8px 12px 12px;font-size:11px;line-height:1.5}.prompt-hint code{color:var(--accent-2)}.at-anchor{flex-direction:column;min-height:0;display:flex;position:relative}.prompt-anchor{flex:1;margin:0 12px}.prompt-anchor .prompt-editor{flex:1;margin:0}.at-search{z-index:10;background:var(--panel);border:1px solid var(--border);border-radius:8px;max-height:220px;margin:0;padding:4px;list-style:none;position:absolute;left:0;right:0;overflow-y:auto;box-shadow:0 8px 24px #00000080}.at-search.up{bottom:calc(100% + 6px)}.at-search.down{top:6px;left:6px;right:6px}.at-item{text-align:left;width:100%;font-size:11.5px;font-family:var(--ff-mono);color:var(--text);cursor:pointer;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:1px solid #0000;border-radius:6px;padding:5px 8px;display:block;overflow:hidden}.at-item:hover,.at-item.active{border-color:var(--accent);background:#e8925b26}.at-item.dir{color:var(--accent-2)}.regenerate{border:1px solid var(--accent);color:var(--accent);cursor:pointer;white-space:nowrap;background:0 0;border-radius:8px;padding:8px 14px;font-size:13px;font-weight:600}.regenerate:hover:not(:disabled){color:var(--accent-hover);border-color:var(--accent-hover)}.regenerate:disabled{opacity:.45;cursor:default}.chat{flex-direction:column;flex:1;min-height:0;display:flex}.chat-messages{flex-direction:column;flex:1;gap:10px;padding:12px;display:flex;overflow-y:auto}.chat-empty{color:var(--muted);padding:12px 4px;font-size:12.5px;line-height:1.55}.chat-empty code{color:var(--accent-2)}.chat-message{border:1px solid var(--border);border-radius:8px;padding:8px 10px;font-size:12.5px;line-height:1.55}.chat-user{border-color:var(--accent);background:#e8925b14}.chat-summary{background:#28c8400f;border-style:dashed}.chat-role{text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin-bottom:4px;font-size:10px}.chat-summary .chat-role{color:var(--accent-2)}.chat-text{white-space:pre-wrap;word-break:break-word}.chat-thinking{color:var(--muted);border-style:dashed}.chat-fault{color:var(--danger);white-space:pre-wrap;padding:4px;font-size:12px}.chat-refs{color:var(--muted);margin-top:6px;font-size:11px}.chat-refs summary{cursor:pointer}.chat-refs ul{margin:6px 0 0;padding-left:18px}.chat-refs li{color:var(--accent-2)}.chat-refs li.chat-ref-missing{color:var(--danger)}.chat-composer{border-top:1px solid var(--border);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.chat-input{background:var(--bg);border:1px solid var(--border);color:var(--text);font-size:12.5px;font-family:var(--ff-mono);resize:vertical;border-radius:8px;min-height:40px;padding:8px 10px}.chat-input:focus{border-color:var(--accent);outline:none}.chat-composer-actions{justify-content:space-between;gap:8px;display:flex}.chat-send{background:var(--accent);color:var(--bg);cursor:pointer;border:none;border-radius:6px;padding:6px 14px;font-size:12px;font-weight:600}.chat-send:hover:not(:disabled){background:var(--accent-hover)}.chat-send:disabled{opacity:.6;cursor:default}.chat-clear{border:1px solid var(--border);color:var(--muted);cursor:pointer;background:0 0;border-radius:6px;padding:6px 12px;font-size:12px}.chat-clear:hover:not(:disabled){color:var(--danger);border-color:var(--danger)}.chat-clear:disabled{opacity:.45;cursor:default}.share-pill{border:1px solid var(--border);color:var(--muted);white-space:nowrap;border-radius:999px;align-items:center;gap:8px;padding:4px 6px 4px 12px;font-size:11.5px;display:flex}.share-dot{background:#868e96;border-radius:50%;flex-shrink:0;width:8px;height:8px}.share-connected .share-dot{background:#2f9e44;box-shadow:0 0 6px #2f9e44b3}.share-connecting .share-dot,.share-reconnecting .share-dot{background:#f08c00;animation:1.2s ease-in-out infinite share-pulse}.share-ended .share-dot,.share-rejected .share-dot{background:#e03131}@keyframes share-pulse{50%{opacity:.35}}.share-copy{border:1px solid var(--border);color:var(--muted);cursor:pointer;background:0 0;border-radius:999px;padding:3px 10px;font-size:11px}.share-copy:hover{color:var(--text);border-color:var(--accent-2)}.viewer-notice{background:var(--bg);justify-content:center;align-items:center;height:100vh;display:flex}.viewer-notice-card{text-align:center;border:1px solid var(--border);border-radius:12px;max-width:440px;padding:40px}.viewer-notice-card .logo{font-size:28px}.viewer-notice-card h1{color:var(--text);margin:12px 0 8px;font-size:18px}.viewer-notice-card p{color:var(--muted);margin:0;font-size:13px;line-height:1.6}.viewer-canvas{flex:1}.react-flow{background:var(--bg)}.react-flow__attribution{display:none}.react-flow__controls{border:1px solid var(--border);border-radius:8px;overflow:hidden;box-shadow:0 2px 10px #00000059}.react-flow__controls-button{background:var(--panel);border-bottom:1px solid var(--border);color:var(--text);width:26px;height:26px}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls-button svg{fill:var(--text);max-width:12px;max-height:12px}.react-flow__controls-button:hover{background:var(--bg);color:var(--accent)}.react-flow__controls-button:hover svg{fill:var(--accent)}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill:var(--muted);fill-opacity:.6}.card{border:1px solid var(--border);background:var(--panel);width:240px;font-family:var(--ff-mono);color:var(--text);border-radius:8px;padding:10px 12px;box-shadow:0 2px 10px #00000059}.card-spec{border-color:var(--accent)}.card-story{border-style:dashed}.card-kind{text-transform:uppercase;letter-spacing:.8px;color:var(--muted);margin-bottom:4px;font-size:10px}.card-spec .card-kind{color:var(--accent)}.card-title{overflow-wrap:anywhere;font-size:13px;font-weight:700}.card-text{overflow-wrap:anywhere;font-size:12px;line-height:1.45}.card-actions{align-items:center;gap:6px;margin-top:8px;display:flex}.react-flow__handle{background:var(--accent);border:1px solid var(--bg);width:9px;height:9px}.edge-dependency .react-flow__edge-path{stroke:var(--accent);stroke-width:1.6px}.edge-containment .react-flow__edge-path{stroke:var(--muted);stroke-width:1.4px}.canvas{position:relative}.toast{border:1px solid var(--danger);max-width:80%;color:var(--text);z-index:30;background:#2a1512;border-radius:8px;padding:10px 14px;font-size:12.5px;position:absolute;bottom:22px;left:50%;transform:translate(-50%);box-shadow:0 6px 20px #00000080}.plan-pane{flex-direction:column;gap:18px;padding:14px;display:flex;overflow-y:auto}.plan-form{flex-direction:column;gap:8px;display:flex}.plan-form h2{text-transform:uppercase;letter-spacing:.8px;color:var(--muted);margin:0;font-size:12px}.plan-form input,.plan-form textarea,.plan-form select{background:var(--bg);border:1px solid var(--border);color:var(--text);font-family:var(--ff-mono);border-radius:6px;padding:8px 10px;font-size:12.5px}.plan-form input:focus,.plan-form textarea:focus,.plan-form select:focus{border-color:var(--accent);outline:none}.plan-form button{background:var(--accent);color:#14100c;cursor:pointer;font-family:var(--ff-mono);border:none;border-radius:6px;align-self:flex-start;padding:7px 12px;font-size:12.5px;font-weight:700}.plan-form button:hover:not(:disabled){background:var(--accent-hover)}.plan-form button:disabled{opacity:.45;cursor:default}.plan-counts{margin:0}.backlog-pane{flex-direction:column;gap:16px;padding:14px;display:flex;overflow-y:auto}.backlog-section h2{text-transform:uppercase;letter-spacing:.8px;color:var(--muted);margin:0 0 8px;font-size:12px}.backlog-list{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.backlog-item{border:1px solid var(--border);border-radius:6px;padding:8px 10px;font-size:12.5px}.backlog-item .backlog-id{color:var(--muted);margin-top:3px;font-size:10.5px;display:block}.card-generate{border:1px solid var(--accent);color:var(--accent);cursor:pointer;font-family:var(--ff-mono);background:0 0;border-radius:5px;padding:4px 8px;font-size:10.5px}.card-generate:hover:not(:disabled){background:var(--accent);color:#14100c}.card-generate:disabled{opacity:.5;cursor:default}.card-badge{color:var(--accent-2);letter-spacing:.4px;margin-left:8px}.card-has-spec{cursor:pointer}.dialog-overlay{z-index:40;background:#0000008c;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.dialog{background:var(--panel);border:1px solid var(--border);border-radius:10px;flex-direction:column;gap:10px;width:min(860px,92%);max-height:88%;padding:14px;display:flex;box-shadow:0 14px 48px #0009}.dialog-head{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.dialog-title{font-size:14px;font-weight:700}.dialog-path{color:var(--muted);font-size:11px}.dialog-actions{gap:8px;display:flex}.dialog-notice{border:1px solid var(--accent);color:var(--text);background:#221507;border-radius:6px;margin:0;padding:8px 10px;font-size:12px;line-height:1.5}.dialog-body{flex:1;min-height:200px}.backlog-actions{gap:8px;display:flex}.card-description{color:var(--muted);margin-top:5px;font-size:11px}.dialog-create{width:min(560px,92%)}.dialog-create .plan-form h2{margin-top:6px}.dialog-submit{justify-content:flex-end;display:flex}.react-flow__edge.selected .react-flow__edge-path{stroke:var(--danger);stroke-width:2.4px}.card-status-wrap{margin-left:auto;display:inline-block;position:relative}.card-status{background:var(--bg);border:1px solid var(--border);color:var(--muted);font-family:var(--ff-mono);text-transform:uppercase;letter-spacing:.6px;cursor:pointer;border-radius:999px;padding:1px 7px;font-size:9.5px}.card-status:focus{border-color:var(--accent);outline:none}.status-menu{z-index:60;background:var(--panel);border:1px solid var(--border);border-radius:8px;flex-direction:column;gap:2px;min-width:92px;padding:4px;display:flex;position:absolute;top:calc(100% + 4px);right:0;box-shadow:0 8px 26px #0000008c}.status-option{color:var(--text);cursor:pointer;font-family:var(--ff-mono);text-align:left;text-transform:uppercase;letter-spacing:.6px;background:0 0;border:none;border-radius:5px;padding:5px 8px;font-size:10.5px}.status-option:hover{background:var(--bg)}.status-option.current{color:var(--accent);font-weight:700}.status-option.status-done:hover,.status-option.status-done.current{color:var(--accent-2)}.card-status.status-active{color:var(--accent);border-color:var(--accent)}.card-status.status-done{color:var(--accent-2);border-color:var(--accent-2)}.card-status.status-deferred{opacity:.6}.card-kind{align-items:center;gap:4px;display:flex}
|
|
@@ -75,4 +75,4 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
75
75
|
`,`
|
|
76
76
|
+`).split(`
|
|
77
77
|
`));return[t,t.reduce((e,t)=>e.concat(...t),[])]}return[[],[]]},[e]);return(0,U.useEffect)(()=>{let n=t?.target??Kh,c=t?.actInsideInputWithModifier??!0;if(e!==null){let e=e=>{if(i.current=e.ctrlKey||e.metaKey||e.shiftKey||e.altKey,(!i.current||i.current&&!c)&&Sp(e))return!1;let n=Yh(e.code,s);if(a.current.add(e[n]),Jh(o,a.current,!1)){let n=e.composedPath?.()?.[0]||e.target,a=n?.nodeName===`BUTTON`||n?.nodeName===`A`;t.preventDefault!==!1&&(i.current||!a)&&e.preventDefault(),r(!0)}},l=e=>{let t=Yh(e.code,s);Jh(o,a.current,!0)?(r(!1),a.current.clear()):a.current.delete(e[t]),e.key===`Meta`&&a.current.clear(),i.current=!1},u=()=>{a.current.clear(),r(!1)};return n?.addEventListener(`keydown`,e),n?.addEventListener(`keyup`,l),window.addEventListener(`blur`,u),window.addEventListener(`contextmenu`,u),()=>{n?.removeEventListener(`keydown`,e),n?.removeEventListener(`keyup`,l),window.removeEventListener(`blur`,u),window.removeEventListener(`contextmenu`,u)}}},[e,r]),n}function Jh(e,t,n){return e.filter(e=>n||e.length===t.size).some(e=>e.every(e=>t.has(e)))}function Yh(e,t){return t.includes(e)?`code`:`key`}var Xh=()=>{let e=yh();return(0,U.useMemo)(()=>({zoomIn:async t=>{let{panZoom:n}=e.getState();return n?n.scaleBy(1.2,t):!1},zoomOut:async t=>{let{panZoom:n}=e.getState();return n?n.scaleBy(1/1.2,t):!1},zoomTo:async(t,n)=>{let{panZoom:r}=e.getState();return r?r.scaleTo(t,n):!1},getZoom:()=>e.getState().transform[2],setViewport:async(t,n)=>{let{transform:[r,i,a],panZoom:o}=e.getState();return o?(await o.setViewport({x:t.x??r,y:t.y??i,zoom:t.zoom??a},n),!0):!1},getViewport:()=>{let[t,n,r]=e.getState().transform;return{x:t,y:n,zoom:r}},setCenter:async(t,n,r)=>e.getState().setCenter(t,n,r),fitBounds:async(t,n)=>{let{width:r,height:i,minZoom:a,maxZoom:o,panZoom:s}=e.getState(),c=lp(t,r,i,a,o,n?.padding??.1);return s?(await s.setViewport(c,{duration:n?.duration,ease:n?.ease,interpolate:n?.interpolate}),!0):!1},screenToFlowPosition:(t,n={})=>{let{transform:r,snapGrid:i,snapToGrid:a,domNode:o}=e.getState();if(!o)return t;let{x:s,y:c}=o.getBoundingClientRect(),l={x:t.x-s,y:t.y-c},u=n.snapGrid??i;return ip(l,r,n.snapToGrid??a,u)},flowToScreenPosition:t=>{let{transform:n,domNode:r}=e.getState();if(!r)return t;let{x:i,y:a}=r.getBoundingClientRect(),o=ap(t,n);return{x:o.x+i,y:o.y+a}}}),[])};function Zh(e,t){let n=[],r=new Map,i=[];for(let t of e)if(t.type===`add`){i.push(t);continue}else if(t.type===`remove`||t.type===`replace`)r.set(t.id,[t]);else{let e=r.get(t.id);e?e.push(t):r.set(t.id,[t])}for(let e of t){let t=r.get(e.id);if(!t){n.push(e);continue}if(t[0].type===`remove`)continue;if(t[0].type===`replace`){n.push({...t[0].item});continue}let i={...e};for(let e of t)Qh(e,i);n.push(i)}return i.length&&i.forEach(e=>{e.index===void 0?n.push({...e.item}):n.splice(e.index,0,{...e.item})}),n}function Qh(e,t){switch(e.type){case`select`:t.selected=e.selected;break;case`position`:e.position!==void 0&&(t.position=e.position),e.dragging!==void 0&&(t.dragging=e.dragging);break;case`dimensions`:e.dimensions!==void 0&&(t.measured={...e.dimensions},e.setAttributes&&((e.setAttributes===!0||e.setAttributes===`width`)&&(t.width=e.dimensions.width),(e.setAttributes===!0||e.setAttributes===`height`)&&(t.height=e.dimensions.height))),typeof e.resizing==`boolean`&&(t.resizing=e.resizing);break}}function $h(e,t){return Zh(e,t)}function eg(e,t){return Zh(e,t)}function tg(e,t){return{id:e,type:`select`,selected:t}}function ng(e,t=new Set,n=!1){let r=[];for(let[i,a]of e){let e=t.has(i);!(a.selected===void 0&&!e)&&a.selected!==e&&(n&&(a.selected=e),r.push(tg(a.id,e)))}return r}function rg({items:e=[],lookup:t}){let n=[],r=new Map(e.map(e=>[e.id,e]));for(let[r,i]of e.entries()){let e=t.get(i.id),a=e?.internals?.userNode??e;a!==void 0&&a!==i&&n.push({id:i.id,item:i,type:`replace`}),a===void 0&&n.push({item:i,type:`add`,index:r})}for(let[e]of t)r.get(e)===void 0&&n.push({id:e,type:`remove`});return n}function ig(e){return{id:e.id,type:`remove`}}var ag=np(`React Flow`,`https://reactflow.dev/`);function og(e,t,n={}){return Fp(e,t,{...n,onError:n.onError??ag})}var sg=e=>Af(e),cg=e=>kf(e);function lg(e){return(0,U.forwardRef)(e)}var ug=typeof window<`u`?U.useLayoutEffect:U.useEffect;function dg(e){let[t,n]=(0,U.useState)(BigInt(0)),[r]=(0,U.useState)(()=>fg(()=>n(e=>e+BigInt(1))));return ug(()=>{let t=r.get();t.length&&(e(t),r.reset())},[t]),r}function fg(e){let t=[];return{get:()=>t,reset:()=>{t=[]},push:n=>{t.push(n),e()}}}var pg=(0,U.createContext)(null);function mg({children:e}){let t=yh(),n=dg((0,U.useCallback)(e=>{let{nodes:n=[],setNodes:r,hasDefaultNodes:i,onNodesChange:a,nodeLookup:o,fitViewQueued:s,onNodesChangeMiddlewareMap:c}=t.getState(),l=n;for(let t of e)l=typeof t==`function`?t(l):t;let u=rg({items:l,lookup:o});for(let e of c.values())u=e(u);i&&r(l),u.length>0?a?.(u):s&&window.requestAnimationFrame(()=>{let{fitViewQueued:e,nodes:n,setNodes:r}=t.getState();e&&r(n)})},[])),r=dg((0,U.useCallback)(e=>{let{edges:n=[],setEdges:r,hasDefaultEdges:i,onEdgesChange:a,edgeLookup:o}=t.getState(),s=n;for(let t of e)s=typeof t==`function`?t(s):t;i?r(s):a&&a(rg({items:s,lookup:o}))},[])),i=(0,U.useMemo)(()=>({nodeQueue:n,edgeQueue:r}),[]);return(0,W.jsx)(pg.Provider,{value:i,children:e})}function hg(){let e=(0,U.useContext)(pg);if(!e)throw Error(`useBatchContext must be used within a BatchProvider`);return e}var gg=e=>!!e.panZoom;function _g(){let e=Xh(),t=yh(),n=hg(),r=$(gg),i=(0,U.useMemo)(()=>{let e=e=>t.getState().nodeLookup.get(e),r=e=>{n.nodeQueue.push(e)},i=e=>{n.edgeQueue.push(e)},a=e=>{let{nodeLookup:n,nodeOrigin:r}=t.getState(),i=sg(e)?e:n.get(e.id),a=i.parentId?mp(i.position,i.measured,i.parentId,n,r):i.position;return Yf({...i,position:a,width:i.measured?.width??i.width,height:i.measured?.height??i.height})},o=(e,t,n={replace:!1})=>{r(r=>r.map(r=>{if(r.id===e){let e=typeof t==`function`?t(r):t;return n.replace&&sg(e)?e:{...r,...e}}return r}))},s=(e,t,n={replace:!1})=>{i(r=>r.map(r=>{if(r.id===e){let e=typeof t==`function`?t(r):t;return n.replace&&cg(e)?e:{...r,...e}}return r}))};return{getNodes:()=>t.getState().nodes.map(e=>({...e})),getNode:t=>e(t)?.internals.userNode,getInternalNode:e,getEdges:()=>{let{edges:e=[]}=t.getState();return e.map(e=>({...e}))},getEdge:e=>t.getState().edgeLookup.get(e),setNodes:r,setEdges:i,addNodes:e=>{let t=Array.isArray(e)?e:[e];n.nodeQueue.push(e=>[...e,...t])},addEdges:e=>{let t=Array.isArray(e)?e:[e];n.edgeQueue.push(e=>[...e,...t])},toObject:()=>{let{nodes:e=[],edges:n=[],transform:r}=t.getState(),[i,a,o]=r;return{nodes:e.map(e=>({...e})),edges:n.map(e=>({...e})),viewport:{x:i,y:a,zoom:o}}},deleteElements:async({nodes:e=[],edges:n=[]})=>{let{nodes:r,edges:i,onNodesDelete:a,onEdgesDelete:o,triggerNodeChanges:s,triggerEdgeChanges:c,onDelete:l,onBeforeDelete:u}=t.getState(),{nodes:d,edges:f}=await Bf({nodesToRemove:e,edgesToRemove:n,nodes:r,edges:i,onBeforeDelete:u}),p=f.length>0,m=d.length>0;if(p){let e=f.map(ig);o?.(f),c(e)}if(m){let e=d.map(ig);a?.(d),s(e)}return(m||p)&&l?.({nodes:d,edges:f}),{deletedNodes:d,deletedEdges:f}},getIntersectingNodes:(e,n=!0,r)=>{let i=ep(e),o=i?e:a(e),s=r!==void 0;return o?(r||t.getState().nodes).filter(r=>{let a=t.getState().nodeLookup.get(r.id);if(a&&!i&&(r.id===e.id||!a.internals.positionAbsolute))return!1;let c=Yf(s?r:a),l=$f(c,o);return n&&l>0||l>=c.width*c.height||l>=o.width*o.height}):[]},isNodeIntersecting:(e,t,n=!0)=>{let r=ep(e)?e:a(e);if(!r)return!1;let i=$f(r,t);return n&&i>0||i>=t.width*t.height||i>=r.width*r.height},updateNode:o,updateNodeData:(e,t,n={replace:!1})=>{o(e,e=>{let r=typeof t==`function`?t(e):t;return n.replace?{...e,data:r}:{...e,data:{...e.data,...r}}},n)},updateEdge:s,updateEdgeData:(e,t,n={replace:!1})=>{s(e,e=>{let r=typeof t==`function`?t(e):t;return n.replace?{...e,data:r}:{...e,data:{...e.data,...r}}},n)},getNodesBounds:e=>{let{nodeLookup:n,nodeOrigin:r}=t.getState();return Nf(e,{nodeLookup:n,nodeOrigin:r})},getHandleConnections:({type:e,id:n,nodeId:r})=>Array.from(t.getState().connectionLookup.get(`${r}-${e}${n?`-${n}`:``}`)?.values()??[]),getNodeConnections:({type:e,handleId:n,nodeId:r})=>Array.from(t.getState().connectionLookup.get(`${r}${e?n?`-${e}-${n}`:`-${e}`:``}`)?.values()??[]),fitView:async e=>{let r=t.getState().fitViewResolver??gp();return t.setState({fitViewQueued:!0,fitViewOptions:e,fitViewResolver:r}),n.nodeQueue.push(e=>[...e]),r.promise}}},[]);return(0,U.useMemo)(()=>({...i,...e,viewportInitialized:r}),[r])}var vg=e=>e.selected,yg=typeof window<`u`?window:void 0;function bg({deleteKeyCode:e,multiSelectionKeyCode:t}){let n=yh(),{deleteElements:r}=_g(),i=qh(e,{actInsideInputWithModifier:!1}),a=qh(t,{target:yg});(0,U.useEffect)(()=>{if(i){let{edges:e,nodes:t}=n.getState();r({nodes:t.filter(vg),edges:e.filter(vg)}),n.setState({nodesSelectionActive:!1})}},[i]),(0,U.useEffect)(()=>{n.setState({multiSelectionActive:a})},[a])}function xg(e){let t=yh();(0,U.useEffect)(()=>{let n=()=>{if(!e.current||!(e.current.checkVisibility?.()??!0))return!1;let n=yp(e.current);(n.height===0||n.width===0)&&t.getState().onError?.(`004`,_f.error004()),t.setState({width:n.width||500,height:n.height||500})};if(e.current){n(),window.addEventListener(`resize`,n);let t=new ResizeObserver(()=>n());return t.observe(e.current),()=>{window.removeEventListener(`resize`,n),t&&e.current&&t.unobserve(e.current)}}},[])}var Sg={position:`absolute`,width:`100%`,height:`100%`,top:0,left:0},Cg=e=>({userSelectionActive:e.userSelectionActive,lib:e.lib,connectionInProgress:e.connection.inProgress});function wg({onPaneContextMenu:e,zoomOnScroll:t=!0,zoomOnPinch:n=!0,panOnScroll:r=!1,panOnScrollSpeed:i=.5,panOnScrollMode:a=Sf.Free,zoomOnDoubleClick:o=!0,panOnDrag:s=!0,defaultViewport:c,translateExtent:l,minZoom:u,maxZoom:d,zoomActivationKeyCode:f,preventScrolling:p=!0,children:m,noWheelClassName:h,noPanClassName:g,onViewportChange:_,isControlledViewport:v,paneClickDistance:y,selectionOnDrag:b}){let x=yh(),S=(0,U.useRef)(null),{userSelectionActive:C,lib:w,connectionInProgress:T}=$(Cg,hh),E=qh(f),D=(0,U.useRef)();xg(S);let O=(0,U.useCallback)(e=>{_?.({x:e[0],y:e[1],zoom:e[2]}),v||x.setState({transform:e})},[_,v]);return(0,U.useEffect)(()=>{if(S.current){D.current=Wm({domNode:S.current,minZoom:u,maxZoom:d,translateExtent:l,viewport:c,onDraggingChange:e=>x.setState(t=>t.paneDragging===e?t:{paneDragging:e}),onPanZoomStart:(e,t)=>{let{onViewportChangeStart:n,onMoveStart:r}=x.getState();r?.(e,t),n?.(t)},onPanZoom:(e,t)=>{let{onViewportChange:n,onMove:r}=x.getState();r?.(e,t),n?.(t)},onPanZoomEnd:(e,t)=>{let{onViewportChangeEnd:n,onMoveEnd:r}=x.getState();r?.(e,t),n?.(t)}});let{x:e,y:t,zoom:n}=D.current.getViewport();return x.setState({panZoom:D.current,transform:[e,t,n],domNode:S.current.closest(`.react-flow`)}),()=>{D.current?.destroy()}}},[]),(0,U.useEffect)(()=>{D.current?.update({onPaneContextMenu:e,zoomOnScroll:t,zoomOnPinch:n,panOnScroll:r,panOnScrollSpeed:i,panOnScrollMode:a,zoomOnDoubleClick:o,panOnDrag:s,zoomActivationKeyPressed:E,preventScrolling:p,noPanClassName:g,userSelectionActive:C,noWheelClassName:h,lib:w,onTransformChange:O,connectionInProgress:T,selectionOnDrag:b,paneClickDistance:y})},[e,t,n,r,i,a,o,s,E,p,g,C,h,w,O,T,b,y]),(0,W.jsx)(`div`,{className:`react-flow__renderer`,ref:S,style:Sg,children:m})}var Tg=e=>({userSelectionActive:e.userSelectionActive,userSelectionRect:e.userSelectionRect});function Eg(){let{userSelectionActive:e,userSelectionRect:t}=$(Tg,hh);return e&&t?(0,W.jsx)(`div`,{className:`react-flow__selection react-flow__container`,style:{width:t.width,height:t.height,transform:`translate(${t.x}px, ${t.y}px)`}}):null}var Dg=(e,t)=>n=>{n.target===t.current&&e?.(n)},Og=e=>({userSelectionActive:e.userSelectionActive,elementsSelectable:e.elementsSelectable,dragging:e.paneDragging,panBy:e.panBy,autoPanSpeed:e.autoPanSpeed});function kg({isSelecting:e,selectionKeyPressed:t,selectionMode:n=Cf.Full,panOnDrag:r,autoPanOnSelection:i,paneClickDistance:a,selectionOnDrag:o,onSelectionStart:s,onSelectionEnd:c,onPaneClick:l,onPaneContextMenu:u,onPaneScroll:d,onPaneMouseEnter:f,onPaneMouseMove:p,onPaneMouseLeave:m,children:h}){let g=(0,U.useRef)(0),_=yh(),{userSelectionActive:v,elementsSelectable:y,dragging:b,panBy:x,autoPanSpeed:S}=$(Og,hh),C=y&&(e||v),w=(0,U.useRef)(null),T=(0,U.useRef)(),E=(0,U.useRef)(new Set),D=(0,U.useRef)(new Set),O=(0,U.useRef)(!1),k=(0,U.useRef)(!1),A=(0,U.useRef)({x:0,y:0}),j=(0,U.useRef)(!1),M=e=>{if(k.current||O.current||_.getState().connection.inProgress){k.current=!1,O.current=!1;return}l?.(e),_.getState().resetSelectedElements(),_.setState({nodesSelectionActive:!1})},ee=e=>{if(Array.isArray(r)&&r?.includes(2)){e.preventDefault();return}u?.(e)},te=d?e=>d(e):void 0,ne=e=>{k.current&&=(e.stopPropagation(),!1)},N=n=>{let{domNode:r,transform:i}=_.getState();if(T.current=r?.getBoundingClientRect(),!T.current)return;let a=n.target===w.current;if(!a&&n.target.closest(`.nokey`)||!e||!(o&&a||t)||n.button!==0||!n.isPrimary)return;n.target?.setPointerCapture?.(n.pointerId),k.current=!1;let{x:s,y:c}=wp(n.nativeEvent,T.current),l=ip({x:s,y:c},i);_.setState({userSelectionRect:{width:0,height:0,startX:l.x,startY:l.y,x:s,y:c}}),a||(n.stopPropagation(),n.preventDefault())};function P(e,t){let{userSelectionRect:r}=_.getState();if(!r)return;let{transform:i,nodeLookup:a,edgeLookup:o,connectionLookup:s,triggerNodeChanges:c,triggerEdgeChanges:l,defaultEdgeOptions:u}=_.getState(),d={x:r.startX,y:r.startY},{x:f,y:p}=ap(d,i),m={startX:d.x,startY:d.y,x:e<f?e:f,y:t<p?t:p,width:Math.abs(e-f),height:Math.abs(t-p)},h=E.current,g=D.current;E.current=new Set(Ff(a,m,i,n===Cf.Partial,!0).map(e=>e.id)),D.current=new Set;let v=u?.selectable??!0;for(let e of E.current){let t=s.get(e);if(t)for(let{edgeId:e}of t.values()){let t=o.get(e);t&&(t.selectable??v)&&D.current.add(e)}}hp(h,E.current)||c(ng(a,E.current,!0)),hp(g,D.current)||l(ng(o,D.current)),_.setState({userSelectionRect:m,userSelectionActive:!0,nodesSelectionActive:!1})}function F(){if(!i||!T.current)return;let[e,t]=Gf(A.current,T.current,S);x({x:e,y:t}).then(e=>{if(!k.current||!e){g.current=requestAnimationFrame(F);return}let{x:t,y:n}=A.current;P(t,n),g.current=requestAnimationFrame(F)})}let re=()=>{cancelAnimationFrame(g.current),g.current=0,j.current=!1};return(0,U.useEffect)(()=>()=>re(),[]),(0,W.jsxs)(`div`,{className:zo([`react-flow__pane`,{draggable:r===!0||Array.isArray(r)&&r.includes(0),dragging:b,selection:e}]),onClick:C?void 0:Dg(M,w),onContextMenu:Dg(ee,w),onWheel:Dg(te,w),onPointerEnter:C?void 0:f,onPointerMove:C?e=>{let{userSelectionRect:n,transform:r,resetSelectedElements:i}=_.getState();if(!T.current||!n)return;let{x:o,y:c}=wp(e.nativeEvent,T.current);A.current={x:o,y:c};let l=ap({x:n.startX,y:n.startY},r);if(!k.current){let n=t?0:a;if(Math.hypot(o-l.x,c-l.y)<=n)return;i(),s?.(e)}k.current=!0,j.current||=(F(),!0),P(o,c)}:p,onPointerUp:e=>{if(!C){e.target===w.current&&_.getState().connection.inProgress&&(O.current=!0);return}e.button===0&&(e.target?.releasePointerCapture?.(e.pointerId),!v&&e.target===w.current&&_.getState().userSelectionRect&&M?.(e),_.setState({userSelectionActive:!1,userSelectionRect:null}),k.current&&(c?.(e),_.setState({nodesSelectionActive:E.current.size>0})),re())},onPointerCancel:C?e=>{e.target?.releasePointerCapture?.(e.pointerId),re()}:void 0,onPointerDownCapture:C?N:void 0,onClickCapture:C?ne:void 0,onPointerLeave:m,ref:w,style:Sg,children:[h,(0,W.jsx)(Eg,{})]})}function Ag({id:e,store:t,unselect:n=!1,nodeRef:r}){let{addSelectedNodes:i,unselectNodesAndEdges:a,multiSelectionActive:o,nodeLookup:s,onError:c}=t.getState(),l=s.get(e);if(!l){c?.(`012`,_f.error012(e));return}t.setState({nodesSelectionActive:!1}),l.selected?(n||l.selected&&o)&&(a({nodes:[l],edges:[]}),requestAnimationFrame(()=>r?.current?.blur())):i([e])}function jg({nodeRef:e,disabled:t=!1,noDragClassName:n,handleSelector:r,nodeId:i,isSelectable:a,nodeClickDistance:o}){let s=yh(),[c,l]=(0,U.useState)(!1),u=(0,U.useRef)();return(0,U.useEffect)(()=>{if(!t)return u.current=ym({getStoreItems:()=>s.getState(),onNodeMouseDown:t=>{Ag({id:t,store:s,nodeRef:e})},onDragStart:()=>{l(!0)},onDragStop:()=>{l(!1)}}),()=>{u.current?.destroy(),u.current=void 0}},[t,s,e]),(0,U.useEffect)(()=>{t||!e.current||!u.current||u.current.update({noDragClassName:n,handleSelector:r,domNode:e.current,isSelectable:a,nodeId:i,nodeClickDistance:o})},[n,r,t,a,e,i,o]),c}var Mg=e=>t=>t.selected&&(t.draggable||e&&t.draggable===void 0);function Ng(){let e=yh();return(0,U.useCallback)(t=>{let{nodeExtent:n,snapToGrid:r,snapGrid:i,nodesDraggable:a,onError:o,updateNodePositions:s,nodeLookup:c,nodeOrigin:l}=e.getState(),u=new Map,d=Mg(a),f=r?i[0]:5,p=r?i[1]:5,m=t.direction.x*f*t.factor,h=t.direction.y*p*t.factor;for(let[,e]of c){if(!d(e))continue;let t={x:e.internals.positionAbsolute.x+m,y:e.internals.positionAbsolute.y+h};r&&(t=rp(t,i));let{position:a,positionAbsolute:s}=zf({nodeId:e.id,nextPosition:t,nodeLookup:c,nodeExtent:n,nodeOrigin:l,onError:o});e.position=a,e.internals.positionAbsolute=s,u.set(e.id,e)}s(u)},[])}var Pg=(0,U.createContext)(null),Fg=Pg.Provider;Pg.Consumer;var Ig=()=>(0,U.useContext)(Pg),Lg=e=>({connectOnClick:e.connectOnClick,noPanClassName:e.noPanClassName,rfId:e.rfId}),Rg=(0,U.createContext)(null);function zg({children:e}){let t=$(Lg,hh);return(0,W.jsx)(Rg.Provider,{value:t,children:e})}function Bg(){let e=(0,U.useContext)(Rg);if(!e)throw Error(`useHandleConfig must be used within a HandleConfigProvider`);return e}var Vg={connectingFrom:!1,connectingTo:!1,clickConnecting:!1,isPossibleEndHandle:!0,connectionInProcess:!1,clickConnectionInProcess:!1,valid:!1},Hg=(e,t,n)=>r=>{let{connectionClickStartHandle:i,connectionMode:a,connection:o}=r,{fromHandle:s,toHandle:c,isValid:l}=o;if(!s&&!i)return Vg;let u=c?.nodeId===e&&c?.id===t&&c?.type===n;return{connectingFrom:s?.nodeId===e&&s?.id===t&&s?.type===n,connectingTo:u,clickConnecting:i?.nodeId===e&&i?.id===t&&i?.type===n,isPossibleEndHandle:a===xf.Strict?s?.type!==n:e!==s?.nodeId||t!==s?.id,connectionInProcess:!!s,clickConnectionInProcess:!!i,valid:u&&l}};function Ug({type:e=`source`,position:t=Q.Top,isValidConnection:n,isConnectable:r=!0,isConnectableStart:i=!0,isConnectableEnd:a=!0,id:o,onConnect:s,children:c,className:l,onMouseDown:u,onTouchStart:d,...f},p){let m=o||null,h=e===`target`,g=yh(),_=Ig(),{connectOnClick:v,noPanClassName:y,rfId:b}=Bg(),{connectingFrom:x,connectingTo:S,clickConnecting:C,isPossibleEndHandle:w,connectionInProcess:T,clickConnectionInProcess:E,valid:D}=$(Hg(_,m,e),hh);_||g.getState().onError?.(`010`,_f.error010());let O=e=>{let{defaultEdgeOptions:t,onConnect:n,hasDefaultEdges:r}=g.getState(),i={...t,...e};if(r){let{edges:e,setEdges:t,onError:n}=g.getState();t(og(i,e,{onError:n}))}n?.(i),s?.(i)},k=e=>{if(!_)return;let t=Cp(e.nativeEvent);if(i&&(t&&e.button===0||!t)){let t=g.getState();km.onPointerDown(e.nativeEvent,{handleDomNode:e.currentTarget,autoPanOnConnect:t.autoPanOnConnect,connectionMode:t.connectionMode,connectionRadius:t.connectionRadius,domNode:t.domNode,nodeLookup:t.nodeLookup,lib:t.lib,isTarget:h,handleId:m,nodeId:_,flowId:t.rfId,panBy:t.panBy,cancelConnection:t.cancelConnection,onConnectStart:t.onConnectStart,onConnectEnd:(...e)=>g.getState().onConnectEnd?.(...e),updateConnection:t.updateConnection,onConnect:O,isValidConnection:n||((...e)=>g.getState().isValidConnection?.(...e)??!0),getTransform:()=>g.getState().transform,getFromHandle:()=>g.getState().connection.fromHandle,autoPanSpeed:t.autoPanSpeed,dragThreshold:t.connectionDragThreshold})}t?u?.(e):d?.(e)};return(0,W.jsx)(`div`,{"data-handleid":m,"data-nodeid":_,"data-handlepos":t,"data-id":`${b}-${_}-${m}-${e}`,className:zo([`react-flow__handle`,`react-flow__handle-${t}`,`nodrag`,y,l,{source:!h,target:h,connectable:r,connectablestart:i,connectableend:a,clickconnecting:C,connectingfrom:x,connectingto:S,valid:D,connectionindicator:r&&(!T||w)&&(T||E?a:i)}]),onMouseDown:k,onTouchStart:k,onClick:v?t=>{let{onClickConnectStart:r,onClickConnectEnd:a,connectionClickStartHandle:o,connectionMode:s,isValidConnection:c,lib:l,rfId:u,nodeLookup:d,connection:f}=g.getState();if(!_||!o&&!i)return;if(!o){r?.(t.nativeEvent,{nodeId:_,handleId:m,handleType:e}),g.setState({connectionClickStartHandle:{nodeId:_,type:e,id:m}});return}let p=bp(t.target),h=n||c,{connection:v,isValid:y}=km.isValid(t.nativeEvent,{handle:{nodeId:_,id:m,type:e},connectionMode:s,fromNodeId:o.nodeId,fromHandleId:o.id||null,fromType:o.type,isValidConnection:h,flowId:u,doc:p,lib:l,nodeLookup:d});y&&v&&O(v);let b=structuredClone(f);delete b.inProgress,b.toPosition=b.toHandle?b.toHandle.position:null,a?.(t,b),g.setState({connectionClickStartHandle:null})}:void 0,ref:p,...f,children:c})}var Wg=(0,U.memo)(lg(Ug));function Gg({data:e,isConnectable:t,sourcePosition:n=Q.Bottom}){return(0,W.jsxs)(W.Fragment,{children:[e?.label,(0,W.jsx)(Wg,{type:`source`,position:n,isConnectable:t})]})}function Kg({data:e,isConnectable:t,targetPosition:n=Q.Top,sourcePosition:r=Q.Bottom}){return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(Wg,{type:`target`,position:n,isConnectable:t}),e?.label,(0,W.jsx)(Wg,{type:`source`,position:r,isConnectable:t})]})}function qg(){return null}function Jg({data:e,isConnectable:t,targetPosition:n=Q.Top}){return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(Wg,{type:`target`,position:n,isConnectable:t}),e?.label]})}var Yg={ArrowUp:{x:0,y:-1},ArrowDown:{x:0,y:1},ArrowLeft:{x:-1,y:0},ArrowRight:{x:1,y:0}},Xg={input:Gg,default:Kg,output:Jg,group:qg};function Zg(e){return e.internals.handleBounds===void 0?{width:e.width??e.initialWidth??e.style?.width,height:e.height??e.initialHeight??e.style?.height}:{width:e.width??e.style?.width,height:e.height??e.style?.height}}var Qg=e=>{let{width:t,height:n,x:r,y:i}=Pf(e.nodeLookup,{filter:e=>!!e.selected});return{width:tp(t)?t:null,height:tp(n)?n:null,userSelectionActive:e.userSelectionActive,transformString:`translate(${e.transform[0]}px,${e.transform[1]}px) scale(${e.transform[2]}) translate(${r}px,${i}px)`}};function $g({onSelectionContextMenu:e,noPanClassName:t,disableKeyboardA11y:n}){let r=yh(),{width:i,height:a,transformString:o,userSelectionActive:s}=$(Qg,hh),c=Ng(),l=(0,U.useRef)(null);(0,U.useEffect)(()=>{n||l.current?.focus({preventScroll:!0})},[n]);let u=!s&&i!==null&&a!==null;if(jg({nodeRef:l,disabled:!u}),!u)return null;let d=e?t=>{e(t,r.getState().nodes.filter(e=>e.selected))}:void 0;return(0,W.jsx)(`div`,{className:zo([`react-flow__nodesselection`,`react-flow__container`,t]),style:{transform:o},children:(0,W.jsx)(`div`,{ref:l,className:`react-flow__nodesselection-rect`,onContextMenu:d,tabIndex:n?void 0:-1,onKeyDown:n?void 0:e=>{Object.prototype.hasOwnProperty.call(Yg,e.key)&&(e.preventDefault(),c({direction:Yg[e.key],factor:e.shiftKey?4:1}))},style:{width:i,height:a}})})}var e_=typeof window<`u`?window:void 0,t_=e=>({nodesSelectionActive:e.nodesSelectionActive,userSelectionActive:e.userSelectionActive});function n_({children:e,onPaneClick:t,onPaneMouseEnter:n,onPaneMouseMove:r,onPaneMouseLeave:i,onPaneContextMenu:a,onPaneScroll:o,paneClickDistance:s,deleteKeyCode:c,selectionKeyCode:l,selectionOnDrag:u,selectionMode:d,onSelectionStart:f,onSelectionEnd:p,multiSelectionKeyCode:m,panActivationKeyCode:h,zoomActivationKeyCode:g,elementsSelectable:_,zoomOnScroll:v,zoomOnPinch:y,panOnScroll:b,panOnScrollSpeed:x,panOnScrollMode:S,zoomOnDoubleClick:C,panOnDrag:w,autoPanOnSelection:T,defaultViewport:E,translateExtent:D,minZoom:O,maxZoom:k,preventScrolling:A,onSelectionContextMenu:j,noWheelClassName:M,noPanClassName:ee,disableKeyboardA11y:te,onViewportChange:ne,isControlledViewport:N}){let{nodesSelectionActive:P,userSelectionActive:F}=$(t_,hh),re=qh(l,{target:e_}),ie=qh(h,{target:e_}),ae=ie||w,I=ie||b,L=u&&ae!==!0,oe=re||F||L;return bg({deleteKeyCode:c,multiSelectionKeyCode:m}),(0,W.jsx)(wg,{onPaneContextMenu:a,elementsSelectable:_,zoomOnScroll:v,zoomOnPinch:y,panOnScroll:I,panOnScrollSpeed:x,panOnScrollMode:S,zoomOnDoubleClick:C,panOnDrag:!re&&ae,defaultViewport:E,translateExtent:D,minZoom:O,maxZoom:k,zoomActivationKeyCode:g,preventScrolling:A,noWheelClassName:M,noPanClassName:ee,onViewportChange:ne,isControlledViewport:N,paneClickDistance:s,selectionOnDrag:L,children:(0,W.jsxs)(kg,{onSelectionStart:f,onSelectionEnd:p,onPaneClick:t,onPaneMouseEnter:n,onPaneMouseMove:r,onPaneMouseLeave:i,onPaneContextMenu:a,onPaneScroll:o,panOnDrag:ae,autoPanOnSelection:T,isSelecting:!!oe,selectionMode:d,selectionKeyPressed:re,paneClickDistance:s,selectionOnDrag:L,children:[e,P&&(0,W.jsx)($g,{onSelectionContextMenu:j,noPanClassName:ee,disableKeyboardA11y:te})]})})}n_.displayName=`FlowRenderer`;var r_=(0,U.memo)(n_),i_=e=>t=>e?Ff(t.nodeLookup,{x:0,y:0,width:t.width,height:t.height},t.transform,!0).map(e=>e.id):Array.from(t.nodeLookup.keys());function a_(e){return $((0,U.useCallback)(i_(e),[e]),hh)}var o_=e=>e.updateNodeInternals;function s_(){let e=$(o_),[t]=(0,U.useState)(()=>typeof ResizeObserver>`u`?null:new ResizeObserver(t=>{let n=new Map;t.forEach(e=>{let t=e.target.getAttribute(`data-id`);n.set(t,{id:t,nodeElement:e.target,force:!0})}),e(n)}));return(0,U.useEffect)(()=>()=>{t?.disconnect()},[t]),t}function c_({node:e,nodeType:t,hasDimensions:n,resizeObserver:r}){let i=yh(),a=(0,U.useRef)(null),o=(0,U.useRef)(null),s=(0,U.useRef)(e.sourcePosition),c=(0,U.useRef)(e.targetPosition),l=(0,U.useRef)(t),u=n&&!!e.internals.handleBounds;return(0,U.useEffect)(()=>{a.current&&!e.hidden&&(!u||o.current!==a.current)&&(o.current&&r?.unobserve(o.current),r?.observe(a.current),o.current=a.current)},[u,e.hidden]),(0,U.useEffect)(()=>()=>{o.current&&=(r?.unobserve(o.current),null)},[]),(0,U.useEffect)(()=>{if(a.current){let n=l.current!==t,r=s.current!==e.sourcePosition,o=c.current!==e.targetPosition;(n||r||o)&&(l.current=t,s.current=e.sourcePosition,c.current=e.targetPosition,i.getState().updateNodeInternals(new Map([[e.id,{id:e.id,nodeElement:a.current,force:!0}]])))}},[e.id,t,e.sourcePosition,e.targetPosition]),a}function l_({id:e,onClick:t,onMouseEnter:n,onMouseMove:r,onMouseLeave:i,onContextMenu:a,onDoubleClick:o,nodesDraggable:s,elementsSelectable:c,nodesConnectable:l,nodesFocusable:u,resizeObserver:d,noDragClassName:f,noPanClassName:p,disableKeyboardA11y:m,rfId:h,nodeTypes:g,nodeClickDistance:_,onError:v}){let{node:y,internals:b,isParent:x}=$(t=>{let n=t.nodeLookup.get(e),r=t.parentLookup.has(e);return{node:n,internals:n.internals,isParent:r}},hh),S=y.type||`default`,C=g?.[S]||Xg[S];C===void 0&&(v?.(`003`,_f.error003(S)),S=`default`,C=g?.default||Xg.default);let w=!!(y.draggable||s&&y.draggable===void 0),T=!!(y.selectable||c&&y.selectable===void 0),E=!!(y.connectable||l&&y.connectable===void 0),D=!!(y.focusable||u&&y.focusable===void 0),O=yh(),k=pp(y),A=c_({node:y,nodeType:S,hasDimensions:k,resizeObserver:d}),j=jg({nodeRef:A,disabled:y.hidden||!w,noDragClassName:f,handleSelector:y.dragHandle,nodeId:e,isSelectable:T,nodeClickDistance:_}),M=Ng();if(y.hidden)return null;let ee=fp(y),te=Zg(y),ne=T||w||t||n||r||i,N=n?e=>n(e,{...b.userNode}):void 0,P=r?e=>r(e,{...b.userNode}):void 0,F=i?e=>i(e,{...b.userNode}):void 0,re=a?e=>a(e,{...b.userNode}):void 0,ie=o?e=>o(e,{...b.userNode}):void 0,ae=n=>{let{selectNodesOnDrag:r,nodeDragThreshold:i}=O.getState();T&&(!r||!w||i>0)&&Ag({id:e,store:O,nodeRef:A}),t&&t(n,{...b.userNode})},I=t=>{if(!(Sp(t.nativeEvent)||m)){if(yf.includes(t.key)&&T){let n=t.key===`Escape`;Ag({id:e,store:O,unselect:n,nodeRef:A})}else if(w&&y.selected&&Object.prototype.hasOwnProperty.call(Yg,t.key)){t.preventDefault();let{ariaLabelConfig:e}=O.getState();O.setState({ariaLiveMessage:e[`node.a11yDescription.ariaLiveMessage`]({direction:t.key.replace(`Arrow`,``).toLowerCase(),x:~~b.positionAbsolute.x,y:~~b.positionAbsolute.y})}),M({direction:Yg[t.key],factor:t.shiftKey?4:1})}}},L=()=>{if(m||!A.current?.matches(`:focus-visible`))return;let{transform:t,width:n,height:r,autoPanOnNodeFocus:i,setCenter:a}=O.getState();i&&(Ff(new Map([[e,y]]),{x:0,y:0,width:n,height:r},t,!0).length>0||a(y.position.x+ee.width/2,y.position.y+ee.height/2,{zoom:t[2]}))};return(0,W.jsx)(`div`,{className:zo([`react-flow__node`,`react-flow__node-${S}`,{[p]:w},y.className,{selected:y.selected,selectable:T,parent:x,draggable:w,dragging:j}]),ref:A,style:{zIndex:b.z,transform:`translate(${b.positionAbsolute.x}px,${b.positionAbsolute.y}px)`,pointerEvents:ne?`all`:`none`,visibility:k?`visible`:`hidden`,...y.style,...te},"data-id":e,"data-testid":`rf__node-${e}`,onMouseEnter:N,onMouseMove:P,onMouseLeave:F,onContextMenu:re,onClick:ae,onDoubleClick:ie,onKeyDown:D?I:void 0,tabIndex:D?0:void 0,onFocus:D?L:void 0,role:y.ariaRole??(D?`group`:void 0),"aria-roledescription":`node`,"aria-describedby":m?void 0:`${Sh}-${h}`,"aria-label":y.ariaLabel,...y.domAttributes,children:(0,W.jsx)(Fg,{value:e,children:(0,W.jsx)(C,{id:e,data:y.data,type:S,positionAbsoluteX:b.positionAbsolute.x,positionAbsoluteY:b.positionAbsolute.y,selected:y.selected??!1,selectable:T,draggable:w,deletable:y.deletable??!0,isConnectable:E,sourcePosition:y.sourcePosition,targetPosition:y.targetPosition,dragging:j,dragHandle:y.dragHandle,zIndex:b.z,parentId:y.parentId,...ee})})})}var u_=(0,U.memo)(l_),d_=e=>({nodesConnectable:e.nodesConnectable,nodesFocusable:e.nodesFocusable,elementsSelectable:e.elementsSelectable,onError:e.onError});function f_(e){let{nodesConnectable:t,nodesFocusable:n,elementsSelectable:r,onError:i}=$(d_,hh),a=a_(e.onlyRenderVisibleElements),o=s_();return(0,W.jsx)(`div`,{className:`react-flow__nodes`,style:Sg,children:a.map(a=>(0,W.jsx)(u_,{id:a,nodeTypes:e.nodeTypes,nodeExtent:e.nodeExtent,onClick:e.onNodeClick,onMouseEnter:e.onNodeMouseEnter,onMouseMove:e.onNodeMouseMove,onMouseLeave:e.onNodeMouseLeave,onContextMenu:e.onNodeContextMenu,onDoubleClick:e.onNodeDoubleClick,noDragClassName:e.noDragClassName,noPanClassName:e.noPanClassName,rfId:e.rfId,disableKeyboardA11y:e.disableKeyboardA11y,resizeObserver:o,nodesDraggable:e.nodesDraggable??!0,nodesConnectable:t,nodesFocusable:n,elementsSelectable:r,nodeClickDistance:e.nodeClickDistance,onError:i},a))})}f_.displayName=`NodeRenderer`;var p_=(0,U.memo)(f_);function m_(e){return $((0,U.useCallback)(t=>{if(!e)return t.edges.map(e=>e.id);let n=[];if(t.width&&t.height)for(let e of t.edges){let r=t.nodeLookup.get(e.source),i=t.nodeLookup.get(e.target);r&&i&&Mp({sourceNode:r,targetNode:i,width:t.width,height:t.height,transform:t.transform})&&n.push(e.id)}return n},[e]),hh)}var h_=({color:e=`none`,strokeWidth:t=1})=>(0,W.jsx)(`polyline`,{className:`arrow`,style:{strokeWidth:t,...e&&{stroke:e}},strokeLinecap:`round`,fill:`none`,strokeLinejoin:`round`,points:`-5,-4 0,0 -5,4`}),g_=({color:e=`none`,strokeWidth:t=1})=>(0,W.jsx)(`polyline`,{className:`arrowclosed`,style:{strokeWidth:t,...e&&{stroke:e,fill:e}},strokeLinecap:`round`,strokeLinejoin:`round`,points:`-5,-4 0,0 -5,4 -5,-4`}),__={[Ef.Arrow]:h_,[Ef.ArrowClosed]:g_};function v_(e){let t=yh();return(0,U.useMemo)(()=>Object.prototype.hasOwnProperty.call(__,e)?__[e]:(t.getState().onError?.(`009`,_f.error009(e)),null),[e])}var y_=({id:e,type:t,color:n,width:r=12.5,height:i=12.5,markerUnits:a=`strokeWidth`,strokeWidth:o,orient:s=`auto-start-reverse`})=>{let c=v_(t);return c?(0,W.jsx)(`marker`,{className:`react-flow__arrowhead`,id:e,markerWidth:`${r}`,markerHeight:`${i}`,viewBox:`-10 -10 20 20`,markerUnits:a,orient:s,refX:`0`,refY:`0`,children:(0,W.jsx)(c,{color:n,strokeWidth:o})}):null},b_=({defaultColor:e,rfId:t})=>{let n=$(e=>e.edges),r=$(e=>e.defaultEdgeOptions),i=(0,U.useMemo)(()=>Yp(n,{id:t,defaultColor:e,defaultMarkerStart:r?.markerStart,defaultMarkerEnd:r?.markerEnd}),[n,r,t,e]);return i.length?(0,W.jsx)(`svg`,{className:`react-flow__marker`,"aria-hidden":`true`,children:(0,W.jsx)(`defs`,{children:i.map(e=>(0,W.jsx)(y_,{id:e.id,type:e.type,color:e.color,width:e.width,height:e.height,markerUnits:e.markerUnits,strokeWidth:e.strokeWidth,orient:e.orient},e.id))})}):null};b_.displayName=`MarkerDefinitions`;var x_=(0,U.memo)(b_);function S_({x:e,y:t,label:n,labelStyle:r,labelShowBg:i=!0,labelBgStyle:a,labelBgPadding:o=[2,4],labelBgBorderRadius:s=2,children:c,className:l,...u}){let[d,f]=(0,U.useState)({x:1,y:0,width:0,height:0}),p=zo([`react-flow__edge-textwrapper`,l]),m=(0,U.useRef)(null);return(0,U.useEffect)(()=>{if(m.current){let e=m.current.getBBox();f({x:e.x,y:e.y,width:e.width,height:e.height})}},[n]),n?(0,W.jsxs)(`g`,{transform:`translate(${e-d.width/2} ${t-d.height/2})`,className:p,visibility:d.width?`visible`:`hidden`,...u,children:[i&&(0,W.jsx)(`rect`,{width:d.width+2*o[0],x:-o[0],y:-o[1],height:d.height+2*o[1],className:`react-flow__edge-textbg`,style:a,rx:s,ry:s}),(0,W.jsx)(`text`,{className:`react-flow__edge-text`,y:d.height/2,dy:`0.3em`,ref:m,style:r,children:n}),c]}):null}S_.displayName=`EdgeText`;var C_=(0,U.memo)(S_);function w_({path:e,labelX:t,labelY:n,label:r,labelStyle:i,labelShowBg:a,labelBgStyle:o,labelBgPadding:s,labelBgBorderRadius:c,interactionWidth:l=20,...u}){return(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`path`,{...u,d:e,fill:`none`,className:zo([`react-flow__edge-path`,u.className])}),l?(0,W.jsx)(`path`,{d:e,fill:`none`,strokeOpacity:0,strokeWidth:l,className:`react-flow__edge-interaction`}):null,r&&tp(t)&&tp(n)?(0,W.jsx)(C_,{x:t,y:n,label:r,labelStyle:i,labelShowBg:a,labelBgStyle:o,labelBgPadding:s,labelBgBorderRadius:c}):null]})}function T_({pos:e,x1:t,y1:n,x2:r,y2:i}){return e===Q.Left||e===Q.Right?[.5*(t+r),n]:[t,.5*(n+i)]}function E_({sourceX:e,sourceY:t,sourcePosition:n=Q.Bottom,targetX:r,targetY:i,targetPosition:a=Q.Top}){let[o,s]=T_({pos:n,x1:e,y1:t,x2:r,y2:i}),[c,l]=T_({pos:a,x1:r,y1:i,x2:e,y2:t}),[u,d,f,p]=Ep({sourceX:e,sourceY:t,targetX:r,targetY:i,sourceControlX:o,sourceControlY:s,targetControlX:c,targetControlY:l});return[`M${e},${t} C${o},${s} ${c},${l} ${r},${i}`,u,d,f,p]}function D_(e){return(0,U.memo)(({id:t,sourceX:n,sourceY:r,targetX:i,targetY:a,sourcePosition:o,targetPosition:s,label:c,labelStyle:l,labelShowBg:u,labelBgStyle:d,labelBgPadding:f,labelBgBorderRadius:p,style:m,markerEnd:h,markerStart:g,interactionWidth:_})=>{let[v,y,b]=E_({sourceX:n,sourceY:r,sourcePosition:o,targetX:i,targetY:a,targetPosition:s});return(0,W.jsx)(w_,{id:e.isInternal?void 0:t,path:v,labelX:y,labelY:b,label:c,labelStyle:l,labelShowBg:u,labelBgStyle:d,labelBgPadding:f,labelBgBorderRadius:p,style:m,markerEnd:h,markerStart:g,interactionWidth:_})})}var O_=D_({isInternal:!1}),k_=D_({isInternal:!0});O_.displayName=`SimpleBezierEdge`,k_.displayName=`SimpleBezierEdgeInternal`;function A_(e){return(0,U.memo)(({id:t,sourceX:n,sourceY:r,targetX:i,targetY:a,label:o,labelStyle:s,labelShowBg:c,labelBgStyle:l,labelBgPadding:u,labelBgBorderRadius:d,style:f,sourcePosition:p=Q.Bottom,targetPosition:m=Q.Top,markerEnd:h,markerStart:g,pathOptions:_,interactionWidth:v})=>{let[y,b,x]=Hp({sourceX:n,sourceY:r,sourcePosition:p,targetX:i,targetY:a,targetPosition:m,borderRadius:_?.borderRadius,offset:_?.offset,stepPosition:_?.stepPosition});return(0,W.jsx)(w_,{id:e.isInternal?void 0:t,path:y,labelX:b,labelY:x,label:o,labelStyle:s,labelShowBg:c,labelBgStyle:l,labelBgPadding:u,labelBgBorderRadius:d,style:f,markerEnd:h,markerStart:g,interactionWidth:v})})}var j_=A_({isInternal:!1}),M_=A_({isInternal:!0});j_.displayName=`SmoothStepEdge`,M_.displayName=`SmoothStepEdgeInternal`;function N_(e){return(0,U.memo)(({id:t,...n})=>{let r=e.isInternal?void 0:t;return(0,W.jsx)(j_,{...n,id:r,pathOptions:(0,U.useMemo)(()=>({borderRadius:0,offset:n.pathOptions?.offset}),[n.pathOptions?.offset])})})}var P_=N_({isInternal:!1}),F_=N_({isInternal:!0});P_.displayName=`StepEdge`,F_.displayName=`StepEdgeInternal`;function I_(e){return(0,U.memo)(({id:t,sourceX:n,sourceY:r,targetX:i,targetY:a,label:o,labelStyle:s,labelShowBg:c,labelBgStyle:l,labelBgPadding:u,labelBgBorderRadius:d,style:f,markerEnd:p,markerStart:m,interactionWidth:h})=>{let[g,_,v]=Ip({sourceX:n,sourceY:r,targetX:i,targetY:a});return(0,W.jsx)(w_,{id:e.isInternal?void 0:t,path:g,labelX:_,labelY:v,label:o,labelStyle:s,labelShowBg:c,labelBgStyle:l,labelBgPadding:u,labelBgBorderRadius:d,style:f,markerEnd:p,markerStart:m,interactionWidth:h})})}var L_=I_({isInternal:!1}),R_=I_({isInternal:!0});L_.displayName=`StraightEdge`,R_.displayName=`StraightEdgeInternal`;function z_(e){return(0,U.memo)(({id:t,sourceX:n,sourceY:r,targetX:i,targetY:a,sourcePosition:o=Q.Bottom,targetPosition:s=Q.Top,label:c,labelStyle:l,labelShowBg:u,labelBgStyle:d,labelBgPadding:f,labelBgBorderRadius:p,style:m,markerEnd:h,markerStart:g,pathOptions:_,interactionWidth:v})=>{let[y,b,x]=kp({sourceX:n,sourceY:r,sourcePosition:o,targetX:i,targetY:a,targetPosition:s,curvature:_?.curvature});return(0,W.jsx)(w_,{id:e.isInternal?void 0:t,path:y,labelX:b,labelY:x,label:c,labelStyle:l,labelShowBg:u,labelBgStyle:d,labelBgPadding:f,labelBgBorderRadius:p,style:m,markerEnd:h,markerStart:g,interactionWidth:v})})}var B_=z_({isInternal:!1}),V_=z_({isInternal:!0});B_.displayName=`BezierEdge`,V_.displayName=`BezierEdgeInternal`;var H_={default:V_,straight:R_,step:F_,smoothstep:M_,simplebezier:k_},U_={sourceX:null,sourceY:null,targetX:null,targetY:null,sourcePosition:null,targetPosition:null,zIndex:void 0},W_=(e,t,n)=>n===Q.Left?e-t:n===Q.Right?e+t:e,G_=(e,t,n)=>n===Q.Top?e-t:n===Q.Bottom?e+t:e,K_=`react-flow__edgeupdater`;function q_({position:e,centerX:t,centerY:n,radius:r=10,onMouseDown:i,onMouseEnter:a,onMouseOut:o,type:s}){return(0,W.jsx)(`circle`,{onMouseDown:i,onMouseEnter:a,onMouseOut:o,className:zo([K_,`${K_}-${s}`]),cx:W_(t,r,e),cy:G_(n,r,e),r,stroke:`transparent`,fill:`transparent`})}function J_({isReconnectable:e,reconnectRadius:t,edge:n,sourceX:r,sourceY:i,targetX:a,targetY:o,sourcePosition:s,targetPosition:c,onReconnect:l,onReconnectStart:u,onReconnectEnd:d,setReconnecting:f,setUpdateHover:p}){let m=yh(),h=(e,t)=>{if(e.button!==0)return;let{autoPanOnConnect:r,domNode:i,connectionMode:a,connectionRadius:o,lib:s,onConnectStart:c,cancelConnection:p,nodeLookup:h,rfId:g,panBy:_,updateConnection:v}=m.getState(),y=t.type===`target`;km.onPointerDown(e.nativeEvent,{autoPanOnConnect:r,connectionMode:a,connectionRadius:o,domNode:i,handleId:t.id,nodeId:t.nodeId,nodeLookup:h,isTarget:y,edgeUpdaterType:t.type,lib:s,flowId:g,cancelConnection:p,panBy:_,isValidConnection:(...e)=>m.getState().isValidConnection?.(...e)??!0,onConnect:e=>l?.(n,e),onConnectStart:(r,i)=>{f(!0),u?.(e,n,t.type),c?.(r,i)},onConnectEnd:(...e)=>m.getState().onConnectEnd?.(...e),onReconnectEnd:(e,r)=>{f(!1),d?.(e,n,t.type,r)},updateConnection:v,getTransform:()=>m.getState().transform,getFromHandle:()=>m.getState().connection.fromHandle,dragThreshold:m.getState().connectionDragThreshold,handleDomNode:e.currentTarget})},g=e=>h(e,{nodeId:n.target,id:n.targetHandle??null,type:`target`}),_=e=>h(e,{nodeId:n.source,id:n.sourceHandle??null,type:`source`}),v=()=>p(!0),y=()=>p(!1);return(0,W.jsxs)(W.Fragment,{children:[(e===!0||e===`source`)&&(0,W.jsx)(q_,{position:s,centerX:r,centerY:i,radius:t,onMouseDown:g,onMouseEnter:v,onMouseOut:y,type:`source`}),(e===!0||e===`target`)&&(0,W.jsx)(q_,{position:c,centerX:a,centerY:o,radius:t,onMouseDown:_,onMouseEnter:v,onMouseOut:y,type:`target`})]})}function Y_({id:e,edgesFocusable:t,edgesReconnectable:n,elementsSelectable:r,onClick:i,onDoubleClick:a,onContextMenu:o,onMouseEnter:s,onMouseMove:c,onMouseLeave:l,reconnectRadius:u,onReconnect:d,onReconnectStart:f,onReconnectEnd:p,rfId:m,edgeTypes:h,noPanClassName:g,onError:_,disableKeyboardA11y:v}){let y=$(t=>t.edgeLookup.get(e)),b=$(e=>e.defaultEdgeOptions);y=b?{...b,...y}:y;let x=y.type||`default`,S=h?.[x]||H_[x];S===void 0&&(_?.(`011`,_f.error011(x)),x=`default`,S=h?.default||H_.default);let C=!!(y.focusable||t&&y.focusable===void 0),w=d!==void 0&&(y.reconnectable||n&&y.reconnectable===void 0),T=!!(y.selectable||r&&y.selectable===void 0),E=(0,U.useRef)(null),[D,O]=(0,U.useState)(!1),[k,A]=(0,U.useState)(!1),j=yh(),{zIndex:M=y.zIndex,sourceX:ee,sourceY:te,targetX:ne,targetY:N,sourcePosition:P,targetPosition:F}=$((0,U.useCallback)(t=>{let n=t.nodeLookup.get(y.source),r=t.nodeLookup.get(y.target);if(!n||!r)return U_;let i=Wp({id:e,sourceNode:n,targetNode:r,sourceHandle:y.sourceHandle||null,targetHandle:y.targetHandle||null,connectionMode:t.connectionMode,onError:_}),a=jp({selected:y.selected,zIndex:y.zIndex,sourceNode:n,targetNode:r,elevateOnSelect:t.elevateEdgesOnSelect,zIndexMode:t.zIndexMode});return{...i||U_,zIndex:a}},[y.source,y.target,y.sourceHandle,y.targetHandle,y.selected,y.zIndex]),hh),re=(0,U.useMemo)(()=>y.markerStart?`url('#${Jp(y.markerStart,m)}')`:void 0,[y.markerStart,m]),ie=(0,U.useMemo)(()=>y.markerEnd?`url('#${Jp(y.markerEnd,m)}')`:void 0,[y.markerEnd,m]);if(y.hidden||ee===null||te===null||ne===null||N===null)return null;let ae=t=>{let{addSelectedEdges:n,unselectNodesAndEdges:r,multiSelectionActive:a}=j.getState();T&&(j.setState({nodesSelectionActive:!1}),y.selected&&a?(r({nodes:[],edges:[y]}),E.current?.blur()):n([e])),i&&i(t,y)},I=a?e=>{a(e,{...y})}:void 0,L=o?e=>{o(e,{...y})}:void 0,oe=s?e=>{s(e,{...y})}:void 0,se=c?e=>{c(e,{...y})}:void 0,ce=l?e=>{l(e,{...y})}:void 0;return(0,W.jsx)(`svg`,{style:{zIndex:M},children:(0,W.jsxs)(`g`,{className:zo([`react-flow__edge`,`react-flow__edge-${x}`,y.className,g,{selected:y.selected,animated:y.animated,inactive:!T&&!i,updating:D,selectable:T}]),onClick:ae,onDoubleClick:I,onContextMenu:L,onMouseEnter:oe,onMouseMove:se,onMouseLeave:ce,onKeyDown:C?t=>{if(!v&&yf.includes(t.key)&&T){let{unselectNodesAndEdges:n,addSelectedEdges:r}=j.getState();t.key===`Escape`?(E.current?.blur(),n({edges:[y]})):r([e])}}:void 0,tabIndex:C?0:void 0,role:y.ariaRole??(C?`group`:`img`),"aria-roledescription":`edge`,"data-id":e,"data-testid":`rf__edge-${e}`,"aria-label":y.ariaLabel===null?void 0:y.ariaLabel||`Edge from ${y.source} to ${y.target}`,"aria-describedby":C?`${Ch}-${m}`:void 0,ref:E,...y.domAttributes,children:[!k&&(0,W.jsx)(S,{id:e,source:y.source,target:y.target,type:y.type,selected:y.selected,animated:y.animated,selectable:T,deletable:y.deletable??!0,label:y.label,labelStyle:y.labelStyle,labelShowBg:y.labelShowBg,labelBgStyle:y.labelBgStyle,labelBgPadding:y.labelBgPadding,labelBgBorderRadius:y.labelBgBorderRadius,sourceX:ee,sourceY:te,targetX:ne,targetY:N,sourcePosition:P,targetPosition:F,data:y.data,style:y.style,sourceHandleId:y.sourceHandle,targetHandleId:y.targetHandle,markerStart:re,markerEnd:ie,pathOptions:`pathOptions`in y?y.pathOptions:void 0,interactionWidth:y.interactionWidth}),w&&(0,W.jsx)(J_,{edge:y,isReconnectable:w,reconnectRadius:u,onReconnect:d,onReconnectStart:f,onReconnectEnd:p,sourceX:ee,sourceY:te,targetX:ne,targetY:N,sourcePosition:P,targetPosition:F,setUpdateHover:O,setReconnecting:A})]})})}var X_=(0,U.memo)(Y_),Z_=e=>({edgesFocusable:e.edgesFocusable,edgesReconnectable:e.edgesReconnectable,elementsSelectable:e.elementsSelectable,connectionMode:e.connectionMode,onError:e.onError});function Q_({defaultMarkerColor:e,onlyRenderVisibleElements:t,rfId:n,edgeTypes:r,noPanClassName:i,onReconnect:a,onEdgeContextMenu:o,onEdgeMouseEnter:s,onEdgeMouseMove:c,onEdgeMouseLeave:l,onEdgeClick:u,reconnectRadius:d,onEdgeDoubleClick:f,onReconnectStart:p,onReconnectEnd:m,disableKeyboardA11y:h}){let{edgesFocusable:g,edgesReconnectable:_,elementsSelectable:v,onError:y}=$(Z_,hh),b=m_(t);return(0,W.jsxs)(`div`,{className:`react-flow__edges`,children:[(0,W.jsx)(x_,{defaultColor:e,rfId:n}),b.map(e=>(0,W.jsx)(X_,{id:e,edgesFocusable:g,edgesReconnectable:_,elementsSelectable:v,noPanClassName:i,onReconnect:a,onContextMenu:o,onMouseEnter:s,onMouseMove:c,onMouseLeave:l,onClick:u,reconnectRadius:d,onDoubleClick:f,onReconnectStart:p,onReconnectEnd:m,rfId:n,onError:y,edgeTypes:r,disableKeyboardA11y:h},e))]})}Q_.displayName=`EdgeRenderer`;var $_=(0,U.memo)(Q_),ev=e=>`translate(${e[0]}px,${e[1]}px) scale(${e[2]})`;function tv({children:e}){let t=yh(),n=(0,U.useRef)(null),[r]=(0,U.useState)(()=>t.getState().transform);return ug(()=>{let e=null,r=()=>{let r=t.getState().transform;e&&r[0]===e[0]&&r[1]===e[1]&&r[2]===e[2]||(e=r,n.current&&(n.current.style.transform=ev(r)))};return r(),t.subscribe(r)},[t]),(0,W.jsx)(`div`,{ref:n,className:`react-flow__viewport xyflow__viewport react-flow__container`,style:{transform:ev(r)},children:e})}function nv(e){let t=_g(),n=(0,U.useRef)(!1);(0,U.useEffect)(()=>{!n.current&&t.viewportInitialized&&e&&(setTimeout(()=>e(t),1),n.current=!0)},[e,t.viewportInitialized])}var rv=e=>e.panZoom?.syncViewport;function iv(e){let t=$(rv),n=yh();return(0,U.useEffect)(()=>{e&&(t?.(e),n.setState({transform:[e.x,e.y,e.zoom]}))},[e,t]),null}function av(e){return e.connection.inProgress?{...e.connection,to:ip(e.connection.to,e.transform)}:{...e.connection}}function ov(e){return e?t=>e(av(t)):av}function sv(e){return $(ov(e),hh)}var cv=e=>({nodesConnectable:e.nodesConnectable,isValid:e.connection.isValid,inProgress:e.connection.inProgress,width:e.width,height:e.height});function lv({containerStyle:e,style:t,type:n,component:r}){let{nodesConnectable:i,width:a,height:o,isValid:s,inProgress:c}=$(cv,hh);return a&&i&&c?(0,W.jsx)(`svg`,{style:e,width:a,height:o,className:`react-flow__connectionline react-flow__container`,children:(0,W.jsx)(`g`,{className:zo([`react-flow__connection`,Of(s)]),children:(0,W.jsx)(uv,{style:t,type:n,CustomComponent:r,isValid:s})})}):null}var uv=({style:e,type:t=Tf.Bezier,CustomComponent:n,isValid:r})=>{let{inProgress:i,from:a,fromNode:o,fromHandle:s,fromPosition:c,to:l,toNode:u,toHandle:d,toPosition:f,pointer:p}=sv();if(!i)return;if(n)return(0,W.jsx)(n,{connectionLineType:t,connectionLineStyle:e,fromNode:o,fromHandle:s,fromX:a.x,fromY:a.y,toX:l.x,toY:l.y,fromPosition:c,toPosition:f,connectionStatus:Of(r),toNode:u,toHandle:d,pointer:p});let m=``,h={sourceX:a.x,sourceY:a.y,sourcePosition:c,targetX:l.x,targetY:l.y,targetPosition:f};switch(t){case Tf.Bezier:[m]=kp(h);break;case Tf.SimpleBezier:[m]=E_(h);break;case Tf.Step:[m]=Hp({...h,borderRadius:0});break;case Tf.SmoothStep:[m]=Hp(h);break;default:[m]=Ip(h)}return(0,W.jsx)(`path`,{d:m,fill:`none`,className:`react-flow__connection-path`,style:e})};uv.displayName=`ConnectionLine`;var dv={};function fv(e=dv){(0,U.useRef)(e),yh(),(0,U.useEffect)(()=>{},[e])}function pv(){yh(),(0,U.useRef)(!1),(0,U.useEffect)(()=>{},[])}function mv({nodeTypes:e,edgeTypes:t,onInit:n,onNodeClick:r,onEdgeClick:i,onNodeDoubleClick:a,onEdgeDoubleClick:o,onNodeMouseEnter:s,onNodeMouseMove:c,onNodeMouseLeave:l,onNodeContextMenu:u,onSelectionContextMenu:d,onSelectionStart:f,onSelectionEnd:p,connectionLineType:m,connectionLineStyle:h,connectionLineComponent:g,connectionLineContainerStyle:_,selectionKeyCode:v,selectionOnDrag:y,selectionMode:b,multiSelectionKeyCode:x,panActivationKeyCode:S,zoomActivationKeyCode:C,deleteKeyCode:w,onlyRenderVisibleElements:T,elementsSelectable:E,defaultViewport:D,translateExtent:O,minZoom:k,maxZoom:A,preventScrolling:j,defaultMarkerColor:M,zoomOnScroll:ee,zoomOnPinch:te,panOnScroll:ne,panOnScrollSpeed:N,panOnScrollMode:P,zoomOnDoubleClick:F,panOnDrag:re,autoPanOnSelection:ie,onPaneClick:ae,onPaneMouseEnter:I,onPaneMouseMove:L,onPaneMouseLeave:oe,onPaneScroll:se,onPaneContextMenu:ce,paneClickDistance:le,nodeClickDistance:ue,onEdgeContextMenu:de,onEdgeMouseEnter:fe,onEdgeMouseMove:pe,onEdgeMouseLeave:me,reconnectRadius:he,onReconnect:ge,onReconnectStart:_e,onReconnectEnd:ve,noDragClassName:ye,noWheelClassName:be,noPanClassName:xe,disableKeyboardA11y:Se,nodeExtent:Ce,rfId:we,viewport:Te,onViewportChange:Ee,nodesDraggable:De}){return fv(e),fv(t),pv(),nv(n),iv(Te),(0,W.jsx)(r_,{onPaneClick:ae,onPaneMouseEnter:I,onPaneMouseMove:L,onPaneMouseLeave:oe,onPaneContextMenu:ce,onPaneScroll:se,paneClickDistance:le,deleteKeyCode:w,selectionKeyCode:v,selectionOnDrag:y,selectionMode:b,onSelectionStart:f,onSelectionEnd:p,multiSelectionKeyCode:x,panActivationKeyCode:S,zoomActivationKeyCode:C,elementsSelectable:E,zoomOnScroll:ee,zoomOnPinch:te,zoomOnDoubleClick:F,panOnScroll:ne,panOnScrollSpeed:N,panOnScrollMode:P,panOnDrag:re,autoPanOnSelection:ie,defaultViewport:D,translateExtent:O,minZoom:k,maxZoom:A,onSelectionContextMenu:d,preventScrolling:j,noDragClassName:ye,noWheelClassName:be,noPanClassName:xe,disableKeyboardA11y:Se,onViewportChange:Ee,isControlledViewport:!!Te,children:(0,W.jsxs)(tv,{children:[(0,W.jsx)($_,{edgeTypes:t,onEdgeClick:i,onEdgeDoubleClick:o,onReconnect:ge,onReconnectStart:_e,onReconnectEnd:ve,onlyRenderVisibleElements:T,onEdgeContextMenu:de,onEdgeMouseEnter:fe,onEdgeMouseMove:pe,onEdgeMouseLeave:me,reconnectRadius:he,defaultMarkerColor:M,noPanClassName:xe,disableKeyboardA11y:Se,rfId:we}),(0,W.jsx)(lv,{style:h,type:m,component:g,containerStyle:_}),(0,W.jsx)(`div`,{className:`react-flow__edgelabel-renderer`}),(0,W.jsx)(p_,{nodeTypes:e,onNodeClick:r,onNodeDoubleClick:a,onNodeMouseEnter:s,onNodeMouseMove:c,onNodeMouseLeave:l,onNodeContextMenu:u,nodeClickDistance:ue,onlyRenderVisibleElements:T,noPanClassName:xe,noDragClassName:ye,disableKeyboardA11y:Se,nodeExtent:Ce,rfId:we,nodesDraggable:De}),(0,W.jsx)(`div`,{className:`react-flow__viewport-portal`})]})})}mv.displayName=`GraphView`;var hv=(0,U.memo)(mv),gv=np(`React Flow`,`https://reactflow.dev/`),_v=({nodes:e,edges:t,defaultNodes:n,defaultEdges:r,width:i,height:a,fitView:o,fitViewOptions:s,minZoom:c=.5,maxZoom:l=2,nodeOrigin:u,nodeExtent:d,zIndexMode:f=`basic`}={})=>{let p=new Map,m=new Map,h=new Map,g=new Map,_=r??t??[],v=n??e??[],y=u??[0,0],b=d??vf;pm(h,g,_);let{nodesInitialized:x}=im(v,p,m,{nodeOrigin:y,nodeExtent:b,zIndexMode:f}),S=[0,0,1];if(o&&i&&a){let{x:e,y:t,zoom:n}=lp(Pf(p,{filter:e=>!!((e.width||e.initialWidth)&&(e.height||e.initialHeight))}),i,a,c,l,s?.padding??.1);S=[e,t,n]}return{rfId:`1`,width:i??0,height:a??0,transform:S,nodes:v,nodesInitialized:x,nodeLookup:p,parentLookup:m,edges:_,edgeLookup:g,connectionLookup:h,onNodesChange:null,onEdgesChange:null,hasDefaultNodes:n!==void 0,hasDefaultEdges:r!==void 0,panZoom:null,minZoom:c,maxZoom:l,translateExtent:vf,nodeExtent:b,nodesSelectionActive:!1,userSelectionActive:!1,userSelectionRect:null,connectionMode:xf.Strict,domNode:null,paneDragging:!1,noPanClassName:`nopan`,nodeOrigin:y,nodeDragThreshold:1,connectionDragThreshold:1,snapGrid:[15,15],snapToGrid:!1,nodesDraggable:!0,nodesConnectable:!0,nodesFocusable:!0,edgesFocusable:!0,edgesReconnectable:!0,elementsSelectable:!0,elevateNodesOnSelect:!0,elevateEdgesOnSelect:!0,selectNodesOnDrag:!0,multiSelectionActive:!1,fitViewQueued:o??!1,fitViewOptions:s,fitViewResolver:null,connection:{...wf},connectionClickStartHandle:null,connectOnClick:!0,ariaLiveMessage:``,autoPanOnConnect:!0,autoPanOnNodeDrag:!0,autoPanOnNodeFocus:!0,autoPanSpeed:15,connectionRadius:20,onError:gv,isValidConnection:void 0,onSelectionChangeHandlers:[],lib:`react`,debug:!1,ariaLabelConfig:bf,zIndexMode:f,onNodesChangeMiddlewareMap:new Map,onEdgesChangeMiddlewareMap:new Map}},vv=({nodes:e,edges:t,defaultNodes:n,defaultEdges:r,width:i,height:a,fitView:o,fitViewOptions:s,minZoom:c,maxZoom:l,nodeOrigin:u,nodeExtent:d,zIndexMode:f})=>mh((p,m)=>{async function h(){let{nodeLookup:e,panZoom:t,fitViewOptions:n,fitViewResolver:r,width:i,height:a,minZoom:o,maxZoom:s}=m();t&&(await Rf({nodes:e,width:i,height:a,panZoom:t,minZoom:o,maxZoom:s},n),r?.resolve(!0),p({fitViewResolver:null}))}return{..._v({nodes:e,edges:t,width:i,height:a,fitView:o,fitViewOptions:s,minZoom:c,maxZoom:l,nodeOrigin:u,nodeExtent:d,defaultNodes:n,defaultEdges:r,zIndexMode:f}),setNodes:e=>{let{nodeLookup:t,parentLookup:n,nodeOrigin:r,elevateNodesOnSelect:i,fitViewQueued:a,zIndexMode:o,nodesSelectionActive:s}=m(),{nodesInitialized:c,hasSelectedNodes:l}=im(e,t,n,{nodeOrigin:r,nodeExtent:d,elevateNodesOnSelect:i,checkEquality:!0,zIndexMode:o}),u=s&&l;a&&c?(h(),p({nodes:e,nodesInitialized:c,fitViewQueued:!1,fitViewOptions:void 0,nodesSelectionActive:u})):p({nodes:e,nodesInitialized:c,nodesSelectionActive:u})},setEdges:e=>{let{connectionLookup:t,edgeLookup:n}=m();pm(t,n,e),p({edges:e})},setDefaultNodesAndEdges:(e,t)=>{if(e){let{setNodes:t}=m();t(e),p({hasDefaultNodes:!0})}if(t){let{setEdges:e}=m();e(t),p({hasDefaultEdges:!0})}},updateNodeInternals:e=>{let{triggerNodeChanges:t,nodeLookup:n,parentLookup:r,domNode:i,nodeOrigin:a,nodeExtent:o,debug:s,fitViewQueued:c,zIndexMode:l}=m(),{changes:u,updatedInternals:d}=um(e,n,r,i,a,o,l);d&&(tm(n,r,{nodeOrigin:a,nodeExtent:o,zIndexMode:l}),c?(h(),p({fitViewQueued:!1,fitViewOptions:void 0})):p({}),u?.length>0&&(s&&console.log(`React Flow: trigger node changes`,u),t?.(u)))},updateNodePositions:(e,t=!1)=>{let n=[],r=[],{nodeLookup:i,triggerNodeChanges:a,connection:o,updateConnection:s,onNodesChangeMiddlewareMap:c}=m();for(let[a,c]of e){let e=i.get(a),l=!!(e?.expandParent&&e?.parentId&&c?.position),u={id:a,type:`position`,position:l?{x:Math.max(0,c.position.x),y:Math.max(0,c.position.y)}:c.position,dragging:t};if(e&&o.inProgress&&o.fromNode.id===e.id){let t=Kp(e,o.fromHandle,Q.Left,!0);s({...o,from:t})}l&&e.parentId&&n.push({id:a,parentId:e.parentId,rect:{...c.internals.positionAbsolute,width:c.measured.width??0,height:c.measured.height??0}}),r.push(u)}if(n.length>0){let{parentLookup:e,nodeOrigin:t}=m(),a=lm(n,i,e,t);r.push(...a)}for(let e of c.values())r=e(r);a(r)},triggerNodeChanges:e=>{let{onNodesChange:t,setNodes:n,nodes:r,hasDefaultNodes:i,debug:a}=m();e?.length&&(i&&n($h(e,r)),a&&console.log(`React Flow: trigger node changes`,e),t?.(e))},triggerEdgeChanges:e=>{let{onEdgesChange:t,setEdges:n,edges:r,hasDefaultEdges:i,debug:a}=m();e?.length&&(i&&n(eg(e,r)),a&&console.log(`React Flow: trigger edge changes`,e),t?.(e))},addSelectedNodes:e=>{let{multiSelectionActive:t,edgeLookup:n,nodeLookup:r,triggerNodeChanges:i,triggerEdgeChanges:a}=m();if(t){i(e.map(e=>tg(e,!0)));return}i(ng(r,new Set([...e]),!0)),a(ng(n))},addSelectedEdges:e=>{let{multiSelectionActive:t,edgeLookup:n,nodeLookup:r,triggerNodeChanges:i,triggerEdgeChanges:a}=m();if(t){a(e.map(e=>tg(e,!0)));return}a(ng(n,new Set([...e]))),i(ng(r,new Set,!0))},unselectNodesAndEdges:({nodes:e,edges:t}={})=>{let{edges:n,nodes:r,nodeLookup:i,triggerNodeChanges:a,triggerEdgeChanges:o}=m(),s=e||r,c=t||n,l=[];for(let e of s){if(!e.selected)continue;let t=i.get(e.id);t&&(t.selected=!1),l.push(tg(e.id,!1))}let u=[];for(let e of c)e.selected&&u.push(tg(e.id,!1));a(l),o(u)},setMinZoom:e=>{let{panZoom:t,maxZoom:n}=m();t?.setScaleExtent([e,n]),p({minZoom:e})},setMaxZoom:e=>{let{panZoom:t,minZoom:n}=m();t?.setScaleExtent([n,e]),p({maxZoom:e})},setTranslateExtent:e=>{m().panZoom?.setTranslateExtent(e),p({translateExtent:e})},resetSelectedElements:()=>{let{edges:e,nodes:t,triggerNodeChanges:n,triggerEdgeChanges:r,elementsSelectable:i}=m();if(!i)return;let a=t.reduce((e,t)=>t.selected?[...e,tg(t.id,!1)]:e,[]),o=e.reduce((e,t)=>t.selected?[...e,tg(t.id,!1)]:e,[]);n(a),r(o)},setNodeExtent:e=>{let{nodes:t,nodeLookup:n,parentLookup:r,nodeOrigin:i,elevateNodesOnSelect:a,nodeExtent:o,zIndexMode:s}=m();e[0][0]===o[0][0]&&e[0][1]===o[0][1]&&e[1][0]===o[1][0]&&e[1][1]===o[1][1]||(im(t,n,r,{nodeOrigin:i,nodeExtent:e,elevateNodesOnSelect:a,checkEquality:!1,zIndexMode:s}),p({nodeExtent:e}))},panBy:e=>{let{transform:t,width:n,height:r,panZoom:i,translateExtent:a}=m();return dm({delta:e,panZoom:i,transform:t,translateExtent:a,width:n,height:r})},setCenter:async(e,t,n)=>{let{width:r,height:i,maxZoom:a,panZoom:o}=m();if(!o)return!1;let s=n?.zoom===void 0?a:n.zoom;return await o.setViewport({x:r/2-e*s,y:i/2-t*s,zoom:s},{duration:n?.duration,ease:n?.ease,interpolate:n?.interpolate}),!0},cancelConnection:()=>{p({connection:{...wf}})},updateConnection:e=>{p({connection:e})},reset:()=>p({..._v()})}},Object.is);function yv({initialNodes:e,initialEdges:t,defaultNodes:n,defaultEdges:r,initialWidth:i,initialHeight:a,initialMinZoom:o,initialMaxZoom:s,initialFitViewOptions:c,fitView:l,nodeOrigin:u,nodeExtent:d,zIndexMode:f,children:p}){let[m]=(0,U.useState)(()=>vv({nodes:e,edges:t,defaultNodes:n,defaultEdges:r,width:i,height:a,fitView:l,minZoom:o,maxZoom:s,fitViewOptions:c,nodeOrigin:u,nodeExtent:d,zIndexMode:f}));return(0,W.jsx)(_h,{value:m,children:(0,W.jsx)(mg,{children:(0,W.jsx)(zg,{children:p})})})}function bv({children:e,nodes:t,edges:n,defaultNodes:r,defaultEdges:i,width:a,height:o,fitView:s,fitViewOptions:c,minZoom:l,maxZoom:u,nodeOrigin:d,nodeExtent:f,zIndexMode:p}){return(0,U.useContext)(gh)?(0,W.jsx)(W.Fragment,{children:e}):(0,W.jsx)(yv,{initialNodes:t,initialEdges:n,defaultNodes:r,defaultEdges:i,initialWidth:a,initialHeight:o,fitView:s,initialFitViewOptions:c,initialMinZoom:l,initialMaxZoom:u,nodeOrigin:d,nodeExtent:f,zIndexMode:p,children:e})}var xv={width:`100%`,height:`100%`,overflow:`hidden`,position:`relative`,zIndex:0};function Sv({nodes:e,edges:t,defaultNodes:n,defaultEdges:r,className:i,nodeTypes:a,edgeTypes:o,onNodeClick:s,onEdgeClick:c,onInit:l,onMove:u,onMoveStart:d,onMoveEnd:f,onConnect:p,onConnectStart:m,onConnectEnd:h,onClickConnectStart:g,onClickConnectEnd:_,onNodeMouseEnter:v,onNodeMouseMove:y,onNodeMouseLeave:b,onNodeContextMenu:x,onNodeDoubleClick:S,onNodeDragStart:C,onNodeDrag:w,onNodeDragStop:T,onNodesDelete:E,onEdgesDelete:D,onDelete:O,onSelectionChange:k,onSelectionDragStart:A,onSelectionDrag:j,onSelectionDragStop:M,onSelectionContextMenu:ee,onSelectionStart:te,onSelectionEnd:ne,onBeforeDelete:N,connectionMode:P,connectionLineType:F=Tf.Bezier,connectionLineStyle:re,connectionLineComponent:ie,connectionLineContainerStyle:ae,deleteKeyCode:I=`Backspace`,selectionKeyCode:L=`Shift`,selectionOnDrag:oe=!1,selectionMode:se=Cf.Full,panActivationKeyCode:ce=`Space`,multiSelectionKeyCode:le=up()?`Meta`:`Control`,zoomActivationKeyCode:ue=up()?`Meta`:`Control`,snapToGrid:de,snapGrid:fe,onlyRenderVisibleElements:pe=!1,selectNodesOnDrag:me,nodesDraggable:he,autoPanOnNodeFocus:ge,nodesConnectable:_e,nodesFocusable:ve,nodeOrigin:ye=Rh,edgesFocusable:be,edgesReconnectable:xe,elementsSelectable:Se=!0,defaultViewport:Ce=zh,minZoom:we=.5,maxZoom:Te=2,translateExtent:Ee=vf,preventScrolling:De=!0,nodeExtent:Oe,defaultMarkerColor:ke=`#b1b1b7`,zoomOnScroll:Ae=!0,zoomOnPinch:je=!0,panOnScroll:Me=!1,panOnScrollSpeed:Ne=.5,panOnScrollMode:Pe=Sf.Free,zoomOnDoubleClick:Fe=!0,panOnDrag:Ie=!0,onPaneClick:Le,onPaneMouseEnter:Re,onPaneMouseMove:ze,onPaneMouseLeave:Be,onPaneScroll:Ve,onPaneContextMenu:He,paneClickDistance:Ue=1,nodeClickDistance:We=0,children:Ge,onReconnect:Ke,onReconnectStart:qe,onReconnectEnd:Je,onEdgeContextMenu:Ye,onEdgeDoubleClick:Xe,onEdgeMouseEnter:Ze,onEdgeMouseMove:Qe,onEdgeMouseLeave:$e,reconnectRadius:et=10,onNodesChange:tt,onEdgesChange:nt,noDragClassName:rt=`nodrag`,noWheelClassName:it=`nowheel`,noPanClassName:at=`nopan`,fitView:ot,fitViewOptions:st,connectOnClick:ct,attributionPosition:lt,proOptions:ut,defaultEdgeOptions:dt,elevateNodesOnSelect:ft=!0,elevateEdgesOnSelect:pt=!1,disableKeyboardA11y:mt=!1,autoPanOnConnect:ht,autoPanOnNodeDrag:gt,autoPanOnSelection:_t=!0,autoPanSpeed:vt,connectionRadius:yt,isValidConnection:bt,onError:xt,style:St,id:Ct,nodeDragThreshold:wt,connectionDragThreshold:Tt,viewport:Et,onViewportChange:Dt,width:Ot,height:kt,colorMode:At=`light`,debug:jt,onScroll:Mt,ariaLabelConfig:Nt,zIndexMode:Pt=`basic`,...Ft},It){let Lt=Ct||`1`,Rt=Gh(At),R=(0,U.useCallback)(e=>{e.currentTarget.scrollTo({top:0,left:0,behavior:`instant`}),Mt?.(e)},[Mt]);return(0,W.jsx)(`div`,{"data-testid":`rf__wrapper`,...Ft,onScroll:R,style:{...St,...xv},ref:It,className:zo([`react-flow`,i,Rt]),id:Ct,role:`application`,children:(0,W.jsxs)(bv,{nodes:e,edges:t,width:Ot,height:kt,fitView:ot,fitViewOptions:st,minZoom:we,maxZoom:Te,nodeOrigin:ye,nodeExtent:Oe,zIndexMode:Pt,children:[(0,W.jsx)(Uh,{nodes:e,edges:t,defaultNodes:n,defaultEdges:r,onConnect:p,onConnectStart:m,onConnectEnd:h,onClickConnectStart:g,onClickConnectEnd:_,nodesDraggable:he,autoPanOnNodeFocus:ge,nodesConnectable:_e,nodesFocusable:ve,edgesFocusable:be,edgesReconnectable:xe,elementsSelectable:Se,elevateNodesOnSelect:ft,elevateEdgesOnSelect:pt,minZoom:we,maxZoom:Te,nodeExtent:Oe,onNodesChange:tt,onEdgesChange:nt,snapToGrid:de,snapGrid:fe,connectionMode:P,translateExtent:Ee,connectOnClick:ct,defaultEdgeOptions:dt,fitView:ot,fitViewOptions:st,onNodesDelete:E,onEdgesDelete:D,onDelete:O,onNodeDragStart:C,onNodeDrag:w,onNodeDragStop:T,onSelectionDrag:j,onSelectionDragStart:A,onSelectionDragStop:M,onMove:u,onMoveStart:d,onMoveEnd:f,noPanClassName:at,nodeOrigin:ye,rfId:Lt,autoPanOnConnect:ht,autoPanOnNodeDrag:gt,autoPanSpeed:vt,onError:xt,connectionRadius:yt,isValidConnection:bt,selectNodesOnDrag:me,nodeDragThreshold:wt,connectionDragThreshold:Tt,onBeforeDelete:N,debug:jt,ariaLabelConfig:Nt,zIndexMode:Pt}),(0,W.jsx)(hv,{onInit:l,onNodeClick:s,onEdgeClick:c,onNodeMouseEnter:v,onNodeMouseMove:y,onNodeMouseLeave:b,onNodeContextMenu:x,onNodeDoubleClick:S,nodeTypes:a,edgeTypes:o,connectionLineType:F,connectionLineStyle:re,connectionLineComponent:ie,connectionLineContainerStyle:ae,selectionKeyCode:L,selectionOnDrag:oe,selectionMode:se,deleteKeyCode:I,multiSelectionKeyCode:le,panActivationKeyCode:ce,zoomActivationKeyCode:ue,onlyRenderVisibleElements:pe,defaultViewport:Ce,translateExtent:Ee,minZoom:we,maxZoom:Te,preventScrolling:De,zoomOnScroll:Ae,zoomOnPinch:je,zoomOnDoubleClick:Fe,panOnScroll:Me,panOnScrollSpeed:Ne,panOnScrollMode:Pe,panOnDrag:Ie,autoPanOnSelection:_t,onPaneClick:Le,onPaneMouseEnter:Re,onPaneMouseMove:ze,onPaneMouseLeave:Be,onPaneScroll:Ve,onPaneContextMenu:He,paneClickDistance:Ue,nodeClickDistance:We,onSelectionContextMenu:ee,onSelectionStart:te,onSelectionEnd:ne,onReconnect:Ke,onReconnectStart:qe,onReconnectEnd:Je,onEdgeContextMenu:Ye,onEdgeDoubleClick:Xe,onEdgeMouseEnter:Ze,onEdgeMouseMove:Qe,onEdgeMouseLeave:$e,reconnectRadius:et,defaultMarkerColor:ke,noDragClassName:rt,noWheelClassName:it,noPanClassName:at,rfId:Lt,disableKeyboardA11y:mt,nodeExtent:Oe,viewport:Et,onViewportChange:Dt,nodesDraggable:he}),(0,W.jsx)(Lh,{onSelectionChange:k}),Ge,(0,W.jsx)(jh,{proOptions:ut,position:lt}),(0,W.jsx)(Oh,{rfId:Lt,disableKeyboardA11y:mt})]})})}var Cv=lg(Sv);_f.error014();function wv({dimensions:e,lineWidth:t,variant:n,className:r}){return(0,W.jsx)(`path`,{strokeWidth:t,d:`M${e[0]/2} 0 V${e[1]} M0 ${e[1]/2} H${e[0]}`,className:zo([`react-flow__background-pattern`,n,r])})}function Tv({radius:e,className:t}){return(0,W.jsx)(`circle`,{cx:e,cy:e,r:e,className:zo([`react-flow__background-pattern`,`dots`,t])})}var Ev;(function(e){e.Lines=`lines`,e.Dots=`dots`,e.Cross=`cross`})(Ev||={});var Dv={[Ev.Dots]:1,[Ev.Lines]:1,[Ev.Cross]:6},Ov=e=>({transform:e.transform,patternId:`pattern-${e.rfId}`});function kv({id:e,variant:t=Ev.Dots,gap:n=20,size:r,lineWidth:i=1,offset:a=0,color:o,bgColor:s,style:c,className:l,patternClassName:u}){let d=(0,U.useRef)(null),{transform:f,patternId:p}=$(Ov,hh),m=r||Dv[t],h=t===Ev.Dots,g=t===Ev.Cross,_=Array.isArray(n)?n:[n,n],v=[_[0]*f[2]||1,_[1]*f[2]||1],y=m*f[2],b=Array.isArray(a)?a:[a,a],x=g?[y,y]:v,S=[b[0]*f[2]||1+x[0]/2,b[1]*f[2]||1+x[1]/2],C=`${p}${e||``}`;return(0,W.jsxs)(`svg`,{className:zo([`react-flow__background`,l]),style:{...c,...Sg,"--xy-background-color-props":s,"--xy-background-pattern-color-props":o},ref:d,"data-testid":`rf__background`,children:[(0,W.jsx)(`pattern`,{id:C,x:f[0]%v[0],y:f[1]%v[1],width:v[0],height:v[1],patternUnits:`userSpaceOnUse`,patternTransform:`translate(-${S[0]},-${S[1]})`,children:h?(0,W.jsx)(Tv,{radius:y/2,className:u}):(0,W.jsx)(wv,{dimensions:x,lineWidth:i,variant:t,className:u})}),(0,W.jsx)(`rect`,{x:`0`,y:`0`,width:`100%`,height:`100%`,fill:`url(#${C})`})]})}kv.displayName=`Background`;var Av=(0,U.memo)(kv);function jv(){return(0,W.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 32 32`,children:(0,W.jsx)(`path`,{d:`M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z`})})}function Mv(){return(0,W.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 32 5`,children:(0,W.jsx)(`path`,{d:`M0 0h32v4.2H0z`})})}function Nv(){return(0,W.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 32 30`,children:(0,W.jsx)(`path`,{d:`M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z`})})}function Pv(){return(0,W.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 25 32`,children:(0,W.jsx)(`path`,{d:`M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z`})})}function Fv(){return(0,W.jsx)(`svg`,{xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 25 32`,children:(0,W.jsx)(`path`,{d:`M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z`})})}function Iv({children:e,className:t,...n}){return(0,W.jsx)(`button`,{type:`button`,className:zo([`react-flow__controls-button`,t]),...n,children:e})}var Lv=e=>({isInteractive:e.nodesDraggable||e.nodesConnectable||e.elementsSelectable,minZoomReached:e.transform[2]<=e.minZoom,maxZoomReached:e.transform[2]>=e.maxZoom,ariaLabelConfig:e.ariaLabelConfig});function Rv({style:e,showZoom:t=!0,showFitView:n=!0,showInteractive:r=!0,fitViewOptions:i,onZoomIn:a,onZoomOut:o,onFitView:s,onInteractiveChange:c,className:l,children:u,position:d=`bottom-left`,orientation:f=`vertical`,"aria-label":p}){let m=yh(),{isInteractive:h,minZoomReached:g,maxZoomReached:_,ariaLabelConfig:v}=$(Lv,hh),{zoomIn:y,zoomOut:b,fitView:x}=_g();return(0,W.jsxs)(kh,{className:zo([`react-flow__controls`,f===`horizontal`?`horizontal`:`vertical`,l]),position:d,style:e,"data-testid":`rf__controls`,"aria-label":p??v[`controls.ariaLabel`],children:[t&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(Iv,{onClick:()=>{y(),a?.()},className:`react-flow__controls-zoomin`,title:v[`controls.zoomIn.ariaLabel`],"aria-label":v[`controls.zoomIn.ariaLabel`],disabled:_,children:(0,W.jsx)(jv,{})}),(0,W.jsx)(Iv,{onClick:()=>{b(),o?.()},className:`react-flow__controls-zoomout`,title:v[`controls.zoomOut.ariaLabel`],"aria-label":v[`controls.zoomOut.ariaLabel`],disabled:g,children:(0,W.jsx)(Mv,{})})]}),n&&(0,W.jsx)(Iv,{className:`react-flow__controls-fitview`,onClick:()=>{x(i),s?.()},title:v[`controls.fitView.ariaLabel`],"aria-label":v[`controls.fitView.ariaLabel`],children:(0,W.jsx)(Nv,{})}),r&&(0,W.jsx)(Iv,{className:`react-flow__controls-interactive`,onClick:()=>{m.setState({nodesDraggable:!h,nodesConnectable:!h,elementsSelectable:!h}),c?.(!h)},title:v[`controls.interactive.ariaLabel`],"aria-label":v[`controls.interactive.ariaLabel`],children:h?(0,W.jsx)(Fv,{}):(0,W.jsx)(Pv,{})}),u]})}Rv.displayName=`Controls`;var zv=(0,U.memo)(Rv);function Bv({id:e,x:t,y:n,width:r,height:i,style:a,color:o,strokeColor:s,strokeWidth:c,className:l,borderRadius:u,shapeRendering:d,selected:f,onClick:p}){let{background:m,backgroundColor:h}=a||{},g=o||m||h;return(0,W.jsx)(`rect`,{className:zo([`react-flow__minimap-node`,{selected:f},l]),x:t,y:n,rx:u,ry:u,width:r,height:i,style:{fill:g,stroke:s,strokeWidth:c},shapeRendering:d,onClick:p?t=>p(t,e):void 0})}var Vv=(0,U.memo)(Bv),Hv=e=>e.nodes.map(e=>e.id),Uv=e=>e instanceof Function?e:()=>e;function Wv({nodeStrokeColor:e,nodeColor:t,nodeClassName:n=``,nodeBorderRadius:r=5,nodeStrokeWidth:i,nodeComponent:a=Vv,onClick:o}){let s=$(Hv,hh),c=Uv(t),l=Uv(e),u=Uv(n),d=typeof window>`u`||window.chrome?`crispEdges`:`geometricPrecision`;return(0,W.jsx)(W.Fragment,{children:s.map(e=>(0,W.jsx)(Kv,{id:e,nodeColorFunc:c,nodeStrokeColorFunc:l,nodeClassNameFunc:u,nodeBorderRadius:r,nodeStrokeWidth:i,NodeComponent:a,onClick:o,shapeRendering:d},e))})}function Gv({id:e,nodeColorFunc:t,nodeStrokeColorFunc:n,nodeClassNameFunc:r,nodeBorderRadius:i,nodeStrokeWidth:a,shapeRendering:o,NodeComponent:s,onClick:c}){let{node:l,x:u,y:d,width:f,height:p}=$(t=>{let n=t.nodeLookup.get(e);if(!n)return{node:void 0,x:0,y:0,width:0,height:0};let r=n.internals.userNode,{x:i,y:a}=n.internals.positionAbsolute,{width:o,height:s}=fp(r);return{node:r,x:i,y:a,width:o,height:s}},hh);return!l||l.hidden||!pp(l)?null:(0,W.jsx)(s,{x:u,y:d,width:f,height:p,style:l.style,selected:!!l.selected,className:r(l),color:t(l),borderRadius:i,strokeColor:n(l),strokeWidth:a,shapeRendering:o,onClick:c,id:l.id})}var Kv=(0,U.memo)(Gv),qv=(0,U.memo)(Wv),Jv=200,Yv=150,Xv=e=>!e.hidden,Zv=e=>{let t={x:-e.transform[0]/e.transform[2],y:-e.transform[1]/e.transform[2],width:e.width/e.transform[2],height:e.height/e.transform[2]};return{viewBB:t,boundingRect:e.nodeLookup.size>0?Zf(Pf(e.nodeLookup,{filter:Xv}),t):t,rfId:e.rfId,panZoom:e.panZoom,translateExtent:e.translateExtent,flowWidth:e.width,flowHeight:e.height,ariaLabelConfig:e.ariaLabelConfig}},Qv=(e,t)=>e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height,$v=(e,t)=>Qv(e.viewBB,t.viewBB)&&Qv(e.boundingRect,t.boundingRect)&&e.rfId===t.rfId&&e.panZoom===t.panZoom&&e.translateExtent===t.translateExtent&&e.flowWidth===t.flowWidth&&e.flowHeight===t.flowHeight&&e.ariaLabelConfig===t.ariaLabelConfig,ey=`react-flow__minimap-desc`;function ty({style:e,className:t,nodeStrokeColor:n,nodeColor:r,nodeClassName:i=``,nodeBorderRadius:a=5,nodeStrokeWidth:o,nodeComponent:s,bgColor:c,maskColor:l,maskStrokeColor:u,maskStrokeWidth:d,position:f=`bottom-right`,onClick:p,onNodeClick:m,pannable:h=!1,zoomable:g=!1,ariaLabel:_,inversePan:v,zoomStep:y=1,offsetScale:b=5}){let x=yh(),S=(0,U.useRef)(null),{boundingRect:C,viewBB:w,rfId:T,panZoom:E,translateExtent:D,flowWidth:O,flowHeight:k,ariaLabelConfig:A}=$(Zv,$v),j=e?.width??Jv,M=e?.height??Yv,ee=C.width/j,te=C.height/M,ne=Math.max(ee,te),N=ne*j,P=ne*M,F=b*ne,re=C.x-(N-C.width)/2-F,ie=C.y-(P-C.height)/2-F,ae=N+F*2,I=P+F*2,L=`${ey}-${T}`,oe=(0,U.useRef)(0),se=(0,U.useRef)();oe.current=ne,(0,U.useEffect)(()=>{if(S.current&&E)return se.current=Am({domNode:S.current,panZoom:E,getTransform:()=>x.getState().transform,getViewScale:()=>oe.current}),()=>{se.current?.destroy()}},[E]),(0,U.useEffect)(()=>{se.current?.update({translateExtent:D,width:O,height:k,inversePan:v,pannable:h,zoomStep:y,zoomable:g})},[h,g,v,y,D,O,k]);let ce=p?e=>{let[t,n]=se.current?.pointer(e)||[0,0];p(e,{x:t,y:n})}:void 0,le=m?(0,U.useCallback)((e,t)=>{let n=x.getState().nodeLookup.get(t).internals.userNode;m(e,n)},[]):void 0,ue=_??A[`minimap.ariaLabel`];return(0,W.jsx)(kh,{position:f,style:{...e,"--xy-minimap-background-color-props":typeof c==`string`?c:void 0,"--xy-minimap-mask-background-color-props":typeof l==`string`?l:void 0,"--xy-minimap-mask-stroke-color-props":typeof u==`string`?u:void 0,"--xy-minimap-mask-stroke-width-props":typeof d==`number`?d*ne:void 0,"--xy-minimap-node-background-color-props":typeof r==`string`?r:void 0,"--xy-minimap-node-stroke-color-props":typeof n==`string`?n:void 0,"--xy-minimap-node-stroke-width-props":typeof o==`number`?o:void 0},className:zo([`react-flow__minimap`,t]),"data-testid":`rf__minimap`,children:(0,W.jsxs)(`svg`,{width:j,height:M,viewBox:`${re} ${ie} ${ae} ${I}`,className:`react-flow__minimap-svg`,role:`img`,"aria-labelledby":L,ref:S,onClick:ce,children:[ue&&(0,W.jsx)(`title`,{id:L,children:ue}),(0,W.jsx)(qv,{onClick:le,nodeColor:r,nodeStrokeColor:n,nodeBorderRadius:a,nodeClassName:i,nodeStrokeWidth:o,nodeComponent:s}),(0,W.jsx)(`path`,{className:`react-flow__minimap-mask`,d:`M${re-F},${ie-F}h${ae+F*2}v${I+F*2}h${-ae-F*2}z
|
|
78
|
-
M${w.x},${w.y}h${w.width}v${w.height}h${-w.width}z`,fillRule:`evenodd`,pointerEvents:`none`})]})})}ty.displayName=`MiniMap`,(0,U.memo)(ty);var ny=e=>t=>e?`${Math.max(1/t.transform[2],1)}`:void 0,ry={[Gm.Line]:`right`,[Gm.Handle]:`bottom-right`};function iy({nodeId:e,position:t,variant:n=Gm.Handle,className:r,style:i=void 0,children:a,color:o,minWidth:s=10,minHeight:c=10,maxWidth:l=Number.MAX_VALUE,maxHeight:u=Number.MAX_VALUE,keepAspectRatio:d=!1,resizeDirection:f,autoScale:p=!0,shouldResize:m,onResizeStart:h,onResize:g,onResizeEnd:_}){let v=Ig(),y=typeof e==`string`?e:v,b=yh(),x=(0,U.useRef)(null),S=n===Gm.Handle,C=$((0,U.useCallback)(ny(S&&p),[S,p]),hh),w=(0,U.useRef)(null),T=t??ry[n];return(0,U.useEffect)(()=>{if(!(!x.current||!y))return w.current||=nh({domNode:x.current,nodeId:y,getStoreItems:()=>{let{nodeLookup:e,transform:t,snapGrid:n,snapToGrid:r,nodeOrigin:i,domNode:a}=b.getState();return{nodeLookup:e,transform:t,snapGrid:n,snapToGrid:r,nodeOrigin:i,paneDomNode:a}},onChange:(e,t)=>{let{triggerNodeChanges:n,nodeLookup:r,parentLookup:i,nodeOrigin:a}=b.getState(),o=[],s={x:e.x,y:e.y},c=r.get(y);if(c&&c.expandParent&&c.parentId){let t=c.origin??a,n=e.width??c.measured.width??0,l=e.height??c.measured.height??0,u=lm([{id:c.id,parentId:c.parentId,rect:{width:n,height:l,...mp({x:e.x??c.position.x,y:e.y??c.position.y},{width:n,height:l},c.parentId,r,t)}}],r,i,a);o.push(...u),s.x=e.x?Math.max(t[0]*n,e.x):void 0,s.y=e.y?Math.max(t[1]*l,e.y):void 0}if(s.x!==void 0&&s.y!==void 0){let e={id:y,type:`position`,position:{...s}};o.push(e)}if(e.width!==void 0&&e.height!==void 0){let t={id:y,type:`dimensions`,resizing:!0,setAttributes:f?f===`horizontal`?`width`:`height`:!0,dimensions:{width:e.width,height:e.height}};o.push(t)}for(let e of t){let t={...e,type:`position`};o.push(t)}n(o)},onEnd:({width:e,height:t})=>{let n={id:y,type:`dimensions`,resizing:!1,dimensions:{width:e,height:t}};b.getState().triggerNodeChanges([n])}}),w.current.update({controlPosition:T,boundaries:{minWidth:s,minHeight:c,maxWidth:l,maxHeight:u},keepAspectRatio:d,resizeDirection:f,onResizeStart:h,onResize:g,onResizeEnd:_,shouldResize:m}),()=>{w.current?.destroy()}},[T,s,c,l,u,d,h,g,_,m]),(0,W.jsx)(`div`,{className:zo([`react-flow__resize-control`,`nodrag`,...T.split(`-`),n,r]),ref:x,style:{...i,scale:C,...o&&{[S?`backgroundColor`:`borderColor`]:o}},children:a})}(0,U.memo)(iy);function ay({rootName:e,model:t,onModelChange:n}){return(0,W.jsxs)(`header`,{className:`topbar`,children:[(0,W.jsxs)(`div`,{className:`brand`,children:[(0,W.jsx)(`span`,{className:`logo`,children:`◇`}),(0,W.jsxs)(`div`,{children:[(0,W.jsxs)(`h1`,{children:[(0,W.jsx)(`span`,{className:`brand-coop`,children:`coop`}),` specplan`]}),(0,W.jsxs)(`p`,{children:[`Plan `,(0,W.jsx)(`code`,{className:`canvas-id`,children:e}),` — autosaves to specplan.yaml`]})]})]}),(0,W.jsx)(`div`,{className:`actions`,children:t!==void 0&&n&&(0,W.jsx)(`select`,{"aria-label":`Model`,className:`model-select`,onChange:e=>n(e.target.value),title:`Model used by chat and Generate OpenSpec`,value:t,children:_o.map(e=>(0,W.jsx)(`option`,{value:e,children:e.replace(/^claude-/,``)},e))})})]})}function oy(e){let t=new Map;for(let n of e){if(n.type!==`dependency`)continue;let e=t.get(n.from)??[];e.push(n.to),t.set(n.from,e)}return t}function sy(e){let t=new Set(e.edges.flatMap(e=>[e.from,e.to])),n=e.nodes.filter(e=>!t.has(e.id));return{specs:ly(n.filter(e=>e.type===`spec`)),stories:ly(n.filter(e=>e.type===`user_story`))}}function cy(e){let t=oy(e.edges),n=new Map,r=(e,i)=>{let a=n.get(e);if(a!==void 0)return a;if(i.has(e))return 0;i.add(e);let o=t.get(e)??[],s=o.length===0?0:1+Math.max(...o.map(e=>r(e,i)));return n.set(e,s),s};for(let t of e.nodes)t.type===`spec`&&r(t.id,new Set);return n}function ly(e){return[...e].sort((e,t)=>e.order-t.order)}function uy({data:e}){let[t,n]=(0,U.useState)(!1),r=e.status??`draft`;return(0,U.useEffect)(()=>{if(!t)return;let e=()=>n(!1);return window.addEventListener(`click`,e),()=>window.removeEventListener(`click`,e)},[t]),(0,W.jsxs)(`div`,{className:`card card-spec${e.hasSpec?` card-has-spec`:``}`,title:e.hasSpec?`An OpenSpec change exists — click to view it`:void 0,children:[(0,W.jsx)(Wg,{type:`target`,position:Q.Left}),(0,W.jsxs)(`div`,{className:`card-kind`,children:[`spec`,e.hasSpec&&(0,W.jsx)(`span`,{className:`card-badge`,children:`openspec ✓`}),e.onStatus&&(0,W.jsxs)(`span`,{className:`card-status-wrap nodrag nopan`,children:[(0,W.jsxs)(`button`,{"aria-label":`Status: ${r}`,className:`card-status status-${r}`,onClick:e=>{e.stopPropagation(),n(e=>!e)},title:`Lifecycle status — click to change (draft / active / done / deferred)`,type:`button`,children:[r,` ▾`]}),t&&(0,W.jsx)(`span`,{className:`status-menu`,role:`menu`,children:Co.map(t=>(0,W.jsx)(`button`,{className:`status-option status-${t}${t===r?` current`:``}`,onClick:i=>{i.stopPropagation(),n(!1),t!==r&&e.onStatus?.(t)},role:`menuitem`,type:`button`,children:t},t))})]})]}),(0,W.jsx)(`div`,{className:`card-title`,children:e.title}),e.description&&(0,W.jsx)(`div`,{className:`card-text card-description`,children:e.description.length>110?`${e.description.slice(0,110)}…`:e.description}),!e.hasSpec&&e.onGenerate&&(0,W.jsx)(`div`,{className:`card-actions`,children:(0,W.jsx)(`button`,{className:`card-generate`,disabled:e.generating,onClick:t=>{t.stopPropagation(),e.onGenerate?.()},title:`Generate the OpenSpec change for this spec from its contained stories and dependencies`,type:`button`,children:e.generating?`Generating…`:`Generate OpenSpec`})}),(0,W.jsx)(Wg,{type:`source`,position:Q.Right})]})}function dy({data:e}){return(0,W.jsxs)(`div`,{className:`card card-story`,children:[(0,W.jsx)(Wg,{type:`target`,position:Q.Left}),(0,W.jsx)(`div`,{className:`card-kind`,children:`user story`}),(0,W.jsx)(`div`,{className:`card-text`,children:e.text})]})}var fy={spec:uy,story:dy};function py(e,t){let n={...t},r=cy(e),i=ly(e.nodes.filter(e=>e.type===`spec`)),a=new Map,o=0;for(let e of i){let t=r.get(e.id)??0;o=Math.max(o,t);let i=a.get(t)??0;a.set(t,i+1),n[e.id]??={x:80+t*340,y:80+i*150}}return ly(e.nodes.filter(e=>e.type===`user_story`)).forEach((e,t)=>{n[e.id]??={x:80+(o+1)*340+40,y:80+t*130}}),n}function my(e,t,n,r){return e.nodes.map(e=>({id:e.id,type:e.type===`spec`?`spec`:`story`,deletable:!1,position:t[e.id]??{x:0,y:0},data:e.type===`spec`?{title:e.title,...e.description?{description:e.description}:{},hasSpec:r?.[e.id]?.hasSpec===!0,status:r?.[e.id]?.status??`draft`,...n?{...n.generate?{generating:n.generatingId===e.id,onGenerate:()=>n.generate?.(e.id)}:{},onStatus:t=>n.setStatus(e.id,t)}:{}}:{text:e.text}}))}function hy(e){return e.edges.map(e=>({id:`${e.from}->${e.to}`,source:e.from,target:e.to,deletable:!0,className:`edge-${e.type}`,...e.type===`dependency`?{markerEnd:{type:Ef.ArrowClosed}}:{style:{strokeDasharray:`6 4`}}}))}function gy({rfNodes:e,rfEdges:t,onConnect:n,onEdgesChange:r,onNodesChange:i,onNodeClick:a,toast:o,children:s}){return(0,W.jsxs)(`section`,{className:`canvas`,"aria-label":`Planning canvas`,children:[(0,W.jsxs)(Cv,{deleteKeyCode:[`Backspace`,`Delete`],edges:t,fitView:!0,nodes:e,nodeTypes:fy,onConnect:n,onEdgesChange:r,onNodeClick:(e,t)=>a(t.id),onNodesChange:i,proOptions:{hideAttribution:!0},children:[(0,W.jsx)(Av,{}),(0,W.jsx)(zv,{})]}),o&&(0,W.jsx)(`div`,{className:`toast`,"data-testid":`toast`,role:`alert`,children:o}),s]})}function _y(e,t){let n=e.slice(0,Math.max(0,Math.min(t,e.length))),r=n.lastIndexOf(`@`);if(r===-1)return null;let i=r===0?``:n[r-1];if(i!==``&&!/[\s([{'"`]/.test(i))return null;let a=n.slice(r+1);return/\s/.test(a)||a.includes(`@`)?null:{start:r,query:a}}function vy(e,t,n,r){let i=e.slice(0,t.start),a=Math.max(t.start,Math.min(n,e.length));for(;a<e.length&&!/\s/.test(e[a]);)a++;let o=e.slice(a);if(r.endsWith(`/`)){let e=`@${r}`;return{text:i+e+o,caret:i.length+e.length}}let s=o.startsWith(` `),c=`@${r}${s?``:` `}`;return{text:i+c+o,caret:i.length+c.length+ +!!s}}function yy(e,t,n){let[r,i]=(0,U.useState)(null),[a,o]=(0,U.useState)([]),[s,c]=(0,U.useState)(0);function l(){let t=e.current;i(t?_y(t.value,t.selectionStart??t.value.length):null)}let u=r?.query;(0,U.useEffect)(()=>{if(u===void 0||!n){o([]);return}let e=!1,t=setTimeout(()=>{n(u).then(t=>{e||(o(t),c(0))}).catch(()=>{})},120);return()=>{e=!0,clearTimeout(t)}},[u,n]);let d=r!==null&&a.length>0;function f(n){let a=e.current;if(!a||!r)return;let o=vy(a.value,r,a.selectionStart??a.value.length,n);t(o.text),i(n.endsWith(`/`)?{start:r.start,query:n}:null),requestAnimationFrame(()=>{a.focus(),a.setSelectionRange(o.caret,o.caret)})}function p(e){if(!d)return!1;if(e.key===`ArrowDown`||e.key===`ArrowUp`){e.preventDefault();let t=e.key===`ArrowDown`?1:a.length-1;return c(e=>(e+t)%a.length),!0}if(e.key===`Enter`||e.key===`Tab`){e.preventDefault();let t=a[s];return t!==void 0&&f(t),!0}return e.key===`Escape`?(e.preventDefault(),i(null),!0):!1}return{open:d,results:a,highlight:s,sync:l,select:f,onKeyDown:p}}function by({search:e,placement:t}){return e.open?(0,W.jsx)(`ul`,{"aria-label":`File search results`,className:`at-search ${t}`,role:`listbox`,children:e.results.map((t,n)=>(0,W.jsx)(`li`,{children:(0,W.jsxs)(`button`,{"aria-selected":n===e.highlight,className:`at-item${n===e.highlight?` active`:``}${t.endsWith(`/`)?` dir`:``}`,onMouseDown:n=>{n.preventDefault(),e.select(t)},role:`option`,type:`button`,children:[`@`,t]})},t))}):null}function xy(e){return e.map(({role:e,text:t,at:n})=>({role:e,text:t,at:n}))}function Sy({messages:e,pending:t,error:n,onSend:r,onClear:i,searchFiles:a}){let[o,s]=(0,U.useState)(``),c=(0,U.useRef)(null),l=(0,U.useRef)(null),u=yy(l,s,a);(0,U.useEffect)(()=>{c.current?.scrollTo({top:c.current.scrollHeight})},[e.length,t]);function d(){let e=o.trim();!e||t||(s(``),r(e))}return(0,W.jsxs)(`div`,{className:`chat`,children:[(0,W.jsxs)(`div`,{className:`chat-messages`,ref:c,children:[e.length===0&&!n&&(0,W.jsxs)(`div`,{className:`chat-empty`,children:[`Ask the assistant to add specs and stories, link dependencies, contain stories, or reorder items — it applies changes straight to the canvas and can never delete anything. Pull files into context with`,` `,(0,W.jsx)(`code`,{children:`@path/to/file`}),` or `,(0,W.jsx)(`code`,{children:`@filename`}),`.`]}),e.map((e,t)=>(0,W.jsxs)(`div`,{className:`chat-message chat-${e.role}`,children:[(0,W.jsx)(`div`,{className:`chat-role`,children:e.role}),(0,W.jsx)(`div`,{className:`chat-text`,children:e.text}),e.toolCalls&&e.toolCalls.length>0&&(0,W.jsxs)(`details`,{className:`chat-refs chat-tools`,"data-testid":`chat-tools`,open:!0,children:[(0,W.jsxs)(`summary`,{children:[e.toolCalls.length,` change`,e.toolCalls.length===1?``:`s`,` applied`]}),(0,W.jsx)(`ul`,{children:e.toolCalls.map((e,t)=>(0,W.jsxs)(`li`,{children:[e.tool,`: `,e.summary]},`${e.tool}-${t}`))})]}),e.refs&&(e.refs.resolved.length>0||e.refs.unresolved.length>0)&&(0,W.jsxs)(`details`,{className:`chat-refs`,children:[(0,W.jsxs)(`summary`,{children:[e.refs.resolved.length,` file`,e.refs.resolved.length===1?``:`s`,` in context`,e.refs.unresolved.length>0&&`, ${e.refs.unresolved.length} unresolved`]}),(0,W.jsxs)(`ul`,{children:[e.refs.resolved.map(e=>(0,W.jsxs)(`li`,{children:[`@`,e]},e)),e.refs.unresolved.map(e=>(0,W.jsxs)(`li`,{className:`chat-ref-missing`,children:[`@`,e.ref,` — `,e.reason]},e.ref))]})]})]},`${e.at}-${t}`)),t&&(0,W.jsx)(`div`,{className:`chat-message chat-assistant chat-thinking`,children:`thinking…`}),n&&(0,W.jsx)(`div`,{className:`chat-fault`,children:n})]}),(0,W.jsxs)(`div`,{className:`chat-composer`,children:[(0,W.jsxs)(`div`,{className:`at-anchor`,children:[(0,W.jsx)(by,{placement:`up`,search:u}),(0,W.jsx)(`textarea`,{"aria-label":`Chat message`,className:`chat-input`,onChange:e=>{s(e.target.value),u.sync()},onKeyDown:e=>{u.onKeyDown(e)||e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),d())},onSelect:u.sync,placeholder:`Ask to add, link, or reorder… (@ searches files)`,ref:l,rows:2,value:o})]}),(0,W.jsxs)(`div`,{className:`chat-composer-actions`,children:[(0,W.jsx)(`button`,{className:`chat-clear`,disabled:e.length===0&&!n,onClick:i,title:`Clear the conversation and start over`,type:`button`,children:`Clear`}),(0,W.jsx)(`button`,{className:`chat-send`,disabled:t||!o.trim(),onClick:d,type:`button`,children:t?`Sending…`:`Send`})]})]})]})}function Cy({info:e,failed:t,onSave:n,searchFiles:r}){let[i,a]=(0,U.useState)(),o=(0,U.useRef)(null),s=yy(o,a,r);if(t)return(0,W.jsx)(`div`,{className:`empty error`,children:`Could not load the system prompt.`});if(!e)return(0,W.jsx)(`div`,{className:`empty`,children:`Loading the system prompt…`});let c=i??e.system,l=c!==e.system,u=c===e.default&&!e.custom;return(0,W.jsxs)(`div`,{className:`prompt-pane`,children:[(0,W.jsxs)(`div`,{className:`artifact-head`,children:[(0,W.jsxs)(`code`,{className:`path`,children:[`generation system prompt`,e.custom?` — customized`:``,l?` (unsaved)`:``]}),(0,W.jsxs)(`div`,{className:`prompt-actions`,children:[(0,W.jsx)(`button`,{className:`copy`,disabled:u&&!l,onClick:()=>{a(void 0),n(null)},title:`Restore the built-in default prompt`,type:`button`,children:`Reset`}),(0,W.jsx)(`button`,{className:`copy prompt-save`,disabled:!l||!c.trim(),onClick:()=>{n(c),a(void 0)},type:`button`,children:`Save`})]})]}),(0,W.jsxs)(`div`,{className:`at-anchor prompt-anchor`,children:[(0,W.jsx)(by,{placement:`down`,search:s}),(0,W.jsx)(`textarea`,{"aria-label":`Generation system prompt`,className:`prompt-editor`,onChange:e=>{a(e.target.value),s.sync()},onKeyDown:e=>void s.onKeyDown(e),onSelect:s.sync,ref:o,spellCheck:!1,value:c})]}),(0,W.jsxs)(`p`,{className:`prompt-hint`,children:[`Drives every generation. `,(0,W.jsx)(`code`,{children:`@path`}),` / `,(0,W.jsx)(`code`,{children:`@filename`}),` references resolve to file contents. Saved edits persist with the plan root.`]})]})}function wy({plan:e,llm:t,onCreateSpec:n,onCreateStory:r,promptInfo:i,promptFailed:a,onSavePrompt:o,chat:s,chatPending:c,chatError:l,onSendChat:u,onClearChat:d,searchFiles:f}){let[p,m]=(0,U.useState)(`backlog`);return(0,W.jsxs)(`aside`,{className:`panel`,"aria-label":`Planning pane`,children:[(0,W.jsx)(`nav`,{className:`pane-nav`,"aria-label":`Side pane options`,children:[{key:`backlog`,label:`Backlog`},...t?[{key:`chat`,label:`Chat`},{key:`prompt`,label:`System Prompt`}]:[]].map(e=>(0,W.jsx)(`button`,{className:p===e.key?`pane-item active`:`pane-item`,onClick:()=>m(e.key),type:`button`,children:e.label},e.key))}),p===`backlog`&&(0,W.jsx)(Ty,{plan:e,onCreateSpec:n,onCreateStory:r,searchFiles:f}),p===`chat`&&t&&(0,W.jsx)(Sy,{messages:s,pending:c,error:l,onSend:u,onClear:d,searchFiles:f}),p===`prompt`&&t&&(0,W.jsx)(Cy,{failed:a,info:i,onSave:o,searchFiles:f})]})}function Ty({plan:e,onCreateSpec:t,onCreateStory:n,searchFiles:r}){let[i,a]=(0,U.useState)(null),{specs:o,stories:s}=sy(e),c=(e,t,n,r)=>(0,W.jsxs)(`div`,{className:`backlog-section`,"data-testid":t,children:[(0,W.jsx)(`h2`,{children:e}),n.length===0?(0,W.jsx)(`p`,{className:`hint`,children:r}):(0,W.jsx)(`ul`,{className:`backlog-list`,children:n.map(e=>(0,W.jsxs)(`li`,{className:`backlog-item`,children:[e.type===`spec`?e.title:e.text,(0,W.jsx)(`span`,{className:`backlog-id`,children:e.id})]},e.id))})]});return(0,W.jsxs)(`div`,{className:`backlog-pane`,"aria-label":`Backlog`,children:[(0,W.jsxs)(`div`,{className:`backlog-actions`,children:[(0,W.jsx)(`button`,{className:`chat-send`,onClick:()=>a(`spec`),type:`button`,children:`New spec…`}),(0,W.jsx)(`button`,{className:`chat-send`,onClick:()=>a(`story`),type:`button`,children:`New story…`})]}),(0,W.jsx)(`p`,{className:`hint`,children:`Not yet linked into the plan — drag a link on the canvas (or ask the chat) and an item clears from this list.`}),c(`Specs`,`backlog-specs`,o,`Every spec is linked into the plan.`),c(`User stories`,`backlog-stories`,s,`Every story is covered by a spec.`),i&&(0,W.jsx)(Ey,{kind:i,onCreateSpec:t,onCreateStory:n,onClose:()=>a(null),searchFiles:r})]})}function Ey({kind:e,onCreateSpec:t,onCreateStory:n,onClose:r,searchFiles:i}){let[a,o]=(0,U.useState)(``),[s,c]=(0,U.useState)(``),[l,u]=(0,U.useState)(``),[d,f]=(0,U.useState)(!1),p=(0,U.useRef)(null),m=yy(p,c,i);(0,U.useEffect)(()=>{let e=e=>{e.key===`Escape`&&r()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[r]);let h=e===`spec`?!!a.trim():!!l.trim();function g(){!h||d||(f(!0),(e===`spec`?t(a,s):n(l)).then(e=>{e&&r()}).finally(()=>f(!1)))}return(0,W.jsx)(`div`,{className:`dialog-overlay`,onClick:r,role:`presentation`,children:(0,W.jsxs)(`div`,{"aria-label":e===`spec`?`Create spec dialog`:`Create user story dialog`,className:`dialog dialog-create`,"data-testid":`create-dialog`,onClick:e=>e.stopPropagation(),role:`dialog`,children:[(0,W.jsxs)(`div`,{className:`dialog-head`,children:[(0,W.jsx)(`div`,{className:`dialog-title`,children:e===`spec`?`New spec`:`New user story`}),(0,W.jsx)(`div`,{className:`dialog-actions`,children:(0,W.jsx)(`button`,{className:`chat-clear`,onClick:r,type:`button`,children:`Cancel`})})]}),e===`spec`?(0,W.jsxs)(`div`,{className:`plan-form`,children:[(0,W.jsx)(`h2`,{children:`Name`}),(0,W.jsx)(`input`,{"aria-label":`New spec title`,autoFocus:!0,onChange:e=>o(e.target.value),placeholder:`Spec title…`,value:a}),(0,W.jsx)(`h2`,{children:`Description / generation prompt`}),(0,W.jsxs)(`div`,{className:`at-anchor`,children:[(0,W.jsx)(by,{placement:`down`,search:m}),(0,W.jsx)(`textarea`,{"aria-label":`Spec description`,onChange:e=>{c(e.target.value),m.sync()},onKeyDown:e=>void m.onKeyDown(e),onSelect:m.sync,placeholder:`What this spec covers — steers generation. @path / @filename pulls files into context…`,ref:p,rows:6,value:s})]})]}):(0,W.jsxs)(`div`,{className:`plan-form`,children:[(0,W.jsx)(`h2`,{children:`Story`}),(0,W.jsx)(`textarea`,{"aria-label":`New user story`,autoFocus:!0,onChange:e=>u(e.target.value),placeholder:`As a <user>, I want to <feature> so that <value>…`,rows:4,value:l})]}),(0,W.jsx)(`div`,{className:`dialog-actions dialog-submit`,children:(0,W.jsx)(`button`,{className:`chat-send`,disabled:!h||d,onClick:g,type:`button`,children:d?`Creating…`:e===`spec`?`Create spec`:`Create story`})})]})})}function Dy({specId:e,title:t,generating:n,loadArtifacts:r,onRegenerate:i,onClose:a}){let[o,s]=(0,U.useState)(null),[c,l]=(0,U.useState)(),[u,d]=(0,U.useState)(0),f=(0,U.useCallback)(async()=>{try{s(await r(e)),l(void 0)}catch(e){l(e instanceof Error?e.message:String(e))}},[e,r]);(0,U.useEffect)(()=>{f()},[f]),(0,U.useEffect)(()=>{let e=e=>{e.key===`Escape`&&a()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[a]);let p=o?.files??[],m=p[Math.min(u,Math.max(p.length-1,0))];return(0,W.jsx)(`div`,{className:`dialog-overlay`,onClick:a,role:`presentation`,children:(0,W.jsxs)(`div`,{"aria-label":`OpenSpec change for ${t}`,className:`dialog`,"data-testid":`spec-dialog`,onClick:e=>e.stopPropagation(),role:`dialog`,children:[(0,W.jsxs)(`div`,{className:`dialog-head`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`dialog-title`,children:t}),(0,W.jsxs)(`code`,{className:`dialog-path`,children:[`openspec/changes/`,e,`/`]})]}),(0,W.jsxs)(`div`,{className:`dialog-actions`,children:[i&&(0,W.jsx)(`button`,{className:`chat-send`,disabled:n,onClick:()=>{i().then(e=>{e&&f()})},title:o?.handEdited?`Body is hand-edited — regeneration updates metadata only`:`Re-run generation from the card’s current stories and dependencies`,type:`button`,children:n?`Regenerating…`:`Regenerate`}),(0,W.jsx)(`button`,{className:`chat-clear`,onClick:a,type:`button`,children:`Close`})]})]}),o?.handEdited&&(0,W.jsx)(`p`,{className:`dialog-notice`,"data-testid":`hand-edited-notice`,children:`This change's body was edited outside specplan (or predates it) — Regenerate updates only the plan metadata and leaves every .md file untouched.`}),c&&(0,W.jsx)(`div`,{className:`empty error`,children:c}),!c&&!o&&(0,W.jsx)(`div`,{className:`empty`,children:`Loading the change…`}),!c&&o&&p.length===0&&(0,W.jsx)(`div`,{className:`empty`,children:`No body files on disk (metadata only so far).`}),m&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`div`,{className:`tabs`,children:p.map((e,t)=>(0,W.jsx)(`button`,{className:t===u?`tab active`:`tab`,onClick:()=>d(t),type:`button`,children:e.path},e.path))}),(0,W.jsxs)(`div`,{className:`artifact-head`,children:[(0,W.jsxs)(`code`,{className:`path`,children:[`openspec/changes/`,e,`/`,m.path]}),(0,W.jsx)(`button`,{className:`copy`,onClick:()=>navigator.clipboard?.writeText(m.content),type:`button`,children:`Copy`})]}),(0,W.jsx)(`pre`,{className:`artifact-body dialog-body`,children:m.content})]})]})})}function Oy({session:e,api:t}){let n=t.llm,[r,i]=(0,U.useState)(e.plan),a=(0,U.useRef)(py(e.plan,e.positions)),[o,s]=(0,U.useState)(e.specStates),[c,l]=(0,U.useState)(()=>my(e.plan,a.current,void 0,e.specStates)),[u,d]=(0,U.useState)(()=>hy(e.plan)),[f,p]=(0,U.useState)(null),[m,h]=(0,U.useState)(null),g=(0,U.useRef)(e.model??`claude-opus-4-8`),[_,v]=(0,U.useState)(g.current),y=(0,U.useRef)(void 0),[b,x]=(0,U.useState)();(0,U.useEffect)(()=>{if(!b)return;let e=setTimeout(()=>x(void 0),4e3);return()=>clearTimeout(e)},[b]);let[S,C]=(0,U.useState)(e.chat??[]),[w,T]=(0,U.useState)(!1),[E,D]=(0,U.useState)();async function O(e){let t=e.trim();if(!t||w||!n)return;let r=xy(S);C(e=>[...e,{role:`user`,text:t,at:new Date().toISOString()}]),T(!0),D(void 0);try{let e=await n.chat(t,r,g.current);i(e.plan),C(t=>[...t,{...e.reply,...e.toolCalls.length>0?{toolCalls:e.toolCalls}:{},...e.resolvedRefs.length>0||e.unresolvedRefs.length>0?{refs:{resolved:e.resolvedRefs,unresolved:e.unresolvedRefs}}:{}}])}catch(e){D(e instanceof Error?e.message:String(e))}finally{T(!1)}}function k(){C([]),D(void 0),n?.clearChat().catch(()=>{})}let[A,j]=(0,U.useState)(),[M,ee]=(0,U.useState)(!1);(0,U.useEffect)(()=>{if(!n)return;let e=!1;return n.getPrompt().then(t=>{e||j(t)}).catch(()=>{e||ee(!0)}),()=>{e=!0}},[n]);function te(e){A&&(j(e===null?{...A,system:A.default,custom:!1}:{...A,system:e,custom:e!==A.default}),n?.savePrompt(e).catch(()=>{}))}let ne=(0,U.useCallback)(async e=>{if(!n)return null;p(e);try{let t=await n.generate(e,g.current);return x(t.mode===`metadata-only`?`Body is hand-edited — updated metadata only, .md files untouched.`:`Generated + validated: ${t.changedFiles.length} file${t.changedFiles.length===1?``:`s`} changed.`),s(n=>{let r=n[e]?.status??`draft`;return{...n,[e]:t.mode===`generated`?{hasSpec:!0,handEdited:!1,status:r}:n[e]??{hasSpec:!0,handEdited:!0,status:r}}}),t.mode}catch(e){return x(e instanceof Error?e.message:String(e)),null}finally{p(null)}},[n]),N=(0,U.useCallback)(async(e,n)=>{try{await t.setStatus(e,n),s(t=>({...t,[e]:{...t[e]??{hasSpec:!1,handEdited:!1,status:n},status:n}}))}catch(e){x(e instanceof Error?e.message:String(e))}},[t]);(0,U.useEffect)(()=>{a.current=py(r,a.current),l(my(r,a.current,{...n?{generate:e=>void ne(e)}:{},generatingId:f,setStatus:(e,t)=>void N(e,t)},o)),d(hy(r))},[r,f,ne,N,o,n]);let P=(0,U.useCallback)(()=>{clearTimeout(y.current),y.current=setTimeout(()=>{t.saveUiState({...t.llm?{model:g.current}:{},positions:a.current}).catch(()=>{})},800)},[t]);function F(e){g.current=e,v(e),P()}let re=(0,U.useCallback)(e=>{l(t=>$h(e,t));let t=!1;for(let n of e)n.type===`position`&&n.position&&(a.current={...a.current,[n.id]:{x:n.position.x,y:n.position.y}},n.dragging||(t=!0));t&&P()},[P]);async function ie(e,n){try{let r=await t.createSpec(e,n);return i(e=>({...e,nodes:[...e.nodes,r]})),!0}catch(e){return x(e instanceof Error?e.message:String(e)),!1}}async function ae(e){try{let n=await t.createStory(e);return i(e=>({...e,nodes:[...e.nodes,n]})),!0}catch(e){return x(e instanceof Error?e.message:String(e)),!1}}let I=(0,U.useCallback)(async(e,n)=>{try{let r=await t.link(e,n);return i(e=>({...e,edges:[...e.edges,r]})),!0}catch(e){return x(e instanceof Error?e.message:String(e)),!1}},[t]),L=(0,U.useCallback)(e=>{!e.source||!e.target||I(e.source,e.target)},[I]),oe=(0,U.useCallback)(async(e,n)=>{try{await t.unlink(e,n),i(t=>({...t,edges:t.edges.filter(t=>!(t.from===e&&t.to===n))})),x(`Unlinked ${e} -> ${n}.`)}catch(e){x(e instanceof Error?e.message:String(e))}},[t]),se=(0,U.useCallback)(e=>{let t=e.filter(e=>e.type!==`remove`);t.length>0&&d(e=>eg(t,e));for(let t of e){if(t.type!==`remove`)continue;let[e,n]=t.id.split(`->`);e&&n&&oe(e,n)}},[oe]);return(0,W.jsxs)(`div`,{className:`app`,children:[(0,W.jsx)(ay,{rootName:e.rootName,...n?{model:_,onModelChange:F}:{}}),(0,W.jsxs)(`main`,{className:`workspace`,children:[(0,W.jsx)(gy,{rfNodes:c,rfEdges:u,onConnect:L,onEdgesChange:se,onNodesChange:re,onNodeClick:e=>{let t=r.nodes.find(t=>t.id===e);t?.type===`spec`&&o[e]?.hasSpec&&h({id:t.id,title:t.title})},toast:b,children:m&&(0,W.jsx)(Dy,{specId:m.id,title:m.title,generating:f===m.id,loadArtifacts:e=>t.getSpecArtifacts(e),...n?{onRegenerate:()=>ne(m.id)}:{},onClose:()=>h(null)})}),(0,W.jsx)(wy,{plan:r,llm:!!n,onCreateSpec:ie,onCreateStory:ae,promptInfo:A,promptFailed:M,onSavePrompt:te,chat:S,chatPending:w,chatError:E,onSendChat:O,onClearChat:k,searchFiles:n?e=>n.searchFiles(e):void 0})]})]})}var ky=Io(`/api`,{llm:!0});function Ay(){let[e,t]=(0,U.useState)({mode:`loading`});return(0,U.useEffect)(()=>{Lo(ky).then(t)},[]),e.mode===`loading`?(0,W.jsx)(`div`,{className:`boot`,children:`Loading…`}):e.mode===`error`?(0,W.jsxs)(`div`,{className:`boot`,children:[`Could not reach the specplan server: `,e.detail,`. Launch it with`,` `,(0,W.jsx)(`code`,{children:`specplan [rootDir]`}),` and reload.`]}):(0,W.jsx)(Oy,{session:e.session,api:ky})}var jy=document.getElementById(`root`);if(!jy)throw Error(`Missing #root element`);(0,go.createRoot)(jy).render((0,W.jsx)(U.StrictMode,{children:(0,W.jsx)(Ay,{})}));
|
|
78
|
+
M${w.x},${w.y}h${w.width}v${w.height}h${-w.width}z`,fillRule:`evenodd`,pointerEvents:`none`})]})})}ty.displayName=`MiniMap`,(0,U.memo)(ty);var ny=e=>t=>e?`${Math.max(1/t.transform[2],1)}`:void 0,ry={[Gm.Line]:`right`,[Gm.Handle]:`bottom-right`};function iy({nodeId:e,position:t,variant:n=Gm.Handle,className:r,style:i=void 0,children:a,color:o,minWidth:s=10,minHeight:c=10,maxWidth:l=Number.MAX_VALUE,maxHeight:u=Number.MAX_VALUE,keepAspectRatio:d=!1,resizeDirection:f,autoScale:p=!0,shouldResize:m,onResizeStart:h,onResize:g,onResizeEnd:_}){let v=Ig(),y=typeof e==`string`?e:v,b=yh(),x=(0,U.useRef)(null),S=n===Gm.Handle,C=$((0,U.useCallback)(ny(S&&p),[S,p]),hh),w=(0,U.useRef)(null),T=t??ry[n];return(0,U.useEffect)(()=>{if(!(!x.current||!y))return w.current||=nh({domNode:x.current,nodeId:y,getStoreItems:()=>{let{nodeLookup:e,transform:t,snapGrid:n,snapToGrid:r,nodeOrigin:i,domNode:a}=b.getState();return{nodeLookup:e,transform:t,snapGrid:n,snapToGrid:r,nodeOrigin:i,paneDomNode:a}},onChange:(e,t)=>{let{triggerNodeChanges:n,nodeLookup:r,parentLookup:i,nodeOrigin:a}=b.getState(),o=[],s={x:e.x,y:e.y},c=r.get(y);if(c&&c.expandParent&&c.parentId){let t=c.origin??a,n=e.width??c.measured.width??0,l=e.height??c.measured.height??0,u=lm([{id:c.id,parentId:c.parentId,rect:{width:n,height:l,...mp({x:e.x??c.position.x,y:e.y??c.position.y},{width:n,height:l},c.parentId,r,t)}}],r,i,a);o.push(...u),s.x=e.x?Math.max(t[0]*n,e.x):void 0,s.y=e.y?Math.max(t[1]*l,e.y):void 0}if(s.x!==void 0&&s.y!==void 0){let e={id:y,type:`position`,position:{...s}};o.push(e)}if(e.width!==void 0&&e.height!==void 0){let t={id:y,type:`dimensions`,resizing:!0,setAttributes:f?f===`horizontal`?`width`:`height`:!0,dimensions:{width:e.width,height:e.height}};o.push(t)}for(let e of t){let t={...e,type:`position`};o.push(t)}n(o)},onEnd:({width:e,height:t})=>{let n={id:y,type:`dimensions`,resizing:!1,dimensions:{width:e,height:t}};b.getState().triggerNodeChanges([n])}}),w.current.update({controlPosition:T,boundaries:{minWidth:s,minHeight:c,maxWidth:l,maxHeight:u},keepAspectRatio:d,resizeDirection:f,onResizeStart:h,onResize:g,onResizeEnd:_,shouldResize:m}),()=>{w.current?.destroy()}},[T,s,c,l,u,d,h,g,_,m]),(0,W.jsx)(`div`,{className:zo([`react-flow__resize-control`,`nodrag`,...T.split(`-`),n,r]),ref:x,style:{...i,scale:C,...o&&{[S?`backgroundColor`:`borderColor`]:o}},children:a})}(0,U.memo)(iy);function ay({rootName:e,model:t,onModelChange:n}){return(0,W.jsxs)(`header`,{className:`topbar`,children:[(0,W.jsxs)(`div`,{className:`brand`,children:[(0,W.jsx)(`span`,{className:`logo`,children:`◇`}),(0,W.jsxs)(`div`,{children:[(0,W.jsxs)(`h1`,{children:[(0,W.jsx)(`span`,{className:`brand-coop`,children:`coop`}),` specplan`]}),(0,W.jsxs)(`p`,{children:[`Plan `,(0,W.jsx)(`code`,{className:`canvas-id`,children:e}),` — autosaves to specplan.yaml`]})]})]}),(0,W.jsx)(`div`,{className:`actions`,children:t!==void 0&&n&&(0,W.jsx)(`select`,{"aria-label":`Model`,className:`model-select`,onChange:e=>n(e.target.value),title:`Model used by chat and Generate OpenSpec`,value:t,children:_o.map(e=>(0,W.jsx)(`option`,{value:e,children:e.replace(/^claude-/,``)},e))})})]})}function oy(e){let t=new Map;for(let n of e){if(n.type!==`dependency`)continue;let e=t.get(n.from)??[];e.push(n.to),t.set(n.from,e)}return t}function sy(e){let t=new Set(e.edges.flatMap(e=>[e.from,e.to])),n=e.nodes.filter(e=>!t.has(e.id));return{specs:ly(n.filter(e=>e.type===`spec`)),stories:ly(n.filter(e=>e.type===`user_story`))}}function cy(e){let t=oy(e.edges),n=new Map,r=(e,i)=>{let a=n.get(e);if(a!==void 0)return a;if(i.has(e))return 0;i.add(e);let o=t.get(e)??[],s=o.length===0?0:1+Math.max(...o.map(e=>r(e,i)));return n.set(e,s),s};for(let t of e.nodes)t.type===`spec`&&r(t.id,new Set);return n}function ly(e){return[...e].sort((e,t)=>e.order-t.order)}function uy({data:e}){let[t,n]=(0,U.useState)(!1),r=e.status??`draft`;return(0,U.useEffect)(()=>{if(!t)return;let e=()=>n(!1);return window.addEventListener(`click`,e),()=>window.removeEventListener(`click`,e)},[t]),(0,W.jsxs)(`div`,{className:`card card-spec${e.hasSpec?` card-has-spec`:``}`,title:e.hasSpec?`An OpenSpec change exists — click to view it`:void 0,children:[(0,W.jsx)(Wg,{type:`target`,position:Q.Left}),(0,W.jsxs)(`div`,{className:`card-kind`,children:[`spec`,e.hasSpec&&(0,W.jsx)(`span`,{className:`card-badge`,children:`openspec ✓`}),e.onStatus&&(0,W.jsxs)(`span`,{className:`card-status-wrap nodrag nopan`,children:[(0,W.jsxs)(`button`,{"aria-label":`Status: ${r}`,className:`card-status status-${r}`,onClick:e=>{e.stopPropagation(),n(e=>!e)},title:`Lifecycle status — click to change (draft / active / done / deferred)`,type:`button`,children:[r,` ▾`]}),t&&(0,W.jsx)(`span`,{className:`status-menu`,role:`menu`,children:Co.map(t=>(0,W.jsx)(`button`,{className:`status-option status-${t}${t===r?` current`:``}`,onClick:i=>{i.stopPropagation(),n(!1),t!==r&&e.onStatus?.(t)},role:`menuitem`,type:`button`,children:t},t))})]})]}),(0,W.jsx)(`div`,{className:`card-title`,children:e.title}),e.description&&(0,W.jsx)(`div`,{className:`card-text card-description`,children:e.description.length>110?`${e.description.slice(0,110)}…`:e.description}),!e.hasSpec&&e.onGenerate&&(0,W.jsx)(`div`,{className:`card-actions`,children:(0,W.jsx)(`button`,{className:`card-generate`,disabled:e.generating,onClick:t=>{t.stopPropagation(),e.onGenerate?.()},title:`Generate the OpenSpec change for this spec from its contained stories and dependencies`,type:`button`,children:e.generating?`Generating…`:`Generate OpenSpec`})}),(0,W.jsx)(Wg,{type:`source`,position:Q.Right})]})}function dy({data:e}){return(0,W.jsxs)(`div`,{className:`card card-story`,children:[(0,W.jsx)(Wg,{type:`target`,position:Q.Left}),(0,W.jsx)(`div`,{className:`card-kind`,children:`user story`}),(0,W.jsx)(`div`,{className:`card-text`,children:e.text})]})}var fy={spec:uy,story:dy};function py(e,t){let n={...t},r=cy(e),i=ly(e.nodes.filter(e=>e.type===`spec`)),a=new Map,o=0;for(let e of i){let t=r.get(e.id)??0;o=Math.max(o,t);let i=a.get(t)??0;a.set(t,i+1),n[e.id]??={x:80+t*340,y:80+i*150}}return ly(e.nodes.filter(e=>e.type===`user_story`)).forEach((e,t)=>{n[e.id]??={x:80+(o+1)*340+40,y:80+t*130}}),n}function my(e,t,n,r){return e.nodes.map(e=>({id:e.id,type:e.type===`spec`?`spec`:`story`,deletable:!1,position:t[e.id]??{x:0,y:0},data:e.type===`spec`?{title:e.title,...e.description?{description:e.description}:{},hasSpec:r?.[e.id]?.hasSpec===!0,status:r?.[e.id]?.status??`draft`,...n?{...n.generate?{generating:n.generatingId===e.id,onGenerate:()=>n.generate?.(e.id)}:{},onStatus:t=>n.setStatus(e.id,t)}:{}}:{text:e.text}}))}function hy(e){return e.edges.map(e=>({id:`${e.from}->${e.to}`,source:e.from,target:e.to,deletable:!0,className:`edge-${e.type}`,...e.type===`dependency`?{markerEnd:{type:Ef.ArrowClosed}}:{style:{strokeDasharray:`6 4`}}}))}function gy({rfNodes:e,rfEdges:t,onConnect:n,onEdgesChange:r,onNodesChange:i,onNodeClick:a,toast:o,children:s}){return(0,W.jsxs)(`section`,{className:`canvas`,"aria-label":`Planning canvas`,children:[(0,W.jsxs)(Cv,{deleteKeyCode:[`Backspace`,`Delete`],edges:t,fitView:!0,nodes:e,nodeTypes:fy,onConnect:n,onEdgesChange:r,onNodeClick:(e,t)=>a(t.id),onNodesChange:i,proOptions:{hideAttribution:!0},children:[(0,W.jsx)(Av,{}),(0,W.jsx)(zv,{})]}),o&&(0,W.jsx)(`div`,{className:`toast`,"data-testid":`toast`,role:`alert`,children:o}),s]})}function _y(e,t){let n=e.slice(0,Math.max(0,Math.min(t,e.length))),r=n.lastIndexOf(`@`);if(r===-1)return null;let i=r===0?``:n[r-1];if(i!==``&&!/[\s([{'"`]/.test(i))return null;let a=n.slice(r+1);return/\s/.test(a)||a.includes(`@`)?null:{start:r,query:a}}function vy(e,t,n,r){let i=e.slice(0,t.start),a=Math.max(t.start,Math.min(n,e.length));for(;a<e.length&&!/\s/.test(e[a]);)a++;let o=e.slice(a);if(r.endsWith(`/`)){let e=`@${r}`;return{text:i+e+o,caret:i.length+e.length}}let s=o.startsWith(` `),c=`@${r}${s?``:` `}`;return{text:i+c+o,caret:i.length+c.length+ +!!s}}function yy(e,t,n){let[r,i]=(0,U.useState)(null),[a,o]=(0,U.useState)([]),[s,c]=(0,U.useState)(0);function l(){let t=e.current;i(t?_y(t.value,t.selectionStart??t.value.length):null)}let u=r?.query;(0,U.useEffect)(()=>{if(u===void 0||!n){o([]);return}let e=!1,t=setTimeout(()=>{n(u).then(t=>{e||(o(t),c(0))}).catch(()=>{})},120);return()=>{e=!0,clearTimeout(t)}},[u,n]);let d=r!==null&&a.length>0;function f(n){let a=e.current;if(!a||!r)return;let o=vy(a.value,r,a.selectionStart??a.value.length,n);t(o.text),i(n.endsWith(`/`)?{start:r.start,query:n}:null),requestAnimationFrame(()=>{a.focus(),a.setSelectionRange(o.caret,o.caret)})}function p(e){if(!d)return!1;if(e.key===`ArrowDown`||e.key===`ArrowUp`){e.preventDefault();let t=e.key===`ArrowDown`?1:a.length-1;return c(e=>(e+t)%a.length),!0}if(e.key===`Enter`||e.key===`Tab`){e.preventDefault();let t=a[s];return t!==void 0&&f(t),!0}return e.key===`Escape`?(e.preventDefault(),i(null),!0):!1}return{open:d,results:a,highlight:s,sync:l,select:f,onKeyDown:p}}function by({search:e,placement:t}){return e.open?(0,W.jsx)(`ul`,{"aria-label":`File search results`,className:`at-search ${t}`,role:`listbox`,children:e.results.map((t,n)=>(0,W.jsx)(`li`,{children:(0,W.jsxs)(`button`,{"aria-selected":n===e.highlight,className:`at-item${n===e.highlight?` active`:``}${t.endsWith(`/`)?` dir`:``}`,onMouseDown:n=>{n.preventDefault(),e.select(t)},role:`option`,type:`button`,children:[`@`,t]})},t))}):null}function xy(e){return e.map(({role:e,text:t,at:n})=>({role:e,text:t,at:n}))}function Sy({messages:e,pending:t,error:n,onSend:r,onClear:i,searchFiles:a}){let[o,s]=(0,U.useState)(``),c=(0,U.useRef)(null),l=(0,U.useRef)(null),u=yy(l,s,a);(0,U.useEffect)(()=>{c.current?.scrollTo({top:c.current.scrollHeight})},[e.length,t]);function d(){let e=o.trim();!e||t||(s(``),r(e))}return(0,W.jsxs)(`div`,{className:`chat`,children:[(0,W.jsxs)(`div`,{className:`chat-messages`,ref:c,children:[e.length===0&&!n&&(0,W.jsxs)(`div`,{className:`chat-empty`,children:[`Ask the assistant to add specs and stories, link dependencies, contain stories, or reorder items — it applies changes straight to the canvas and can never delete anything. Pull files into context with`,` `,(0,W.jsx)(`code`,{children:`@path/to/file`}),` or `,(0,W.jsx)(`code`,{children:`@filename`}),`.`]}),e.map((e,t)=>(0,W.jsxs)(`div`,{className:`chat-message chat-${e.role}`,children:[(0,W.jsx)(`div`,{className:`chat-role`,children:e.role}),(0,W.jsx)(`div`,{className:`chat-text`,children:e.text}),e.toolCalls&&e.toolCalls.length>0&&(0,W.jsxs)(`details`,{className:`chat-refs chat-tools`,"data-testid":`chat-tools`,open:!0,children:[(0,W.jsxs)(`summary`,{children:[e.toolCalls.length,` change`,e.toolCalls.length===1?``:`s`,` applied`]}),(0,W.jsx)(`ul`,{children:e.toolCalls.map((e,t)=>(0,W.jsxs)(`li`,{children:[e.tool,`: `,e.summary]},`${e.tool}-${t}`))})]}),e.refs&&(e.refs.resolved.length>0||e.refs.unresolved.length>0)&&(0,W.jsxs)(`details`,{className:`chat-refs`,children:[(0,W.jsxs)(`summary`,{children:[e.refs.resolved.length,` file`,e.refs.resolved.length===1?``:`s`,` in context`,e.refs.unresolved.length>0&&`, ${e.refs.unresolved.length} unresolved`]}),(0,W.jsxs)(`ul`,{children:[e.refs.resolved.map(e=>(0,W.jsxs)(`li`,{children:[`@`,e]},e)),e.refs.unresolved.map(e=>(0,W.jsxs)(`li`,{className:`chat-ref-missing`,children:[`@`,e.ref,` — `,e.reason]},e.ref))]})]})]},`${e.at}-${t}`)),t&&(0,W.jsx)(`div`,{className:`chat-message chat-assistant chat-thinking`,children:`thinking…`}),n&&(0,W.jsx)(`div`,{className:`chat-fault`,children:n})]}),(0,W.jsxs)(`div`,{className:`chat-composer`,children:[(0,W.jsxs)(`div`,{className:`at-anchor`,children:[(0,W.jsx)(by,{placement:`up`,search:u}),(0,W.jsx)(`textarea`,{"aria-label":`Chat message`,className:`chat-input`,onChange:e=>{s(e.target.value),u.sync()},onKeyDown:e=>{u.onKeyDown(e)||e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),d())},onSelect:u.sync,placeholder:`Ask to add, link, or reorder… (@ searches files)`,ref:l,rows:2,value:o})]}),(0,W.jsxs)(`div`,{className:`chat-composer-actions`,children:[(0,W.jsx)(`button`,{className:`chat-clear`,disabled:e.length===0&&!n,onClick:i,title:`Clear the conversation and start over`,type:`button`,children:`Clear`}),(0,W.jsx)(`button`,{className:`chat-send`,disabled:t||!o.trim(),onClick:d,type:`button`,children:t?`Sending…`:`Send`})]})]})]})}function Cy({info:e,failed:t,onSave:n,searchFiles:r}){let[i,a]=(0,U.useState)(),o=(0,U.useRef)(null),s=yy(o,a,r);if(t)return(0,W.jsx)(`div`,{className:`empty error`,children:`Could not load the system prompt.`});if(!e)return(0,W.jsx)(`div`,{className:`empty`,children:`Loading the system prompt…`});let c=i??e.system,l=c!==e.system,u=c===e.default&&!e.custom;return(0,W.jsxs)(`div`,{className:`prompt-pane`,children:[(0,W.jsxs)(`div`,{className:`artifact-head`,children:[(0,W.jsxs)(`code`,{className:`path`,children:[`generation system prompt`,e.custom?` — customized`:``,l?` (unsaved)`:``]}),(0,W.jsxs)(`div`,{className:`prompt-actions`,children:[(0,W.jsx)(`button`,{className:`copy`,disabled:u&&!l,onClick:()=>{a(void 0),n(null)},title:`Restore the built-in default prompt`,type:`button`,children:`Reset`}),(0,W.jsx)(`button`,{className:`copy prompt-save`,disabled:!l||!c.trim(),onClick:()=>{n(c),a(void 0)},type:`button`,children:`Save`})]})]}),(0,W.jsxs)(`div`,{className:`at-anchor prompt-anchor`,children:[(0,W.jsx)(by,{placement:`down`,search:s}),(0,W.jsx)(`textarea`,{"aria-label":`Generation system prompt`,className:`prompt-editor`,onChange:e=>{a(e.target.value),s.sync()},onKeyDown:e=>void s.onKeyDown(e),onSelect:s.sync,ref:o,spellCheck:!1,value:c})]}),(0,W.jsxs)(`p`,{className:`prompt-hint`,children:[`Drives every generation. `,(0,W.jsx)(`code`,{children:`@path`}),` / `,(0,W.jsx)(`code`,{children:`@filename`}),` references resolve to file contents. Saved edits persist with the plan root.`]})]})}function wy({plan:e,llm:t,onCreateSpec:n,onCreateStory:r,promptInfo:i,promptFailed:a,onSavePrompt:o,chat:s,chatPending:c,chatError:l,onSendChat:u,onClearChat:d,searchFiles:f}){let[p,m]=(0,U.useState)(`backlog`),[h,g]=(0,U.useState)(!1),_=[{key:`backlog`,label:`Backlog`},...t?[{key:`chat`,label:`Chat`},{key:`prompt`,label:`System Prompt`}]:[]];return h?(0,W.jsx)(`button`,{"aria-label":`Show planning pane`,className:`panel-reopen`,"data-testid":`panel-reopen`,onClick:()=>g(!1),title:`Show planning pane`,type:`button`,children:`«`}):(0,W.jsxs)(`aside`,{className:`panel`,"aria-label":`Planning pane`,children:[(0,W.jsxs)(`nav`,{className:`pane-nav`,"aria-label":`Side pane options`,children:[_.map(e=>(0,W.jsx)(`button`,{className:p===e.key?`pane-item active`:`pane-item`,onClick:()=>m(e.key),type:`button`,children:e.label},e.key)),(0,W.jsx)(`button`,{"aria-label":`Hide planning pane`,className:`pane-collapse`,"data-testid":`panel-collapse`,onClick:()=>g(!0),title:`Hide planning pane`,type:`button`,children:`»`})]}),p===`backlog`&&(0,W.jsx)(Ty,{plan:e,onCreateSpec:n,onCreateStory:r,searchFiles:f}),p===`chat`&&t&&(0,W.jsx)(Sy,{messages:s,pending:c,error:l,onSend:u,onClear:d,searchFiles:f}),p===`prompt`&&t&&(0,W.jsx)(Cy,{failed:a,info:i,onSave:o,searchFiles:f})]})}function Ty({plan:e,onCreateSpec:t,onCreateStory:n,searchFiles:r}){let[i,a]=(0,U.useState)(null),{specs:o,stories:s}=sy(e),c=(e,t,n,r)=>(0,W.jsxs)(`div`,{className:`backlog-section`,"data-testid":t,children:[(0,W.jsx)(`h2`,{children:e}),n.length===0?(0,W.jsx)(`p`,{className:`hint`,children:r}):(0,W.jsx)(`ul`,{className:`backlog-list`,children:n.map(e=>(0,W.jsxs)(`li`,{className:`backlog-item`,children:[e.type===`spec`?e.title:e.text,(0,W.jsx)(`span`,{className:`backlog-id`,children:e.id})]},e.id))})]});return(0,W.jsxs)(`div`,{className:`backlog-pane`,"aria-label":`Backlog`,children:[(0,W.jsxs)(`div`,{className:`backlog-actions`,children:[(0,W.jsx)(`button`,{className:`chat-send`,onClick:()=>a(`spec`),type:`button`,children:`New spec…`}),(0,W.jsx)(`button`,{className:`chat-send`,onClick:()=>a(`story`),type:`button`,children:`New story…`})]}),(0,W.jsx)(`p`,{className:`hint`,children:`Not yet linked into the plan — drag a link on the canvas (or ask the chat) and an item clears from this list.`}),c(`Specs`,`backlog-specs`,o,`Every spec is linked into the plan.`),c(`User stories`,`backlog-stories`,s,`Every story is covered by a spec.`),i&&(0,W.jsx)(Ey,{kind:i,onCreateSpec:t,onCreateStory:n,onClose:()=>a(null),searchFiles:r})]})}function Ey({kind:e,onCreateSpec:t,onCreateStory:n,onClose:r,searchFiles:i}){let[a,o]=(0,U.useState)(``),[s,c]=(0,U.useState)(``),[l,u]=(0,U.useState)(``),[d,f]=(0,U.useState)(!1),p=(0,U.useRef)(null),m=yy(p,c,i);(0,U.useEffect)(()=>{let e=e=>{e.key===`Escape`&&r()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[r]);let h=e===`spec`?!!a.trim():!!l.trim();function g(){!h||d||(f(!0),(e===`spec`?t(a,s):n(l)).then(e=>{e&&r()}).finally(()=>f(!1)))}return(0,W.jsx)(`div`,{className:`dialog-overlay`,onClick:r,role:`presentation`,children:(0,W.jsxs)(`div`,{"aria-label":e===`spec`?`Create spec dialog`:`Create user story dialog`,className:`dialog dialog-create`,"data-testid":`create-dialog`,onClick:e=>e.stopPropagation(),role:`dialog`,children:[(0,W.jsxs)(`div`,{className:`dialog-head`,children:[(0,W.jsx)(`div`,{className:`dialog-title`,children:e===`spec`?`New spec`:`New user story`}),(0,W.jsx)(`div`,{className:`dialog-actions`,children:(0,W.jsx)(`button`,{className:`chat-clear`,onClick:r,type:`button`,children:`Cancel`})})]}),e===`spec`?(0,W.jsxs)(`div`,{className:`plan-form`,children:[(0,W.jsx)(`h2`,{children:`Name`}),(0,W.jsx)(`input`,{"aria-label":`New spec title`,autoFocus:!0,onChange:e=>o(e.target.value),placeholder:`Spec title…`,value:a}),(0,W.jsx)(`h2`,{children:`Description / generation prompt`}),(0,W.jsxs)(`div`,{className:`at-anchor`,children:[(0,W.jsx)(by,{placement:`down`,search:m}),(0,W.jsx)(`textarea`,{"aria-label":`Spec description`,onChange:e=>{c(e.target.value),m.sync()},onKeyDown:e=>void m.onKeyDown(e),onSelect:m.sync,placeholder:`What this spec covers — steers generation. @path / @filename pulls files into context…`,ref:p,rows:6,value:s})]})]}):(0,W.jsxs)(`div`,{className:`plan-form`,children:[(0,W.jsx)(`h2`,{children:`Story`}),(0,W.jsx)(`textarea`,{"aria-label":`New user story`,autoFocus:!0,onChange:e=>u(e.target.value),placeholder:`As a <user>, I want to <feature> so that <value>…`,rows:4,value:l})]}),(0,W.jsx)(`div`,{className:`dialog-actions dialog-submit`,children:(0,W.jsx)(`button`,{className:`chat-send`,disabled:!h||d,onClick:g,type:`button`,children:d?`Creating…`:e===`spec`?`Create spec`:`Create story`})})]})})}function Dy({specId:e,title:t,generating:n,loadArtifacts:r,onRegenerate:i,onClose:a}){let[o,s]=(0,U.useState)(null),[c,l]=(0,U.useState)(),[u,d]=(0,U.useState)(0),f=(0,U.useCallback)(async()=>{try{s(await r(e)),l(void 0)}catch(e){l(e instanceof Error?e.message:String(e))}},[e,r]);(0,U.useEffect)(()=>{f()},[f]),(0,U.useEffect)(()=>{let e=e=>{e.key===`Escape`&&a()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[a]);let p=o?.files??[],m=p[Math.min(u,Math.max(p.length-1,0))];return(0,W.jsx)(`div`,{className:`dialog-overlay`,onClick:a,role:`presentation`,children:(0,W.jsxs)(`div`,{"aria-label":`OpenSpec change for ${t}`,className:`dialog`,"data-testid":`spec-dialog`,onClick:e=>e.stopPropagation(),role:`dialog`,children:[(0,W.jsxs)(`div`,{className:`dialog-head`,children:[(0,W.jsxs)(`div`,{children:[(0,W.jsx)(`div`,{className:`dialog-title`,children:t}),(0,W.jsxs)(`code`,{className:`dialog-path`,children:[`openspec/changes/`,e,`/`]})]}),(0,W.jsxs)(`div`,{className:`dialog-actions`,children:[i&&(0,W.jsx)(`button`,{className:`chat-send`,disabled:n,onClick:()=>{i().then(e=>{e&&f()})},title:o?.handEdited?`Body is hand-edited — regeneration updates metadata only`:`Re-run generation from the card’s current stories and dependencies`,type:`button`,children:n?`Regenerating…`:`Regenerate`}),(0,W.jsx)(`button`,{className:`chat-clear`,onClick:a,type:`button`,children:`Close`})]})]}),o?.handEdited&&(0,W.jsx)(`p`,{className:`dialog-notice`,"data-testid":`hand-edited-notice`,children:`This change's body was edited outside specplan (or predates it) — Regenerate updates only the plan metadata and leaves every .md file untouched.`}),c&&(0,W.jsx)(`div`,{className:`empty error`,children:c}),!c&&!o&&(0,W.jsx)(`div`,{className:`empty`,children:`Loading the change…`}),!c&&o&&p.length===0&&(0,W.jsx)(`div`,{className:`empty`,children:`No body files on disk (metadata only so far).`}),m&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`div`,{className:`tabs`,children:p.map((e,t)=>(0,W.jsx)(`button`,{className:t===u?`tab active`:`tab`,onClick:()=>d(t),type:`button`,children:e.path},e.path))}),(0,W.jsxs)(`div`,{className:`artifact-head`,children:[(0,W.jsxs)(`code`,{className:`path`,children:[`openspec/changes/`,e,`/`,m.path]}),(0,W.jsx)(`button`,{className:`copy`,onClick:()=>navigator.clipboard?.writeText(m.content),type:`button`,children:`Copy`})]}),(0,W.jsx)(`pre`,{className:`artifact-body dialog-body`,children:m.content})]})]})})}function Oy({session:e,api:t}){let n=t.llm,[r,i]=(0,U.useState)(e.plan),a=(0,U.useRef)(py(e.plan,e.positions)),[o,s]=(0,U.useState)(e.specStates),[c,l]=(0,U.useState)(()=>my(e.plan,a.current,void 0,e.specStates)),[u,d]=(0,U.useState)(()=>hy(e.plan)),[f,p]=(0,U.useState)(null),[m,h]=(0,U.useState)(null),g=(0,U.useRef)(e.model??`claude-opus-4-8`),[_,v]=(0,U.useState)(g.current),y=(0,U.useRef)(void 0),[b,x]=(0,U.useState)();(0,U.useEffect)(()=>{if(!b)return;let e=setTimeout(()=>x(void 0),4e3);return()=>clearTimeout(e)},[b]);let[S,C]=(0,U.useState)(e.chat??[]),[w,T]=(0,U.useState)(!1),[E,D]=(0,U.useState)();async function O(e){let t=e.trim();if(!t||w||!n)return;let r=xy(S);C(e=>[...e,{role:`user`,text:t,at:new Date().toISOString()}]),T(!0),D(void 0);try{let e=await n.chat(t,r,g.current);i(e.plan),C(t=>[...t,{...e.reply,...e.toolCalls.length>0?{toolCalls:e.toolCalls}:{},...e.resolvedRefs.length>0||e.unresolvedRefs.length>0?{refs:{resolved:e.resolvedRefs,unresolved:e.unresolvedRefs}}:{}}])}catch(e){D(e instanceof Error?e.message:String(e))}finally{T(!1)}}function k(){C([]),D(void 0),n?.clearChat().catch(()=>{})}let[A,j]=(0,U.useState)(),[M,ee]=(0,U.useState)(!1);(0,U.useEffect)(()=>{if(!n)return;let e=!1;return n.getPrompt().then(t=>{e||j(t)}).catch(()=>{e||ee(!0)}),()=>{e=!0}},[n]);function te(e){A&&(j(e===null?{...A,system:A.default,custom:!1}:{...A,system:e,custom:e!==A.default}),n?.savePrompt(e).catch(()=>{}))}let ne=(0,U.useCallback)(async e=>{if(!n)return null;p(e);try{let t=await n.generate(e,g.current);return x(t.mode===`metadata-only`?`Body is hand-edited — updated metadata only, .md files untouched.`:`Generated + validated: ${t.changedFiles.length} file${t.changedFiles.length===1?``:`s`} changed.`),s(n=>{let r=n[e]?.status??`draft`;return{...n,[e]:t.mode===`generated`?{hasSpec:!0,handEdited:!1,status:r}:n[e]??{hasSpec:!0,handEdited:!0,status:r}}}),t.mode}catch(e){return x(e instanceof Error?e.message:String(e)),null}finally{p(null)}},[n]),N=(0,U.useCallback)(async(e,n)=>{try{await t.setStatus(e,n),s(t=>({...t,[e]:{...t[e]??{hasSpec:!1,handEdited:!1,status:n},status:n}}))}catch(e){x(e instanceof Error?e.message:String(e))}},[t]);(0,U.useEffect)(()=>{a.current=py(r,a.current),l(my(r,a.current,{...n?{generate:e=>void ne(e)}:{},generatingId:f,setStatus:(e,t)=>void N(e,t)},o)),d(hy(r))},[r,f,ne,N,o,n]);let P=(0,U.useCallback)(()=>{clearTimeout(y.current),y.current=setTimeout(()=>{t.saveUiState({...t.llm?{model:g.current}:{},positions:a.current}).catch(()=>{})},800)},[t]);function F(e){g.current=e,v(e),P()}let re=(0,U.useCallback)(e=>{l(t=>$h(e,t));let t=!1;for(let n of e)n.type===`position`&&n.position&&(a.current={...a.current,[n.id]:{x:n.position.x,y:n.position.y}},n.dragging||(t=!0));t&&P()},[P]);async function ie(e,n){try{let r=await t.createSpec(e,n);return i(e=>({...e,nodes:[...e.nodes,r]})),!0}catch(e){return x(e instanceof Error?e.message:String(e)),!1}}async function ae(e){try{let n=await t.createStory(e);return i(e=>({...e,nodes:[...e.nodes,n]})),!0}catch(e){return x(e instanceof Error?e.message:String(e)),!1}}let I=(0,U.useCallback)(async(e,n)=>{try{let r=await t.link(e,n);return i(e=>({...e,edges:[...e.edges,r]})),!0}catch(e){return x(e instanceof Error?e.message:String(e)),!1}},[t]),L=(0,U.useCallback)(e=>{!e.source||!e.target||I(e.source,e.target)},[I]),oe=(0,U.useCallback)(async(e,n)=>{try{await t.unlink(e,n),i(t=>({...t,edges:t.edges.filter(t=>!(t.from===e&&t.to===n))})),x(`Unlinked ${e} -> ${n}.`)}catch(e){x(e instanceof Error?e.message:String(e))}},[t]),se=(0,U.useCallback)(e=>{let t=e.filter(e=>e.type!==`remove`);t.length>0&&d(e=>eg(t,e));for(let t of e){if(t.type!==`remove`)continue;let[e,n]=t.id.split(`->`);e&&n&&oe(e,n)}},[oe]);return(0,W.jsxs)(`div`,{className:`app`,children:[(0,W.jsx)(ay,{rootName:e.rootName,...n?{model:_,onModelChange:F}:{}}),(0,W.jsxs)(`main`,{className:`workspace`,children:[(0,W.jsx)(gy,{rfNodes:c,rfEdges:u,onConnect:L,onEdgesChange:se,onNodesChange:re,onNodeClick:e=>{let t=r.nodes.find(t=>t.id===e);t?.type===`spec`&&o[e]?.hasSpec&&h({id:t.id,title:t.title})},toast:b,children:m&&(0,W.jsx)(Dy,{specId:m.id,title:m.title,generating:f===m.id,loadArtifacts:e=>t.getSpecArtifacts(e),...n?{onRegenerate:()=>ne(m.id)}:{},onClose:()=>h(null)})}),(0,W.jsx)(wy,{plan:r,llm:!!n,onCreateSpec:ie,onCreateStory:ae,promptInfo:A,promptFailed:M,onSavePrompt:te,chat:S,chatPending:w,chatError:E,onSendChat:O,onClearChat:k,searchFiles:n?e=>n.searchFiles(e):void 0})]})]})}var ky=Io(`/api`,{llm:!0});function Ay(){let[e,t]=(0,U.useState)({mode:`loading`});return(0,U.useEffect)(()=>{Lo(ky).then(t)},[]),e.mode===`loading`?(0,W.jsx)(`div`,{className:`boot`,children:`Loading…`}):e.mode===`error`?(0,W.jsxs)(`div`,{className:`boot`,children:[`Could not reach the specplan server: `,e.detail,`. Launch it with`,` `,(0,W.jsx)(`code`,{children:`specplan [rootDir]`}),` and reload.`]}):(0,W.jsx)(Oy,{session:e.session,api:ky})}var jy=document.getElementById(`root`);if(!jy)throw Error(`Missing #root element`);(0,go.createRoot)(jy).render((0,W.jsx)(U.StrictMode,{children:(0,W.jsx)(Ay,{})}));
|
package/dist/client/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>SpecPlan</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-WZJ90U6D.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CRmpUkRq.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coopcli/specplan",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.6",
|
|
4
4
|
"description": "coopcli specplan — plan your project as a DAG of specs and user stories on a React Flow canvas, generate OpenSpec changes per spec card. Local-only.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.react-flow{--xy-edge-stroke-default:#b1b1b7;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#555;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#ffffff80;--xy-minimap-background-color-default:#fff;--xy-minimap-mask-background-color-default:#f0f0f099;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#e2e2e2;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:transparent;--xy-background-pattern-dots-color-default:#91919a;--xy-background-pattern-lines-color-default:#eee;--xy-background-pattern-cross-color-default:#e2e2e2;background-color:var(--xy-background-color,var(--xy-background-color-default));--xy-node-color-default:inherit;--xy-node-border-default:1px solid #1a192b;--xy-node-background-color-default:#fff;--xy-node-group-background-color-default:#f0f0f040;--xy-node-boxshadow-hover-default:0 1px 4px 1px #00000014;--xy-node-boxshadow-selected-default:0 0 0 .5px #1a192b;--xy-node-border-radius-default:3px;--xy-handle-background-color-default:#1a192b;--xy-handle-border-color-default:#fff;--xy-selection-background-color-default:#0059dc14;--xy-selection-border-default:1px dotted #0059dccc;--xy-controls-button-background-color-default:#fefefe;--xy-controls-button-background-color-hover-default:#f4f4f4;--xy-controls-button-color-default:inherit;--xy-controls-button-color-hover-default:inherit;--xy-controls-button-border-color-default:#eee;--xy-controls-box-shadow-default:0 0 2px 1px #00000014;--xy-edge-label-background-color-default:#fff;--xy-edge-label-color-default:inherit;--xy-resize-background-color-default:#3367d9;direction:ltr}.react-flow.dark{--xy-edge-stroke-default:#3e3e3e;--xy-edge-stroke-width-default:1;--xy-edge-stroke-selected-default:#727272;--xy-connectionline-stroke-default:#b1b1b7;--xy-connectionline-stroke-width-default:1;--xy-attribution-background-color-default:#96969640;--xy-minimap-background-color-default:#141414;--xy-minimap-mask-background-color-default:#3c3c3c99;--xy-minimap-mask-stroke-color-default:transparent;--xy-minimap-mask-stroke-width-default:1;--xy-minimap-node-background-color-default:#2b2b2b;--xy-minimap-node-stroke-color-default:transparent;--xy-minimap-node-stroke-width-default:2;--xy-background-color-default:#141414;--xy-background-pattern-dots-color-default:#555;--xy-background-pattern-lines-color-default:#333;--xy-background-pattern-cross-color-default:#333;--xy-node-color-default:#f8f8f8;--xy-node-border-default:1px solid #3c3c3c;--xy-node-background-color-default:#1e1e1e;--xy-node-group-background-color-default:#f0f0f040;--xy-node-boxshadow-hover-default:0 1px 4px 1px #ffffff14;--xy-node-boxshadow-selected-default:0 0 0 .5px #999;--xy-handle-background-color-default:#bebebe;--xy-handle-border-color-default:#1e1e1e;--xy-selection-background-color-default:#c8c8dc14;--xy-selection-border-default:1px dotted #c8c8dccc;--xy-controls-button-background-color-default:#2b2b2b;--xy-controls-button-background-color-hover-default:#3e3e3e;--xy-controls-button-color-default:#f8f8f8;--xy-controls-button-color-hover-default:#fff;--xy-controls-button-border-color-default:#5b5b5b;--xy-controls-box-shadow-default:0 0 2px 1px #00000014;--xy-edge-label-background-color-default:#141414;--xy-edge-label-color-default:#f8f8f8}.react-flow__background{background-color:var(--xy-background-color-props,var(--xy-background-color,var(--xy-background-color-default)));pointer-events:none;z-index:-1}.react-flow__container{width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__pane{z-index:1;touch-action:none}.react-flow__pane.draggable{cursor:grab}.react-flow__pane.dragging{cursor:grabbing}.react-flow__pane.selection{cursor:pointer}.react-flow__viewport{transform-origin:0 0;z-index:2;pointer-events:none}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow__edge-path{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default));stroke-width:var(--xy-edge-stroke-width,var(--xy-edge-stroke-width-default));fill:none}.react-flow__connection-path{stroke:var(--xy-connectionline-stroke,var(--xy-connectionline-stroke-default));stroke-width:var(--xy-connectionline-stroke-width,var(--xy-connectionline-stroke-width-default));fill:none}.react-flow .react-flow__edges{position:absolute}.react-flow .react-flow__edges svg{pointer-events:none;position:absolute;overflow:visible}.react-flow__edge{pointer-events:visibleStroke}.react-flow__edge.selectable{cursor:pointer}.react-flow__edge.animated path{stroke-dasharray:5;animation:.5s linear infinite dashdraw}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge.selectable:focus .react-flow__edge-path,.react-flow__edge.selectable:focus-visible .react-flow__edge-path{stroke:var(--xy-edge-stroke-selected,var(--xy-edge-stroke-selected-default))}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;user-select:none}.react-flow__arrowhead polyline{stroke:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__arrowhead polyline.arrowclosed{fill:var(--xy-edge-stroke,var(--xy-edge-stroke-default))}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:.5s linear infinite dashdraw}svg.react-flow__connectionline{z-index:1001;position:absolute;overflow:visible}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{-webkit-user-select:none;user-select:none;pointer-events:all;transform-origin:0 0;box-sizing:border-box;cursor:default;position:absolute}.react-flow__node.selectable{cursor:pointer}.react-flow__node.draggable{cursor:grab;pointer-events:all}.react-flow__node.draggable.dragging{cursor:grabbing}.react-flow__nodesselection{z-index:3;transform-origin:0 0;pointer-events:none}.react-flow__nodesselection-rect{pointer-events:all;cursor:grab;position:absolute}.react-flow__handle{pointer-events:none;background-color:var(--xy-handle-background-color,var(--xy-handle-background-color-default));border:1px solid var(--xy-handle-border-color,var(--xy-handle-border-color-default));border-radius:100%;width:6px;min-width:5px;height:6px;min-height:5px;position:absolute}.react-flow__handle.connectingfrom{pointer-events:all}.react-flow__handle.connectionindicator{pointer-events:all;cursor:crosshair}.react-flow__handle-bottom{top:auto;bottom:0;left:50%;transform:translate(-50%,50%)}.react-flow__handle-top{top:0;left:50%;transform:translate(-50%,-50%)}.react-flow__handle-left{top:50%;left:0;transform:translate(-50%,-50%)}.react-flow__handle-right{top:50%;right:0;transform:translate(50%,-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__pane.selection .react-flow__panel{pointer-events:none}.react-flow__panel{z-index:5;margin:15px;position:absolute}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.top.center,.react-flow__panel.bottom.center{left:50%;transform:translate(-15px)translate(-50%)}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.left.center,.react-flow__panel.right.center{top:50%;transform:translateY(-15px)translateY(-50%)}.react-flow__attribution{background:var(--xy-attribution-background-color,var(--xy-attribution-background-color-default));margin:0;padding:2px 3px;font-size:10px}.react-flow__attribution a{color:#999;text-decoration:none}@keyframes dashdraw{0%{stroke-dashoffset:10px}}.react-flow__edgelabel-renderer{pointer-events:none;-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__viewport-portal{-webkit-user-select:none;user-select:none;width:100%;height:100%;position:absolute;top:0;left:0}.react-flow__minimap{background:var(--xy-minimap-background-color-props,var(--xy-minimap-background-color,var(--xy-minimap-background-color-default)))}.react-flow__minimap-svg{display:block}.react-flow__minimap-mask{fill:var(--xy-minimap-mask-background-color-props,var(--xy-minimap-mask-background-color,var(--xy-minimap-mask-background-color-default)));stroke:var(--xy-minimap-mask-stroke-color-props,var(--xy-minimap-mask-stroke-color,var(--xy-minimap-mask-stroke-color-default)));stroke-width:var(--xy-minimap-mask-stroke-width-props,var(--xy-minimap-mask-stroke-width,var(--xy-minimap-mask-stroke-width-default)))}.react-flow__minimap-node{fill:var(--xy-minimap-node-background-color-props,var(--xy-minimap-node-background-color,var(--xy-minimap-node-background-color-default)));stroke:var(--xy-minimap-node-stroke-color-props,var(--xy-minimap-node-stroke-color,var(--xy-minimap-node-stroke-color-default)));stroke-width:var(--xy-minimap-node-stroke-width-props,var(--xy-minimap-node-stroke-width,var(--xy-minimap-node-stroke-width-default)))}.react-flow__background-pattern.dots{fill:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-dots-color-default)))}.react-flow__background-pattern.lines{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-lines-color-default)))}.react-flow__background-pattern.cross{stroke:var(--xy-background-pattern-color-props,var(--xy-background-pattern-color,var(--xy-background-pattern-cross-color-default)))}.react-flow__controls{box-shadow:var(--xy-controls-box-shadow,var(--xy-controls-box-shadow-default));flex-direction:column;display:flex}.react-flow__controls.horizontal{flex-direction:row}.react-flow__controls-button{background:var(--xy-controls-button-background-color,var(--xy-controls-button-background-color-default));border:none;border-bottom:1px solid var(--xy-controls-button-border-color-props,var(--xy-controls-button-border-color,var(--xy-controls-button-border-color-default)));width:26px;height:26px;color:var(--xy-controls-button-color-props,var(--xy-controls-button-color,var(--xy-controls-button-color-default)));cursor:pointer;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;padding:4px;display:flex}.react-flow__controls-button svg{fill:currentColor;width:100%;max-width:12px;max-height:12px}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-input,.react-flow__node-default,.react-flow__node-output,.react-flow__node-group{border-radius:var(--xy-node-border-radius,var(--xy-node-border-radius-default));width:150px;color:var(--xy-node-color,var(--xy-node-color-default));text-align:center;border:var(--xy-node-border,var(--xy-node-border-default));background-color:var(--xy-node-background-color,var(--xy-node-background-color-default));padding:10px;font-size:12px}.react-flow__node-input.selectable:hover,.react-flow__node-default.selectable:hover,.react-flow__node-output.selectable:hover,.react-flow__node-group.selectable:hover{box-shadow:var(--xy-node-boxshadow-hover,var(--xy-node-boxshadow-hover-default))}.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible{box-shadow:var(--xy-node-boxshadow-selected,var(--xy-node-boxshadow-selected-default))}.react-flow__node-group{background-color:var(--xy-node-group-background-color,var(--xy-node-group-background-color-default))}.react-flow__nodesselection-rect,.react-flow__selection{background:var(--xy-selection-background-color,var(--xy-selection-background-color-default));border:var(--xy-selection-border,var(--xy-selection-border-default))}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls-button:hover{background:var(--xy-controls-button-background-color-hover-props,var(--xy-controls-button-background-color-hover,var(--xy-controls-button-background-color-hover-default)));color:var(--xy-controls-button-color-hover-props,var(--xy-controls-button-color-hover,var(--xy-controls-button-color-hover-default)))}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__controls-button:last-child{border-bottom:none}.react-flow__controls.horizontal .react-flow__controls-button{border-bottom:none;border-right:1px solid var(--xy-controls-button-border-color-props,var(--xy-controls-button-border-color,var(--xy-controls-button-border-color-default)))}.react-flow__controls.horizontal .react-flow__controls-button:last-child{border-right:none}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.top,.react-flow__resize-control.bottom{cursor:ns-resize}.react-flow__resize-control.top.left,.react-flow__resize-control.bottom.right{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{background-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border:1px solid #fff;border-radius:1px;width:5px;height:5px;translate:-50% -50%}.react-flow__resize-control.handle.left{top:50%;left:0}.react-flow__resize-control.handle.right{top:50%;left:100%}.react-flow__resize-control.handle.top{top:0;left:50%}.react-flow__resize-control.handle.bottom{top:100%;left:50%}.react-flow__resize-control.handle.top.left,.react-flow__resize-control.handle.bottom.left{left:0}.react-flow__resize-control.handle.top.right,.react-flow__resize-control.handle.bottom.right{left:100%}.react-flow__resize-control.line{border-color:var(--xy-resize-background-color,var(--xy-resize-background-color-default));border-style:solid;border-width:0}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{width:1px;height:100%;top:0;transform:translate(-50%)}.react-flow__resize-control.line.left{border-left-width:1px;left:0}.react-flow__resize-control.line.right{border-right-width:1px;left:100%}.react-flow__resize-control.line.top,.react-flow__resize-control.line.bottom{width:100%;height:1px;left:0;transform:translateY(-50%)}.react-flow__resize-control.line.top{border-top-width:1px;top:0}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__edge-textbg{fill:var(--xy-edge-label-background-color,var(--xy-edge-label-background-color-default))}.react-flow__edge-text{fill:var(--xy-edge-label-color,var(--xy-edge-label-color-default))}:root{--bg:#0f0f0f;--panel:#1a1a1a;--border:#2a2a2a;--text:#e8e8e8;--muted:#888;--accent:#e8925b;--accent-hover:#f0a873;--accent-2:#28c840;--danger:#ff5f57;--ff-mono:"SF Mono", "Fira Code", "Cascadia Code", ui-monospace, Menlo, Consolas, monospace}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{font-family:var(--ff-mono);color:var(--text);background:var(--bg)}.app{flex-direction:column;height:100%;display:flex}.topbar{border-bottom:1px solid var(--border);background:var(--panel);justify-content:space-between;align-items:center;gap:16px;padding:10px 16px;display:flex}.brand{align-items:center;gap:12px;display:flex}.logo{color:var(--accent);font-size:26px}.brand h1{letter-spacing:.2px;margin:0;font-size:16px;font-weight:700}.brand-coop{color:var(--accent);font-weight:800}.brand p{color:var(--muted);margin:2px 0 0;font-size:12px}.actions{align-items:center;gap:10px;display:flex}.title-input{background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:8px;width:240px;padding:8px 12px;font-size:13px}.title-input:focus{border-color:var(--accent);outline:none}.model-select{background:var(--bg);border:1px solid var(--border);color:var(--muted);font-size:12px;font-family:var(--ff-mono);cursor:pointer;border-radius:8px;padding:8px 10px}.model-select:focus{border-color:var(--accent);color:var(--text);outline:none}.generate{background:var(--accent);color:var(--bg);cursor:pointer;border:none;border-radius:8px;padding:9px 16px;font-size:13px;font-weight:600}.generate:hover:not(:disabled){background:var(--accent-hover)}.generate:disabled{opacity:.6;cursor:default}.boot{height:100%;color:var(--muted);justify-content:center;align-items:center;font-size:14px;display:flex}.canvas-id{font-family:var(--ff-mono);color:var(--accent-2);font-size:11px}.view-toggle{border:1px solid var(--border);border-radius:8px;gap:0;display:flex;overflow:hidden}.toggle{color:var(--muted);cursor:pointer;background:0 0;border:none;padding:8px 18px;font-size:13px}.toggle.active{color:var(--text);background:#e8925b33}.toggle:disabled{opacity:.45;cursor:not-allowed}.copy-link{border:1px solid var(--border);color:var(--muted);cursor:pointer;white-space:nowrap;background:0 0;border-radius:8px;padding:8px 12px;font-size:12px}.copy-link:hover{color:var(--text);border-color:var(--accent)}.workspace,.spec-view{flex:1;min-height:0;display:flex}.tree{border-right:1px solid var(--border);background:var(--panel);width:320px;padding:12px;overflow-y:auto}.tree-head{border-bottom:1px solid var(--border);margin-bottom:12px;padding:4px 6px 12px}.tree-change{font-family:var(--ff-mono);color:var(--accent);font-size:13px;font-weight:600}.tree-summary{color:var(--muted);margin:8px 0 0;font-size:12px;line-height:1.5}.tree-group{margin-bottom:14px}.tree-group-name{text-transform:uppercase;letter-spacing:.08em;color:var(--muted);padding:4px 6px;font-size:11px}.tree-item{text-align:left;cursor:pointer;width:100%;color:var(--text);background:0 0;border:1px solid #0000;border-radius:6px;padding:6px 8px;display:block}.tree-item:hover{border-color:var(--border)}.tree-item.active{border-color:var(--accent);background:#e8925b26}.tree-label{font-family:var(--ff-mono);font-size:12px;display:block}.tree-path{color:var(--accent-2);font-size:10.5px;font-family:var(--ff-mono);text-overflow:ellipsis;white-space:nowrap;margin-top:2px;display:block;overflow:hidden}.reader{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.reader .artifact-body{max-width:900px}.canvas{flex:1;min-width:0;position:relative}.canvas :where(.excalidraw){height:100%}.panel{border-left:1px solid var(--border);background:var(--panel);flex-direction:column;width:420px;min-height:0;display:flex}.empty{color:var(--muted);padding:24px;font-size:14px;line-height:1.5}.empty .hint{margin-top:12px;font-size:12px}.empty.error{color:var(--danger);white-space:pre-wrap}.tabs{border-bottom:1px solid var(--border);flex-wrap:wrap;gap:4px;padding:10px;display:flex}.tab{border:1px solid var(--border);color:var(--muted);font-size:11px;font-family:var(--ff-mono);cursor:pointer;background:0 0;border-radius:6px;padding:5px 9px}.tab.active{color:var(--text);border-color:var(--accent);background:#e8925b26}.artifact-head{justify-content:space-between;align-items:center;gap:8px;padding:10px 12px;display:flex}.path{color:var(--accent-2);font-size:11px;font-family:var(--ff-mono);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.copy{border:1px solid var(--border);color:var(--muted);cursor:pointer;background:0 0;border-radius:6px;flex-shrink:0;padding:4px 10px;font-size:11px}.artifact-body{white-space:pre-wrap;word-break:break-word;font-family:var(--ff-mono);color:var(--text);flex:1;margin:0;padding:0 16px 16px;font-size:12.5px;line-height:1.55;overflow:auto}.pane-nav{border-bottom:1px solid var(--border);background:var(--panel);flex-shrink:0;gap:0;display:flex}.pane-item{color:var(--muted);font-size:12px;font-family:var(--ff-mono);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-bottom:2px solid #0000;flex:1;padding:10px 12px}.pane-item:hover:not(:disabled){color:var(--text)}.pane-item.active{color:var(--text);border-bottom-color:var(--accent);background:#e8925b14}.pane-item:disabled{opacity:.45;cursor:not-allowed}.prompt-pane{flex-direction:column;flex:1;min-height:0;display:flex}.prompt-actions{flex-shrink:0;gap:6px;display:flex}.prompt-save:not(:disabled){color:var(--bg);background:var(--accent);border-color:var(--accent)}.prompt-save:disabled,.prompt-actions .copy:disabled{opacity:.45;cursor:default}.prompt-editor{background:var(--bg);border:1px solid var(--border);color:var(--text);font-size:12.5px;line-height:1.55;font-family:var(--ff-mono);resize:none;border-radius:8px;flex:1;min-height:0;margin:0 12px;padding:10px 12px}.prompt-editor:focus{border-color:var(--accent);outline:none}.prompt-hint{color:var(--muted);margin:8px 12px 12px;font-size:11px;line-height:1.5}.prompt-hint code{color:var(--accent-2)}.at-anchor{flex-direction:column;min-height:0;display:flex;position:relative}.prompt-anchor{flex:1;margin:0 12px}.prompt-anchor .prompt-editor{flex:1;margin:0}.at-search{z-index:10;background:var(--panel);border:1px solid var(--border);border-radius:8px;max-height:220px;margin:0;padding:4px;list-style:none;position:absolute;left:0;right:0;overflow-y:auto;box-shadow:0 8px 24px #00000080}.at-search.up{bottom:calc(100% + 6px)}.at-search.down{top:6px;left:6px;right:6px}.at-item{text-align:left;width:100%;font-size:11.5px;font-family:var(--ff-mono);color:var(--text);cursor:pointer;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:1px solid #0000;border-radius:6px;padding:5px 8px;display:block;overflow:hidden}.at-item:hover,.at-item.active{border-color:var(--accent);background:#e8925b26}.at-item.dir{color:var(--accent-2)}.regenerate{border:1px solid var(--accent);color:var(--accent);cursor:pointer;white-space:nowrap;background:0 0;border-radius:8px;padding:8px 14px;font-size:13px;font-weight:600}.regenerate:hover:not(:disabled){color:var(--accent-hover);border-color:var(--accent-hover)}.regenerate:disabled{opacity:.45;cursor:default}.chat{flex-direction:column;flex:1;min-height:0;display:flex}.chat-messages{flex-direction:column;flex:1;gap:10px;padding:12px;display:flex;overflow-y:auto}.chat-empty{color:var(--muted);padding:12px 4px;font-size:12.5px;line-height:1.55}.chat-empty code{color:var(--accent-2)}.chat-message{border:1px solid var(--border);border-radius:8px;padding:8px 10px;font-size:12.5px;line-height:1.55}.chat-user{border-color:var(--accent);background:#e8925b14}.chat-summary{background:#28c8400f;border-style:dashed}.chat-role{text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin-bottom:4px;font-size:10px}.chat-summary .chat-role{color:var(--accent-2)}.chat-text{white-space:pre-wrap;word-break:break-word}.chat-thinking{color:var(--muted);border-style:dashed}.chat-fault{color:var(--danger);white-space:pre-wrap;padding:4px;font-size:12px}.chat-refs{color:var(--muted);margin-top:6px;font-size:11px}.chat-refs summary{cursor:pointer}.chat-refs ul{margin:6px 0 0;padding-left:18px}.chat-refs li{color:var(--accent-2)}.chat-refs li.chat-ref-missing{color:var(--danger)}.chat-composer{border-top:1px solid var(--border);flex-direction:column;gap:8px;padding:10px 12px;display:flex}.chat-input{background:var(--bg);border:1px solid var(--border);color:var(--text);font-size:12.5px;font-family:var(--ff-mono);resize:vertical;border-radius:8px;min-height:40px;padding:8px 10px}.chat-input:focus{border-color:var(--accent);outline:none}.chat-composer-actions{justify-content:space-between;gap:8px;display:flex}.chat-send{background:var(--accent);color:var(--bg);cursor:pointer;border:none;border-radius:6px;padding:6px 14px;font-size:12px;font-weight:600}.chat-send:hover:not(:disabled){background:var(--accent-hover)}.chat-send:disabled{opacity:.6;cursor:default}.chat-clear{border:1px solid var(--border);color:var(--muted);cursor:pointer;background:0 0;border-radius:6px;padding:6px 12px;font-size:12px}.chat-clear:hover:not(:disabled){color:var(--danger);border-color:var(--danger)}.chat-clear:disabled{opacity:.45;cursor:default}.share-pill{border:1px solid var(--border);color:var(--muted);white-space:nowrap;border-radius:999px;align-items:center;gap:8px;padding:4px 6px 4px 12px;font-size:11.5px;display:flex}.share-dot{background:#868e96;border-radius:50%;flex-shrink:0;width:8px;height:8px}.share-connected .share-dot{background:#2f9e44;box-shadow:0 0 6px #2f9e44b3}.share-connecting .share-dot,.share-reconnecting .share-dot{background:#f08c00;animation:1.2s ease-in-out infinite share-pulse}.share-ended .share-dot,.share-rejected .share-dot{background:#e03131}@keyframes share-pulse{50%{opacity:.35}}.share-copy{border:1px solid var(--border);color:var(--muted);cursor:pointer;background:0 0;border-radius:999px;padding:3px 10px;font-size:11px}.share-copy:hover{color:var(--text);border-color:var(--accent-2)}.viewer-notice{background:var(--bg);justify-content:center;align-items:center;height:100vh;display:flex}.viewer-notice-card{text-align:center;border:1px solid var(--border);border-radius:12px;max-width:440px;padding:40px}.viewer-notice-card .logo{font-size:28px}.viewer-notice-card h1{color:var(--text);margin:12px 0 8px;font-size:18px}.viewer-notice-card p{color:var(--muted);margin:0;font-size:13px;line-height:1.6}.viewer-canvas{flex:1}.react-flow{background:var(--bg)}.react-flow__attribution{display:none}.card{border:1px solid var(--border);background:var(--panel);width:240px;font-family:var(--ff-mono);color:var(--text);border-radius:8px;padding:10px 12px;box-shadow:0 2px 10px #00000059}.card-spec{border-color:var(--accent)}.card-story{border-style:dashed}.card-kind{text-transform:uppercase;letter-spacing:.8px;color:var(--muted);margin-bottom:4px;font-size:10px}.card-spec .card-kind{color:var(--accent)}.card-title{overflow-wrap:anywhere;font-size:13px;font-weight:700}.card-text{overflow-wrap:anywhere;font-size:12px;line-height:1.45}.card-actions{align-items:center;gap:6px;margin-top:8px;display:flex}.react-flow__handle{background:var(--accent);border:1px solid var(--bg);width:9px;height:9px}.edge-dependency .react-flow__edge-path{stroke:var(--accent);stroke-width:1.6px}.edge-containment .react-flow__edge-path{stroke:var(--muted);stroke-width:1.4px}.canvas{position:relative}.toast{border:1px solid var(--danger);max-width:80%;color:var(--text);z-index:30;background:#2a1512;border-radius:8px;padding:10px 14px;font-size:12.5px;position:absolute;bottom:22px;left:50%;transform:translate(-50%);box-shadow:0 6px 20px #00000080}.plan-pane{flex-direction:column;gap:18px;padding:14px;display:flex;overflow-y:auto}.plan-form{flex-direction:column;gap:8px;display:flex}.plan-form h2{text-transform:uppercase;letter-spacing:.8px;color:var(--muted);margin:0;font-size:12px}.plan-form input,.plan-form textarea,.plan-form select{background:var(--bg);border:1px solid var(--border);color:var(--text);font-family:var(--ff-mono);border-radius:6px;padding:8px 10px;font-size:12.5px}.plan-form input:focus,.plan-form textarea:focus,.plan-form select:focus{border-color:var(--accent);outline:none}.plan-form button{background:var(--accent);color:#14100c;cursor:pointer;font-family:var(--ff-mono);border:none;border-radius:6px;align-self:flex-start;padding:7px 12px;font-size:12.5px;font-weight:700}.plan-form button:hover:not(:disabled){background:var(--accent-hover)}.plan-form button:disabled{opacity:.45;cursor:default}.plan-counts{margin:0}.backlog-pane{flex-direction:column;gap:16px;padding:14px;display:flex;overflow-y:auto}.backlog-section h2{text-transform:uppercase;letter-spacing:.8px;color:var(--muted);margin:0 0 8px;font-size:12px}.backlog-list{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.backlog-item{border:1px solid var(--border);border-radius:6px;padding:8px 10px;font-size:12.5px}.backlog-item .backlog-id{color:var(--muted);margin-top:3px;font-size:10.5px;display:block}.card-generate{border:1px solid var(--accent);color:var(--accent);cursor:pointer;font-family:var(--ff-mono);background:0 0;border-radius:5px;padding:4px 8px;font-size:10.5px}.card-generate:hover:not(:disabled){background:var(--accent);color:#14100c}.card-generate:disabled{opacity:.5;cursor:default}.card-badge{color:var(--accent-2);letter-spacing:.4px;margin-left:8px}.card-has-spec{cursor:pointer}.dialog-overlay{z-index:40;background:#0000008c;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.dialog{background:var(--panel);border:1px solid var(--border);border-radius:10px;flex-direction:column;gap:10px;width:min(860px,92%);max-height:88%;padding:14px;display:flex;box-shadow:0 14px 48px #0009}.dialog-head{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.dialog-title{font-size:14px;font-weight:700}.dialog-path{color:var(--muted);font-size:11px}.dialog-actions{gap:8px;display:flex}.dialog-notice{border:1px solid var(--accent);color:var(--text);background:#221507;border-radius:6px;margin:0;padding:8px 10px;font-size:12px;line-height:1.5}.dialog-body{flex:1;min-height:200px}.backlog-actions{gap:8px;display:flex}.card-description{color:var(--muted);margin-top:5px;font-size:11px}.dialog-create{width:min(560px,92%)}.dialog-create .plan-form h2{margin-top:6px}.dialog-submit{justify-content:flex-end;display:flex}.react-flow__edge.selected .react-flow__edge-path{stroke:var(--danger);stroke-width:2.4px}.card-status-wrap{margin-left:auto;display:inline-block;position:relative}.card-status{background:var(--bg);border:1px solid var(--border);color:var(--muted);font-family:var(--ff-mono);text-transform:uppercase;letter-spacing:.6px;cursor:pointer;border-radius:999px;padding:1px 7px;font-size:9.5px}.card-status:focus{border-color:var(--accent);outline:none}.status-menu{z-index:60;background:var(--panel);border:1px solid var(--border);border-radius:8px;flex-direction:column;gap:2px;min-width:92px;padding:4px;display:flex;position:absolute;top:calc(100% + 4px);right:0;box-shadow:0 8px 26px #0000008c}.status-option{color:var(--text);cursor:pointer;font-family:var(--ff-mono);text-align:left;text-transform:uppercase;letter-spacing:.6px;background:0 0;border:none;border-radius:5px;padding:5px 8px;font-size:10.5px}.status-option:hover{background:var(--bg)}.status-option.current{color:var(--accent);font-weight:700}.status-option.status-done:hover,.status-option.status-done.current{color:var(--accent-2)}.card-status.status-active{color:var(--accent);border-color:var(--accent)}.card-status.status-done{color:var(--accent-2);border-color:var(--accent-2)}.card-status.status-deferred{opacity:.6}.card-kind{align-items:center;gap:4px;display:flex}
|