@field/cascade 0.10.0 → 0.12.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 (229) hide show
  1. package/AGENTS.md +25 -5
  2. package/ARCHITECTURE.md +5 -4
  3. package/CHANGELOG.md +382 -0
  4. package/README.md +1 -2
  5. package/dist/assets/AgentPanel-1JugFjE4.css +1 -0
  6. package/dist/assets/AgentPanel-BDL5MddA.js +5 -0
  7. package/dist/assets/{CodeEditor-DSZBpzdy.js → CodeEditor-C-xYG-Wn.js} +120 -120
  8. package/dist/assets/CodePanel-CtXd50m6.js +2 -0
  9. package/dist/assets/CookInfoPanel-B3NMhKJF.css +1 -0
  10. package/dist/assets/CookInfoPanel-DG4_TRsX.js +2 -0
  11. package/dist/assets/CustomNodeDialog-CHfZUs-r.js +1 -0
  12. package/dist/assets/DefinitionNode-CaRTXQ_b.js +1 -0
  13. package/dist/assets/DefinitionPanel-C3CxZY9r.js +1 -0
  14. package/dist/assets/DefinitionPanel-VNLnAiQD.css +1 -0
  15. package/dist/assets/OpenGraphDialog-BLdr6k_q.js +1 -0
  16. package/dist/assets/ProjectSettings-ZnvmIAir.js +2 -0
  17. package/dist/assets/{SettingsDialog-p25h3tj0.js → SettingsDialog-CBX3Wa87.js} +1 -1
  18. package/dist/assets/TimelinePanel-CDeR0arY.css +1 -0
  19. package/dist/assets/TimelinePanel-CWgnFH1e.js +1 -0
  20. package/dist/assets/{VersionHistoryDialog-DzFLUotB.js → VersionHistoryDialog-BOSoW1R-.js} +1 -1
  21. package/dist/assets/assert-BO2_erPD.js +1 -0
  22. package/dist/assets/assert-hvykGCnP.js +1 -0
  23. package/dist/assets/builder-BmBKcDix.js +1 -0
  24. package/dist/assets/camera-DFF7YA3F.js +1 -0
  25. package/dist/assets/checks-DAvyO9Gf.js +1 -0
  26. package/dist/assets/contactSheet-N1NcaWxw.js +2 -0
  27. package/dist/assets/{core-BICrEt0y.js → core-DB-MkGjj.js} +3 -4
  28. package/dist/assets/coreTypes-DtnDATZ7.js +1 -0
  29. package/dist/assets/{cssMode-D7TXw57I.js → cssMode-DPVckSOc.js} +1 -1
  30. package/dist/assets/definitions-B227e7f_.js +1 -0
  31. package/dist/assets/definitions-D0WOUJd7.js +1 -0
  32. package/dist/assets/{editor.api-DvkCO3ko.js → editor.api-Dkutg_Z1.js} +1 -1
  33. package/dist/assets/expressions-X-Z-GrgW.js +5 -0
  34. package/dist/assets/file-DAL6IfjV.js +1 -0
  35. package/dist/assets/filters-D3k1LRMa.js +1 -0
  36. package/dist/assets/{freemarker2-BA2lxsF1.js → freemarker2-CLiLKk3B.js} +1 -1
  37. package/dist/assets/generators-BhDxRAFC.js +1 -0
  38. package/dist/assets/geo-BsMImJIJ.js +1 -0
  39. package/dist/assets/geo-C4YngDob.js +2 -0
  40. package/dist/assets/{handlebars-BcDiyPd8.js → handlebars-CcD3aMeL.js} +1 -1
  41. package/dist/assets/{html-C7O4TyhX.js → html-DvZWGfqb.js} +1 -1
  42. package/dist/assets/{htmlMode-WaDGF3Mj.js → htmlMode-DUD3VaoN.js} +1 -1
  43. package/dist/assets/image-0SfH-snh.js +1 -0
  44. package/dist/assets/image-Ck-RdGU4.js +2 -0
  45. package/dist/assets/index-BWnrmIB9.js +137 -0
  46. package/dist/assets/index-DIaxEONI.css +1 -0
  47. package/dist/assets/io-BGmt2g0D.js +1 -0
  48. package/dist/assets/{javascript-CpIEK7tz.js → javascript-Cap2ahgh.js} +1 -1
  49. package/dist/assets/{jsonMode-B2FltW0f.js → jsonMode-B0uLjp9C.js} +1 -1
  50. package/dist/assets/{liquid-CN6FFHZE.js → liquid-CnxwhfLn.js} +1 -1
  51. package/dist/assets/{lspLanguageFeatures-QhV9XtLp.js → lspLanguageFeatures-Dn9hlKX6.js} +1 -1
  52. package/dist/assets/math-GeULS-sk.js +1 -0
  53. package/dist/assets/{mdx-DE89pafV.js → mdx-BV3jbrVa.js} +1 -1
  54. package/dist/assets/pop-KMF_qloi.js +1 -0
  55. package/dist/assets/preload-helper-Czpn1I53.js +1 -0
  56. package/dist/assets/{python-ByTllTB9.js → python-CGyFk4XK.js} +1 -1
  57. package/dist/assets/{razor-USYlRRCE.js → razor-CQfzX3-N.js} +1 -1
  58. package/dist/assets/remap-5SjXQU-q.js +1 -0
  59. package/dist/assets/renderMarkdown-ork0Oir7.js +67 -0
  60. package/dist/assets/studioImages-CAyH-0Pl.js +1 -0
  61. package/dist/assets/text-ZpX7qNkx.js +2 -0
  62. package/dist/assets/time-P_OiBhcf.js +1 -0
  63. package/dist/assets/{tsMode-BXpN8iUz.js → tsMode-BOeXzO9H.js} +1 -1
  64. package/dist/assets/{typescript-DInBjGQQ.js → typescript-J1SnE_Tu.js} +1 -1
  65. package/dist/assets/{workers-C7Ye5B7D.js → workers-CYwwTiVF.js} +1 -1
  66. package/dist/assets/{xml-U0Uocqyo.js → xml-DnPRNzK9.js} +1 -1
  67. package/dist/assets/{yaml-CBw_PVYf.js → yaml-BmmYBNa9.js} +1 -1
  68. package/dist/cli/DefinitionNode-P7AA4TAU.js +15 -0
  69. package/dist/cli/Graph-OB6EWSGL.js +2975 -0
  70. package/dist/cli/assert-GROGQNCQ.js +25 -0
  71. package/dist/cli/checks-3WB44XBL.js +189 -0
  72. package/dist/cli/chunk-2JEU3MGB.js +1125 -0
  73. package/dist/cli/chunk-2KXB47FP.js +115 -0
  74. package/dist/cli/chunk-3RXL5GHB.js +816 -0
  75. package/dist/cli/chunk-53LGFPWX.js +138 -0
  76. package/dist/cli/chunk-5ORUQ6ES.js +267 -0
  77. package/dist/cli/chunk-73S4JZXK.js +336 -0
  78. package/dist/cli/chunk-7QE2ZNSN.js +121 -0
  79. package/dist/cli/chunk-BP7UKF36.js +376 -0
  80. package/dist/cli/chunk-BPODRH52.js +201 -0
  81. package/dist/cli/chunk-BZ63XQ3I.js +1301 -0
  82. package/dist/cli/chunk-CKS2FQWR.js +89 -0
  83. package/dist/cli/chunk-CO22XHNG.js +593 -0
  84. package/dist/cli/chunk-CTPLRSWF.js +2197 -0
  85. package/dist/cli/chunk-DEQSEFFH.js +153 -0
  86. package/dist/cli/chunk-EU4ZFZ7Y.js +122 -0
  87. package/dist/cli/chunk-EZRWJ4G2.js +104 -0
  88. package/dist/cli/chunk-FWMSGKEH.js +71 -0
  89. package/dist/cli/chunk-G23A2BZZ.js +705 -0
  90. package/dist/cli/chunk-GRIN2DDP.js +1465 -0
  91. package/dist/cli/chunk-HFHWYL55.js +139 -0
  92. package/dist/cli/chunk-HSNOBIVT.js +263 -0
  93. package/dist/cli/chunk-ICH7N5PN.js +26 -0
  94. package/dist/cli/chunk-J7VK7MNF.js +418 -0
  95. package/dist/cli/chunk-JVOCK5W4.js +83 -0
  96. package/dist/cli/chunk-KBGUO27Q.js +15 -0
  97. package/dist/cli/chunk-KH4MUBKF.js +1551 -0
  98. package/dist/cli/chunk-L6B6FUQP.js +330 -0
  99. package/dist/cli/chunk-LTXWBXOM.js +438 -0
  100. package/dist/cli/chunk-MI5JLQYA.js +220 -0
  101. package/dist/cli/chunk-MP653A5O.js +3766 -0
  102. package/dist/cli/chunk-NJFMDXHR.js +320 -0
  103. package/dist/cli/chunk-OM6BEME6.js +267 -0
  104. package/dist/cli/chunk-OWWBYLHC.js +136 -0
  105. package/dist/cli/chunk-QQPA2ZHH.js +273 -0
  106. package/dist/cli/chunk-RUU3YWXU.js +99 -0
  107. package/dist/cli/chunk-RXDIMXN5.js +98 -0
  108. package/dist/cli/chunk-ST6LROUG.js +267 -0
  109. package/dist/cli/chunk-TJW67QSI.js +225 -0
  110. package/dist/cli/chunk-WD62JIP6.js +118 -0
  111. package/dist/cli/chunk-WGKPJZDY.js +364 -0
  112. package/dist/cli/chunk-X4WKAOQP.js +634 -0
  113. package/dist/cli/chunk-X566FWBV.js +156 -0
  114. package/dist/cli/chunk-YH637PDL.js +317 -0
  115. package/dist/cli/chunk-ZL4JTG5Y.js +37 -0
  116. package/dist/cli/chunk-ZSCUZE6I.js +112 -0
  117. package/dist/cli/cliCommands-JJN5Z3ZC.js +3470 -0
  118. package/dist/cli/commands-PHYFYA3F.js +1374 -0
  119. package/dist/cli/contactSheet-2PQVRUFW.js +11 -0
  120. package/dist/cli/definitions-BPOPW52L.js +32 -0
  121. package/dist/cli/doctorCommand-ORWQRNYP.js +106 -0
  122. package/dist/cli/edit-S5KEQ5RA.js +28 -0
  123. package/dist/cli/editorCommands-NFR32JOY.js +41 -0
  124. package/dist/cli/encode-ICPEPMH5.js +17 -0
  125. package/dist/cli/file-3HTQHPYQ.js +41 -0
  126. package/dist/cli/filters-6ODFWYK4.js +379 -0
  127. package/dist/cli/frames-LSAUBZ7P.js +16 -0
  128. package/dist/cli/generators-YU7GB4MD.js +210 -0
  129. package/dist/cli/geo-6ZPGKZRU.js +43 -0
  130. package/dist/cli/graphCommands-EOUOBOIJ.js +184 -0
  131. package/dist/cli/graphFile-YTGJB5F5.js +292 -0
  132. package/dist/cli/headlessCanvas-ENRHC7GS.js +16 -0
  133. package/dist/cli/helpCommand-PULH6ZYB.js +157 -0
  134. package/dist/cli/image-TXELZZK5.js +55 -0
  135. package/dist/cli/index.js +100 -30756
  136. package/dist/cli/math-RSYRQ3C6.js +16 -0
  137. package/dist/cli/mcp-JVZFQOEX.js +164 -0
  138. package/dist/cli/parity-X6DEH2DV.js +334 -0
  139. package/dist/cli/pop-B7SIIYKN.js +39 -0
  140. package/dist/cli/project-VYGIA7JX.js +12 -0
  141. package/dist/cli/projectDefinition-F3D7UIHJ.js +27 -0
  142. package/dist/cli/projectRuntime-2Q4JKEH3.js +55 -0
  143. package/dist/cli/registerStandardNodes-BXJCB6E4.js +744 -0
  144. package/dist/cli/render-PT4MWI6U.js +438 -0
  145. package/dist/cli/runCommand-HNPQVZMS.js +198 -0
  146. package/dist/cli/runner-5XPXVW7J.js +43 -0
  147. package/dist/cli/runtime/image.ts +302 -0
  148. package/dist/cli/runtime/io.ts +78 -0
  149. package/dist/cli/runtime/stage.ts +4 -1
  150. package/dist/cli/share-MHF6TNRK.js +166 -0
  151. package/dist/cli/stageCache-TY2BFZJR.js +15 -0
  152. package/dist/cli/stageRunner-KY2EJP7X.js +10 -0
  153. package/dist/cli/text-MB3EKR4H.js +126 -0
  154. package/dist/cli/verbs-PI2JH5FI.js +19 -0
  155. package/dist/cli/webBuild-WPPMGGW7.js +44 -0
  156. package/dist/contracts/capabilities.d.ts +18 -1
  157. package/dist/contracts/color.d.ts +8 -0
  158. package/dist/contracts/color.js +23 -0
  159. package/dist/contracts/definition.d.ts +10 -0
  160. package/dist/contracts/documentFormat.d.ts +18 -0
  161. package/dist/contracts/documentFormat.js +195 -0
  162. package/dist/contracts/editor.d.ts +17 -0
  163. package/dist/contracts/index.d.ts +1 -0
  164. package/dist/contracts/index.js +1 -0
  165. package/dist/contracts/schema.d.ts +1 -1
  166. package/dist/contracts/schema.js +1 -0
  167. package/dist/contracts/validate.js +11 -1
  168. package/dist/contracts/values.d.ts +24 -0
  169. package/dist/image.d.ts +156 -0
  170. package/dist/image.js +161 -0
  171. package/dist/index.html +8 -2
  172. package/dist/io.d.ts +29 -0
  173. package/dist/io.js +40 -0
  174. package/dist/player/app.js +3 -2
  175. package/dist/player/editor.js +35 -9
  176. package/dist/player/editorEngine.js +3 -2
  177. package/dist/runtime/builtins/assert/checks.d.ts +18 -0
  178. package/dist/runtime/builtins/assert/checks.js +207 -0
  179. package/dist/runtime/builtins/assert/definitions.d.ts +130 -0
  180. package/dist/runtime/builtins/assert/definitions.js +54 -0
  181. package/dist/runtime/builtins/assert/index.d.ts +152 -0
  182. package/dist/runtime/builtins/assert/index.js +36 -0
  183. package/dist/runtime/builtins/image/contactSheet.d.ts +64 -0
  184. package/dist/runtime/builtins/image/contactSheet.js +150 -0
  185. package/dist/runtime/builtins/image/definitions.d.ts +950 -0
  186. package/dist/runtime/builtins/image/definitions.js +343 -0
  187. package/dist/runtime/builtins/image/file.d.ts +8 -0
  188. package/dist/runtime/builtins/image/file.js +37 -0
  189. package/dist/runtime/builtins/image/filters.d.ts +8 -0
  190. package/dist/runtime/builtins/image/filters.js +394 -0
  191. package/dist/runtime/builtins/image/generators.d.ts +7 -0
  192. package/dist/runtime/builtins/image/generators.js +144 -0
  193. package/dist/runtime/builtins/image/index.d.ts +952 -0
  194. package/dist/runtime/builtins/image/index.js +44 -0
  195. package/dist/runtime/builtins/image/io.d.ts +100 -0
  196. package/dist/runtime/builtins/image/io.js +142 -0
  197. package/dist/runtime/builtins/image/planar.d.ts +55 -0
  198. package/dist/runtime/builtins/image/planar.js +274 -0
  199. package/dist/runtime/builtins/image/simplex.d.ts +22 -0
  200. package/dist/runtime/builtins/image/simplex.js +92 -0
  201. package/dist/runtime/builtins/image/text.d.ts +4 -0
  202. package/dist/runtime/builtins/image/text.js +141 -0
  203. package/dist/runtime/builtins/index.d.ts +3 -0
  204. package/dist/runtime/builtins/index.js +7 -0
  205. package/dist/runtime/gpu.d.ts +25 -0
  206. package/dist/runtime/gpu.js +40 -0
  207. package/dist/runtime/runtime.d.ts +2 -0
  208. package/dist/runtime/runtime.js +268 -44
  209. package/dist/runtime/types.d.ts +30 -0
  210. package/dist/stage.js +4 -1
  211. package/doc/CLI_REFERENCE.md +91 -2
  212. package/doc/EDITOR_EXPORT.md +37 -2
  213. package/doc/MCP.md +18 -1
  214. package/doc/NODE_REFERENCE.md +424 -10
  215. package/doc/PROJECT_AUTHORING.md +222 -7
  216. package/package.json +19 -4
  217. package/dist/assets/CodePanel-sY6sZa7B.js +0 -2
  218. package/dist/assets/CustomNodeDialog-BRKnqZhp.js +0 -1
  219. package/dist/assets/ExportDialog-C7dVGua4.js +0 -358
  220. package/dist/assets/ExportDialog-DOq0flMV.css +0 -1
  221. package/dist/assets/OpenGraphDialog-ZsgL-iwr.js +0 -1
  222. package/dist/assets/ProjectSettings-Cw17nNe3.js +0 -2
  223. package/dist/assets/definitions-DUww2Rt-.js +0 -1
  224. package/dist/assets/geo-C2RHOVHC.js +0 -1
  225. package/dist/assets/image-DR4oeyJB.js +0 -2062
  226. package/dist/assets/index-7vae6YFC.css +0 -1
  227. package/dist/assets/index-DyvDC6pS.js +0 -219
  228. package/dist/assets/math-DaDEgWKt.js +0 -1
  229. package/dist/assets/pop-pLH7L0PW.js +0 -1
