@field/cascade 0.11.0 → 0.13.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 (220) hide show
  1. package/AGENTS.md +8 -5
  2. package/ARCHITECTURE.md +5 -4
  3. package/CHANGELOG.md +245 -0
  4. package/README.md +1 -1
  5. package/dist/assets/AgentPanel-1JugFjE4.css +1 -0
  6. package/dist/assets/AgentPanel-BDL5MddA.js +5 -0
  7. package/dist/assets/{CodeEditor-4O7FQ__R.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-Bz8JxISH.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-D5Z0nJ5-.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-Yqi0Ni61.js → core-DB-MkGjj.js} +3 -4
  28. package/dist/assets/coreTypes-DtnDATZ7.js +1 -0
  29. package/dist/assets/{cssMode-CxUzc4vp.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-BNFb25CX.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-0ZDnWxeM.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-Cy18MoaD.js → handlebars-CcD3aMeL.js} +1 -1
  41. package/dist/assets/{html-B-2Dx7nq.js → html-DvZWGfqb.js} +1 -1
  42. package/dist/assets/{htmlMode-DUAc9B_d.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-DeQsDqP5.js → javascript-Cap2ahgh.js} +1 -1
  49. package/dist/assets/{jsonMode-BiFwJVSk.js → jsonMode-B0uLjp9C.js} +1 -1
  50. package/dist/assets/{liquid-BLoHH68a.js → liquid-CnxwhfLn.js} +1 -1
  51. package/dist/assets/{lspLanguageFeatures-CNFgm1Kv.js → lspLanguageFeatures-Dn9hlKX6.js} +1 -1
  52. package/dist/assets/math-GeULS-sk.js +1 -0
  53. package/dist/assets/{mdx-CFXQVNfs.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-Cf7S7p2E.js → python-CGyFk4XK.js} +1 -1
  57. package/dist/assets/{razor-CMHBcG-g.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-BEih0GDj.js → tsMode-BOeXzO9H.js} +1 -1
  64. package/dist/assets/{typescript-COEKYD_a.js → typescript-J1SnE_Tu.js} +1 -1
  65. package/dist/assets/{workers-BNhAhMNn.js → workers-CYwwTiVF.js} +1 -1
  66. package/dist/assets/{xml-CPiMpnPl.js → xml-DnPRNzK9.js} +1 -1
  67. package/dist/assets/{yaml-Bgp1ITLR.js → yaml-BmmYBNa9.js} +1 -1
  68. package/dist/cli/DefinitionNode-P7AA4TAU.js +15 -0
  69. package/dist/cli/{Graph-ZJJTRQTM.js → Graph-OB6EWSGL.js} +12 -12
  70. package/dist/cli/assert-GROGQNCQ.js +25 -0
  71. package/dist/cli/checks-3WB44XBL.js +189 -0
  72. package/dist/cli/{chunk-3JTJHF7V.js → chunk-2L34ERS2.js} +4 -4
  73. package/dist/cli/chunk-53LGFPWX.js +138 -0
  74. package/dist/cli/chunk-5ORUQ6ES.js +267 -0
  75. package/dist/cli/{chunk-YAT5Y25U.js → chunk-7QE2ZNSN.js} +3 -3
  76. package/dist/cli/{chunk-SGJAET2L.js → chunk-BPODRH52.js} +8 -4
  77. package/dist/cli/{chunk-XWDSKG7N.js → chunk-BZ63XQ3I.js} +2 -2
  78. package/dist/cli/{chunk-FCDXJ6EK.js → chunk-CTPLRSWF.js} +2 -13
  79. package/dist/cli/{chunk-WIH4TEIS.js → chunk-EZRWJ4G2.js} +1 -1
  80. package/dist/cli/{chunk-BIJO5OFS.js → chunk-FWMSGKEH.js} +1 -1
  81. package/dist/cli/{chunk-POMMNKZZ.js → chunk-G23A2BZZ.js} +38 -5
  82. package/dist/cli/{chunk-35D343DC.js → chunk-GRIN2DDP.js} +19 -1
  83. package/dist/cli/{chunk-WKURDVYP.js → chunk-JEW5MPGI.js} +28 -331
  84. package/dist/cli/chunk-JVOCK5W4.js +83 -0
  85. package/dist/cli/chunk-KBGUO27Q.js +15 -0
  86. package/dist/cli/{chunk-GFS6W3C5.js → chunk-L6B6FUQP.js} +54 -32
  87. package/dist/cli/chunk-LTXWBXOM.js +438 -0
  88. package/dist/cli/chunk-MI5JLQYA.js +220 -0
  89. package/dist/cli/{chunk-A4OAMOZH.js → chunk-NJFMDXHR.js} +13 -3
  90. package/dist/cli/{chunk-DUIUFVU2.js → chunk-OBZAP3GG.js} +49 -23
  91. package/dist/cli/chunk-QAGATJGE.js +336 -0
  92. package/dist/cli/{chunk-EUIAC3U3.js → chunk-QKL7CCRS.js} +966 -132
  93. package/dist/cli/{chunk-RLCAJBVR.js → chunk-TJW67QSI.js} +8 -7
  94. package/dist/cli/{chunk-RQZ4SX5R.js → chunk-W5PJ5RMP.js} +156 -84
  95. package/dist/cli/chunk-W7OUAT7J.js +122 -0
  96. package/dist/cli/chunk-WGKPJZDY.js +364 -0
  97. package/dist/cli/{chunk-D6BUOHUG.js → chunk-X4WKAOQP.js} +4 -4
  98. package/dist/cli/{chunk-VVGSLVSF.js → chunk-X566FWBV.js} +6 -1
  99. package/dist/cli/chunk-YH637PDL.js +317 -0
  100. package/dist/cli/chunk-ZSCUZE6I.js +112 -0
  101. package/dist/cli/{cliCommands-UQSFGEHF.js → cliCommands-XVFRD7CF.js} +23 -17
  102. package/dist/cli/{commands-Q23M26QM.js → commands-M2XLTPTZ.js} +129 -47
  103. package/dist/cli/contactSheet-2PQVRUFW.js +11 -0
  104. package/dist/cli/{definitions-HF2FTHYU.js → definitions-BPOPW52L.js} +7 -7
  105. package/dist/cli/{doctorCommand-B7BPQMN6.js → doctorCommand-RAEI7GVY.js} +36 -6
  106. package/dist/cli/{edit-JHCPTQFT.js → edit-S5KEQ5RA.js} +3 -3
  107. package/dist/cli/editorCommands-5BBG4S6V.js +41 -0
  108. package/dist/cli/{encode-HAUZTYPT.js → encode-ICPEPMH5.js} +2 -2
  109. package/dist/cli/file-3HTQHPYQ.js +41 -0
  110. package/dist/cli/filters-6ODFWYK4.js +379 -0
  111. package/dist/cli/generators-YU7GB4MD.js +210 -0
  112. package/dist/cli/{geo-4RNK3QVN.js → geo-6ZPGKZRU.js} +7 -7
  113. package/dist/cli/{graphCommands-6BMAKGQE.js → graphCommands-MULQ7VD2.js} +4 -4
  114. package/dist/cli/{graphFile-VPSQ6OF7.js → graphFile-CITF36ZM.js} +25 -19
  115. package/dist/cli/{headlessCanvas-5XLDZT7M.js → headlessCanvas-ENRHC7GS.js} +3 -2
  116. package/dist/cli/{helpCommand-3VRE3KVO.js → helpCommand-X2QDANM3.js} +9 -7
  117. package/dist/cli/image-TXELZZK5.js +55 -0
  118. package/dist/cli/index.js +14 -14
  119. package/dist/cli/{math-ZRMLKU2D.js → math-RSYRQ3C6.js} +5 -5
  120. package/dist/cli/{mcp-ZLEEMYGF.js → mcp-YRIGRLYQ.js} +4 -4
  121. package/dist/cli/{parity-KINARCP2.js → parity-3N3HTKWX.js} +42 -36
  122. package/dist/cli/{pop-USDFXB7H.js → pop-B7SIIYKN.js} +5 -5
  123. package/dist/cli/project-SJF5ZF3F.js +12 -0
  124. package/dist/cli/{projectDefinition-DMTZN2NE.js → projectDefinition-F3D7UIHJ.js} +8 -8
  125. package/dist/cli/{projectRuntime-Z5PJOH47.js → projectRuntime-NY4XMDFH.js} +19 -12
  126. package/dist/cli/registerStandardNodes-BXJCB6E4.js +744 -0
  127. package/dist/cli/{render-YURAPPUI.js → render-Y23W6MY6.js} +29 -22
  128. package/dist/cli/{runCommand-PI764LEG.js → runCommand-XOG7AVC5.js} +3 -3
  129. package/dist/cli/runner-DNJO5WO2.js +43 -0
  130. package/dist/cli/runtime/image.ts +27 -2
  131. package/dist/cli/runtime/io.ts +78 -0
  132. package/dist/cli/share-B7HTCOJX.js +166 -0
  133. package/dist/cli/stageCache-TY2BFZJR.js +15 -0
  134. package/dist/cli/{stageRunner-KUNIMQKJ.js → stageRunner-KY2EJP7X.js} +2 -2
  135. package/dist/cli/text-MB3EKR4H.js +126 -0
  136. package/dist/cli/{verbs-RCE3K4VQ.js → verbs-PI2JH5FI.js} +2 -2
  137. package/dist/cli/webBuild-2K4COCGY.js +44 -0
  138. package/dist/contracts/capabilities.d.ts +39 -1
  139. package/dist/contracts/color.d.ts +8 -0
  140. package/dist/contracts/color.js +23 -0
  141. package/dist/contracts/definition.d.ts +10 -0
  142. package/dist/contracts/schema.d.ts +1 -1
  143. package/dist/contracts/schema.js +1 -0
  144. package/dist/contracts/validate.js +11 -1
  145. package/dist/contracts/values.d.ts +24 -0
  146. package/dist/image.d.ts +15 -0
  147. package/dist/image.js +36 -2
  148. package/dist/index.html +8 -2
  149. package/dist/io.d.ts +29 -0
  150. package/dist/io.js +40 -0
  151. package/dist/player/app.js +11 -7
  152. package/dist/player/editor.js +3 -2
  153. package/dist/player/editorEngine.js +3 -2
  154. package/dist/player/embed.js +2 -0
  155. package/dist/player/types.d.ts +6 -0
  156. package/dist/runtime/builtins/assert/checks.d.ts +18 -0
  157. package/dist/runtime/builtins/assert/checks.js +207 -0
  158. package/dist/runtime/builtins/assert/definitions.d.ts +130 -0
  159. package/dist/runtime/builtins/assert/definitions.js +54 -0
  160. package/dist/runtime/builtins/assert/index.d.ts +152 -0
  161. package/dist/runtime/builtins/assert/index.js +36 -0
  162. package/dist/runtime/builtins/image/contactSheet.d.ts +3 -165
  163. package/dist/runtime/builtins/image/contactSheet.js +0 -49
  164. package/dist/runtime/builtins/image/definitions.d.ts +950 -0
  165. package/dist/runtime/builtins/image/definitions.js +343 -0
  166. package/dist/runtime/builtins/image/file.d.ts +8 -0
  167. package/dist/runtime/builtins/image/file.js +37 -0
  168. package/dist/runtime/builtins/image/filters.d.ts +8 -0
  169. package/dist/runtime/builtins/image/filters.js +394 -0
  170. package/dist/runtime/builtins/image/generators.d.ts +7 -0
  171. package/dist/runtime/builtins/image/generators.js +144 -0
  172. package/dist/runtime/builtins/image/index.d.ts +947 -4
  173. package/dist/runtime/builtins/image/index.js +41 -6
  174. package/dist/runtime/builtins/image/io.d.ts +100 -0
  175. package/dist/runtime/builtins/image/io.js +142 -0
  176. package/dist/runtime/builtins/image/planar.d.ts +55 -0
  177. package/dist/runtime/builtins/image/planar.js +274 -0
  178. package/dist/runtime/builtins/image/simplex.d.ts +22 -0
  179. package/dist/runtime/builtins/image/simplex.js +92 -0
  180. package/dist/runtime/builtins/image/text.d.ts +4 -0
  181. package/dist/runtime/builtins/image/text.js +141 -0
  182. package/dist/runtime/builtins/index.d.ts +3 -0
  183. package/dist/runtime/builtins/index.js +7 -0
  184. package/dist/runtime/definition/architecture.js +89 -0
  185. package/dist/runtime/gpu.d.ts +25 -0
  186. package/dist/runtime/gpu.js +40 -0
  187. package/dist/runtime/runtime.d.ts +2 -0
  188. package/dist/runtime/runtime.js +268 -44
  189. package/dist/runtime/types.d.ts +30 -0
  190. package/doc/CLI_REFERENCE.md +21 -3
  191. package/doc/EDITOR_EXPORT.md +26 -0
  192. package/doc/MCP.md +2 -1
  193. package/doc/NODE_REFERENCE.md +286 -14
  194. package/doc/PROJECT_AUTHORING.md +158 -4
  195. package/doc/WEB_PLAYER.md +9 -1
  196. package/package.json +4 -1
  197. package/dist/assets/CodePanel-BU-autmq.js +0 -2
  198. package/dist/assets/CustomNodeDialog-BRpDfOV5.js +0 -1
  199. package/dist/assets/OpenGraphDialog-BwbRlC0X.js +0 -1
  200. package/dist/assets/ProjectSettings-DLOXLxcA.js +0 -2
  201. package/dist/assets/definitions-GreEMXLV.js +0 -1
  202. package/dist/assets/geo-u0n_jOsD.js +0 -1
  203. package/dist/assets/image-cAa-Nu9O.js +0 -2062
  204. package/dist/assets/index-5ZtDAuy2.js +0 -220
  205. package/dist/assets/index-7vae6YFC.css +0 -1
  206. package/dist/assets/math-DioIQOPJ.js +0 -1
  207. package/dist/assets/pop-DC_TQG9t.js +0 -1
  208. package/dist/cli/chunk-36P5K3SD.js +0 -631
  209. package/dist/cli/chunk-4UDFYF5G.js +0 -132
  210. package/dist/cli/chunk-53NMBJAO.js +0 -35
  211. package/dist/cli/chunk-MIIEFUGG.js +0 -623
  212. package/dist/cli/chunk-QBBKRNGY.js +0 -90
  213. package/dist/cli/chunk-WPUDGEFY.js +0 -20
  214. package/dist/cli/editorCommands-UIF5YLUZ.js +0 -33
  215. package/dist/cli/project-K3QIPGBB.js +0 -12
  216. package/dist/cli/registerStandardNodes-S2VLMF6J.js +0 -3081
  217. package/dist/cli/runner-RA6UKEPD.js +0 -37
  218. package/dist/cli/webBuild-GT4PZT5D.js +0 -37
  219. package/dist/runtime/builtins/headless.d.ts +0 -19
  220. package/dist/runtime/builtins/headless.js +0 -25
