@field/cascade 0.2.22 → 0.3.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 (228) hide show
  1. package/AGENTS.md +47 -7
  2. package/ARCHITECTURE.md +30 -2
  3. package/CHANGELOG.md +89 -0
  4. package/DESIGN.md +10 -5
  5. package/README.md +103 -7
  6. package/dist/assets/CodeEditor-BADFbTJS.js +623 -0
  7. package/dist/assets/CodePanel-faK6PRfz.js +2 -0
  8. package/dist/assets/CustomNodeDialog-DhlKuviy.js +1 -0
  9. package/dist/assets/{ExportDialog-DWN4nhXI.js → ExportDialog-BJu2Bpvv.js} +2 -2
  10. package/dist/assets/ProjectSettings-D6a6kjqR.js +2 -0
  11. package/dist/assets/SettingsDialog-DJZdIvLC.js +1 -0
  12. package/dist/assets/VersionHistoryDialog-C1X3HOhc.js +3 -0
  13. package/dist/assets/{core-Bji4aZUU.js → core-CiuiuWZi.js} +29 -38
  14. package/dist/assets/{cssMode-B6Z_Q1Kh.js → cssMode-D-NwZSMJ.js} +1 -1
  15. package/dist/assets/{editor.api-jMoW_43X.js → editor.api-DT3WEvBd.js} +1 -1
  16. package/dist/assets/{freemarker2-DvvPV6m5.js → freemarker2-eKNYQaiz.js} +1 -1
  17. package/dist/assets/geo-DUvVbLnx.js +1 -0
  18. package/dist/assets/{handlebars-B8rfuSIa.js → handlebars-C2w1ggK2.js} +1 -1
  19. package/dist/assets/{html-DyHm6JCp.js → html-DQb41jyo.js} +1 -1
  20. package/dist/assets/{htmlMode-E9XLWE5u.js → htmlMode-IhNlh6Lv.js} +1 -1
  21. package/dist/assets/{image-BUcQC7PG.js → image-DMCXBY-_.js} +26 -40
  22. package/dist/assets/index-BDV5xGBZ.css +1 -0
  23. package/dist/assets/index-HTCN44kj.js +212 -0
  24. package/dist/assets/index-client-BoJgsN9M.js +1 -0
  25. package/dist/assets/{javascript-C_bM5PCN.js → javascript-BIT6jMLC.js} +1 -1
  26. package/dist/assets/{jsonMode-BdyVS7G4.js → jsonMode-CNfyB1ro.js} +1 -1
  27. package/dist/assets/{legacy-DIu3XRwl.js → legacy-CAj2_7QE.js} +2 -2
  28. package/dist/assets/{liquid-CDkn3spA.js → liquid-CmSmJmOG.js} +1 -1
  29. package/dist/assets/{lspLanguageFeatures-AB5DMAsr.js → lspLanguageFeatures-BqMm3uMP.js} +1 -1
  30. package/dist/assets/{mdx-BvH_NjDN.js → mdx-6r6YgOFw.js} +1 -1
  31. package/dist/assets/{nodeTypeUtils-CweA3NHd.js → nodeTypeUtils-BBA1JqHx.js} +1 -1
  32. package/dist/assets/{python-B7uii4fi.js → python-x1H0TQuI.js} +1 -1
  33. package/dist/assets/{razor-Z48fWdJc.js → razor-Dzl1vZFm.js} +1 -1
  34. package/dist/assets/{tsMode-BDgacVG4.js → tsMode-n6DMMe3a.js} +1 -1
  35. package/dist/assets/{typescript-Derb6Oqa.js → typescript-ziEz65xN.js} +1 -1
  36. package/dist/assets/{workers-BtoMX_pm.js → workers-D-qUdp-r.js} +1 -1
  37. package/dist/assets/{xml-B1CaFSrG.js → xml-DMZjt5lE.js} +1 -1
  38. package/dist/assets/{yaml-HmIeA0KH.js → yaml-DFe5qZSO.js} +1 -1
  39. package/dist/cli/index.js +16194 -10195
  40. package/dist/cli/runtime/io.ts +93 -7
  41. package/dist/contracts/animation.d.ts +40 -0
  42. package/dist/contracts/animation.js +14 -0
  43. package/dist/contracts/definition.d.ts +39 -1
  44. package/dist/contracts/document.d.ts +15 -0
  45. package/dist/contracts/index.d.ts +1 -0
  46. package/dist/contracts/index.js +1 -0
  47. package/dist/contracts/validate.d.ts +10 -1
  48. package/dist/contracts/validate.js +9 -1
  49. package/dist/graphs/default.cascade +1 -1
  50. package/dist/index.html +5 -5
  51. package/dist/io.d.ts +196 -0
  52. package/dist/io.js +303 -0
  53. package/dist/net.d.ts +1 -0
  54. package/dist/net.js +28 -0
  55. package/dist/runtime/animation/channel.d.ts +108 -0
  56. package/dist/runtime/animation/channel.js +204 -0
  57. package/dist/runtime/animation/frameRange.d.ts +78 -0
  58. package/dist/runtime/animation/frameRange.js +76 -0
  59. package/dist/runtime/animation/index.d.ts +10 -0
  60. package/dist/runtime/animation/index.js +8 -0
  61. package/dist/runtime/builtins/core/random.d.ts +1 -1
  62. package/dist/runtime/builtins/core/remap.d.ts +1 -1
  63. package/dist/runtime/builtins/geo/copyToPoints.d.ts +1 -1
  64. package/dist/runtime/builtins/geo/copyToPoints.js +1 -1
  65. package/dist/runtime/builtins/geo/generators.d.ts +1 -1
  66. package/dist/runtime/builtins/geo/merge.d.ts +1 -1
  67. package/dist/runtime/builtins/geo/svgExport.d.ts +1 -1
  68. package/dist/runtime/builtins/geo/svgExport.js +1 -1
  69. package/dist/runtime/builtins/geo/transform.d.ts +1 -1
  70. package/dist/runtime/builtins/geo/transform.js +1 -1
  71. package/dist/runtime/definition/architecture.d.ts +1 -1
  72. package/dist/runtime/definition/extract.d.ts +1 -1
  73. package/dist/runtime/definition/extract.js +1 -1
  74. package/dist/runtime/error.d.ts +1 -1
  75. package/dist/runtime/expressions/evaluator.d.ts +53 -0
  76. package/dist/runtime/expressions/evaluator.js +193 -0
  77. package/dist/runtime/expressions/index.d.ts +15 -0
  78. package/dist/runtime/expressions/index.js +12 -0
  79. package/dist/runtime/expressions/math.d.ts +75 -0
  80. package/dist/runtime/expressions/math.js +140 -0
  81. package/dist/runtime/expressions/preprocess.d.ts +33 -0
  82. package/dist/runtime/expressions/preprocess.js +102 -0
  83. package/dist/runtime/expressions/scope.d.ts +27 -0
  84. package/dist/runtime/expressions/scope.js +10 -0
  85. package/dist/runtime/expressions/time.d.ts +54 -0
  86. package/dist/runtime/expressions/time.js +71 -0
  87. package/dist/runtime/expressions/types.d.ts +66 -0
  88. package/dist/runtime/expressions/types.js +9 -0
  89. package/dist/runtime/geometry/attributes.d.ts +2 -2
  90. package/dist/runtime/geometry/attributes.js +1 -1
  91. package/dist/runtime/geometry/builder.d.ts +1 -1
  92. package/dist/runtime/geometry/builder.js +1 -1
  93. package/dist/runtime/geometry/copy.d.ts +1 -1
  94. package/dist/runtime/geometry/copy.js +1 -1
  95. package/dist/runtime/geometry/generate.d.ts +1 -1
  96. package/dist/runtime/geometry/groups.d.ts +1 -1
  97. package/dist/runtime/geometry/groups.js +1 -1
  98. package/dist/runtime/geometry/matrix.d.ts +1 -1
  99. package/dist/runtime/geometry/merge.d.ts +1 -1
  100. package/dist/runtime/geometry/merge.js +1 -1
  101. package/dist/runtime/geometry/primitives.d.ts +1 -1
  102. package/dist/runtime/geometry/primitives.js +1 -1
  103. package/dist/runtime/geometry/promote.d.ts +1 -1
  104. package/dist/runtime/geometry/promote.js +1 -1
  105. package/dist/runtime/geometry/resample.d.ts +1 -1
  106. package/dist/runtime/geometry/resample.js +1 -1
  107. package/dist/runtime/geometry/svg.d.ts +1 -1
  108. package/dist/runtime/geometry/svg.js +1 -1
  109. package/dist/runtime/geometry/transform.d.ts +1 -1
  110. package/dist/runtime/geometry/transform.js +1 -1
  111. package/dist/runtime/index.d.ts +4 -1
  112. package/dist/runtime/index.js +4 -1
  113. package/dist/runtime/params/animator.d.ts +74 -0
  114. package/dist/runtime/params/animator.js +137 -0
  115. package/dist/runtime/params/index.d.ts +11 -0
  116. package/dist/runtime/params/index.js +9 -0
  117. package/dist/runtime/params/resolve.d.ts +73 -0
  118. package/dist/runtime/params/resolve.js +62 -0
  119. package/dist/runtime/runtime.d.ts +22 -0
  120. package/dist/runtime/runtime.js +242 -14
  121. package/dist/runtime/types.d.ts +30 -4
  122. package/dist/shell.d.ts +3 -3
  123. package/doc/NODE_REFERENCE.md +395 -0
  124. package/doc/PROJECT_AUTHORING.md +148 -6
  125. package/package.json +26 -3
  126. package/dist/assets/CodeEditor-DoaNEUaM.js +0 -641
  127. package/dist/assets/CodePanel-B0_2XJ-t.js +0 -2
  128. package/dist/assets/CustomNodeDialog-026lzecD.js +0 -1
  129. package/dist/assets/ProjectSettings-BzT164Yx.js +0 -2
  130. package/dist/assets/SettingsDialog-DmHb1V0r.js +0 -1
  131. package/dist/assets/VersionHistoryDialog-hH6VsXLX.js +0 -3
  132. package/dist/assets/geo-CXmCtzMM.js +0 -2
  133. package/dist/assets/index-BXYXSdgh.js +0 -224
  134. package/dist/assets/index-CrNke7SW.css +0 -1
  135. package/dist/assets/index-client-DN_FvjN8.js +0 -1
  136. package/dist/assets/quill-DjZ69wL_.js +0 -121
  137. package/dist/cli/index.js.map +0 -7
  138. package/dist/contracts/capabilities.d.ts.map +0 -1
  139. package/dist/contracts/capabilities.js.map +0 -1
  140. package/dist/contracts/color.d.ts.map +0 -1
  141. package/dist/contracts/color.js.map +0 -1
  142. package/dist/contracts/definition.d.ts.map +0 -1
  143. package/dist/contracts/definition.js.map +0 -1
  144. package/dist/contracts/document.d.ts.map +0 -1
  145. package/dist/contracts/document.js.map +0 -1
  146. package/dist/contracts/geometry.d.ts.map +0 -1
  147. package/dist/contracts/geometry.js.map +0 -1
  148. package/dist/contracts/index.d.ts.map +0 -1
  149. package/dist/contracts/index.js.map +0 -1
  150. package/dist/contracts/schema.d.ts.map +0 -1
  151. package/dist/contracts/schema.js.map +0 -1
  152. package/dist/contracts/validate.d.ts.map +0 -1
  153. package/dist/contracts/validate.js.map +0 -1
  154. package/dist/contracts/values.d.ts.map +0 -1
  155. package/dist/contracts/values.js.map +0 -1
  156. package/dist/graphs/default-orig.cascade +0 -128
  157. package/dist/runtime/browser.d.ts.map +0 -1
  158. package/dist/runtime/browser.js.map +0 -1
  159. package/dist/runtime/builtins/core/index.d.ts.map +0 -1
  160. package/dist/runtime/builtins/core/index.js.map +0 -1
  161. package/dist/runtime/builtins/core/random.d.ts.map +0 -1
  162. package/dist/runtime/builtins/core/random.js.map +0 -1
  163. package/dist/runtime/builtins/core/remap.d.ts.map +0 -1
  164. package/dist/runtime/builtins/core/remap.js.map +0 -1
  165. package/dist/runtime/builtins/core/routing.d.ts.map +0 -1
  166. package/dist/runtime/builtins/core/routing.js.map +0 -1
  167. package/dist/runtime/builtins/core/structural.d.ts.map +0 -1
  168. package/dist/runtime/builtins/core/structural.js.map +0 -1
  169. package/dist/runtime/builtins/geo/copyToPoints.d.ts.map +0 -1
  170. package/dist/runtime/builtins/geo/copyToPoints.js.map +0 -1
  171. package/dist/runtime/builtins/geo/definitions.d.ts.map +0 -1
  172. package/dist/runtime/builtins/geo/definitions.js.map +0 -1
  173. package/dist/runtime/builtins/geo/generators.d.ts.map +0 -1
  174. package/dist/runtime/builtins/geo/generators.js.map +0 -1
  175. package/dist/runtime/builtins/geo/index.d.ts.map +0 -1
  176. package/dist/runtime/builtins/geo/index.js.map +0 -1
  177. package/dist/runtime/builtins/geo/merge.d.ts.map +0 -1
  178. package/dist/runtime/builtins/geo/merge.js.map +0 -1
  179. package/dist/runtime/builtins/geo/namespace.d.ts.map +0 -1
  180. package/dist/runtime/builtins/geo/namespace.js.map +0 -1
  181. package/dist/runtime/builtins/geo/svgExport.d.ts.map +0 -1
  182. package/dist/runtime/builtins/geo/svgExport.js.map +0 -1
  183. package/dist/runtime/builtins/geo/transform.d.ts.map +0 -1
  184. package/dist/runtime/builtins/geo/transform.js.map +0 -1
  185. package/dist/runtime/builtins/index.d.ts.map +0 -1
  186. package/dist/runtime/builtins/index.js.map +0 -1
  187. package/dist/runtime/definition/architecture.d.ts.map +0 -1
  188. package/dist/runtime/definition/architecture.js.map +0 -1
  189. package/dist/runtime/definition/extract.d.ts.map +0 -1
  190. package/dist/runtime/definition/extract.js.map +0 -1
  191. package/dist/runtime/error.d.ts.map +0 -1
  192. package/dist/runtime/error.js.map +0 -1
  193. package/dist/runtime/geometry/attributes.d.ts.map +0 -1
  194. package/dist/runtime/geometry/attributes.js.map +0 -1
  195. package/dist/runtime/geometry/builder.d.ts.map +0 -1
  196. package/dist/runtime/geometry/builder.js.map +0 -1
  197. package/dist/runtime/geometry/copy.d.ts.map +0 -1
  198. package/dist/runtime/geometry/copy.js.map +0 -1
  199. package/dist/runtime/geometry/generate.d.ts.map +0 -1
  200. package/dist/runtime/geometry/generate.js.map +0 -1
  201. package/dist/runtime/geometry/groups.d.ts.map +0 -1
  202. package/dist/runtime/geometry/groups.js.map +0 -1
  203. package/dist/runtime/geometry/index.d.ts.map +0 -1
  204. package/dist/runtime/geometry/index.js.map +0 -1
  205. package/dist/runtime/geometry/matrix.d.ts.map +0 -1
  206. package/dist/runtime/geometry/matrix.js.map +0 -1
  207. package/dist/runtime/geometry/merge.d.ts.map +0 -1
  208. package/dist/runtime/geometry/merge.js.map +0 -1
  209. package/dist/runtime/geometry/primitives.d.ts.map +0 -1
  210. package/dist/runtime/geometry/primitives.js.map +0 -1
  211. package/dist/runtime/geometry/promote.d.ts.map +0 -1
  212. package/dist/runtime/geometry/promote.js.map +0 -1
  213. package/dist/runtime/geometry/resample.d.ts.map +0 -1
  214. package/dist/runtime/geometry/resample.js.map +0 -1
  215. package/dist/runtime/geometry/svg.d.ts.map +0 -1
  216. package/dist/runtime/geometry/svg.js.map +0 -1
  217. package/dist/runtime/geometry/transform.d.ts.map +0 -1
  218. package/dist/runtime/geometry/transform.js.map +0 -1
  219. package/dist/runtime/index.d.ts.map +0 -1
  220. package/dist/runtime/index.js.map +0 -1
  221. package/dist/runtime/node.d.ts.map +0 -1
  222. package/dist/runtime/node.js.map +0 -1
  223. package/dist/runtime/runtime.d.ts.map +0 -1
  224. package/dist/runtime/runtime.js.map +0 -1
  225. package/dist/runtime/types.d.ts.map +0 -1
  226. package/dist/runtime/types.js.map +0 -1
  227. package/dist/shell.js.map +0 -7
  228. package/dist/stage.js.map +0 -7
