@ultrst-armada/floks 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +2 -3
  2. package/index.d.ts +2 -0
  3. package/index.js +2 -0
  4. package/package.json +67 -4
  5. package/packages/canvas-ui/dist/canvas/index.d.ts +54 -0
  6. package/packages/canvas-ui/dist/canvas/index.js +12 -0
  7. package/packages/canvas-ui/dist/chunk-2GLR35UM.js +391 -0
  8. package/packages/canvas-ui/dist/chunk-34YRDZPJ.js +189 -0
  9. package/packages/canvas-ui/dist/chunk-6VB74RCH.js +147 -0
  10. package/packages/canvas-ui/dist/chunk-QTTWWBNN.js +114 -0
  11. package/packages/canvas-ui/dist/chunk-QWQ4PCXQ.js +718 -0
  12. package/packages/canvas-ui/dist/chunk-SA3JADUG.js +160 -0
  13. package/packages/canvas-ui/dist/chunk-UEIMM6PV.js +508 -0
  14. package/packages/canvas-ui/dist/dock/index.d.ts +37 -0
  15. package/packages/canvas-ui/dist/dock/index.js +10 -0
  16. package/packages/canvas-ui/dist/editor/index.d.ts +44 -0
  17. package/packages/canvas-ui/dist/editor/index.js +10 -0
  18. package/packages/canvas-ui/dist/graph-2d/index.d.ts +270 -0
  19. package/packages/canvas-ui/dist/graph-2d/index.js +50 -0
  20. package/packages/canvas-ui/dist/index.d.ts +176 -0
  21. package/packages/canvas-ui/dist/index.js +1171 -0
  22. package/packages/canvas-ui/dist/predictive/index.d.ts +74 -0
  23. package/packages/canvas-ui/dist/predictive/index.js +13 -0
  24. package/packages/canvas-ui/dist/tile-menu/index.d.ts +45 -0
  25. package/packages/canvas-ui/dist/tile-menu/index.js +12 -0
  26. package/packages/canvas-ui/dist/types-D3RRfQUo.d.ts +46 -0
  27. package/packages/canvas-ui/floks.manifest.json +35 -0
  28. package/packages/canvas-ui/package.json +82 -0
  29. package/packages/ui/dist/BottomStrip-DYhAUQR4.d.ts +12 -0
  30. package/packages/ui/dist/chunk-5ZMXFCD4.js +0 -0
  31. package/packages/ui/dist/chunk-62ITRDJX.js +141 -0
  32. package/packages/ui/dist/chunk-A2CDQISJ.js +32 -0
  33. package/packages/ui/dist/chunk-C32CB5WO.js +1161 -0
  34. package/packages/ui/dist/chunk-C3L53YN4.js +372 -0
  35. package/packages/ui/dist/chunk-DABYTYOU.js +351 -0
  36. package/packages/ui/dist/chunk-DZJ3NSCX.js +665 -0
  37. package/packages/ui/dist/chunk-ELZOBTWX.js +562 -0
  38. package/packages/ui/dist/chunk-GKP6KHTI.js +75 -0
  39. package/packages/ui/dist/chunk-GWW3BGOB.js +238 -0
  40. package/packages/ui/dist/chunk-KIFQA7L6.js +167 -0
  41. package/packages/ui/dist/chunk-OHISLM3Z.js +703 -0
  42. package/packages/ui/dist/chunk-OR5ZNJI4.js +62 -0
  43. package/packages/ui/dist/chunk-QWXEW7WH.js +238 -0
  44. package/packages/ui/dist/chunk-RLQ2ALJG.js +182 -0
  45. package/packages/ui/dist/chunk-S227WJ5E.js +152 -0
  46. package/packages/ui/dist/chunk-SLJBDDSN.js +0 -0
  47. package/packages/ui/dist/chunk-TXKLROFC.js +370 -0
  48. package/packages/ui/dist/chunk-UOR4P6PO.js +32 -0
  49. package/packages/ui/dist/chunk-W42SJGOJ.js +19 -0
  50. package/packages/ui/dist/chunk-XXIH2HWI.js +297 -0
  51. package/packages/ui/dist/chunk-ZQK5I5ZL.js +277 -0
  52. package/packages/ui/dist/components/auth/index.css +183 -0
  53. package/packages/ui/dist/components/auth/index.d.ts +10 -0
  54. package/packages/ui/dist/components/auth/index.js +8 -0
  55. package/packages/ui/dist/components/base/index.css +183 -0
  56. package/packages/ui/dist/components/base/index.d.ts +74 -0
  57. package/packages/ui/dist/components/base/index.js +33 -0
  58. package/packages/ui/dist/components/bottom-strip/index.css +183 -0
  59. package/packages/ui/dist/components/bottom-strip/index.d.ts +67 -0
  60. package/packages/ui/dist/components/bottom-strip/index.js +22 -0
  61. package/packages/ui/dist/components/composite/index.css +273 -0
  62. package/packages/ui/dist/components/composite/index.d.ts +104 -0
  63. package/packages/ui/dist/components/composite/index.js +33 -0
  64. package/packages/ui/dist/components/containers/index.css +404 -0
  65. package/packages/ui/dist/components/containers/index.d.ts +93 -0
  66. package/packages/ui/dist/components/containers/index.js +35 -0
  67. package/packages/ui/dist/components/layout/index.css +246 -0
  68. package/packages/ui/dist/components/layout/index.d.ts +53 -0
  69. package/packages/ui/dist/components/layout/index.js +16 -0
  70. package/packages/ui/dist/components/settings/index.css +183 -0
  71. package/packages/ui/dist/components/settings/index.d.ts +14 -0
  72. package/packages/ui/dist/components/settings/index.js +12 -0
  73. package/packages/ui/dist/components/workspace/index.d.ts +101 -0
  74. package/packages/ui/dist/components/workspace/index.js +16 -0
  75. package/packages/ui/dist/hierarchy/index.css +183 -0
  76. package/packages/ui/dist/hierarchy/index.d.ts +168 -0
  77. package/packages/ui/dist/hierarchy/index.js +36 -0
  78. package/packages/ui/dist/index.css +467 -0
  79. package/packages/ui/dist/index.d.ts +16 -0
  80. package/packages/ui/dist/index.js +282 -0
  81. package/packages/ui/dist/palette/index.d.ts +29 -0
  82. package/packages/ui/dist/palette/index.js +27 -0
  83. package/packages/ui/dist/palettes-De5u5iID.d.ts +394 -0
  84. package/packages/ui/dist/theme/index.d.ts +12063 -0
  85. package/packages/ui/dist/theme/index.js +96 -0
  86. package/packages/ui/floks.manifest.json +119 -0
  87. package/packages/ui/package.json +92 -0
  88. package/packages/ui/src/styles/base.css +130 -0
  89. package/packages/ui/src/styles/composite.css +6 -0
  90. package/packages/ui/src/styles/containers.css +10 -0
  91. package/packages/ui/src/styles/details-panel.css +147 -0
  92. package/packages/ui/src/styles/layout.css +58 -0
  93. package/packages/ui/src/theme/tokens.css +93 -0