@@ -0,0 +1,744 @@
1
+ import {
2
+ CORE_TYPES,
3
+ Node,
4
+ isCoreType,
5
+ registerNodeClasses
6
+ } from "./chunk-CTPLRSWF.js";
7
+ import "./chunk-RUU3YWXU.js";
8
+ import {
9
+ randomFromSeed,
10
+ remap
11
+ } from "./chunk-RXDIMXN5.js";
12
+ import "./chunk-HFHWYL55.js";
13
+ import "./chunk-CO22XHNG.js";
14
+ import "./chunk-FWMSGKEH.js";
15
+
16
+ // src/nodes/core/nodes/SwitchNode.ts
17
+ var SwitchNode = class extends Node {
18
+ constructor(id, graph) {
19
+ super(id, "Switch", graph);
20
+ }
21
+ /**
22
+ * Get the index of the currently active input
23
+ * Used by connection rendering to grey out inactive wires
24
+ */
25
+ get activeInputIndex() {
26
+ const inputs = this.getVariadicInputs();
27
+ return Math.min(this.props.index?.value ?? 0, inputs.length - 1);
28
+ }
29
+ /**
30
+ * Check if a specific input port is active (for connection coloring)
31
+ */
32
+ isInputActive(portId) {
33
+ const inputs = this.getVariadicInputs();
34
+ const activeIdx = this.activeInputIndex;
35
+ const portIndex = inputs.findIndex((p) => p.id === portId);
36
+ return portIndex === activeIdx;
37
+ }
38
+ setup() {
39
+ this.setVariadic();
40
+ this.output = this.out("output");
41
+ const index = this.param("index", 0, { type: "int", min: 0, max: 0, step: 1 });
42
+ index.documentField = "props";
43
+ this.watchProp("index", () => this.update());
44
+ this.onUpdate = () => this.update();
45
+ this.onReady = () => this.update();
46
+ }
47
+ onCook() {
48
+ this.update();
49
+ }
50
+ update() {
51
+ const inputs = this.getVariadicInputs();
52
+ const connectedCount = inputs.filter((p) => p.connections.length > 0).length;
53
+ this.updatePropParams("index", { max: Math.max(0, connectedCount - 1) });
54
+ const idx = Math.min(this.props.index.value, inputs.length - 1);
55
+ const selectedInput = inputs[idx];
56
+ if (selectedInput) {
57
+ this.output.setValue(selectedInput.value);
58
+ if (this.isPreviewValue(selectedInput.value)) {
59
+ this.preview = selectedInput.value;
60
+ } else {
61
+ this.preview = null;
62
+ }
63
+ } else {
64
+ this.output.setValue(null);
65
+ this.preview = null;
66
+ }
67
+ }
68
+ };
69
+
70
+ // src/nodes/core/nodes/MergeNode.ts
71
+ var MergeNode = class extends Node {
72
+ constructor(id, graph) {
73
+ super(id, "Merge", graph);
74
+ }
75
+ setup() {
76
+ this.setVariadic();
77
+ this.output = this.out("output");
78
+ this.addParm("append", {
79
+ value: false,
80
+ type: "boolean",
81
+ displayName: "Append Mode",
82
+ hidden: () => {
83
+ const inputs = this.getVariadicInputs();
84
+ return !Array.isArray(inputs[0]?.value);
85
+ }
86
+ });
87
+ this.watchProp("append", () => this.update());
88
+ this.onUpdate = () => this.update();
89
+ this.onReady = () => this.update();
90
+ }
91
+ update() {
92
+ const inputs = this.getVariadicInputs();
93
+ const values = inputs.filter((p) => p.value !== null).map((p) => p.value);
94
+ const appendMode = this.props.append.value;
95
+ if (appendMode && values.length > 0 && Array.isArray(values[0])) {
96
+ const result = [...values[0], ...values.slice(1)];
97
+ this.output.setValue(result);
98
+ } else {
99
+ this.output.setValue(values);
100
+ }
101
+ this.preview = null;
102
+ for (const val of values) {
103
+ if (val instanceof HTMLCanvasElement || val instanceof HTMLImageElement) {
104
+ this.preview = val;
105
+ break;
106
+ }
107
+ }
108
+ }
109
+ };
110
+
111
+ // src/nodes/core/nodes/SubnetNode.ts
112
+ var SubnetNode = class extends Node {
113
+ constructor(id, graph) {
114
+ super(id, "Subnet", graph);
115
+ }
116
+ setup() {
117
+ this.onUpdate = () => this.update();
118
+ this.onReady = () => {
119
+ this.syncPorts();
120
+ this.update();
121
+ };
122
+ }
123
+ /**
124
+ * Override: Subnets are networks and can contain children
125
+ */
126
+ isNetwork() {
127
+ return true;
128
+ }
129
+ /**
130
+ * Add a child node to this subnet
131
+ */
132
+ addChild(node) {
133
+ node.parent = this;
134
+ this._children.push(node);
135
+ if (node.type === "Input" || node.type === "Output") {
136
+ this.syncPorts();
137
+ }
138
+ }
139
+ /**
140
+ * Remove a child node from this subnet
141
+ */
142
+ removeChild(node) {
143
+ const index = this._children.indexOf(node);
144
+ if (index !== -1) {
145
+ const wasInputOutput = node.type === "Input" || node.type === "Output";
146
+ this._children.splice(index, 1);
147
+ node.parent = null;
148
+ if (wasInputOutput) {
149
+ this.syncPorts();
150
+ }
151
+ }
152
+ }
153
+ /**
154
+ * Sync input/output ports based on child Input/Output nodes
155
+ */
156
+ syncPorts() {
157
+ const inputNodes = this._children.filter((n) => n.type === "Input");
158
+ const maxInputIndex = inputNodes.reduce((max, node) => {
159
+ const idx = node.inputIndex ?? 0;
160
+ return Math.max(max, idx);
161
+ }, -1);
162
+ const outputNodes = this._children.filter((n) => n.type === "Output");
163
+ const maxOutputIndex = outputNodes.reduce((max, node) => {
164
+ const idx = node.outputIndex ?? 0;
165
+ return Math.max(max, idx);
166
+ }, -1);
167
+ const requiredInputs = maxInputIndex + 1;
168
+ const currentInputs = this.inputs.length;
169
+ for (let i = currentInputs; i < requiredInputs; i++) {
170
+ const boundary = inputNodes.find((n) => n.inputIndex === i);
171
+ const port = this.in(boundary?.inputName || `input_${i}`, null, {
172
+ type: boundary?.dataType || "any"
173
+ });
174
+ port.onChange = (value) => {
175
+ this._children.filter((n) => n.type === "Input" && n.inputIndex === i).forEach((n) => n.markDirty());
176
+ };
177
+ }
178
+ for (let i = requiredInputs; i < currentInputs; i++) {
179
+ if (this.inputs[i]) {
180
+ this.inputs[i].options = { ...this.inputs[i].options, hidden: true };
181
+ }
182
+ }
183
+ for (let i = 0; i < requiredInputs; i++) {
184
+ if (this.inputs[i]) {
185
+ const boundary = inputNodes.find((n) => n.inputIndex === i);
186
+ this.inputs[i].name = boundary?.inputName || `input_${i}`;
187
+ this.inputs[i].dataType = boundary?.dataType || "any";
188
+ this.inputs[i].options = { ...this.inputs[i].options, hidden: false };
189
+ }
190
+ }
191
+ const requiredOutputs = maxOutputIndex + 1;
192
+ const currentOutputs = this.outputs.length;
193
+ for (let i = currentOutputs; i < requiredOutputs; i++) {
194
+ const boundary = outputNodes.find((n) => n.outputIndex === i);
195
+ this.out(boundary?.outputName || `output_${i}`, "param", {
196
+ type: boundary?.dataType || "any"
197
+ });
198
+ }
199
+ for (let i = requiredOutputs; i < currentOutputs; i++) {
200
+ if (this.outputs[i]) {
201
+ this.outputs[i].options = { ...this.outputs[i].options, hidden: true };
202
+ }
203
+ }
204
+ for (let i = 0; i < requiredOutputs; i++) {
205
+ if (this.outputs[i]) {
206
+ const boundary = outputNodes.find((n) => n.outputIndex === i);
207
+ this.outputs[i].name = boundary?.outputName || `output_${i}`;
208
+ this.outputs[i].dataType = boundary?.dataType || "any";
209
+ this.outputs[i].options = { ...this.outputs[i].options, hidden: false };
210
+ }
211
+ }
212
+ this.inputs = [...this.inputs];
213
+ this.outputs = [...this.outputs];
214
+ }
215
+ /**
216
+ * Get the node that defines this subnet's output
217
+ * Priority: Output node > cooking node > last node
218
+ */
219
+ outputNode() {
220
+ const outputNode = this._children.find((n) => n.type === "Output");
221
+ if (outputNode) return outputNode;
222
+ const cookingNode = this._children.find((n) => n.cook);
223
+ if (cookingNode) return cookingNode;
224
+ return this._children.length > 0 ? this._children[this._children.length - 1] : null;
225
+ }
226
+ /**
227
+ * Get the cooking (display) node in this subnet
228
+ */
229
+ displayNode() {
230
+ return this._children.find((n) => n.cook) ?? null;
231
+ }
232
+ /**
233
+ * Get all Input nodes inside this subnet
234
+ */
235
+ indirectInputs() {
236
+ return this._children.filter((n) => n.type === "Input");
237
+ }
238
+ update() {
239
+ const outputNodes = this._children.filter((n) => n.type === "Output");
240
+ const outputByIndex = /* @__PURE__ */ new Map();
241
+ for (const node of outputNodes) {
242
+ const idx = node.outputIndex ?? 0;
243
+ outputByIndex.set(idx, node);
244
+ }
245
+ for (let i = 0; i < this.outputs.length; i++) {
246
+ const outNode = outputByIndex.get(i);
247
+ if (outNode && outNode.inputs.length > 0) {
248
+ const value = outNode.inputs[0].value;
249
+ this.outputs[i].setValue(value);
250
+ if (i === 0 && (value instanceof HTMLCanvasElement || value instanceof HTMLImageElement)) {
251
+ this.preview = value;
252
+ }
253
+ } else if (i === 0) {
254
+ const cookingNode = this._children.find((n) => n.cook);
255
+ if (cookingNode && cookingNode.outputs.length > 0) {
256
+ this.outputs[i].setValue(cookingNode.outputs[0].value);
257
+ if (cookingNode.preview) {
258
+ this.preview = cookingNode.preview;
259
+ }
260
+ } else {
261
+ this.outputs[i].setValue(null);
262
+ }
263
+ } else {
264
+ this.outputs[i].setValue(null);
265
+ }
266
+ }
267
+ if (this.outputs.length === 0 || !outputByIndex.has(0)) {
268
+ const cookingNode = this._children.find((n) => n.cook);
269
+ if (!cookingNode?.preview) {
270
+ this.preview = null;
271
+ }
272
+ }
273
+ }
274
+ };
275
+
276
+ // src/nodes/core/nodes/InputNode.ts
277
+ var TYPE_CHOICES = CORE_TYPES.map((type) => ({ value: type, label: type }));
278
+ var InputNode = class extends Node {
279
+ constructor(id, graph) {
280
+ super(id, "Input", graph);
281
+ }
282
+ setup() {
283
+ this.output = this.out("output");
284
+ this.addParm("inputIndex", {
285
+ value: 0,
286
+ type: "int",
287
+ params: { min: 0, step: 1 },
288
+ displayName: "Input Index"
289
+ });
290
+ this.addParm("inputName", {
291
+ value: "",
292
+ type: "text",
293
+ displayName: "Input Name"
294
+ });
295
+ this.addParm("dataType", {
296
+ value: "any",
297
+ type: "select",
298
+ params: { options: TYPE_CHOICES },
299
+ displayName: "Data Type"
300
+ });
301
+ const syncParent = () => {
302
+ if (this.parent && this.parent.syncPorts) {
303
+ this.parent.syncPorts();
304
+ }
305
+ this.update();
306
+ };
307
+ this.watchProp("inputIndex", syncParent);
308
+ this.watchProp("inputName", syncParent);
309
+ this.watchProp("dataType", () => {
310
+ this.output.dataType = this.dataType;
311
+ syncParent();
312
+ });
313
+ this.onUpdate = () => this.update();
314
+ this.onReady = () => this.update();
315
+ }
316
+ /**
317
+ * Get the input index this node represents
318
+ */
319
+ get inputIndex() {
320
+ return this.props.inputIndex?.value ?? 0;
321
+ }
322
+ /**
323
+ * Get the input name (for documentation)
324
+ */
325
+ get inputName() {
326
+ return this.props.inputName?.value ?? "";
327
+ }
328
+ get dataType() {
329
+ const value = this.props.dataType?.value;
330
+ return typeof value === "string" && isCoreType(value) ? value : "any";
331
+ }
332
+ update() {
333
+ if (this.parent && this.parent.inputs.length > 0) {
334
+ const idx = this.inputIndex;
335
+ const parentInput = this.parent.inputs[idx];
336
+ if (parentInput) {
337
+ this.output.setValue(parentInput.value);
338
+ if (this.isPreviewValue(parentInput.value)) {
339
+ this.preview = parentInput.value;
340
+ } else {
341
+ this.preview = null;
342
+ }
343
+ return;
344
+ }
345
+ }
346
+ this.output.setValue(null);
347
+ this.preview = null;
348
+ }
349
+ };
350
+
351
+ // src/nodes/core/nodes/OutputNode.ts
352
+ var TYPE_CHOICES2 = CORE_TYPES.map((type) => ({ value: type, label: type }));
353
+ var OutputNode = class extends Node {
354
+ constructor(id, graph) {
355
+ super(id, "Output", graph);
356
+ }
357
+ setup() {
358
+ this.in("input", null);
359
+ this.addParm("outputIndex", {
360
+ value: 0,
361
+ type: "int",
362
+ params: { min: 0, step: 1 },
363
+ displayName: "Output Index"
364
+ });
365
+ this.addParm("outputName", {
366
+ value: "",
367
+ type: "text",
368
+ displayName: "Output Name"
369
+ });
370
+ this.addParm("dataType", {
371
+ value: "any",
372
+ type: "select",
373
+ params: { options: TYPE_CHOICES2 },
374
+ displayName: "Data Type"
375
+ });
376
+ const syncParent = () => {
377
+ if (this.parent && this.parent.syncPorts) {
378
+ this.parent.syncPorts();
379
+ }
380
+ this.update();
381
+ };
382
+ this.watchProp("outputIndex", syncParent);
383
+ this.watchProp("outputName", syncParent);
384
+ this.watchProp("dataType", () => {
385
+ if (this.inputs[0]) this.inputs[0].dataType = this.dataType;
386
+ syncParent();
387
+ });
388
+ this.onUpdate = () => this.update();
389
+ this.onReady = () => this.update();
390
+ }
391
+ /**
392
+ * Get the output index this node represents
393
+ */
394
+ get outputIndex() {
395
+ return this.props.outputIndex?.value ?? 0;
396
+ }
397
+ get outputName() {
398
+ return this.props.outputName?.value ?? "";
399
+ }
400
+ get dataType() {
401
+ const value = this.props.dataType?.value;
402
+ return typeof value === "string" && isCoreType(value) ? value : "any";
403
+ }
404
+ update() {
405
+ const input = this.inputs[0];
406
+ if (input) {
407
+ if (this.isPreviewValue(input.value)) {
408
+ this.preview = input.value;
409
+ } else {
410
+ this.preview = null;
411
+ }
412
+ }
413
+ }
414
+ };
415
+
416
+ // src/nodes/core/nodes/RandomNode.ts
417
+ var RandomNode = class extends Node {
418
+ constructor(id, graph) {
419
+ super(id, "Random", graph);
420
+ }
421
+ setup() {
422
+ const seed = this.in("seed", 0, { type: "int" });
423
+ const sample = this.in("sample", 0, { type: "int" });
424
+ const value = this.out("value");
425
+ const update = () => value.setValue(randomFromSeed(seed.value, sample.value));
426
+ seed.onChange = update;
427
+ sample.onChange = update;
428
+ this.onUpdate = update;
429
+ this.onReady = update;
430
+ }
431
+ };
432
+
433
+ // src/nodes/core/nodes/RemapNode.ts
434
+ var RemapNode = class extends Node {
435
+ constructor(id, graph) {
436
+ super(id, "Remap", graph);
437
+ }
438
+ setup() {
439
+ const value = this.in("value", 0, { type: "float" });
440
+ const inMin = this.in("inMin", 0, { type: "float" });
441
+ const inMax = this.in("inMax", 1, { type: "float" });
442
+ const outMin = this.in("outMin", 0, { type: "float" });
443
+ const outMax = this.in("outMax", 1, { type: "float" });
444
+ const result = this.out("result");
445
+ this.addParm("clamp", { value: false, type: "boolean", displayName: "Clamp" });
446
+ const update = () => result.setValue(remap(
447
+ value.value,
448
+ inMin.value,
449
+ inMax.value,
450
+ outMin.value,
451
+ outMax.value,
452
+ this.props.clamp.value
453
+ ));
454
+ for (const input of [value, inMin, inMax, outMin, outMax]) input.onChange = update;
455
+ this.watchProp("clamp", update);
456
+ this.onUpdate = update;
457
+ this.onReady = update;
458
+ }
459
+ };
460
+
461
+ // src/nodes/core/nodes/SelectNode.ts
462
+ var SelectNode = class extends Node {
463
+ constructor(id, graph) {
464
+ super(id, "Select", graph);
465
+ }
466
+ setup() {
467
+ this.arrayInput = this.in("array", [], { type: "array" });
468
+ this.itemOutput = this.out("item", "param");
469
+ this.countOutput = this.out("count", "param");
470
+ this.addParm("index", {
471
+ value: 0,
472
+ type: "int",
473
+ params: { min: 0, max: 0, step: 1 },
474
+ displayName: "Index"
475
+ });
476
+ this.addParm("wrap", {
477
+ value: true,
478
+ type: "boolean",
479
+ displayName: "Wrap Index"
480
+ });
481
+ this.watchProp("index", () => this.update());
482
+ this.watchProp("wrap", () => this.update());
483
+ this.onUpdate = () => this.update();
484
+ this.onReady = () => this.update();
485
+ }
486
+ update() {
487
+ const array = this.arrayInput.value;
488
+ if (!Array.isArray(array) || array.length === 0) {
489
+ this.itemOutput.setValue(null);
490
+ this.countOutput.setValue(0);
491
+ this.updatePropParams("index", { max: 0 });
492
+ return;
493
+ }
494
+ this.updatePropParams("index", { max: array.length - 1 });
495
+ let index = this.props.index?.value ?? 0;
496
+ const wrap = this.props.wrap?.value ?? true;
497
+ if (wrap && array.length > 0) {
498
+ index = (index % array.length + array.length) % array.length;
499
+ } else {
500
+ index = Math.max(0, Math.min(index, array.length - 1));
501
+ }
502
+ const item = array[index];
503
+ this.itemOutput.setValue(item);
504
+ this.countOutput.setValue(array.length);
505
+ if (item instanceof HTMLCanvasElement || item instanceof HTMLImageElement) {
506
+ this.preview = item;
507
+ } else {
508
+ this.preview = null;
509
+ }
510
+ }
511
+ };
512
+
513
+ // src/nodes/core/nodes/NullNode.ts
514
+ var NullNode = class extends Node {
515
+ constructor(id, graph) {
516
+ super(id, "Null", graph);
517
+ }
518
+ setup() {
519
+ const input = this.in("input", null, { type: "any" });
520
+ const output = this.out("output");
521
+ const update = () => output.setValue(input.value);
522
+ input.onChange = update;
523
+ this.onUpdate = update;
524
+ this.onReady = update;
525
+ }
526
+ };
527
+
528
+ // src/nodes/image/surface.ts
529
+ var globals = () => globalThis;
530
+ function hasPixels(value) {
531
+ if (typeof value !== "object" || value === null) return false;
532
+ const candidate = value;
533
+ if (typeof candidate.width !== "number" || typeof candidate.height !== "number") return false;
534
+ return typeof candidate.getContext === "function" || "src" in candidate || typeof candidate.close === "function";
535
+ }
536
+ var MissingRenderSurfaceError = class extends Error {
537
+ constructor(kind) {
538
+ super(
539
+ `Cascade has no ${kind} in this environment. Install the optional '@napi-rs/canvas' renderer before cooking a graph that draws.`
540
+ );
541
+ this.name = "MissingRenderSurfaceError";
542
+ }
543
+ };
544
+ function provider() {
545
+ const host = globals();
546
+ if (typeof host.document?.createElement === "function") return domProvider;
547
+ if (typeof host.OffscreenCanvas === "function") return offscreenProvider;
548
+ return null;
549
+ }
550
+ function createSurface(width, height) {
551
+ const current = provider();
552
+ if (!current) throw new MissingRenderSurfaceError("drawing surface");
553
+ return current.createSurface(width, height);
554
+ }
555
+ function bytesOf(source) {
556
+ return source instanceof Uint8Array ? source : new Uint8Array(source);
557
+ }
558
+ async function decodeViaBitmap(source) {
559
+ const host = globals();
560
+ if (typeof host.createImageBitmap !== "function" || typeof source === "string") return null;
561
+ const input = source instanceof Uint8Array || source instanceof ArrayBuffer ? typeof host.Blob === "function" ? new host.Blob([bytesOf(source)]) : bytesOf(source) : source;
562
+ return host.createImageBitmap(input);
563
+ }
564
+ async function decodeViaImage(source) {
565
+ const host = globals();
566
+ if (typeof host.Image !== "function") throw new MissingRenderSurfaceError("image decoder");
567
+ const image = new host.Image();
568
+ if (typeof source === "string") {
569
+ if (!/^(data:|blob:)/.test(source)) image.crossOrigin = "anonymous";
570
+ image.src = source;
571
+ } else if (source instanceof Uint8Array || source instanceof ArrayBuffer) {
572
+ image.src = bytesOf(source);
573
+ } else {
574
+ image.src = new Uint8Array(await source.arrayBuffer());
575
+ }
576
+ await image.decode();
577
+ if (!image.width || !image.height) throw new Error("cascade: could not decode image data");
578
+ return image;
579
+ }
580
+ async function decode(source) {
581
+ if (typeof source !== "string") {
582
+ const bitmap = await decodeViaBitmap(source);
583
+ if (bitmap) return bitmap;
584
+ }
585
+ return decodeViaImage(source);
586
+ }
587
+ var domProvider = {
588
+ name: "DOM canvas",
589
+ createSurface(width, height) {
590
+ const surface = globals().document.createElement("canvas");
591
+ surface.width = width;
592
+ surface.height = height;
593
+ return surface;
594
+ },
595
+ decodeImage: decode
596
+ };
597
+ var offscreenProvider = {
598
+ name: "OffscreenCanvas",
599
+ createSurface(width, height) {
600
+ const Offscreen = globals().OffscreenCanvas;
601
+ return new Offscreen(width, height);
602
+ },
603
+ decodeImage: decode
604
+ };
605
+
606
+ // src/nodes/core/nodes/FreezeNode.ts
607
+ function previewWanted() {
608
+ return typeof document !== "undefined";
609
+ }
610
+ var FreezeNode = class extends Node {
611
+ constructor(id, graph) {
612
+ super(id, "Freeze", graph);
613
+ this.frozenValue = null;
614
+ this.hasCaptured = false;
615
+ }
616
+ setup() {
617
+ this.input = this.in("input", null, { type: "any" });
618
+ this.output = this.out("output", "param");
619
+ this.addParm("frozen", {
620
+ value: false,
621
+ type: "boolean",
622
+ displayName: "Frozen"
623
+ });
624
+ this.addAction("capture", {
625
+ label: "Capture",
626
+ icon: "Camera",
627
+ callback: () => this.capture()
628
+ });
629
+ this.addAction("clear", {
630
+ label: "Clear",
631
+ icon: "Trash2",
632
+ callback: () => this.clear()
633
+ });
634
+ this.watchProp("frozen", () => this.update());
635
+ this.onUpdate = () => this.update();
636
+ this.onReady = () => this.update();
637
+ }
638
+ /**
639
+ * Capture the current input value
640
+ */
641
+ capture() {
642
+ this.frozenValue = this.deepClone(this.input.value);
643
+ this.hasCaptured = true;
644
+ this.setParm("frozen", true);
645
+ this.update();
646
+ }
647
+ /**
648
+ * Clear the frozen value
649
+ */
650
+ clear() {
651
+ this.frozenValue = null;
652
+ this.hasCaptured = false;
653
+ this.setParm("frozen", false);
654
+ this.update();
655
+ }
656
+ /**
657
+ * Deep clone a value if possible
658
+ */
659
+ deepClone(value) {
660
+ if (value === null || value === void 0) {
661
+ return value;
662
+ }
663
+ if (hasPixels(value)) {
664
+ const source = value;
665
+ const width = source.naturalWidth || source.width;
666
+ const height = source.naturalHeight || source.height;
667
+ const canvas = createSurface(width, height);
668
+ const ctx = canvas.getContext("2d");
669
+ ctx?.drawImage(value, 0, 0);
670
+ return canvas;
671
+ }
672
+ if (Array.isArray(value)) {
673
+ return value.map((item) => this.deepClone(item));
674
+ }
675
+ if (typeof value === "object") {
676
+ try {
677
+ return JSON.parse(JSON.stringify(value));
678
+ } catch {
679
+ return value;
680
+ }
681
+ }
682
+ return value;
683
+ }
684
+ update() {
685
+ const isFrozen = this.props.frozen?.value ?? false;
686
+ if (isFrozen && this.hasCaptured) {
687
+ this.output.setValue(this.frozenValue);
688
+ if (previewWanted() && hasPixels(this.frozenValue)) {
689
+ this.preview = this.frozenValue;
690
+ }
691
+ } else {
692
+ this.output.setValue(this.input.value);
693
+ if (previewWanted() && hasPixels(this.input.value)) {
694
+ this.preview = this.input.value;
695
+ } else {
696
+ this.preview = null;
697
+ }
698
+ }
699
+ }
700
+ /**
701
+ * Serialize with frozen state
702
+ */
703
+ serialize() {
704
+ return {
705
+ hasCaptured: this.hasCaptured
706
+ };
707
+ }
708
+ /**
709
+ * Deserialize and restore frozen state
710
+ */
711
+ deserialize(data) {
712
+ this.hasCaptured = data.hasCaptured === true;
713
+ }
714
+ };
715
+
716
+ // src/nodes/core/classes.ts
717
+ var coreNodeClasses = {
718
+ "Switch": SwitchNode,
719
+ "Merge": MergeNode,
720
+ "Subnet": SubnetNode,
721
+ "Input": InputNode,
722
+ "Output": OutputNode,
723
+ "Random": RandomNode,
724
+ "Remap": RemapNode,
725
+ "Select": SelectNode,
726
+ "Null": NullNode,
727
+ "Freeze": FreezeNode
728
+ };
729
+
730
+ // src/nodes/registerStandardNodes.ts
731
+ var registered = false;
732
+ function registerStandardNodes() {
733
+ if (registered) return;
734
+ registerNodeClasses("core", coreNodeClasses);
735
+ registered = true;
736
+ }
737
+ function standardNodesRegistered() {
738
+ return registered;
739
+ }
740
+ export {
741
+ registerStandardNodes,
742
+ standardNodesRegistered
743
+ };
744
+ //# sourceMappingURL=registerStandardNodes-BXJCB6E4.js.map