@@ -1,5 +1,5 @@
1
- import{c as e,o as t}from"./nodeTypeUtils-CweA3NHd.js";import{E as n,T as r,_ as i,g as a,o}from"./index-BXYXSdgh.js";var s=class extends o{constructor(e,t){super(e,`Color`,t)}setup(){this.addParm(`color`,{value:{r:1,g:1,b:1},type:`color`,displayName:`Color`}),this.addResolutionParm(),this.output=this.out(`image`),this.watchProp(`color`,()=>this.requestCook()),this.onReady=()=>this.requestCook()}render(){let[e,t]=this.getResolution(),r=n(this.props.color.value),a=i.solid(e,t,r);this.setOutput(this.output,a)}},c=class extends o{constructor(e,t){super(e,`File`,t)}setup(){this.imageInput=this.in(`image`,null),this.addParm(`file`,{value:``,type:`image`,params:{accept:`image/*`},displayName:`File`,onChange:()=>{this.props.file.value&&!this.imageInput.value&&this.requestCook()}}),this.addParm(`resolutionMode`,{value:`original`,params:{options:[{value:`original`,label:`Original`},{value:`max`,label:`Max Resolution`},{value:`fixed`,label:`Fixed Resolution`}]},displayName:`Resolution Mode`,onChange:()=>{(this.props.file.value||this.imageInput.value)&&this.requestCook()}}),this.addParm(`maxResolution`,{value:[2048,2048],params:{min:[1,1],max:[4096,4096]},displayName:`Max Resolution`,hidden:()=>this.props.resolutionMode.value!==`max`,onChange:()=>{(this.props.file.value||this.imageInput.value)&&this.props.resolutionMode.value===`max`&&this.requestCook()}}),this.addParm(`fixedResolution`,{value:[512,512],params:{min:[1,1],max:[4096,4096]},displayName:`Fixed Resolution`,hidden:()=>this.props.resolutionMode.value!==`fixed`,onChange:()=>{(this.props.file.value||this.imageInput.value)&&this.props.resolutionMode.value===`fixed`&&this.requestCook()}}),this.output=this.out(`image`),this.imageInput.onChange=()=>this.requestCook(),this.onReady=()=>{(this.props.file.value||this.imageInput.value)&&this.requestCook()}}async render(){let e=null;if(this.imageInput.value){if(this.imageInput.value instanceof i)e=this.imageInput.value;else if(this.imageInput.value instanceof HTMLImageElement||this.imageInput.value instanceof HTMLCanvasElement)e=i.fromCanvas(this.imageInput.value);else if(typeof this.imageInput.value==`string`){let t=new Image;t.crossOrigin=`anonymous`,await new Promise((e,n)=>{t.onload=()=>e(),t.onerror=n,t.src=this.imageInput.value}),e=i.fromCanvas(t)}}else if(this.props.file.value){let t=new Image;t.crossOrigin=`anonymous`,await new Promise((e,n)=>{t.onload=()=>e(),t.onerror=n,t.src=this.props.file.value}),e=i.fromCanvas(t)}if(e)try{let t=this.props.resolutionMode.value,n;if(t===`original`)n=e;else if(t===`max`){let[t,r]=this.props.maxResolution.value,i=e.width/e.height,a=e.width,o=e.height;a>t&&(a=t,o=t/i),o>r&&(o=r,a=r*i),a=Math.round(a),o=Math.round(o),n=a!==e.width||o!==e.height?this.resizeBuffer(e,a,o):e}else{let[t,r]=this.props.fixedResolution.value;n=this.resizeBuffer(e,t,r)}this.setOutput(this.output,n)}catch(e){this.error=e,console.error(`Failed to process image:`,e)}}resizeBuffer(e,t,n){let r=i.rgba(t,n),a=e.width/t,o=e.height/n;for(let i=0;i<Math.min(e.channelCount,4);i++){let s=r.channels[i];for(let r=0;r<n;r++)for(let n=0;n<t;n++){let c=n*a,l=r*o;s[r*t+n]=e.sample(c,l,i)}}return e.channelCount<4&&r.fill(3,1),r}},l=class extends o{constructor(e,t){super(e,`Composite`,t)}setup(){this.image1=this.in(`image1`,null),this.image2=this.in(`image2`,null),this.addParm(`blendMode`,{value:`multiply`,params:{options:[{value:`normal`,label:`Normal`},{value:`multiply`,label:`Multiply`},{value:`screen`,label:`Screen`},{value:`overlay`,label:`Overlay`},{value:`darken`,label:`Darken`},{value:`lighten`,label:`Lighten`},{value:`color-dodge`,label:`Color Dodge`},{value:`color-burn`,label:`Color Burn`},{value:`hard-light`,label:`Hard Light`},{value:`soft-light`,label:`Soft Light`},{value:`difference`,label:`Difference`},{value:`exclusion`,label:`Exclusion`},{value:`add`,label:`Add`},{value:`subtract`,label:`Subtract`},{value:`divide`,label:`Divide`},{value:`pin-light`,label:`Pin Light`},{value:`vivid-light`,label:`Vivid Light`},{value:`linear-dodge`,label:`Linear Dodge`},{value:`linear-burn`,label:`Linear Burn`}]},displayName:`Blend Mode`,onChange:()=>this.requestCook()}),this.addParm(`opacity`,{value:1,params:{min:0,max:1,step:.01},displayName:`Opacity`,onChange:()=>this.requestCook()}),this.addParm(`outputResolution`,{value:`input1`,params:{options:[{value:`input1`,label:`Use Input 1`},{value:`input2`,label:`Use Input 2`},{value:`largest`,label:`Largest Input`},{value:`smallest`,label:`Smallest Input`},{value:`custom`,label:`Custom`}]},displayName:`Output Resolution`,onChange:()=>this.requestCook()}),this.addParm(`customResolution`,{value:[512,512],params:{min:[1,1],max:[4096,4096],integer:!0},displayName:`Resolution`,hidden:()=>this.props.outputResolution.value!==`custom`,onChange:()=>this.requestCook()}),this.addParm(`fitMode`,{value:`fill`,params:{options:[{value:`fill`,label:`Fill (Crop)`},{value:`fit`,label:`Fit (Letterbox)`},{value:`stretch`,label:`Stretch`},{value:`native`,label:`Native (No Scale)`}]},displayName:`Fit Mode`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.image1.onChange=()=>this.requestCook(),this.image2.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}blendBuffers(e,t,n,r){let a=e.width,o=e.height,s=i.rgba(a,o),c=e.channelCount>=4?e:e.toRGBA(),l=t.channelCount>=4?t:t.toRGBA(),u=c.channels[0],d=c.channels[1],f=c.channels[2],p=c.channels[3],m=l.channels[0],h=l.channels[1],g=l.channels[2],_=l.channels[3],v=s.channels[0],y=s.channels[1],b=s.channels[2],x=s.channels[3];for(let e=0;e<a*o;e++){let t=u[e],i=d[e],a=f[e],o=p[e],s=m[e],c=h[e],l=g[e],S=_[e],C,w,T;switch(n){case`normal`:C=s,w=c,T=l;break;case`multiply`:C=t*s,w=i*c,T=a*l;break;case`screen`:C=1-(1-t)*(1-s),w=1-(1-i)*(1-c),T=1-(1-a)*(1-l);break;case`overlay`:C=t<.5?2*t*s:1-2*(1-t)*(1-s),w=i<.5?2*i*c:1-2*(1-i)*(1-c),T=a<.5?2*a*l:1-2*(1-a)*(1-l);break;case`darken`:C=Math.min(t,s),w=Math.min(i,c),T=Math.min(a,l);break;case`lighten`:C=Math.max(t,s),w=Math.max(i,c),T=Math.max(a,l);break;case`color-dodge`:C=s===1?1:Math.min(1,t/(1-s)),w=c===1?1:Math.min(1,i/(1-c)),T=l===1?1:Math.min(1,a/(1-l));break;case`color-burn`:C=s===0?0:Math.max(0,1-(1-t)/s),w=c===0?0:Math.max(0,1-(1-i)/c),T=l===0?0:Math.max(0,1-(1-a)/l);break;case`hard-light`:C=s<.5?2*t*s:1-2*(1-t)*(1-s),w=c<.5?2*i*c:1-2*(1-i)*(1-c),T=l<.5?2*a*l:1-2*(1-a)*(1-l);break;case`soft-light`:C=s<.5?t-(1-2*s)*t*(1-t):t+(2*s-1)*(Math.sqrt(t)-t),w=c<.5?i-(1-2*c)*i*(1-i):i+(2*c-1)*(Math.sqrt(i)-i),T=l<.5?a-(1-2*l)*a*(1-a):a+(2*l-1)*(Math.sqrt(a)-a);break;case`difference`:C=Math.abs(t-s),w=Math.abs(i-c),T=Math.abs(a-l);break;case`exclusion`:C=t+s-2*t*s,w=i+c-2*i*c,T=a+l-2*a*l;break;case`add`:C=Math.min(1,t+s),w=Math.min(1,i+c),T=Math.min(1,a+l);break;case`subtract`:C=Math.max(0,t-s),w=Math.max(0,i-c),T=Math.max(0,a-l);break;case`divide`:C=s===0?1:Math.min(1,t/s),w=c===0?1:Math.min(1,i/c),T=l===0?1:Math.min(1,a/l);break;case`pin-light`:C=s<.5?Math.min(t,2*s):Math.max(t,2*(s-.5)),w=c<.5?Math.min(i,2*c):Math.max(i,2*(c-.5)),T=l<.5?Math.min(a,2*l):Math.max(a,2*(l-.5));break;case`vivid-light`:C=s<.5?s===0?0:1-(1-t)/(2*s):s===1?1:t/(2*(1-s)),w=c<.5?c===0?0:1-(1-i)/(2*c):c===1?1:i/(2*(1-c)),T=l<.5?l===0?0:1-(1-a)/(2*l):l===1?1:a/(2*(1-l));break;case`linear-dodge`:C=Math.min(1,t+s),w=Math.min(1,i+c),T=Math.min(1,a+l);break;case`linear-burn`:C=Math.max(0,t+s-1),w=Math.max(0,i+c-1),T=Math.max(0,a+l-1);break;default:C=s,w=c,T=l}v[e]=t+(C-t)*r*S,y[e]=i+(w-i)*r*S,b[e]=a+(T-a)*r*S,x[e]=o+(S-o)*r}return s}render(){let e=this.props.outputResolution.value,t=this.props.fitMode.value,n=this.props.customResolution.value,{buffers:r}=this.prepareInputs([this.image1.value,this.image2.value],e,t,n),[i,a]=r;if(!i||!a)return;let o=this.props.blendMode.value,s=this.props.opacity.value;try{let e=this.blendBuffers(i,a,o,s);this.setOutput(this.output,e)}catch(e){console.error(`Composite render error:`,e),this.error=e}}},u=class extends o{constructor(e,t){super(e,`Checkers`,t)}setup(){this.addParm(`color1`,{value:{r:1,g:1,b:1},type:`color`,displayName:`Color 1`,onChange:()=>this.requestCook()}),this.addParm(`color2`,{value:{r:0,g:0,b:0},type:`color`,displayName:`Color 2`,onChange:()=>this.requestCook()}),this.addParm(`mode`,{value:`size`,params:{options:[{value:`size`,label:`Size`},{value:`divisions`,label:`Divisions`}]},displayName:`Mode`,onChange:()=>this.requestCook()}),this.addParm(`size`,{value:32,params:{min:1,max:512,step:.1},displayName:`Size`,hidden:()=>this.props.mode.value!==`size`,onChange:()=>this.requestCook()}),this.addParm(`divisions`,{value:16,params:{min:1,max:512,step:1,integer:!0},displayName:`Divisions`,hidden:()=>this.props.mode.value!==`divisions`,onChange:()=>this.requestCook()}),this.addParm(`centered`,{value:!1,type:`boolean`,displayName:`Centered`,onChange:()=>this.requestCook()}),this.addResolutionParm(),this.output=this.out(`image`),this.onReady=()=>this.requestCook()}render(){let[e,t]=this.getResolution(),r=this.props.mode.value,a=n(this.props.color1.value),o=n(this.props.color2.value),s=this.props.centered.value,c;c=r===`size`?this.props.size.value:e/this.props.divisions.value;let l=0,u=0;s&&(l=e/2%c-c/2,u=t/2%c-c/2);let d=i.rgba(e,t),f=d.r(),p=d.g(),m=d.b(),h=d.a();for(let n=0;n<t;n++)for(let t=0;t<e;t++){let r=n*e+t,i=(Math.floor((t-l)/c)+Math.floor((n-u)/c))%2==0?a:o;f[r]=i.r,p[r]=i.g,m[r]=i.b,h[r]=i.a}d.markDirty(),this.setOutput(this.output,d)}},d=class extends o{constructor(e,t){super(e,`Resize`,t)}setup(){this.image=this.in(`image`,null),this.addParm(`mode`,{value:`scale`,params:{options:[{value:`scale`,label:`Scale`},{value:`fixed`,label:`Fixed`}]},displayName:`Mode`,onChange:()=>this.requestCook()}),this.addParm(`scale`,{value:1,params:{min:.1,max:10,step:.1},displayName:`Scale`,hidden:()=>this.props.mode.value!==`scale`,onChange:()=>this.requestCook()}),this.addParm(`width`,{value:512,params:{min:1,max:4096,step:1},displayName:`Width`,hidden:()=>this.props.mode.value!==`fixed`,onChange:()=>this.requestCook()}),this.addParm(`height`,{value:512,params:{min:1,max:4096,step:1},displayName:`Height`,hidden:()=>this.props.mode.value!==`fixed`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.image.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}resizeBuffer(e,t,n){let r=i.rgba(t,n),a=e.width/t,o=e.height/n;for(let i=0;i<Math.min(e.channelCount,4);i++){let s=r.channels[i];for(let r=0;r<n;r++)for(let n=0;n<t;n++){let c=n*a,l=r*o;s[r*t+n]=e.sample(c,l,i)}}return e.channelCount<4&&r.fill(3,1),r}render(){let e=this.toImageBuffer(this.image.value);if(!e)return;let t,n;if(this.props.mode.value===`scale`){let r=this.props.scale.value;t=Math.round(e.width*r),n=Math.round(e.height*r)}else t=this.props.width.value,n=this.props.height.value;let r=this.resizeBuffer(e,t,n);this.setOutput(this.output,r)}},f=class extends o{constructor(e,t){super(e,`NormalMap`,t)}setup(){this.image=this.in(`image`,null),this.addParm(`scale`,{value:1,params:{min:0,max:10,step:.1},displayName:`Scale`,onChange:()=>this.requestCook()}),this.addParm(`flipX`,{value:!1,type:`boolean`,displayName:`Flip X`,onChange:()=>this.requestCook()}),this.addParm(`flipY`,{value:!1,type:`boolean`,displayName:`Flip Y`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.image.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}computeNormalMap(e,t,n,r){let{width:a,height:o}=e,s=i.rgba(a,o),c=e.channels[0],l=s.channels[0],u=s.channels[1],d=s.channels[2],f=s.channels[3];for(let e=0;e<o;e++)for(let i=0;i<a;i++){let s=e*a+i,p=c[s],m=c[Math.min(i+1,a-1)+e*a],h=c[i+Math.min(e+1,o-1)*a],g=(m-p)*t,_=(h-p)*t,v=n?-g:g,y=r?-_:_,b=-v,x=-y,S=Math.sqrt(b*b+x*x+1),C=b/S,w=x/S,T=1/S;l[s]=C*.5+.5,u[s]=w*.5+.5,d[s]=T*.5+.5,f[s]=1}return s}render(){let e=this.toImageBuffer(this.image.value);if(!e)return;let t=this.props.scale.value,n=this.props.flipX.value,r=this.props.flipY.value,i=this.computeNormalMap(e,t,n,r);this.setOutput(this.output,i)}},p=class extends o{constructor(e,t){super(e,`Ramp`,t)}setup(){this.addParm(`type`,{value:`horizontal`,params:{options:[{value:`horizontal`,label:`Horizontal`},{value:`vertical`,label:`Vertical`},{value:`radial`,label:`Radial`},{value:`concentric`,label:`Concentric`}]},displayName:`Type`,onChange:()=>this.requestCook()}),this.addParm(`points`,{value:[{position:0,color:{r:0,g:0,b:0},interpolation:`linear`},{position:1,color:{r:1,g:1,b:1},interpolation:`linear`}],type:`colorramp`,displayName:`Ramp`,onChange:()=>this.requestCook()}),this.addResolutionParm(),this.output=this.out(`image`),this.onReady=()=>this.requestCook()}normalizeRampColor(e){if(typeof e==`object`&&e&&`r`in e&&`g`in e&&`b`in e){let t=e.r<=1&&e.g<=1&&e.b<=1;return{r:t?e.r:e.r/255,g:t?e.g:e.g/255,b:t?e.b:e.b/255,a:e.a===void 0?1:t?e.a:e.a/255}}if(Array.isArray(e)){let t=e.every(e=>e<=1);return{r:t?e[0]:e[0]/255,g:t?e[1]:e[1]/255,b:t?e[2]:e[2]/255,a:e[3]===void 0?1:t?e[3]:e[3]/255}}if(typeof e==`string`){let t=e.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);if(t)return{r:parseInt(t[1],10)/255,g:parseInt(t[2],10)/255,b:parseInt(t[3],10)/255,a:1};let n=e.replace(`#`,``);if(n.length===3||n.length===6){let e=n.length===3?n.split(``).map(e=>e+e).join(``):n,t=/^([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(t)return{r:parseInt(t[1],16)/255,g:parseInt(t[2],16)/255,b:parseInt(t[3],16)/255,a:1}}}return{r:0,g:0,b:0,a:1}}interpolateColor(e,t,n,r){return r===`constant`?n<.5?e:t:(r===`smooth`&&(n=n*n*(3-2*n)),{r:e.r+(t.r-e.r)*n,g:e.g+(t.g-e.g)*n,b:e.b+(t.b-e.b)*n,a:(e.a??1)+((t.a??1)-(e.a??1))*n})}getColorAtPosition(e,t){let n=[...e].sort((e,t)=>e.position-t.position);t=Math.max(0,Math.min(1,t));let r=null,i=null;for(let e=0;e<n.length;e++)if(n[e].position<=t&&(r=n[e]),n[e].position>=t&&!i){i=n[e];break}if(!r&&i)return this.normalizeRampColor(i.color);if(r&&!i)return this.normalizeRampColor(r.color);if(!r&&!i)return{r:0,g:0,b:0,a:1};if(r.position===t)return this.normalizeRampColor(r.color);if(i.position===t)return this.normalizeRampColor(i.color);let a=(t-r.position)/(i.position-r.position),o=this.normalizeRampColor(r.color),s=this.normalizeRampColor(i.color),c=i.interpolation||`linear`;return this.interpolateColor(o,s,a,c)}render(){let[e,t]=this.getResolution(),n=this.props.type.value,r=this.props.points.value||[];if(r.length===0)return;let a=i.rgba(e,t),o=a.r(),s=a.g(),c=a.b(),l=a.a(),u=e/2,d=t/2,f=Math.sqrt(u*u+d*d);for(let i=0;i<t;i++)for(let a=0;a<e;a++){let p=0;if(n===`horizontal`)p=a/e;else if(n===`vertical`)p=i/t;else if(n===`radial`){let e=a-u,t=i-d;p=(Math.atan2(t,e)+Math.PI)/(2*Math.PI)}else if(n===`concentric`){let e=a-u,t=i-d;p=Math.sqrt(e*e+t*t)/f}let m=this.getColorAtPosition(r,p),h=i*e+a;o[h]=m.r,s[h]=m.g,c[h]=m.b,l[h]=m.a??1}a.markDirty(),this.setOutput(this.output,a)}},m=class extends o{constructor(e,t){super(e,`Noise`,t),this.noise2D=null,this.currentSeed=null}setup(){this.addParm(`seed`,{value:0,params:{min:0,max:1e4,step:1,integer:!0},displayName:`Seed`,onChange:()=>{this.initNoise().then(()=>{this.noise2D&&this.requestCook()})}}),this.addParm(`scale`,{value:.01,params:{min:.001,max:1,step:.001},displayName:`Scale`,onChange:()=>this.requestCook()}),this.addParm(`iterations`,{value:4,params:{min:1,max:8,step:1,integer:!0},displayName:`Iterations`,onChange:()=>this.requestCook()}),this.addResolutionParm(),this.output=this.out(`image`),this.onReady=async()=>{await this.initNoise(),this.noise2D&&this.requestCook()}}async initNoise(){try{let{createNoise2D:e}=await this.require(`simplex-noise`),t=this.props.seed.value,n=t;function r(){return n=(n*9301+49297)%233280,n/233280}this.noise2D=e(r),this.currentSeed=t}catch(e){console.error(`Failed to load simplex-noise:`,e),this.error=e}}render(){if(!this.noise2D){this.initNoise().then(()=>{this.noise2D&&this.requestCook()});return}let[e,t]=this.getResolution(),n=this.props.scale.value,r=this.props.iterations.value;if(this.props.seed.value!==this.currentSeed){this.initNoise().then(()=>{this.noise2D&&this.requestCook()});return}let a=i.grayscale(e,t),o=a.r();for(let i=0;i<t;i++)for(let t=0;t<e;t++){let a=0,s=1,c=n,l=0;for(let e=0;e<r;e++){let e=t*c,n=i*c,r=this.noise2D(e,n);a+=r*s,l+=s,s*=.5,c*=2}a=(a/l+1)*.5,o[i*e+t]=a}a.markDirty(),this.setOutput(this.output,a)}},h=class extends o{constructor(e,t){super(e,`Blur`,t)}setup(){this.image=this.in(`image`,null),this.addParm(`method`,{value:`box`,params:{options:[{value:`box`,label:`Box (Fast)`},{value:`gaussian`,label:`Gaussian (Accurate)`}]},displayName:`Method`,onChange:()=>this.requestCook()}),this.addParm(`radius`,{value:5,params:{min:0,max:100,step:.1},displayName:`Radius`,onChange:()=>this.requestCook()}),this.addParm(`wrapEdges`,{value:!1,type:`boolean`,displayName:`Wrap Edges`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.image.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}boxBlur(e,t,n){if(t<=0)return e.clone();let{width:r,height:i}=e,a=t,o=this.boxesForGauss(a,3),s=e.emptyClone();for(let t=0;t<e.channelCount;t++){let a=new Float32Array(e.channels[t]);for(let e of o)this.boxBlurPass(a,r,i,e,n);s.channels[t].set(a)}return s}boxesForGauss(e,t){let n=Math.sqrt(12*e*e/t+1),r=Math.floor(n);r%2==0&&r--;let i=r+2,a=(12*e*e-t*r*r-4*t*r-3*t)/(-4*r-4),o=Math.round(a),s=[];for(let e=0;e<t;e++)s.push(e<o?r:i);return s.map(e=>(e-1)/2)}boxBlurPass(e,t,n,r,i){if(r<1)return;let a=new Float32Array(t*n),o=Math.floor(r),s=1/(o*2+1);for(let r=0;r<n;r++){let n=r*t,c=0;for(let r=-o;r<=o;r++){let a=i?(r%t+t)%t:Math.max(0,Math.min(t-1,r));c+=e[n+a]}a[n]=c*s;for(let r=1;r<t;r++){let l=i?((r-o-1)%t+t)%t:Math.max(0,r-o-1),u=i?((r+o)%t+t)%t:Math.min(t-1,r+o);c-=e[n+l],c+=e[n+u],a[n+r]=c*s}}for(let r=0;r<t;r++){let c=0;for(let e=-o;e<=o;e++){let o=i?(e%n+n)%n:Math.max(0,Math.min(n-1,e));c+=a[o*t+r]}e[r]=c*s;for(let l=1;l<n;l++){let u=i?((l-o-1)%n+n)%n:Math.max(0,l-o-1),d=i?((l+o)%n+n)%n:Math.min(n-1,l+o);c-=a[u*t+r],c+=a[d*t+r],e[l*t+r]=c*s}}}trueGaussianBlur(e,t,n){if(t<=0)return e.clone();let{width:r,height:i}=e,a=e.emptyClone(),o=Math.ceil(t*3)*2+1,s=new Float32Array(o),c=t/3,l=2*c*c,u=0,d=o-1>>1;for(let e=0;e<o;e++){let t=e-d,n=Math.exp(-(t*t)/l);s[e]=n,u+=n}let f=1/u;for(let e=0;e<o;e++)s[e]*=f;let p=n?e=>(e%r+r)%r:e=>e<0?0:e>=r?r-1:e,m=n?e=>(e%i+i)%i:e=>e<0?0:e>=i?i-1:e;for(let t=0;t<e.channelCount;t++){let n=e.channels[t],c=a.channels[t],l=new Float32Array(r*i);for(let e=0;e<i;e++){let t=e*r;for(let e=0;e<r;e++){let r=0;for(let i=0;i<o;i++){let a=p(e+i-d);r+=n[t+a]*s[i]}l[t+e]=r}}for(let e=0;e<r;e++)for(let t=0;t<i;t++){let n=0;for(let i=0;i<o;i++){let a=m(t+i-d);n+=l[a*r+e]*s[i]}c[t*r+e]=n}}return a}render(){let e=this.toImageBuffer(this.image.value);if(!e)return;let t=this.props.method.value,n=this.props.radius.value,r=this.props.wrapEdges.value,i=t===`gaussian`?this.trueGaussianBlur(e,n,r):this.boxBlur(e,n,r);this.setOutput(this.output,i)}},g=class extends o{constructor(e,t){super(e,`Text`,t)}setup(){this.addParm(`text`,{value:`Hello, World!`,type:`textarea`,displayName:`Text`}),this.addParm(`font`,{value:`Inter, system-ui, sans-serif`,type:`text`,displayName:`Font`}),this.addParm(`fontSize`,{value:48,type:`slider`,params:{min:1,max:500,step:1},displayName:`Font Size`}),this.addParm(`fontWeight`,{value:`normal`,type:`select`,params:{options:[{value:`normal`,label:`Normal`},{value:`bold`,label:`Bold`},{value:`100`,label:`Thin (100)`},{value:`200`,label:`Extra Light (200)`},{value:`300`,label:`Light (300)`},{value:`500`,label:`Medium (500)`},{value:`600`,label:`Semi Bold (600)`},{value:`700`,label:`Bold (700)`},{value:`800`,label:`Extra Bold (800)`},{value:`900`,label:`Black (900)`}]},displayName:`Font Weight`}),this.addParm(`fontStyle`,{value:`normal`,type:`select`,params:{options:[{value:`normal`,label:`Normal`},{value:`italic`,label:`Italic`},{value:`oblique`,label:`Oblique`}]},displayName:`Font Style`}),this.addParm(`alignH`,{value:`center`,type:`select`,params:{options:[{value:`left`,label:`Left`},{value:`center`,label:`Center`},{value:`right`,label:`Right`}]},displayName:`Horizontal Align`}),this.addParm(`alignV`,{value:`middle`,type:`select`,params:{options:[{value:`top`,label:`Top`},{value:`middle`,label:`Middle`},{value:`bottom`,label:`Bottom`}]},displayName:`Vertical Align`}),this.addParm(`color`,{value:{r:1,g:1,b:1},type:`color`,displayName:`Color`}),this.addParm(`backgroundColor`,{value:{r:0,g:0,b:0,a:0},type:`color`,displayName:`Background`}),this.addResolutionParm(),this.addParm(`offset`,{value:[0,0],params:{min:[-2048,-2048],max:[2048,2048],step:1},displayName:`Offset`}),this.addParm(`rotation`,{value:0,type:`slider`,params:{min:-180,max:180,step:.1},displayName:`Rotation`}),this.addParm(`letterSpacing`,{value:0,type:`slider`,params:{min:-50,max:100,step:.5},displayName:`Letter Spacing`}),this.addParm(`lineHeight`,{value:1.2,type:`slider`,params:{min:.5,max:3,step:.05},displayName:`Line Height`}),this.addParm(`opacity`,{value:1,type:`slider`,params:{min:0,max:1,step:.01},displayName:`Opacity`}),this.output=this.out(`image`),[`text`,`font`,`fontSize`,`fontWeight`,`fontStyle`,`alignH`,`alignV`,`color`,`backgroundColor`,`offset`,`rotation`,`letterSpacing`,`lineHeight`,`opacity`].forEach(e=>this.watchProp(e,()=>this.requestCook())),this.onReady=()=>this.requestCook()}render(){let[e,t]=this.getResolution(),a=this.props.text.value,o=this.props.font.value,s=this.props.fontSize.value,c=this.props.fontWeight.value,l=this.props.fontStyle.value,u=this.props.alignH.value,d=this.props.alignV.value,f=n(this.props.color.value),p=n(this.props.backgroundColor.value),[m,h]=this.props.offset.value,g=this.props.rotation.value,_=this.props.letterSpacing.value,v=this.props.lineHeight.value,y=this.props.opacity.value,b=document.createElement(`canvas`);b.width=e,b.height=t;let x=b.getContext(`2d`);if(!x){this.setOutput(this.output,i.rgba(e,t));return}p.a>0?(x.fillStyle=r(p),x.fillRect(0,0,e,t)):x.clearRect(0,0,e,t),x.save(),x.globalAlpha=y,x.font=`${l} ${c} ${s}px ${o}`,x.fillStyle=r(f);let S=a.split(`
2
- `),C=s*v,w=S.length*C,T,E;switch(u){case`left`:x.textAlign=`left`,T=0;break;case`right`:x.textAlign=`right`,T=e;break;default:x.textAlign=`center`,T=e/2}switch(d){case`top`:E=s;break;case`bottom`:E=t-w+s;break;default:E=(t-w)/2+s}if(T+=m,E+=h,g!==0){let e=g*Math.PI/180;x.translate(T,E-s/2+w/2),x.rotate(e),x.translate(-T,-(E-s/2+w/2))}if(_!==0){x.textAlign=`left`;for(let e=0;e<S.length;e++){let t=S[e],n=E+e*C,r=0;for(let e of t)r+=x.measureText(e).width+_;r-=_;let i;switch(u){case`left`:i=T;break;case`right`:i=T-r;break;default:i=T-r/2}for(let e of t)x.fillText(e,i,n),i+=x.measureText(e).width+_}}else for(let e=0;e<S.length;e++){let t=E+e*C;x.fillText(S[e],T,t)}x.restore();let D=i.fromCanvas(b);this.setOutput(this.output,D)}},_=class extends o{constructor(e,t){super(e,`Transform`,t)}setup(){this.imageInput=this.in(`image`,null),this.addParm(`translate`,{value:[0,0],params:{min:[-2048,-2048],max:[2048,2048],step:1},displayName:`Translate`,onChange:()=>this.requestCook()}),this.addParm(`rotation`,{value:0,params:{min:-180,max:180,step:.1},displayName:`Rotation`,onChange:()=>this.requestCook()}),this.addParm(`scale`,{value:[1,1],params:{min:[.01,.01],max:[10,10],step:.01},displayName:`Scale`,onChange:()=>this.requestCook()}),this.addParm(`uniformScale`,{value:!0,type:`boolean`,displayName:`Uniform Scale`,onChange:()=>this.requestCook()}),this.addParm(`pivot`,{value:`center`,params:{options:[{value:`center`,label:`Center`},{value:`top-left`,label:`Top Left`},{value:`top-right`,label:`Top Right`},{value:`bottom-left`,label:`Bottom Left`},{value:`bottom-right`,label:`Bottom Right`},{value:`custom`,label:`Custom`}]},displayName:`Pivot`,onChange:()=>this.requestCook()}),this.addParm(`customPivot`,{value:[.5,.5],params:{min:[0,0],max:[1,1],step:.01},displayName:`Custom Pivot`,hidden:()=>this.props.pivot.value!==`custom`,onChange:()=>this.requestCook()}),this.addParm(`filter`,{value:`bilinear`,params:{options:[{value:`nearest`,label:`Nearest`},{value:`bilinear`,label:`Bilinear`}]},displayName:`Filter`,onChange:()=>this.requestCook()}),this.addParm(`wrap`,{value:`clamp`,params:{options:[{value:`clamp`,label:`Clamp`},{value:`repeat`,label:`Repeat`},{value:`mirror`,label:`Mirror`},{value:`transparent`,label:`Transparent`}]},displayName:`Wrap Mode`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.imageInput.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}getPivotPoint(e,t){switch(this.props.pivot.value){case`center`:return[e/2,t/2];case`top-left`:return[0,0];case`top-right`:return[e,0];case`bottom-left`:return[0,t];case`bottom-right`:return[e,t];case`custom`:let[n,r]=this.props.customPivot.value;return[n*e,r*t];default:return[e/2,t/2]}}wrapCoord(e,t,n){if(n===`clamp`)return Math.max(0,Math.min(t-1,e));if(n===`repeat`)return e%=t,e<0&&(e+=t),e;if(n===`mirror`){let n=t*2;return e=Math.abs(e%n),e>=t&&(e=n-e-1),Math.max(0,Math.min(t-1,e))}return e}render(){let e=this.toImageBuffer(this.imageInput.value);if(!e)return;let t=e.width,n=e.height,[r,a]=this.props.translate.value,o=this.props.rotation.value*Math.PI/180,[s,c]=this.props.scale.value,l=this.props.uniformScale.value,u=this.props.filter.value,d=this.props.wrap.value;l&&(c=s);let[f,p]=this.getPivotPoint(t,n),m=Math.cos(-o),h=Math.sin(-o),g=1/s,_=1/c,v=i.rgba(t,n),y=Math.min(e.channelCount,4);for(let i=0;i<n;i++)for(let o=0;o<t;o++){let s=o-f-r,c=i-p-a,l=s*m-c*h,b=s*h+c*m,x=l*g+f,S=b*_+p;if(d===`transparent`&&(x<0||x>=t||S<0||S>=n)){let e=i*t+o;for(let t=0;t<4;t++)v.channels[t][e]=0;continue}let C=i*t+o;if(u===`nearest`){let r=Math.round(x),i=Math.round(S),a=this.wrapCoord(r,t,d),o=this.wrapCoord(i,n,d)*t+a;for(let t=0;t<y;t++)v.channels[t][C]=e.channels[t][o];y<4&&(v.channels[3][C]=1)}else{let r=Math.floor(x),i=Math.floor(S),a=r+1,o=i+1,s=x-r,c=S-i,l=this.wrapCoord(r,t,d),u=this.wrapCoord(a,t,d),f=this.wrapCoord(i,n,d),p=this.wrapCoord(o,n,d),m=f*t+l,h=f*t+u,g=p*t+l,_=p*t+u;for(let t=0;t<y;t++){let n=e.channels[t][m],r=e.channels[t][h],i=e.channels[t][g],a=e.channels[t][_],o=n+(r-n)*s,l=i+(a-i)*s;v.channels[t][C]=o+(l-o)*c}y<4&&(v.channels[3][C]=1)}}v.markDirty(),this.setOutput(this.output,v)}},v=`/**
1
+ import{c as e,u as t}from"./nodeTypeUtils-BBA1JqHx.js";import{O as n,_ as r,h as i,k as a,m as o,o as s,v as c}from"./index-HTCN44kj.js";var l=class extends s{constructor(e,t){super(e,`Color`,t)}setup(){this.addParm(`color`,{value:{r:1,g:1,b:1},type:`color`,displayName:`Color`}),this.addResolutionParm(),this.output=this.out(`image`),this.watchProp(`color`,()=>this.requestCook()),this.onReady=()=>this.requestCook()}render(){let[e,t]=this.getResolution(),n=a(this.props.color.value),r=i.solid(e,t,n);this.setOutput(this.output,r)}},u=class extends s{constructor(e,t){super(e,`File`,t)}setup(){this.imageInput=this.in(`image`,null),this.addParm(`file`,{value:``,type:`image`,params:{accept:`image/*`},displayName:`File`,onChange:()=>{this.props.file.value&&!this.imageInput.value&&this.requestCook()}}),this.addParm(`resolutionMode`,{value:`original`,params:{options:[{value:`original`,label:`Original`},{value:`max`,label:`Max Resolution`},{value:`fixed`,label:`Fixed Resolution`}]},displayName:`Resolution Mode`,onChange:()=>{(this.props.file.value||this.imageInput.value)&&this.requestCook()}}),this.addParm(`maxResolution`,{value:[2048,2048],params:{min:[1,1],max:[4096,4096]},displayName:`Max Resolution`,hidden:()=>this.props.resolutionMode.value!==`max`,onChange:()=>{(this.props.file.value||this.imageInput.value)&&this.props.resolutionMode.value===`max`&&this.requestCook()}}),this.addParm(`fixedResolution`,{value:[512,512],params:{min:[1,1],max:[4096,4096]},displayName:`Fixed Resolution`,hidden:()=>this.props.resolutionMode.value!==`fixed`,onChange:()=>{(this.props.file.value||this.imageInput.value)&&this.props.resolutionMode.value===`fixed`&&this.requestCook()}}),this.output=this.out(`image`),this.imageInput.onChange=()=>this.requestCook(),this.onReady=()=>{(this.props.file.value||this.imageInput.value)&&this.requestCook()}}async render(){let e=null;if(this.imageInput.value?e=this.imageInput.value instanceof i?this.imageInput.value:typeof this.imageInput.value==`string`?i.fromCanvas(await c(this.imageInput.value)):i.fromCanvas(this.imageInput.value):this.props.file.value&&(e=i.fromCanvas(await c(this.props.file.value))),e)try{let t=this.props.resolutionMode.value,n;if(t===`original`)n=e;else if(t===`max`){let[t,r]=this.props.maxResolution.value,i=e.width/e.height,a=e.width,o=e.height;a>t&&(a=t,o=t/i),o>r&&(o=r,a=r*i),a=Math.round(a),o=Math.round(o),n=a!==e.width||o!==e.height?this.resizeBuffer(e,a,o):e}else{let[t,r]=this.props.fixedResolution.value;n=this.resizeBuffer(e,t,r)}this.setOutput(this.output,n)}catch(e){this.error=e,console.error(`Failed to process image:`,e)}}resizeBuffer(e,t,n){let r=i.rgba(t,n),a=e.width/t,o=e.height/n;for(let i=0;i<Math.min(e.channelCount,4);i++){let s=r.channels[i];for(let r=0;r<n;r++)for(let n=0;n<t;n++){let c=n*a,l=r*o;s[r*t+n]=e.sample(c,l,i)}}return e.channelCount<4&&r.fill(3,1),r}},d=class extends s{constructor(e,t){super(e,`Composite`,t)}setup(){this.image1=this.in(`image1`,null),this.image2=this.in(`image2`,null),this.addParm(`blendMode`,{value:`multiply`,params:{options:[{value:`normal`,label:`Normal`},{value:`multiply`,label:`Multiply`},{value:`screen`,label:`Screen`},{value:`overlay`,label:`Overlay`},{value:`darken`,label:`Darken`},{value:`lighten`,label:`Lighten`},{value:`color-dodge`,label:`Color Dodge`},{value:`color-burn`,label:`Color Burn`},{value:`hard-light`,label:`Hard Light`},{value:`soft-light`,label:`Soft Light`},{value:`difference`,label:`Difference`},{value:`exclusion`,label:`Exclusion`},{value:`add`,label:`Add`},{value:`subtract`,label:`Subtract`},{value:`divide`,label:`Divide`},{value:`pin-light`,label:`Pin Light`},{value:`vivid-light`,label:`Vivid Light`},{value:`linear-dodge`,label:`Linear Dodge`},{value:`linear-burn`,label:`Linear Burn`}]},displayName:`Blend Mode`,onChange:()=>this.requestCook()}),this.addParm(`opacity`,{value:1,params:{min:0,max:1,step:.01},displayName:`Opacity`,onChange:()=>this.requestCook()}),this.addParm(`outputResolution`,{value:`input1`,params:{options:[{value:`input1`,label:`Use Input 1`},{value:`input2`,label:`Use Input 2`},{value:`largest`,label:`Largest Input`},{value:`smallest`,label:`Smallest Input`},{value:`custom`,label:`Custom`}]},displayName:`Output Resolution`,onChange:()=>this.requestCook()}),this.addParm(`customResolution`,{value:[512,512],params:{min:[1,1],max:[4096,4096],integer:!0},displayName:`Resolution`,hidden:()=>this.props.outputResolution.value!==`custom`,onChange:()=>this.requestCook()}),this.addParm(`fitMode`,{value:`fill`,params:{options:[{value:`fill`,label:`Fill (Crop)`},{value:`fit`,label:`Fit (Letterbox)`},{value:`stretch`,label:`Stretch`},{value:`native`,label:`Native (No Scale)`}]},displayName:`Fit Mode`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.image1.onChange=()=>this.requestCook(),this.image2.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}blendBuffers(e,t,n,r){let a=e.width,o=e.height,s=i.rgba(a,o),c=e.channelCount>=4?e:e.toRGBA(),l=t.channelCount>=4?t:t.toRGBA(),u=c.channels[0],d=c.channels[1],f=c.channels[2],p=c.channels[3],m=l.channels[0],h=l.channels[1],g=l.channels[2],_=l.channels[3],v=s.channels[0],y=s.channels[1],b=s.channels[2],x=s.channels[3];for(let e=0;e<a*o;e++){let t=u[e],i=d[e],a=f[e],o=p[e],s=m[e],c=h[e],l=g[e],S=_[e],C,w,T;switch(n){case`normal`:C=s,w=c,T=l;break;case`multiply`:C=t*s,w=i*c,T=a*l;break;case`screen`:C=1-(1-t)*(1-s),w=1-(1-i)*(1-c),T=1-(1-a)*(1-l);break;case`overlay`:C=t<.5?2*t*s:1-2*(1-t)*(1-s),w=i<.5?2*i*c:1-2*(1-i)*(1-c),T=a<.5?2*a*l:1-2*(1-a)*(1-l);break;case`darken`:C=Math.min(t,s),w=Math.min(i,c),T=Math.min(a,l);break;case`lighten`:C=Math.max(t,s),w=Math.max(i,c),T=Math.max(a,l);break;case`color-dodge`:C=s===1?1:Math.min(1,t/(1-s)),w=c===1?1:Math.min(1,i/(1-c)),T=l===1?1:Math.min(1,a/(1-l));break;case`color-burn`:C=s===0?0:Math.max(0,1-(1-t)/s),w=c===0?0:Math.max(0,1-(1-i)/c),T=l===0?0:Math.max(0,1-(1-a)/l);break;case`hard-light`:C=s<.5?2*t*s:1-2*(1-t)*(1-s),w=c<.5?2*i*c:1-2*(1-i)*(1-c),T=l<.5?2*a*l:1-2*(1-a)*(1-l);break;case`soft-light`:C=s<.5?t-(1-2*s)*t*(1-t):t+(2*s-1)*(Math.sqrt(t)-t),w=c<.5?i-(1-2*c)*i*(1-i):i+(2*c-1)*(Math.sqrt(i)-i),T=l<.5?a-(1-2*l)*a*(1-a):a+(2*l-1)*(Math.sqrt(a)-a);break;case`difference`:C=Math.abs(t-s),w=Math.abs(i-c),T=Math.abs(a-l);break;case`exclusion`:C=t+s-2*t*s,w=i+c-2*i*c,T=a+l-2*a*l;break;case`add`:C=Math.min(1,t+s),w=Math.min(1,i+c),T=Math.min(1,a+l);break;case`subtract`:C=Math.max(0,t-s),w=Math.max(0,i-c),T=Math.max(0,a-l);break;case`divide`:C=s===0?1:Math.min(1,t/s),w=c===0?1:Math.min(1,i/c),T=l===0?1:Math.min(1,a/l);break;case`pin-light`:C=s<.5?Math.min(t,2*s):Math.max(t,2*(s-.5)),w=c<.5?Math.min(i,2*c):Math.max(i,2*(c-.5)),T=l<.5?Math.min(a,2*l):Math.max(a,2*(l-.5));break;case`vivid-light`:C=s<.5?s===0?0:1-(1-t)/(2*s):s===1?1:t/(2*(1-s)),w=c<.5?c===0?0:1-(1-i)/(2*c):c===1?1:i/(2*(1-c)),T=l<.5?l===0?0:1-(1-a)/(2*l):l===1?1:a/(2*(1-l));break;case`linear-dodge`:C=Math.min(1,t+s),w=Math.min(1,i+c),T=Math.min(1,a+l);break;case`linear-burn`:C=Math.max(0,t+s-1),w=Math.max(0,i+c-1),T=Math.max(0,a+l-1);break;default:C=s,w=c,T=l}v[e]=t+(C-t)*r*S,y[e]=i+(w-i)*r*S,b[e]=a+(T-a)*r*S,x[e]=o+(S-o)*r}return s}render(){let e=this.props.outputResolution.value,t=this.props.fitMode.value,n=this.props.customResolution.value,{buffers:r}=this.prepareInputs([this.image1.value,this.image2.value],e,t,n),[i,a]=r;if(!i||!a)return;let o=this.props.blendMode.value,s=this.props.opacity.value;try{let e=this.blendBuffers(i,a,o,s);this.setOutput(this.output,e)}catch(e){console.error(`Composite render error:`,e),this.error=e}}},f=class extends s{constructor(e,t){super(e,`Checkers`,t)}setup(){this.addParm(`color1`,{value:{r:1,g:1,b:1},type:`color`,displayName:`Color 1`,onChange:()=>this.requestCook()}),this.addParm(`color2`,{value:{r:0,g:0,b:0},type:`color`,displayName:`Color 2`,onChange:()=>this.requestCook()}),this.addParm(`mode`,{value:`size`,params:{options:[{value:`size`,label:`Size`},{value:`divisions`,label:`Divisions`}]},displayName:`Mode`,onChange:()=>this.requestCook()}),this.addParm(`size`,{value:32,params:{min:1,max:512,step:.1},displayName:`Size`,hidden:()=>this.props.mode.value!==`size`,onChange:()=>this.requestCook()}),this.addParm(`divisions`,{value:16,params:{min:1,max:512,step:1,integer:!0},displayName:`Divisions`,hidden:()=>this.props.mode.value!==`divisions`,onChange:()=>this.requestCook()}),this.addParm(`centered`,{value:!1,type:`boolean`,displayName:`Centered`,onChange:()=>this.requestCook()}),this.addResolutionParm(),this.output=this.out(`image`),this.onReady=()=>this.requestCook()}render(){let[e,t]=this.getResolution(),n=this.props.mode.value,r=a(this.props.color1.value),o=a(this.props.color2.value),s=this.props.centered.value,c;c=n===`size`?this.props.size.value:e/this.props.divisions.value;let l=0,u=0;s&&(l=e/2%c-c/2,u=t/2%c-c/2);let d=i.rgba(e,t),f=d.r(),p=d.g(),m=d.b(),h=d.a();for(let n=0;n<t;n++)for(let t=0;t<e;t++){let i=n*e+t,a=(Math.floor((t-l)/c)+Math.floor((n-u)/c))%2==0?r:o;f[i]=a.r,p[i]=a.g,m[i]=a.b,h[i]=a.a}d.markDirty(),this.setOutput(this.output,d)}},p=class extends s{constructor(e,t){super(e,`Resize`,t)}setup(){this.image=this.in(`image`,null),this.addParm(`mode`,{value:`scale`,params:{options:[{value:`scale`,label:`Scale`},{value:`fixed`,label:`Fixed`}]},displayName:`Mode`,onChange:()=>this.requestCook()}),this.addParm(`scale`,{value:1,params:{min:.1,max:10,step:.1},displayName:`Scale`,hidden:()=>this.props.mode.value!==`scale`,onChange:()=>this.requestCook()}),this.addParm(`width`,{value:512,params:{min:1,max:4096,step:1},displayName:`Width`,hidden:()=>this.props.mode.value!==`fixed`,onChange:()=>this.requestCook()}),this.addParm(`height`,{value:512,params:{min:1,max:4096,step:1},displayName:`Height`,hidden:()=>this.props.mode.value!==`fixed`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.image.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}resizeBuffer(e,t,n){let r=i.rgba(t,n),a=e.width/t,o=e.height/n;for(let i=0;i<Math.min(e.channelCount,4);i++){let s=r.channels[i];for(let r=0;r<n;r++)for(let n=0;n<t;n++){let c=n*a,l=r*o;s[r*t+n]=e.sample(c,l,i)}}return e.channelCount<4&&r.fill(3,1),r}render(){let e=this.toImageBuffer(this.image.value);if(!e)return;let t,n;if(this.props.mode.value===`scale`){let r=this.props.scale.value;t=Math.round(e.width*r),n=Math.round(e.height*r)}else t=this.props.width.value,n=this.props.height.value;let r=this.resizeBuffer(e,t,n);this.setOutput(this.output,r)}},m=class extends s{constructor(e,t){super(e,`NormalMap`,t)}setup(){this.image=this.in(`image`,null),this.addParm(`scale`,{value:1,params:{min:0,max:10,step:.1},displayName:`Scale`,onChange:()=>this.requestCook()}),this.addParm(`flipX`,{value:!1,type:`boolean`,displayName:`Flip X`,onChange:()=>this.requestCook()}),this.addParm(`flipY`,{value:!1,type:`boolean`,displayName:`Flip Y`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.image.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}computeNormalMap(e,t,n,r){let{width:a,height:o}=e,s=i.rgba(a,o),c=e.channels[0],l=s.channels[0],u=s.channels[1],d=s.channels[2],f=s.channels[3];for(let e=0;e<o;e++)for(let i=0;i<a;i++){let s=e*a+i,p=c[s],m=c[Math.min(i+1,a-1)+e*a],h=c[i+Math.min(e+1,o-1)*a],g=(m-p)*t,_=(h-p)*t,v=n?-g:g,y=r?-_:_,b=-v,x=-y,S=Math.sqrt(b*b+x*x+1),C=b/S,w=x/S,T=1/S;l[s]=C*.5+.5,u[s]=w*.5+.5,d[s]=T*.5+.5,f[s]=1}return s}render(){let e=this.toImageBuffer(this.image.value);if(!e)return;let t=this.props.scale.value,n=this.props.flipX.value,r=this.props.flipY.value,i=this.computeNormalMap(e,t,n,r);this.setOutput(this.output,i)}},h=class extends s{constructor(e,t){super(e,`Ramp`,t)}setup(){this.addParm(`type`,{value:`horizontal`,params:{options:[{value:`horizontal`,label:`Horizontal`},{value:`vertical`,label:`Vertical`},{value:`radial`,label:`Radial`},{value:`concentric`,label:`Concentric`}]},displayName:`Type`,onChange:()=>this.requestCook()}),this.addParm(`points`,{value:[{position:0,color:{r:0,g:0,b:0},interpolation:`linear`},{position:1,color:{r:1,g:1,b:1},interpolation:`linear`}],type:`colorramp`,displayName:`Ramp`,onChange:()=>this.requestCook()}),this.addResolutionParm(),this.output=this.out(`image`),this.onReady=()=>this.requestCook()}normalizeRampColor(e){if(typeof e==`object`&&e&&`r`in e&&`g`in e&&`b`in e){let t=e.r<=1&&e.g<=1&&e.b<=1;return{r:t?e.r:e.r/255,g:t?e.g:e.g/255,b:t?e.b:e.b/255,a:e.a===void 0?1:t?e.a:e.a/255}}if(Array.isArray(e)){let t=e.every(e=>e<=1);return{r:t?e[0]:e[0]/255,g:t?e[1]:e[1]/255,b:t?e[2]:e[2]/255,a:e[3]===void 0?1:t?e[3]:e[3]/255}}if(typeof e==`string`){let t=e.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);if(t)return{r:parseInt(t[1],10)/255,g:parseInt(t[2],10)/255,b:parseInt(t[3],10)/255,a:1};let n=e.replace(`#`,``);if(n.length===3||n.length===6){let e=n.length===3?n.split(``).map(e=>e+e).join(``):n,t=/^([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);if(t)return{r:parseInt(t[1],16)/255,g:parseInt(t[2],16)/255,b:parseInt(t[3],16)/255,a:1}}}return{r:0,g:0,b:0,a:1}}interpolateColor(e,t,n,r){return r===`constant`?n<.5?e:t:(r===`smooth`&&(n=n*n*(3-2*n)),{r:e.r+(t.r-e.r)*n,g:e.g+(t.g-e.g)*n,b:e.b+(t.b-e.b)*n,a:(e.a??1)+((t.a??1)-(e.a??1))*n})}getColorAtPosition(e,t){let n=[...e].sort((e,t)=>e.position-t.position);t=Math.max(0,Math.min(1,t));let r=null,i=null;for(let e=0;e<n.length;e++)if(n[e].position<=t&&(r=n[e]),n[e].position>=t&&!i){i=n[e];break}if(!r&&i)return this.normalizeRampColor(i.color);if(r&&!i)return this.normalizeRampColor(r.color);if(!r&&!i)return{r:0,g:0,b:0,a:1};if(r.position===t)return this.normalizeRampColor(r.color);if(i.position===t)return this.normalizeRampColor(i.color);let a=(t-r.position)/(i.position-r.position),o=this.normalizeRampColor(r.color),s=this.normalizeRampColor(i.color),c=i.interpolation||`linear`;return this.interpolateColor(o,s,a,c)}render(){let[e,t]=this.getResolution(),n=this.props.type.value,r=this.props.points.value||[];if(r.length===0)return;let a=i.rgba(e,t),o=a.r(),s=a.g(),c=a.b(),l=a.a(),u=e/2,d=t/2,f=Math.sqrt(u*u+d*d);for(let i=0;i<t;i++)for(let a=0;a<e;a++){let p=0;if(n===`horizontal`)p=a/e;else if(n===`vertical`)p=i/t;else if(n===`radial`){let e=a-u,t=i-d;p=(Math.atan2(t,e)+Math.PI)/(2*Math.PI)}else if(n===`concentric`){let e=a-u,t=i-d;p=Math.sqrt(e*e+t*t)/f}let m=this.getColorAtPosition(r,p),h=i*e+a;o[h]=m.r,s[h]=m.g,c[h]=m.b,l[h]=m.a??1}a.markDirty(),this.setOutput(this.output,a)}},g=class extends s{constructor(e,t){super(e,`Noise`,t),this.noise2D=null,this.currentSeed=null}setup(){this.addParm(`seed`,{value:0,params:{min:0,max:1e4,step:1,integer:!0},displayName:`Seed`,onChange:()=>{this.initNoise().then(()=>{this.noise2D&&this.requestCook()})}}),this.addParm(`scale`,{value:.01,params:{min:.001,max:1,step:.001},displayName:`Scale`,onChange:()=>this.requestCook()}),this.addParm(`iterations`,{value:4,params:{min:1,max:8,step:1,integer:!0},displayName:`Iterations`,onChange:()=>this.requestCook()}),this.addResolutionParm(),this.output=this.out(`image`),this.onReady=async()=>{await this.initNoise(),this.noise2D&&this.requestCook()}}async initNoise(){try{let{createNoise2D:e}=await this.require(`simplex-noise`),t=this.props.seed.value,n=t;function r(){return n=(n*9301+49297)%233280,n/233280}this.noise2D=e(r),this.currentSeed=t}catch(e){console.error(`Failed to load simplex-noise:`,e),this.error=e}}render(){if(!this.noise2D){this.initNoise().then(()=>{this.noise2D&&this.requestCook()});return}let[e,t]=this.getResolution(),n=this.props.scale.value,r=this.props.iterations.value;if(this.props.seed.value!==this.currentSeed){this.initNoise().then(()=>{this.noise2D&&this.requestCook()});return}let a=i.grayscale(e,t),o=a.r();for(let i=0;i<t;i++)for(let t=0;t<e;t++){let a=0,s=1,c=n,l=0;for(let e=0;e<r;e++){let e=t*c,n=i*c,r=this.noise2D(e,n);a+=r*s,l+=s,s*=.5,c*=2}a=(a/l+1)*.5,o[i*e+t]=a}a.markDirty(),this.setOutput(this.output,a)}},_=class extends s{constructor(e,t){super(e,`Blur`,t)}setup(){this.image=this.in(`image`,null),this.addParm(`method`,{value:`box`,params:{options:[{value:`box`,label:`Box (Fast)`},{value:`gaussian`,label:`Gaussian (Accurate)`}]},displayName:`Method`,onChange:()=>this.requestCook()}),this.addParm(`radius`,{value:5,params:{min:0,max:100,step:.1},displayName:`Radius`,onChange:()=>this.requestCook()}),this.addParm(`wrapEdges`,{value:!1,type:`boolean`,displayName:`Wrap Edges`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.image.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}boxBlur(e,t,n){if(t<=0)return e.clone();let{width:r,height:i}=e,a=t,o=this.boxesForGauss(a,3),s=e.emptyClone();for(let t=0;t<e.channelCount;t++){let a=new Float32Array(e.channels[t]);for(let e of o)this.boxBlurPass(a,r,i,e,n);s.channels[t].set(a)}return s}boxesForGauss(e,t){let n=Math.sqrt(12*e*e/t+1),r=Math.floor(n);r%2==0&&r--;let i=r+2,a=(12*e*e-t*r*r-4*t*r-3*t)/(-4*r-4),o=Math.round(a),s=[];for(let e=0;e<t;e++)s.push(e<o?r:i);return s.map(e=>(e-1)/2)}boxBlurPass(e,t,n,r,i){if(r<1)return;let a=new Float32Array(t*n),o=Math.floor(r),s=1/(o*2+1);for(let r=0;r<n;r++){let n=r*t,c=0;for(let r=-o;r<=o;r++){let a=i?(r%t+t)%t:Math.max(0,Math.min(t-1,r));c+=e[n+a]}a[n]=c*s;for(let r=1;r<t;r++){let l=i?((r-o-1)%t+t)%t:Math.max(0,r-o-1),u=i?((r+o)%t+t)%t:Math.min(t-1,r+o);c-=e[n+l],c+=e[n+u],a[n+r]=c*s}}for(let r=0;r<t;r++){let c=0;for(let e=-o;e<=o;e++){let o=i?(e%n+n)%n:Math.max(0,Math.min(n-1,e));c+=a[o*t+r]}e[r]=c*s;for(let l=1;l<n;l++){let u=i?((l-o-1)%n+n)%n:Math.max(0,l-o-1),d=i?((l+o)%n+n)%n:Math.min(n-1,l+o);c-=a[u*t+r],c+=a[d*t+r],e[l*t+r]=c*s}}}trueGaussianBlur(e,t,n){if(t<=0)return e.clone();let{width:r,height:i}=e,a=e.emptyClone(),o=Math.ceil(t*3)*2+1,s=new Float32Array(o),c=t/3,l=2*c*c,u=0,d=o-1>>1;for(let e=0;e<o;e++){let t=e-d,n=Math.exp(-(t*t)/l);s[e]=n,u+=n}let f=1/u;for(let e=0;e<o;e++)s[e]*=f;let p=n?e=>(e%r+r)%r:e=>e<0?0:e>=r?r-1:e,m=n?e=>(e%i+i)%i:e=>e<0?0:e>=i?i-1:e;for(let t=0;t<e.channelCount;t++){let n=e.channels[t],c=a.channels[t],l=new Float32Array(r*i);for(let e=0;e<i;e++){let t=e*r;for(let e=0;e<r;e++){let r=0;for(let i=0;i<o;i++){let a=p(e+i-d);r+=n[t+a]*s[i]}l[t+e]=r}}for(let e=0;e<r;e++)for(let t=0;t<i;t++){let n=0;for(let i=0;i<o;i++){let a=m(t+i-d);n+=l[a*r+e]*s[i]}c[t*r+e]=n}}return a}render(){let e=this.toImageBuffer(this.image.value);if(!e)return;let t=this.props.method.value,n=this.props.radius.value,r=this.props.wrapEdges.value,i=t===`gaussian`?this.trueGaussianBlur(e,n,r):this.boxBlur(e,n,r);this.setOutput(this.output,i)}},v=class extends s{constructor(e,t){super(e,`Text`,t)}setup(){this.addParm(`text`,{value:`Hello, World!`,type:`textarea`,displayName:`Text`}),this.addParm(`font`,{value:`Inter, system-ui, sans-serif`,type:`text`,displayName:`Font`}),this.addParm(`fontSize`,{value:48,type:`slider`,params:{min:1,max:500,step:1},displayName:`Font Size`}),this.addParm(`fontWeight`,{value:`normal`,type:`select`,params:{options:[{value:`normal`,label:`Normal`},{value:`bold`,label:`Bold`},{value:`100`,label:`Thin (100)`},{value:`200`,label:`Extra Light (200)`},{value:`300`,label:`Light (300)`},{value:`500`,label:`Medium (500)`},{value:`600`,label:`Semi Bold (600)`},{value:`700`,label:`Bold (700)`},{value:`800`,label:`Extra Bold (800)`},{value:`900`,label:`Black (900)`}]},displayName:`Font Weight`}),this.addParm(`fontStyle`,{value:`normal`,type:`select`,params:{options:[{value:`normal`,label:`Normal`},{value:`italic`,label:`Italic`},{value:`oblique`,label:`Oblique`}]},displayName:`Font Style`}),this.addParm(`alignH`,{value:`center`,type:`select`,params:{options:[{value:`left`,label:`Left`},{value:`center`,label:`Center`},{value:`right`,label:`Right`}]},displayName:`Horizontal Align`}),this.addParm(`alignV`,{value:`middle`,type:`select`,params:{options:[{value:`top`,label:`Top`},{value:`middle`,label:`Middle`},{value:`bottom`,label:`Bottom`}]},displayName:`Vertical Align`}),this.addParm(`color`,{value:{r:1,g:1,b:1},type:`color`,displayName:`Color`}),this.addParm(`backgroundColor`,{value:{r:0,g:0,b:0,a:0},type:`color`,displayName:`Background`}),this.addResolutionParm(),this.addParm(`offset`,{value:[0,0],params:{min:[-2048,-2048],max:[2048,2048],step:1},displayName:`Offset`}),this.addParm(`rotation`,{value:0,type:`slider`,params:{min:-180,max:180,step:.1},displayName:`Rotation`}),this.addParm(`letterSpacing`,{value:0,type:`slider`,params:{min:-50,max:100,step:.5},displayName:`Letter Spacing`}),this.addParm(`lineHeight`,{value:1.2,type:`slider`,params:{min:.5,max:3,step:.05},displayName:`Line Height`}),this.addParm(`opacity`,{value:1,type:`slider`,params:{min:0,max:1,step:.01},displayName:`Opacity`}),this.output=this.out(`image`),[`text`,`font`,`fontSize`,`fontWeight`,`fontStyle`,`alignH`,`alignV`,`color`,`backgroundColor`,`offset`,`rotation`,`letterSpacing`,`lineHeight`,`opacity`].forEach(e=>this.watchProp(e,()=>this.requestCook())),this.onReady=()=>this.requestCook()}render(){let[e,t]=this.getResolution(),o=this.props.text.value,s=this.props.font.value,c=this.props.fontSize.value,l=this.props.fontWeight.value,u=this.props.fontStyle.value,d=this.props.alignH.value,f=this.props.alignV.value,p=a(this.props.color.value),m=a(this.props.backgroundColor.value),[h,g]=this.props.offset.value,_=this.props.rotation.value,v=this.props.letterSpacing.value,y=this.props.lineHeight.value,b=this.props.opacity.value,x=r(e,t),S=x.getContext(`2d`);if(!S){this.setOutput(this.output,i.rgba(e,t));return}m.a>0?(S.fillStyle=n(m),S.fillRect(0,0,e,t)):S.clearRect(0,0,e,t),S.save(),S.globalAlpha=b,S.font=`${u} ${l} ${c}px ${s}`,S.fillStyle=n(p);let C=o.split(`
2
+ `),w=c*y,T=C.length*w,E,D;switch(d){case`left`:S.textAlign=`left`,E=0;break;case`right`:S.textAlign=`right`,E=e;break;default:S.textAlign=`center`,E=e/2}switch(f){case`top`:D=c;break;case`bottom`:D=t-T+c;break;default:D=(t-T)/2+c}if(E+=h,D+=g,_!==0){let e=_*Math.PI/180;S.translate(E,D-c/2+T/2),S.rotate(e),S.translate(-E,-(D-c/2+T/2))}if(v!==0){S.textAlign=`left`;for(let e=0;e<C.length;e++){let t=C[e],n=D+e*w,r=0;for(let e of t)r+=S.measureText(e).width+v;r-=v;let i;switch(d){case`left`:i=E;break;case`right`:i=E-r;break;default:i=E-r/2}for(let e of t)S.fillText(e,i,n),i+=S.measureText(e).width+v}}else for(let e=0;e<C.length;e++){let t=D+e*w;S.fillText(C[e],E,t)}S.restore();let O=i.fromCanvas(x);this.setOutput(this.output,O)}},y=class extends s{constructor(e,t){super(e,`Transform`,t)}setup(){this.imageInput=this.in(`image`,null),this.addParm(`translate`,{value:[0,0],params:{min:[-2048,-2048],max:[2048,2048],step:1},displayName:`Translate`,onChange:()=>this.requestCook()}),this.addParm(`rotation`,{value:0,params:{min:-180,max:180,step:.1},displayName:`Rotation`,onChange:()=>this.requestCook()}),this.addParm(`scale`,{value:[1,1],params:{min:[.01,.01],max:[10,10],step:.01},displayName:`Scale`,onChange:()=>this.requestCook()}),this.addParm(`uniformScale`,{value:!0,type:`boolean`,displayName:`Uniform Scale`,onChange:()=>this.requestCook()}),this.addParm(`pivot`,{value:`center`,params:{options:[{value:`center`,label:`Center`},{value:`top-left`,label:`Top Left`},{value:`top-right`,label:`Top Right`},{value:`bottom-left`,label:`Bottom Left`},{value:`bottom-right`,label:`Bottom Right`},{value:`custom`,label:`Custom`}]},displayName:`Pivot`,onChange:()=>this.requestCook()}),this.addParm(`customPivot`,{value:[.5,.5],params:{min:[0,0],max:[1,1],step:.01},displayName:`Custom Pivot`,hidden:()=>this.props.pivot.value!==`custom`,onChange:()=>this.requestCook()}),this.addParm(`filter`,{value:`bilinear`,params:{options:[{value:`nearest`,label:`Nearest`},{value:`bilinear`,label:`Bilinear`}]},displayName:`Filter`,onChange:()=>this.requestCook()}),this.addParm(`wrap`,{value:`clamp`,params:{options:[{value:`clamp`,label:`Clamp`},{value:`repeat`,label:`Repeat`},{value:`mirror`,label:`Mirror`},{value:`transparent`,label:`Transparent`}]},displayName:`Wrap Mode`,onChange:()=>this.requestCook()}),this.output=this.out(`image`),this.imageInput.onChange=()=>this.requestCook(),this.onReady=()=>this.requestCook()}getPivotPoint(e,t){switch(this.props.pivot.value){case`center`:return[e/2,t/2];case`top-left`:return[0,0];case`top-right`:return[e,0];case`bottom-left`:return[0,t];case`bottom-right`:return[e,t];case`custom`:let[n,r]=this.props.customPivot.value;return[n*e,r*t];default:return[e/2,t/2]}}wrapCoord(e,t,n){if(n===`clamp`)return Math.max(0,Math.min(t-1,e));if(n===`repeat`)return e%=t,e<0&&(e+=t),e;if(n===`mirror`){let n=t*2;return e=Math.abs(e%n),e>=t&&(e=n-e-1),Math.max(0,Math.min(t-1,e))}return e}render(){let e=this.toImageBuffer(this.imageInput.value);if(!e)return;let t=e.width,n=e.height,[r,a]=this.props.translate.value,o=this.props.rotation.value*Math.PI/180,[s,c]=this.props.scale.value,l=this.props.uniformScale.value,u=this.props.filter.value,d=this.props.wrap.value;l&&(c=s);let[f,p]=this.getPivotPoint(t,n),m=Math.cos(-o),h=Math.sin(-o),g=1/s,_=1/c,v=i.rgba(t,n),y=Math.min(e.channelCount,4);for(let i=0;i<n;i++)for(let o=0;o<t;o++){let s=o-f-r,c=i-p-a,l=s*m-c*h,b=s*h+c*m,x=l*g+f,S=b*_+p;if(d===`transparent`&&(x<0||x>=t||S<0||S>=n)){let e=i*t+o;for(let t=0;t<4;t++)v.channels[t][e]=0;continue}let C=i*t+o;if(u===`nearest`){let r=Math.round(x),i=Math.round(S),a=this.wrapCoord(r,t,d),o=this.wrapCoord(i,n,d)*t+a;for(let t=0;t<y;t++)v.channels[t][C]=e.channels[t][o];y<4&&(v.channels[3][C]=1)}else{let r=Math.floor(x),i=Math.floor(S),a=r+1,o=i+1,s=x-r,c=S-i,l=this.wrapCoord(r,t,d),u=this.wrapCoord(a,t,d),f=this.wrapCoord(i,n,d),p=this.wrapCoord(o,n,d),m=f*t+l,h=f*t+u,g=p*t+l,_=p*t+u;for(let t=0;t<y;t++){let n=e.channels[t][m],r=e.channels[t][h],i=e.channels[t][g],a=e.channels[t][_],o=n+(r-n)*s,l=i+(a-i)*s;v.channels[t][C]=o+(l-o)*c}y<4&&(v.channels[3][C]=1)}}v.markDirty(),this.setOutput(this.output,v)}},b={Color:l,Image:u,Composite:d,Checkers:f,Resize:p,NormalMap:m,Ramp:h,Noise:g,Blur:_,Text:v,Transform:y},x=`/**
3
3
  * ColorNode - creates a solid color ImageBuffer
4
4
  */
5
5
 
@@ -39,16 +39,18 @@ export class ColorNode extends ImageNodeBase {
39
39
  this.setOutput(this.output, buffer);
40
40
  }
41
41
  }
42
- `,y=`/**
42
+ `,S=`/**
43
43
  * ImageNode - loads an image file or accepts image input
44
44
  * Converts to ImageBuffer for the processing pipeline
45
45
  */
46
46
 
47
- import { ImageNodeBase, ImageBuffer, type ImageInput } from '../ImageNodeBase';
47
+ import { ImageNodeBase, ImageBuffer } from '../ImageNodeBase';
48
48
  import type { Graph } from '@/nodes/Graph';
49
49
  import type { InputPort, OutputPort } from '@/types/node.types';
50
+ import { decodeImage } from '../surface.js';
51
+ import type { ImageSourceLike } from '../ImageBuffer';
50
52
 
51
- type ImageInputValue = HTMLCanvasElement | HTMLImageElement | ImageBuffer | string | null;
53
+ type ImageInputValue = ImageSourceLike | ImageBuffer | string | null;
52
54
 
53
55
  export class ImageNode extends ImageNodeBase {
54
56
  private imageInput!: InputPort<ImageInputValue>;
@@ -136,32 +138,17 @@ export class ImageNode extends ImageNodeBase {
136
138
  protected async render(): Promise<void> {
137
139
  let sourceBuffer: ImageBuffer | null = null;
138
140
 
139
- // First check input port
141
+ // The shared decoder awaits both browser and headless image loads.
140
142
  if (this.imageInput.value) {
141
143
  if (this.imageInput.value instanceof ImageBuffer) {
142
144
  sourceBuffer = this.imageInput.value;
143
- } else if (this.imageInput.value instanceof HTMLImageElement ||
144
- this.imageInput.value instanceof HTMLCanvasElement) {
145
- sourceBuffer = ImageBuffer.fromCanvas(this.imageInput.value);
146
145
  } else if (typeof this.imageInput.value === 'string') {
147
- const img = new Image();
148
- img.crossOrigin = 'anonymous';
149
- await new Promise<void>((resolve, reject) => {
150
- img.onload = () => resolve();
151
- img.onerror = reject;
152
- img.src = this.imageInput.value as string;
153
- });
154
- sourceBuffer = ImageBuffer.fromCanvas(img);
146
+ sourceBuffer = ImageBuffer.fromCanvas(await decodeImage(this.imageInput.value));
147
+ } else {
148
+ sourceBuffer = ImageBuffer.fromCanvas(this.imageInput.value);
155
149
  }
156
150
  } else if (this.props.file.value) {
157
- const img = new Image();
158
- img.crossOrigin = 'anonymous';
159
- await new Promise<void>((resolve, reject) => {
160
- img.onload = () => resolve();
161
- img.onerror = reject;
162
- img.src = this.props.file.value;
163
- });
164
- sourceBuffer = ImageBuffer.fromCanvas(img);
151
+ sourceBuffer = ImageBuffer.fromCanvas(await decodeImage(this.props.file.value as string));
165
152
  }
166
153
 
167
154
  if (!sourceBuffer) {
@@ -233,7 +220,7 @@ export class ImageNode extends ImageNodeBase {
233
220
  return result;
234
221
  }
235
222
  }
236
- `,b=`/**
223
+ `,C=`/**
237
224
  * CompositeNode - blends two ImageBuffers together
238
225
  * Supports resolution control similar to TouchDesigner TOPs
239
226
  */
@@ -500,7 +487,7 @@ export class CompositeNode extends ImageNodeBase {
500
487
  }
501
488
  }
502
489
  }
503
- `,x=`/**
490
+ `,w=`/**
504
491
  * CheckersNode - generates a checkerboard pattern as ImageBuffer
505
492
  */
506
493
 
@@ -628,7 +615,7 @@ export class CheckersNode extends ImageNodeBase {
628
615
  this.setOutput(this.output, buffer);
629
616
  }
630
617
  }
631
- `,S=`/**
618
+ `,T=`/**
632
619
  * ResizeNode - scales or resizes an ImageBuffer with bilinear interpolation
633
620
  */
634
621
 
@@ -749,7 +736,7 @@ export class ResizeNode extends ImageNodeBase {
749
736
  this.setOutput(this.output, resized);
750
737
  }
751
738
  }
752
- `,C=`/**
739
+ `,E=`/**
753
740
  * NormalMapNode - computes normal map from height map (red/grayscale channel)
754
741
  */
755
742
 
@@ -864,7 +851,7 @@ export class NormalMapNode extends ImageNodeBase {
864
851
  this.setOutput(this.output, normalMap);
865
852
  }
866
853
  }
867
- `,w=`/**
854
+ `,D=`/**
868
855
  * RampNode - generates color ramps as ImageBuffer
869
856
  */
870
857
 
@@ -1075,7 +1062,7 @@ export class RampNode extends ImageNodeBase {
1075
1062
  this.setOutput(this.output, buffer);
1076
1063
  }
1077
1064
  }
1078
- `,T=`/**
1065
+ `,O=`/**
1079
1066
  * NoiseNode - generates procedural noise patterns as ImageBuffer
1080
1067
  */
1081
1068
 
@@ -1222,7 +1209,7 @@ export class NoiseNode extends ImageNodeBase {
1222
1209
  this.setOutput(this.output, buffer);
1223
1210
  }
1224
1211
  }
1225
- `,E=`/**
1212
+ `,k=`/**
1226
1213
  * BlurNode - applies Gaussian blur to an ImageBuffer
1227
1214
  * Uses separable convolution for efficiency
1228
1215
  */
@@ -1484,7 +1471,7 @@ export class BlurNode extends ImageNodeBase {
1484
1471
  this.setOutput(this.output, blurred);
1485
1472
  }
1486
1473
  }
1487
- `,D=`/**
1474
+ `,A=`/**
1488
1475
  * TextNode - Renders text onto an ImageBuffer
1489
1476
  *
1490
1477
  * Similar to Houdini's Font node, provides extensive control over
@@ -1495,6 +1482,7 @@ import { ImageNodeBase, ImageBuffer } from '../ImageNodeBase';
1495
1482
  import type { Graph } from '@/nodes/Graph';
1496
1483
  import type { OutputPort } from '@/types/node.types';
1497
1484
  import { colorToCss, normalizeColor } from '@/utils/colorUtils';
1485
+ import { createSurface } from '../surface.js';
1498
1486
 
1499
1487
  export class TextNode extends ImageNodeBase {
1500
1488
  private output!: OutputPort<ImageBuffer>;
@@ -1678,11 +1666,9 @@ export class TextNode extends ImageNodeBase {
1678
1666
  const lineHeight = this.props.lineHeight.value as number;
1679
1667
  const opacity = this.props.opacity.value as number;
1680
1668
 
1681
- // Create canvas for rendering
1682
- const canvas = document.createElement('canvas');
1683
- canvas.width = width;
1684
- canvas.height = height;
1685
- const ctx = canvas.getContext('2d');
1669
+ // Use the current host's Canvas 2D surface.
1670
+ const canvas = createSurface(width, height);
1671
+ const ctx = canvas.getContext('2d') as CanvasRenderingContext2D | null;
1686
1672
  if (!ctx) {
1687
1673
  this.setOutput(this.output, ImageBuffer.rgba(width, height));
1688
1674
  return;
@@ -1809,7 +1795,7 @@ export class TextNode extends ImageNodeBase {
1809
1795
  this.setOutput(this.output, buffer);
1810
1796
  }
1811
1797
  }
1812
- `,O=`/**
1798
+ `,j=`/**
1813
1799
  * TransformNode - 2D transformation (rotation, translation, scaling) for images
1814
1800
  */
1815
1801
 
@@ -2073,4 +2059,4 @@ export class TransformNode extends ImageNodeBase {
2073
2059
  this.setOutput(this.output, buffer);
2074
2060
  }
2075
2061
  }
2076
- `;function k(e,t){let n=document.createElement(`canvas`);return n.width=e,n.height=t,n}function A(e){return e instanceof HTMLCanvasElement?{width:e.width,height:e.height}:e instanceof HTMLImageElement?{width:e.naturalWidth||e.width,height:e.naturalHeight||e.height}:{width:0,height:0}}function j(e){if(e instanceof HTMLCanvasElement)return e;let t=k(e.naturalWidth||e.width,e.naturalHeight||e.height),n=t.getContext(`2d`);return n&&n.drawImage(e,0,0),t}function M(e){return new Promise((t,n)=>{let r=new Image;r.crossOrigin=`anonymous`,r.onload=()=>t(r),r.onerror=()=>n(Error(`Failed to load image: ${e}`)),r.src=e})}function N(e,t,n){let{width:r,height:i}=A(e),a=r/i,o=r,s=i;r>t&&(o=t,s=t/a),s>n&&(s=n,o=n*a);let c=k(Math.round(o),Math.round(s)),l=c.getContext(`2d`);return l&&l.drawImage(e,0,0,c.width,c.height),c}function P(e,t,n){let r=k(t,n),i=r.getContext(`2d`);return i&&i.drawImage(e,0,0,t,n),r}function F(e,t){let{width:n,height:r}=A(e);return P(e,Math.round(n*t),Math.round(r*t))}function I(e){return{normal:`source-over`,multiply:`multiply`,screen:`screen`,overlay:`overlay`,darken:`darken`,lighten:`lighten`,"color-dodge":`color-dodge`,"color-burn":`color-burn`,"hard-light":`hard-light`,"soft-light":`soft-light`,difference:`difference`,exclusion:`exclusion`,add:`lighter`,subtract:`difference`}[e]||`source-over`}var L={Color:s,Image:c,Composite:l,Checkers:u,Resize:d,NormalMap:f,Ramp:p,Noise:m,Blur:h,Text:g,Transform:_};t(`image`,L),e(`Color`,v),e(`Image`,y),e(`Composite`,b),e(`Checkers`,x),e(`Resize`,S),e(`NormalMap`,C),e(`Ramp`,w),e(`Noise`,T),e(`Blur`,E),e(`Text`,D),e(`Transform`,O);export{h as BlurNode,u as CheckersNode,s as ColorNode,l as CompositeNode,c as ImageNode,o as ImageNodeBase,m as NoiseNode,f as NormalMapNode,p as RampNode,d as ResizeNode,g as TextNode,_ as TransformNode,k as createCanvas,I as getBlendMode,A as getImageResolution,a as imageLibrary,L as imageNodeClasses,j as imageToCanvas,M as loadImage,P as resizeImageToFixed,N as resizeImageWithAspectRatio,F as scaleImage};
2062
+ `;function M(e,t){let n=document.createElement(`canvas`);return n.width=e,n.height=t,n}function N(e){return e instanceof HTMLCanvasElement?{width:e.width,height:e.height}:e instanceof HTMLImageElement?{width:e.naturalWidth||e.width,height:e.naturalHeight||e.height}:{width:0,height:0}}function P(e){if(e instanceof HTMLCanvasElement)return e;let t=M(e.naturalWidth||e.width,e.naturalHeight||e.height),n=t.getContext(`2d`);return n&&n.drawImage(e,0,0),t}function F(e){return new Promise((t,n)=>{let r=new Image;r.crossOrigin=`anonymous`,r.onload=()=>t(r),r.onerror=()=>n(Error(`Failed to load image: ${e}`)),r.src=e})}function I(e,t,n){let{width:r,height:i}=N(e),a=r/i,o=r,s=i;r>t&&(o=t,s=t/a),s>n&&(s=n,o=n*a);let c=M(Math.round(o),Math.round(s)),l=c.getContext(`2d`);return l&&l.drawImage(e,0,0,c.width,c.height),c}function L(e,t,n){let r=M(t,n),i=r.getContext(`2d`);return i&&i.drawImage(e,0,0,t,n),r}function R(e,t){let{width:n,height:r}=N(e);return L(e,Math.round(n*t),Math.round(r*t))}function z(e){return{normal:`source-over`,multiply:`multiply`,screen:`screen`,overlay:`overlay`,darken:`darken`,lighten:`lighten`,"color-dodge":`color-dodge`,"color-burn":`color-burn`,"hard-light":`hard-light`,"soft-light":`soft-light`,difference:`difference`,exclusion:`exclusion`,add:`lighter`,subtract:`difference`}[e]||`source-over`}e(`image`,b),t(`Color`,x),t(`Image`,S),t(`Composite`,C),t(`Checkers`,w),t(`Resize`,T),t(`NormalMap`,E),t(`Ramp`,D),t(`Noise`,O),t(`Blur`,k),t(`Text`,A),t(`Transform`,j);export{_ as BlurNode,f as CheckersNode,l as ColorNode,d as CompositeNode,u as ImageNode,s as ImageNodeBase,g as NoiseNode,m as NormalMapNode,h as RampNode,p as ResizeNode,v as TextNode,y as TransformNode,M as createCanvas,z as getBlendMode,N as getImageResolution,o as imageLibrary,b as imageNodeClasses,P as imageToCanvas,F as loadImage,L as resizeImageToFixed,I as resizeImageWithAspectRatio,R as scaleImage};