framefields 2.0.2

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 (408) hide show
  1. package/LICENCE +202 -0
  2. package/README.md +740 -0
  3. package/dist/audio/index.d.mts +5 -0
  4. package/dist/audio/index.mjs +14 -0
  5. package/dist/audio-Dvwwz8xU.d.mts +37 -0
  6. package/dist/audio-Dvwwz8xU.d.mts.map +1 -0
  7. package/dist/audio-TAvPwzLR.mjs +214 -0
  8. package/dist/audio-TAvPwzLR.mjs.map +1 -0
  9. package/dist/audio-x28ZgQBP.mjs +85 -0
  10. package/dist/audio-x28ZgQBP.mjs.map +1 -0
  11. package/dist/chunk-GMkBE123.mjs +47 -0
  12. package/dist/client-C74hb7fy.mjs +66 -0
  13. package/dist/client-C74hb7fy.mjs.map +1 -0
  14. package/dist/dist-1iUYuPct.mjs +1859 -0
  15. package/dist/dist-1iUYuPct.mjs.map +1 -0
  16. package/dist/dist-Bx6J0VcM.mjs +1859 -0
  17. package/dist/dist-Bx6J0VcM.mjs.map +1 -0
  18. package/dist/dist-C_hjvkdN.mjs +2220 -0
  19. package/dist/dist-C_hjvkdN.mjs.map +1 -0
  20. package/dist/dist-DKm2IyEJ.mjs +94 -0
  21. package/dist/dist-DKm2IyEJ.mjs.map +1 -0
  22. package/dist/dist-cjs-B5EVqDFp.mjs +85 -0
  23. package/dist/dist-cjs-B5EVqDFp.mjs.map +1 -0
  24. package/dist/dist-cjs-BGJkdexX.mjs +437 -0
  25. package/dist/dist-cjs-BGJkdexX.mjs.map +1 -0
  26. package/dist/dist-cjs-BKmGCgtm.mjs +9069 -0
  27. package/dist/dist-cjs-BKmGCgtm.mjs.map +1 -0
  28. package/dist/dist-cjs-BUc0_kg-.mjs +1091 -0
  29. package/dist/dist-cjs-BUc0_kg-.mjs.map +1 -0
  30. package/dist/dist-cjs-BUwe2XhR.mjs +153 -0
  31. package/dist/dist-cjs-BUwe2XhR.mjs.map +1 -0
  32. package/dist/dist-cjs-BWgoUCXJ.mjs +137 -0
  33. package/dist/dist-cjs-BWgoUCXJ.mjs.map +1 -0
  34. package/dist/dist-cjs-CmZEMtO6.mjs +6 -0
  35. package/dist/dist-cjs-D7kEM-Mj.mjs +181 -0
  36. package/dist/dist-cjs-D7kEM-Mj.mjs.map +1 -0
  37. package/dist/dist-cjs-DFUmy89O.mjs +48 -0
  38. package/dist/dist-cjs-DFUmy89O.mjs.map +1 -0
  39. package/dist/dist-cjs-Df7144zM.mjs +209 -0
  40. package/dist/dist-cjs-Df7144zM.mjs.map +1 -0
  41. package/dist/dist-cjs-DgxjcvBN.mjs +98 -0
  42. package/dist/dist-cjs-DgxjcvBN.mjs.map +1 -0
  43. package/dist/dist-cjs-DsMdld8l.mjs +5015 -0
  44. package/dist/dist-cjs-DsMdld8l.mjs.map +1 -0
  45. package/dist/dist-cjs-Dzs5P3K0.mjs +51 -0
  46. package/dist/dist-cjs-Dzs5P3K0.mjs.map +1 -0
  47. package/dist/dist-cjs-ECMuIF57.mjs +323 -0
  48. package/dist/dist-cjs-ECMuIF57.mjs.map +1 -0
  49. package/dist/dist-cjs-lYvO8aDo.mjs +64 -0
  50. package/dist/dist-cjs-lYvO8aDo.mjs.map +1 -0
  51. package/dist/dist-cjs-qEJrwjGk.mjs +66 -0
  52. package/dist/dist-cjs-qEJrwjGk.mjs.map +1 -0
  53. package/dist/dist-cjs-x5cwlqA5.mjs +43 -0
  54. package/dist/dist-cjs-x5cwlqA5.mjs.map +1 -0
  55. package/dist/dist-gjHmorxL.mjs +27479 -0
  56. package/dist/dist-gjHmorxL.mjs.map +1 -0
  57. package/dist/effects/index.d.mts +5 -0
  58. package/dist/effects/index.mjs +35 -0
  59. package/dist/effects-CHWORCYd.mjs +811 -0
  60. package/dist/effects-CHWORCYd.mjs.map +1 -0
  61. package/dist/event-streams-D-APZ7Ke.mjs +204 -0
  62. package/dist/event-streams-D-APZ7Ke.mjs.map +1 -0
  63. package/dist/fonts/index.d.mts +2 -0
  64. package/dist/fonts/index.mjs +3 -0
  65. package/dist/fonts-DrGTBJJk.mjs +188 -0
  66. package/dist/fonts-DrGTBJJk.mjs.map +1 -0
  67. package/dist/index-B0BNPEoH.d.mts +2117 -0
  68. package/dist/index-B0BNPEoH.d.mts.map +1 -0
  69. package/dist/index-BMVVmc4G.d.mts +72 -0
  70. package/dist/index-BMVVmc4G.d.mts.map +1 -0
  71. package/dist/index-D1ZsMpke.d.mts +264 -0
  72. package/dist/index-D1ZsMpke.d.mts.map +1 -0
  73. package/dist/index-D2jDC7O5.d.mts +3643 -0
  74. package/dist/index-D2jDC7O5.d.mts.map +1 -0
  75. package/dist/index-D2wJqSl5.d.mts +114 -0
  76. package/dist/index-D2wJqSl5.d.mts.map +1 -0
  77. package/dist/index-DKFGNyMB.d.mts +309 -0
  78. package/dist/index-DKFGNyMB.d.mts.map +1 -0
  79. package/dist/index-DiSKzDGR.d.mts +65 -0
  80. package/dist/index-DiSKzDGR.d.mts.map +1 -0
  81. package/dist/index.d.mts +4425 -0
  82. package/dist/index.d.mts.map +1 -0
  83. package/dist/index.mjs +2623 -0
  84. package/dist/index.mjs.map +1 -0
  85. package/dist/package-C58KmGKw.mjs +6 -0
  86. package/dist/package-C58KmGKw.mjs.map +1 -0
  87. package/dist/preview/index.d.mts +90 -0
  88. package/dist/preview/index.d.mts.map +1 -0
  89. package/dist/preview/index.mjs +15 -0
  90. package/dist/preview-engine/audio.mjs +1 -0
  91. package/dist/preview-engine/child_process-AIL2NBWS.mjs +1 -0
  92. package/dist/preview-engine/chunk-24P6DAB3.mjs +1 -0
  93. package/dist/preview-engine/chunk-37EFVZWT.mjs +1 -0
  94. package/dist/preview-engine/chunk-3O5OKR6D.mjs +223 -0
  95. package/dist/preview-engine/chunk-47VT677S.mjs +8 -0
  96. package/dist/preview-engine/chunk-4BEJJKEU.mjs +315 -0
  97. package/dist/preview-engine/chunk-4GEWSUX5.mjs +1 -0
  98. package/dist/preview-engine/chunk-55CCFPUX.mjs +237 -0
  99. package/dist/preview-engine/chunk-5JD65JSJ.mjs +110 -0
  100. package/dist/preview-engine/chunk-5UP7FSGT.mjs +294 -0
  101. package/dist/preview-engine/chunk-5XDHHOF2.mjs +367 -0
  102. package/dist/preview-engine/chunk-6YJP57MZ.mjs +729 -0
  103. package/dist/preview-engine/chunk-6ZOXGAYA.mjs +112 -0
  104. package/dist/preview-engine/chunk-AOLAHYVV.mjs +529 -0
  105. package/dist/preview-engine/chunk-B6PLCMBM.mjs +1 -0
  106. package/dist/preview-engine/chunk-BJKH76OM.mjs +264 -0
  107. package/dist/preview-engine/chunk-BUIQ5TUH.mjs +104 -0
  108. package/dist/preview-engine/chunk-BVF64D6H.mjs +1 -0
  109. package/dist/preview-engine/chunk-CA5N7JRZ.mjs +138 -0
  110. package/dist/preview-engine/chunk-CNSHAFEA.mjs +1 -0
  111. package/dist/preview-engine/chunk-CURR5X7D.mjs +1 -0
  112. package/dist/preview-engine/chunk-CVGM2U4J.mjs +47 -0
  113. package/dist/preview-engine/chunk-CYY366IE.mjs +1 -0
  114. package/dist/preview-engine/chunk-D5PHI6ET.mjs +109 -0
  115. package/dist/preview-engine/chunk-D7MZHP2Y.mjs +275 -0
  116. package/dist/preview-engine/chunk-DPPH3NK2.mjs +182 -0
  117. package/dist/preview-engine/chunk-DPST2XLC.mjs +418 -0
  118. package/dist/preview-engine/chunk-DRLEOHN5.mjs +1 -0
  119. package/dist/preview-engine/chunk-EDIZNO3P.mjs +1 -0
  120. package/dist/preview-engine/chunk-EHIIT4ZR.mjs +52 -0
  121. package/dist/preview-engine/chunk-FKZ4XXPE.mjs +1 -0
  122. package/dist/preview-engine/chunk-G3HW4VER.mjs +60 -0
  123. package/dist/preview-engine/chunk-G76HSKOS.mjs +184 -0
  124. package/dist/preview-engine/chunk-GYG2IIBR.mjs +1 -0
  125. package/dist/preview-engine/chunk-H2F5NVQ6.mjs +63 -0
  126. package/dist/preview-engine/chunk-H5BPCY7N.mjs +188 -0
  127. package/dist/preview-engine/chunk-HAXK42HG.mjs +997 -0
  128. package/dist/preview-engine/chunk-HXMDPMLB.mjs +1 -0
  129. package/dist/preview-engine/chunk-HYBAPT6I.mjs +1 -0
  130. package/dist/preview-engine/chunk-I4FH6HYU.mjs +73 -0
  131. package/dist/preview-engine/chunk-IYVN2QEL.mjs +1 -0
  132. package/dist/preview-engine/chunk-JPXQPP6J.mjs +1 -0
  133. package/dist/preview-engine/chunk-JWNHTRED.mjs +164 -0
  134. package/dist/preview-engine/chunk-KZOLCZIV.mjs +103 -0
  135. package/dist/preview-engine/chunk-L62MRHGZ.mjs +89 -0
  136. package/dist/preview-engine/chunk-LEEZXHQO.mjs +117 -0
  137. package/dist/preview-engine/chunk-LKYN3BM2.mjs +1 -0
  138. package/dist/preview-engine/chunk-LP3EP33S.mjs +610 -0
  139. package/dist/preview-engine/chunk-M2GRYRLM.mjs +111 -0
  140. package/dist/preview-engine/chunk-MC7TZZLD.mjs +134 -0
  141. package/dist/preview-engine/chunk-MT2DZQHO.mjs +1 -0
  142. package/dist/preview-engine/chunk-MTJHQATU.mjs +1 -0
  143. package/dist/preview-engine/chunk-N4LHIPHZ.mjs +340 -0
  144. package/dist/preview-engine/chunk-N4PWLBZ7.mjs +5 -0
  145. package/dist/preview-engine/chunk-NQZKBFC6.mjs +40 -0
  146. package/dist/preview-engine/chunk-NWRSVVTF.mjs +186 -0
  147. package/dist/preview-engine/chunk-P3HBP725.mjs +1 -0
  148. package/dist/preview-engine/chunk-PIAJWALT.mjs +1 -0
  149. package/dist/preview-engine/chunk-PJ3DVG45.mjs +1 -0
  150. package/dist/preview-engine/chunk-QP2NI4XD.mjs +82 -0
  151. package/dist/preview-engine/chunk-SA3JUR6D.mjs +52 -0
  152. package/dist/preview-engine/chunk-SRT2OCQW.mjs +1 -0
  153. package/dist/preview-engine/chunk-SWD76532.mjs +98 -0
  154. package/dist/preview-engine/chunk-SXX7HX34.mjs +191 -0
  155. package/dist/preview-engine/chunk-SZ7YRPKO.mjs +3 -0
  156. package/dist/preview-engine/chunk-TMRLZV5X.mjs +1 -0
  157. package/dist/preview-engine/chunk-U446SQP3.mjs +292 -0
  158. package/dist/preview-engine/chunk-UDNCEHUI.mjs +141 -0
  159. package/dist/preview-engine/chunk-V3H7WWOT.mjs +271 -0
  160. package/dist/preview-engine/chunk-V7ZVVUQU.mjs +108 -0
  161. package/dist/preview-engine/chunk-VJGK7MLJ.mjs +3 -0
  162. package/dist/preview-engine/chunk-VSSB73UU.mjs +58 -0
  163. package/dist/preview-engine/chunk-VXUJWPIK.mjs +1 -0
  164. package/dist/preview-engine/chunk-XD4GKD6H.mjs +5 -0
  165. package/dist/preview-engine/chunk-XKO4RYKN.mjs +3 -0
  166. package/dist/preview-engine/chunk-XOEEGC4Z.mjs +1 -0
  167. package/dist/preview-engine/chunk-YAQFFQPG.mjs +1 -0
  168. package/dist/preview-engine/chunk-YKMBRUAE.mjs +1 -0
  169. package/dist/preview-engine/chunk-YSTLMWCG.mjs +1 -0
  170. package/dist/preview-engine/chunk-Z4ERCLNF.mjs +1 -0
  171. package/dist/preview-engine/chunk-ZEYUXJIV.mjs +1 -0
  172. package/dist/preview-engine/chunk-ZX6APG6E.mjs +117 -0
  173. package/dist/preview-engine/effects.mjs +1 -0
  174. package/dist/preview-engine/esbuild-GWV7CM7D.mjs +1 -0
  175. package/dist/preview-engine/fonts.mjs +1 -0
  176. package/dist/preview-engine/framefields.mjs +1959 -0
  177. package/dist/preview-engine/onnxruntime-node-56GSZEH3.mjs +1 -0
  178. package/dist/preview-engine/player.mjs +155 -0
  179. package/dist/preview-engine/renderers-2AUSIYZN.mjs +1 -0
  180. package/dist/preview-engine/renderers-2QN6KZJP.mjs +1 -0
  181. package/dist/preview-engine/renderers-32SKW7ML.mjs +1 -0
  182. package/dist/preview-engine/renderers-5QYK6766.mjs +1 -0
  183. package/dist/preview-engine/renderers-6BJA6MSU.mjs +251 -0
  184. package/dist/preview-engine/renderers-6QAF3LQ2.mjs +1 -0
  185. package/dist/preview-engine/renderers-7AO5746S.mjs +296 -0
  186. package/dist/preview-engine/renderers-AFYKNM6N.mjs +1 -0
  187. package/dist/preview-engine/renderers-AGMH5CRH.mjs +1 -0
  188. package/dist/preview-engine/renderers-AHSGP6LY.mjs +126 -0
  189. package/dist/preview-engine/renderers-ASTBICLA.mjs +1 -0
  190. package/dist/preview-engine/renderers-BHVPLYNN.mjs +1 -0
  191. package/dist/preview-engine/renderers-D7PVQFVU.mjs +1 -0
  192. package/dist/preview-engine/renderers-DB4ABTNA.mjs +1 -0
  193. package/dist/preview-engine/renderers-F2NFJI5L.mjs +1 -0
  194. package/dist/preview-engine/renderers-FI7YHNLY.mjs +1 -0
  195. package/dist/preview-engine/renderers-GBHULMPH.mjs +1 -0
  196. package/dist/preview-engine/renderers-GUKQUMGG.mjs +55 -0
  197. package/dist/preview-engine/renderers-HGT7QDY3.mjs +1 -0
  198. package/dist/preview-engine/renderers-HOYLA7ZK.mjs +1 -0
  199. package/dist/preview-engine/renderers-KKI2D3MZ.mjs +1 -0
  200. package/dist/preview-engine/renderers-KRAJNV4E.mjs +1 -0
  201. package/dist/preview-engine/renderers-KUGZKSVE.mjs +1 -0
  202. package/dist/preview-engine/renderers-L2EQQIOC.mjs +1 -0
  203. package/dist/preview-engine/renderers-LK3NRMGR.mjs +1 -0
  204. package/dist/preview-engine/renderers-LX654SZ3.mjs +1 -0
  205. package/dist/preview-engine/renderers-MCFQFYEL.mjs +1 -0
  206. package/dist/preview-engine/renderers-O6HOYIPS.mjs +1 -0
  207. package/dist/preview-engine/renderers-OEVXCGE2.mjs +1 -0
  208. package/dist/preview-engine/renderers-QVD6C4CS.mjs +1 -0
  209. package/dist/preview-engine/renderers-R3XEYD5V.mjs +248 -0
  210. package/dist/preview-engine/renderers-RBFWJWVM.mjs +1 -0
  211. package/dist/preview-engine/renderers-RX3VLVLO.mjs +1 -0
  212. package/dist/preview-engine/renderers-SM6JP64K.mjs +1 -0
  213. package/dist/preview-engine/renderers-TKMAATVS.mjs +1 -0
  214. package/dist/preview-engine/renderers-UGZUPONY.mjs +1 -0
  215. package/dist/preview-engine/renderers-UTFXZE3G.mjs +1 -0
  216. package/dist/preview-engine/renderers-UWPH7HBH.mjs +1 -0
  217. package/dist/preview-engine/renderers-UZGECFVO.mjs +1 -0
  218. package/dist/preview-engine/renderers-VGU3LNLT.mjs +1 -0
  219. package/dist/preview-engine/renderers-W3VVM5HB.mjs +1 -0
  220. package/dist/preview-engine/renderers-WJUTT5BB.mjs +1 -0
  221. package/dist/preview-engine/renderers-XA2M4YXK.mjs +1 -0
  222. package/dist/preview-engine/renderers-XIHRFEFQ.mjs +1 -0
  223. package/dist/preview-engine/renderers-XJTA5MFG.mjs +1 -0
  224. package/dist/preview-engine/renderers-XLTY5APF.mjs +1 -0
  225. package/dist/preview-engine/renderers-XZ3VXFGZ.mjs +1 -0
  226. package/dist/preview-engine/renderers-YKUQUCTO.mjs +124 -0
  227. package/dist/preview-engine/renderers-YVN3EIOP.mjs +1 -0
  228. package/dist/preview-engine/renderers-YWRP23SZ.mjs +125 -0
  229. package/dist/preview-engine/renderers-ZPWOUWZJ.mjs +120 -0
  230. package/dist/preview-engine/resvg-js-VMU4A77S.mjs +1 -0
  231. package/dist/preview-engine/server-utils-2FAIV45N.mjs +1 -0
  232. package/dist/preview-engine/sharp-V6ZTBNDW.mjs +1 -0
  233. package/dist/preview-engine/shims/fs-promises.mjs +1 -0
  234. package/dist/preview-engine/shims/fs.mjs +1 -0
  235. package/dist/preview-engine/shims/module.mjs +1 -0
  236. package/dist/preview-engine/shims/os.mjs +1 -0
  237. package/dist/preview-engine/shims/path.mjs +1 -0
  238. package/dist/preview-engine/shims/url.mjs +1 -0
  239. package/dist/preview-engine/signals.mjs +1 -0
  240. package/dist/preview-engine/webgpu-NSSANM4F.mjs +1 -0
  241. package/dist/preview-uQM210iy.mjs +2149 -0
  242. package/dist/preview-uQM210iy.mjs.map +1 -0
  243. package/dist/program-Dl510wmI.mjs +5183 -0
  244. package/dist/program-Dl510wmI.mjs.map +1 -0
  245. package/dist/renderer/index.d.mts +3 -0
  246. package/dist/renderer/index.mjs +6 -0
  247. package/dist/renderer-3BNskNuJ.mjs +3 -0
  248. package/dist/renderer-7DOcIxFG.mjs +288 -0
  249. package/dist/renderer-7DOcIxFG.mjs.map +1 -0
  250. package/dist/renderer-9dHlMQGX.mjs +3 -0
  251. package/dist/renderer-B1CvhW4p.mjs +677 -0
  252. package/dist/renderer-B1CvhW4p.mjs.map +1 -0
  253. package/dist/renderer-B2XzjK0z.mjs +3 -0
  254. package/dist/renderer-B80s47yo.mjs +166 -0
  255. package/dist/renderer-B80s47yo.mjs.map +1 -0
  256. package/dist/renderer-B9-QSJcG.mjs +479 -0
  257. package/dist/renderer-B9-QSJcG.mjs.map +1 -0
  258. package/dist/renderer-BAQmR0Zo.mjs +3 -0
  259. package/dist/renderer-BDLnExoP.mjs +127 -0
  260. package/dist/renderer-BDLnExoP.mjs.map +1 -0
  261. package/dist/renderer-BGXU6vcW.mjs +270 -0
  262. package/dist/renderer-BGXU6vcW.mjs.map +1 -0
  263. package/dist/renderer-BGvORwkQ.mjs +3 -0
  264. package/dist/renderer-BLikd6BK.mjs +3 -0
  265. package/dist/renderer-BMovYRoR.mjs +3 -0
  266. package/dist/renderer-BQHbp-Sp.mjs +243 -0
  267. package/dist/renderer-BQHbp-Sp.mjs.map +1 -0
  268. package/dist/renderer-BREIjsUU.mjs +252 -0
  269. package/dist/renderer-BREIjsUU.mjs.map +1 -0
  270. package/dist/renderer-BSbTJBWc.mjs +3 -0
  271. package/dist/renderer-BTu2EVhF.mjs +3 -0
  272. package/dist/renderer-BU1rwNRT.mjs +3 -0
  273. package/dist/renderer-BXMmISWG.mjs +499 -0
  274. package/dist/renderer-BXMmISWG.mjs.map +1 -0
  275. package/dist/renderer-BZJm3m4f.mjs +3 -0
  276. package/dist/renderer-B_NuVaIP.mjs +744 -0
  277. package/dist/renderer-B_NuVaIP.mjs.map +1 -0
  278. package/dist/renderer-BfJSUjPN.mjs +3 -0
  279. package/dist/renderer-BqyAgNt3.mjs +3 -0
  280. package/dist/renderer-BryTM2g7.mjs +3 -0
  281. package/dist/renderer-BsgIcBKH.mjs +391 -0
  282. package/dist/renderer-BsgIcBKH.mjs.map +1 -0
  283. package/dist/renderer-ByDhfrPE.mjs +422 -0
  284. package/dist/renderer-ByDhfrPE.mjs.map +1 -0
  285. package/dist/renderer-C-H680_l.mjs +3 -0
  286. package/dist/renderer-C17wL9QX.mjs +181 -0
  287. package/dist/renderer-C17wL9QX.mjs.map +1 -0
  288. package/dist/renderer-C2n-EHxg.mjs +1 -0
  289. package/dist/renderer-CB5aWAaf.mjs +343 -0
  290. package/dist/renderer-CB5aWAaf.mjs.map +1 -0
  291. package/dist/renderer-CB7lH5K8.mjs +3 -0
  292. package/dist/renderer-CDLrNgfo.mjs +3 -0
  293. package/dist/renderer-CDOUAN7X.mjs +454 -0
  294. package/dist/renderer-CDOUAN7X.mjs.map +1 -0
  295. package/dist/renderer-CH8sdfYX.mjs +387 -0
  296. package/dist/renderer-CH8sdfYX.mjs.map +1 -0
  297. package/dist/renderer-CIvaRnP_.mjs +261 -0
  298. package/dist/renderer-CIvaRnP_.mjs.map +1 -0
  299. package/dist/renderer-CMzEjdzi.mjs +369 -0
  300. package/dist/renderer-CMzEjdzi.mjs.map +1 -0
  301. package/dist/renderer-COkcU3db.mjs +3302 -0
  302. package/dist/renderer-COkcU3db.mjs.map +1 -0
  303. package/dist/renderer-CQCoggIa.mjs +3 -0
  304. package/dist/renderer-CQdVj2JS.mjs +3 -0
  305. package/dist/renderer-CQiTodg9.mjs +337 -0
  306. package/dist/renderer-CQiTodg9.mjs.map +1 -0
  307. package/dist/renderer-CV2m6k1V.mjs +3 -0
  308. package/dist/renderer-CYY-poLe.mjs +3 -0
  309. package/dist/renderer-CZgB5st8.mjs +3 -0
  310. package/dist/renderer-C_Ki91kc.mjs +3 -0
  311. package/dist/renderer-CclIvsLO.mjs +3 -0
  312. package/dist/renderer-Cj-whdVr.mjs +655 -0
  313. package/dist/renderer-Cj-whdVr.mjs.map +1 -0
  314. package/dist/renderer-CkykdR_D.mjs +3 -0
  315. package/dist/renderer-Cl1oUXMi.mjs +1143 -0
  316. package/dist/renderer-Cl1oUXMi.mjs.map +1 -0
  317. package/dist/renderer-CmApuKjS.mjs +3 -0
  318. package/dist/renderer-CpkiHRhh.mjs +269 -0
  319. package/dist/renderer-CpkiHRhh.mjs.map +1 -0
  320. package/dist/renderer-CszOjcRW.mjs +3 -0
  321. package/dist/renderer-CtVkU_GA.mjs +44 -0
  322. package/dist/renderer-CtVkU_GA.mjs.map +1 -0
  323. package/dist/renderer-Cu074POw.mjs +3 -0
  324. package/dist/renderer-CwQhzcUn.mjs +644 -0
  325. package/dist/renderer-CwQhzcUn.mjs.map +1 -0
  326. package/dist/renderer-CzPWB0Ss.mjs +273 -0
  327. package/dist/renderer-CzPWB0Ss.mjs.map +1 -0
  328. package/dist/renderer-D4qLmox-.mjs +3 -0
  329. package/dist/renderer-D6bWQtr-.mjs +3 -0
  330. package/dist/renderer-D6cJ6MSq.mjs +3 -0
  331. package/dist/renderer-D7EX8IjU.mjs +240 -0
  332. package/dist/renderer-D7EX8IjU.mjs.map +1 -0
  333. package/dist/renderer-DDp7_TUi.d.mts +10 -0
  334. package/dist/renderer-DDp7_TUi.d.mts.map +1 -0
  335. package/dist/renderer-DFKsLrUs.mjs +256 -0
  336. package/dist/renderer-DFKsLrUs.mjs.map +1 -0
  337. package/dist/renderer-DPSsf8-t.mjs +3 -0
  338. package/dist/renderer-DQLGnEFc.mjs +3 -0
  339. package/dist/renderer-DY2SVYUW.mjs +3 -0
  340. package/dist/renderer-DZGtBUCx.mjs +792 -0
  341. package/dist/renderer-DZGtBUCx.mjs.map +1 -0
  342. package/dist/renderer-DabG62XS.mjs +406 -0
  343. package/dist/renderer-DabG62XS.mjs.map +1 -0
  344. package/dist/renderer-DbaQLI4z.mjs +771 -0
  345. package/dist/renderer-DbaQLI4z.mjs.map +1 -0
  346. package/dist/renderer-DjI45OYC.mjs +71 -0
  347. package/dist/renderer-DjI45OYC.mjs.map +1 -0
  348. package/dist/renderer-Dm08-hAU.mjs +323 -0
  349. package/dist/renderer-Dm08-hAU.mjs.map +1 -0
  350. package/dist/renderer-DoAY5JbB.mjs +4 -0
  351. package/dist/renderer-Dp_FfvF-.mjs +401 -0
  352. package/dist/renderer-Dp_FfvF-.mjs.map +1 -0
  353. package/dist/renderer-Dt6fzgX5.mjs +756 -0
  354. package/dist/renderer-Dt6fzgX5.mjs.map +1 -0
  355. package/dist/renderer-DuplLRbp.mjs +3 -0
  356. package/dist/renderer-DvfUbZ31.mjs +3 -0
  357. package/dist/renderer-DxjVQV6f.mjs +311 -0
  358. package/dist/renderer-DxjVQV6f.mjs.map +1 -0
  359. package/dist/renderer-Fco4EmAu.mjs +23868 -0
  360. package/dist/renderer-Fco4EmAu.mjs.map +1 -0
  361. package/dist/renderer-HFfcJlmR.mjs +981 -0
  362. package/dist/renderer-HFfcJlmR.mjs.map +1 -0
  363. package/dist/renderer-I-Sw3JBB.mjs +145 -0
  364. package/dist/renderer-I-Sw3JBB.mjs.map +1 -0
  365. package/dist/renderer-OWQmmg4Z.mjs +697 -0
  366. package/dist/renderer-OWQmmg4Z.mjs.map +1 -0
  367. package/dist/renderer-Q_uUQipO.mjs +3 -0
  368. package/dist/renderer-Ryo2CEFD.mjs +586 -0
  369. package/dist/renderer-Ryo2CEFD.mjs.map +1 -0
  370. package/dist/renderer-Tp6OXWNZ.mjs +257 -0
  371. package/dist/renderer-Tp6OXWNZ.mjs.map +1 -0
  372. package/dist/renderer-UQFCgeNx.mjs +3 -0
  373. package/dist/renderer-WkVrkCVA.mjs +83 -0
  374. package/dist/renderer-WkVrkCVA.mjs.map +1 -0
  375. package/dist/renderer-XcmYTd6P.mjs +3818 -0
  376. package/dist/renderer-XcmYTd6P.mjs.map +1 -0
  377. package/dist/renderer-_uvdg48N.mjs +333 -0
  378. package/dist/renderer-_uvdg48N.mjs.map +1 -0
  379. package/dist/renderer-bZU_ndxf.mjs +8 -0
  380. package/dist/renderer-bZU_ndxf.mjs.map +1 -0
  381. package/dist/renderer-eMsnzJg9.mjs +3 -0
  382. package/dist/renderer-ho_jXJ0H.mjs +254 -0
  383. package/dist/renderer-ho_jXJ0H.mjs.map +1 -0
  384. package/dist/renderer-k2JL79kM.mjs +306 -0
  385. package/dist/renderer-k2JL79kM.mjs.map +1 -0
  386. package/dist/renderer-pHiz78e0.mjs +3 -0
  387. package/dist/renderer-pxXf9dvk.mjs +394 -0
  388. package/dist/renderer-pxXf9dvk.mjs.map +1 -0
  389. package/dist/renderer-vCFTm0oe.mjs +226 -0
  390. package/dist/renderer-vCFTm0oe.mjs.map +1 -0
  391. package/dist/renderer-vvpdx1vk.mjs +379 -0
  392. package/dist/renderer-vvpdx1vk.mjs.map +1 -0
  393. package/dist/renderer-x2s9LmVL.mjs +1121 -0
  394. package/dist/renderer-x2s9LmVL.mjs.map +1 -0
  395. package/dist/renderers-BWg16W-V-BXG_cjhM.mjs +49 -0
  396. package/dist/renderers-BWg16W-V-BXG_cjhM.mjs.map +1 -0
  397. package/dist/signals/index.d.mts +7 -0
  398. package/dist/signals/index.mjs +10 -0
  399. package/dist/signals-BwbdO3AN.mjs +224 -0
  400. package/dist/signals-BwbdO3AN.mjs.map +1 -0
  401. package/dist/signin-CZj4Oc5s.mjs +865 -0
  402. package/dist/signin-CZj4Oc5s.mjs.map +1 -0
  403. package/dist/sso-oidc-C0_31ThY.mjs +1051 -0
  404. package/dist/sso-oidc-C0_31ThY.mjs.map +1 -0
  405. package/dist/sts-DD4ggEXC.mjs +6 -0
  406. package/dist/sts-nXw8RDJI.mjs +1395 -0
  407. package/dist/sts-nXw8RDJI.mjs.map +1 -0
  408. package/package.json +173 -0