@@ -0,0 +1,1171 @@
1
+ import {
2
+ CanvasViewport,
3
+ InfiniteCanvas,
4
+ MiniMap,
5
+ useCanvas
6
+ } from "./chunk-34YRDZPJ.js";
7
+ import {
8
+ DockBar,
9
+ DockItem,
10
+ useDock
11
+ } from "./chunk-6VB74RCH.js";
12
+ import {
13
+ MonacoEditor,
14
+ skipoDarkTheme,
15
+ useMonaco
16
+ } from "./chunk-QTTWWBNN.js";
17
+ import {
18
+ BIOME_CONFIGS,
19
+ COORD_SCALE,
20
+ CanvasBackground2D,
21
+ CanvasErrorBoundary,
22
+ ContainerNode2D,
23
+ EffectNode2D,
24
+ MagneticTraces2D,
25
+ ModuleNode2D,
26
+ NodeRenderer2D,
27
+ RotaryKnob,
28
+ TriggerNode2D,
29
+ Wire2D,
30
+ useCanvas2DCoordinates,
31
+ useCanvas2DMagnetic
32
+ } from "./chunk-QWQ4PCXQ.js";
33
+ import {
34
+ PredictiveGhostNodeCard,
35
+ PredictiveHudToolbar,
36
+ PredictiveLayer2D,
37
+ usePredictiveGraph2D
38
+ } from "./chunk-UEIMM6PV.js";
39
+ import {
40
+ NODE_CARD_WIDTH,
41
+ Node2DBase,
42
+ RecorderWaveformDisplay,
43
+ SOCKET_ROW_HEIGHT,
44
+ Socket2D,
45
+ getSocketLocalOffset,
46
+ getSocketScreenPosition,
47
+ renderSpriteIcon
48
+ } from "./chunk-2GLR35UM.js";
49
+ import {
50
+ Tile,
51
+ TileCreateButton,
52
+ TileGrid,
53
+ useTileMenu
54
+ } from "./chunk-SA3JADUG.js";
55
+
56
+ // src/node-graph-ui/widgets/MidpointWidgets.tsx
57
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
58
+ function MidpointWidgets({ x, y, locked, onDelete, onInspect, onToggleLock }) {
59
+ return /* @__PURE__ */ jsxs(
60
+ "div",
61
+ {
62
+ style: {
63
+ position: "absolute",
64
+ left: x,
65
+ top: y,
66
+ transform: "translate(-50%, -50%)",
67
+ display: "flex",
68
+ alignItems: "center",
69
+ gap: "4px",
70
+ backgroundColor: "var(--skipo-surface, #1e1e1e)",
71
+ border: "1px solid var(--skipo-border, #333)",
72
+ borderRadius: "12px",
73
+ padding: "2px 6px",
74
+ boxShadow: "0 2px 8px rgba(0,0,0,0.5)",
75
+ zIndex: 7,
76
+ // Below node bodies (z-index 10) per Skipo invariant
77
+ pointerEvents: "auto"
78
+ },
79
+ onClick: (e) => e.stopPropagation(),
80
+ children: [
81
+ onToggleLock && /* @__PURE__ */ jsx(
82
+ "button",
83
+ {
84
+ type: "button",
85
+ title: locked ? "Unlock Connection" : "Lock Connection",
86
+ style: {
87
+ background: "none",
88
+ border: "none",
89
+ cursor: "pointer",
90
+ padding: "2px",
91
+ color: locked ? "var(--skipo-accent, #d4af37)" : "var(--skipo-text-muted, #888)",
92
+ display: "flex",
93
+ alignItems: "center"
94
+ },
95
+ onClick: onToggleLock,
96
+ children: /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: locked ? /* @__PURE__ */ jsxs(Fragment, { children: [
97
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
98
+ /* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
99
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
100
+ /* @__PURE__ */ jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2", ry: "2" }),
101
+ /* @__PURE__ */ jsx("path", { d: "M7 11V7a5 5 0 0 1 9.9-1" })
102
+ ] }) })
103
+ }
104
+ ),
105
+ onInspect && /* @__PURE__ */ jsx(
106
+ "button",
107
+ {
108
+ type: "button",
109
+ title: "Inspect Signal",
110
+ style: {
111
+ background: "none",
112
+ border: "none",
113
+ cursor: "pointer",
114
+ padding: "2px",
115
+ color: "var(--skipo-text-muted, #888)",
116
+ display: "flex",
117
+ alignItems: "center"
118
+ },
119
+ onClick: onInspect,
120
+ children: /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
121
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
122
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
123
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
124
+ ] })
125
+ }
126
+ ),
127
+ onDelete && !locked && /* @__PURE__ */ jsx(
128
+ "button",
129
+ {
130
+ type: "button",
131
+ title: "Delete Connection",
132
+ style: {
133
+ background: "none",
134
+ border: "none",
135
+ cursor: "pointer",
136
+ padding: "2px",
137
+ color: "#e06c75",
138
+ display: "flex",
139
+ alignItems: "center"
140
+ },
141
+ onClick: onDelete,
142
+ children: /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
143
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
144
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
145
+ ] })
146
+ }
147
+ )
148
+ ]
149
+ }
150
+ );
151
+ }
152
+
153
+ // src/node-graph-ui/widgets/SolidifyWidget.tsx
154
+ import { jsx as jsx2 } from "react/jsx-runtime";
155
+ function SolidifyWidget({ x, y, onSolidify }) {
156
+ return /* @__PURE__ */ jsx2(
157
+ "div",
158
+ {
159
+ style: {
160
+ position: "absolute",
161
+ left: x,
162
+ top: y,
163
+ transform: "translate(-50%, -50%)",
164
+ zIndex: 7,
165
+ pointerEvents: "auto"
166
+ },
167
+ onClick: (e) => e.stopPropagation(),
168
+ children: /* @__PURE__ */ jsx2(
169
+ "button",
170
+ {
171
+ type: "button",
172
+ title: "Solidify Connection",
173
+ "aria-label": "Solidify Connection",
174
+ style: {
175
+ backgroundColor: "var(--skipo-accent, #61afef)",
176
+ border: "1px solid var(--skipo-border, #61afef)",
177
+ borderRadius: "50%",
178
+ width: "22px",
179
+ height: "22px",
180
+ color: "var(--skipo-text, #ffffff)",
181
+ cursor: "pointer",
182
+ padding: 0,
183
+ display: "flex",
184
+ alignItems: "center",
185
+ justifyContent: "center",
186
+ boxShadow: "0 2px 6px rgba(0, 0, 0, 0.4)",
187
+ transition: "transform 0.1s ease"
188
+ },
189
+ onClick: onSolidify,
190
+ children: /* @__PURE__ */ jsx2("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx2("polyline", { points: "20 6 9 17 4 12" }) })
191
+ }
192
+ )
193
+ }
194
+ );
195
+ }
196
+
197
+ // src/node-graph-ui/widgets/CompatibleNodePicker.tsx
198
+ import { useState, useMemo } from "react";
199
+ import { ConnectionRuleStore } from "@ultrst-armada/kloks/state-graph";
200
+ import { useSearchKeyboardNavigation, BaseButton, BaseInput } from "@ultrst-armada/floks/ui";
201
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
202
+ function CompatibleNodePicker({
203
+ x,
204
+ y,
205
+ sourceHandle,
206
+ availableNodeTypes,
207
+ onSelect,
208
+ onClose
209
+ }) {
210
+ const [selectedTypes, setSelectedTypes] = useState(/* @__PURE__ */ new Set());
211
+ const [searchTerm, setSearchTerm] = useState("");
212
+ const compatibleNodes = useMemo(() => {
213
+ const isOut = sourceHandle.direction === "output";
214
+ return ConnectionRuleStore.getCompatibleNodeTypes(
215
+ { dataType: sourceHandle.dataType || "ANY", direction: isOut ? "OUTPUT" : "INPUT", handleCategory: "DATA" },
216
+ availableNodeTypes
217
+ );
218
+ }, [sourceHandle, availableNodeTypes]);
219
+ const filteredNodes = useMemo(() => {
220
+ if (!searchTerm.trim()) return compatibleNodes;
221
+ const term = searchTerm.toLowerCase();
222
+ return compatibleNodes.filter((n) => n.type.toLowerCase().includes(term) || n.label.toLowerCase().includes(term));
223
+ }, [compatibleNodes, searchTerm]);
224
+ const handleQuickSelect = (type) => onSelect([type]);
225
+ const { highlightedIndex, setHighlightedIndex, handleKeyDown, listContainerRef } = useSearchKeyboardNavigation({
226
+ items: filteredNodes,
227
+ onSelect: (node) => handleQuickSelect(node.type),
228
+ onClose
229
+ });
230
+ const toggleSelect = (type) => {
231
+ setSelectedTypes((prev) => {
232
+ const next = new Set(prev);
233
+ if (next.has(type)) next.delete(type);
234
+ else next.add(type);
235
+ return next;
236
+ });
237
+ };
238
+ return /* @__PURE__ */ jsxs2(
239
+ "div",
240
+ {
241
+ style: {
242
+ position: "absolute",
243
+ left: x,
244
+ top: y,
245
+ transform: "translate(-50%, 0)",
246
+ width: "270px",
247
+ maxHeight: "360px",
248
+ backgroundColor: "var(--skipo-surface)",
249
+ border: "var(--skipo-border)",
250
+ borderRadius: "var(--skipo-radius)",
251
+ boxShadow: "var(--skipo-shadow)",
252
+ color: "var(--skipo-text)",
253
+ zIndex: 50,
254
+ display: "flex",
255
+ flexDirection: "column",
256
+ overflow: "hidden",
257
+ fontFamily: "var(--skipo-font)"
258
+ },
259
+ onClick: (e) => e.stopPropagation(),
260
+ onMouseDown: (e) => e.stopPropagation(),
261
+ children: [
262
+ /* @__PURE__ */ jsxs2("div", { style: { padding: "8px 12px", borderBottom: "var(--skipo-border)", display: "flex", alignItems: "center", justifyContent: "space-between", backgroundColor: "var(--skipo-matte-bg)" }, children: [
263
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column" }, children: [
264
+ /* @__PURE__ */ jsx3("span", { style: { fontSize: "11px", fontWeight: 600, color: "var(--skipo-accent)" }, children: "Compatible Nodes" }),
265
+ /* @__PURE__ */ jsxs2("span", { style: { fontSize: "9px", color: "var(--skipo-text-muted)" }, children: [
266
+ "For ",
267
+ sourceHandle.dataType || "ANY",
268
+ " (",
269
+ sourceHandle.direction,
270
+ ")"
271
+ ] })
272
+ ] }),
273
+ /* @__PURE__ */ jsx3(BaseButton, { variant: "ghost", size: "sm", onClick: onClose, "aria-label": "Close picker", style: { padding: "2px 6px" }, children: "\u2715" })
274
+ ] }),
275
+ /* @__PURE__ */ jsx3("div", { style: { padding: "6px 8px", borderBottom: "var(--skipo-border)" }, children: /* @__PURE__ */ jsx3(BaseInput, { autoFocus: true, placeholder: "Filter nodes... (\u2191\u2193 navigate, \u21B5 spawn)", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), onKeyDown: handleKeyDown }) }),
276
+ /* @__PURE__ */ jsx3("div", { ref: listContainerRef, style: { flex: 1, overflowY: "auto", maxHeight: "180px", padding: "4px" }, children: filteredNodes.length === 0 ? /* @__PURE__ */ jsx3("div", { style: { padding: "16px", textAlign: "center", fontSize: "11px", color: "var(--skipo-text-muted)" }, children: "No compatible nodes found" }) : filteredNodes.map((node, idx) => {
277
+ const isSelected = selectedTypes.has(node.type);
278
+ const isHighlighted = idx === highlightedIndex;
279
+ return /* @__PURE__ */ jsxs2(
280
+ "div",
281
+ {
282
+ onMouseEnter: () => setHighlightedIndex(idx),
283
+ onClick: () => toggleSelect(node.type),
284
+ onDoubleClick: () => handleQuickSelect(node.type),
285
+ style: {
286
+ display: "flex",
287
+ alignItems: "center",
288
+ gap: "8px",
289
+ padding: "6px 8px",
290
+ borderRadius: "var(--skipo-radius-sm)",
291
+ cursor: "pointer",
292
+ backgroundColor: isHighlighted ? "var(--skipo-surface-hover)" : isSelected ? "var(--skipo-matte-bg)" : "transparent",
293
+ border: isHighlighted ? "var(--skipo-border)" : "1px solid transparent",
294
+ marginBottom: "2px",
295
+ transition: "background-color 0.1s ease"
296
+ },
297
+ children: [
298
+ /* @__PURE__ */ jsx3("input", { type: "checkbox", checked: isSelected, onChange: () => toggleSelect(node.type), onClick: (e) => e.stopPropagation(), style: { cursor: "pointer" } }),
299
+ /* @__PURE__ */ jsxs2("div", { style: { flex: 1, minWidth: 0 }, children: [
300
+ /* @__PURE__ */ jsx3("div", { style: { fontSize: "11px", fontWeight: isHighlighted ? 600 : 500, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", color: isHighlighted ? "var(--skipo-accent)" : "inherit" }, children: node.label || node.type }),
301
+ node.description && /* @__PURE__ */ jsx3("div", { style: { fontSize: "9px", color: "var(--skipo-text-muted)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: node.description })
302
+ ] }),
303
+ isHighlighted && /* @__PURE__ */ jsx3("span", { style: { fontSize: "8px", fontWeight: 600, color: "var(--skipo-accent)", padding: "1px 4px", borderRadius: "var(--skipo-radius-sm)", backgroundColor: "var(--skipo-matte-bg)", border: "var(--skipo-border)", whiteSpace: "nowrap" }, children: "\u21B5 Enter" })
304
+ ]
305
+ },
306
+ node.type
307
+ );
308
+ }) }),
309
+ /* @__PURE__ */ jsxs2("div", { style: { padding: "6px 8px", borderTop: "var(--skipo-border)", display: "flex", justifyContent: "space-between", alignItems: "center", backgroundColor: "var(--skipo-matte-bg)" }, children: [
310
+ /* @__PURE__ */ jsx3("span", { style: { fontSize: "10px", color: "var(--skipo-text-muted)" }, children: selectedTypes.size > 0 ? `${selectedTypes.size} selected` : "\u21B5 Spawn top match" }),
311
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "6px" }, children: [
312
+ /* @__PURE__ */ jsx3(BaseButton, { variant: "secondary", size: "sm", onClick: onClose, style: { padding: "2px 8px", fontSize: "10px" }, children: "Cancel" }),
313
+ /* @__PURE__ */ jsx3(
314
+ BaseButton,
315
+ {
316
+ variant: "accent",
317
+ size: "sm",
318
+ disabled: selectedTypes.size === 0 && filteredNodes.length === 0,
319
+ onClick: () => {
320
+ if (selectedTypes.size > 0) onSelect(Array.from(selectedTypes));
321
+ else if (filteredNodes.length > 0) handleQuickSelect(filteredNodes[highlightedIndex >= 0 ? highlightedIndex : 0].type);
322
+ },
323
+ style: { padding: "2px 10px", fontSize: "10px" },
324
+ children: "Spawn & Solidify"
325
+ }
326
+ )
327
+ ] })
328
+ ] })
329
+ ]
330
+ }
331
+ );
332
+ }
333
+
334
+ // src/node-graph-ui/widgets/NodeSearchPalette.tsx
335
+ import { useState as useState2, useMemo as useMemo2 } from "react";
336
+ import { useSearchKeyboardNavigation as useSearchKeyboardNavigation2, BaseButton as BaseButton2, BaseInput as BaseInput2 } from "@ultrst-armada/floks/ui";
337
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
338
+ function NodeSearchPalette({
339
+ x,
340
+ y,
341
+ availableNodeTypes = [],
342
+ onSpawnNode,
343
+ onClose
344
+ }) {
345
+ const [query, setQuery] = useState2("");
346
+ const filteredNodes = useMemo2(() => {
347
+ if (!availableNodeTypes || availableNodeTypes.length === 0) {
348
+ return [{ type: "default", label: "Default Node", description: "Standard dual-port node" }];
349
+ }
350
+ if (!query.trim()) return availableNodeTypes;
351
+ const q = query.toLowerCase();
352
+ return availableNodeTypes.filter(
353
+ (n) => n.type.toLowerCase().includes(q) || n.label.toLowerCase().includes(q) || n.description?.toLowerCase().includes(q)
354
+ );
355
+ }, [availableNodeTypes, query]);
356
+ const {
357
+ highlightedIndex,
358
+ setHighlightedIndex,
359
+ handleKeyDown,
360
+ listContainerRef
361
+ } = useSearchKeyboardNavigation2({
362
+ items: filteredNodes,
363
+ onSelect: (node) => {
364
+ onSpawnNode(node.type);
365
+ onClose();
366
+ },
367
+ onClose
368
+ });
369
+ return /* @__PURE__ */ jsxs3(
370
+ "div",
371
+ {
372
+ style: {
373
+ position: "absolute",
374
+ left: x,
375
+ top: y,
376
+ transform: "translate(-50%, 0)",
377
+ width: "290px",
378
+ maxHeight: "380px",
379
+ backgroundColor: "var(--skipo-surface)",
380
+ border: "var(--skipo-border)",
381
+ borderRadius: "var(--skipo-radius)",
382
+ boxShadow: "var(--skipo-shadow)",
383
+ color: "var(--skipo-text)",
384
+ zIndex: 70,
385
+ display: "flex",
386
+ flexDirection: "column",
387
+ overflow: "hidden",
388
+ fontFamily: "var(--skipo-font)"
389
+ },
390
+ onClick: (e) => e.stopPropagation(),
391
+ onMouseDown: (e) => e.stopPropagation(),
392
+ children: [
393
+ /* @__PURE__ */ jsxs3("div", { style: {
394
+ padding: "10px 12px",
395
+ borderBottom: "var(--skipo-border)",
396
+ display: "flex",
397
+ alignItems: "center",
398
+ justifyContent: "space-between",
399
+ backgroundColor: "var(--skipo-matte-bg)"
400
+ }, children: [
401
+ /* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "center", gap: "6px" }, children: [
402
+ /* @__PURE__ */ jsx4("span", { style: { fontSize: "11px", fontWeight: 600, color: "var(--skipo-accent)" }, children: "Spawn Node" }),
403
+ /* @__PURE__ */ jsx4("span", { style: { fontSize: "9px", color: "var(--skipo-text-muted)", fontFamily: "var(--skipo-font-mono)", backgroundColor: "var(--skipo-surface)", padding: "1px 4px", borderRadius: "var(--skipo-radius-sm)" }, children: "hotkey [N]" })
404
+ ] }),
405
+ /* @__PURE__ */ jsx4(
406
+ BaseButton2,
407
+ {
408
+ variant: "ghost",
409
+ size: "sm",
410
+ onClick: onClose,
411
+ "aria-label": "Close search",
412
+ style: { padding: "2px 6px", fontSize: "12px" },
413
+ children: "\u2715"
414
+ }
415
+ )
416
+ ] }),
417
+ /* @__PURE__ */ jsx4("div", { style: { padding: "8px", borderBottom: "var(--skipo-border)" }, children: /* @__PURE__ */ jsx4(
418
+ BaseInput2,
419
+ {
420
+ autoFocus: true,
421
+ placeholder: "Search nodes... (\u2191\u2193 navigate, \u21B5 spawn)",
422
+ value: query,
423
+ onChange: (e) => setQuery(e.target.value),
424
+ onKeyDown: handleKeyDown
425
+ }
426
+ ) }),
427
+ /* @__PURE__ */ jsx4("div", { ref: listContainerRef, style: { flex: 1, overflowY: "auto", maxHeight: "220px", padding: "4px 6px" }, children: filteredNodes.length === 0 ? /* @__PURE__ */ jsx4("div", { style: { padding: "20px", textAlign: "center", fontSize: "11px", color: "var(--skipo-text-muted)" }, children: "No matching nodes" }) : filteredNodes.map((node, idx) => {
428
+ const isHighlighted = idx === highlightedIndex;
429
+ return /* @__PURE__ */ jsxs3(
430
+ "div",
431
+ {
432
+ onMouseEnter: () => setHighlightedIndex(idx),
433
+ onClick: () => {
434
+ onSpawnNode(node.type);
435
+ onClose();
436
+ },
437
+ style: {
438
+ display: "flex",
439
+ alignItems: "center",
440
+ justifyContent: "space-between",
441
+ padding: "7px 10px",
442
+ borderRadius: "var(--skipo-radius-sm)",
443
+ cursor: "pointer",
444
+ backgroundColor: isHighlighted ? "var(--skipo-surface-hover)" : "transparent",
445
+ border: isHighlighted ? "var(--skipo-border)" : "1px solid transparent",
446
+ marginBottom: "2px",
447
+ transition: "background-color 0.1s ease"
448
+ },
449
+ children: [
450
+ /* @__PURE__ */ jsxs3("div", { style: { minWidth: 0, flex: 1 }, children: [
451
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: "11px", fontWeight: isHighlighted ? 600 : 500, color: isHighlighted ? "var(--skipo-accent)" : "inherit" }, children: node.label || node.type }),
452
+ node.description && /* @__PURE__ */ jsx4("div", { style: { fontSize: "9px", color: "var(--skipo-text-muted)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: node.description })
453
+ ] }),
454
+ isHighlighted && /* @__PURE__ */ jsx4("span", { style: { fontSize: "9px", fontWeight: 600, color: "var(--skipo-accent)", padding: "2px 5px", borderRadius: "var(--skipo-radius-sm)", backgroundColor: "var(--skipo-matte-bg)", border: "var(--skipo-border)", whiteSpace: "nowrap", marginLeft: "6px" }, children: "\u21B5 Spawn" })
455
+ ]
456
+ },
457
+ node.type
458
+ );
459
+ }) }),
460
+ /* @__PURE__ */ jsxs3("div", { style: {
461
+ padding: "6px 10px",
462
+ borderTop: "var(--skipo-border)",
463
+ display: "flex",
464
+ justifyContent: "space-between",
465
+ alignItems: "center",
466
+ backgroundColor: "var(--skipo-matte-bg)",
467
+ fontSize: "9px",
468
+ color: "var(--skipo-text-muted)"
469
+ }, children: [
470
+ /* @__PURE__ */ jsxs3("span", { children: [
471
+ filteredNodes.length,
472
+ " nodes available"
473
+ ] }),
474
+ /* @__PURE__ */ jsxs3("span", { children: [
475
+ "Press ",
476
+ /* @__PURE__ */ jsx4("strong", { children: "Enter \u21B5" }),
477
+ " to spawn"
478
+ ] })
479
+ ] })
480
+ ]
481
+ }
482
+ );
483
+ }
484
+
485
+ // src/node-graph-ui/widgets/CanvasContextMenu.tsx
486
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
487
+ function CanvasContextMenu({
488
+ x,
489
+ y,
490
+ availableNodeTypes,
491
+ hasSelection,
492
+ onSpawnNode,
493
+ onOpenSpawnMenu,
494
+ onSelectAll,
495
+ onDeleteSelected,
496
+ onClearSelection,
497
+ onClose
498
+ }) {
499
+ const itemStyle = {
500
+ padding: "6px 12px",
501
+ fontSize: "11px",
502
+ cursor: "pointer",
503
+ display: "flex",
504
+ alignItems: "center",
505
+ justifyContent: "space-between",
506
+ gap: "12px",
507
+ color: "var(--skipo-text, #fff)",
508
+ borderRadius: "4px",
509
+ userSelect: "none"
510
+ };
511
+ const shortcutStyle = {
512
+ fontSize: "9px",
513
+ color: "var(--skipo-text-muted, #888)",
514
+ fontFamily: "monospace"
515
+ };
516
+ return /* @__PURE__ */ jsxs4(
517
+ "div",
518
+ {
519
+ style: {
520
+ position: "absolute",
521
+ left: x,
522
+ top: y,
523
+ minWidth: "180px",
524
+ backgroundColor: "var(--skipo-surface, #1e1e1e)",
525
+ border: "1px solid var(--skipo-border, #333)",
526
+ borderRadius: "6px",
527
+ boxShadow: "0 6px 20px rgba(0, 0, 0, 0.6)",
528
+ padding: "4px",
529
+ zIndex: 60,
530
+ fontFamily: "Inter, system-ui, sans-serif"
531
+ },
532
+ onClick: (e) => e.stopPropagation(),
533
+ onMouseDown: (e) => e.stopPropagation(),
534
+ children: [
535
+ onOpenSpawnMenu && /* @__PURE__ */ jsxs4(
536
+ "div",
537
+ {
538
+ style: {
539
+ ...itemStyle,
540
+ fontWeight: 600,
541
+ color: "var(--skipo-accent, #61afef)",
542
+ backgroundColor: "rgba(97, 175, 239, 0.08)"
543
+ },
544
+ onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "rgba(97, 175, 239, 0.16)",
545
+ onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "rgba(97, 175, 239, 0.08)",
546
+ onClick: () => {
547
+ onOpenSpawnMenu();
548
+ onClose();
549
+ },
550
+ children: [
551
+ /* @__PURE__ */ jsx5("span", { children: "Spawn Node Menu..." }),
552
+ /* @__PURE__ */ jsx5("span", { style: shortcutStyle, children: "N" })
553
+ ]
554
+ }
555
+ ),
556
+ /* @__PURE__ */ jsx5("div", { style: { padding: "4px 8px", fontSize: "9px", textTransform: "uppercase", color: "var(--skipo-text-muted, #888)", fontWeight: 600 }, children: "Quick Spawn" }),
557
+ /* @__PURE__ */ jsx5("div", { style: { maxHeight: "140px", overflowY: "auto" }, children: !availableNodeTypes || availableNodeTypes.length === 0 ? /* @__PURE__ */ jsx5(
558
+ "div",
559
+ {
560
+ style: itemStyle,
561
+ onClick: () => {
562
+ onSpawnNode("default");
563
+ onClose();
564
+ },
565
+ children: /* @__PURE__ */ jsx5("span", { children: "Default Node" })
566
+ }
567
+ ) : availableNodeTypes.map((def) => /* @__PURE__ */ jsx5(
568
+ "div",
569
+ {
570
+ style: itemStyle,
571
+ onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.08)",
572
+ onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent",
573
+ onClick: () => {
574
+ onSpawnNode(def.type);
575
+ onClose();
576
+ },
577
+ children: /* @__PURE__ */ jsx5("span", { children: def.label || def.type })
578
+ },
579
+ def.type
580
+ )) }),
581
+ /* @__PURE__ */ jsx5("div", { style: { height: "1px", backgroundColor: "var(--skipo-border, #333)", margin: "4px 0" } }),
582
+ /* @__PURE__ */ jsxs4(
583
+ "div",
584
+ {
585
+ style: itemStyle,
586
+ onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.08)",
587
+ onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent",
588
+ onClick: () => {
589
+ onSelectAll();
590
+ onClose();
591
+ },
592
+ children: [
593
+ /* @__PURE__ */ jsx5("span", { children: "Select All" }),
594
+ /* @__PURE__ */ jsx5("span", { style: shortcutStyle, children: "\u2318A" })
595
+ ]
596
+ }
597
+ ),
598
+ hasSelection && /* @__PURE__ */ jsxs4(Fragment2, { children: [
599
+ /* @__PURE__ */ jsxs4(
600
+ "div",
601
+ {
602
+ style: { ...itemStyle, color: "#e06c75" },
603
+ onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "rgba(224, 108, 117, 0.15)",
604
+ onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent",
605
+ onClick: () => {
606
+ onDeleteSelected();
607
+ onClose();
608
+ },
609
+ children: [
610
+ /* @__PURE__ */ jsx5("span", { children: "Delete Selected" }),
611
+ /* @__PURE__ */ jsx5("span", { style: shortcutStyle, children: "Del" })
612
+ ]
613
+ }
614
+ ),
615
+ /* @__PURE__ */ jsx5(
616
+ "div",
617
+ {
618
+ style: itemStyle,
619
+ onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.08)",
620
+ onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "transparent",
621
+ onClick: () => {
622
+ onClearSelection();
623
+ onClose();
624
+ },
625
+ children: /* @__PURE__ */ jsx5("span", { children: "Clear Selection" })
626
+ }
627
+ )
628
+ ] })
629
+ ]
630
+ }
631
+ );
632
+ }
633
+
634
+ // src/node-graph-ui/toolbar/GraphToolbar.tsx
635
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
636
+ function GraphToolbar({
637
+ settings,
638
+ onUpdateSettings,
639
+ onRefreshTraces,
640
+ onLockAllConnections,
641
+ onSaveView,
642
+ onLoadView,
643
+ className = ""
644
+ }) {
645
+ const btnStyle = (active) => ({
646
+ background: active ? "var(--skipo-accent, #d4af37)" : "transparent",
647
+ color: active ? "#000000" : "var(--skipo-text, #ffffff)",
648
+ border: "1px solid var(--skipo-border, #444)",
649
+ borderRadius: "4px",
650
+ padding: "4px 8px",
651
+ fontSize: "11px",
652
+ cursor: "pointer",
653
+ display: "flex",
654
+ alignItems: "center",
655
+ gap: "4px"
656
+ });
657
+ return /* @__PURE__ */ jsxs5(
658
+ "div",
659
+ {
660
+ className,
661
+ style: {
662
+ display: "flex",
663
+ alignItems: "center",
664
+ gap: "6px",
665
+ padding: "6px 12px",
666
+ backgroundColor: "var(--skipo-surface, #1e1e1e)",
667
+ border: "1px solid var(--skipo-border, #333)",
668
+ borderRadius: "6px",
669
+ boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
670
+ zIndex: 25
671
+ },
672
+ children: [
673
+ /* @__PURE__ */ jsxs5(
674
+ "button",
675
+ {
676
+ type: "button",
677
+ style: btnStyle(settings.tracingEnabled),
678
+ onClick: () => onUpdateSettings({ tracingEnabled: !settings.tracingEnabled }),
679
+ children: [
680
+ "Tracing: ",
681
+ settings.tracingEnabled ? "ON" : "OFF"
682
+ ]
683
+ }
684
+ ),
685
+ /* @__PURE__ */ jsxs5(
686
+ "button",
687
+ {
688
+ type: "button",
689
+ style: btnStyle(settings.autoSolidify),
690
+ onClick: () => onUpdateSettings({ autoSolidify: !settings.autoSolidify }),
691
+ children: [
692
+ "Solidify: ",
693
+ settings.autoSolidify ? "AUTO" : "MANUAL"
694
+ ]
695
+ }
696
+ ),
697
+ /* @__PURE__ */ jsx6(
698
+ "button",
699
+ {
700
+ type: "button",
701
+ style: btnStyle(false),
702
+ onClick: onRefreshTraces,
703
+ children: "Refresh Traces"
704
+ }
705
+ ),
706
+ /* @__PURE__ */ jsxs5(
707
+ "button",
708
+ {
709
+ type: "button",
710
+ style: btnStyle(settings.attractionEnabled),
711
+ onClick: () => onUpdateSettings({ attractionEnabled: !settings.attractionEnabled }),
712
+ children: [
713
+ "Attraction: ",
714
+ settings.attractionEnabled ? "ON" : "OFF"
715
+ ]
716
+ }
717
+ ),
718
+ /* @__PURE__ */ jsx6(
719
+ "button",
720
+ {
721
+ type: "button",
722
+ style: btnStyle(false),
723
+ onClick: onLockAllConnections,
724
+ children: "Lock All"
725
+ }
726
+ ),
727
+ onSaveView && /* @__PURE__ */ jsx6("button", { type: "button", style: btnStyle(false), onClick: onSaveView, children: "Save View" }),
728
+ onLoadView && /* @__PURE__ */ jsx6("button", { type: "button", style: btnStyle(false), onClick: onLoadView, children: "Load View" })
729
+ ]
730
+ }
731
+ );
732
+ }
733
+
734
+ // src/node-graph-ui/react-flow/ReactFlowAdapter.ts
735
+ var ReactFlowAdapter = class {
736
+ static toReactFlowNodes(nodes) {
737
+ return nodes.map((node) => ({
738
+ id: node.id,
739
+ type: "magneticNode",
740
+ position: { x: node.position.x, y: node.position.y },
741
+ data: {
742
+ nodeId: node.id,
743
+ label: node.label,
744
+ type: node.type,
745
+ handles: node.handles.map((h) => ({
746
+ id: h.id,
747
+ direction: h.direction,
748
+ category: h.handleCategory,
749
+ dataType: h.dataType,
750
+ offset: { ...h.offset }
751
+ })),
752
+ positionLocked: node.positionLocked,
753
+ customData: node.state
754
+ }
755
+ }));
756
+ }
757
+ static toReactFlowEdges(connections, traces = [], viewLinks = []) {
758
+ const edges = [];
759
+ for (const conn of connections) {
760
+ edges.push({
761
+ id: conn.id,
762
+ source: conn.sourceNodeId,
763
+ sourceHandle: conn.sourceHandleId,
764
+ target: conn.targetNodeId,
765
+ targetHandle: conn.targetHandleId,
766
+ type: "magneticSolidEdge",
767
+ data: {
768
+ connectionId: conn.id,
769
+ sourceNodeId: conn.sourceNodeId,
770
+ sourceHandleId: conn.sourceHandleId,
771
+ targetNodeId: conn.targetNodeId,
772
+ targetHandleId: conn.targetHandleId,
773
+ wireType: conn.wireType,
774
+ locked: conn.locked,
775
+ isTrace: false
776
+ }
777
+ });
778
+ }
779
+ for (const trace of traces) {
780
+ edges.push({
781
+ id: trace.id,
782
+ source: trace.sourceNodeId,
783
+ sourceHandle: trace.sourceHandleId,
784
+ target: trace.targetNodeId,
785
+ targetHandle: trace.targetHandleId,
786
+ type: "magneticTraceEdge",
787
+ animated: true,
788
+ data: {
789
+ connectionId: trace.id,
790
+ sourceNodeId: trace.sourceNodeId,
791
+ sourceHandleId: trace.sourceHandleId,
792
+ targetNodeId: trace.targetNodeId,
793
+ targetHandleId: trace.targetHandleId,
794
+ wireType: trace.wireType,
795
+ locked: false,
796
+ isTrace: true
797
+ }
798
+ });
799
+ }
800
+ for (const link of viewLinks) {
801
+ edges.push({
802
+ id: link.id,
803
+ source: link.sourceNodeId,
804
+ sourceHandle: link.sourceViewHandleId,
805
+ target: link.targetViewWindowId,
806
+ targetHandle: "window-in",
807
+ type: "viewLinkEdge",
808
+ data: {
809
+ connectionId: link.id,
810
+ sourceNodeId: link.sourceNodeId,
811
+ sourceHandleId: link.sourceViewHandleId,
812
+ targetNodeId: link.targetViewWindowId,
813
+ targetHandleId: "window-in",
814
+ wireType: "VIEW",
815
+ locked: true,
816
+ isViewLink: true
817
+ }
818
+ });
819
+ }
820
+ return edges;
821
+ }
822
+ static toReactFlowViewWindows(windows) {
823
+ return windows.map((w) => ({
824
+ id: w.id,
825
+ type: "viewWindowWidget",
826
+ position: { x: w.position.x, y: w.position.y },
827
+ data: {
828
+ windowId: w.id,
829
+ viewType: w.viewType,
830
+ sourceNodeId: w.sourceNodeId,
831
+ dynamicState: w.dynamicState,
832
+ pinnedLive: w.pinnedLive,
833
+ size: { ...w.size }
834
+ }
835
+ }));
836
+ }
837
+ };
838
+
839
+ // src/Viewer2DNodes.tsx
840
+ import { useState as useState3, useRef } from "react";
841
+ import { getBeamPoints, calculateSocketCoordinates } from "@ultrst-armada/kloks/state-graph";
842
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
843
+ function Viewer2DNodes({
844
+ node,
845
+ selected,
846
+ onMouseDown,
847
+ onDoubleClick,
848
+ onSocketMouseDown,
849
+ onSocketNudgeChange
850
+ }) {
851
+ const cardWidth = node.width ?? 180;
852
+ const headerHeight = 36;
853
+ const socketSpacing = 36;
854
+ const centerX = cardWidth / 2;
855
+ return /* @__PURE__ */ jsxs6(
856
+ "div",
857
+ {
858
+ style: {
859
+ position: "absolute",
860
+ left: node.position.x,
861
+ top: node.position.y,
862
+ width: cardWidth,
863
+ backgroundColor: "rgba(20, 24, 30, 0.9)",
864
+ backdropFilter: "blur(12px)",
865
+ border: `2px solid ${selected ? "#d4af37" : "rgba(255, 255, 255, 0.12)"}`,
866
+ borderRadius: "10px",
867
+ color: "#f5ede4",
868
+ fontFamily: "Inter, system-ui, sans-serif",
869
+ userSelect: "none",
870
+ boxShadow: selected ? "0 0 20px rgba(212, 175, 55, 0.45)" : "0 8px 16px rgba(0, 0, 0, 0.4)",
871
+ zIndex: selected ? 25 : 15
872
+ },
873
+ onMouseDown: (e) => onMouseDown?.(e, node.id),
874
+ onDoubleClick: () => onDoubleClick?.(node.id),
875
+ children: [
876
+ /* @__PURE__ */ jsxs6(
877
+ "div",
878
+ {
879
+ style: {
880
+ height: `${headerHeight}px`,
881
+ padding: "0 12px",
882
+ display: "flex",
883
+ justifyContent: "space-between",
884
+ alignItems: "center",
885
+ borderBottom: "1px solid rgba(255, 255, 255, 0.08)",
886
+ backgroundColor: "rgba(0, 0, 0, 0.25)",
887
+ borderTopLeftRadius: "8px",
888
+ borderTopRightRadius: "8px"
889
+ },
890
+ children: [
891
+ /* @__PURE__ */ jsx7("span", { style: { fontSize: "12px", fontWeight: 600, letterSpacing: "0.02em" }, children: node.label }),
892
+ /* @__PURE__ */ jsx7(
893
+ "span",
894
+ {
895
+ style: {
896
+ fontSize: "9px",
897
+ textTransform: "uppercase",
898
+ letterSpacing: "0.05em",
899
+ padding: "2px 6px",
900
+ borderRadius: "4px",
901
+ backgroundColor: "rgba(255, 255, 255, 0.08)",
902
+ color: "#a0aec0"
903
+ },
904
+ children: node.type
905
+ }
906
+ )
907
+ ]
908
+ }
909
+ ),
910
+ /* @__PURE__ */ jsx7("div", { style: { position: "relative", minHeight: "60px", padding: "12px 16px" }, children: node.data && /* @__PURE__ */ jsxs6("div", { style: { fontSize: "11px", color: "#94a3b8" }, children: [
911
+ Object.keys(node.data).length,
912
+ " properties"
913
+ ] }) }),
914
+ /* @__PURE__ */ jsxs6("div", { style: { position: "absolute", top: headerHeight + 10, left: centerX, width: 0, height: 0 }, children: [
915
+ node.inputs?.map((socket, idx) => /* @__PURE__ */ jsx7(
916
+ MovableSocketHandle,
917
+ {
918
+ socket,
919
+ nodeId: node.id,
920
+ cardWidth,
921
+ isOutput: false,
922
+ baseY: idx * socketSpacing,
923
+ onSocketMouseDown,
924
+ onSocketNudgeChange
925
+ },
926
+ socket.id
927
+ )),
928
+ node.outputs?.map((socket, idx) => /* @__PURE__ */ jsx7(
929
+ MovableSocketHandle,
930
+ {
931
+ socket,
932
+ nodeId: node.id,
933
+ cardWidth,
934
+ isOutput: true,
935
+ baseY: idx * socketSpacing,
936
+ onSocketMouseDown,
937
+ onSocketNudgeChange
938
+ },
939
+ socket.id
940
+ ))
941
+ ] })
942
+ ]
943
+ }
944
+ );
945
+ }
946
+ function MovableSocketHandle({
947
+ socket,
948
+ nodeId,
949
+ cardWidth,
950
+ isOutput,
951
+ baseY,
952
+ onSocketMouseDown,
953
+ onSocketNudgeChange
954
+ }) {
955
+ const [isHovered, setIsHovered] = useState3(false);
956
+ const [localNudge, setLocalNudge] = useState3(
957
+ socket.offset ?? { x: 0, y: 0 }
958
+ );
959
+ const isDraggingGizmoRef = useRef(false);
960
+ const dragStartPosRef = useRef({
961
+ clientX: 0,
962
+ clientY: 0,
963
+ origX: 0,
964
+ origY: 0
965
+ });
966
+ const nudge = socket.offset ?? localNudge;
967
+ const isDisplaced = nudge.x !== 0 || nudge.y !== 0;
968
+ const coords = calculateSocketCoordinates(baseY, {
969
+ cardWidth,
970
+ isOutput,
971
+ clearance: 12,
972
+ nudge
973
+ });
974
+ const handleGizmoMouseDown = (e) => {
975
+ e.stopPropagation();
976
+ e.preventDefault();
977
+ isDraggingGizmoRef.current = true;
978
+ dragStartPosRef.current = {
979
+ clientX: e.clientX,
980
+ clientY: e.clientY,
981
+ origX: nudge.x,
982
+ origY: nudge.y
983
+ };
984
+ const handleWindowMouseMove = (moveEvt) => {
985
+ if (!isDraggingGizmoRef.current) return;
986
+ const dx = moveEvt.clientX - dragStartPosRef.current.clientX;
987
+ const dy = moveEvt.clientY - dragStartPosRef.current.clientY;
988
+ const updated = {
989
+ x: Math.round(dragStartPosRef.current.origX + dx),
990
+ y: Math.round(dragStartPosRef.current.origY + dy)
991
+ };
992
+ setLocalNudge(updated);
993
+ onSocketNudgeChange?.(nodeId, socket.id, updated);
994
+ };
995
+ const handleWindowMouseUp = () => {
996
+ isDraggingGizmoRef.current = false;
997
+ window.removeEventListener("mousemove", handleWindowMouseMove);
998
+ window.removeEventListener("mouseup", handleWindowMouseUp);
999
+ };
1000
+ window.addEventListener("mousemove", handleWindowMouseMove);
1001
+ window.addEventListener("mouseup", handleWindowMouseUp);
1002
+ };
1003
+ const beamCorePoints = getBeamPoints(nudge, 5, 1.2);
1004
+ const beamShroudPoints = getBeamPoints(nudge, 8, 2.5);
1005
+ const socketThemeColor = isOutput ? "#61afef" : "#98c379";
1006
+ const gizmoOffsetX = isOutput ? 18 : -18;
1007
+ return /* @__PURE__ */ jsxs6(
1008
+ "div",
1009
+ {
1010
+ style: {
1011
+ position: "absolute",
1012
+ left: 0,
1013
+ top: 0
1014
+ },
1015
+ onMouseEnter: () => setIsHovered(true),
1016
+ onMouseLeave: () => setIsHovered(false),
1017
+ children: [
1018
+ isDisplaced && /* @__PURE__ */ jsxs6(
1019
+ "svg",
1020
+ {
1021
+ style: {
1022
+ position: "absolute",
1023
+ left: coords.effectiveX,
1024
+ top: coords.effectiveY,
1025
+ overflow: "visible",
1026
+ pointerEvents: "none",
1027
+ zIndex: 1
1028
+ },
1029
+ children: [
1030
+ /* @__PURE__ */ jsx7(
1031
+ "polygon",
1032
+ {
1033
+ points: beamShroudPoints,
1034
+ fill: socketThemeColor,
1035
+ opacity: 0.35
1036
+ }
1037
+ ),
1038
+ /* @__PURE__ */ jsx7(
1039
+ "polygon",
1040
+ {
1041
+ points: beamCorePoints,
1042
+ fill: "#ffffff",
1043
+ opacity: 0.9
1044
+ }
1045
+ )
1046
+ ]
1047
+ }
1048
+ ),
1049
+ /* @__PURE__ */ jsx7(
1050
+ "div",
1051
+ {
1052
+ style: {
1053
+ position: "absolute",
1054
+ left: coords.effectiveX - 14,
1055
+ top: coords.effectiveY - 14,
1056
+ width: "28px",
1057
+ height: "28px",
1058
+ borderRadius: "50%",
1059
+ backgroundColor: "#181a1f",
1060
+ border: `2px solid ${socketThemeColor}`,
1061
+ boxShadow: isHovered ? `0 0 12px ${socketThemeColor}, inset 0 0 6px ${socketThemeColor}` : "0 2px 6px rgba(0,0,0,0.6)",
1062
+ display: "flex",
1063
+ alignItems: "center",
1064
+ justifyContent: "center",
1065
+ cursor: "crosshair",
1066
+ zIndex: 4
1067
+ },
1068
+ onMouseDown: (e) => {
1069
+ e.stopPropagation();
1070
+ onSocketMouseDown?.(e, nodeId, socket.id, isOutput ? "output" : "input");
1071
+ },
1072
+ children: /* @__PURE__ */ jsx7(
1073
+ "div",
1074
+ {
1075
+ style: {
1076
+ width: "10px",
1077
+ height: "10px",
1078
+ borderRadius: "50%",
1079
+ backgroundColor: socketThemeColor,
1080
+ boxShadow: `0 0 4px ${socketThemeColor}`
1081
+ }
1082
+ }
1083
+ )
1084
+ }
1085
+ ),
1086
+ (isHovered || isDraggingGizmoRef.current) && /* @__PURE__ */ jsx7(
1087
+ "div",
1088
+ {
1089
+ title: "Drag to displace socket handle",
1090
+ style: {
1091
+ position: "absolute",
1092
+ left: coords.effectiveX + gizmoOffsetX - 8,
1093
+ top: coords.effectiveY - 8,
1094
+ width: "16px",
1095
+ height: "16px",
1096
+ borderRadius: "4px",
1097
+ backgroundColor: "rgba(30, 34, 42, 0.95)",
1098
+ border: "1px solid rgba(255, 255, 255, 0.3)",
1099
+ display: "flex",
1100
+ alignItems: "center",
1101
+ justifyContent: "center",
1102
+ cursor: "grab",
1103
+ zIndex: 6,
1104
+ boxShadow: "0 2px 4px rgba(0,0,0,0.5)"
1105
+ },
1106
+ onMouseDown: handleGizmoMouseDown,
1107
+ children: /* @__PURE__ */ jsxs6("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "#d4af37", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
1108
+ /* @__PURE__ */ jsx7("polyline", { points: "5 9 2 12 5 15" }),
1109
+ /* @__PURE__ */ jsx7("polyline", { points: "9 5 12 2 15 5" }),
1110
+ /* @__PURE__ */ jsx7("polyline", { points: "15 19 12 22 9 19" }),
1111
+ /* @__PURE__ */ jsx7("polyline", { points: "19 9 22 12 19 15" }),
1112
+ /* @__PURE__ */ jsx7("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
1113
+ /* @__PURE__ */ jsx7("line", { x1: "12", y1: "2", x2: "12", y2: "22" })
1114
+ ] })
1115
+ }
1116
+ )
1117
+ ]
1118
+ }
1119
+ );
1120
+ }
1121
+ export {
1122
+ BIOME_CONFIGS,
1123
+ COORD_SCALE,
1124
+ CanvasBackground2D,
1125
+ CanvasContextMenu,
1126
+ CanvasErrorBoundary,
1127
+ CanvasViewport,
1128
+ CompatibleNodePicker,
1129
+ ContainerNode2D,
1130
+ DockBar,
1131
+ DockItem,
1132
+ EffectNode2D,
1133
+ GraphToolbar,
1134
+ InfiniteCanvas,
1135
+ MagneticTraces2D,
1136
+ MidpointWidgets,
1137
+ MiniMap,
1138
+ ModuleNode2D,
1139
+ MonacoEditor,
1140
+ MovableSocketHandle,
1141
+ NODE_CARD_WIDTH,
1142
+ Node2DBase,
1143
+ NodeRenderer2D,
1144
+ NodeSearchPalette,
1145
+ PredictiveGhostNodeCard,
1146
+ PredictiveHudToolbar,
1147
+ PredictiveLayer2D,
1148
+ ReactFlowAdapter,
1149
+ RecorderWaveformDisplay,
1150
+ RotaryKnob,
1151
+ SOCKET_ROW_HEIGHT,
1152
+ Socket2D,
1153
+ SolidifyWidget,
1154
+ Tile,
1155
+ TileCreateButton,
1156
+ TileGrid,
1157
+ TriggerNode2D,
1158
+ Viewer2DNodes,
1159
+ Wire2D,
1160
+ getSocketLocalOffset,
1161
+ getSocketScreenPosition,
1162
+ renderSpriteIcon,
1163
+ skipoDarkTheme,
1164
+ useCanvas,
1165
+ useCanvas2DCoordinates,
1166
+ useCanvas2DMagnetic,
1167
+ useDock,
1168
+ useMonaco,
1169
+ usePredictiveGraph2D,
1170
+ useTileMenu
1171
+ };