@@ -0,0 +1,343 @@
1
+ /**
2
+ * The image library's declarations: `cascade.image.*`, the eleven nodes that
3
+ * were Studio classes until 2026-11-07, with the same module ids, ports and
4
+ * prop names, so a saved graph loads unchanged.
5
+ *
6
+ * Literal and small on purpose: these sit in Studio's first-paint bundle with
7
+ * the rest of the built-in list, and each node's body loads behind a dynamic
8
+ * import the first time it cooks (`index.ts`).
9
+ *
10
+ * Every node is `portable` with `assets`: an image arrives as an `ImageRef`
11
+ * and leaves as one, through the host's in-memory image contract (`io.ts`).
12
+ */
13
+ export const contactSheetDefinition = {
14
+ apiVersion: 1,
15
+ label: "Contact Sheet",
16
+ description: "Lay images out as one labelled grid.",
17
+ icon: "LayoutGrid",
18
+ runsOn: "portable",
19
+ capabilities: ["assets"],
20
+ inputs: {
21
+ images: { kind: "data", type: "image", variadic: true },
22
+ /** More images after the wired ones: image values or project-relative paths. */
23
+ list: { kind: "data", type: "array" },
24
+ },
25
+ outputs: {
26
+ image: { kind: "data", type: "image" },
27
+ asset: { kind: "data", type: "asset" },
28
+ },
29
+ props: {
30
+ columns: { type: "int", default: 0, min: 0, max: 64, description: "0: as square as the count allows." },
31
+ gap: { type: "int", default: 16, min: 0, max: 512 },
32
+ background: { type: "color", default: [1, 1, 1, 1], label: "Background" },
33
+ cellWidth: { type: "int", default: 0, min: 0, max: 8192, description: "0: images at their own size. Otherwise each is scaled to fit this width." },
34
+ labels: { type: "string", default: "", description: "One label per line, in image order." },
35
+ labelSize: { type: "int", default: 14, min: 6, max: 128 },
36
+ labelColor: { type: "color", default: [0.1, 0.1, 0.1, 1], label: "Label Colour" },
37
+ filename: { type: "string", default: "contact-sheet.png", label: "Filename" },
38
+ },
39
+ };
40
+ export const colorDefinition = {
41
+ apiVersion: 1,
42
+ label: "Color",
43
+ description: "A solid colour.",
44
+ icon: "Square",
45
+ runsOn: "portable",
46
+ capabilities: ["assets"],
47
+ outputs: { image: { kind: "data", type: "image" } },
48
+ props: {
49
+ color: { type: "color", default: [1, 1, 1, 1], label: "Color" },
50
+ resolution: { type: "vec2i", default: [512, 512], min: 1, max: 4096, label: "Resolution" },
51
+ },
52
+ };
53
+ export const checkersDefinition = {
54
+ apiVersion: 1,
55
+ label: "Checkers",
56
+ description: "A checkerboard.",
57
+ icon: "Grid",
58
+ runsOn: "portable",
59
+ capabilities: ["assets"],
60
+ outputs: { image: { kind: "data", type: "image" } },
61
+ props: {
62
+ color1: { type: "color", default: [1, 1, 1, 1], label: "Color 1" },
63
+ color2: { type: "color", default: [0, 0, 0, 1], label: "Color 2" },
64
+ mode: {
65
+ type: "string", default: "size", label: "Mode", control: "select",
66
+ options: [{ value: "size", label: "Size" }, { value: "divisions", label: "Divisions" }],
67
+ },
68
+ size: { type: "float", default: 32, min: 1, max: 512, step: 0.1, label: "Size", description: "Cell size in pixels (mode Size)." },
69
+ divisions: { type: "int", default: 16, min: 1, max: 512, step: 1, label: "Divisions", description: "Cells across (mode Divisions)." },
70
+ centered: { type: "bool", default: false, label: "Centered" },
71
+ resolution: { type: "vec2i", default: [512, 512], min: 1, max: 4096, label: "Resolution" },
72
+ },
73
+ };
74
+ export const noiseDefinition = {
75
+ apiVersion: 1,
76
+ label: "Noise",
77
+ description: "Fractal simplex noise, grey.",
78
+ icon: "Cloud",
79
+ runsOn: "portable",
80
+ capabilities: ["assets"],
81
+ outputs: { image: { kind: "data", type: "image" } },
82
+ props: {
83
+ seed: { type: "int", default: 0, min: 0, max: 10000, step: 1, label: "Seed" },
84
+ scale: { type: "float", default: 0.01, min: 0.001, max: 1, step: 0.001, label: "Scale" },
85
+ iterations: { type: "int", default: 4, min: 1, max: 8, step: 1, label: "Iterations" },
86
+ resolution: { type: "vec2i", default: [512, 512], min: 1, max: 4096, label: "Resolution" },
87
+ },
88
+ };
89
+ export const rampDefinition = {
90
+ apiVersion: 1,
91
+ label: "Ramp",
92
+ description: "A colour ramp: horizontal, vertical, radial or concentric.",
93
+ icon: "Gradient",
94
+ runsOn: "portable",
95
+ capabilities: ["assets"],
96
+ outputs: { image: { kind: "data", type: "image" } },
97
+ props: {
98
+ type: {
99
+ type: "string", default: "horizontal", label: "Type", control: "select",
100
+ options: [
101
+ { value: "horizontal", label: "Horizontal" },
102
+ { value: "vertical", label: "Vertical" },
103
+ { value: "radial", label: "Radial" },
104
+ { value: "concentric", label: "Concentric" },
105
+ ],
106
+ },
107
+ points: {
108
+ type: "array",
109
+ label: "Ramp",
110
+ description: "{ position, color, interpolation: linear | smooth | constant } stops.",
111
+ default: [
112
+ { position: 0, color: { r: 0, g: 0, b: 0 }, interpolation: "linear" },
113
+ { position: 1, color: { r: 1, g: 1, b: 1 }, interpolation: "linear" },
114
+ ],
115
+ },
116
+ resolution: { type: "vec2i", default: [512, 512], min: 1, max: 4096, label: "Resolution" },
117
+ },
118
+ };
119
+ export const textDefinition = {
120
+ apiVersion: 1,
121
+ label: "Text",
122
+ description: "Text drawn with a CSS font family, or a font file from the project.",
123
+ icon: "Type",
124
+ runsOn: "portable",
125
+ capabilities: ["assets"],
126
+ outputs: { image: { kind: "data", type: "image" } },
127
+ props: {
128
+ text: { type: "string", default: "Hello, World!", label: "Text", control: "textarea" },
129
+ font: {
130
+ type: "string", default: "Inter, system-ui, sans-serif", label: "Font",
131
+ description: "A CSS font family list, or a project font file (.otf, .ttf, .woff, .woff2); a file that is not there falls back to sans-serif.",
132
+ },
133
+ fontSize: { type: "float", default: 48, min: 1, max: 500, step: 1, label: "Font Size", control: "slider" },
134
+ fontWeight: {
135
+ type: "string", default: "normal", label: "Font Weight", control: "select",
136
+ options: [
137
+ { value: "normal", label: "Normal" },
138
+ { value: "bold", label: "Bold" },
139
+ { value: "100", label: "Thin (100)" },
140
+ { value: "200", label: "Extra Light (200)" },
141
+ { value: "300", label: "Light (300)" },
142
+ { value: "500", label: "Medium (500)" },
143
+ { value: "600", label: "Semi Bold (600)" },
144
+ { value: "700", label: "Bold (700)" },
145
+ { value: "800", label: "Extra Bold (800)" },
146
+ { value: "900", label: "Black (900)" },
147
+ ],
148
+ },
149
+ fontStyle: {
150
+ type: "string", default: "normal", label: "Font Style", control: "select",
151
+ options: [{ value: "normal", label: "Normal" }, { value: "italic", label: "Italic" }, { value: "oblique", label: "Oblique" }],
152
+ },
153
+ alignH: {
154
+ type: "string", default: "center", label: "Horizontal Align", control: "select",
155
+ options: [{ value: "left", label: "Left" }, { value: "center", label: "Center" }, { value: "right", label: "Right" }],
156
+ },
157
+ alignV: {
158
+ type: "string", default: "middle", label: "Vertical Align", control: "select",
159
+ options: [{ value: "top", label: "Top" }, { value: "middle", label: "Middle" }, { value: "bottom", label: "Bottom" }],
160
+ },
161
+ color: { type: "color", default: [1, 1, 1, 1], label: "Color" },
162
+ backgroundColor: { type: "color", default: [0, 0, 0, 0], label: "Background" },
163
+ resolution: { type: "vec2i", default: [512, 512], min: 1, max: 4096, label: "Resolution" },
164
+ offset: { type: "vec2", default: [0, 0], min: -2048, max: 2048, step: 1, label: "Offset" },
165
+ rotation: { type: "float", default: 0, min: -180, max: 180, step: 0.1, label: "Rotation", control: "slider" },
166
+ letterSpacing: { type: "float", default: 0, min: -50, max: 100, step: 0.5, label: "Letter Spacing", control: "slider" },
167
+ lineHeight: { type: "float", default: 1.2, min: 0.5, max: 3, step: 0.05, label: "Line Height", control: "slider" },
168
+ opacity: { type: "float", default: 1, min: 0, max: 1, step: 0.01, label: "Opacity", control: "slider" },
169
+ },
170
+ };
171
+ export const imageDefinition = {
172
+ apiVersion: 1,
173
+ label: "File",
174
+ description: "An image file from the project, or an image input, optionally resized.",
175
+ icon: "FileImage",
176
+ runsOn: "portable",
177
+ capabilities: ["assets"],
178
+ inputs: { image: { kind: "data", type: "image", description: "Used instead of the file when wired." } },
179
+ outputs: { image: { kind: "data", type: "image" } },
180
+ props: {
181
+ file: { type: "string", default: "", label: "File", description: "A project-relative image path." },
182
+ resolutionMode: {
183
+ type: "string", default: "original", label: "Resolution Mode", control: "select",
184
+ options: [{ value: "original", label: "Original" }, { value: "max", label: "Max Resolution" }, { value: "fixed", label: "Fixed Resolution" }],
185
+ },
186
+ maxResolution: { type: "vec2i", default: [2048, 2048], min: 1, max: 4096, label: "Max Resolution" },
187
+ fixedResolution: { type: "vec2i", default: [512, 512], min: 1, max: 4096, label: "Fixed Resolution" },
188
+ },
189
+ };
190
+ export const blurDefinition = {
191
+ apiVersion: 1,
192
+ label: "Blur",
193
+ description: "Box (three passes, fast) or true Gaussian blur.",
194
+ icon: "Droplets",
195
+ runsOn: "portable",
196
+ capabilities: ["assets"],
197
+ inputs: { image: { kind: "data", type: "image" } },
198
+ outputs: { image: { kind: "data", type: "image" } },
199
+ props: {
200
+ method: {
201
+ type: "string", default: "box", label: "Method", control: "select",
202
+ options: [{ value: "box", label: "Box (Fast)" }, { value: "gaussian", label: "Gaussian (Accurate)" }],
203
+ },
204
+ radius: { type: "float", default: 5, min: 0, max: 100, step: 0.1, label: "Radius" },
205
+ wrapEdges: { type: "bool", default: false, label: "Wrap Edges" },
206
+ },
207
+ };
208
+ export const normalMapDefinition = {
209
+ apiVersion: 1,
210
+ label: "Normal Map",
211
+ description: "A normal map from the red (or grey) channel as height.",
212
+ icon: "Box",
213
+ runsOn: "portable",
214
+ capabilities: ["assets"],
215
+ inputs: { image: { kind: "data", type: "image" } },
216
+ outputs: { image: { kind: "data", type: "image" } },
217
+ props: {
218
+ scale: { type: "float", default: 1, min: 0, max: 10, step: 0.1, label: "Scale" },
219
+ flipX: { type: "bool", default: false, label: "Flip X" },
220
+ flipY: { type: "bool", default: false, label: "Flip Y" },
221
+ },
222
+ };
223
+ export const resizeDefinition = {
224
+ apiVersion: 1,
225
+ label: "Resize",
226
+ description: "Scale an image, or resize it to a fixed size, bilinear.",
227
+ icon: "Maximize2",
228
+ runsOn: "portable",
229
+ capabilities: ["assets"],
230
+ inputs: { image: { kind: "data", type: "image" } },
231
+ outputs: { image: { kind: "data", type: "image" } },
232
+ props: {
233
+ mode: {
234
+ type: "string", default: "scale", label: "Mode", control: "select",
235
+ options: [{ value: "scale", label: "Scale" }, { value: "fixed", label: "Fixed" }],
236
+ },
237
+ scale: { type: "float", default: 1, min: 0.1, max: 10, step: 0.1, label: "Scale" },
238
+ width: { type: "int", default: 512, min: 1, max: 4096, step: 1, label: "Width" },
239
+ height: { type: "int", default: 512, min: 1, max: 4096, step: 1, label: "Height" },
240
+ },
241
+ };
242
+ export const transformDefinition = {
243
+ apiVersion: 1,
244
+ label: "Transform",
245
+ description: "Rotate, translate and scale an image about a pivot.",
246
+ icon: "Move",
247
+ runsOn: "portable",
248
+ capabilities: ["assets"],
249
+ inputs: { image: { kind: "data", type: "image" } },
250
+ outputs: { image: { kind: "data", type: "image" } },
251
+ props: {
252
+ translate: { type: "vec2", default: [0, 0], min: -2048, max: 2048, step: 1, label: "Translate" },
253
+ rotation: { type: "float", default: 0, min: -180, max: 180, step: 0.1, label: "Rotation" },
254
+ scale: { type: "vec2", default: [1, 1], min: 0.01, max: 10, step: 0.01, label: "Scale" },
255
+ uniformScale: { type: "bool", default: true, label: "Uniform Scale" },
256
+ pivot: {
257
+ type: "string", default: "center", label: "Pivot", control: "select",
258
+ options: [
259
+ { value: "center", label: "Center" },
260
+ { value: "top-left", label: "Top Left" },
261
+ { value: "top-right", label: "Top Right" },
262
+ { value: "bottom-left", label: "Bottom Left" },
263
+ { value: "bottom-right", label: "Bottom Right" },
264
+ { value: "custom", label: "Custom" },
265
+ ],
266
+ },
267
+ customPivot: { type: "vec2", default: [0.5, 0.5], min: 0, max: 1, step: 0.01, label: "Custom Pivot" },
268
+ filter: {
269
+ type: "string", default: "bilinear", label: "Filter", control: "select",
270
+ options: [{ value: "nearest", label: "Nearest" }, { value: "bilinear", label: "Bilinear" }],
271
+ },
272
+ wrap: {
273
+ type: "string", default: "clamp", label: "Wrap Mode", control: "select",
274
+ options: [
275
+ { value: "clamp", label: "Clamp" },
276
+ { value: "repeat", label: "Repeat" },
277
+ { value: "mirror", label: "Mirror" },
278
+ { value: "transparent", label: "Transparent" },
279
+ ],
280
+ },
281
+ },
282
+ };
283
+ export const compositeDefinition = {
284
+ apiVersion: 1,
285
+ label: "Composite",
286
+ description: "Blend image2 over image1.",
287
+ icon: "Layers",
288
+ runsOn: "portable",
289
+ capabilities: ["assets"],
290
+ inputs: {
291
+ image1: { kind: "data", type: "image" },
292
+ image2: { kind: "data", type: "image" },
293
+ },
294
+ outputs: { image: { kind: "data", type: "image" } },
295
+ props: {
296
+ blendMode: {
297
+ type: "string", default: "multiply", label: "Blend Mode", control: "select",
298
+ options: [
299
+ { value: "normal", label: "Normal" },
300
+ { value: "multiply", label: "Multiply" },
301
+ { value: "screen", label: "Screen" },
302
+ { value: "overlay", label: "Overlay" },
303
+ { value: "darken", label: "Darken" },
304
+ { value: "lighten", label: "Lighten" },
305
+ { value: "color-dodge", label: "Color Dodge" },
306
+ { value: "color-burn", label: "Color Burn" },
307
+ { value: "hard-light", label: "Hard Light" },
308
+ { value: "soft-light", label: "Soft Light" },
309
+ { value: "difference", label: "Difference" },
310
+ { value: "exclusion", label: "Exclusion" },
311
+ { value: "add", label: "Add" },
312
+ { value: "subtract", label: "Subtract" },
313
+ { value: "divide", label: "Divide" },
314
+ { value: "pin-light", label: "Pin Light" },
315
+ { value: "vivid-light", label: "Vivid Light" },
316
+ { value: "linear-dodge", label: "Linear Dodge" },
317
+ { value: "linear-burn", label: "Linear Burn" },
318
+ ],
319
+ },
320
+ opacity: { type: "float", default: 1, min: 0, max: 1, step: 0.01, label: "Opacity" },
321
+ outputResolution: {
322
+ type: "string", default: "input1", label: "Output Resolution", control: "select",
323
+ options: [
324
+ { value: "input1", label: "Use Input 1" },
325
+ { value: "input2", label: "Use Input 2" },
326
+ { value: "largest", label: "Largest Input" },
327
+ { value: "smallest", label: "Smallest Input" },
328
+ { value: "custom", label: "Custom" },
329
+ ],
330
+ },
331
+ customResolution: { type: "vec2i", default: [512, 512], min: 1, max: 4096, label: "Resolution" },
332
+ fitMode: {
333
+ type: "string", default: "fill", label: "Fit Mode", control: "select",
334
+ options: [
335
+ { value: "fill", label: "Fill (Crop)" },
336
+ { value: "fit", label: "Fit (Letterbox)" },
337
+ { value: "stretch", label: "Stretch" },
338
+ { value: "native", label: "Native (No Scale)" },
339
+ ],
340
+ },
341
+ },
342
+ };
343
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1,8 @@
1
+ import type { NodeExecutionContext } from "@field/cascade/contracts";
2
+ import type { imageDefinition } from "./definitions.js";
3
+ /**
4
+ * `cascade.image.Image` (labelled File): a project image, or the image wired
5
+ * into it, at its own size, within a maximum, or at a fixed size.
6
+ */
7
+ export declare function executeImage(context: NodeExecutionContext<typeof imageDefinition>): Promise<void>;
8
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1,37 @@
1
+ import { imageReference, output, readPlanar } from "./io.js";
2
+ import { resample } from "./planar.js";
3
+ /**
4
+ * `cascade.image.Image` (labelled File): a project image, or the image wired
5
+ * into it, at its own size, within a maximum, or at a fixed size.
6
+ */
7
+ export async function executeImage(context) {
8
+ const { props } = context;
9
+ const source = await readPlanar(context, imageReference(context.inputs.image) ?? imageReference(props.file));
10
+ if (!source)
11
+ return;
12
+ if (props.resolutionMode === "original") {
13
+ await output(context, source);
14
+ return;
15
+ }
16
+ if (props.resolutionMode === "max") {
17
+ const [maxWidth, maxHeight] = props.maxResolution;
18
+ const aspect = source.width / source.height;
19
+ let width = source.width;
20
+ let height = source.height;
21
+ if (width > maxWidth) {
22
+ width = maxWidth;
23
+ height = maxWidth / aspect;
24
+ }
25
+ if (height > maxHeight) {
26
+ height = maxHeight;
27
+ width = maxHeight * aspect;
28
+ }
29
+ width = Math.round(width);
30
+ height = Math.round(height);
31
+ await output(context, width !== source.width || height !== source.height ? resample(source, width, height) : source);
32
+ return;
33
+ }
34
+ const [width, height] = props.fixedResolution;
35
+ await output(context, resample(source, width, height));
36
+ }
37
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1,8 @@
1
+ import type { NodeExecutionContext } from "@field/cascade/contracts";
2
+ import type { blurDefinition, compositeDefinition, normalMapDefinition, resizeDefinition, transformDefinition } from "./definitions.js";
3
+ export declare function executeBlur(context: NodeExecutionContext<typeof blurDefinition>): Promise<void>;
4
+ export declare function executeNormalMap(context: NodeExecutionContext<typeof normalMapDefinition>): Promise<void>;
5
+ export declare function executeResize(context: NodeExecutionContext<typeof resizeDefinition>): Promise<void>;
6
+ export declare function executeTransform(context: NodeExecutionContext<typeof transformDefinition>): Promise<void>;
7
+ export declare function executeComposite(context: NodeExecutionContext<typeof compositeDefinition>): Promise<void>;
8
+ //# sourceMappingURL=filters.d.ts.map