package/dist/index.mjs ADDED
@@ -0,0 +1,2623 @@
1
+ import "./chunk-GMkBE123.mjs";
2
+ import { $ as VideoAnimationSchema, A as MediaSourceSchema, At as programmaticSignal, B as SignalChannelMetaSchema, Bt as takeRenderDiagnostics, C as GeneratorSignalDataSchema, Ct as getLeafMediaType, D as MIME_TYPES, Dt as isEqual, E as JsonValueSchema, Et as hasOnlySingleSource, F as NodeResultSchema, Ft as serializeSignalData, G as SingleOutputGenericSchema, H as SignalGateDataSchema, Ht as updateClockSignals, I as NodeVisualConfigSchema, It as signal, J as TextOperationSchema, K as SourceOperationSchema, L as OutputItemSchema, Lt as signalBuilder, M as ModerationUnrefundableError, Mt as registerSignalDependency, N as MultiOutputGenericSchema, Nt as reportRenderDiagnostic, O as MediaMetadataSchema, Ot as isSignal, P as NodeMetadataSchema, Pt as resolveMediaMimeType, Q as TransitionTypeSchema, R as ProgrammaticSignal, Rt as sineSignal, S as FileDataSchema, St as getFingerprint, T as HandleTypeVal, Tt as getRenderFingerprint, U as SignalMathDataSchema, V as SignalDataSchema, Vt as timeSignal, W as SignalStatsSchema, X as TimelineTransformSchema, Y as TimelineSegmentSchema, Z as TransitionSchema, _ as DataTypes, _t as frameArraySignal, a as BaseVideoLayerPropsSchema, at as VirtualMediaDataSchema, b as ExtendedLayerSchema, bt as getActiveMediaMetadata, c as COMPOSITOR_DEFAULTS, ct as computeVideoCropRenderProps, d as DATA_TYPE_EXTENSIONS, dt as createOutputItemSchema, et as VideoLayerTypeSchema, f as DEFAULT_DURATION_MS, ft as createVirtualMedia, g as DataTypeVal, gt as findSourceAsset, h as DataType, ht as extractSvgDimensions, i as BaseMediaOperationPropsSchema, it as VideoTimingPropsSchema, j as ModerationError, jt as progressSignal, k as MediaOperationSchema, kt as isVirtualMediaData, l as ConfigHandleSchema, lt as computed, m as DEFAULT_MEDIA_DIMENSION, mt as deserializeSignalData, n as AnyOutputUnionSchema, nt as VideoStylePropsSchema, o as CAPTION_LAYER_DEFAULTS, ot as appendOperation, p as DEFAULT_FPS, pt as dataTypeColors, q as TEXT_LAYER_DEFAULTS, r as AudioExtractorSignalDataSchema, rt as VideoTextPropsSchema, s as COMPOSITE_OPERATIONS, st as checkNodeResultCache, t as AnimationTypeSchema, tt as VideoSpatialPropsSchema, u as ConfigSchemaRegistry, ut as cosineSignal, v as Effect$1, vt as frameSignal, w as GlobalCompositeOperation, wt as getMediaType, x as FileAssetSchema, xt as getFileDataMetadata, y as ExportResultSchema, yt as generateId, z as Signal, zt as stampResult } from "./dist-Bx6J0VcM.mjs";
3
+ import { B as inputStore, F as ensureDevice, G as lutStore, H as loadFBX, I as generateExtrudedTextGeometry, U as loadModel3D, W as loadOBJ, X as parseMTL, Y as parseFBX, Z as parseOBJ, _ as ShadowPipeline, a as Camera3D, c as Light3D, et as shaderStore, f as Path3D, h as SSAOPipeline, m as Renderer3D, n as AudioLatentTrackCache, o as EffectPipeline, p as Renderer2D, q as mediaDecoderCache, r as AudioMeshDeformPipeline, rt as textureCache, s as GlassPipeline, t as AudioLatentEngine, tt as signalRegistry, u as MotionBlurPipeline, x as SlugPipeline, y as SlugFontCache } from "./dist-gjHmorxL.mjs";
4
+ import "./renderers-BWg16W-V-BXG_cjhM.mjs";
5
+ import "./signals-BwbdO3AN.mjs";
6
+ import "./renderer-BXMmISWG.mjs";
7
+ import "./renderer-bZU_ndxf.mjs";
8
+ import { S as springCalculation, _ as measureTextAsync, b as requiresIsolation, c as MAX_LIGHTS, d as bezier, f as computeStrokeRect, g as measureText, h as measureSpring, i as mixAudioTracks, l as Matrix4Math, m as mapBlendModeToSkia, o as Easing, p as interpolate, s as LIGHT_UNIFORM_SIZE_BYTES, u as Vector3Math, v as parseColorToRgb, x as spring, y as preloadFont } from "./dist-1iUYuPct.mjs";
9
+ import { t as AudioSignal } from "./audio-x28ZgQBP.mjs";
10
+ import { t as FontManager } from "./fonts-DrGTBJJk.mjs";
11
+ import "./renderer-Tp6OXWNZ.mjs";
12
+ import "./renderer-vCFTm0oe.mjs";
13
+ import "./renderer-C17wL9QX.mjs";
14
+ import "./renderer-7DOcIxFG.mjs";
15
+ import "./renderer-BGXU6vcW.mjs";
16
+ import "./renderer-vvpdx1vk.mjs";
17
+ import "./renderer-C2n-EHxg.mjs";
18
+ import "./renderer-WkVrkCVA.mjs";
19
+ import { i as softLimit, n as mixSfxInto, r as renderSfx, t as encodeStereoWav } from "./audio-TAvPwzLR.mjs";
20
+ import { i as OpticalFlowComputePipeline, n as ControlNetMultiplexer, o as TemporalDeflickerPipeline, r as DepthNormalsComputePipeline, s as TensorPipeline, t as CannyComputePipeline } from "./dist-C_hjvkdN.mjs";
21
+ import { a as PoseSkeletonRenderer, c as TemporalObjectTracker, d as VisionRunner, f as analyzeSequence, h as COCO_CLASSES, i as COCO17_KEYPOINT_NAMES, l as VisionBundle, m as pinNodeToObject, n as COCO17_BONES, o as SegmentationTexturePool, p as pinNodeToLandmark, r as COCO17_KEYPOINTS, s as SpatialLandmarkTransformer, u as VisionNode } from "./renderer-XcmYTd6P.mjs";
22
+ import { $ as TextPathBuilder, A as MaterialTypeSchema, At as evaluateAnimationAtFrame, B as SelectorUnitsSchema, Bt as evaluateVolumetricFormation, C as KineticMarqueeConfigSchema, Ct as computeLayoutSync, D as LightTypeSchema, Dt as deterministicWigglyNoise, E as LightNodeSchema, Et as computeStaggerDelay, F as SceneDefinitionSchema, Ft as evaluateSelectorCombination, G as SpringPhysicsSchema, H as ShapeNodeSchema, Ht as generatePathSegments, I as SceneTransitionTypeSchema, It as evaluateSkewMatrix, J as TextAnimatorBuilder, Jt as sampleCurveGeometry, K as TextAnchorConfigSchema, Kt as parseSvgPathToCubicBeziers, L as SelectorBasedOnSchema, Lt as evaluateSpringProgress, M as Model3DNodeSchema, Mt as evaluateCubicBezierDerivative, N as ParticleDissolveConfigSchema, Nt as evaluateExpressionSelector, O as LineSpacingDynamicsSchema, Ot as distanceToCurveParameter, P as Scene, Pt as evaluateMarqueeOffset, Q as TextNodeSchema, R as SelectorModeSchema, Rt as evaluateTrackAtFrame, S as GlyphAnchorPointSchema, St as computeLayout, T as LayoutNodeSchema, Tt as computeRangeSelectorWeight, U as SkewPropertiesSchema, Ut as getScramblePool, V as Sequence, Vt as generateArcLengthLUT, W as Spatial3DPropertiesSchema, Wt as getShuffledOrder, X as TextCursorConfigSchema, Xt as waveToCubicBeziers, Y as TextAnimatorSchema, Yt as samplePathChainGeometry, Z as TextCursorStyleSchema, _ as EnhancedTextNodeSchema, _t as calculateSequenceTimeline, a as AnchorPresetSchema, at as TextSignalSelectorSchema, b as FlexNodeSchema, bt as computeAnchorPivotOffset, c as BoxNodeSchema, ct as TextWigglySelectorSchema, d as CarrierHandoffConfigSchema, dt as VariableFontAxesSchema, et as TextPathOptionsSchema, f as ChromaticGlitchConfigSchema, ft as Vec2Schema, g as DynamicStrokePropertiesSchema, gt as buildPathLUT, h as CubicBezierSegmentSchema, ht as applyStaggerToChildren, i as AnchorGroupingSchema, it as TextSelectorSchema, j as MediaNodeSchema, jt as evaluateCubicBezier, k as LongShadowConfigSchema, kt as ellipseToCubicBeziers, l as CameraAnimation, lt as TypewriterAnimatorSchema, m as CompositorProgramSchema, mt as VolumetricFormationModeSchema, n as AdvancedTextAnimatorBuilder, nt as TextRangeSelectorSchema, o as AnimatableGlyphPropsSchema, ot as TextSpanMarkSchema, p as ColorStopSchema, pt as VolumetricFormationConfigSchema, q as TextAnimator, qt as sampleAudioSpectrumScale, r as AdvancedTextAnimatorSchema, rt as TextScrambleConfigSchema, s as AudioSpectrumTypographySchema, st as TextSpanSchema, t as AETextAnimatorSchema, tt as TextPathSourceSchema, u as CameraNodeSchema, ut as TypingCadenceSchema, v as ExpressionSelectorSchema, vt as collectNodeOps, w as LayerAnimation, wt as computeLineLeadingDisplacement, x as GlyphAnchorGroupingSchema, xt as computeCarrierContinuity, y as ExtendedGlyphPropertiesSchema, yt as compositorToProgram, z as SelectorShapeSchema, zt as evaluateTypewriterState } from "./program-Dl510wmI.mjs";
23
+ import "./renderer-Cl1oUXMi.mjs";
24
+ import "./renderer-CDOUAN7X.mjs";
25
+ import "./renderer-pxXf9dvk.mjs";
26
+ import "./renderer-CQiTodg9.mjs";
27
+ import "./renderer-CzPWB0Ss.mjs";
28
+ import "./renderer-DZGtBUCx.mjs";
29
+ import "./renderer-BDLnExoP.mjs";
30
+ import "./renderer-CH8sdfYX.mjs";
31
+ import "./renderer-CB5aWAaf.mjs";
32
+ import "./renderer-ho_jXJ0H.mjs";
33
+ import "./renderer-DxjVQV6f.mjs";
34
+ import "./renderer-Ryo2CEFD.mjs";
35
+ import "./renderer-BsgIcBKH.mjs";
36
+ import "./renderer-_uvdg48N.mjs";
37
+ import "./renderer-x2s9LmVL.mjs";
38
+ import "./renderer-BQHbp-Sp.mjs";
39
+ import "./renderer-CpkiHRhh.mjs";
40
+ import "./renderer-CMzEjdzi.mjs";
41
+ import "./renderer-DbaQLI4z.mjs";
42
+ import "./renderer-BREIjsUU.mjs";
43
+ import "./renderer-I-Sw3JBB.mjs";
44
+ import "./renderer-OWQmmg4Z.mjs";
45
+ import "./renderer-Dt6fzgX5.mjs";
46
+ import "./renderer-B_NuVaIP.mjs";
47
+ import "./renderer-CwQhzcUn.mjs";
48
+ import "./renderer-DFKsLrUs.mjs";
49
+ import "./renderer-B1CvhW4p.mjs";
50
+ import "./renderer-k2JL79kM.mjs";
51
+ import "./renderer-ByDhfrPE.mjs";
52
+ import "./renderer-Dp_FfvF-.mjs";
53
+ import { D as Vignette, E as ColorKey, S as Vision, T as ColorBalance, _ as SelectiveColor, a as CustomEffect, b as TileOffset, c as GradientMap, d as Levels, f as Modulate, g as SSAO, h as Relight3D, i as Curves, l as HalftoneScreen, m as PBRGlass, n as AudioSignalExtractor, o as DepthOfField, p as MotionBlur, r as Crop, s as FilmGrain, t as ApplyLUT, u as HighPass, v as ShadowsHighlights, w as Blur, x as UnsharpMask, y as TemporalDeflicker } from "./effects-CHWORCYd.mjs";
54
+ import { a as HeadlessWebGPURenderer, i as HeadlessMediaRenderer, n as renderFrameGrid, o as formatQaReport, r as resolveSamplePoints, s as renderSemaphore, t as computeGridLayout } from "./renderer-Fco4EmAu.mjs";
55
+ import "./dist-cjs-BKmGCgtm.mjs";
56
+ import { t as startPreview } from "./preview-uQM210iy.mjs";
57
+ import path from "node:path";
58
+ import fs from "node:fs/promises";
59
+ import { format } from "d3-format";
60
+ import { scaleBand, scaleLinear, scaleUtc } from "d3-scale";
61
+ import { arc, area, curveLinear, curveMonotoneX, curveStepAfter, line, pie, stack, stackOffsetDiverging } from "d3-shape";
62
+
63
+ //#region src/ids.ts
64
+ /**
65
+ * Default ids for nodes created without one. A counter per prefix rather than
66
+ * a random suffix: the same composition script builds the same ids on every
67
+ * run and in every render worker, so specs, caches and diffs stay stable.
68
+ */
69
+ const counters = /* @__PURE__ */ new Map();
70
+ function autoId(prefix) {
71
+ const n = (counters.get(prefix) ?? 0) + 1;
72
+ counters.set(prefix, n);
73
+ return `${prefix}-auto-${n}`;
74
+ }
75
+
76
+ //#endregion
77
+ //#region src/rich-text.ts
78
+ /**
79
+ * Tagged template literal for authoring rich, multi-style text runs.
80
+ *
81
+ * Interpolates strings, numbers, reactive signals, and typed span modifiers
82
+ * directly into a structured TextSpan[] array with zero runtime parsing.
83
+ *
84
+ * @example
85
+ * rich`Scale ${bold("10x", { fill: "#6366f1" })} faster with ${mark("120 FPS", { bg: "#10b98133" })}`
86
+ */
87
+ function rich(strings, ...values) {
88
+ const spans = [];
89
+ for (let i = 0; i < strings.length; i++) {
90
+ const str = strings[i];
91
+ if (str) spans.push({ text: str });
92
+ if (i < values.length) {
93
+ const val = values[i];
94
+ if (val === null || val === void 0) continue;
95
+ if (Array.isArray(val)) {
96
+ for (const item of val) if (typeof item === "string") {
97
+ if (item) spans.push({ text: item });
98
+ } else if (item && typeof item === "object" && "text" in item) spans.push(item);
99
+ } else if (typeof val === "object" && "text" in val) spans.push(val);
100
+ else if (typeof val === "object" && "get" in val && typeof val.get === "function") spans.push({ text: val });
101
+ else spans.push({ text: String(val) });
102
+ }
103
+ }
104
+ return spans;
105
+ }
106
+ function span(text, options = {}) {
107
+ return {
108
+ text,
109
+ ...options
110
+ };
111
+ }
112
+ function bold(text, options = {}) {
113
+ return {
114
+ text,
115
+ fontWeight: options.fontWeight ?? 700,
116
+ ...options
117
+ };
118
+ }
119
+ function italic(text, options = {}) {
120
+ return {
121
+ text,
122
+ fontStyle: "italic",
123
+ ...options
124
+ };
125
+ }
126
+ function accent(text, options = {}) {
127
+ return {
128
+ text,
129
+ fill: options.fill ?? "#6366f1",
130
+ ...options
131
+ };
132
+ }
133
+ function color(text, fill, options = {}) {
134
+ return {
135
+ text,
136
+ fill,
137
+ ...options
138
+ };
139
+ }
140
+ function size(text, fontSize, options = {}) {
141
+ return {
142
+ text,
143
+ fontSize,
144
+ ...options
145
+ };
146
+ }
147
+ function mark(text, options = {}) {
148
+ const { bg, fill, radius, paddingX, paddingY, ...rest } = options;
149
+ return {
150
+ text,
151
+ fill,
152
+ mark: {
153
+ background: bg ?? "#6366f133",
154
+ borderRadius: radius ?? 4,
155
+ paddingX: paddingX ?? 6,
156
+ paddingY: paddingY ?? 2
157
+ },
158
+ ...rest
159
+ };
160
+ }
161
+ function sup(text, options = {}) {
162
+ return {
163
+ text,
164
+ baselineShift: options.baselineShift ?? -8,
165
+ ...options
166
+ };
167
+ }
168
+ function sub(text, options = {}) {
169
+ return {
170
+ text,
171
+ baselineShift: options.baselineShift ?? 6,
172
+ ...options
173
+ };
174
+ }
175
+ function code(text, options = {}) {
176
+ return {
177
+ text,
178
+ fontFamily: options.fontFamily ?? "JetBrains Mono",
179
+ mark: options.mark ?? {
180
+ background: "#ffffff18",
181
+ borderRadius: 4,
182
+ paddingX: 6,
183
+ paddingY: 2
184
+ },
185
+ ...options
186
+ };
187
+ }
188
+ /**
189
+ * Normalizes string, TextSpan[], or array of mixed strings/spans into plain text and spans.
190
+ */
191
+ function normalizeTextSpans(input) {
192
+ if (typeof input === "string") return { text: input };
193
+ if (!Array.isArray(input)) return { text: String(input) };
194
+ const spans = [];
195
+ let plainText = "";
196
+ for (const item of input) if (typeof item === "string") {
197
+ if (item) {
198
+ spans.push({ text: item });
199
+ plainText += item;
200
+ }
201
+ } else if (item && typeof item === "object" && "text" in item) {
202
+ const s = item;
203
+ spans.push(s);
204
+ const piece = typeof s.text === "string" ? s.text : s.text && typeof s.text === "object" && "get" in s.text && typeof s.text.get === "function" ? String(s.text.get()) : String(s.text ?? "");
205
+ plainText += piece;
206
+ }
207
+ return {
208
+ text: plainText,
209
+ spans: spans.length > 0 ? spans : void 0
210
+ };
211
+ }
212
+ /**
213
+ * Upfront parser for external CMS or subtitle strings containing basic tags
214
+ * (<b>, <i>, <span>, <color>, <mark>, <accent>, <code>, <sup>, <sub>).
215
+ *
216
+ * Compiles string markup into clean TextSpan[] before entering the composition pipeline.
217
+ */
218
+ function parseMarkup(markup) {
219
+ if (!markup || !markup.includes("<")) return [{ text: markup }];
220
+ const spans = [];
221
+ const tagRegex = /<(\/?[a-zA-Z0-9_-]+)([^>]*)>/g;
222
+ let lastIndex = 0;
223
+ const stack$1 = [];
224
+ const getCurrentStyle = () => {
225
+ const merged = {};
226
+ for (const state of stack$1) Object.assign(merged, state.style);
227
+ return merged;
228
+ };
229
+ for (;;) {
230
+ const match = tagRegex.exec(markup);
231
+ if (!match) break;
232
+ const textBefore = markup.slice(lastIndex, match.index);
233
+ if (textBefore) spans.push({
234
+ text: textBefore,
235
+ ...getCurrentStyle()
236
+ });
237
+ lastIndex = match.index + match[0].length;
238
+ const tagName = match[1].toLowerCase();
239
+ const rawAttrs = match[2];
240
+ if (tagName.startsWith("/")) {
241
+ const closingTag = tagName.slice(1);
242
+ for (let i = stack$1.length - 1; i >= 0; i--) if (stack$1[i].tag === closingTag) {
243
+ stack$1.splice(i, 1);
244
+ break;
245
+ }
246
+ } else {
247
+ const attrs = {};
248
+ const attrRegex = /([a-zA-Z0-9_-]+)=["']([^"']*)["']/g;
249
+ for (;;) {
250
+ const attrMatch = attrRegex.exec(rawAttrs);
251
+ if (!attrMatch) break;
252
+ attrs[attrMatch[1].toLowerCase()] = attrMatch[2];
253
+ }
254
+ const style = {};
255
+ if (tagName === "b" || tagName === "strong") {
256
+ style.fontWeight = 700;
257
+ if (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;
258
+ } else if (tagName === "i" || tagName === "em") {
259
+ style.fontStyle = "italic";
260
+ if (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;
261
+ } else if (tagName === "accent") style.fill = "#6366f1";
262
+ else if (tagName === "color") style.fill = attrs.value ?? attrs.hex ?? attrs.fill;
263
+ else if (tagName === "size") {
264
+ const num = parseFloat(attrs.value ?? attrs.px ?? attrs.pt ?? "0");
265
+ if (num > 0) style.fontSize = num;
266
+ } else if (tagName === "mark") {
267
+ style.mark = {
268
+ background: attrs.bg ?? attrs.background ?? "#6366f133",
269
+ borderRadius: attrs.radius ? parseFloat(attrs.radius) : 4,
270
+ paddingX: attrs.paddingx ? parseFloat(attrs.paddingx) : 6,
271
+ paddingY: attrs.paddingy ? parseFloat(attrs.paddingy) : 2
272
+ };
273
+ if (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;
274
+ } else if (tagName === "sup") style.baselineShift = -8;
275
+ else if (tagName === "sub") style.baselineShift = 6;
276
+ else if (tagName === "code") {
277
+ style.fontFamily = "JetBrains Mono";
278
+ style.mark = {
279
+ background: attrs.bg ?? "#ffffff18",
280
+ borderRadius: 4,
281
+ paddingX: 6,
282
+ paddingY: 2
283
+ };
284
+ } else if (tagName === "span") {
285
+ if (attrs.color || attrs.fill) style.fill = attrs.color ?? attrs.fill;
286
+ if (attrs.fontfamily) style.fontFamily = attrs.fontfamily;
287
+ if (attrs.fontsize) style.fontSize = parseFloat(attrs.fontsize);
288
+ if (attrs.fontweight) {
289
+ const nw = parseInt(attrs.fontweight, 10);
290
+ style.fontWeight = Number.isNaN(nw) ? attrs.fontweight : nw;
291
+ }
292
+ if (attrs.fontstyle === "italic" || attrs.fontstyle === "normal") style.fontStyle = attrs.fontstyle;
293
+ if (attrs.letterspacing) style.letterSpacing = parseFloat(attrs.letterspacing);
294
+ if (attrs.baselineshift) style.baselineShift = parseFloat(attrs.baselineshift);
295
+ if (attrs.opacity) style.opacity = parseFloat(attrs.opacity);
296
+ }
297
+ stack$1.push({
298
+ tag: tagName,
299
+ style
300
+ });
301
+ }
302
+ }
303
+ const remainingText = markup.slice(lastIndex);
304
+ if (remainingText) spans.push({
305
+ text: remainingText,
306
+ ...getCurrentStyle()
307
+ });
308
+ return spans;
309
+ }
310
+
311
+ //#endregion
312
+ //#region src/chart.ts
313
+ /**
314
+ * Charts built from ordinary layout nodes. d3 does the math (scales, ticks,
315
+ * line/area/arc geometry, stacking); every bar, line, slice and label is a
316
+ * regular box, shape or text node, so charts use the composition's fonts and
317
+ * can be animated, graded and composited like any other layer.
318
+ */
319
+ const DEFAULT_CHART_COLORS = [
320
+ "#6366f1",
321
+ "#22d3ee",
322
+ "#f59e0b",
323
+ "#ec4899",
324
+ "#10b981",
325
+ "#8b5cf6",
326
+ "#f97316",
327
+ "#3b82f6"
328
+ ];
329
+ const isCandle = (d) => typeof d === "object" && d !== null && "open" in d && "close" in d;
330
+ const isSlice = (d) => typeof d === "object" && d !== null && "label" in d && "value" in d;
331
+ function curveOf(curve) {
332
+ if (curve === "linear") return curveLinear;
333
+ if (curve === "step") return curveStepAfter;
334
+ return curveMonotoneX;
335
+ }
336
+ function withAlpha(color$1, alpha) {
337
+ const hex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color$1.trim());
338
+ if (!hex) return color$1;
339
+ let h = hex[1];
340
+ if (h.length === 3) h = [...h].map((c) => c + c).join("");
341
+ const n = parseInt(h, 16);
342
+ return `rgba(${n >> 16 & 255}, ${n >> 8 & 255}, ${n & 255}, ${alpha})`;
343
+ }
344
+ function fmt(axis) {
345
+ if (!axis?.format) return null;
346
+ if (typeof axis.format === "function") return axis.format;
347
+ const f = format(axis.format);
348
+ return (v) => typeof v === "number" ? f(v) : String(v);
349
+ }
350
+ function round(v) {
351
+ return Math.round(v * 100) / 100;
352
+ }
353
+ function fadeIn(t, delay = 0, duration = t.duration) {
354
+ return LayerAnimation.create().fromTo("opacity", 0, 1, {
355
+ start: t.start + delay,
356
+ end: t.start + delay + Math.max(1, duration),
357
+ ease: "power2.out"
358
+ });
359
+ }
360
+ /** Builds the chart as a box of absolutely positioned child nodes. */
361
+ function buildChart(options, props, defaultFontFamily) {
362
+ const id = props.id ?? autoId("chart");
363
+ const width = options.width ?? (typeof props.width === "number" ? props.width : 960);
364
+ const height = options.height ?? (typeof props.height === "number" ? props.height : 540);
365
+ const type = options.type ?? "line";
366
+ const fontSize = options.fontSize ?? 18;
367
+ const fontFamily = options.fontFamily ?? defaultFontFamily;
368
+ const textColor = options.textColor ?? "#94a3b8";
369
+ const strongText = options.textColor ?? "#e2e8f0";
370
+ const gridColor = options.gridColor ?? "rgba(148, 163, 184, 0.18)";
371
+ const colors = options.colors?.length ? options.colors : DEFAULT_CHART_COLORS;
372
+ const radius = options.cornerRadius ?? 4;
373
+ const anim = options.animate === false ? void 0 : options.animate ?? {};
374
+ const timing = {
375
+ enabled: anim !== void 0,
376
+ start: anim?.start ?? 0,
377
+ duration: anim?.duration ?? 30,
378
+ stagger: anim?.stagger ?? -1,
379
+ ease: anim?.ease ?? "power3.out"
380
+ };
381
+ const children = [];
382
+ const label = (text, rect, align, extra = {}, key = "") => {
383
+ const node = Layer.text(text, {
384
+ id: `${id}-label-${key || children.length}`,
385
+ position: "absolute",
386
+ x: round(rect.x),
387
+ y: round(rect.y),
388
+ width: round(rect.width),
389
+ height: round(rect.height),
390
+ fontFamily,
391
+ fontSize,
392
+ fontWeight: extra.weight ?? 500,
393
+ fill: extra.color ?? textColor,
394
+ align,
395
+ verticalAlign: "middle"
396
+ });
397
+ if (timing.enabled) node.animate(fadeIn(timing, extra.delay ?? 0));
398
+ children.push(node);
399
+ };
400
+ const lineHeight = Math.ceil(fontSize * 1.4);
401
+ if (type === "pie" || type === "donut") buildPie();
402
+ else buildCartesian();
403
+ for (const child of children) snapKeyframes(child);
404
+ return Layer.box({
405
+ background: options.background ?? "transparent",
406
+ ...props,
407
+ id,
408
+ width,
409
+ height,
410
+ children
411
+ });
412
+ function buildPie() {
413
+ const slices = collectSlices();
414
+ const total = slices.reduce((s, d) => s + Math.max(0, d.value), 0);
415
+ const showLegend = options.legend ?? true;
416
+ const plot = plotRect(resolvePadding({
417
+ top: 16,
418
+ right: showLegend ? legendColumnWidth(slices.map((s) => s.label)) : 16,
419
+ bottom: 16,
420
+ left: 16
421
+ }));
422
+ const r = Math.max(1, Math.min(plot.width, plot.height) / 2);
423
+ const inner = r * (options.innerRadius ?? (type === "donut" ? .6 : 0));
424
+ const cx = plot.x + plot.width / 2;
425
+ const cy = plot.y + plot.height / 2;
426
+ const m = 4;
427
+ const arcs = pie().sort(null).value((d) => Math.max(0, d.value)).padAngle(slices.length > 1 ? .012 : 0)(slices);
428
+ const arcGen = arc().innerRadius(inner).outerRadius(r).cornerRadius(Math.min(radius, (r - inner) / 2));
429
+ const step = staggerStep(arcs.length);
430
+ arcs.forEach((a, i) => {
431
+ const d = arcGen(a);
432
+ if (!d) return;
433
+ const color$1 = slices[i].color ?? colors[i % colors.length];
434
+ const node = Layer.shape("path", {
435
+ id: `${id}-slice-${i}`,
436
+ position: "absolute",
437
+ x: round(cx - r - m),
438
+ y: round(cy - r - m),
439
+ width: round(2 * (r + m)),
440
+ height: round(2 * (r + m)),
441
+ d: translatePath(d, r + m, r + m),
442
+ fillColor: color$1,
443
+ anchorX: .5,
444
+ anchorY: .5
445
+ });
446
+ if (timing.enabled) {
447
+ const s = timing.start + i * step;
448
+ node.animate(LayerAnimation.create().fromTo("opacity", 0, 1, {
449
+ start: s,
450
+ end: s + timing.duration * .5
451
+ }).fromTo("scale", .85, 1, {
452
+ start: s,
453
+ end: s + timing.duration,
454
+ ease: timing.ease
455
+ }));
456
+ }
457
+ children.push(node);
458
+ if (options.valueLabels && total > 0 && a.value > 0) {
459
+ const [lx, ly] = arc().innerRadius(inner || r * .55).outerRadius(r).centroid(a);
460
+ label(`${Math.round(a.value / total * 100)}%`, {
461
+ x: cx + lx - 60,
462
+ y: cy + ly - lineHeight / 2,
463
+ width: 120,
464
+ height: lineHeight
465
+ }, "center", {
466
+ delay: i * step + timing.duration * .5,
467
+ color: "#ffffff",
468
+ weight: 700
469
+ }, `value-${i}`);
470
+ }
471
+ });
472
+ if (showLegend) legendColumn(slices.map((s, i) => ({
473
+ name: s.label,
474
+ color: s.color ?? colors[i % colors.length]
475
+ })), {
476
+ x: plot.x + plot.width + 24,
477
+ y: plot.y,
478
+ height: plot.height
479
+ });
480
+ }
481
+ function collectSlices() {
482
+ return (options.data ?? options.series?.[0]?.data ?? []).map((d, i) => {
483
+ if (isSlice(d)) return d;
484
+ const value = typeof d === "number" ? d : Array.isArray(d) ? Number(d[1]) : Number(d.y);
485
+ return {
486
+ label: options.categories?.[i] ?? (Array.isArray(d) ? String(d[0]) : typeof d === "object" && d ? String(d.x) : `${i + 1}`),
487
+ value
488
+ };
489
+ });
490
+ }
491
+ function buildCartesian() {
492
+ const series = options.series?.length ? [...options.series] : options.data ? [{ data: options.data }] : [];
493
+ if (series.length === 0) return;
494
+ const typeOf = (s) => s.type ?? type ?? "line";
495
+ const colorOf = (s, i) => s.color ?? colors[i % colors.length];
496
+ const points = series.map((s) => s.data.map((d, i) => {
497
+ if (isCandle(d)) return {
498
+ x: d.x,
499
+ y: d.close
500
+ };
501
+ if (typeof d === "number") return {
502
+ x: options.categories?.[i] ?? i,
503
+ y: d
504
+ };
505
+ if (Array.isArray(d)) return {
506
+ x: d[0],
507
+ y: Number(d[1])
508
+ };
509
+ return {
510
+ x: d.x,
511
+ y: Number(d.y)
512
+ };
513
+ }));
514
+ const anyBand = series.some((s) => typeOf(s) === "bar" || typeOf(s) === "candlestick");
515
+ const allX = points.flat().map((p) => p.x);
516
+ const xKind = anyBand || allX.some((x$1) => typeof x$1 === "string") ? "band" : allX.some((x$1) => x$1 instanceof Date) ? "time" : "linear";
517
+ const stackable = (s) => typeOf(s) === "bar" || typeOf(s) === "area";
518
+ const stacked = !!options.stacked;
519
+ const categories = xKind === "band" ? [...new Set(allX.map(String))] : [];
520
+ const stackRanges = /* @__PURE__ */ new Map();
521
+ if (stacked) {
522
+ const keys = series.map((_, i) => i).filter((i) => stackable(series[i]));
523
+ const rows = categories.length ? categories : [...new Set(allX.map((x$1) => +x$1))].sort((a, b) => a - b).map(String);
524
+ const table = rows.map((key) => {
525
+ const row = {};
526
+ for (const i of keys) row[i] = points[i].find((pt) => String(xKind === "band" ? pt.x : +pt.x) === key)?.y ?? 0;
527
+ return row;
528
+ });
529
+ stack().keys(keys.map(String)).offset(stackOffsetDiverging)(table).forEach((layer) => {
530
+ const i = Number(layer.key);
531
+ stackRanges.set(i, points[i].map((p) => {
532
+ const idx = rows.indexOf(String(xKind === "band" ? p.x : +p.x));
533
+ return [layer[idx][0], layer[idx][1]];
534
+ }));
535
+ });
536
+ }
537
+ const yValues = [0];
538
+ series.forEach((s, i) => {
539
+ const range = stackRanges.get(i);
540
+ if (typeOf(s) === "candlestick") for (const c of s.data) yValues.push(c.high, c.low);
541
+ else if (range) for (const [a, b] of range) yValues.push(a, b);
542
+ else for (const p of points[i]) yValues.push(p.y);
543
+ });
544
+ if (series.every((s) => typeOf(s) === "candlestick" || typeOf(s) === "scatter" || typeOf(s) === "line")) yValues.shift();
545
+ const yAxis = options.yAxis ?? {};
546
+ const xAxis = options.xAxis ?? {};
547
+ const yTickCount = yAxis.ticks ?? 5;
548
+ let lo = yAxis.min ?? Math.min(...yValues);
549
+ let hi = yAxis.max ?? Math.max(...yValues);
550
+ if (!Number.isFinite(lo) || !Number.isFinite(hi)) [lo, hi] = [0, 1];
551
+ if (lo === hi) [lo, hi] = [lo - 1, hi + 1];
552
+ const y = scaleLinear().domain([lo, hi]);
553
+ if (yAxis.min === void 0 || yAxis.max === void 0) y.nice(yTickCount);
554
+ const yFormat = fmt(yAxis) ?? ((v) => y.tickFormat(yTickCount)(v));
555
+ const yTicks = y.ticks(yTickCount);
556
+ const legendItems = series.map((s, i) => ({
557
+ name: s.name ?? `Series ${i + 1}`,
558
+ color: colorOf(s, i)
559
+ }));
560
+ const showLegend = options.legend ?? series.length > 1;
561
+ const showY = yAxis.show !== false;
562
+ const showX = xAxis.show !== false;
563
+ const yLabelWidth = showY ? Math.max(...yTicks.map((t) => yFormat(t).length)) * fontSize * .7 + 20 : 0;
564
+ const plot = plotRect(resolvePadding({
565
+ top: (showLegend ? lineHeight + 20 : 0) + Math.ceil(lineHeight / 2),
566
+ right: 20,
567
+ bottom: showX ? lineHeight + 14 : 12,
568
+ left: Math.max(16, Math.ceil(yLabelWidth))
569
+ }));
570
+ const labelRoom = lineHeight + 6;
571
+ const barValues = options.valueLabels ? series.flatMap((s, i) => typeOf(s) === "bar" ? points[i].map((p) => p.y) : []) : [];
572
+ const topInset = barValues.some((v) => v > 0) ? labelRoom : 0;
573
+ const bottomInset = barValues.some((v) => v < 0) ? labelRoom : 0;
574
+ y.range([plot.height - bottomInset, topInset]);
575
+ let x;
576
+ if (xKind === "band") x = scaleBand().domain(categories).range([0, plot.width]).paddingInner(anyBand ? .28 : 0).paddingOuter(anyBand ? .14 : .5);
577
+ else if (xKind === "time") {
578
+ const xs = allX.map((v) => +new Date(v));
579
+ x = scaleUtc().domain([Math.min(...xs), Math.max(...xs)]).range([0, plot.width]);
580
+ } else {
581
+ const xs = allX.map(Number);
582
+ x = scaleLinear().domain([xAxis.min ?? Math.min(...xs), xAxis.max ?? Math.max(...xs)]).range([0, plot.width]);
583
+ }
584
+ const xPos = (v) => {
585
+ if (xKind === "band") {
586
+ const b = x;
587
+ return (b(String(v)) ?? 0) + b.bandwidth() / 2;
588
+ }
589
+ if (xKind === "time") return x(new Date(v));
590
+ return x(Number(v));
591
+ };
592
+ const gridDelay = 0;
593
+ if (yAxis.grid !== false) yTicks.forEach((t, i) => {
594
+ const node = Layer.box({
595
+ id: `${id}-ygrid-${i}`,
596
+ position: "absolute",
597
+ x: plot.x,
598
+ y: round(plot.y + y(t) - .5),
599
+ width: plot.width,
600
+ height: 1,
601
+ background: gridColor
602
+ });
603
+ if (timing.enabled) node.animate(fadeIn(timing, gridDelay, timing.duration / 2));
604
+ children.push(node);
605
+ });
606
+ if (showY) yTicks.forEach((t, i) => {
607
+ label(yFormat(t), {
608
+ x: 0,
609
+ y: plot.y + y(t) - lineHeight / 2,
610
+ width: plot.x - 12,
611
+ height: lineHeight
612
+ }, "end", {}, `y-${i}`);
613
+ });
614
+ const xTicks = [];
615
+ const xFormat = fmt(xAxis);
616
+ if (xKind === "band") {
617
+ const b = x;
618
+ const every = Math.max(1, Math.ceil(categories.length / Math.max(1, Math.floor(plot.width / (fontSize * 4)))));
619
+ categories.forEach((c, i) => {
620
+ if (i % every === 0) xTicks.push({
621
+ pos: (b(c) ?? 0) + b.bandwidth() / 2,
622
+ text: xFormat ? xFormat(c) : c
623
+ });
624
+ });
625
+ } else {
626
+ const s = x;
627
+ const count = xAxis.ticks ?? Math.max(2, Math.floor(plot.width / (fontSize * 6)));
628
+ const tf = s.tickFormat(count);
629
+ for (const t of s.ticks(count)) xTicks.push({
630
+ pos: s(t),
631
+ text: xFormat ? xFormat(xKind === "time" ? new Date(t) : t) : tf(t)
632
+ });
633
+ }
634
+ if (xAxis.grid) xTicks.forEach((t, i) => {
635
+ const node = Layer.box({
636
+ id: `${id}-xgrid-${i}`,
637
+ position: "absolute",
638
+ x: round(plot.x + t.pos - .5),
639
+ y: plot.y,
640
+ width: 1,
641
+ height: plot.height,
642
+ background: gridColor
643
+ });
644
+ if (timing.enabled) node.animate(fadeIn(timing, gridDelay, timing.duration / 2));
645
+ children.push(node);
646
+ });
647
+ if (showX) {
648
+ const slot = Math.max(fontSize * 3, plot.width / Math.max(1, xTicks.length));
649
+ xTicks.forEach((t, i) => {
650
+ label(t.text, {
651
+ x: plot.x + t.pos - slot / 2,
652
+ y: plot.y + plot.height + 10,
653
+ width: slot,
654
+ height: lineHeight
655
+ }, "center", {}, `x-${i}`);
656
+ });
657
+ }
658
+ const [y0, y1] = y.domain();
659
+ if (y0 <= 0 && y1 >= 0 && anyBand) {
660
+ const node = Layer.box({
661
+ id: `${id}-zero`,
662
+ position: "absolute",
663
+ x: plot.x,
664
+ y: round(plot.y + y(0) - 1),
665
+ width: plot.width,
666
+ height: 2,
667
+ background: withAlpha("#94a3b8", .45)
668
+ });
669
+ if (timing.enabled) node.animate(fadeIn(timing, 0, timing.duration / 2));
670
+ children.push(node);
671
+ }
672
+ const barSeries = series.map((_, i) => i).filter((i) => typeOf(series[i]) === "bar");
673
+ const order = [
674
+ ...barSeries,
675
+ ...series.map((_, i) => i).filter((i) => typeOf(series[i]) === "candlestick"),
676
+ ...series.map((_, i) => i).filter((i) => typeOf(series[i]) === "area"),
677
+ ...series.map((_, i) => i).filter((i) => typeOf(series[i]) === "line"),
678
+ ...series.map((_, i) => i).filter((i) => typeOf(series[i]) === "scatter")
679
+ ];
680
+ const band = xKind === "band" ? x : null;
681
+ const bandStep = band ? staggerStep(categories.length) : 0;
682
+ const categoryIndex = (v) => band ? categories.indexOf(String(v)) : 0;
683
+ order.forEach((si, rank) => {
684
+ const s = series[si];
685
+ const color$1 = colorOf(s, si);
686
+ const kind = typeOf(s);
687
+ const pts = points[si];
688
+ const range = stackRanges.get(si);
689
+ if (kind === "bar" && band) {
690
+ const groupSize = stacked ? 1 : barSeries.length;
691
+ const groupIdx = stacked ? 0 : barSeries.indexOf(si);
692
+ const bw = band.bandwidth() / groupSize;
693
+ const gap = groupSize > 1 ? Math.min(4, bw * .12) : 0;
694
+ pts.forEach((p, i) => {
695
+ const [lo$1, hi$1] = range ? range[i] : [0, p.y];
696
+ const top = plot.y + y(Math.max(lo$1, hi$1));
697
+ const bottom = plot.y + y(Math.min(lo$1, hi$1));
698
+ const h = Math.max(0, bottom - top);
699
+ const bx = plot.x + (band(String(p.x)) ?? 0) + groupIdx * bw + gap / 2;
700
+ const grows = p.y >= 0 ? "up" : "down";
701
+ const node = Layer.box({
702
+ id: `${id}-bar-${si}-${i}`,
703
+ position: "absolute",
704
+ x: round(bx),
705
+ y: round(top),
706
+ width: round(Math.max(1, bw - gap)),
707
+ height: round(h),
708
+ background: color$1,
709
+ borderRadius: Math.min(radius, (bw - gap) / 2, h / 2)
710
+ });
711
+ const delay = categoryIndex(p.x) * bandStep + (stacked ? barSeries.indexOf(si) * timing.duration * .6 : 0);
712
+ if (timing.enabled) {
713
+ const st = timing.start + delay;
714
+ const end = st + timing.duration;
715
+ const a = LayerAnimation.create().fromTo("height", 0, round(h), {
716
+ start: st,
717
+ end,
718
+ ease: timing.ease
719
+ });
720
+ if (grows === "up") a.fromTo("y", round(top + h), round(top), {
721
+ start: st,
722
+ end,
723
+ ease: timing.ease
724
+ });
725
+ node.animate(a);
726
+ }
727
+ children.push(node);
728
+ if (options.valueLabels) {
729
+ const text = yFormat(p.y);
730
+ const ly = grows === "up" ? top - lineHeight - 4 : top + h + 4;
731
+ label(text, {
732
+ x: bx - 30,
733
+ y: ly,
734
+ width: bw - gap + 60,
735
+ height: lineHeight
736
+ }, "center", {
737
+ delay: delay + timing.duration * .6,
738
+ color: strongText,
739
+ weight: 600
740
+ }, `value-${si}-${i}`);
741
+ }
742
+ });
743
+ return;
744
+ }
745
+ if (kind === "candlestick" && band) {
746
+ const up = options.upColor ?? "#22c55e";
747
+ const down = options.downColor ?? "#ef4444";
748
+ const bw = band.bandwidth();
749
+ s.data.forEach((c, i) => {
750
+ const col = c.close >= c.open ? up : down;
751
+ const cxp = plot.x + (band(String(c.x)) ?? 0) + bw / 2;
752
+ const delay = categoryIndex(c.x) * bandStep;
753
+ const parts = [["wick", {
754
+ x: cxp - Math.max(1, bw * .06),
755
+ y: plot.y + y(c.high),
756
+ width: Math.max(2, bw * .12),
757
+ height: Math.max(1, y(c.low) - y(c.high))
758
+ }], ["body", {
759
+ x: cxp - bw / 2,
760
+ y: plot.y + y(Math.max(c.open, c.close)),
761
+ width: bw,
762
+ height: Math.max(2, Math.abs(y(c.open) - y(c.close)))
763
+ }]];
764
+ for (const [part, r] of parts) {
765
+ const node = Layer.box({
766
+ id: `${id}-candle-${si}-${i}-${part}`,
767
+ position: "absolute",
768
+ x: round(r.x),
769
+ y: round(r.y),
770
+ width: round(r.width),
771
+ height: round(r.height),
772
+ background: col,
773
+ borderRadius: part === "body" ? Math.min(radius / 2, r.width / 2) : 0
774
+ });
775
+ if (timing.enabled) {
776
+ const st = timing.start + delay;
777
+ const mid = r.y + r.height / 2;
778
+ node.animate(LayerAnimation.create().fromTo("height", 0, round(r.height), {
779
+ start: st,
780
+ end: st + timing.duration,
781
+ ease: timing.ease
782
+ }).fromTo("y", round(mid), round(r.y), {
783
+ start: st,
784
+ end: st + timing.duration,
785
+ ease: timing.ease
786
+ }));
787
+ }
788
+ children.push(node);
789
+ }
790
+ });
791
+ return;
792
+ }
793
+ if (kind === "line" || kind === "area") {
794
+ const sw = s.strokeWidth ?? 3;
795
+ const m = Math.ceil(sw * 2 + (s.pointRadius ?? 0) + 2);
796
+ const xy = pts.map((p, i) => ({
797
+ x: xPos(p.x) + m,
798
+ top: (range ? y(range[i][1]) : y(p.y)) + m,
799
+ base: (range ? y(range[i][0]) : y(Math.max(y.domain()[0], Math.min(0, y.domain()[1])))) + m
800
+ }));
801
+ const curve = curveOf(s.curve);
802
+ const frame = {
803
+ x: plot.x - m,
804
+ y: plot.y - m,
805
+ width: plot.width + 2 * m,
806
+ height: plot.height + 2 * m
807
+ };
808
+ const delay = rank * (timing.duration / 3);
809
+ if (kind === "area") {
810
+ const d$1 = area().x((p) => p.x).y0((p) => p.base).y1((p) => p.top).curve(curve)(xy);
811
+ if (d$1) {
812
+ const node = Layer.shape("path", {
813
+ id: `${id}-area-${si}`,
814
+ position: "absolute",
815
+ ...roundRect(frame),
816
+ d: roundPath(d$1),
817
+ fillType: "linear",
818
+ fillColor: withAlpha(color$1, .45),
819
+ gradientEndColor: withAlpha(color$1, .02),
820
+ gradientAngle: 90
821
+ });
822
+ if (timing.enabled) node.animate(fadeIn(timing, delay + timing.duration * .4, timing.duration));
823
+ children.push(node);
824
+ }
825
+ }
826
+ const d = line().x((p) => p.x).y((p) => p.top).curve(curve)(xy);
827
+ if (d && sw > 0) {
828
+ const node = Layer.shape("path", {
829
+ id: `${id}-line-${si}`,
830
+ position: "absolute",
831
+ ...roundRect(frame),
832
+ d: roundPath(d),
833
+ fillType: "none",
834
+ strokeColor: color$1,
835
+ strokeWidth: sw,
836
+ strokeLineCap: "round",
837
+ strokeLineJoin: "round"
838
+ });
839
+ if (timing.enabled) node.animate(LayerAnimation.create().fromTo("trimEnd", 0, 1, {
840
+ start: timing.start + delay,
841
+ end: timing.start + delay + timing.duration * 1.5,
842
+ ease: "power2.inOut"
843
+ }));
844
+ children.push(node);
845
+ }
846
+ if ((s.pointRadius ?? 0) > 0) dots(si, pts, color$1, s.pointRadius ?? 0, delay + timing.duration * .5, range);
847
+ return;
848
+ }
849
+ if (kind === "scatter") dots(si, pts, color$1, s.pointRadius ?? 6, rank * (timing.duration / 3), range);
850
+ });
851
+ if (showLegend) legendRow(legendItems);
852
+ function dots(si, pts, color$1, r, baseDelay, range) {
853
+ const step = staggerStep(pts.length);
854
+ pts.forEach((p, i) => {
855
+ const py = range ? y(range[i][1]) : y(p.y);
856
+ const node = Layer.shape("circle", {
857
+ id: `${id}-point-${si}-${i}`,
858
+ position: "absolute",
859
+ x: round(plot.x + xPos(p.x) - r),
860
+ y: round(plot.y + py - r),
861
+ width: round(r * 2),
862
+ height: round(r * 2),
863
+ fillColor: color$1,
864
+ anchorX: .5,
865
+ anchorY: .5
866
+ });
867
+ if (timing.enabled) {
868
+ const st = timing.start + baseDelay + i * step;
869
+ node.animate(LayerAnimation.create().fromTo("scale", 0, 1, {
870
+ start: st,
871
+ end: st + timing.duration * .6,
872
+ ease: "back.out(2)"
873
+ }).fromTo("opacity", 0, 1, {
874
+ start: st,
875
+ end: st + 6
876
+ }));
877
+ }
878
+ children.push(node);
879
+ });
880
+ }
881
+ }
882
+ function staggerStep(count) {
883
+ if (!timing.enabled || count <= 1) return 0;
884
+ if (timing.stagger >= 0) return timing.stagger;
885
+ return Math.min(4, timing.duration / count);
886
+ }
887
+ function resolvePadding(auto) {
888
+ const p = options.padding;
889
+ if (typeof p === "number") return {
890
+ top: p,
891
+ right: p,
892
+ bottom: p,
893
+ left: p
894
+ };
895
+ return {
896
+ top: p?.top ?? auto.top,
897
+ right: p?.right ?? auto.right,
898
+ bottom: p?.bottom ?? auto.bottom,
899
+ left: p?.left ?? auto.left
900
+ };
901
+ }
902
+ function plotRect(p) {
903
+ return {
904
+ x: p.left,
905
+ y: p.top,
906
+ width: Math.max(1, width - p.left - p.right),
907
+ height: Math.max(1, height - p.top - p.bottom)
908
+ };
909
+ }
910
+ function legendColumnWidth(names) {
911
+ const longest = Math.max(0, ...names.map((n) => n.length));
912
+ return Math.min(width * .4, longest * fontSize * .6 + fontSize + 48);
913
+ }
914
+ function legendColumn(items, at) {
915
+ const rowH = lineHeight + 8;
916
+ const top = at.y + Math.max(0, (at.height - items.length * rowH) / 2);
917
+ items.forEach((item, i) => {
918
+ legendItem(item, at.x, top + i * rowH, i);
919
+ });
920
+ }
921
+ function legendRow(items) {
922
+ const widths = items.map((it) => it.name.length * fontSize * .6 + fontSize + 28);
923
+ const total = widths.reduce((a, b) => a + b, 0);
924
+ let cursor = Math.max(0, width - total - 20);
925
+ items.forEach((item, i) => {
926
+ legendItem(item, cursor, 4, i);
927
+ cursor += widths[i];
928
+ });
929
+ }
930
+ function legendItem(item, lx, ly, i) {
931
+ const sw = Math.round(fontSize * .7);
932
+ const swatch = Layer.box({
933
+ id: `${id}-legend-swatch-${i}`,
934
+ position: "absolute",
935
+ x: round(lx),
936
+ y: round(ly + (lineHeight - sw) / 2),
937
+ width: sw,
938
+ height: sw,
939
+ borderRadius: Math.round(sw / 4),
940
+ background: item.color
941
+ });
942
+ if (timing.enabled) swatch.animate(fadeIn(timing, 0, timing.duration / 2));
943
+ children.push(swatch);
944
+ label(item.name, {
945
+ x: lx + sw + 8,
946
+ y: ly,
947
+ width: item.name.length * fontSize * .6 + 12,
948
+ height: lineHeight
949
+ }, "start", { color: options.textColor ?? "#cbd5e1" }, `legend-${i}`);
950
+ }
951
+ }
952
+ function snapKeyframes(node) {
953
+ for (const track of node.animation?.tracks ?? []) for (const kf of track.keyframes ?? []) kf.frame = Math.round(kf.frame);
954
+ for (const child of node.children ?? []) snapKeyframes(child);
955
+ }
956
+ function roundRect(r) {
957
+ return {
958
+ x: round(r.x),
959
+ y: round(r.y),
960
+ width: round(r.width),
961
+ height: round(r.height)
962
+ };
963
+ }
964
+ /** Shortens the long float literals d3 emits. */
965
+ function roundPath(d) {
966
+ return d.replace(/-?\d*\.\d{3,}(?:e-?\d+)?/gi, (n) => String(round(Number(n))));
967
+ }
968
+ /** Offsets an absolute SVG path (as produced by d3-arc) by dx, dy. */
969
+ function translatePath(d, dx, dy) {
970
+ const out = [];
971
+ for (const [, cmd, args] of d.matchAll(/([MLAZ])([^MLAZ]*)/gi)) {
972
+ const nums = (args.match(/-?\d*\.?\d+(?:e-?\d+)?/gi) ?? []).map(Number);
973
+ if (cmd.toUpperCase() === "A") for (let i = 0; i + 6 < nums.length; i += 7) {
974
+ nums[i + 5] += dx;
975
+ nums[i + 6] += dy;
976
+ }
977
+ else if (cmd.toUpperCase() !== "Z") for (let i = 0; i + 1 < nums.length; i += 2) {
978
+ nums[i] += dx;
979
+ nums[i + 1] += dy;
980
+ }
981
+ out.push(cmd + nums.map(round).join(","));
982
+ }
983
+ return out.join("");
984
+ }
985
+
986
+ //#endregion
987
+ //#region src/shapes3d.ts
988
+ /**
989
+ * Attaches the faces/items handles as non-enumerable properties, like
990
+ * `animate`, so they stay out of `toSpec()` and schema validation.
991
+ */
992
+ function withParts(node, parts) {
993
+ const list = parts.faces ?? parts.items ?? [];
994
+ for (const [key, value] of Object.entries(parts)) Object.defineProperty(node, key, {
995
+ value,
996
+ enumerable: false,
997
+ configurable: true
998
+ });
999
+ Object.defineProperty(node, Symbol.iterator, {
1000
+ value: function* () {
1001
+ yield* list;
1002
+ },
1003
+ enumerable: false,
1004
+ configurable: true
1005
+ });
1006
+ return node;
1007
+ }
1008
+ /** Largest initial scale of an extruded text node along its outline's axes. */
1009
+ function extrudedTextScale(options) {
1010
+ const scale = options.scale ?? 1;
1011
+ const s = Math.max(Math.abs(scale * (options.scaleX ?? 1)), Math.abs(scale * (options.scaleY ?? 1)));
1012
+ return s > 0 ? s : 1;
1013
+ }
1014
+ const Layer3D = {
1015
+ cube(options) {
1016
+ const size$1 = options.size;
1017
+ const [w, h, d] = typeof size$1 === "number" ? [
1018
+ size$1,
1019
+ size$1,
1020
+ size$1
1021
+ ] : size$1;
1022
+ const twoSided = options.twoSided ?? true;
1023
+ const defaultColors = {
1024
+ front: "#3b82f6",
1025
+ back: "#1d4ed8",
1026
+ left: "#2563eb",
1027
+ right: "#1e40af",
1028
+ top: "#60a5fa",
1029
+ bottom: "#172554"
1030
+ };
1031
+ const buildFace = (faceId, input, defaultColor, faceW, faceH, faceProps) => {
1032
+ if (input && typeof input === "object" && "kind" in input) {
1033
+ const node = input;
1034
+ node.position = "absolute";
1035
+ node.is3D = true;
1036
+ node.twoSided = twoSided;
1037
+ node.material = node.material ?? options.material ?? "lit";
1038
+ node.shininess = node.shininess ?? options.shininess ?? 32;
1039
+ node.specularIntensity = node.specularIntensity ?? options.specularIntensity ?? .5;
1040
+ if (options.roughness !== void 0 && node.roughness === void 0) node.roughness = options.roughness;
1041
+ if (options.metallic !== void 0 && node.metallic === void 0) node.metallic = options.metallic;
1042
+ if (options.ambientIntensity !== void 0 && node.ambientIntensity === void 0) node.ambientIntensity = options.ambientIntensity;
1043
+ Object.assign(node, faceProps);
1044
+ return node;
1045
+ }
1046
+ const cfg = typeof input === "string" ? { background: input } : input ?? { background: defaultColor };
1047
+ return Layer.box({
1048
+ id: `${options.id ?? "cube"}-${faceId}`,
1049
+ position: "absolute",
1050
+ width: faceW,
1051
+ height: faceH,
1052
+ is3D: true,
1053
+ twoSided,
1054
+ material: cfg.material ?? options.material ?? "lit",
1055
+ shininess: cfg.shininess ?? options.shininess ?? 32,
1056
+ specularIntensity: cfg.specularIntensity ?? options.specularIntensity ?? .5,
1057
+ roughness: cfg.roughness ?? options.roughness,
1058
+ metallic: cfg.metallic ?? options.metallic,
1059
+ ambientIntensity: cfg.ambientIntensity ?? options.ambientIntensity ?? 1,
1060
+ background: cfg.background ?? defaultColor,
1061
+ borderRadius: cfg.borderRadius ?? 0,
1062
+ borderWidth: cfg.borderWidth,
1063
+ borderColor: cfg.borderColor,
1064
+ opacity: cfg.opacity ?? 1,
1065
+ children: cfg.children ?? [],
1066
+ ...faceProps
1067
+ });
1068
+ };
1069
+ const halfW = w / 2;
1070
+ const halfH = h / 2;
1071
+ const halfD = d / 2;
1072
+ const faces = [
1073
+ buildFace("front", options.faces?.front, defaultColors.front, w, h, {
1074
+ x: 0,
1075
+ y: 0,
1076
+ z: -halfD,
1077
+ rotateX: 0,
1078
+ rotateY: 0,
1079
+ rotateZ: 0
1080
+ }),
1081
+ buildFace("back", options.faces?.back, defaultColors.back, w, h, {
1082
+ x: 0,
1083
+ y: 0,
1084
+ z: halfD,
1085
+ rotateX: 0,
1086
+ rotateY: 180,
1087
+ rotateZ: 0
1088
+ }),
1089
+ buildFace("left", options.faces?.left, defaultColors.left, d, h, {
1090
+ x: -halfW,
1091
+ y: 0,
1092
+ z: 0,
1093
+ rotateX: 0,
1094
+ rotateY: 90,
1095
+ rotateZ: 0
1096
+ }),
1097
+ buildFace("right", options.faces?.right, defaultColors.right, d, h, {
1098
+ x: halfW,
1099
+ y: 0,
1100
+ z: 0,
1101
+ rotateX: 0,
1102
+ rotateY: -90,
1103
+ rotateZ: 0
1104
+ }),
1105
+ buildFace("top", options.faces?.top, defaultColors.top, w, d, {
1106
+ x: 0,
1107
+ y: -halfH,
1108
+ z: 0,
1109
+ rotateX: -90,
1110
+ rotateY: 0,
1111
+ rotateZ: 0
1112
+ }),
1113
+ buildFace("bottom", options.faces?.bottom, defaultColors.bottom, w, d, {
1114
+ x: 0,
1115
+ y: halfH,
1116
+ z: 0,
1117
+ rotateX: 90,
1118
+ rotateY: 0,
1119
+ rotateZ: 0
1120
+ })
1121
+ ];
1122
+ return withParts(Layer.box({
1123
+ id: options.id ?? autoId("cube"),
1124
+ position: "absolute",
1125
+ x: options.x ?? 0,
1126
+ y: options.y ?? 0,
1127
+ z: options.z ?? 0,
1128
+ width: w,
1129
+ height: h,
1130
+ is3D: true,
1131
+ transformStyle: "preserve-3d",
1132
+ rotateX: options.rotateX ?? 0,
1133
+ rotateY: options.rotateY ?? 0,
1134
+ rotateZ: options.rotateZ ?? 0,
1135
+ opacity: options.opacity ?? 1,
1136
+ background: "transparent",
1137
+ children: faces
1138
+ }), { faces });
1139
+ },
1140
+ carousel(options) {
1141
+ const { items, radius, faceInward = false, twoSided = true } = options;
1142
+ const n = items.length;
1143
+ const angleStep = n > 0 ? 360 / n : 0;
1144
+ const transformedItems = items.map((item, idx) => {
1145
+ const angleDeg = idx * angleStep;
1146
+ const rad = angleDeg * Math.PI / 180;
1147
+ const x = radius * Math.sin(rad);
1148
+ const z = -radius * Math.cos(rad);
1149
+ const ry = faceInward ? 180 - angleDeg : -angleDeg;
1150
+ const node = item;
1151
+ node.position = "absolute";
1152
+ node.is3D = true;
1153
+ node.twoSided = twoSided;
1154
+ node.x = x;
1155
+ node.y = 0;
1156
+ node.z = z;
1157
+ node.rotateY = ry;
1158
+ return node;
1159
+ });
1160
+ return withParts(Layer.box({
1161
+ id: options.id ?? autoId("carousel"),
1162
+ position: "absolute",
1163
+ x: options.x ?? 0,
1164
+ y: options.y ?? 0,
1165
+ z: options.z ?? 0,
1166
+ width: options.itemWidth ?? 200,
1167
+ height: options.itemHeight ?? 200,
1168
+ is3D: true,
1169
+ transformStyle: "preserve-3d",
1170
+ rotateX: options.rotateX ?? 0,
1171
+ rotateY: options.rotateY ?? 0,
1172
+ rotateZ: options.rotateZ ?? 0,
1173
+ opacity: options.opacity ?? 1,
1174
+ background: "transparent",
1175
+ children: transformedItems
1176
+ }), { items: transformedItems });
1177
+ },
1178
+ prism(options) {
1179
+ const { sides, radius, height, twoSided = true } = options;
1180
+ const n = Math.max(3, sides);
1181
+ const sideWidth = 2 * radius * Math.tan(Math.PI / n);
1182
+ const angleStep = 360 / n;
1183
+ const panels = [];
1184
+ for (let i = 0; i < n; i++) {
1185
+ const angleDeg = i * angleStep;
1186
+ const rad = angleDeg * Math.PI / 180;
1187
+ const x = radius * Math.sin(rad);
1188
+ const z = radius * Math.cos(rad);
1189
+ const cfg = options.sideConfigs?.[i];
1190
+ const color$1 = typeof cfg === "string" ? cfg : cfg?.background ?? `hsl(${i * 360 / n}, 70%, 50%)`;
1191
+ panels.push(Layer.box({
1192
+ id: `${options.id ?? "prism"}-panel-${i}`,
1193
+ position: "absolute",
1194
+ width: sideWidth,
1195
+ height,
1196
+ is3D: true,
1197
+ twoSided,
1198
+ x,
1199
+ y: 0,
1200
+ z,
1201
+ rotateY: angleDeg,
1202
+ background: color$1
1203
+ }));
1204
+ }
1205
+ return withParts(Layer.box({
1206
+ id: options.id ?? autoId("prism"),
1207
+ position: "absolute",
1208
+ x: options.x ?? 0,
1209
+ y: options.y ?? 0,
1210
+ z: options.z ?? 0,
1211
+ width: sideWidth,
1212
+ height,
1213
+ is3D: true,
1214
+ transformStyle: "preserve-3d",
1215
+ rotateX: options.rotateX ?? 0,
1216
+ rotateY: options.rotateY ?? 0,
1217
+ rotateZ: options.rotateZ ?? 0,
1218
+ opacity: options.opacity ?? 1,
1219
+ background: "transparent",
1220
+ children: panels
1221
+ }), { faces: panels });
1222
+ },
1223
+ plane(options) {
1224
+ return Layer.box({
1225
+ id: options.id ?? autoId("plane"),
1226
+ position: "absolute",
1227
+ width: options.width,
1228
+ height: options.height,
1229
+ x: options.x ?? 0,
1230
+ y: options.y ?? 0,
1231
+ z: options.z ?? 0,
1232
+ is3D: true,
1233
+ twoSided: options.twoSided ?? true,
1234
+ rotateX: options.rotateX ?? 0,
1235
+ rotateY: options.rotateY ?? 0,
1236
+ rotateZ: options.rotateZ ?? 0,
1237
+ background: options.background ?? "#3b82f6",
1238
+ borderRadius: options.borderRadius ?? 0,
1239
+ opacity: options.opacity ?? 1,
1240
+ children: options.children ?? []
1241
+ });
1242
+ },
1243
+ grid(options) {
1244
+ const { width, height } = options;
1245
+ const id = options.id ?? autoId("grid");
1246
+ const divisions = Math.max(1, Math.round(options.divisions ?? 10));
1247
+ const lineWidth = options.lineWidth ?? 2;
1248
+ const color$1 = options.color ?? "rgba(59, 130, 246, 0.5)";
1249
+ const line$1 = (lineId, x, y, w, h) => Layer.box({
1250
+ id: `${id}-${lineId}`,
1251
+ position: "absolute",
1252
+ x,
1253
+ y,
1254
+ z: 0,
1255
+ width: w,
1256
+ height: h,
1257
+ is3D: true,
1258
+ twoSided: true,
1259
+ material: "unlit",
1260
+ background: color$1
1261
+ });
1262
+ const MAX_SEGMENT = 4096;
1263
+ const lines = [];
1264
+ const vSegments = Math.ceil(height / MAX_SEGMENT);
1265
+ const hSegments = Math.ceil(width / MAX_SEGMENT);
1266
+ for (let i = 0; i <= divisions; i++) {
1267
+ const u = i / divisions - .5;
1268
+ for (let k = 0; k < vSegments; k++) {
1269
+ const len = height / vSegments;
1270
+ const y = -height / 2 + len * (k + .5);
1271
+ lines.push(line$1(`v${i}-${k}`, u * width, y, lineWidth, len));
1272
+ }
1273
+ for (let k = 0; k < hSegments; k++) {
1274
+ const len = width / hSegments;
1275
+ const x = -width / 2 + len * (k + .5);
1276
+ lines.push(line$1(`h${i}-${k}`, x, u * height, len, lineWidth));
1277
+ }
1278
+ }
1279
+ return Layer.box({
1280
+ id,
1281
+ position: "absolute",
1282
+ width,
1283
+ height,
1284
+ x: options.x ?? 0,
1285
+ y: options.y ?? 0,
1286
+ z: options.z ?? 0,
1287
+ is3D: true,
1288
+ transformStyle: "preserve-3d",
1289
+ rotateX: options.rotateX ?? 90,
1290
+ rotateY: options.rotateY ?? 0,
1291
+ rotateZ: options.rotateZ ?? 0,
1292
+ background: "transparent",
1293
+ opacity: options.opacity ?? 1,
1294
+ children: lines
1295
+ });
1296
+ },
1297
+ text(options) {
1298
+ if (options.extrusionDepth && options.extrusionDepth > 0) return Layer3D.extrudedText({
1299
+ ...options,
1300
+ depth: options.extrusionDepth
1301
+ });
1302
+ return Layer.text(options.text, {
1303
+ id: options.id ?? autoId("text3d"),
1304
+ position: "absolute",
1305
+ x: options.x ?? 0,
1306
+ y: options.y ?? 0,
1307
+ z: options.z ?? 0,
1308
+ is3D: true,
1309
+ twoSided: options.twoSided ?? true,
1310
+ rotateX: options.rotateX ?? 0,
1311
+ rotateY: options.rotateY ?? 0,
1312
+ rotateZ: options.rotateZ ?? 0,
1313
+ fontSize: options.fontSize ?? 48,
1314
+ fontFamily: options.fontFamily,
1315
+ fontWeight: options.fontWeight ?? "bold",
1316
+ fontStyle: options.fontStyle,
1317
+ fill: options.fill ?? "#ffffff",
1318
+ align: options.align ?? "center",
1319
+ verticalAlign: options.verticalAlign ?? "middle",
1320
+ letterSpacing: options.letterSpacing,
1321
+ lineHeight: options.lineHeight,
1322
+ material: options.material ?? "lit",
1323
+ shininess: options.shininess ?? 64,
1324
+ roughness: options.roughness,
1325
+ specularIntensity: options.specularIntensity ?? .8,
1326
+ ambientIntensity: options.ambientIntensity ?? 1,
1327
+ metallic: options.metallic,
1328
+ opacity: options.opacity ?? 1,
1329
+ background: options.background,
1330
+ borderRadius: options.borderRadius,
1331
+ padding: options.padding,
1332
+ stroke: options.stroke,
1333
+ strokeWidth: options.strokeWidth
1334
+ });
1335
+ },
1336
+ extrudedText(options) {
1337
+ const { depth, text, fill = "#ffffff", bevelColor } = options;
1338
+ let modelData;
1339
+ const curveTolerance = (options.curveTolerance ?? .1) / extrudedTextScale(options);
1340
+ const parsedFont = (options.fontFamily ? SlugFontCache.getParsed(options.fontFamily) : null) ?? SlugFontCache.getParsed("Inter") ?? SlugFontCache.getParsed("Unbounded") ?? SlugFontCache.getFirstParsed();
1341
+ if (parsedFont) modelData = generateExtrudedTextGeometry({
1342
+ text,
1343
+ font: parsedFont,
1344
+ fontSize: options.fontSize ?? 48,
1345
+ depth,
1346
+ fill,
1347
+ bevelColor,
1348
+ curveSegments: options.curveSegments,
1349
+ curveTolerance,
1350
+ align: options.align,
1351
+ verticalAlign: options.verticalAlign,
1352
+ letterSpacing: options.letterSpacing,
1353
+ material: options.material === "lit" || options.material === "unlit" || options.material === "toon" ? options.material : void 0,
1354
+ shininess: options.shininess,
1355
+ roughness: options.roughness,
1356
+ metallic: options.metallic
1357
+ }).modelData;
1358
+ const modelNode = Layer.model({
1359
+ id: options.id ?? autoId("extruded-text"),
1360
+ modelData,
1361
+ is3D: true,
1362
+ x: options.x ?? 0,
1363
+ y: options.y ?? 0,
1364
+ z: options.z ?? 0,
1365
+ rotateX: options.rotateX ?? 0,
1366
+ rotateY: options.rotateY ?? 0,
1367
+ rotateZ: options.rotateZ ?? 0,
1368
+ scale: options.scale ?? 1,
1369
+ scaleX: options.scaleX ?? 1,
1370
+ scaleY: options.scaleY ?? 1,
1371
+ scaleZ: options.scaleZ ?? 1,
1372
+ opacity: options.opacity ?? 1,
1373
+ material: options.material,
1374
+ shininess: options.shininess ?? 32,
1375
+ roughness: options.roughness,
1376
+ specularIntensity: options.specularIntensity ?? .8,
1377
+ ambientIntensity: options.ambientIntensity ?? 1,
1378
+ metallic: options.metallic,
1379
+ twoSided: options.twoSided ?? true,
1380
+ text3dOptions: {
1381
+ ...options,
1382
+ curveTolerance
1383
+ }
1384
+ });
1385
+ return withParts(modelNode, {
1386
+ faces: [modelNode],
1387
+ items: [modelNode]
1388
+ });
1389
+ },
1390
+ model(options = {}) {
1391
+ return Layer.model(options);
1392
+ },
1393
+ obj(src, options = {}) {
1394
+ return Layer.obj(src, options);
1395
+ },
1396
+ fbx(src, options = {}) {
1397
+ return Layer.fbx(src, options);
1398
+ },
1399
+ gltf(src, options = {}) {
1400
+ return Layer.gltf(src, options);
1401
+ },
1402
+ glb(src, options = {}) {
1403
+ return Layer.glb(src, options);
1404
+ },
1405
+ stl(src, options = {}) {
1406
+ return Layer.stl(src, options);
1407
+ },
1408
+ ply(src, options = {}) {
1409
+ return Layer.ply(src, options);
1410
+ },
1411
+ vox(src, options = {}) {
1412
+ return Layer.vox(src, options);
1413
+ },
1414
+ threeDS(src, options = {}) {
1415
+ return Layer.threeDS(src, options);
1416
+ },
1417
+ off(src, options = {}) {
1418
+ return Layer.off(src, options);
1419
+ }
1420
+ };
1421
+
1422
+ //#endregion
1423
+ //#region src/index.ts
1424
+ function decorateTrackSignals(track, source) {
1425
+ if (!track) return track;
1426
+ if (source && !track.source) Object.defineProperty(track, "source", {
1427
+ value: source,
1428
+ enumerable: true,
1429
+ writable: true,
1430
+ configurable: true
1431
+ });
1432
+ if (typeof track.section !== "function") Object.defineProperty(track, "section", {
1433
+ value: (sourceOrOptions, options) => {
1434
+ if (typeof sourceOrOptions === "object" && sourceOrOptions !== null && !("kind" in sourceOrOptions) && !("inputHandleId" in sourceOrOptions) && !("src" in sourceOrOptions)) {
1435
+ const resolvedSource$1 = sourceOrOptions.source ?? track.source ?? source;
1436
+ return Layer.section(resolvedSource$1, track, sourceOrOptions);
1437
+ }
1438
+ const resolvedSource = sourceOrOptions ?? track.source ?? source;
1439
+ return Layer.section(resolvedSource, track, options);
1440
+ },
1441
+ enumerable: false,
1442
+ writable: true,
1443
+ configurable: true
1444
+ });
1445
+ if (typeof track.blurEffect !== "function") Object.defineProperty(track, "blurEffect", {
1446
+ value: (options) => new Blur({
1447
+ track,
1448
+ ...options
1449
+ }),
1450
+ enumerable: false,
1451
+ writable: true,
1452
+ configurable: true
1453
+ });
1454
+ if (typeof track.isolate !== "function") Object.defineProperty(track, "isolate", {
1455
+ value: (sourceArg, options) => Layer.section(sourceArg, track, options),
1456
+ enumerable: false,
1457
+ writable: true,
1458
+ configurable: true
1459
+ });
1460
+ return track;
1461
+ }
1462
+ const origVisionAttach = VisionNode.attach;
1463
+ VisionNode.attach = function(source, config, bundleOptions) {
1464
+ const bundle = origVisionAttach.call(this, source, config, bundleOptions);
1465
+ if (bundle?.objects) {
1466
+ const src = source;
1467
+ const origGet = bundle.objects.get.bind(bundle.objects);
1468
+ bundle.objects.get = (id) => decorateTrackSignals(origGet(id), src);
1469
+ const origByCategory = bundle.objects.byCategory.bind(bundle.objects);
1470
+ bundle.objects.byCategory = (cat, rank) => decorateTrackSignals(origByCategory(cat, rank), src);
1471
+ if (bundle.objects.primary) decorateTrackSignals(bundle.objects.primary, src);
1472
+ }
1473
+ return bundle;
1474
+ };
1475
+ /**
1476
+ * Fluent builder for single clips and chained visual/audio effect pipelines.
1477
+ */
1478
+ var Media = class Media {
1479
+ virtualMedia;
1480
+ constructor(source, type = "Video") {
1481
+ this.virtualMedia = createVirtualMedia(source, type);
1482
+ }
1483
+ static video(source, meta) {
1484
+ const m = new Media(source, "Video");
1485
+ if (meta) Object.assign(m.virtualMedia.metadata, meta);
1486
+ return m;
1487
+ }
1488
+ static image(source, meta) {
1489
+ const m = new Media(source, "Image");
1490
+ if (meta) Object.assign(m.virtualMedia.metadata, meta);
1491
+ return m;
1492
+ }
1493
+ static audio(source, meta) {
1494
+ const m = new Media(source, "Audio");
1495
+ if (meta) Object.assign(m.virtualMedia.metadata, meta);
1496
+ return m;
1497
+ }
1498
+ apply(effectOrOp, config = {}) {
1499
+ let opPayload;
1500
+ if (effectOrOp instanceof Effect || typeof effectOrOp === "object" && effectOrOp !== null && "op" in effectOrOp) opPayload = effectOrOp.toOperation();
1501
+ else opPayload = {
1502
+ op: effectOrOp,
1503
+ ...config
1504
+ };
1505
+ return new Media(appendOperation(this.virtualMedia, {
1506
+ ...opPayload,
1507
+ dataType: this.virtualMedia.operation.dataType
1508
+ }));
1509
+ }
1510
+ /**
1511
+ * Returns the underlying VirtualMediaData AST node ready for rendering.
1512
+ */
1513
+ toVirtualMedia() {
1514
+ return this.virtualMedia;
1515
+ }
1516
+ /**
1517
+ * Renders a single frame from this media pipeline to a PNG Buffer.
1518
+ * Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).
1519
+ */
1520
+ async renderFrame(options = {}) {
1521
+ return (options.renderer ?? new HeadlessMediaRenderer()).renderFrame(this.virtualMedia, options);
1522
+ }
1523
+ get fps() {
1524
+ return this.virtualMedia.metadata?.fps ?? void 0;
1525
+ }
1526
+ get durationMs() {
1527
+ return this.virtualMedia.metadata?.durationMs ?? void 0;
1528
+ }
1529
+ get width() {
1530
+ return this.virtualMedia.metadata?.width ?? void 0;
1531
+ }
1532
+ get height() {
1533
+ return this.virtualMedia.metadata?.height ?? void 0;
1534
+ }
1535
+ /**
1536
+ * Renders an image grid of sequential frames across a given frame or millisecond range.
1537
+ * Ideal for automated visual inspection of animation motion, easing curves, and layout stability.
1538
+ */
1539
+ async renderFrameGrid(options = {}) {
1540
+ return renderFrameGrid(this, options);
1541
+ }
1542
+ /**
1543
+ * Renders this media pipeline into an MP4/WebM video file with audio.
1544
+ */
1545
+ async renderVideo(outputPathOrOptions = {}, options = {}) {
1546
+ const opts = typeof outputPathOrOptions === "string" ? {
1547
+ ...options,
1548
+ outputPath: outputPathOrOptions
1549
+ } : outputPathOrOptions;
1550
+ return deliverToOutputPath(await (opts.renderer ?? new HeadlessMediaRenderer()).renderVideo(this.virtualMedia, opts), opts.outputPath);
1551
+ }
1552
+ };
1553
+ /**
1554
+ * Copies a rendered temp file to `outputPath` and drops the temp, so the
1555
+ * returned `filePath` is where the video actually lives.
1556
+ */
1557
+ async function deliverToOutputPath(result, outputPath) {
1558
+ if (!outputPath) return result;
1559
+ const target = path.resolve(outputPath);
1560
+ await fs.mkdir(path.dirname(target), { recursive: true });
1561
+ await fs.copyFile(result.filePath, target);
1562
+ await result.cleanup();
1563
+ return {
1564
+ ...result,
1565
+ filePath: target,
1566
+ cleanup: async () => {}
1567
+ };
1568
+ }
1569
+ /**
1570
+ * High-level programmatic builder for multi-layer Framefields compositions.
1571
+ */
1572
+ var Composition = class Composition {
1573
+ width;
1574
+ height;
1575
+ fps;
1576
+ durationMs;
1577
+ backgroundColor;
1578
+ antialias3d;
1579
+ fonts;
1580
+ children = [];
1581
+ audioTracks = [];
1582
+ signals = {};
1583
+ _frameHooks = [];
1584
+ _visionConfig;
1585
+ _visionBundle;
1586
+ _effects = [];
1587
+ /**
1588
+ * Applies a whole-composition post-processing effect or vision pipeline.
1589
+ */
1590
+ apply(effect) {
1591
+ if (effect instanceof Vision) {
1592
+ this.withVision(effect);
1593
+ return this;
1594
+ }
1595
+ this._effects.push(effect);
1596
+ return this;
1597
+ }
1598
+ /**
1599
+ * Runs vision on the whole composition — the rendered frame (composition, blur, crop,
1600
+ * anything upstream) is the inference input. Models are LAZY: nothing downloads until
1601
+ * the first frame actually runs a task.
1602
+ * Returns the reactive VisionBundle (objects / masks / pose / classes signals).
1603
+ */
1604
+ withVision(config = {}) {
1605
+ this._visionBundle ??= new VisionBundle({
1606
+ width: this.width,
1607
+ height: this.height,
1608
+ fps: this.fps
1609
+ });
1610
+ this._visionConfig = {
1611
+ ...config instanceof Vision ? config.config : config,
1612
+ visionBundle: this._visionBundle
1613
+ };
1614
+ return this._visionBundle;
1615
+ }
1616
+ /**
1617
+ * One-shot, ffmpeg-free vision analysis of a media source.
1618
+ *
1619
+ * Decodes frames through the same mediabunny pipeline the renderer uses, runs the requested
1620
+ * tasks lazily (only those models download), temporally tracks detections, and returns a
1621
+ * zod-serializable report. The decoder is released and the runner closed on completion.
1622
+ */
1623
+ async analyzeVisionSequence(source, options = {}) {
1624
+ const fps = options.fps ?? this.fps;
1625
+ const durationMs = this.durationMs ?? await this.computeDuration();
1626
+ const totalFrames = options.totalFrames ?? Math.max(1, Math.round(durationMs / 1e3 * fps));
1627
+ const runner = VisionRunner.create({
1628
+ modelsDir: options.modelsDir,
1629
+ baseUrl: options.baseUrl,
1630
+ ...options.confidence !== void 0 ? { confidence: options.confidence } : {},
1631
+ ...options.variant !== void 0 ? { variant: options.variant } : {}
1632
+ });
1633
+ const decoder = mediaDecoderCache.getVideo(source, true);
1634
+ async function* frameSource() {
1635
+ for (let i = 0; i < totalFrames; i++) {
1636
+ const frame = await decoder.getFrame(i / fps);
1637
+ if (frame?.buffer && frame.width > 0 && frame.height > 0) yield {
1638
+ data: frame.buffer,
1639
+ width: frame.width,
1640
+ height: frame.height
1641
+ };
1642
+ }
1643
+ }
1644
+ try {
1645
+ return await analyzeSequence(frameSource(), {
1646
+ runner,
1647
+ source,
1648
+ fps,
1649
+ ...options.tasks !== void 0 ? { tasks: options.tasks } : {},
1650
+ ...options.categories !== void 0 ? { categories: options.categories } : {},
1651
+ ...options.pathStride !== void 0 ? { pathStride: options.pathStride } : {},
1652
+ ...options.includeMasks !== void 0 ? { includeMasks: options.includeMasks } : {},
1653
+ ...options.iouThreshold !== void 0 ? { iouThreshold: options.iouThreshold } : {}
1654
+ });
1655
+ } finally {
1656
+ runner.close();
1657
+ decoder.destroy();
1658
+ }
1659
+ }
1660
+ /**
1661
+ * Game-engine per-frame lifecycle hook for the composition.
1662
+ * Invoked before rendering each frame so scripts or agents can mutate properties and signals.
1663
+ */
1664
+ onRequestFrame(callback) {
1665
+ this._frameHooks.push(callback);
1666
+ return this;
1667
+ }
1668
+ notifyFrame(ctx) {
1669
+ for (const hook of this._frameHooks) hook(ctx);
1670
+ }
1671
+ constructor(options) {
1672
+ this.width = options.width;
1673
+ this.height = options.height;
1674
+ this.fps = options.fps ?? 60;
1675
+ this.durationMs = options.durationMs ?? (options.durationFrames !== void 0 ? options.durationFrames / this.fps * 1e3 : void 0);
1676
+ this.backgroundColor = options.backgroundColor ?? "#000000";
1677
+ this.antialias3d = options.antialias3d;
1678
+ this.fonts = options.fonts ?? [];
1679
+ this.signals = options.signals ?? {};
1680
+ }
1681
+ static create(options) {
1682
+ return new Composition(options);
1683
+ }
1684
+ addSignal(name, signal$1) {
1685
+ this.signals[name] = signal$1;
1686
+ return this;
1687
+ }
1688
+ add(layerOrFirst, ...rest) {
1689
+ if (layerOrFirst instanceof TensorPipeline) this.children.push(layerOrFirst.toNode());
1690
+ else if (layerOrFirst instanceof VisionNode) this.children.push(layerOrFirst.toNode());
1691
+ else if (layerOrFirst && typeof layerOrFirst === "object" && "node" in layerOrFirst) {
1692
+ this.add(layerOrFirst.node, ...rest);
1693
+ return this;
1694
+ } else if (Array.isArray(layerOrFirst)) for (const l of layerOrFirst) this.add(l);
1695
+ else {
1696
+ const targetNode = layerOrFirst;
1697
+ const animCandidate = rest[0];
1698
+ if (animCandidate && !(animCandidate instanceof TensorPipeline) && !Array.isArray(animCandidate) && (animCandidate instanceof LayerAnimation || "tracks" in animCandidate)) {
1699
+ targetNode.animation = animCandidate instanceof LayerAnimation ? animCandidate.toSpec() : animCandidate;
1700
+ this.children.push(targetNode);
1701
+ return this;
1702
+ }
1703
+ this.children.push(targetNode);
1704
+ }
1705
+ for (const item of rest) if (item && !(item instanceof LayerAnimation) && !("tracks" in item)) this.add(item);
1706
+ return this;
1707
+ }
1708
+ addAudio(track) {
1709
+ this.audioTracks.push(track);
1710
+ return this;
1711
+ }
1712
+ /**
1713
+ * Turnkey "Text Behind Subject" ("Sandwich") Primitive.
1714
+ * Lowers into:
1715
+ * 1. Bottom Layer: Full background video plate
1716
+ * 2. Middle Layer: User-supplied `behind` nodes
1717
+ * 3. Top Layer: Subject cutout video with continuous matte alpha registered at identical coordinates
1718
+ */
1719
+ addSubjectSandwich(options) {
1720
+ const src = typeof options.source === "string" ? options.source : options.source.inputHandleId ?? "";
1721
+ const fit = options.fit ?? "cover";
1722
+ const feather = options.feather ?? 4;
1723
+ const featherVal = feather > 1 ? feather / 100 : feather;
1724
+ const variant = options.variant ?? "s";
1725
+ const bottomPlate = Layer.video(src, {
1726
+ width: this.width,
1727
+ height: this.height,
1728
+ position: "absolute",
1729
+ x: 0,
1730
+ y: 0,
1731
+ fit,
1732
+ muted: options.muted ?? false,
1733
+ volume: options.muted ? 0 : options.volume ?? 1
1734
+ });
1735
+ this.add(bottomPlate);
1736
+ for (const node of options.behind) this.add(node);
1737
+ const topPlate = Layer.video(src, {
1738
+ width: this.width,
1739
+ height: this.height,
1740
+ position: "absolute",
1741
+ x: 0,
1742
+ y: 0,
1743
+ fit,
1744
+ muted: true,
1745
+ volume: 0
1746
+ }).withVision({
1747
+ mode: "matte",
1748
+ enableSegmentation: true,
1749
+ variant,
1750
+ confidence: options.confidence ?? .25,
1751
+ featherRadius: featherVal,
1752
+ keyBackground: options.keyBackground ?? true,
1753
+ backgroundKeyThreshold: options.backgroundKeyThreshold
1754
+ });
1755
+ this.add(topPlate);
1756
+ return this;
1757
+ }
1758
+ /**
1759
+ * Dynamic Smart Re-Framing (16:9 → 9:16 Auto-Crop).
1760
+ * Automatically transforms landscape footage into vertical shorts/reels by framing the
1761
+ * tracked subject with smooth camera physics and lead headroom.
1762
+ */
1763
+ addSmartFraming(options) {
1764
+ const src = typeof options.source === "string" ? options.source : options.source.inputHandleId ?? "";
1765
+ const damping = Math.max(0, Math.min(.99, options.damping ?? .8));
1766
+ const headroom = options.leadHeadroom ?? .18;
1767
+ const compW = this.width;
1768
+ const compH = this.height;
1769
+ const sourceAspect = options.sourceAspect ?? 16 / 9;
1770
+ const compAspect = compW / compH;
1771
+ const plateWidth = compAspect < sourceAspect ? Math.round(compH * sourceAspect) : compW;
1772
+ const plateHeight = compAspect < sourceAspect ? compH : Math.round(compW / sourceAspect);
1773
+ const minOffsetX = compW - plateWidth;
1774
+ const minOffsetY = compH - plateHeight;
1775
+ const targetObj = options.target;
1776
+ const rawOffsetX = new ProgrammaticSignal((ctx) => {
1777
+ if (minOffsetX >= 0) return 0;
1778
+ const normX = targetObj.center?.x ? targetObj.center.x.get(ctx) : targetObj.bounds?.centerX ? targetObj.bounds.centerX.get(ctx) / compW : targetObj.center?.screenX ? targetObj.center.screenX.get(ctx) / compW : .5;
1779
+ const targetPx = Math.max(0, Math.min(1, normX)) * plateWidth;
1780
+ const desired = compW / 2 - targetPx;
1781
+ return Math.max(minOffsetX, Math.min(0, desired));
1782
+ }, {
1783
+ fps: this.fps,
1784
+ label: "smart_framing_pan_x"
1785
+ });
1786
+ const rawOffsetY = new ProgrammaticSignal((ctx) => {
1787
+ if (minOffsetY >= 0) return 0;
1788
+ const normY = targetObj.center?.y ? targetObj.center.y.get(ctx) : targetObj.bounds?.centerY ? targetObj.bounds.centerY.get(ctx) / compH : targetObj.center?.screenY ? targetObj.center.screenY.get(ctx) / compH : .5;
1789
+ const targetPy = Math.max(0, Math.min(1, normY)) * plateHeight;
1790
+ const desired = compH * headroom - targetPy;
1791
+ return Math.max(minOffsetY, Math.min(0, desired));
1792
+ }, {
1793
+ fps: this.fps,
1794
+ label: "smart_framing_pan_y"
1795
+ });
1796
+ const smoothOffsetX = new ProgrammaticSignal((ctx) => {
1797
+ const targetFrame = ctx.frame;
1798
+ if (targetFrame <= 0) return rawOffsetX.get(ctx);
1799
+ let filtered = rawOffsetX.get({
1800
+ ...ctx,
1801
+ frame: 0,
1802
+ time: 0
1803
+ });
1804
+ const alpha = 1 - damping;
1805
+ for (let f = 1; f <= targetFrame; f++) {
1806
+ const val = rawOffsetX.get({
1807
+ ...ctx,
1808
+ frame: f,
1809
+ time: f / ctx.fps
1810
+ });
1811
+ filtered = filtered + alpha * (val - filtered);
1812
+ }
1813
+ return filtered;
1814
+ }, {
1815
+ fps: this.fps,
1816
+ label: "smart_framing_smooth_x"
1817
+ });
1818
+ const smoothOffsetY = new ProgrammaticSignal((ctx) => {
1819
+ const targetFrame = ctx.frame;
1820
+ if (targetFrame <= 0) return rawOffsetY.get(ctx);
1821
+ let filtered = rawOffsetY.get({
1822
+ ...ctx,
1823
+ frame: 0,
1824
+ time: 0
1825
+ });
1826
+ const alpha = 1 - damping;
1827
+ for (let f = 1; f <= targetFrame; f++) {
1828
+ const val = rawOffsetY.get({
1829
+ ...ctx,
1830
+ frame: f,
1831
+ time: f / ctx.fps
1832
+ });
1833
+ filtered = filtered + alpha * (val - filtered);
1834
+ }
1835
+ return filtered;
1836
+ }, {
1837
+ fps: this.fps,
1838
+ label: "smart_framing_smooth_y"
1839
+ });
1840
+ const container = Layer.box({
1841
+ width: compW,
1842
+ height: compH,
1843
+ overflow: "hidden",
1844
+ position: "relative"
1845
+ });
1846
+ const videoPlate = Layer.video(src, {
1847
+ width: plateWidth,
1848
+ height: plateHeight,
1849
+ position: "absolute",
1850
+ x: smoothOffsetX,
1851
+ y: smoothOffsetY,
1852
+ fit: options.fit ?? "cover",
1853
+ muted: options.muted ?? false,
1854
+ volume: options.muted ? 0 : options.volume ?? 1
1855
+ });
1856
+ (container.children ??= []).push(videoPlate);
1857
+ this.add(container);
1858
+ return this;
1859
+ }
1860
+ /**
1861
+ * Subject Contour Glow & Neon Outline.
1862
+ * Strokes the silhouette boundary with a stylized bloom/glow and optional audio-reactive pulse.
1863
+ */
1864
+ addSubjectOutline(_subject, options = {}) {
1865
+ const blur = options.blur ?? 12;
1866
+ const compW = this.width;
1867
+ const compH = this.height;
1868
+ const pulse = options.pulseSignal;
1869
+ const baseOpacity = pulse ? new ProgrammaticSignal((ctx) => Math.max(0, Math.min(1, Number(pulse.get(ctx)) || 0)), {
1870
+ fps: this.fps,
1871
+ label: "outline_pulse"
1872
+ }) : 1;
1873
+ const src = typeof options.source === "string" ? options.source : options.source?.inputHandleId ?? "";
1874
+ const outlineLayer = Layer.box({
1875
+ width: compW,
1876
+ height: compH,
1877
+ position: "absolute",
1878
+ x: 0,
1879
+ y: 0,
1880
+ opacity: baseOpacity
1881
+ });
1882
+ if (src) {
1883
+ const maskVideo = Layer.video(src, {
1884
+ width: compW,
1885
+ height: compH,
1886
+ position: "absolute",
1887
+ x: 0,
1888
+ y: 0,
1889
+ fit: "cover",
1890
+ muted: true,
1891
+ volume: 0
1892
+ }).withVision({
1893
+ mode: "mask",
1894
+ enableSegmentation: true
1895
+ });
1896
+ (outlineLayer.children ??= []).push(maskVideo);
1897
+ }
1898
+ outlineLayer.apply(new Blur({
1899
+ strength: blur,
1900
+ blurType: "Gaussian"
1901
+ }));
1902
+ this.add(outlineLayer);
1903
+ return this;
1904
+ }
1905
+ /**
1906
+ * Creates an isolated, styled section of the composition or underlying source plate.
1907
+ * Any WebGPU effects (Blur, FilmGrain, Curves, Vignette, etc.) can be applied to this section.
1908
+ */
1909
+ section(sourceOrTargetOrOptions, targetOrOptions, options) {
1910
+ let source;
1911
+ let target;
1912
+ let opts = {};
1913
+ const isFirstTrack = sourceOrTargetOrOptions !== null && typeof sourceOrTargetOrOptions === "object" && "bounds" in sourceOrTargetOrOptions;
1914
+ const isFirstMedia = typeof sourceOrTargetOrOptions === "string" || sourceOrTargetOrOptions !== null && typeof sourceOrTargetOrOptions === "object" && ("kind" in sourceOrTargetOrOptions || "src" in sourceOrTargetOrOptions || "inputHandleId" in sourceOrTargetOrOptions);
1915
+ if (isFirstMedia && targetOrOptions && typeof targetOrOptions === "object" && "bounds" in targetOrOptions) {
1916
+ source = sourceOrTargetOrOptions;
1917
+ target = targetOrOptions;
1918
+ opts = options ?? {};
1919
+ } else if (isFirstMedia && targetOrOptions) {
1920
+ source = sourceOrTargetOrOptions;
1921
+ opts = targetOrOptions;
1922
+ } else if (isFirstTrack) {
1923
+ target = sourceOrTargetOrOptions;
1924
+ opts = targetOrOptions ?? {};
1925
+ source = opts.source ?? target.source;
1926
+ } else if (sourceOrTargetOrOptions && typeof sourceOrTargetOrOptions === "object") {
1927
+ opts = sourceOrTargetOrOptions;
1928
+ source = opts.source;
1929
+ }
1930
+ if (!source) {
1931
+ const mediaChild = this.children.find((c) => c.kind === "media" && (c.dataType === "Video" || c.dataType === "Image"));
1932
+ if (mediaChild) source = mediaChild;
1933
+ }
1934
+ return Layer.section(source ?? "", target ?? opts, {
1935
+ compositionWidth: this.width,
1936
+ compositionHeight: this.height,
1937
+ ...opts
1938
+ });
1939
+ }
1940
+ /**
1941
+ * Creates a section and immediately adds it to the composition layout tree.
1942
+ */
1943
+ addSection(sourceOrTargetOrOptions, targetOrOptions, options) {
1944
+ const node = this.section(sourceOrTargetOrOptions, targetOrOptions, options);
1945
+ this.add(node);
1946
+ return node;
1947
+ }
1948
+ /**
1949
+ * Dynamically calculates composition duration from the longest media or animation layer.
1950
+ */
1951
+ async computeDuration() {
1952
+ if (this.durationMs !== void 0) return this.durationMs;
1953
+ let maxDurationMs = 0;
1954
+ const mediaSources = [];
1955
+ for (const node of [...this.children, ...this.audioTracks]) {
1956
+ if (node.kind === "media") {
1957
+ const src = node.inputHandleId;
1958
+ if (typeof src === "string" && (node.dataType === "Video" || node.dataType === "Audio")) mediaSources.push(src);
1959
+ }
1960
+ if (typeof node.durationFrames === "number") {
1961
+ const durMs = ((typeof node.startFrame === "number" ? node.startFrame : 0) + node.durationFrames) / this.fps * 1e3;
1962
+ if (durMs > maxDurationMs) maxDurationMs = durMs;
1963
+ }
1964
+ }
1965
+ for (const src of mediaSources) try {
1966
+ const sec = await (await inputStore.acquire(src)).computeDuration();
1967
+ if (Number.isFinite(sec) && sec > 0) {
1968
+ const ms = Math.round(sec * 1e3);
1969
+ if (ms > maxDurationMs) maxDurationMs = ms;
1970
+ }
1971
+ } catch (_) {}
1972
+ return maxDurationMs > 0 ? maxDurationMs : 5e3;
1973
+ }
1974
+ async registerFont(optionsOrFamilyOrSource, source) {
1975
+ const reg = await FontManager.register(optionsOrFamilyOrSource, source);
1976
+ if (reg.filePath && !this.fonts.includes(reg.filePath)) this.fonts.push(reg.filePath);
1977
+ return this;
1978
+ }
1979
+ toSpec() {
1980
+ const layoutItems = [...this.children, ...this.audioTracks];
1981
+ const registeredPaths = FontManager.getRegisteredFontPaths();
1982
+ const mergedFonts = Array.from(new Set([...this.fonts, ...registeredPaths]));
1983
+ return {
1984
+ width: this.width,
1985
+ height: this.height,
1986
+ fps: this.fps,
1987
+ mode: "Video",
1988
+ backgroundColor: this.backgroundColor,
1989
+ ...this.antialias3d !== void 0 && { antialias3d: this.antialias3d },
1990
+ layout: layoutItems,
1991
+ fonts: mergedFonts,
1992
+ signals: this.signals,
1993
+ ...this._effects.length > 0 && { effects: this._effects },
1994
+ ...this._visionConfig && { vision: this._visionConfig },
1995
+ ...this._frameHooks.length > 0 && { onRequestFrame: (ctx) => this.notifyFrame(ctx) }
1996
+ };
1997
+ }
1998
+ /**
1999
+ * Compiles the composition into a VirtualMediaData AST ready for WebGPU rendering.
2000
+ */
2001
+ toVirtualMedia(options = {}) {
2002
+ return compositorToProgram(this.toSpec(), {
2003
+ isVideoMode: true,
2004
+ fps: this.fps,
2005
+ durationMs: options.durationMs ?? this.durationMs,
2006
+ signals: options.signals ?? this.signals,
2007
+ ...this._effects.length > 0 && { effects: this._effects },
2008
+ ...this._visionConfig && { vision: this._visionConfig },
2009
+ ...options
2010
+ });
2011
+ }
2012
+ /**
2013
+ * Compiles the composition into a VirtualMediaData AST with dynamically resolved duration.
2014
+ */
2015
+ async toVirtualMediaAsync(options = {}) {
2016
+ const durationMs = options.durationMs ?? this.durationMs ?? await this.computeDuration();
2017
+ this.durationMs = durationMs;
2018
+ return compositorToProgram(this.toSpec(), {
2019
+ isVideoMode: true,
2020
+ fps: this.fps,
2021
+ durationMs,
2022
+ signals: options.signals ?? this.signals,
2023
+ ...this._effects.length > 0 && { effects: this._effects },
2024
+ ...this._visionConfig && { vision: this._visionConfig },
2025
+ ...options
2026
+ });
2027
+ }
2028
+ /**
2029
+ * Renders a single frame from the composition to a PNG Buffer.
2030
+ * Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).
2031
+ */
2032
+ async renderFrame(options = {}) {
2033
+ if (this._frameHooks.length > 0) {
2034
+ const targetFrame = options.frame ?? (options.atMs !== void 0 ? Math.round(options.atMs / 1e3 * this.fps) : 0);
2035
+ this.notifyFrame({
2036
+ frame: targetFrame,
2037
+ fps: this.fps,
2038
+ time: this.fps > 0 ? targetFrame / this.fps : 0,
2039
+ duration: (this.durationMs ?? 0) / 1e3,
2040
+ durationMs: this.durationMs ?? 0,
2041
+ progress: this.durationMs && this.durationMs > 0 ? Math.max(0, Math.min(1, targetFrame / this.fps * 1e3 / this.durationMs)) : 0,
2042
+ deltaTime: this.fps > 0 ? 1 / this.fps : 0
2043
+ });
2044
+ }
2045
+ return (options.renderer ?? new HeadlessMediaRenderer()).renderFrame(this.toVirtualMedia(), {
2046
+ fps: this.fps,
2047
+ ...options
2048
+ });
2049
+ }
2050
+ /**
2051
+ * Renders an image grid of sequential frames across a given frame or millisecond range.
2052
+ * Ideal for automated visual inspection of animation motion, easing curves, and layout stability.
2053
+ */
2054
+ async renderFrameGrid(options = {}) {
2055
+ return renderFrameGrid(this, options);
2056
+ }
2057
+ /**
2058
+ * Renders this composition into an MP4/WebM video file with audio.
2059
+ */
2060
+ async renderVideo(outputPathOrOptions = {}, options = {}) {
2061
+ const opts = typeof outputPathOrOptions === "string" ? {
2062
+ ...options,
2063
+ outputPath: outputPathOrOptions
2064
+ } : outputPathOrOptions;
2065
+ return deliverToOutputPath(await (opts.renderer ?? new HeadlessMediaRenderer()).renderVideo(this.toVirtualMedia(), opts), opts.outputPath);
2066
+ }
2067
+ };
2068
+ function withAnimation(node) {
2069
+ const target = node;
2070
+ Object.defineProperty(target, "animate", {
2071
+ value: (...anims) => {
2072
+ const flatAnims = anims.flat();
2073
+ if (flatAnims.length > 1 || flatAnims.length === 1 && Array.isArray(anims[0])) target.animation = { tracks: flatAnims.flatMap((a) => a instanceof LayerAnimation ? a.tracks : a.tracks ?? []) };
2074
+ else if (flatAnims.length === 1) {
2075
+ const anim = flatAnims[0];
2076
+ target.animation = anim instanceof LayerAnimation ? anim.toSpec() : anim;
2077
+ }
2078
+ return target;
2079
+ },
2080
+ enumerable: false,
2081
+ writable: true,
2082
+ configurable: true
2083
+ });
2084
+ Object.defineProperty(target, "pinToLandmark", {
2085
+ value: (landmarkTarget, options) => {
2086
+ pinNodeToLandmark(target, landmarkTarget, options);
2087
+ return target;
2088
+ },
2089
+ enumerable: false,
2090
+ writable: true,
2091
+ configurable: true
2092
+ });
2093
+ Object.defineProperty(target, "pinToObject", {
2094
+ value: (objectTarget, options) => {
2095
+ pinNodeToObject(target, objectTarget, options);
2096
+ return target;
2097
+ },
2098
+ enumerable: false,
2099
+ writable: true,
2100
+ configurable: true
2101
+ });
2102
+ Object.defineProperty(target, "withMask", {
2103
+ value: (mask) => {
2104
+ target.mask = mask;
2105
+ return target;
2106
+ },
2107
+ enumerable: false,
2108
+ writable: true,
2109
+ configurable: true
2110
+ });
2111
+ Object.defineProperty(target, "withPbrGlass", {
2112
+ value: (options) => {
2113
+ target.glass = options ?? {};
2114
+ return target;
2115
+ },
2116
+ enumerable: false,
2117
+ writable: true,
2118
+ configurable: true
2119
+ });
2120
+ Object.defineProperty(target, "deformWithAudio", {
2121
+ value: (config) => {
2122
+ target.audioDeform = config ?? {};
2123
+ return target;
2124
+ },
2125
+ enumerable: false,
2126
+ writable: true,
2127
+ configurable: true
2128
+ });
2129
+ Object.defineProperty(target, "withCrop", {
2130
+ value: (cropConfig) => {
2131
+ target.crop = cropConfig instanceof Crop ? cropConfig : new Crop(cropConfig);
2132
+ return target;
2133
+ },
2134
+ enumerable: false,
2135
+ writable: true,
2136
+ configurable: true
2137
+ });
2138
+ Object.defineProperty(target, "withVision", {
2139
+ value: (config) => {
2140
+ target.vision = config instanceof Vision ? config : new Vision(config);
2141
+ return target;
2142
+ },
2143
+ enumerable: false,
2144
+ writable: true,
2145
+ configurable: true
2146
+ });
2147
+ Object.defineProperty(target, "withRelighting", {
2148
+ value: (options) => {
2149
+ target.relighting = options ?? {};
2150
+ return target;
2151
+ },
2152
+ enumerable: false,
2153
+ writable: true,
2154
+ configurable: true
2155
+ });
2156
+ Object.defineProperty(target, "relight", {
2157
+ value: (options) => {
2158
+ target.relighting = options ?? {};
2159
+ return target;
2160
+ },
2161
+ enumerable: false,
2162
+ writable: true,
2163
+ configurable: true
2164
+ });
2165
+ Object.defineProperty(target, "withDeflicker", {
2166
+ value: (options) => {
2167
+ target.deflicker = options ?? {};
2168
+ return target;
2169
+ },
2170
+ enumerable: false,
2171
+ writable: true,
2172
+ configurable: true
2173
+ });
2174
+ Object.defineProperty(target, "apply", {
2175
+ value: (effect) => {
2176
+ if (!target.effects) target.effects = [];
2177
+ target.effects.push(effect);
2178
+ return target;
2179
+ },
2180
+ enumerable: false,
2181
+ writable: true,
2182
+ configurable: true
2183
+ });
2184
+ Object.defineProperty(target, "withEffect", {
2185
+ value: (effect) => {
2186
+ if (!target.effects) target.effects = [];
2187
+ target.effects.push(effect);
2188
+ return target;
2189
+ },
2190
+ enumerable: false,
2191
+ writable: true,
2192
+ configurable: true
2193
+ });
2194
+ Object.defineProperty(target, "withEffects", {
2195
+ value: (effects) => {
2196
+ if (!target.effects) target.effects = [];
2197
+ target.effects.push(...effects);
2198
+ return target;
2199
+ },
2200
+ enumerable: false,
2201
+ writable: true,
2202
+ configurable: true
2203
+ });
2204
+ Object.defineProperty(target, "section", {
2205
+ value: (targetOrOptions = {}, options) => {
2206
+ if (targetOrOptions !== null && typeof targetOrOptions === "object" && "bounds" in targetOrOptions) return Layer.section(target, targetOrOptions, options);
2207
+ return Layer.section(target, targetOrOptions);
2208
+ },
2209
+ enumerable: false,
2210
+ writable: true,
2211
+ configurable: true
2212
+ });
2213
+ Object.defineProperty(target, "blurRegion", {
2214
+ value: (trackTarget, options) => {
2215
+ const blur = new Blur({
2216
+ track: trackTarget,
2217
+ strength: options?.strength ?? 25,
2218
+ shape: options?.shape ?? "ellipse",
2219
+ ...options
2220
+ });
2221
+ if (!target.effects) target.effects = [];
2222
+ target.effects.push(blur);
2223
+ return target;
2224
+ },
2225
+ enumerable: false,
2226
+ writable: true,
2227
+ configurable: true
2228
+ });
2229
+ Object.defineProperty(target, "withBlurRegion", {
2230
+ value: (trackTarget, options) => {
2231
+ return target.blurRegion(trackTarget, options);
2232
+ },
2233
+ enumerable: false,
2234
+ writable: true,
2235
+ configurable: true
2236
+ });
2237
+ return target;
2238
+ }
2239
+ const Layer = {
2240
+ video: (src, options = {}) => withAnimation({
2241
+ id: options.id ?? autoId("video"),
2242
+ kind: "media",
2243
+ inputHandleId: src,
2244
+ dataType: "Video",
2245
+ fit: options.fit ?? "cover",
2246
+ ...options
2247
+ }),
2248
+ image: (src, options = {}) => withAnimation({
2249
+ id: options.id ?? autoId("img"),
2250
+ kind: "media",
2251
+ inputHandleId: src,
2252
+ dataType: "Image",
2253
+ fit: options.fit ?? "cover",
2254
+ ...options
2255
+ }),
2256
+ svg: (src, options = {}) => withAnimation({
2257
+ id: options.id ?? autoId("svg"),
2258
+ kind: "media",
2259
+ inputHandleId: src,
2260
+ dataType: "SVG",
2261
+ fit: options.fit ?? "contain",
2262
+ ...options
2263
+ }),
2264
+ lottie: (src, options = {}) => withAnimation({
2265
+ id: options.id ?? autoId("lottie"),
2266
+ kind: "media",
2267
+ inputHandleId: src,
2268
+ dataType: "Lottie",
2269
+ fit: options.fit ?? "contain",
2270
+ ...options
2271
+ }),
2272
+ audio: (src, options = {}) => withAnimation({
2273
+ id: options.id ?? autoId("audio"),
2274
+ kind: "media",
2275
+ inputHandleId: src,
2276
+ dataType: "Audio",
2277
+ volume: options.volume ?? 1,
2278
+ ...options
2279
+ }),
2280
+ text: (contentOrOptions, maybeOptions = {}) => {
2281
+ const isArray = Array.isArray(contentOrOptions);
2282
+ const isObj = !isArray && typeof contentOrOptions === "object" && contentOrOptions !== null;
2283
+ const options = isObj ? contentOrOptions : maybeOptions;
2284
+ let textContent = "";
2285
+ let spans = options.spans;
2286
+ if (isArray) {
2287
+ const normalized = normalizeTextSpans(contentOrOptions);
2288
+ textContent = normalized.text;
2289
+ spans = normalized.spans;
2290
+ } else if (isObj) if (options.spans && !options.text) textContent = normalizeTextSpans(options.spans).text;
2291
+ else textContent = options.text ?? "";
2292
+ else textContent = typeof contentOrOptions === "string" ? contentOrOptions : String(contentOrOptions ?? "");
2293
+ return withAnimation({
2294
+ id: options.id ?? autoId("text"),
2295
+ kind: "text",
2296
+ fontFamily: options.fontFamily ?? FontManager.getAll()[0]?.family ?? "Inter",
2297
+ fontSize: options.fontSize ?? 48,
2298
+ fill: options.fill ?? "#ffffff",
2299
+ ...options,
2300
+ text: options.text ?? textContent,
2301
+ spans: options.spans ?? spans
2302
+ });
2303
+ },
2304
+ caption: (src, options = {}) => withAnimation({
2305
+ id: options.id ?? autoId("caption"),
2306
+ kind: "media",
2307
+ inputHandleId: src,
2308
+ dataType: options.dataType ?? "Caption",
2309
+ fontFamily: options.fontFamily ?? FontManager.getAll()[0]?.family ?? "Inter",
2310
+ fontSize: options.fontSize ?? 48,
2311
+ fill: options.fill ?? "#ffffff",
2312
+ ...options
2313
+ }),
2314
+ shape: (shapeType = "rect", options = {}) => withAnimation({
2315
+ id: options.id ?? autoId("shape"),
2316
+ kind: "shape",
2317
+ shapeType: options.shapeType ?? shapeType,
2318
+ fillColor: options.fillColor ?? "#3b82f6",
2319
+ ...options
2320
+ }),
2321
+ flex: (options = {}) => withAnimation({
2322
+ id: options.id ?? autoId("flex"),
2323
+ kind: "flex",
2324
+ dir: options.dir ?? "column",
2325
+ children: options.children ?? [],
2326
+ ...options
2327
+ }),
2328
+ box: (options = {}) => withAnimation({
2329
+ id: options.id ?? autoId("box"),
2330
+ kind: "box",
2331
+ background: options.background ?? "transparent",
2332
+ children: options.children ?? [],
2333
+ ...options
2334
+ }),
2335
+ section: (source, targetOrOptions = {}, options = {}) => {
2336
+ let realSource = source;
2337
+ if (source && typeof source === "object" && "toSpec" in source && "children" in source) {
2338
+ const compMedia = (source.children || []).find((c) => c.kind === "media" && (c.dataType === "Video" || c.dataType === "Image"));
2339
+ if (compMedia) realSource = compMedia;
2340
+ }
2341
+ const isTracked = targetOrOptions !== null && typeof targetOrOptions === "object" && "bounds" in targetOrOptions;
2342
+ const opts = isTracked ? options : targetOrOptions;
2343
+ const target = isTracked ? targetOrOptions : void 0;
2344
+ const padding = opts.padding ?? 0;
2345
+ const src = typeof realSource === "string" ? realSource : realSource?.inputHandleId ?? realSource?.src ?? "";
2346
+ const dataType = typeof realSource === "object" && realSource?.dataType ? realSource.dataType : "Video";
2347
+ const compW = opts.compositionWidth ?? opts.compWidth ?? (isTracked ? opts.width : void 0) ?? 1920;
2348
+ const compH = opts.compositionHeight ?? opts.compHeight ?? (isTracked ? opts.height : void 0) ?? 1080;
2349
+ const effList = Array.isArray(opts.effects) ? [...opts.effects] : opts.effects ? [opts.effects] : [];
2350
+ const innerX = target ? target.bounds.screenX.multiply(-1).add(padding) : typeof opts.x === "number" ? -opts.x : opts.x && typeof opts.x.multiply === "function" ? opts.x.multiply(-1) : 0;
2351
+ const innerY = target ? target.bounds.screenY.multiply(-1).add(padding) : typeof opts.y === "number" ? -opts.y : opts.y && typeof opts.y.multiply === "function" ? opts.y.multiply(-1) : 0;
2352
+ const innerMedia = (dataType === "Image" ? Layer.image(src, {
2353
+ position: "absolute",
2354
+ width: compW,
2355
+ height: compH,
2356
+ fit: opts.fit ?? "cover",
2357
+ x: innerX,
2358
+ y: innerY
2359
+ }) : Layer.video(src, {
2360
+ position: "absolute",
2361
+ width: compW,
2362
+ height: compH,
2363
+ fit: opts.fit ?? "cover",
2364
+ x: innerX,
2365
+ y: innerY
2366
+ })).withEffects(effList);
2367
+ const boxWidth = target ? target.bounds.screenWidth.add(padding * 2) : opts.width !== void 0 ? opts.width : compW;
2368
+ const boxHeight = target ? target.bounds.screenHeight.add(padding * 2) : opts.height !== void 0 ? opts.height : compH;
2369
+ const boxChildren = [innerMedia, ...opts.children ?? []];
2370
+ const boxId = opts.id ?? (target ? autoId(`section-track-${target.trackId}`) : autoId("section"));
2371
+ let box = Layer.box({
2372
+ id: boxId,
2373
+ position: opts.position ?? "absolute",
2374
+ width: boxWidth,
2375
+ height: boxHeight,
2376
+ x: target ? void 0 : opts.x,
2377
+ y: target ? void 0 : opts.y,
2378
+ borderRadius: opts.borderRadius ?? 0,
2379
+ borderColor: opts.borderColor,
2380
+ borderWidth: opts.borderWidth,
2381
+ opacity: opts.opacity ?? 1,
2382
+ overflow: "hidden",
2383
+ children: boxChildren
2384
+ });
2385
+ if (target) box = box.pinToObject(target, {
2386
+ anchor: "topLeft",
2387
+ offsetX: -padding,
2388
+ offsetY: -padding,
2389
+ hideWhenLost: opts.hideWhenLost ?? true,
2390
+ smoothFrames: opts.smoothFrames
2391
+ });
2392
+ const sectionNode = box;
2393
+ Object.defineProperty(sectionNode, "innerMedia", {
2394
+ value: innerMedia,
2395
+ enumerable: true,
2396
+ writable: false
2397
+ });
2398
+ Object.defineProperty(sectionNode, "effects", {
2399
+ get: () => effList,
2400
+ enumerable: true
2401
+ });
2402
+ Object.defineProperty(sectionNode, "addEffect", {
2403
+ value: (effect) => {
2404
+ effList.push(effect);
2405
+ innerMedia.effects = effList;
2406
+ return sectionNode;
2407
+ },
2408
+ enumerable: true,
2409
+ writable: false
2410
+ });
2411
+ Object.defineProperty(sectionNode, "withEffect", {
2412
+ value: (effect) => sectionNode.addEffect(effect),
2413
+ enumerable: true,
2414
+ writable: false
2415
+ });
2416
+ Object.defineProperty(sectionNode, "withEffects", {
2417
+ value: (effects) => {
2418
+ for (const eff of effects) sectionNode.addEffect(eff);
2419
+ return sectionNode;
2420
+ },
2421
+ enumerable: true,
2422
+ writable: false
2423
+ });
2424
+ return sectionNode;
2425
+ },
2426
+ trackedRegion: (source, target, options = {}) => {
2427
+ return Layer.section(source, target, options);
2428
+ },
2429
+ blurTrackedRegion: (source, target, options = {}) => {
2430
+ const { padding, borderRadius, borderColor, borderWidth, ...blurOptions } = options;
2431
+ return Layer.section(source, target, {
2432
+ padding: padding ?? 8,
2433
+ borderRadius: borderRadius ?? 12,
2434
+ borderColor,
2435
+ borderWidth,
2436
+ effects: [new Blur({
2437
+ strength: blurOptions.strength ?? 25,
2438
+ blurType: blurOptions.blurType ?? "Gaussian",
2439
+ ...blurOptions
2440
+ })]
2441
+ });
2442
+ },
2443
+ chart: (options, props = {}) => buildChart(options, props, FontManager.getAll()[0]?.family ?? "Inter"),
2444
+ camera: (options = {}) => withAnimation({
2445
+ id: options.id ?? autoId("camera"),
2446
+ kind: "camera",
2447
+ mode: options.mode ?? "lookAt",
2448
+ pitch: options.pitch ?? 0,
2449
+ yaw: options.yaw ?? 0,
2450
+ roll: options.roll ?? 0,
2451
+ ...options
2452
+ }),
2453
+ light: (options = {}) => withAnimation({
2454
+ id: options.id ?? autoId("light"),
2455
+ kind: "light",
2456
+ lightType: options.lightType ?? "point",
2457
+ color: options.color ?? "#ffffff",
2458
+ intensity: options.intensity ?? 1,
2459
+ ...options
2460
+ }),
2461
+ ambientLight: (color$1 = "#ffffff", intensity = .5, options = {}) => Light.ambient(color$1, intensity, options),
2462
+ directionalLight: (options = {}) => Light.directional(options),
2463
+ pointLight: (options = {}) => Light.point(options),
2464
+ spotLight: (options = {}) => Light.spot(options),
2465
+ cube: (options) => Layer3D.cube(options),
2466
+ carousel3d: (options) => Layer3D.carousel(options),
2467
+ plane3d: (options) => Layer3D.plane(options),
2468
+ prism3d: (options) => Layer3D.prism(options),
2469
+ model: (options = {}) => withAnimation({
2470
+ id: options.id ?? autoId("model3d"),
2471
+ kind: "model3d",
2472
+ is3D: options.is3D ?? true,
2473
+ modelFormat: options.modelFormat ?? "auto",
2474
+ loop: options.loop ?? true,
2475
+ scale: options.scale ?? 1,
2476
+ scaleX: options.scaleX ?? 1,
2477
+ scaleY: options.scaleY ?? 1,
2478
+ scaleZ: options.scaleZ ?? 1,
2479
+ opacity: options.opacity ?? 1,
2480
+ ...options
2481
+ }),
2482
+ obj: (src, options = {}) => Layer.model({
2483
+ src,
2484
+ modelFormat: "obj",
2485
+ ...options
2486
+ }),
2487
+ fbx: (src, options = {}) => Layer.model({
2488
+ src,
2489
+ modelFormat: "fbx",
2490
+ ...options
2491
+ }),
2492
+ gltf: (src, options = {}) => Layer.model({
2493
+ src,
2494
+ modelFormat: "gltf",
2495
+ ...options
2496
+ }),
2497
+ glb: (src, options = {}) => Layer.model({
2498
+ src,
2499
+ modelFormat: "glb",
2500
+ ...options
2501
+ }),
2502
+ stl: (src, options = {}) => Layer.model({
2503
+ src,
2504
+ modelFormat: "stl",
2505
+ ...options
2506
+ }),
2507
+ ply: (src, options = {}) => Layer.model({
2508
+ src,
2509
+ modelFormat: "ply",
2510
+ ...options
2511
+ }),
2512
+ vox: (src, options = {}) => Layer.model({
2513
+ src,
2514
+ modelFormat: "vox",
2515
+ ...options
2516
+ }),
2517
+ threeDS: (src, options = {}) => Layer.model({
2518
+ src,
2519
+ modelFormat: "3ds",
2520
+ ...options
2521
+ }),
2522
+ off: (src, options = {}) => Layer.model({
2523
+ src,
2524
+ modelFormat: "off",
2525
+ ...options
2526
+ })
2527
+ };
2528
+ const Light = {
2529
+ ambient: (color$1 = "#ffffff", intensity = .5, options = {}) => withAnimation({
2530
+ id: options.id ?? autoId("light-ambient"),
2531
+ kind: "light",
2532
+ lightType: "ambient",
2533
+ color: color$1,
2534
+ intensity,
2535
+ ...options
2536
+ }),
2537
+ directional: (options = {}) => withAnimation({
2538
+ id: options.id ?? autoId("light-directional"),
2539
+ kind: "light",
2540
+ lightType: "directional",
2541
+ color: options.color ?? "#ffffff",
2542
+ intensity: options.intensity ?? 1,
2543
+ x: options.x ?? 0,
2544
+ y: options.y ?? -1e3,
2545
+ z: options.z ?? -1e3,
2546
+ targetX: options.targetX ?? 0,
2547
+ targetY: options.targetY ?? 0,
2548
+ targetZ: options.targetZ ?? 0,
2549
+ ...options
2550
+ }),
2551
+ point: (options = {}) => withAnimation({
2552
+ id: options.id ?? autoId("light-point"),
2553
+ kind: "light",
2554
+ lightType: "point",
2555
+ color: options.color ?? "#ffffff",
2556
+ intensity: options.intensity ?? 1,
2557
+ x: options.x ?? 0,
2558
+ y: options.y ?? 0,
2559
+ z: options.z ?? -500,
2560
+ radius: options.radius ?? 1e3,
2561
+ decay: options.decay ?? 1,
2562
+ ...options
2563
+ }),
2564
+ spot: (options = {}) => withAnimation({
2565
+ id: options.id ?? autoId("light-spot"),
2566
+ kind: "light",
2567
+ lightType: "spot",
2568
+ color: options.color ?? "#ffffff",
2569
+ intensity: options.intensity ?? 1,
2570
+ x: options.x ?? 0,
2571
+ y: options.y ?? -500,
2572
+ z: options.z ?? -1e3,
2573
+ targetX: options.targetX ?? 0,
2574
+ targetY: options.targetY ?? 0,
2575
+ targetZ: options.targetZ ?? 0,
2576
+ angle: options.angle ?? 45,
2577
+ penumbra: options.penumbra ?? .2,
2578
+ radius: options.radius ?? 2e3,
2579
+ decay: options.decay ?? 1,
2580
+ ...options
2581
+ })
2582
+ };
2583
+ function section(source, targetOrOptions = {}, options = {}) {
2584
+ return Layer.section(source, targetOrOptions, options);
2585
+ }
2586
+ function blurRegion(sourceOrLayer, target, options = {}) {
2587
+ if (typeof sourceOrLayer === "object" && "blurRegion" in sourceOrLayer) return sourceOrLayer.blurRegion(target, options);
2588
+ return Layer.blurTrackedRegion(sourceOrLayer, target, options);
2589
+ }
2590
+ function editTrackedRegion(source, target, options = {}) {
2591
+ return Layer.section(source, target, options);
2592
+ }
2593
+ const Effect = Object.assign(Effect$1, {
2594
+ blur: (config) => new Blur(config),
2595
+ vignette: (config) => new Vignette(config),
2596
+ colorBalance: (config) => new ColorBalance(config),
2597
+ colorKey: (config) => new ColorKey(config),
2598
+ levels: (config) => new Levels(config),
2599
+ filmGrain: (config) => new FilmGrain(config),
2600
+ curves: (config) => new Curves(config),
2601
+ selectiveColor: (config) => new SelectiveColor(config),
2602
+ gradientMap: (config) => new GradientMap(config),
2603
+ shadowsHighlights: (config) => new ShadowsHighlights(config),
2604
+ applyLut: (config) => new ApplyLUT(config),
2605
+ unsharpMask: (config) => new UnsharpMask(config),
2606
+ highPass: (config) => new HighPass(config),
2607
+ halftoneScreen: (config) => new HalftoneScreen(config),
2608
+ tileOffset: (config) => new TileOffset(config),
2609
+ motionBlur: (config) => new MotionBlur(config),
2610
+ ssao: (config) => new SSAO(config),
2611
+ pbrGlass: (config) => new PBRGlass(config),
2612
+ depthOfField: (config) => new DepthOfField(config),
2613
+ crop: (config) => new Crop(config),
2614
+ vision: (config) => new Vision(config),
2615
+ relight3d: (config) => new Relight3D(config),
2616
+ modulate: (config) => new Modulate(config),
2617
+ deflicker: (config) => new TemporalDeflicker(config),
2618
+ custom: (op, config = {}) => new CustomEffect(op, config)
2619
+ });
2620
+
2621
+ //#endregion
2622
+ export { AETextAnimatorSchema, AdvancedTextAnimatorBuilder, AdvancedTextAnimatorSchema, AnchorGroupingSchema, AnchorPresetSchema, AnimatableGlyphPropsSchema, AnimationTypeSchema, AnyOutputUnionSchema, ApplyLUT, AudioExtractorSignalDataSchema, AudioLatentEngine, AudioLatentTrackCache, AudioMeshDeformPipeline, AudioSignal, AudioSignalExtractor, AudioSpectrumTypographySchema, BaseMediaOperationPropsSchema, BaseVideoLayerPropsSchema, Blur, BoxNodeSchema, CAPTION_LAYER_DEFAULTS, COCO17_BONES, COCO17_KEYPOINTS, COCO17_KEYPOINT_NAMES, COCO_CLASSES, COMPOSITE_OPERATIONS, COMPOSITOR_DEFAULTS, Camera3D, CameraAnimation, CameraNodeSchema, CannyComputePipeline, CarrierHandoffConfigSchema, ChromaticGlitchConfigSchema, ColorBalance, ColorKey, ColorStopSchema, Composition, CompositorProgramSchema, ConfigHandleSchema, ConfigSchemaRegistry, ControlNetMultiplexer, Crop, CubicBezierSegmentSchema, Curves, CustomEffect, DATA_TYPE_EXTENSIONS, DEFAULT_CHART_COLORS, DEFAULT_DURATION_MS, DEFAULT_FPS, DEFAULT_MEDIA_DIMENSION, DataType, DataTypeVal, DataTypes, DepthNormalsComputePipeline, DepthOfField, DynamicStrokePropertiesSchema, Easing, Effect, EffectPipeline, EnhancedTextNodeSchema, ExportResultSchema, ExpressionSelectorSchema, ExtendedGlyphPropertiesSchema, ExtendedLayerSchema, FileAssetSchema, FileDataSchema, FilmGrain, FlexNodeSchema, FontManager, GeneratorSignalDataSchema, GlassPipeline, GlobalCompositeOperation, GlyphAnchorGroupingSchema, GlyphAnchorPointSchema, GradientMap, HalftoneScreen, HandleTypeVal, HeadlessMediaRenderer, HeadlessWebGPURenderer, HighPass, JsonValueSchema, KineticMarqueeConfigSchema, LIGHT_UNIFORM_SIZE_BYTES, Layer, Layer3D, LayerAnimation, LayoutNodeSchema, Levels, Light, Light3D, LightNodeSchema, LightTypeSchema, LineSpacingDynamicsSchema, LongShadowConfigSchema, MAX_LIGHTS, MIME_TYPES, MaterialTypeSchema, Matrix4Math, Media, MediaMetadataSchema, MediaNodeSchema, MediaOperationSchema, MediaSourceSchema, Model3DNodeSchema, ModerationError, ModerationUnrefundableError, Modulate, MotionBlur, MotionBlurPipeline, MultiOutputGenericSchema, NodeMetadataSchema, NodeResultSchema, NodeVisualConfigSchema, OpticalFlowComputePipeline, OutputItemSchema, PBRGlass, ParticleDissolveConfigSchema, Path3D, PoseSkeletonRenderer, ProgrammaticSignal, Relight3D, Renderer2D, Renderer3D, SSAO, SSAOPipeline, Scene, SceneDefinitionSchema, SceneTransitionTypeSchema, SegmentationTexturePool, SelectiveColor, SelectorBasedOnSchema, SelectorModeSchema, SelectorShapeSchema, SelectorUnitsSchema, Sequence, ShadowPipeline, ShadowsHighlights, ShapeNodeSchema, Signal, SignalChannelMetaSchema, SignalDataSchema, SignalGateDataSchema, SignalMathDataSchema, SignalStatsSchema, SingleOutputGenericSchema, SkewPropertiesSchema, SlugFontCache, SlugPipeline, SourceOperationSchema, Spatial3DPropertiesSchema, SpatialLandmarkTransformer, SpringPhysicsSchema, TEXT_LAYER_DEFAULTS, TemporalDeflicker, TemporalDeflickerPipeline, TemporalObjectTracker, TensorPipeline, TextAnchorConfigSchema, TextAnimator, TextAnimatorBuilder, TextAnimatorSchema, TextCursorConfigSchema, TextCursorStyleSchema, TextNodeSchema, TextOperationSchema, TextPathBuilder, TextPathOptionsSchema, TextPathSourceSchema, TextRangeSelectorSchema, TextScrambleConfigSchema, TextSelectorSchema, TextSignalSelectorSchema, TextSpanMarkSchema, TextSpanSchema, TextWigglySelectorSchema, TileOffset, TimelineSegmentSchema, TimelineTransformSchema, TransitionSchema, TransitionTypeSchema, TypewriterAnimatorSchema, TypingCadenceSchema, UnsharpMask, VariableFontAxesSchema, Vec2Schema, Vector3Math, VideoAnimationSchema, VideoLayerTypeSchema, VideoSpatialPropsSchema, VideoStylePropsSchema, VideoTextPropsSchema, VideoTimingPropsSchema, Vignette, VirtualMediaDataSchema, Vision, VisionBundle, VisionNode, VisionRunner, VolumetricFormationConfigSchema, VolumetricFormationModeSchema, accent, analyzeSequence, appendOperation, applyStaggerToChildren, bezier, blurRegion, bold, buildPathLUT, calculateSequenceTimeline, checkNodeResultCache, code, collectNodeOps, color, compositorToProgram, computeAnchorPivotOffset, computeCarrierContinuity, computeGridLayout, computeLayout, computeLayoutSync, computeLineLeadingDisplacement, computeRangeSelectorWeight, computeStaggerDelay, computeStrokeRect, computeVideoCropRenderProps, computed, cosineSignal, createOutputItemSchema, createVirtualMedia, dataTypeColors, deserializeSignalData, deterministicWigglyNoise, distanceToCurveParameter, editTrackedRegion, ellipseToCubicBeziers, encodeStereoWav, ensureDevice, evaluateAnimationAtFrame, evaluateCubicBezier, evaluateCubicBezierDerivative, evaluateExpressionSelector, evaluateMarqueeOffset, evaluateSelectorCombination, evaluateSkewMatrix, evaluateSpringProgress, evaluateTrackAtFrame, evaluateTypewriterState, evaluateVolumetricFormation, extractSvgDimensions, findSourceAsset, formatQaReport, frameArraySignal, frameSignal, generateArcLengthLUT, generateId, generatePathSegments, getActiveMediaMetadata, getFileDataMetadata, getFingerprint, getLeafMediaType, getMediaType, getRenderFingerprint, getScramblePool, getShuffledOrder, hasOnlySingleSource, inputStore, interpolate, isEqual, isSignal, isVirtualMediaData, italic, loadFBX, loadModel3D, loadOBJ, lutStore, mapBlendModeToSkia, mark, measureSpring, measureText, measureTextAsync, mixAudioTracks, mixSfxInto, normalizeTextSpans, parseColorToRgb, parseFBX, parseMTL, parseMarkup, parseOBJ, parseSvgPathToCubicBeziers, pinNodeToLandmark, pinNodeToObject, preloadFont, programmaticSignal, progressSignal, registerSignalDependency, renderFrameGrid, renderSemaphore, renderSfx, reportRenderDiagnostic, requiresIsolation, resolveMediaMimeType, resolveSamplePoints, rich, sampleAudioSpectrumScale, sampleCurveGeometry, samplePathChainGeometry, section, serializeSignalData, shaderStore, signal, signalBuilder, signalRegistry, sineSignal, size, softLimit, span, spring, springCalculation, stampResult, startPreview, sub, sup, takeRenderDiagnostics, textureCache, timeSignal, updateClockSignals, waveToCubicBeziers };
2623
+ //# sourceMappingURL=index.mjs.map