framefields 2.11.0 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (540) hide show
  1. package/NOTICE.md +4 -0
  2. package/dist/audio/index.d.mts +6 -5
  3. package/dist/audio/index.mjs +13 -13
  4. package/dist/{audio-CYZkDwae.d.mts → audio-CHV33Od9.d.mts} +3 -4
  5. package/dist/audio-CHV33Od9.d.mts.map +1 -0
  6. package/dist/{audio-BuCVk1IQ.mjs → audio-DHzLQ_RG.mjs} +4 -4
  7. package/dist/{audio-BuCVk1IQ.mjs.map → audio-DHzLQ_RG.mjs.map} +1 -1
  8. package/dist/{audio-KHBadECb.mjs → audio-DS9Jg2ls.mjs} +1 -1
  9. package/dist/{audio-KHBadECb.mjs.map → audio-DS9Jg2ls.mjs.map} +1 -1
  10. package/dist/{check-result-Culfu7Nx.mjs → check-result-DZWx73V8.mjs} +1 -1
  11. package/dist/{check-result-Culfu7Nx.mjs.map → check-result-DZWx73V8.mjs.map} +1 -1
  12. package/dist/cli/check-worker.mjs +51 -51
  13. package/dist/cli/check-worker.mjs.map +1 -1
  14. package/dist/cli/local-worker.d.mts +28 -0
  15. package/dist/cli/local-worker.d.mts.map +1 -0
  16. package/dist/cli/local-worker.mjs +83 -0
  17. package/dist/cli/local-worker.mjs.map +1 -0
  18. package/dist/cli.mjs +390 -124
  19. package/dist/cli.mjs.map +1 -1
  20. package/dist/cloud/index.d.mts +16 -3
  21. package/dist/cloud/index.d.mts.map +1 -1
  22. package/dist/cloud/index.mjs +2 -2
  23. package/dist/cloud-Cj1TIme8.mjs +685 -0
  24. package/dist/cloud-Cj1TIme8.mjs.map +1 -0
  25. package/dist/components/index.d.mts +15 -14
  26. package/dist/components/index.mjs +47 -47
  27. package/dist/{dist-CySGkG54.mjs → dist-BSKAbyea.mjs} +2 -2
  28. package/dist/dist-BSKAbyea.mjs.map +1 -0
  29. package/dist/{dist-CNGv-JTX.mjs → dist-B_rSWeOz.mjs} +1 -1
  30. package/dist/{dist-Bf2_efYP.mjs → dist-C8XSqfTx.mjs} +1 -1
  31. package/dist/{dist-Bf2_efYP.mjs.map → dist-C8XSqfTx.mjs.map} +1 -1
  32. package/dist/{dist-EQX3TUUl.mjs → dist-CUNvNDS3.mjs} +129 -82
  33. package/dist/dist-CUNvNDS3.mjs.map +1 -0
  34. package/dist/dist-CiTgmfUw.mjs +502 -0
  35. package/dist/dist-CiTgmfUw.mjs.map +1 -0
  36. package/dist/{dist-CWLLnigL.mjs → dist-D3BeAZ7X.mjs} +315 -84
  37. package/dist/dist-D3BeAZ7X.mjs.map +1 -0
  38. package/dist/{dist-BIE8fvlv.mjs → dist-DgZpN6IK.mjs} +1 -1
  39. package/dist/{dist-BIE8fvlv.mjs.map → dist-DgZpN6IK.mjs.map} +1 -1
  40. package/dist/{dist-Dg9LMWoX.mjs → dist-Kbf-JTry.mjs} +2 -2
  41. package/dist/{dist-Dg9LMWoX.mjs.map → dist-Kbf-JTry.mjs.map} +1 -1
  42. package/dist/effects/index.d.mts +6 -6
  43. package/dist/effects/index.mjs +36 -36
  44. package/dist/{effects-DKLbLXF7.mjs → effects-BiDgCK1L.mjs} +3 -3
  45. package/dist/{effects-DKLbLXF7.mjs.map → effects-BiDgCK1L.mjs.map} +1 -1
  46. package/dist/fonts/index.d.mts +1 -1
  47. package/dist/fonts/index.mjs +3 -3
  48. package/dist/{fonts-gPbGbShD.mjs → fonts-DeDPWdvJ.mjs} +2 -2
  49. package/dist/{fonts-gPbGbShD.mjs.map → fonts-DeDPWdvJ.mjs.map} +1 -1
  50. package/dist/{gpu-CpkJJLQP.mjs → gpu-CWjgql4C.mjs} +11 -3
  51. package/dist/gpu-CWjgql4C.mjs.map +1 -0
  52. package/dist/index-BFTtXosj.d.mts +63 -0
  53. package/dist/index-BFTtXosj.d.mts.map +1 -0
  54. package/dist/{index-BW0Q1ygn.d.mts → index-C5sgRLlG.d.mts} +1 -1
  55. package/dist/{index-BW0Q1ygn.d.mts.map → index-C5sgRLlG.d.mts.map} +1 -1
  56. package/dist/{index-CdCrae-I.d.mts → index-CnZhBlob.d.mts} +2 -2
  57. package/dist/index-CnZhBlob.d.mts.map +1 -0
  58. package/dist/{index-D2i9J9Zq.d.mts → index-D68eGFNE.d.mts} +3 -30
  59. package/dist/index-D68eGFNE.d.mts.map +1 -0
  60. package/dist/{index-CEU_Zsb9.d.mts → index-DBh3WphX.d.mts} +25 -23
  61. package/dist/index-DBh3WphX.d.mts.map +1 -0
  62. package/dist/{index-gOVtTm-P.d.mts → index-DQ1U3HC3.d.mts} +14 -6
  63. package/dist/index-DQ1U3HC3.d.mts.map +1 -0
  64. package/dist/{index-jSDEM-uE.d.mts → index-Dibc_xpC.d.mts} +6 -6
  65. package/dist/{index-jSDEM-uE.d.mts.map → index-Dibc_xpC.d.mts.map} +1 -1
  66. package/dist/{index-Cro-818i.d.mts → index-E2IXX0Cz.d.mts} +88 -14
  67. package/dist/index-E2IXX0Cz.d.mts.map +1 -0
  68. package/dist/{index-BuiZzc6i.d.mts → index-X2u96TEo.d.mts} +162 -5
  69. package/dist/index-X2u96TEo.d.mts.map +1 -0
  70. package/dist/{index-Bly-7YM1.d.mts → index-YB9j9KUx.d.mts} +3 -3
  71. package/dist/{index-Bly-7YM1.d.mts.map → index-YB9j9KUx.d.mts.map} +1 -1
  72. package/dist/{index-COYNQ_mf.d.mts → index-a6JrbAK0.d.mts} +1 -1
  73. package/dist/{index-COYNQ_mf.d.mts.map → index-a6JrbAK0.d.mts.map} +1 -1
  74. package/dist/{index-C8YwZ6k1.d.mts → index-rtCXNxGO.d.mts} +2 -2
  75. package/dist/{index-C8YwZ6k1.d.mts.map → index-rtCXNxGO.d.mts.map} +1 -1
  76. package/dist/index.d.mts +16 -15
  77. package/dist/index.mjs +58 -58
  78. package/dist/preview/index.d.mts +5 -4
  79. package/dist/preview/index.mjs +12 -12
  80. package/dist/{preview-BToKUTtZ.mjs → preview-PDz7o2xg.mjs} +323 -35
  81. package/dist/preview-PDz7o2xg.mjs.map +1 -0
  82. package/dist/preview-engine/audio.mjs +1 -1
  83. package/dist/preview-engine/{chunk-QF4JWVO3.mjs → chunk-35XSD4QM.mjs} +15 -15
  84. package/dist/preview-engine/{chunk-ZF2MEFKO.mjs → chunk-3DOIE4DV.mjs} +1 -1
  85. package/dist/preview-engine/{chunk-JDB7PMRI.mjs → chunk-3IT7LHWR.mjs} +1 -1
  86. package/dist/preview-engine/{chunk-DNNGWS2C.mjs → chunk-3MLGWUSK.mjs} +1 -1
  87. package/dist/preview-engine/{chunk-KVOFO273.mjs → chunk-3QJ5GRBH.mjs} +1 -1
  88. package/dist/preview-engine/{chunk-54Q5CKSV.mjs → chunk-3QTHW2CD.mjs} +1 -1
  89. package/dist/preview-engine/chunk-44V4V5LD.mjs +1 -0
  90. package/dist/preview-engine/chunk-4P3MMJWD.mjs +1 -0
  91. package/dist/preview-engine/chunk-4YT5YJIF.mjs +1 -0
  92. package/dist/preview-engine/{chunk-BJXNKMSY.mjs → chunk-64L4GUOF.mjs} +20 -6
  93. package/dist/preview-engine/{chunk-UMJ3VGKN.mjs → chunk-6B3NOY5W.mjs} +1 -1
  94. package/dist/preview-engine/chunk-77MT33VR.mjs +1 -0
  95. package/dist/preview-engine/{chunk-BRV7TQDV.mjs → chunk-77WWW75O.mjs} +1 -1
  96. package/dist/preview-engine/chunk-7M5LE6EM.mjs +483 -0
  97. package/dist/preview-engine/chunk-A6OAPDIA.mjs +1 -0
  98. package/dist/preview-engine/chunk-ADLIF544.mjs +39 -0
  99. package/dist/preview-engine/{chunk-OLB4TQLQ.mjs → chunk-AKVRG7UU.mjs} +1 -1
  100. package/dist/preview-engine/{chunk-CIVEZJYF.mjs → chunk-CRBOK3JT.mjs} +1 -1
  101. package/dist/preview-engine/chunk-CSLSWUUT.mjs +1 -0
  102. package/dist/preview-engine/{chunk-ACBBBOUM.mjs → chunk-CYM75INB.mjs} +1 -1
  103. package/dist/preview-engine/{chunk-JSYG6OWZ.mjs → chunk-D7OMXGIZ.mjs} +1 -1
  104. package/dist/preview-engine/{chunk-EPRINA4V.mjs → chunk-E7BKWHOT.mjs} +10 -10
  105. package/dist/preview-engine/{chunk-NOKPBMIP.mjs → chunk-EWDJMJO5.mjs} +1 -1
  106. package/dist/preview-engine/{chunk-5KSBS3AL.mjs → chunk-EYE3GNL5.mjs} +1 -1
  107. package/dist/preview-engine/chunk-FRJPXWAG.mjs +1 -0
  108. package/dist/preview-engine/{chunk-IKVJ4MW5.mjs → chunk-G4ZTSLZU.mjs} +1 -1
  109. package/dist/preview-engine/{chunk-VZLIRYAL.mjs → chunk-GAMAKN5L.mjs} +1 -1
  110. package/dist/preview-engine/{chunk-ZIXPWP2B.mjs → chunk-ICWD36H6.mjs} +1 -1
  111. package/dist/preview-engine/{chunk-OELPPLML.mjs → chunk-IEEV5RB3.mjs} +1 -1
  112. package/dist/preview-engine/chunk-JAAFSVAG.mjs +1 -0
  113. package/dist/preview-engine/{chunk-YVZTRH4Y.mjs → chunk-KDCM7S3S.mjs} +1 -1
  114. package/dist/preview-engine/chunk-LZNHGH56.mjs +5 -0
  115. package/dist/preview-engine/{chunk-O63FLYWC.mjs → chunk-N2VISDTG.mjs} +1 -1
  116. package/dist/preview-engine/{chunk-GN3NDRLI.mjs → chunk-NCQHOGZK.mjs} +1 -1
  117. package/dist/preview-engine/{chunk-YKM7JDQY.mjs → chunk-NJO2BIJX.mjs} +1 -1
  118. package/dist/preview-engine/{chunk-7GMHSTRP.mjs → chunk-NTSALWFF.mjs} +1 -1
  119. package/dist/preview-engine/{chunk-PKNUTHPI.mjs → chunk-NVXFEDJS.mjs} +1 -1
  120. package/dist/preview-engine/{chunk-VFQH5KVS.mjs → chunk-ONHY4KNY.mjs} +1 -1
  121. package/dist/preview-engine/{chunk-Z24UEN4P.mjs → chunk-PD2HKW2S.mjs} +1 -1
  122. package/dist/preview-engine/chunk-PH3UUX6A.mjs +138 -0
  123. package/dist/preview-engine/chunk-PIHG6HJO.mjs +1 -0
  124. package/dist/preview-engine/{chunk-YHMBGJP6.mjs → chunk-QPT2Y2GZ.mjs} +1 -1
  125. package/dist/preview-engine/{chunk-4AGQN53P.mjs → chunk-QXLFTCLC.mjs} +1 -1
  126. package/dist/preview-engine/{chunk-65NANVQL.mjs → chunk-R4H52Q7S.mjs} +1 -1
  127. package/dist/preview-engine/{chunk-FQL4IJZN.mjs → chunk-RN7J5TRU.mjs} +1 -1
  128. package/dist/preview-engine/{chunk-26XWIHW3.mjs → chunk-RVCLMO5Q.mjs} +1 -1
  129. package/dist/preview-engine/{chunk-VQA4DYZU.mjs → chunk-RYSV44B4.mjs} +1 -1
  130. package/dist/preview-engine/{chunk-TEWRQKX3.mjs → chunk-SFHWP65D.mjs} +1 -1
  131. package/dist/preview-engine/{chunk-RDWLLITE.mjs → chunk-SMHEMYCV.mjs} +1 -1
  132. package/dist/preview-engine/{chunk-EXEO245X.mjs → chunk-SV3ZNZQU.mjs} +1 -1
  133. package/dist/preview-engine/{chunk-32WC4FRR.mjs → chunk-UE7Y65C3.mjs} +3 -3
  134. package/dist/preview-engine/chunk-UFPA36D2.mjs +2227 -0
  135. package/dist/preview-engine/{chunk-EAWJXW4J.mjs → chunk-UVEDFIPN.mjs} +1 -1
  136. package/dist/preview-engine/{chunk-6LTINEA4.mjs → chunk-VMXJZ4KQ.mjs} +1 -1
  137. package/dist/preview-engine/{chunk-IBPYV6HF.mjs → chunk-W4XR6F5G.mjs} +1 -1
  138. package/dist/preview-engine/{chunk-UI3VH33L.mjs → chunk-WPYWCWWL.mjs} +1 -1
  139. package/dist/preview-engine/{chunk-GHTG5XV6.mjs → chunk-XYCR3STG.mjs} +84 -25
  140. package/dist/preview-engine/{chunk-WFMUDL55.mjs → chunk-YAPGJZPI.mjs} +1 -1
  141. package/dist/preview-engine/{chunk-LMXMBX4J.mjs → chunk-YJ4DSRDY.mjs} +1 -1
  142. package/dist/preview-engine/{chunk-CCORQLMR.mjs → chunk-YOJKIMU5.mjs} +1 -1
  143. package/dist/preview-engine/{chunk-UGB6JKVS.mjs → chunk-ZHNEZZ6A.mjs} +1 -1
  144. package/dist/preview-engine/{chunk-LFNCWMKS.mjs → chunk-ZZMI3WOT.mjs} +1 -1
  145. package/dist/preview-engine/components.mjs +1 -1
  146. package/dist/preview-engine/effects.mjs +1 -1
  147. package/dist/preview-engine/fonts.mjs +1 -1
  148. package/dist/preview-engine/framefields.mjs +1 -1
  149. package/dist/preview-engine/player.mjs +5 -5
  150. package/dist/preview-engine/{renderers-53EI26GL.mjs → renderers-3FZVDYRQ.mjs} +1 -1
  151. package/dist/preview-engine/renderers-3KEBYOOF.mjs +1 -0
  152. package/dist/preview-engine/{renderers-6YVZUQOH.mjs → renderers-4RPQSUUZ.mjs} +1 -1
  153. package/dist/preview-engine/renderers-5EGFXFPF.mjs +1 -0
  154. package/dist/preview-engine/renderers-5SJHYUTM.mjs +1 -0
  155. package/dist/preview-engine/renderers-66MWDUN6.mjs +1 -0
  156. package/dist/preview-engine/{renderers-CCRZNGVK.mjs → renderers-6FENMFSC.mjs} +1 -1
  157. package/dist/preview-engine/renderers-77OXJ2GY.mjs +1 -0
  158. package/dist/preview-engine/renderers-7LI4QKHO.mjs +1 -0
  159. package/dist/preview-engine/renderers-AFTUFMQQ.mjs +1 -0
  160. package/dist/preview-engine/{renderers-CYJAVWHT.mjs → renderers-AIZRIW2R.mjs} +1 -1
  161. package/dist/preview-engine/{renderers-OGOW3NA4.mjs → renderers-BDI2BDBA.mjs} +1 -1
  162. package/dist/preview-engine/renderers-BDXCO6NR.mjs +1 -0
  163. package/dist/preview-engine/{renderers-EN7LXJLG.mjs → renderers-BUZ67FNZ.mjs} +1 -1
  164. package/dist/preview-engine/renderers-DMTGKURQ.mjs +1 -0
  165. package/dist/preview-engine/renderers-DU7KPFVV.mjs +1 -0
  166. package/dist/preview-engine/{renderers-WSABL3QO.mjs → renderers-ECXMT5BD.mjs} +1 -1
  167. package/dist/preview-engine/{renderers-MOEC2XZZ.mjs → renderers-EILFSWSJ.mjs} +1 -1
  168. package/dist/preview-engine/renderers-EPSF5CSQ.mjs +1 -0
  169. package/dist/preview-engine/{renderers-X6CORAES.mjs → renderers-EVEWFJ7U.mjs} +1 -1
  170. package/dist/preview-engine/renderers-F6PT2LON.mjs +1 -0
  171. package/dist/preview-engine/renderers-F7WPJXKT.mjs +1 -0
  172. package/dist/preview-engine/renderers-FIFF267S.mjs +1 -0
  173. package/dist/preview-engine/{renderers-GQM3KMV3.mjs → renderers-FQISHQEN.mjs} +1 -1
  174. package/dist/preview-engine/{renderers-HKLCB4U6.mjs → renderers-FXAVFNUN.mjs} +1 -1
  175. package/dist/preview-engine/{renderers-P2HORBZ6.mjs → renderers-GITAVRYZ.mjs} +1 -1
  176. package/dist/preview-engine/renderers-GTKRV225.mjs +1 -0
  177. package/dist/preview-engine/{renderers-KCGK33Y2.mjs → renderers-HG6JZIZO.mjs} +1 -1
  178. package/dist/preview-engine/{renderers-I6QKZ7CH.mjs → renderers-HHWMIDN3.mjs} +1 -1
  179. package/dist/preview-engine/renderers-HI3SRJVD.mjs +1 -0
  180. package/dist/preview-engine/{renderers-7CAHX35U.mjs → renderers-HXEDI4BD.mjs} +1 -1
  181. package/dist/preview-engine/{renderers-77PDUMYI.mjs → renderers-HXNSDJBY.mjs} +1 -1
  182. package/dist/preview-engine/{renderers-ACUJMDEK.mjs → renderers-I2ZOUFRU.mjs} +1 -1
  183. package/dist/preview-engine/renderers-JHFD4LHZ.mjs +1 -0
  184. package/dist/preview-engine/{renderers-IHGAWLUF.mjs → renderers-JMSAW7VY.mjs} +1 -1
  185. package/dist/preview-engine/renderers-KGVZUFHD.mjs +1 -0
  186. package/dist/preview-engine/{renderers-RN2MHIFK.mjs → renderers-KICDB5Y6.mjs} +1 -1
  187. package/dist/preview-engine/{renderers-C7SI3NIE.mjs → renderers-KKULMOV4.mjs} +1 -1
  188. package/dist/preview-engine/{renderers-HSFQIILN.mjs → renderers-KMVMPYY7.mjs} +1 -1
  189. package/dist/preview-engine/renderers-LN7WPG6I.mjs +1 -0
  190. package/dist/preview-engine/{renderers-BOBVXYAA.mjs → renderers-LWW4RF6D.mjs} +1 -1
  191. package/dist/preview-engine/renderers-LY57CZZB.mjs +1 -0
  192. package/dist/preview-engine/renderers-MBMJWZEW.mjs +1 -0
  193. package/dist/preview-engine/{renderers-VVP5WQOY.mjs → renderers-MPFU74I3.mjs} +1 -1
  194. package/dist/preview-engine/{renderers-H6PBHEYU.mjs → renderers-MW53LTMB.mjs} +1 -1
  195. package/dist/preview-engine/{renderers-PPZK6VEW.mjs → renderers-NQC4DPX4.mjs} +1 -1
  196. package/dist/preview-engine/renderers-OJWWIVNW.mjs +1 -0
  197. package/dist/preview-engine/{renderers-4IBFDW2S.mjs → renderers-PC2GOZDT.mjs} +1 -1
  198. package/dist/preview-engine/{renderers-UG2C3C7T.mjs → renderers-Q77UPEYE.mjs} +1 -1
  199. package/dist/preview-engine/renderers-QHXCFDHI.mjs +1 -0
  200. package/dist/preview-engine/renderers-RDYJRNAR.mjs +1 -0
  201. package/dist/preview-engine/renderers-RENLKAA7.mjs +1 -0
  202. package/dist/preview-engine/renderers-RHMRWX46.mjs +1 -0
  203. package/dist/preview-engine/{renderers-5XLGCEOA.mjs → renderers-RIPXT4AL.mjs} +1 -1
  204. package/dist/preview-engine/{renderers-FY2HOQCS.mjs → renderers-SFVFAS3C.mjs} +1 -1
  205. package/dist/preview-engine/{renderers-VIGZYJYX.mjs → renderers-SWQVCJHB.mjs} +1 -1
  206. package/dist/preview-engine/renderers-SZVDZDY7.mjs +1 -0
  207. package/dist/preview-engine/renderers-TTXTV4PC.mjs +228 -0
  208. package/dist/preview-engine/renderers-TYSLUZ53.mjs +1 -0
  209. package/dist/preview-engine/{renderers-6LNDAO4B.mjs → renderers-U4IXWMD6.mjs} +1 -1
  210. package/dist/preview-engine/renderers-VEHYARKY.mjs +1 -0
  211. package/dist/preview-engine/renderers-VRXAG3FR.mjs +1 -0
  212. package/dist/preview-engine/{renderers-33FCFHDR.mjs → renderers-VUQAZ56P.mjs} +1 -1
  213. package/dist/preview-engine/renderers-W5YFMLSB.mjs +1 -0
  214. package/dist/preview-engine/renderers-XKDWUK56.mjs +1 -0
  215. package/dist/preview-engine/renderers-XKSBNCLZ.mjs +1 -0
  216. package/dist/preview-engine/renderers-XLQXVD37.mjs +1 -0
  217. package/dist/preview-engine/renderers-ZHSOWEMQ.mjs +1 -0
  218. package/dist/preview-engine/renderers-ZMDRNYSS.mjs +1 -0
  219. package/dist/preview-engine/signals.mjs +1 -1
  220. package/dist/preview-engine/{src-4IUYUKIZ.mjs → src-YXNX4MLK.mjs} +1 -1
  221. package/dist/{program-Bc860ko5.mjs → program-Bn6ko_I4.mjs} +44 -17
  222. package/dist/program-Bn6ko_I4.mjs.map +1 -0
  223. package/dist/renderer/index.d.mts +4 -3
  224. package/dist/renderer/index.mjs +3 -3
  225. package/dist/{renderer-B3Dme2es.mjs → renderer--Q0pM9Vh.mjs} +5 -5
  226. package/dist/{renderer-B3Dme2es.mjs.map → renderer--Q0pM9Vh.mjs.map} +1 -1
  227. package/dist/renderer-1aSF5BmY.mjs +5 -0
  228. package/dist/{renderer-CAWnCsQc.mjs → renderer-45ifiDkn.mjs} +5 -5
  229. package/dist/{renderer-CAWnCsQc.mjs.map → renderer-45ifiDkn.mjs.map} +1 -1
  230. package/dist/{renderer-Cz-n883J.mjs → renderer-549d94qG.mjs} +5 -5
  231. package/dist/{renderer-Cz-n883J.mjs.map → renderer-549d94qG.mjs.map} +1 -1
  232. package/dist/{renderer-BhsrlGKp.mjs → renderer-B-LUGB9h.mjs} +74 -21
  233. package/dist/renderer-B-LUGB9h.mjs.map +1 -0
  234. package/dist/renderer-B2e4Gr9u.mjs +5 -0
  235. package/dist/{renderer-B1LD29TV.mjs → renderer-B5b-ehRb.mjs} +3 -3
  236. package/dist/{renderer-B1LD29TV.mjs.map → renderer-B5b-ehRb.mjs.map} +1 -1
  237. package/dist/renderer-B6fz4j50.mjs +5 -0
  238. package/dist/{renderer-_9gbYS-3.mjs → renderer-BCTUqJG7.mjs} +5 -5
  239. package/dist/{renderer-_9gbYS-3.mjs.map → renderer-BCTUqJG7.mjs.map} +1 -1
  240. package/dist/renderer-BEftIYw-.mjs +5 -0
  241. package/dist/{renderer-C9BSXyrq.mjs → renderer-BHPgkoEL.mjs} +4 -4
  242. package/dist/{renderer-C9BSXyrq.mjs.map → renderer-BHPgkoEL.mjs.map} +1 -1
  243. package/dist/renderer-BHTnO-7e.mjs +5 -0
  244. package/dist/{renderer-fs8f1QeE.mjs → renderer-BIieU9pY.mjs} +5 -5
  245. package/dist/{renderer-fs8f1QeE.mjs.map → renderer-BIieU9pY.mjs.map} +1 -1
  246. package/dist/{renderer-DwK9jsER.mjs → renderer-BKi6jDi_.mjs} +4 -4
  247. package/dist/{renderer-DwK9jsER.mjs.map → renderer-BKi6jDi_.mjs.map} +1 -1
  248. package/dist/renderer-BMlnQqTO.mjs +5 -0
  249. package/dist/{renderer-BNJ6Jk7-.mjs → renderer-BMpmmYOq.mjs} +4 -4
  250. package/dist/{renderer-BNJ6Jk7-.mjs.map → renderer-BMpmmYOq.mjs.map} +1 -1
  251. package/dist/{renderer-DkqZmfm8.mjs → renderer-BO_wuUKA.mjs} +5 -5
  252. package/dist/{renderer-DkqZmfm8.mjs.map → renderer-BO_wuUKA.mjs.map} +1 -1
  253. package/dist/renderer-BOzcFezY.mjs +5 -0
  254. package/dist/{renderer-Bxjb0HYU.mjs → renderer-BPOh9x5X.mjs} +4 -4
  255. package/dist/{renderer-Bxjb0HYU.mjs.map → renderer-BPOh9x5X.mjs.map} +1 -1
  256. package/dist/{renderer-Ros7XQg2.mjs → renderer-BPiWsrC2.mjs} +3 -3
  257. package/dist/{renderer-Ros7XQg2.mjs.map → renderer-BPiWsrC2.mjs.map} +1 -1
  258. package/dist/{renderer-lHNTgiOM.mjs → renderer-BUj7jE6t.mjs} +3 -3
  259. package/dist/{renderer-lHNTgiOM.mjs.map → renderer-BUj7jE6t.mjs.map} +1 -1
  260. package/dist/renderer-BVbjJIKJ.mjs +5 -0
  261. package/dist/renderer-BXsHKf4k.mjs +5 -0
  262. package/dist/{renderer-D0aAZHC7.mjs → renderer-BZgJj8Cl.mjs} +4 -4
  263. package/dist/{renderer-D0aAZHC7.mjs.map → renderer-BZgJj8Cl.mjs.map} +1 -1
  264. package/dist/{renderer-V4dhrf_h.mjs → renderer-BgjPbgbn.mjs} +6 -6
  265. package/dist/{renderer-V4dhrf_h.mjs.map → renderer-BgjPbgbn.mjs.map} +1 -1
  266. package/dist/{renderer-BaIJIfJ6.mjs → renderer-BjgFpwVK.mjs} +5 -5
  267. package/dist/{renderer-BaIJIfJ6.mjs.map → renderer-BjgFpwVK.mjs.map} +1 -1
  268. package/dist/renderer-Bks49NVl.mjs +5 -0
  269. package/dist/{renderer-CU8v-LxD.mjs → renderer-BlZgyBSo.mjs} +5 -5
  270. package/dist/{renderer-CU8v-LxD.mjs.map → renderer-BlZgyBSo.mjs.map} +1 -1
  271. package/dist/{renderer-B6Oeahe_.mjs → renderer-BqUAyzCZ.mjs} +5 -5
  272. package/dist/{renderer-B6Oeahe_.mjs.map → renderer-BqUAyzCZ.mjs.map} +1 -1
  273. package/dist/{renderer-h62QaJYz.mjs → renderer-Br8km655.mjs} +4 -4
  274. package/dist/{renderer-h62QaJYz.mjs.map → renderer-Br8km655.mjs.map} +1 -1
  275. package/dist/{renderer-sfqZK6L5.mjs → renderer-BsMZ5Iaq.mjs} +4 -4
  276. package/dist/{renderer-sfqZK6L5.mjs.map → renderer-BsMZ5Iaq.mjs.map} +1 -1
  277. package/dist/{renderer-g_1t2je9.mjs → renderer-BtgqTg2K.mjs} +3 -3
  278. package/dist/{renderer-DcvjSolU.mjs → renderer-BuvKGwk3.mjs} +11 -2
  279. package/dist/{renderer-DcvjSolU.mjs.map → renderer-BuvKGwk3.mjs.map} +1 -1
  280. package/dist/{renderer-BOrMBwQS.mjs → renderer-C-3qhk5x.mjs} +2 -2
  281. package/dist/{renderer-BOrMBwQS.mjs.map → renderer-C-3qhk5x.mjs.map} +1 -1
  282. package/dist/{renderer-CLAvn9c6.mjs → renderer-C-GTxnfv.mjs} +4 -4
  283. package/dist/{renderer-CLAvn9c6.mjs.map → renderer-C-GTxnfv.mjs.map} +1 -1
  284. package/dist/renderer-C-t7qFKr.mjs +5 -0
  285. package/dist/{renderer-BDZC3o3N.mjs → renderer-C1ctHdXl.mjs} +4 -4
  286. package/dist/{renderer-BDZC3o3N.mjs.map → renderer-C1ctHdXl.mjs.map} +1 -1
  287. package/dist/renderer-C24n-6CX.mjs +6 -0
  288. package/dist/{renderer-pNmI-A9o.mjs → renderer-C7m7Yxgc.mjs} +5 -5
  289. package/dist/{renderer-pNmI-A9o.mjs.map → renderer-C7m7Yxgc.mjs.map} +1 -1
  290. package/dist/{renderer-Bf4-N7k7.mjs → renderer-C9dqx3U7.mjs} +5 -5
  291. package/dist/{renderer-Bf4-N7k7.mjs.map → renderer-C9dqx3U7.mjs.map} +1 -1
  292. package/dist/renderer-CCReX-7M.mjs +5 -0
  293. package/dist/{renderer-JHByuUNb.mjs → renderer-CE4535aW.mjs} +3 -3
  294. package/dist/{renderer-JHByuUNb.mjs.map → renderer-CE4535aW.mjs.map} +1 -1
  295. package/dist/renderer-CIxFQrAm.mjs +5 -0
  296. package/dist/{renderer-ByjaseAo.mjs → renderer-CL-vyXgX.mjs} +5 -5
  297. package/dist/{renderer-ByjaseAo.mjs.map → renderer-CL-vyXgX.mjs.map} +1 -1
  298. package/dist/renderer-CLHBMIqJ.mjs +5 -0
  299. package/dist/renderer-CMJKi-Ye.mjs +5 -0
  300. package/dist/{renderer-B-CMRUag.mjs → renderer-CMnlgAGs.mjs} +4 -4
  301. package/dist/{renderer-B-CMRUag.mjs.map → renderer-CMnlgAGs.mjs.map} +1 -1
  302. package/dist/{renderer-BNHcwxw9.mjs → renderer-CQFMyC_c.mjs} +4 -4
  303. package/dist/{renderer-BNHcwxw9.mjs.map → renderer-CQFMyC_c.mjs.map} +1 -1
  304. package/dist/{renderer-DgPn_SOC.mjs → renderer-CYwVNbUh.mjs} +4 -4
  305. package/dist/{renderer-DgPn_SOC.mjs.map → renderer-CYwVNbUh.mjs.map} +1 -1
  306. package/dist/{renderer-DLPhfwbR.mjs → renderer-CZ5mwBW1.mjs} +3 -3
  307. package/dist/{renderer-DLPhfwbR.mjs.map → renderer-CZ5mwBW1.mjs.map} +1 -1
  308. package/dist/{renderer-4ZUv3X1I.mjs → renderer-C_1eqfI0.mjs} +5 -5
  309. package/dist/{renderer-4ZUv3X1I.mjs.map → renderer-C_1eqfI0.mjs.map} +1 -1
  310. package/dist/renderer-C_H3mHZa.mjs +5 -0
  311. package/dist/{renderer-B1esRxGy.mjs → renderer-CciiDHuU.mjs} +4 -4
  312. package/dist/{renderer-B1esRxGy.mjs.map → renderer-CciiDHuU.mjs.map} +1 -1
  313. package/dist/renderer-CfkTdR5B.mjs +5 -0
  314. package/dist/{renderer-ynFRJh7G.mjs → renderer-CgK7Q1G8.mjs} +3 -3
  315. package/dist/{renderer-CR0mDPYY.mjs → renderer-CnL8Cmmr.mjs} +3 -3
  316. package/dist/renderer-CnhkXJ0R.mjs +5 -0
  317. package/dist/{renderer-fwKnV9zs.mjs → renderer-Cp_HOmp7.mjs} +5 -5
  318. package/dist/{renderer-fwKnV9zs.mjs.map → renderer-Cp_HOmp7.mjs.map} +1 -1
  319. package/dist/renderer-CqpyVsq_.mjs +5 -0
  320. package/dist/renderer-CtWgIpTE.mjs +5 -0
  321. package/dist/{renderer-riIFosX6.mjs → renderer-Cu3iKMSJ.mjs} +5 -5
  322. package/dist/{renderer-riIFosX6.mjs.map → renderer-Cu3iKMSJ.mjs.map} +1 -1
  323. package/dist/{renderer-D4f8f66C.mjs → renderer-CuPAQjDK.mjs} +4 -4
  324. package/dist/{renderer-D4f8f66C.mjs.map → renderer-CuPAQjDK.mjs.map} +1 -1
  325. package/dist/{renderer-CxGx1Lhi.mjs → renderer-CwlY8Tb-.mjs} +3 -3
  326. package/dist/{renderer-CxGx1Lhi.mjs.map → renderer-CwlY8Tb-.mjs.map} +1 -1
  327. package/dist/{renderer-o68mVeyk.mjs → renderer-CxSFvKd1.mjs} +4 -4
  328. package/dist/{renderer-o68mVeyk.mjs.map → renderer-CxSFvKd1.mjs.map} +1 -1
  329. package/dist/{renderer-CrR8Mpxq.mjs → renderer-CyUiXLRa.mjs} +5 -5
  330. package/dist/{renderer-CrR8Mpxq.mjs.map → renderer-CyUiXLRa.mjs.map} +1 -1
  331. package/dist/renderer-CyuKr5ca.mjs +5 -0
  332. package/dist/renderer-CzgcZXKH.mjs +3 -0
  333. package/dist/{renderer-Bx14Wnxl.mjs → renderer-D-GWBoVT.mjs} +58 -4
  334. package/dist/renderer-D-GWBoVT.mjs.map +1 -0
  335. package/dist/{renderer-BwrfKKqw.mjs → renderer-D-fzEZfX.mjs} +4 -4
  336. package/dist/{renderer-BwrfKKqw.mjs.map → renderer-D-fzEZfX.mjs.map} +1 -1
  337. package/dist/renderer-D5yp74NL.mjs +3 -0
  338. package/dist/{renderer-DAn9xiQT.mjs → renderer-D8gN7aqk.mjs} +4 -4
  339. package/dist/{renderer-DAn9xiQT.mjs.map → renderer-D8gN7aqk.mjs.map} +1 -1
  340. package/dist/renderer-D9ON_1Hf.mjs +5 -0
  341. package/dist/renderer-DAnTgh4o.mjs +5 -0
  342. package/dist/{renderer-Dpl6poqD.mjs → renderer-DGOMfyh8.mjs} +2 -2
  343. package/dist/{renderer-Dpl6poqD.mjs.map → renderer-DGOMfyh8.mjs.map} +1 -1
  344. package/dist/{renderer-Rw87u1Cr.mjs → renderer-DGb_wgTW.mjs} +6 -6
  345. package/dist/{renderer-Rw87u1Cr.mjs.map → renderer-DGb_wgTW.mjs.map} +1 -1
  346. package/dist/{renderer-Co6UFbZB.mjs → renderer-DJPZs_zV.mjs} +5 -5
  347. package/dist/{renderer-Co6UFbZB.mjs.map → renderer-DJPZs_zV.mjs.map} +1 -1
  348. package/dist/renderer-DKJOon6y.d.mts +1 -0
  349. package/dist/{renderer-DOkbn1ot.mjs → renderer-DOZPZTxe.mjs} +5 -5
  350. package/dist/{renderer-DOkbn1ot.mjs.map → renderer-DOZPZTxe.mjs.map} +1 -1
  351. package/dist/{renderer-DaXQgGg3.mjs → renderer-DRal7Goa.mjs} +5 -5
  352. package/dist/{renderer-DaXQgGg3.mjs.map → renderer-DRal7Goa.mjs.map} +1 -1
  353. package/dist/renderer-DWgpivA3.mjs +5 -0
  354. package/dist/{renderer-Bo7shNdU.mjs → renderer-DXFJv_e6.mjs} +4 -4
  355. package/dist/{renderer-Bo7shNdU.mjs.map → renderer-DXFJv_e6.mjs.map} +1 -1
  356. package/dist/renderer-Dh_qNNwR.mjs +5 -0
  357. package/dist/renderer-DkCpXPMP.mjs +5 -0
  358. package/dist/{renderer-eMCTAa9e.mjs → renderer-Dp5ChuOs.mjs} +4 -4
  359. package/dist/{renderer-eMCTAa9e.mjs.map → renderer-Dp5ChuOs.mjs.map} +1 -1
  360. package/dist/{renderer-1uoKiILq.mjs → renderer-DpZballM.mjs} +3 -3
  361. package/dist/{renderer-1uoKiILq.mjs.map → renderer-DpZballM.mjs.map} +1 -1
  362. package/dist/renderer-Dre-6cDR.mjs +5 -0
  363. package/dist/renderer-Ds5z4_HX.mjs +5 -0
  364. package/dist/{renderer-7ow5Acsg.mjs → renderer-DwGlDNOV.mjs} +3 -3
  365. package/dist/{renderer-7ow5Acsg.mjs.map → renderer-DwGlDNOV.mjs.map} +1 -1
  366. package/dist/{renderer-q7q6k_cD.mjs → renderer-DxB_OfLs.mjs} +4 -4
  367. package/dist/{renderer-q7q6k_cD.mjs.map → renderer-DxB_OfLs.mjs.map} +1 -1
  368. package/dist/{renderer-DFJWPqOJ.mjs → renderer-Dz6P-rPI.mjs} +3 -3
  369. package/dist/{renderer-DFJWPqOJ.mjs.map → renderer-Dz6P-rPI.mjs.map} +1 -1
  370. package/dist/{renderer-BURhYcpA.mjs → renderer-FPiLBwj5.mjs} +4 -4
  371. package/dist/{renderer-BURhYcpA.mjs.map → renderer-FPiLBwj5.mjs.map} +1 -1
  372. package/dist/renderer-HGSCOMyP.mjs +5 -0
  373. package/dist/renderer-KMY8W-cJ.mjs +5 -0
  374. package/dist/{renderer-D-QVGphn.mjs → renderer-KgsVk9c6.mjs} +4 -4
  375. package/dist/{renderer-D-QVGphn.mjs.map → renderer-KgsVk9c6.mjs.map} +1 -1
  376. package/dist/{renderer-COcKhouz.mjs → renderer-LXhEPCmy.mjs} +5 -5
  377. package/dist/{renderer-COcKhouz.mjs.map → renderer-LXhEPCmy.mjs.map} +1 -1
  378. package/dist/{renderer-HDj9Zb-O.mjs → renderer-NBMmvqWl.mjs} +20 -7
  379. package/dist/renderer-NBMmvqWl.mjs.map +1 -0
  380. package/dist/{renderer-DE9Jik9K.mjs → renderer-Nnu32rqg.mjs} +3 -3
  381. package/dist/{renderer-DE9Jik9K.mjs.map → renderer-Nnu32rqg.mjs.map} +1 -1
  382. package/dist/renderer-R21YvXz3.mjs +5 -0
  383. package/dist/{renderer-celhuAL7.mjs → renderer-RAq3LnNy.mjs} +3 -3
  384. package/dist/{renderer-celhuAL7.mjs.map → renderer-RAq3LnNy.mjs.map} +1 -1
  385. package/dist/renderer-RtzCz37W.mjs +5 -0
  386. package/dist/{renderer-50JEMaVo.mjs → renderer-RzkU_O1i.mjs} +5 -5
  387. package/dist/{renderer-50JEMaVo.mjs.map → renderer-RzkU_O1i.mjs.map} +1 -1
  388. package/dist/{renderer-Bbxh4N8Y.mjs → renderer-S9tVGneU.mjs} +95 -80
  389. package/dist/renderer-S9tVGneU.mjs.map +1 -0
  390. package/dist/{renderer-BSELd5vU.mjs → renderer-SJyp9-62.mjs} +3 -3
  391. package/dist/{renderer-BSELd5vU.mjs.map → renderer-SJyp9-62.mjs.map} +1 -1
  392. package/dist/{renderer-jnAIhWn_.mjs → renderer-_54hiCq0.mjs} +5 -5
  393. package/dist/{renderer-jnAIhWn_.mjs.map → renderer-_54hiCq0.mjs.map} +1 -1
  394. package/dist/{renderer-88C3QpKL.d.mts → renderer-aRk849b3.d.mts} +2 -2
  395. package/dist/{renderer-88C3QpKL.d.mts.map → renderer-aRk849b3.d.mts.map} +1 -1
  396. package/dist/{renderer-BQetXCcZ.mjs → renderer-dGEMVaZ3.mjs} +4 -4
  397. package/dist/{renderer-BQetXCcZ.mjs.map → renderer-dGEMVaZ3.mjs.map} +1 -1
  398. package/dist/{renderer-RvI3qRUI.mjs → renderer-dRXP2dJU.mjs} +5 -5
  399. package/dist/{renderer-RvI3qRUI.mjs.map → renderer-dRXP2dJU.mjs.map} +1 -1
  400. package/dist/{renderer-D06HxSXO.mjs → renderer-g9SstkTz.mjs} +3 -3
  401. package/dist/renderer-iMrqAjix.mjs +5 -0
  402. package/dist/{renderer-BJ-7WRgO.mjs → renderer-opVuiAQR.mjs} +3 -3
  403. package/dist/{renderer-BJ-7WRgO.mjs.map → renderer-opVuiAQR.mjs.map} +1 -1
  404. package/dist/{renderer-KKk7myX1.mjs → renderer-puQhVfDS.mjs} +5 -5
  405. package/dist/{renderer-KKk7myX1.mjs.map → renderer-puQhVfDS.mjs.map} +1 -1
  406. package/dist/renderer-sMed1u1O.mjs +5 -0
  407. package/dist/renderer-tsAuo46l.mjs +5 -0
  408. package/dist/{renderer-TKZCA0B9.mjs → renderer-vll8LX0I.mjs} +211 -72
  409. package/dist/renderer-vll8LX0I.mjs.map +1 -0
  410. package/dist/{renderers-CP8CFWDs-DRoslK4F.mjs → renderers-CP8CFWDs-BRQyvcut.mjs} +4 -4
  411. package/dist/{renderers-CP8CFWDs-DRoslK4F.mjs.map → renderers-CP8CFWDs-BRQyvcut.mjs.map} +1 -1
  412. package/dist/sam/index.d.mts +3 -3
  413. package/dist/sam/index.mjs +1 -1
  414. package/dist/signals/index.d.mts +7 -7
  415. package/dist/signals/index.mjs +8 -8
  416. package/dist/{signals-BfJ1aqpT.mjs → signals-tiho_9fp.mjs} +4 -4
  417. package/dist/{signals-BfJ1aqpT.mjs.map → signals-tiho_9fp.mjs.map} +1 -1
  418. package/dist/{src-Bnr8DUC--BRDqRF6I.mjs → src-BU6vm9sP-DdTHmCr4.mjs} +76 -11
  419. package/dist/src-BU6vm9sP-DdTHmCr4.mjs.map +1 -0
  420. package/dist/{src-BYp6r-cS.mjs → src-BzFGotRc.mjs} +250 -30
  421. package/dist/src-BzFGotRc.mjs.map +1 -0
  422. package/dist/storage/index.d.mts +206 -0
  423. package/dist/storage/index.d.mts.map +1 -0
  424. package/dist/storage/index.mjs +3 -0
  425. package/package.json +67 -59
  426. package/dist/audio-CYZkDwae.d.mts.map +0 -1
  427. package/dist/cloud-xcfV4J03.mjs +0 -233
  428. package/dist/cloud-xcfV4J03.mjs.map +0 -1
  429. package/dist/dist-CWLLnigL.mjs.map +0 -1
  430. package/dist/dist-CySGkG54.mjs.map +0 -1
  431. package/dist/dist-EQX3TUUl.mjs.map +0 -1
  432. package/dist/gpu-CpkJJLQP.mjs.map +0 -1
  433. package/dist/index-BuiZzc6i.d.mts.map +0 -1
  434. package/dist/index-CEU_Zsb9.d.mts.map +0 -1
  435. package/dist/index-CdCrae-I.d.mts.map +0 -1
  436. package/dist/index-Cro-818i.d.mts.map +0 -1
  437. package/dist/index-D2i9J9Zq.d.mts.map +0 -1
  438. package/dist/index-gOVtTm-P.d.mts.map +0 -1
  439. package/dist/preview-BToKUTtZ.mjs.map +0 -1
  440. package/dist/preview-engine/chunk-4FY4TNST.mjs +0 -1
  441. package/dist/preview-engine/chunk-7LDSMOO3.mjs +0 -1
  442. package/dist/preview-engine/chunk-AGAZJZWI.mjs +0 -1
  443. package/dist/preview-engine/chunk-BXPM5SJ3.mjs +0 -1
  444. package/dist/preview-engine/chunk-C4M3B2Q2.mjs +0 -1
  445. package/dist/preview-engine/chunk-CIVJXFWH.mjs +0 -4
  446. package/dist/preview-engine/chunk-D73ZKPFN.mjs +0 -138
  447. package/dist/preview-engine/chunk-KOVN277Z.mjs +0 -1
  448. package/dist/preview-engine/chunk-M4QANUJI.mjs +0 -480
  449. package/dist/preview-engine/chunk-P4Y3PMJF.mjs +0 -1
  450. package/dist/preview-engine/chunk-SE2C623Z.mjs +0 -5
  451. package/dist/preview-engine/chunk-XF6DYP6B.mjs +0 -1974
  452. package/dist/preview-engine/chunk-XYGDTPO7.mjs +0 -39
  453. package/dist/preview-engine/chunk-YGKO4NIU.mjs +0 -1
  454. package/dist/preview-engine/renderers-2NGIILMI.mjs +0 -1
  455. package/dist/preview-engine/renderers-466Z77BH.mjs +0 -1
  456. package/dist/preview-engine/renderers-4KRENGZA.mjs +0 -1
  457. package/dist/preview-engine/renderers-4W52BQEU.mjs +0 -1
  458. package/dist/preview-engine/renderers-55PRAS7G.mjs +0 -1
  459. package/dist/preview-engine/renderers-5LLYINHW.mjs +0 -1
  460. package/dist/preview-engine/renderers-63N3Y2XO.mjs +0 -1
  461. package/dist/preview-engine/renderers-6ROVFDIN.mjs +0 -1
  462. package/dist/preview-engine/renderers-A4RVLPMG.mjs +0 -1
  463. package/dist/preview-engine/renderers-A53P4J6O.mjs +0 -1
  464. package/dist/preview-engine/renderers-AFJ3373L.mjs +0 -1
  465. package/dist/preview-engine/renderers-ATFWTA3U.mjs +0 -1
  466. package/dist/preview-engine/renderers-BPYJXHBU.mjs +0 -1
  467. package/dist/preview-engine/renderers-D3ZF7FXT.mjs +0 -1
  468. package/dist/preview-engine/renderers-D7YN6B4B.mjs +0 -1
  469. package/dist/preview-engine/renderers-DBLASKF5.mjs +0 -1
  470. package/dist/preview-engine/renderers-DC5ZYYHM.mjs +0 -1
  471. package/dist/preview-engine/renderers-J6ZEXW5L.mjs +0 -1
  472. package/dist/preview-engine/renderers-JV4MF46Q.mjs +0 -1
  473. package/dist/preview-engine/renderers-KQKH4ZIX.mjs +0 -1
  474. package/dist/preview-engine/renderers-MDHPQY6D.mjs +0 -1
  475. package/dist/preview-engine/renderers-MEITHN4N.mjs +0 -1
  476. package/dist/preview-engine/renderers-MN3HSBTJ.mjs +0 -1
  477. package/dist/preview-engine/renderers-NTG3QGNH.mjs +0 -1
  478. package/dist/preview-engine/renderers-OU4SFMB2.mjs +0 -1
  479. package/dist/preview-engine/renderers-P6TIBJIG.mjs +0 -1
  480. package/dist/preview-engine/renderers-POJWQ7L3.mjs +0 -1
  481. package/dist/preview-engine/renderers-RJ7S6VHD.mjs +0 -1
  482. package/dist/preview-engine/renderers-RJJAJZYN.mjs +0 -1
  483. package/dist/preview-engine/renderers-UEQ733VK.mjs +0 -1
  484. package/dist/preview-engine/renderers-ULO2AW2U.mjs +0 -1
  485. package/dist/preview-engine/renderers-UPVHGHCK.mjs +0 -1
  486. package/dist/preview-engine/renderers-UZHSNNIM.mjs +0 -1
  487. package/dist/preview-engine/renderers-V5KWZL2C.mjs +0 -1
  488. package/dist/preview-engine/renderers-WL372W36.mjs +0 -228
  489. package/dist/preview-engine/renderers-YMXKYOHQ.mjs +0 -1
  490. package/dist/preview-engine/renderers-YWDAZ2NZ.mjs +0 -1
  491. package/dist/program-Bc860ko5.mjs.map +0 -1
  492. package/dist/renderer--Ymc_4XJ.mjs +0 -5
  493. package/dist/renderer-B-OdV-eq.mjs +0 -5
  494. package/dist/renderer-B65fwoA2.mjs +0 -5
  495. package/dist/renderer-B92Ahkcv.mjs +0 -5
  496. package/dist/renderer-B9z2AK31.mjs +0 -5
  497. package/dist/renderer-BIF3Dg3Z.mjs +0 -5
  498. package/dist/renderer-BJUVaIAT.mjs +0 -5
  499. package/dist/renderer-BKRDMbI-.mjs +0 -5
  500. package/dist/renderer-BSwhyVWa.mjs +0 -5
  501. package/dist/renderer-BUqSZn2X.mjs +0 -5
  502. package/dist/renderer-BVKOQarx.d.mts +0 -99
  503. package/dist/renderer-BVKOQarx.d.mts.map +0 -1
  504. package/dist/renderer-BbmvjqK9.mjs +0 -3
  505. package/dist/renderer-Bbxh4N8Y.mjs.map +0 -1
  506. package/dist/renderer-BhsrlGKp.mjs.map +0 -1
  507. package/dist/renderer-Bpe4k_x6.mjs +0 -5
  508. package/dist/renderer-Bx14Wnxl.mjs.map +0 -1
  509. package/dist/renderer-C1NjG0CJ.mjs +0 -5
  510. package/dist/renderer-C7Puyst9.mjs +0 -5
  511. package/dist/renderer-CGA_7320.mjs +0 -5
  512. package/dist/renderer-CLnFkXO7.mjs +0 -5
  513. package/dist/renderer-CMQIT1Kh.mjs +0 -5
  514. package/dist/renderer-CQ1rwjIh.mjs +0 -5
  515. package/dist/renderer-CT8h0boY.mjs +0 -5
  516. package/dist/renderer-Cb0lszt3.mjs +0 -5
  517. package/dist/renderer-Ci7oLye9.mjs +0 -5
  518. package/dist/renderer-CjqXB3CZ.mjs +0 -5
  519. package/dist/renderer-CqTV04zQ.mjs +0 -5
  520. package/dist/renderer-CtWeRtHK.mjs +0 -5
  521. package/dist/renderer-CzolnwCo.mjs +0 -5
  522. package/dist/renderer-D6qhcx_C.mjs +0 -5
  523. package/dist/renderer-DDfEf0jt.mjs +0 -5
  524. package/dist/renderer-DDpa8ztp.mjs +0 -5
  525. package/dist/renderer-DbQBqzmx.mjs +0 -5
  526. package/dist/renderer-DfUcwMKa.mjs +0 -5
  527. package/dist/renderer-DgIjNANM.mjs +0 -6
  528. package/dist/renderer-Dsh6Tgu0.mjs +0 -3
  529. package/dist/renderer-DuIwR9GT.mjs +0 -5
  530. package/dist/renderer-Dv4u2c14.mjs +0 -5
  531. package/dist/renderer-HDj9Zb-O.mjs.map +0 -1
  532. package/dist/renderer-IE1yu3lZ.mjs +0 -5
  533. package/dist/renderer-PY_wnEN0.mjs +0 -5
  534. package/dist/renderer-TKZCA0B9.mjs.map +0 -1
  535. package/dist/renderer-gv24VyzO.mjs +0 -5
  536. package/dist/renderer-nN6lPZf9.mjs +0 -5
  537. package/dist/src-BYp6r-cS.mjs.map +0 -1
  538. package/dist/src-Bnr8DUC--BRDqRF6I.mjs.map +0 -1
  539. /package/dist/{chunk-W71TSjRM.mjs → chunk-DOL2i2sR.mjs} +0 -0
  540. /package/dist/{renderer-B6rZUBwE.mjs → renderer-Co2YqWX0.mjs} +0 -0
package/NOTICE.md CHANGED
@@ -12,3 +12,7 @@ framefields is licensed under Apache-2.0. It contains no model weights: every vi
12
12
  | SAM 3 (ONNX exports of Meta's SAM 3 checkpoints) | Meta SAM License | required at runtime |
13
13
 
14
14
  Before SAM 3 weights are downloaded or run, you must accept Meta's SAM License (https://github.com/facebookresearch/sam3/blob/main/LICENSE): pass `acceptSamLicense: true` in `comp.vision` options (or `acceptLicense: true` to `Sam3Tracker`), or set `FRAMEFIELDS_ACCEPT_SAM_LICENSE=1`. Your use of SAM 3 is then governed by that license.
15
+
16
+ ## Depth
17
+
18
+ `comp.vision(clip, { depth: true })` and `withVision({ mode: "depth" })` estimate depth with Depth Anything V2 **Small** (onnx-community export of `depth-anything/Depth-Anything-V2-Small`), whose weights are Apache-2.0. The larger Depth Anything V2 checkpoints are licensed CC-BY-NC-4.0 and are not used.
@@ -1,6 +1,7 @@
1
- import "../index-COYNQ_mf.mjs";
2
- import { a as SfxTrigger, c as softLimit, d as _default$5, f as _default$4, g as mixAudioTracks, h as _default$2, i as SfxRenderContext, l as _default$7, m as _default$3, n as encodeStereoWav, o as mixSfxInto, p as _default, r as RenderedSfx, s as renderSfx, t as EncodeWavOptions, u as _default$6 } from "../index-D2i9J9Zq.mjs";
3
- import { G as WebGPUAudioProcessor } from "../index-BuiZzc6i.mjs";
4
- import "../renderer-BVKOQarx.mjs";
5
- import { t as _default$1 } from "../renderer-88C3QpKL.mjs";
1
+ import "../index-a6JrbAK0.mjs";
2
+ import { n as mixAudioTracks } from "../index-BFTtXosj.mjs";
3
+ import { J as WebGPUAudioProcessor } from "../index-X2u96TEo.mjs";
4
+ import "../renderer-DKJOon6y.mjs";
5
+ import { a as SfxTrigger, c as softLimit, d as _default$5, f as _default$4, h as _default$2, i as SfxRenderContext, l as _default$7, m as _default$3, n as encodeStereoWav, o as mixSfxInto, p as _default, r as RenderedSfx, s as renderSfx, t as EncodeWavOptions, u as _default$6 } from "../index-D68eGFNE.mjs";
6
+ import { t as _default$1 } from "../renderer-aRk849b3.mjs";
6
7
  export { EncodeWavOptions, RenderedSfx, SfxRenderContext, SfxTrigger, WebGPUAudioProcessor, _default as audioFadeRenderer, _default$1 as audioSignalExtractorRenderer, _default$2 as compressorRenderer, _default$3 as delayRenderer, encodeStereoWav, mixAudioTracks, mixSfxInto, _default$4 as noiseGateRenderer, _default$5 as parametricEqRenderer, renderSfx, _default$6 as reverbRenderer, softLimit, _default$7 as stereoPanningRenderer };
@@ -1,15 +1,15 @@
1
- import "../chunk-W71TSjRM.mjs";
2
- import { g as WebGPUAudioProcessor } from "../dist-CWLLnigL.mjs";
3
- import { t as renderers_default$1 } from "../renderers-CP8CFWDs-DRoslK4F.mjs";
4
- import { i as mixAudioTracks } from "../dist-EQX3TUUl.mjs";
5
- import { t as renderers_default$2 } from "../renderer-q7q6k_cD.mjs";
6
- import { t as renderers_default$3 } from "../renderer-CLAvn9c6.mjs";
7
- import { t as renderers_default } from "../renderer-BwrfKKqw.mjs";
8
- import { t as renderers_default$4 } from "../renderer-o68mVeyk.mjs";
9
- import { t as renderers_default$5 } from "../renderer-C9BSXyrq.mjs";
10
- import { t as renderers_default$6 } from "../renderer-Bxjb0HYU.mjs";
11
- import "../renderer-B6rZUBwE.mjs";
12
- import { t as renderers_default$7 } from "../renderer-B-CMRUag.mjs";
13
- import { i as softLimit, n as mixSfxInto, r as renderSfx, t as encodeStereoWav } from "../audio-KHBadECb.mjs";
1
+ import "../chunk-DOL2i2sR.mjs";
2
+ import { g as WebGPUAudioProcessor } from "../dist-D3BeAZ7X.mjs";
3
+ import { t as renderers_default$1 } from "../renderers-CP8CFWDs-BRQyvcut.mjs";
4
+ import { i as mixAudioTracks } from "../dist-CUNvNDS3.mjs";
5
+ import { t as renderers_default$2 } from "../renderer-DxB_OfLs.mjs";
6
+ import { t as renderers_default$3 } from "../renderer-C-GTxnfv.mjs";
7
+ import { t as renderers_default } from "../renderer-D-fzEZfX.mjs";
8
+ import { t as renderers_default$4 } from "../renderer-CxSFvKd1.mjs";
9
+ import { t as renderers_default$5 } from "../renderer-BHPgkoEL.mjs";
10
+ import { t as renderers_default$6 } from "../renderer-BPOh9x5X.mjs";
11
+ import "../renderer-Co2YqWX0.mjs";
12
+ import { t as renderers_default$7 } from "../renderer-CMnlgAGs.mjs";
13
+ import { i as softLimit, n as mixSfxInto, r as renderSfx, t as encodeStereoWav } from "../audio-DS9Jg2ls.mjs";
14
14
 
15
15
  export { WebGPUAudioProcessor, renderers_default as audioFadeRenderer, renderers_default$1 as audioSignalExtractorRenderer, renderers_default$2 as compressorRenderer, renderers_default$3 as delayRenderer, encodeStereoWav, mixAudioTracks, mixSfxInto, renderers_default$4 as noiseGateRenderer, renderers_default$5 as parametricEqRenderer, renderSfx, renderers_default$6 as reverbRenderer, softLimit, renderers_default$7 as stereoPanningRenderer };
@@ -1,6 +1,5 @@
1
- import { $ as FrameSignal } from "./index-COYNQ_mf.mjs";
2
- import { o as AudioPitchTrackConfig, s as AudioSignalComputeConfig } from "./index-BuiZzc6i.mjs";
3
- import { n as NodeRendererPlugin } from "./renderer-BVKOQarx.mjs";
1
+ import { $ as FrameSignal } from "./index-a6JrbAK0.mjs";
2
+ import { l as AudioPitchTrackConfig, n as NodeRendererPlugin, u as AudioSignalComputeConfig } from "./index-X2u96TEo.mjs";
4
3
 
5
4
  //#region ../../nodes/node-modulate/dist/renderer.d.mts
6
5
  //#region src/renderers/index.d.ts
@@ -59,4 +58,4 @@ declare const AudioSignal: {
59
58
  };
60
59
  //#endregion
61
60
  export { ExtractedAudioSignalsBundle as a, AudioSignalOptions as i, AudioPitchSignals as n, _default as o, AudioSignal as r, AudioPitchOptions as t };
62
- //# sourceMappingURL=audio-CYZkDwae.d.mts.map
61
+ //# sourceMappingURL=audio-CHV33Od9.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-CHV33Od9.d.mts","names":["_framefields_node_sdk_renderer0","_default","NodeRendererPlugin","Readonly","default"],"sources":["../../../nodes/node-modulate/dist/renderer.d.mts","../src/signals/audio.ts"],"sourcesContent":["import * as _framefields_node_sdk_renderer0 from \"@framefields/node-sdk/renderer\";\n\n//#region src/renderers/index.d.ts\ndeclare const _default: Readonly<_framefields_node_sdk_renderer0.NodeRendererPlugin>;\n//#endregion\nexport { _default as default };\n//# sourceMappingURL=renderer.d.mts.map"],"mappings":";;;;;cAGcC,UAAUE,SAASH;AAHiD;;;UCcjE,kBAAA,SAA2B;;EDX9BC,WAAsE,CAAA,EAAA,MAAA;;;UCiBnE,2BAAA;EANA,OAAA,EAOP,WAPO,CAAmB,MAAA,CAAA;EAMnB,IAAA,EAEV,WAFU,CAAA,MAAA,CAAA;EACP,IAAA,EAEH,WAFG,CAAA,MAAA,CAAA;EACH,MAAA,EAEE,WAFF,CAAA,MAAA,CAAA;EACA,WAAA,EAAA,MAAA;EACE,SAAA,EAAA,MAAA;EAAW,UAAA,EAAA,MAAA;EAaH,WAAA,EAAA,OAAkB;EAKlB,OAAA,EAAA,OAAA;EAEZ,aAAA,EAAA,OAAA;EAEQ,UAAA,EAAA,OAAA;EAEJ,UAAA,EAAA,OAAA;EACO,YAAA,EAAA,OAAA;EAA0B,SAAA,CAAA,KAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;AAAkC,UAZ3D,iBAAA,SAA0B,qBAYiC,CAAA;EAc/D,GAAA,CAAA,EAAA,MAAA;;;AAKD,UA1BK,iBAAA,CA0BL;EAAR;EAoFO,EAAA,EA5GN,WA4GM,CAAA,MAAA,CAAA;EACC;EAAR,UAAA,EA3GS,WA2GT,CAAA,MAAA,CAAA;EAWQ;EAED,MAAA,EAtHF,WAsHE,CAAA,MAAA,CAAA;EACC,OAAA,EAAA;IAAR,EAAA,EAtHY,YAsHZ;IA4BO,UAAA,EAlJ+B,YAkJ/B;IACC,MAAA,EAnJoD,YAmJpD;EAAR,CAAA;EAAO,GAAA,EAAA,MAAA;;;;cArIE;gCAED,8CAED,qBACP,QAAQ;oCAoFD,qBACP,QAAQ;;8BAWA,8CAED,oBACP,QAAQ;;kCA4BD,oBACP,QAAQ"}
@@ -1,6 +1,6 @@
1
- import { Mt as frameArraySignal } from "./dist-Bf2_efYP.mjs";
2
- import { Ot as AudioSignalComputePipeline, ct as trackAudioPitch, j as ensureDevice } from "./dist-CWLLnigL.mjs";
3
- import { n as decodeAudioSource } from "./dist-EQX3TUUl.mjs";
1
+ import { Mt as frameArraySignal } from "./dist-C8XSqfTx.mjs";
2
+ import { At as AudioSignalComputePipeline, j as ensureDevice, lt as trackAudioPitch } from "./dist-D3BeAZ7X.mjs";
3
+ import { n as decodeAudioSource } from "./dist-CUNvNDS3.mjs";
4
4
 
5
5
  //#region src/signals/audio.ts
6
6
  async function decodeOrThrow(source, purpose) {
@@ -108,4 +108,4 @@ const AudioSignal = {
108
108
 
109
109
  //#endregion
110
110
  export { AudioSignal as t };
111
- //# sourceMappingURL=audio-BuCVk1IQ.mjs.map
111
+ //# sourceMappingURL=audio-DHzLQ_RG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"audio-BuCVk1IQ.mjs","names":[],"sources":["../src/signals/audio.ts"],"sourcesContent":["import { decodeAudioSource } from \"@framefields/compositions\";\nimport {\n\ttype FrameSignal,\n\tframeArraySignal,\n\ttype GPUTextureBinding,\n} from \"@framefields/core\";\nimport {\n\ttype AudioPitchTrackConfig,\n\ttype AudioSignalComputeConfig,\n\tAudioSignalComputePipeline,\n\tensureDevice,\n\ttrackAudioPitch,\n} from \"@framefields/webgpu-renderers\";\n\nexport interface AudioSignalOptions extends AudioSignalComputeConfig {\n\tfps?: number;\n\ttargetWidth?: number;\n\tpreviewMode?: \"waveform\" | \"envelope\" | \"beat_markers\" | \"spectrum\";\n}\n\nexport interface ExtractedAudioSignalsBundle {\n\tprimary: FrameSignal<number>;\n\tbeat: FrameSignal<number>;\n\tbass: FrameSignal<number>;\n\tenergy: FrameSignal<number>;\n\tdurationSec: number;\n\tnumFrames: number;\n\tsampleRate: number;\n\ttextureView: unknown;\n\ttexture: unknown;\n\tprimaryBuffer: unknown;\n\tbeatBuffer: unknown;\n\tbassBuffer: unknown;\n\tenergyBuffer: unknown;\n\tseekFrame(frame: number): void;\n}\n\nexport interface AudioPitchOptions extends AudioPitchTrackConfig {\n\tfps?: number;\n}\n\n/** Fundamental frequency per frame, e.g. an engine note (RPM) or a melody line. */\nexport interface AudioPitchSignals {\n\t/** Pitch in Hz; interpolated across unvoiced gaps so it never drops to 0 mid-track. */\n\thz: FrameSignal<number>;\n\t/** 0..1 periodicity of the measured frame, 0 where unvoiced. */\n\tconfidence: FrameSignal<number>;\n\t/** 1 where a pitch was measured, 0 where `hz` is interpolated. */\n\tvoiced: FrameSignal<number>;\n\tsamples: { hz: Float32Array; confidence: Float32Array; voiced: Float32Array };\n\tfps: number;\n\tnumFrames: number;\n\tdurationSec: number;\n}\n\nasync function decodeOrThrow(source: string, purpose: string) {\n\tconst decoded = await decodeAudioSource(source);\n\tif (!decoded || decoded.channels.length === 0) {\n\t\tthrow new Error(`Failed to decode audio source for ${purpose}: ${source}`);\n\t}\n\treturn decoded;\n}\n\nexport const AudioSignal = {\n\tasync extractFromChannels(\n\t\tchannels: Float32Array[],\n\t\tsampleRate: number,\n\t\toptions: AudioSignalOptions = {},\n\t): Promise<ExtractedAudioSignalsBundle> {\n\t\tconst device = await ensureDevice();\n\t\tconst fps = options.fps ?? 24;\n\t\tconst targetWidth = options.targetWidth ?? 512;\n\n\t\tconst extracted = await AudioSignalComputePipeline.extractFeatures(\n\t\t\tdevice,\n\t\t\tchannels,\n\t\t\tsampleRate,\n\t\t\tfps,\n\t\t\toptions,\n\t\t\ttargetWidth,\n\t\t);\n\n\t\tconst samples = extracted.channelSamples ?? {\n\t\t\tprimary: new Float32Array(extracted.numFrames),\n\t\t\tbeat: new Float32Array(extracted.numFrames),\n\t\t\tbass: new Float32Array(extracted.numFrames),\n\t\t\tenergy: new Float32Array(extracted.numFrames),\n\t\t};\n\n\t\tconst primaryBinding: GPUTextureBinding = {\n\t\t\tnodeId: \"audio_primary\",\n\t\t\tchannel: \"primary\",\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tbuffer: extracted.primaryBuffer,\n\t\t\tstats: extracted.stats.primary,\n\t\t};\n\t\tconst beatBinding: GPUTextureBinding = {\n\t\t\tnodeId: \"audio_beat\",\n\t\t\tchannel: \"beat\",\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tbuffer: extracted.beatBuffer,\n\t\t\tstats: extracted.stats.beat,\n\t\t};\n\t\tconst bassBinding: GPUTextureBinding = {\n\t\t\tnodeId: \"audio_bass\",\n\t\t\tchannel: \"bass\",\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tbuffer: extracted.bassBuffer,\n\t\t\tstats: extracted.stats.bass,\n\t\t};\n\t\tconst energyBinding: GPUTextureBinding = {\n\t\t\tnodeId: \"audio_energy\",\n\t\t\tchannel: \"energy\",\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tbuffer: extracted.energyBuffer,\n\t\t\tstats: extracted.stats.energy,\n\t\t};\n\n\t\tconst primary = frameArraySignal(samples.primary, fps, primaryBinding);\n\t\tconst beat = frameArraySignal(samples.beat, fps, beatBinding);\n\t\tconst bass = frameArraySignal(samples.bass, fps, bassBinding);\n\t\tconst energy = frameArraySignal(samples.energy, fps, energyBinding);\n\n\t\treturn {\n\t\t\tprimary,\n\t\t\tbeat,\n\t\t\tbass,\n\t\t\tenergy,\n\t\t\tdurationSec: extracted.durationSec,\n\t\t\tnumFrames: extracted.numFrames,\n\t\t\tsampleRate,\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tprimaryBuffer: extracted.primaryBuffer,\n\t\t\tbeatBuffer: extracted.beatBuffer,\n\t\t\tbassBuffer: extracted.bassBuffer,\n\t\t\tenergyBuffer: extracted.energyBuffer,\n\t\t\tseekFrame(frame: number) {\n\t\t\t\tprimary.seekFrame?.(frame);\n\t\t\t\tbeat.seekFrame?.(frame);\n\t\t\t\tbass.seekFrame?.(frame);\n\t\t\t\tenergy.seekFrame?.(frame);\n\t\t\t},\n\t\t};\n\t},\n\n\tasync extract(\n\t\tsource: string,\n\t\toptions: AudioSignalOptions = {},\n\t): Promise<ExtractedAudioSignalsBundle> {\n\t\tconst decoded = await decodeOrThrow(source, \"feature extraction\");\n\t\treturn AudioSignal.extractFromChannels(\n\t\t\tdecoded.channels,\n\t\t\tdecoded.sampleRate,\n\t\t\toptions,\n\t\t);\n\t},\n\n\t/** Tracks the fundamental frequency of the downmixed channels on the GPU. */\n\tasync pitchFromChannels(\n\t\tchannels: Float32Array[],\n\t\tsampleRate: number,\n\t\toptions: AudioPitchOptions = {},\n\t): Promise<AudioPitchSignals> {\n\t\tconst device = await ensureDevice();\n\t\tconst fps = options.fps ?? 24;\n\t\tconst track = await trackAudioPitch(\n\t\t\tdevice,\n\t\t\tchannels,\n\t\t\tsampleRate,\n\t\t\tfps,\n\t\t\toptions,\n\t\t);\n\t\treturn {\n\t\t\thz: frameArraySignal(track.hz, fps),\n\t\t\tconfidence: frameArraySignal(track.confidence, fps),\n\t\t\tvoiced: frameArraySignal(track.voiced, fps),\n\t\t\tsamples: {\n\t\t\t\thz: track.hz,\n\t\t\t\tconfidence: track.confidence,\n\t\t\t\tvoiced: track.voiced,\n\t\t\t},\n\t\t\tfps,\n\t\t\tnumFrames: track.numFrames,\n\t\t\tdurationSec: track.durationSec,\n\t\t};\n\t},\n\n\t/** Decodes `source` (audio or video file) and tracks its pitch. */\n\tasync pitch(\n\t\tsource: string,\n\t\toptions: AudioPitchOptions = {},\n\t): Promise<AudioPitchSignals> {\n\t\tconst decoded = await decodeOrThrow(source, \"pitch tracking\");\n\t\treturn AudioSignal.pitchFromChannels(\n\t\t\tdecoded.channels,\n\t\t\tdecoded.sampleRate,\n\t\t\toptions,\n\t\t);\n\t},\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"audio-DHzLQ_RG.mjs","names":[],"sources":["../src/signals/audio.ts"],"sourcesContent":["import { decodeAudioSource } from \"@framefields/compositions\";\nimport {\n\ttype FrameSignal,\n\tframeArraySignal,\n\ttype GPUTextureBinding,\n} from \"@framefields/core\";\nimport {\n\ttype AudioPitchTrackConfig,\n\ttype AudioSignalComputeConfig,\n\tAudioSignalComputePipeline,\n\tensureDevice,\n\ttrackAudioPitch,\n} from \"@framefields/webgpu-renderers\";\n\nexport interface AudioSignalOptions extends AudioSignalComputeConfig {\n\tfps?: number;\n\ttargetWidth?: number;\n\tpreviewMode?: \"waveform\" | \"envelope\" | \"beat_markers\" | \"spectrum\";\n}\n\nexport interface ExtractedAudioSignalsBundle {\n\tprimary: FrameSignal<number>;\n\tbeat: FrameSignal<number>;\n\tbass: FrameSignal<number>;\n\tenergy: FrameSignal<number>;\n\tdurationSec: number;\n\tnumFrames: number;\n\tsampleRate: number;\n\ttextureView: unknown;\n\ttexture: unknown;\n\tprimaryBuffer: unknown;\n\tbeatBuffer: unknown;\n\tbassBuffer: unknown;\n\tenergyBuffer: unknown;\n\tseekFrame(frame: number): void;\n}\n\nexport interface AudioPitchOptions extends AudioPitchTrackConfig {\n\tfps?: number;\n}\n\n/** Fundamental frequency per frame, e.g. an engine note (RPM) or a melody line. */\nexport interface AudioPitchSignals {\n\t/** Pitch in Hz; interpolated across unvoiced gaps so it never drops to 0 mid-track. */\n\thz: FrameSignal<number>;\n\t/** 0..1 periodicity of the measured frame, 0 where unvoiced. */\n\tconfidence: FrameSignal<number>;\n\t/** 1 where a pitch was measured, 0 where `hz` is interpolated. */\n\tvoiced: FrameSignal<number>;\n\tsamples: { hz: Float32Array; confidence: Float32Array; voiced: Float32Array };\n\tfps: number;\n\tnumFrames: number;\n\tdurationSec: number;\n}\n\nasync function decodeOrThrow(source: string, purpose: string) {\n\tconst decoded = await decodeAudioSource(source);\n\tif (!decoded || decoded.channels.length === 0) {\n\t\tthrow new Error(`Failed to decode audio source for ${purpose}: ${source}`);\n\t}\n\treturn decoded;\n}\n\nexport const AudioSignal = {\n\tasync extractFromChannels(\n\t\tchannels: Float32Array[],\n\t\tsampleRate: number,\n\t\toptions: AudioSignalOptions = {},\n\t): Promise<ExtractedAudioSignalsBundle> {\n\t\tconst device = await ensureDevice();\n\t\tconst fps = options.fps ?? 24;\n\t\tconst targetWidth = options.targetWidth ?? 512;\n\n\t\tconst extracted = await AudioSignalComputePipeline.extractFeatures(\n\t\t\tdevice,\n\t\t\tchannels,\n\t\t\tsampleRate,\n\t\t\tfps,\n\t\t\toptions,\n\t\t\ttargetWidth,\n\t\t);\n\n\t\tconst samples = extracted.channelSamples ?? {\n\t\t\tprimary: new Float32Array(extracted.numFrames),\n\t\t\tbeat: new Float32Array(extracted.numFrames),\n\t\t\tbass: new Float32Array(extracted.numFrames),\n\t\t\tenergy: new Float32Array(extracted.numFrames),\n\t\t};\n\n\t\tconst primaryBinding: GPUTextureBinding = {\n\t\t\tnodeId: \"audio_primary\",\n\t\t\tchannel: \"primary\",\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tbuffer: extracted.primaryBuffer,\n\t\t\tstats: extracted.stats.primary,\n\t\t};\n\t\tconst beatBinding: GPUTextureBinding = {\n\t\t\tnodeId: \"audio_beat\",\n\t\t\tchannel: \"beat\",\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tbuffer: extracted.beatBuffer,\n\t\t\tstats: extracted.stats.beat,\n\t\t};\n\t\tconst bassBinding: GPUTextureBinding = {\n\t\t\tnodeId: \"audio_bass\",\n\t\t\tchannel: \"bass\",\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tbuffer: extracted.bassBuffer,\n\t\t\tstats: extracted.stats.bass,\n\t\t};\n\t\tconst energyBinding: GPUTextureBinding = {\n\t\t\tnodeId: \"audio_energy\",\n\t\t\tchannel: \"energy\",\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tbuffer: extracted.energyBuffer,\n\t\t\tstats: extracted.stats.energy,\n\t\t};\n\n\t\tconst primary = frameArraySignal(samples.primary, fps, primaryBinding);\n\t\tconst beat = frameArraySignal(samples.beat, fps, beatBinding);\n\t\tconst bass = frameArraySignal(samples.bass, fps, bassBinding);\n\t\tconst energy = frameArraySignal(samples.energy, fps, energyBinding);\n\n\t\treturn {\n\t\t\tprimary,\n\t\t\tbeat,\n\t\t\tbass,\n\t\t\tenergy,\n\t\t\tdurationSec: extracted.durationSec,\n\t\t\tnumFrames: extracted.numFrames,\n\t\t\tsampleRate,\n\t\t\ttextureView: extracted.textureView,\n\t\t\ttexture: extracted.texture,\n\t\t\tprimaryBuffer: extracted.primaryBuffer,\n\t\t\tbeatBuffer: extracted.beatBuffer,\n\t\t\tbassBuffer: extracted.bassBuffer,\n\t\t\tenergyBuffer: extracted.energyBuffer,\n\t\t\tseekFrame(frame: number) {\n\t\t\t\tprimary.seekFrame?.(frame);\n\t\t\t\tbeat.seekFrame?.(frame);\n\t\t\t\tbass.seekFrame?.(frame);\n\t\t\t\tenergy.seekFrame?.(frame);\n\t\t\t},\n\t\t};\n\t},\n\n\tasync extract(\n\t\tsource: string,\n\t\toptions: AudioSignalOptions = {},\n\t): Promise<ExtractedAudioSignalsBundle> {\n\t\tconst decoded = await decodeOrThrow(source, \"feature extraction\");\n\t\treturn AudioSignal.extractFromChannels(\n\t\t\tdecoded.channels,\n\t\t\tdecoded.sampleRate,\n\t\t\toptions,\n\t\t);\n\t},\n\n\t/** Tracks the fundamental frequency of the downmixed channels on the GPU. */\n\tasync pitchFromChannels(\n\t\tchannels: Float32Array[],\n\t\tsampleRate: number,\n\t\toptions: AudioPitchOptions = {},\n\t): Promise<AudioPitchSignals> {\n\t\tconst device = await ensureDevice();\n\t\tconst fps = options.fps ?? 24;\n\t\tconst track = await trackAudioPitch(\n\t\t\tdevice,\n\t\t\tchannels,\n\t\t\tsampleRate,\n\t\t\tfps,\n\t\t\toptions,\n\t\t);\n\t\treturn {\n\t\t\thz: frameArraySignal(track.hz, fps),\n\t\t\tconfidence: frameArraySignal(track.confidence, fps),\n\t\t\tvoiced: frameArraySignal(track.voiced, fps),\n\t\t\tsamples: {\n\t\t\t\thz: track.hz,\n\t\t\t\tconfidence: track.confidence,\n\t\t\t\tvoiced: track.voiced,\n\t\t\t},\n\t\t\tfps,\n\t\t\tnumFrames: track.numFrames,\n\t\t\tdurationSec: track.durationSec,\n\t\t};\n\t},\n\n\t/** Decodes `source` (audio or video file) and tracks its pitch. */\n\tasync pitch(\n\t\tsource: string,\n\t\toptions: AudioPitchOptions = {},\n\t): Promise<AudioPitchSignals> {\n\t\tconst decoded = await decodeOrThrow(source, \"pitch tracking\");\n\t\treturn AudioSignal.pitchFromChannels(\n\t\t\tdecoded.channels,\n\t\t\tdecoded.sampleRate,\n\t\t\toptions,\n\t\t);\n\t},\n};\n"],"mappings":";;;;;AAuDA,eAAe,cAAc,QAAgB,SAAiB;CAC7D,MAAM,UAAU,MAAM,kBAAkB,OAAO;AAC/C,KAAI,CAAC,WAAW,QAAQ,SAAS,WAAW,EAC3C,OAAM,IAAI,MAAM,qCAAqC,QAAQ,IAAI,SAAS;AAE3E,QAAO;;AAGR,MAAa,cAAc;CAC1B,MAAM,oBACL,UACA,YACA,UAA8B,EAAE,EACO;EACvC,MAAM,SAAS,MAAM,cAAc;EACnC,MAAM,MAAM,QAAQ,OAAO;EAC3B,MAAM,cAAc,QAAQ,eAAe;EAE3C,MAAM,YAAY,MAAM,2BAA2B,gBAClD,QACA,UACA,YACA,KACA,SACA,YACA;EAED,MAAM,UAAU,UAAU,kBAAkB;GAC3C,SAAS,IAAI,aAAa,UAAU,UAAU;GAC9C,MAAM,IAAI,aAAa,UAAU,UAAU;GAC3C,MAAM,IAAI,aAAa,UAAU,UAAU;GAC3C,QAAQ,IAAI,aAAa,UAAU,UAAU;GAC7C;EAED,MAAM,iBAAoC;GACzC,QAAQ;GACR,SAAS;GACT,aAAa,UAAU;GACvB,SAAS,UAAU;GACnB,QAAQ,UAAU;GAClB,OAAO,UAAU,MAAM;GACvB;EACD,MAAM,cAAiC;GACtC,QAAQ;GACR,SAAS;GACT,aAAa,UAAU;GACvB,SAAS,UAAU;GACnB,QAAQ,UAAU;GAClB,OAAO,UAAU,MAAM;GACvB;EACD,MAAM,cAAiC;GACtC,QAAQ;GACR,SAAS;GACT,aAAa,UAAU;GACvB,SAAS,UAAU;GACnB,QAAQ,UAAU;GAClB,OAAO,UAAU,MAAM;GACvB;EACD,MAAM,gBAAmC;GACxC,QAAQ;GACR,SAAS;GACT,aAAa,UAAU;GACvB,SAAS,UAAU;GACnB,QAAQ,UAAU;GAClB,OAAO,UAAU,MAAM;GACvB;EAED,MAAM,UAAU,iBAAiB,QAAQ,SAAS,KAAK,eAAe;EACtE,MAAM,OAAO,iBAAiB,QAAQ,MAAM,KAAK,YAAY;EAC7D,MAAM,OAAO,iBAAiB,QAAQ,MAAM,KAAK,YAAY;EAC7D,MAAM,SAAS,iBAAiB,QAAQ,QAAQ,KAAK,cAAc;AAEnE,SAAO;GACN;GACA;GACA;GACA;GACA,aAAa,UAAU;GACvB,WAAW,UAAU;GACrB;GACA,aAAa,UAAU;GACvB,SAAS,UAAU;GACnB,eAAe,UAAU;GACzB,YAAY,UAAU;GACtB,YAAY,UAAU;GACtB,cAAc,UAAU;GACxB,UAAU,OAAe;AACxB,YAAQ,YAAY,MAAM;AAC1B,SAAK,YAAY,MAAM;AACvB,SAAK,YAAY,MAAM;AACvB,WAAO,YAAY,MAAM;;GAE1B;;CAGF,MAAM,QACL,QACA,UAA8B,EAAE,EACO;EACvC,MAAM,UAAU,MAAM,cAAc,QAAQ,qBAAqB;AACjE,SAAO,YAAY,oBAClB,QAAQ,UACR,QAAQ,YACR,QACA;;CAIF,MAAM,kBACL,UACA,YACA,UAA6B,EAAE,EACF;EAC7B,MAAM,SAAS,MAAM,cAAc;EACnC,MAAM,MAAM,QAAQ,OAAO;EAC3B,MAAM,QAAQ,MAAM,gBACnB,QACA,UACA,YACA,KACA,QACA;AACD,SAAO;GACN,IAAI,iBAAiB,MAAM,IAAI,IAAI;GACnC,YAAY,iBAAiB,MAAM,YAAY,IAAI;GACnD,QAAQ,iBAAiB,MAAM,QAAQ,IAAI;GAC3C,SAAS;IACR,IAAI,MAAM;IACV,YAAY,MAAM;IAClB,QAAQ,MAAM;IACd;GACD;GACA,WAAW,MAAM;GACjB,aAAa,MAAM;GACnB;;CAIF,MAAM,MACL,QACA,UAA6B,EAAE,EACF;EAC7B,MAAM,UAAU,MAAM,cAAc,QAAQ,iBAAiB;AAC7D,SAAO,YAAY,kBAClB,QAAQ,UACR,QAAQ,YACR,QACA;;CAEF"}
@@ -211,4 +211,4 @@ function encodeStereoWav(channels, options = {}) {
211
211
 
212
212
  //#endregion
213
213
  export { softLimit as i, mixSfxInto as n, renderSfx as r, encodeStereoWav as t };
214
- //# sourceMappingURL=audio-KHBadECb.mjs.map
214
+ //# sourceMappingURL=audio-DS9Jg2ls.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"audio-KHBadECb.mjs","names":[],"sources":["../src/audio/synth/sfx.ts","../src/audio/synth/wav-encoder.ts"],"sourcesContent":["/**\n * @file packages/framefields/src/audio/synth/sfx.ts\n * Deterministic procedural transition effects (whoosh, riser, impact, downshifter, glitch).\n * Pure CPU DSP: the same trigger always renders the same samples.\n */\n\n/**\n * Procedural sound effect transition event, synthesized deterministically on the CPU.\n * Default durations: whoosh 0.7s, riser 2s, impact 1.8s, downshifter 1.2s, glitch 0.35s.\n */\nexport interface SfxTrigger {\n\ttype: \"whoosh\" | \"riser\" | \"impact\" | \"downshifter\" | \"glitch\";\n\t/** Bar (fractional allowed) where the effect *starts*. A riser landing on a cut starts `durationSec` earlier. */\n\tatBar: number;\n\tdurationSec?: number;\n\tvolume?: number;\n}\n\nexport type StereoBuffer = [Float32Array, Float32Array];\n\nexport interface RenderedSfx {\n\t/** First sample of the effect on the score timeline. */\n\tstartSample: number;\n\tchannels: StereoBuffer;\n}\n\nexport interface SfxRenderContext {\n\tsampleRate: number;\n\tsecondsPerBar: number;\n\t/** Distinguishes otherwise identical triggers so noise differs between them. */\n\tseed: number;\n}\n\nconst DEFAULT_DURATION_SEC: Record<SfxTrigger[\"type\"], number> = {\n\twhoosh: 0.7,\n\triser: 2,\n\timpact: 1.8,\n\tdownshifter: 1.2,\n\tglitch: 0.35,\n};\n\n/** Small, fast, seedable PRNG returning values in [-1, 1). */\nfunction createNoise(seed: number): () => number {\n\tlet state = (seed ^ 0x9e3779b9) >>> 0;\n\treturn () => {\n\t\tstate = (state + 0x6d2b79f5) >>> 0;\n\t\tlet t = state;\n\t\tt = Math.imul(t ^ (t >>> 15), t | 1);\n\t\tt ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n\t\treturn (((t ^ (t >>> 14)) >>> 0) / 4294967296) * 2 - 1;\n\t};\n}\n\n/** Chamberlin state-variable filter; returns the band-pass output of one sample. */\nclass BandPass {\n\tprivate low = 0;\n\tprivate band = 0;\n\n\tpublic process(\n\t\tinput: number,\n\t\tfreq: number,\n\t\tq: number,\n\t\tsampleRate: number,\n\t): number {\n\t\tconst f =\n\t\t\t2 * Math.sin((Math.PI * Math.min(freq, sampleRate * 0.45)) / sampleRate);\n\t\tthis.low += f * this.band;\n\t\tconst high = input - this.low - q * this.band;\n\t\tthis.band += f * high;\n\t\treturn this.band;\n\t}\n}\n\n/** Exponential sweep from `a` to `b` as `x` moves 0 → 1. */\nconst expSweep = (a: number, b: number, x: number): number => a * (b / a) ** x;\n\n/** Fast rise, longer fall: a bell centred at `peak` in 0..1. */\nconst bell = (x: number, peak: number): number =>\n\tx < peak\n\t\t? Math.sin((x / peak) * (Math.PI / 2)) ** 2\n\t\t: Math.cos(((x - peak) / (1 - peak)) * (Math.PI / 2)) ** 2;\n\nfunction whoosh(\n\tn: number,\n\tsr: number,\n\tnoise: () => number,\n\treverse: boolean,\n): StereoBuffer {\n\tconst left = new Float32Array(n);\n\tconst right = new Float32Array(n);\n\tconst filter = new BandPass();\n\tfor (let i = 0; i < n; i++) {\n\t\tconst x = i / n;\n\t\tconst sweep = reverse ? 1 - x : x;\n\t\tconst env = bell(x, reverse ? 0.35 : 0.6);\n\t\tconst s =\n\t\t\tfilter.process(noise(), expSweep(250, 7000, sweep), 0.35, sr) * env * 0.9;\n\t\tconst pan = (reverse ? 1 - x : x) * 2 - 1;\n\t\tleft[i] = s * Math.sqrt((1 - pan) / 2) * 1.4;\n\t\tright[i] = s * Math.sqrt((1 + pan) / 2) * 1.4;\n\t}\n\treturn [left, right];\n}\n\nfunction riser(\n\tn: number,\n\tsr: number,\n\tnoise: () => number,\n\treverse: boolean,\n): StereoBuffer {\n\tconst left = new Float32Array(n);\n\tconst right = new Float32Array(n);\n\tconst air = new BandPass();\n\tlet phase = 0;\n\tfor (let i = 0; i < n; i++) {\n\t\tconst x = i / n;\n\t\tconst sweep = reverse ? 1 - x : x;\n\t\tconst env = reverse ? (1 - x) ** 1.5 : x ** 2.2;\n\t\tconst freq = expSweep(110, 880, sweep);\n\t\tphase += (2 * Math.PI * freq) / sr;\n\t\t// Band-limited enough at these pitches: two detuned-free partials of a saw.\n\t\tconst tone =\n\t\t\t(Math.sin(phase) +\n\t\t\t\t0.5 * Math.sin(phase * 2) +\n\t\t\t\t0.25 * Math.sin(phase * 3)) *\n\t\t\t0.3;\n\t\tconst hiss =\n\t\t\tair.process(noise(), expSweep(300, 9000, sweep), 0.5, sr) * 1.2;\n\t\tconst s = (tone + hiss) * env * 0.6;\n\t\tleft[i] = s;\n\t\tright[i] = s;\n\t}\n\treturn [left, right];\n}\n\nfunction impact(n: number, sr: number, noise: () => number): StereoBuffer {\n\tconst left = new Float32Array(n);\n\tconst right = new Float32Array(n);\n\tconst burst = new BandPass();\n\tlet phase = 0;\n\tfor (let i = 0; i < n; i++) {\n\t\tconst t = i / sr;\n\t\tconst freq = 38 + 62 * Math.exp(-t * 14);\n\t\tphase += (2 * Math.PI * freq) / sr;\n\t\tconst sub = Math.sin(phase) * Math.exp(-t * 2.6);\n\t\tconst body =\n\t\t\tburst.process(noise(), 900 * Math.exp(-t * 6) + 120, 0.6, sr) *\n\t\t\tMath.exp(-t * 9) *\n\t\t\t1.6;\n\t\tconst click = i < 96 ? noise() * (1 - i / 96) * 0.5 : 0;\n\t\tconst s = (sub * 1.1 + body + click) * 0.85;\n\t\t// Slight decorrelated tail widens the hit without smearing the transient.\n\t\tconst tail = noise() * Math.exp(-t * 5) * 0.08;\n\t\tleft[i] = s + tail;\n\t\tright[i] = s - tail;\n\t}\n\treturn [left, right];\n}\n\nfunction glitch(n: number, sr: number, noise: () => number): StereoBuffer {\n\tconst left = new Float32Array(n);\n\tconst right = new Float32Array(n);\n\tconst slice = Math.max(1, Math.round(sr * 0.022));\n\tlet held = 0;\n\tlet gate = 1;\n\tlet crush = 1;\n\tfor (let i = 0; i < n; i++) {\n\t\tif (i % slice === 0) {\n\t\t\tgate = noise() > -0.2 ? 1 : 0;\n\t\t\tcrush = 2 + Math.floor((noise() + 1) * 6);\n\t\t}\n\t\tif (i % crush === 0) held = noise() > 0 ? 1 : -1;\n\t\tconst env = 1 - i / n;\n\t\tconst s = held * gate * env * 0.45;\n\t\tleft[i] = s;\n\t\tright[i] = gate ? -s * 0.6 : 0;\n\t}\n\treturn [left, right];\n}\n\n/**\n * Renders one trigger to stereo PCM positioned at `atBar` on the score timeline.\n * `atBar` is where the effect *starts*; a riser meant to land on a cut starts\n * `durationSec / secondsPerBar` bars before it.\n */\nexport function renderSfx(\n\ttrigger: SfxTrigger,\n\tctx: SfxRenderContext,\n): RenderedSfx {\n\tconst durationSec = trigger.durationSec ?? DEFAULT_DURATION_SEC[trigger.type];\n\tconst sr = ctx.sampleRate;\n\tconst n = Math.max(1, Math.round(durationSec * sr));\n\tconst noise = createNoise(ctx.seed + n);\n\n\tlet channels: StereoBuffer;\n\tswitch (trigger.type) {\n\t\tcase \"whoosh\":\n\t\t\tchannels = whoosh(n, sr, noise, false);\n\t\t\tbreak;\n\t\tcase \"riser\":\n\t\t\tchannels = riser(n, sr, noise, false);\n\t\t\tbreak;\n\t\tcase \"downshifter\":\n\t\t\tchannels = riser(n, sr, noise, true);\n\t\t\tbreak;\n\t\tcase \"impact\":\n\t\t\tchannels = impact(n, sr, noise);\n\t\t\tbreak;\n\t\tcase \"glitch\":\n\t\t\tchannels = glitch(n, sr, noise);\n\t\t\tbreak;\n\t}\n\n\tconst gain = trigger.volume ?? 0.8;\n\tfor (const channel of channels) {\n\t\tfor (let i = 0; i < n; i++)\n\t\t\tchannel[i] = Math.tanh((channel[i] ?? 0) * gain);\n\t}\n\treturn {\n\t\tstartSample: Math.max(\n\t\t\t0,\n\t\t\tMath.round(trigger.atBar * ctx.secondsPerBar * sr),\n\t\t),\n\t\tchannels,\n\t};\n}\n\n/** Adds rendered effects into `target` in place, clipping to its length. */\nexport function mixSfxInto(\n\ttarget: StereoBuffer,\n\teffects: readonly RenderedSfx[],\n): void {\n\tfor (const fx of effects) {\n\t\tfor (let c = 0; c < 2; c++) {\n\t\t\tconst dst = target[c];\n\t\t\tconst src = fx.channels[c];\n\t\t\tif (!dst || !src) continue;\n\t\t\tconst limit = Math.min(src.length, dst.length - fx.startSample);\n\t\t\tfor (let i = 0; i < limit; i++) {\n\t\t\t\tconst val = dst[fx.startSample + i];\n\t\t\t\tconst s = src[i];\n\t\t\t\tif (val !== undefined && s !== undefined) {\n\t\t\t\t\tdst[fx.startSample + i] = val + s;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Soft-knee limiter for sums that may exceed full scale (impacts stacked on a\n * loud mix): transparent below the knee, asymptotically bounded by 1.0 above it.\n */\nexport function softLimit(\n\ttarget: StereoBuffer,\n\tknee = 0.7,\n\tceiling = 0.97,\n): void {\n\tconst headroom = ceiling - knee;\n\tfor (const channel of target) {\n\t\tfor (let i = 0; i < channel.length; i++) {\n\t\t\tconst x = channel[i] ?? 0;\n\t\t\tconst a = Math.abs(x);\n\t\t\tif (a > knee)\n\t\t\t\tchannel[i] =\n\t\t\t\t\tMath.sign(x) * (knee + headroom * Math.tanh((a - knee) / headroom));\n\t\t}\n\t}\n}\n","/**\n * @file packages/framefields/src/audio/synth/wav-encoder.ts\n * High-performance 16-bit PCM RIFF/WAVE stereo audio encoder.\n */\n\nexport interface EncodeWavOptions {\n\tsampleRate?: number;\n}\n\n/**\n * Encodes stereo Float32Array PCM channels (-1.0 to +1.0) into a standard 16-bit RIFF/WAVE Buffer.\n */\nexport function encodeStereoWav(\n\tchannels: [Float32Array, Float32Array],\n\toptions: EncodeWavOptions = {},\n): Buffer {\n\tconst sampleRate = options.sampleRate ?? 48000;\n\tconst numChannels = 2;\n\tconst left = channels[0];\n\tconst right = channels[1];\n\tconst numSamples = Math.min(left.length, right.length);\n\n\tconst bytesPerSample = 2; // 16-bit\n\tconst blockAlign = numChannels * bytesPerSample;\n\tconst byteRate = sampleRate * blockAlign;\n\tconst dataSize = numSamples * blockAlign;\n\tconst totalSize = 44 + dataSize;\n\n\tconst buffer = Buffer.alloc(totalSize);\n\n\t// RIFF Header\n\tbuffer.write(\"RIFF\", 0, \"ascii\");\n\tbuffer.writeUInt32LE(36 + dataSize, 4);\n\tbuffer.write(\"WAVE\", 8, \"ascii\");\n\n\t// \"fmt \" chunk\n\tbuffer.write(\"fmt \", 12, \"ascii\");\n\tbuffer.writeUInt32LE(16, 16); // PCM header size\n\tbuffer.writeUInt16LE(1, 20); // AudioFormat 1 = PCM\n\tbuffer.writeUInt16LE(numChannels, 22);\n\tbuffer.writeUInt32LE(sampleRate, 24);\n\tbuffer.writeUInt32LE(byteRate, 28);\n\tbuffer.writeUInt16LE(blockAlign, 32);\n\tbuffer.writeUInt16LE(16, 34); // Bits per sample\n\n\t// \"data\" chunk\n\tbuffer.write(\"data\", 36, \"ascii\");\n\tbuffer.writeUInt32LE(dataSize, 40);\n\n\tlet offset = 44;\n\tfor (let i = 0; i < numSamples; i++) {\n\t\t// Left channel\n\t\tconst sl = Math.max(-1, Math.min(1, left[i] ?? 0));\n\t\tconst intL = sl < 0 ? sl * 0x8000 : sl * 0x7fff;\n\t\tbuffer.writeInt16LE(Math.round(intL), offset);\n\t\toffset += 2;\n\n\t\t// Right channel\n\t\tconst sr = Math.max(-1, Math.min(1, right[i] ?? 0));\n\t\tconst intR = sr < 0 ? sr * 0x8000 : sr * 0x7fff;\n\t\tbuffer.writeInt16LE(Math.round(intR), offset);\n\t\toffset += 2;\n\t}\n\n\treturn buffer;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"audio-DS9Jg2ls.mjs","names":[],"sources":["../src/audio/synth/sfx.ts","../src/audio/synth/wav-encoder.ts"],"sourcesContent":["/**\n * @file packages/framefields/src/audio/synth/sfx.ts\n * Deterministic procedural transition effects (whoosh, riser, impact, downshifter, glitch).\n * Pure CPU DSP: the same trigger always renders the same samples.\n */\n\n/**\n * Procedural sound effect transition event, synthesized deterministically on the CPU.\n * Default durations: whoosh 0.7s, riser 2s, impact 1.8s, downshifter 1.2s, glitch 0.35s.\n */\nexport interface SfxTrigger {\n\ttype: \"whoosh\" | \"riser\" | \"impact\" | \"downshifter\" | \"glitch\";\n\t/** Bar (fractional allowed) where the effect *starts*. A riser landing on a cut starts `durationSec` earlier. */\n\tatBar: number;\n\tdurationSec?: number;\n\tvolume?: number;\n}\n\nexport type StereoBuffer = [Float32Array, Float32Array];\n\nexport interface RenderedSfx {\n\t/** First sample of the effect on the score timeline. */\n\tstartSample: number;\n\tchannels: StereoBuffer;\n}\n\nexport interface SfxRenderContext {\n\tsampleRate: number;\n\tsecondsPerBar: number;\n\t/** Distinguishes otherwise identical triggers so noise differs between them. */\n\tseed: number;\n}\n\nconst DEFAULT_DURATION_SEC: Record<SfxTrigger[\"type\"], number> = {\n\twhoosh: 0.7,\n\triser: 2,\n\timpact: 1.8,\n\tdownshifter: 1.2,\n\tglitch: 0.35,\n};\n\n/** Small, fast, seedable PRNG returning values in [-1, 1). */\nfunction createNoise(seed: number): () => number {\n\tlet state = (seed ^ 0x9e3779b9) >>> 0;\n\treturn () => {\n\t\tstate = (state + 0x6d2b79f5) >>> 0;\n\t\tlet t = state;\n\t\tt = Math.imul(t ^ (t >>> 15), t | 1);\n\t\tt ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n\t\treturn (((t ^ (t >>> 14)) >>> 0) / 4294967296) * 2 - 1;\n\t};\n}\n\n/** Chamberlin state-variable filter; returns the band-pass output of one sample. */\nclass BandPass {\n\tprivate low = 0;\n\tprivate band = 0;\n\n\tpublic process(\n\t\tinput: number,\n\t\tfreq: number,\n\t\tq: number,\n\t\tsampleRate: number,\n\t): number {\n\t\tconst f =\n\t\t\t2 * Math.sin((Math.PI * Math.min(freq, sampleRate * 0.45)) / sampleRate);\n\t\tthis.low += f * this.band;\n\t\tconst high = input - this.low - q * this.band;\n\t\tthis.band += f * high;\n\t\treturn this.band;\n\t}\n}\n\n/** Exponential sweep from `a` to `b` as `x` moves 0 → 1. */\nconst expSweep = (a: number, b: number, x: number): number => a * (b / a) ** x;\n\n/** Fast rise, longer fall: a bell centred at `peak` in 0..1. */\nconst bell = (x: number, peak: number): number =>\n\tx < peak\n\t\t? Math.sin((x / peak) * (Math.PI / 2)) ** 2\n\t\t: Math.cos(((x - peak) / (1 - peak)) * (Math.PI / 2)) ** 2;\n\nfunction whoosh(\n\tn: number,\n\tsr: number,\n\tnoise: () => number,\n\treverse: boolean,\n): StereoBuffer {\n\tconst left = new Float32Array(n);\n\tconst right = new Float32Array(n);\n\tconst filter = new BandPass();\n\tfor (let i = 0; i < n; i++) {\n\t\tconst x = i / n;\n\t\tconst sweep = reverse ? 1 - x : x;\n\t\tconst env = bell(x, reverse ? 0.35 : 0.6);\n\t\tconst s =\n\t\t\tfilter.process(noise(), expSweep(250, 7000, sweep), 0.35, sr) * env * 0.9;\n\t\tconst pan = (reverse ? 1 - x : x) * 2 - 1;\n\t\tleft[i] = s * Math.sqrt((1 - pan) / 2) * 1.4;\n\t\tright[i] = s * Math.sqrt((1 + pan) / 2) * 1.4;\n\t}\n\treturn [left, right];\n}\n\nfunction riser(\n\tn: number,\n\tsr: number,\n\tnoise: () => number,\n\treverse: boolean,\n): StereoBuffer {\n\tconst left = new Float32Array(n);\n\tconst right = new Float32Array(n);\n\tconst air = new BandPass();\n\tlet phase = 0;\n\tfor (let i = 0; i < n; i++) {\n\t\tconst x = i / n;\n\t\tconst sweep = reverse ? 1 - x : x;\n\t\tconst env = reverse ? (1 - x) ** 1.5 : x ** 2.2;\n\t\tconst freq = expSweep(110, 880, sweep);\n\t\tphase += (2 * Math.PI * freq) / sr;\n\t\t// Band-limited enough at these pitches: two detuned-free partials of a saw.\n\t\tconst tone =\n\t\t\t(Math.sin(phase) +\n\t\t\t\t0.5 * Math.sin(phase * 2) +\n\t\t\t\t0.25 * Math.sin(phase * 3)) *\n\t\t\t0.3;\n\t\tconst hiss =\n\t\t\tair.process(noise(), expSweep(300, 9000, sweep), 0.5, sr) * 1.2;\n\t\tconst s = (tone + hiss) * env * 0.6;\n\t\tleft[i] = s;\n\t\tright[i] = s;\n\t}\n\treturn [left, right];\n}\n\nfunction impact(n: number, sr: number, noise: () => number): StereoBuffer {\n\tconst left = new Float32Array(n);\n\tconst right = new Float32Array(n);\n\tconst burst = new BandPass();\n\tlet phase = 0;\n\tfor (let i = 0; i < n; i++) {\n\t\tconst t = i / sr;\n\t\tconst freq = 38 + 62 * Math.exp(-t * 14);\n\t\tphase += (2 * Math.PI * freq) / sr;\n\t\tconst sub = Math.sin(phase) * Math.exp(-t * 2.6);\n\t\tconst body =\n\t\t\tburst.process(noise(), 900 * Math.exp(-t * 6) + 120, 0.6, sr) *\n\t\t\tMath.exp(-t * 9) *\n\t\t\t1.6;\n\t\tconst click = i < 96 ? noise() * (1 - i / 96) * 0.5 : 0;\n\t\tconst s = (sub * 1.1 + body + click) * 0.85;\n\t\t// Slight decorrelated tail widens the hit without smearing the transient.\n\t\tconst tail = noise() * Math.exp(-t * 5) * 0.08;\n\t\tleft[i] = s + tail;\n\t\tright[i] = s - tail;\n\t}\n\treturn [left, right];\n}\n\nfunction glitch(n: number, sr: number, noise: () => number): StereoBuffer {\n\tconst left = new Float32Array(n);\n\tconst right = new Float32Array(n);\n\tconst slice = Math.max(1, Math.round(sr * 0.022));\n\tlet held = 0;\n\tlet gate = 1;\n\tlet crush = 1;\n\tfor (let i = 0; i < n; i++) {\n\t\tif (i % slice === 0) {\n\t\t\tgate = noise() > -0.2 ? 1 : 0;\n\t\t\tcrush = 2 + Math.floor((noise() + 1) * 6);\n\t\t}\n\t\tif (i % crush === 0) held = noise() > 0 ? 1 : -1;\n\t\tconst env = 1 - i / n;\n\t\tconst s = held * gate * env * 0.45;\n\t\tleft[i] = s;\n\t\tright[i] = gate ? -s * 0.6 : 0;\n\t}\n\treturn [left, right];\n}\n\n/**\n * Renders one trigger to stereo PCM positioned at `atBar` on the score timeline.\n * `atBar` is where the effect *starts*; a riser meant to land on a cut starts\n * `durationSec / secondsPerBar` bars before it.\n */\nexport function renderSfx(\n\ttrigger: SfxTrigger,\n\tctx: SfxRenderContext,\n): RenderedSfx {\n\tconst durationSec = trigger.durationSec ?? DEFAULT_DURATION_SEC[trigger.type];\n\tconst sr = ctx.sampleRate;\n\tconst n = Math.max(1, Math.round(durationSec * sr));\n\tconst noise = createNoise(ctx.seed + n);\n\n\tlet channels: StereoBuffer;\n\tswitch (trigger.type) {\n\t\tcase \"whoosh\":\n\t\t\tchannels = whoosh(n, sr, noise, false);\n\t\t\tbreak;\n\t\tcase \"riser\":\n\t\t\tchannels = riser(n, sr, noise, false);\n\t\t\tbreak;\n\t\tcase \"downshifter\":\n\t\t\tchannels = riser(n, sr, noise, true);\n\t\t\tbreak;\n\t\tcase \"impact\":\n\t\t\tchannels = impact(n, sr, noise);\n\t\t\tbreak;\n\t\tcase \"glitch\":\n\t\t\tchannels = glitch(n, sr, noise);\n\t\t\tbreak;\n\t}\n\n\tconst gain = trigger.volume ?? 0.8;\n\tfor (const channel of channels) {\n\t\tfor (let i = 0; i < n; i++)\n\t\t\tchannel[i] = Math.tanh((channel[i] ?? 0) * gain);\n\t}\n\treturn {\n\t\tstartSample: Math.max(\n\t\t\t0,\n\t\t\tMath.round(trigger.atBar * ctx.secondsPerBar * sr),\n\t\t),\n\t\tchannels,\n\t};\n}\n\n/** Adds rendered effects into `target` in place, clipping to its length. */\nexport function mixSfxInto(\n\ttarget: StereoBuffer,\n\teffects: readonly RenderedSfx[],\n): void {\n\tfor (const fx of effects) {\n\t\tfor (let c = 0; c < 2; c++) {\n\t\t\tconst dst = target[c];\n\t\t\tconst src = fx.channels[c];\n\t\t\tif (!dst || !src) continue;\n\t\t\tconst limit = Math.min(src.length, dst.length - fx.startSample);\n\t\t\tfor (let i = 0; i < limit; i++) {\n\t\t\t\tconst val = dst[fx.startSample + i];\n\t\t\t\tconst s = src[i];\n\t\t\t\tif (val !== undefined && s !== undefined) {\n\t\t\t\t\tdst[fx.startSample + i] = val + s;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Soft-knee limiter for sums that may exceed full scale (impacts stacked on a\n * loud mix): transparent below the knee, asymptotically bounded by 1.0 above it.\n */\nexport function softLimit(\n\ttarget: StereoBuffer,\n\tknee = 0.7,\n\tceiling = 0.97,\n): void {\n\tconst headroom = ceiling - knee;\n\tfor (const channel of target) {\n\t\tfor (let i = 0; i < channel.length; i++) {\n\t\t\tconst x = channel[i] ?? 0;\n\t\t\tconst a = Math.abs(x);\n\t\t\tif (a > knee)\n\t\t\t\tchannel[i] =\n\t\t\t\t\tMath.sign(x) * (knee + headroom * Math.tanh((a - knee) / headroom));\n\t\t}\n\t}\n}\n","/**\n * @file packages/framefields/src/audio/synth/wav-encoder.ts\n * High-performance 16-bit PCM RIFF/WAVE stereo audio encoder.\n */\n\nexport interface EncodeWavOptions {\n\tsampleRate?: number;\n}\n\n/**\n * Encodes stereo Float32Array PCM channels (-1.0 to +1.0) into a standard 16-bit RIFF/WAVE Buffer.\n */\nexport function encodeStereoWav(\n\tchannels: [Float32Array, Float32Array],\n\toptions: EncodeWavOptions = {},\n): Buffer {\n\tconst sampleRate = options.sampleRate ?? 48000;\n\tconst numChannels = 2;\n\tconst left = channels[0];\n\tconst right = channels[1];\n\tconst numSamples = Math.min(left.length, right.length);\n\n\tconst bytesPerSample = 2; // 16-bit\n\tconst blockAlign = numChannels * bytesPerSample;\n\tconst byteRate = sampleRate * blockAlign;\n\tconst dataSize = numSamples * blockAlign;\n\tconst totalSize = 44 + dataSize;\n\n\tconst buffer = Buffer.alloc(totalSize);\n\n\t// RIFF Header\n\tbuffer.write(\"RIFF\", 0, \"ascii\");\n\tbuffer.writeUInt32LE(36 + dataSize, 4);\n\tbuffer.write(\"WAVE\", 8, \"ascii\");\n\n\t// \"fmt \" chunk\n\tbuffer.write(\"fmt \", 12, \"ascii\");\n\tbuffer.writeUInt32LE(16, 16); // PCM header size\n\tbuffer.writeUInt16LE(1, 20); // AudioFormat 1 = PCM\n\tbuffer.writeUInt16LE(numChannels, 22);\n\tbuffer.writeUInt32LE(sampleRate, 24);\n\tbuffer.writeUInt32LE(byteRate, 28);\n\tbuffer.writeUInt16LE(blockAlign, 32);\n\tbuffer.writeUInt16LE(16, 34); // Bits per sample\n\n\t// \"data\" chunk\n\tbuffer.write(\"data\", 36, \"ascii\");\n\tbuffer.writeUInt32LE(dataSize, 40);\n\n\tlet offset = 44;\n\tfor (let i = 0; i < numSamples; i++) {\n\t\t// Left channel\n\t\tconst sl = Math.max(-1, Math.min(1, left[i] ?? 0));\n\t\tconst intL = sl < 0 ? sl * 0x8000 : sl * 0x7fff;\n\t\tbuffer.writeInt16LE(Math.round(intL), offset);\n\t\toffset += 2;\n\n\t\t// Right channel\n\t\tconst sr = Math.max(-1, Math.min(1, right[i] ?? 0));\n\t\tconst intR = sr < 0 ? sr * 0x8000 : sr * 0x7fff;\n\t\tbuffer.writeInt16LE(Math.round(intR), offset);\n\t\toffset += 2;\n\t}\n\n\treturn buffer;\n}\n"],"mappings":"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"}
@@ -19,4 +19,4 @@ function failedCheck(entry, exportName, sdkVersion, code, message) {
19
19
 
20
20
  //#endregion
21
21
  export { failedCheck as t };
22
- //# sourceMappingURL=check-result-Culfu7Nx.mjs.map
22
+ //# sourceMappingURL=check-result-DZWx73V8.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-result-Culfu7Nx.mjs","names":[],"sources":["../src/cli/check-result.ts"],"sourcesContent":["import type { RenderDiagnostic } from \"@framefields/core\";\n\nexport interface CheckDiagnostic extends RenderDiagnostic {\n\tstage:\n\t\t| \"build\"\n\t\t| \"schema\"\n\t\t| \"assets\"\n\t\t| \"lint\"\n\t\t| \"timeline\"\n\t\t| \"render\"\n\t\t| \"worker\";\n\tpath?: string;\n}\n\nexport interface CheckReport {\n\tschemaVersion: 1;\n\tsdkVersion: string;\n\tentry: string;\n\texportName: string;\n\tstatus: \"passed\" | \"failed\";\n\tdiagnostics: CheckDiagnostic[];\n\tartifacts: string[];\n\trender: \"not_requested\" | \"skipped\" | \"passed\" | \"failed\";\n\truntime?: { node: string; platform: string; arch: string };\n\ttimeline?: { fps: number; totalFrames: number; durationMs: number };\n\tbackend?: {\n\t\tvendor: string;\n\t\tdevice: string;\n\t\tdescription: string;\n\t\tsoftware: boolean;\n\t};\n}\n\nexport function failedCheck(\n\tentry: string,\n\texportName: string,\n\tsdkVersion: string,\n\tcode: string,\n\tmessage: string,\n): CheckReport {\n\treturn {\n\t\tschemaVersion: 1,\n\t\tsdkVersion,\n\t\tentry,\n\t\texportName,\n\t\tstatus: \"failed\",\n\t\tdiagnostics: [{ severity: \"error\", code, message, stage: \"worker\" }],\n\t\tartifacts: [],\n\t\trender: \"not_requested\",\n\t};\n}\n"],"mappings":";AAiCA,SAAgB,YACf,OACA,YACA,YACA,MACA,SACc;AACd,QAAO;EACN,eAAe;EACf;EACA;EACA;EACA,QAAQ;EACR,aAAa,CAAC;GAAE,UAAU;GAAS;GAAM;GAAS,OAAO;GAAU,CAAC;EACpE,WAAW,EAAE;EACb,QAAQ;EACR"}
1
+ {"version":3,"file":"check-result-DZWx73V8.mjs","names":[],"sources":["../src/cli/check-result.ts"],"sourcesContent":["import type { RenderDiagnostic } from \"@framefields/core\";\n\nexport interface CheckDiagnostic extends RenderDiagnostic {\n\tstage:\n\t\t| \"build\"\n\t\t| \"schema\"\n\t\t| \"assets\"\n\t\t| \"lint\"\n\t\t| \"timeline\"\n\t\t| \"render\"\n\t\t| \"worker\";\n\tpath?: string;\n}\n\nexport interface CheckReport {\n\tschemaVersion: 1;\n\tsdkVersion: string;\n\tentry: string;\n\texportName: string;\n\tstatus: \"passed\" | \"failed\";\n\tdiagnostics: CheckDiagnostic[];\n\tartifacts: string[];\n\trender: \"not_requested\" | \"skipped\" | \"passed\" | \"failed\";\n\truntime?: { node: string; platform: string; arch: string };\n\ttimeline?: { fps: number; totalFrames: number; durationMs: number };\n\tbackend?: {\n\t\tvendor: string;\n\t\tdevice: string;\n\t\tdescription: string;\n\t\tsoftware: boolean;\n\t};\n}\n\nexport function failedCheck(\n\tentry: string,\n\texportName: string,\n\tsdkVersion: string,\n\tcode: string,\n\tmessage: string,\n): CheckReport {\n\treturn {\n\t\tschemaVersion: 1,\n\t\tsdkVersion,\n\t\tentry,\n\t\texportName,\n\t\tstatus: \"failed\",\n\t\tdiagnostics: [{ severity: \"error\", code, message, stage: \"worker\" }],\n\t\tartifacts: [],\n\t\trender: \"not_requested\",\n\t};\n}\n"],"mappings":";AAiCA,SAAgB,YACf,OACA,YACA,YACA,MACA,SACc;AACd,QAAO;EACN,eAAe;EACf;EACA;EACA;EACA,QAAQ;EACR,aAAa,CAAC;GAAE,UAAU;GAAS;GAAM;GAAS,OAAO;GAAU,CAAC;EACpE,WAAW,EAAE;EACb,QAAQ;EACR"}
@@ -1,53 +1,53 @@
1
- import "../chunk-W71TSjRM.mjs";
2
- import { Nt as frameCount } from "../dist-Bf2_efYP.mjs";
3
- import { t as Composition } from "../src-BYp6r-cS.mjs";
4
- import { x as describeGpu } from "../dist-CWLLnigL.mjs";
5
- import "../renderers-CP8CFWDs-DRoslK4F.mjs";
6
- import "../signals-BfJ1aqpT.mjs";
7
- import "../renderer-DAn9xiQT.mjs";
8
- import "../renderer-Dpl6poqD.mjs";
9
- import "../renderer-q7q6k_cD.mjs";
10
- import "../renderer-CLAvn9c6.mjs";
11
- import "../renderer-BwrfKKqw.mjs";
12
- import "../renderer-o68mVeyk.mjs";
13
- import "../renderer-C9BSXyrq.mjs";
14
- import "../renderer-Bxjb0HYU.mjs";
15
- import "../renderer-B6rZUBwE.mjs";
16
- import "../renderer-B-CMRUag.mjs";
17
- import { s as CompositorProgramSchema } from "../program-Bc860ko5.mjs";
18
- import "../renderer-HDj9Zb-O.mjs";
19
- import "../renderer-7ow5Acsg.mjs";
20
- import "../renderer-sfqZK6L5.mjs";
21
- import "../renderer-BSELd5vU.mjs";
22
- import "../renderer-Ros7XQg2.mjs";
23
- import "../renderer-CxGx1Lhi.mjs";
24
- import "../renderer-h62QaJYz.mjs";
25
- import "../renderer-DwK9jsER.mjs";
26
- import "../renderer-D-QVGphn.mjs";
27
- import "../renderer-DFJWPqOJ.mjs";
28
- import "../renderer-lHNTgiOM.mjs";
29
- import "../renderer-BDZC3o3N.mjs";
30
- import "../renderer-D0aAZHC7.mjs";
31
- import "../renderer-celhuAL7.mjs";
32
- import "../renderer-BhsrlGKp.mjs";
33
- import "../renderer-fs8f1QeE.mjs";
34
- import "../renderer-1uoKiILq.mjs";
35
- import "../renderer-B1esRxGy.mjs";
36
- import "../renderer-DgPn_SOC.mjs";
37
- import "../renderer-JHByuUNb.mjs";
38
- import "../renderer-B1LD29TV.mjs";
39
- import "../renderer-BNHcwxw9.mjs";
40
- import "../renderer-BNJ6Jk7-.mjs";
41
- import "../renderer-D4f8f66C.mjs";
42
- import "../renderer-CrR8Mpxq.mjs";
43
- import "../renderer-Bo7shNdU.mjs";
44
- import "../renderer-BJ-7WRgO.mjs";
45
- import "../renderer-BQetXCcZ.mjs";
46
- import "../renderer-DE9Jik9K.mjs";
47
- import "../renderer-eMCTAa9e.mjs";
48
- import "../renderer-DLPhfwbR.mjs";
49
- import "../renderer-Bx14Wnxl.mjs";
50
- import { t as failedCheck } from "../check-result-Culfu7Nx.mjs";
1
+ import "../chunk-DOL2i2sR.mjs";
2
+ import { Nt as frameCount } from "../dist-C8XSqfTx.mjs";
3
+ import { t as Composition } from "../src-BzFGotRc.mjs";
4
+ import { x as describeGpu } from "../dist-D3BeAZ7X.mjs";
5
+ import "../renderers-CP8CFWDs-BRQyvcut.mjs";
6
+ import "../signals-tiho_9fp.mjs";
7
+ import "../renderer-D8gN7aqk.mjs";
8
+ import "../renderer-DGOMfyh8.mjs";
9
+ import "../renderer-DxB_OfLs.mjs";
10
+ import "../renderer-C-GTxnfv.mjs";
11
+ import "../renderer-D-fzEZfX.mjs";
12
+ import "../renderer-CxSFvKd1.mjs";
13
+ import "../renderer-BHPgkoEL.mjs";
14
+ import "../renderer-BPOh9x5X.mjs";
15
+ import "../renderer-Co2YqWX0.mjs";
16
+ import "../renderer-CMnlgAGs.mjs";
17
+ import { s as CompositorProgramSchema } from "../program-Bn6ko_I4.mjs";
18
+ import "../renderer-NBMmvqWl.mjs";
19
+ import "../renderer-DwGlDNOV.mjs";
20
+ import "../renderer-BsMZ5Iaq.mjs";
21
+ import "../renderer-SJyp9-62.mjs";
22
+ import "../renderer-BPiWsrC2.mjs";
23
+ import "../renderer-CwlY8Tb-.mjs";
24
+ import "../renderer-Br8km655.mjs";
25
+ import "../renderer-BKi6jDi_.mjs";
26
+ import "../renderer-KgsVk9c6.mjs";
27
+ import "../renderer-Dz6P-rPI.mjs";
28
+ import "../renderer-BUj7jE6t.mjs";
29
+ import "../renderer-C1ctHdXl.mjs";
30
+ import "../renderer-BZgJj8Cl.mjs";
31
+ import "../renderer-RAq3LnNy.mjs";
32
+ import "../renderer-B-LUGB9h.mjs";
33
+ import "../renderer-BIieU9pY.mjs";
34
+ import "../renderer-DpZballM.mjs";
35
+ import "../renderer-CciiDHuU.mjs";
36
+ import "../renderer-CYwVNbUh.mjs";
37
+ import "../renderer-CE4535aW.mjs";
38
+ import "../renderer-B5b-ehRb.mjs";
39
+ import "../renderer-CQFMyC_c.mjs";
40
+ import "../renderer-BMpmmYOq.mjs";
41
+ import "../renderer-CuPAQjDK.mjs";
42
+ import "../renderer-CyUiXLRa.mjs";
43
+ import "../renderer-DXFJv_e6.mjs";
44
+ import "../renderer-opVuiAQR.mjs";
45
+ import "../renderer-dGEMVaZ3.mjs";
46
+ import "../renderer-Nnu32rqg.mjs";
47
+ import "../renderer-Dp5ChuOs.mjs";
48
+ import "../renderer-CZ5mwBW1.mjs";
49
+ import "../renderer-D-GWBoVT.mjs";
50
+ import { t as failedCheck } from "../check-result-DZWx73V8.mjs";
51
51
  import { existsSync } from "node:fs";
52
52
  import { join } from "node:path";
53
53
  import { mkdir, writeFile } from "node:fs/promises";
@@ -65,7 +65,7 @@ function checkLocalAssets(spec) {
65
65
  stage: "assets",
66
66
  path: path$1,
67
67
  ...layerId && { layerId },
68
- message: `Local asset '${source}' does not exist. Restore it or correct the source path relative to the project working directory.`
68
+ message: `Local asset '${source}' does not exist. Restore it (\`npx framefields assets pull\` when framefields.json pins it) or correct the source path relative to the project working directory.`
69
69
  });
70
70
  };
71
71
  for (const [i, font] of (spec.fonts ?? []).entries()) check(font, `fonts.${i}`);
@@ -1 +1 @@
1
- {"version":3,"file":"check-worker.mjs","names":["path"],"sources":["../../src/cli/check-assets.ts","../../src/cli/check-worker.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n\tCompositorProgramConfig,\n\tLayoutNode,\n} from \"@framefields/compositions/program\";\nimport type { CheckDiagnostic } from \"./check-result.js\";\n\n/** Local files only; remote availability and decoding belong to render checks. */\nexport function checkLocalAssets(\n\tspec: CompositorProgramConfig,\n): CheckDiagnostic[] {\n\tconst diagnostics: CheckDiagnostic[] = [];\n\tconst check = (source: string, path: string, layerId?: string) => {\n\t\tif (/^[a-z][a-z\\d+.-]*:/i.test(source) && !source.startsWith(\"file:\"))\n\t\t\treturn;\n\t\tconst file = source.startsWith(\"file:\") ? fileURLToPath(source) : source;\n\t\tif (!existsSync(file))\n\t\t\tdiagnostics.push({\n\t\t\t\tseverity: \"error\",\n\t\t\t\tcode: \"missing_local_asset\",\n\t\t\t\tstage: \"assets\",\n\t\t\t\tpath,\n\t\t\t\t...(layerId && { layerId }),\n\t\t\t\tmessage: `Local asset '${source}' does not exist. Restore it or correct the source path relative to the project working directory.`,\n\t\t\t});\n\t};\n\tfor (const [i, font] of (spec.fonts ?? []).entries())\n\t\tcheck(font, `fonts.${i}`);\n\tconst visit = (nodes: LayoutNode[], path: string) => {\n\t\tfor (const [i, node] of nodes.entries()) {\n\t\t\tconst location = `${path}.${i}`;\n\t\t\tif (node.kind === \"media\") {\n\t\t\t\tconst source = node.src ?? node.inputHandleId;\n\t\t\t\tif (\n\t\t\t\t\ttypeof source === \"string\" &&\n\t\t\t\t\t(node.src !== undefined || /[/.]/.test(source))\n\t\t\t\t)\n\t\t\t\t\tcheck(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\t`${location}.${node.src !== undefined ? \"src\" : \"inputHandleId\"}`,\n\t\t\t\t\t\tnode.id,\n\t\t\t\t\t);\n\t\t\t}\n\t\t\tif (\"children\" in node && Array.isArray(node.children))\n\t\t\t\tvisit(node.children, `${location}.children`);\n\t\t}\n\t};\n\tvisit(spec.layout, \"layout\");\n\treturn diagnostics;\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { frameCount } from \"@framefields/core\";\nimport { Composition, CompositorProgramSchema, describeGpu } from \"../index.js\";\nimport type { CheckOptions } from \"./check.js\";\nimport { checkLocalAssets } from \"./check-assets.js\";\nimport { type CheckReport, failedCheck } from \"./check-result.js\";\n\ntype WorkerOptions = CheckOptions & {\n\texportName: string;\n\tsdkVersion: string;\n\toutputDir: string;\n};\n\nasync function inspect(options: WorkerOptions): Promise<CheckReport> {\n\tconst report: CheckReport = {\n\t\tschemaVersion: 1,\n\t\tsdkVersion: options.sdkVersion,\n\t\tentry: options.entry,\n\t\texportName: options.exportName,\n\t\tstatus: \"passed\",\n\t\tdiagnostics: [],\n\t\tartifacts: [],\n\t\trender: options.render ? \"skipped\" : \"not_requested\",\n\t\truntime: {\n\t\t\tnode: process.version,\n\t\t\tplatform: process.platform,\n\t\t\tarch: process.arch,\n\t\t},\n\t};\n\tlet stage: \"build\" | \"schema\" | \"lint\" | \"timeline\" | \"render\" = \"build\";\n\ttry {\n\t\t// User-selected entry and export are necessarily loaded at runtime.\n\t\tconst mod: Record<string, unknown> = await import(\n\t\t\tpathToFileURL(options.entry).href\n\t\t);\n\t\tconst exported = mod[options.exportName];\n\t\tconst comp: unknown =\n\t\t\ttypeof exported === \"function\" ? await exported() : exported;\n\t\tif (!isComposition(comp))\n\t\t\tthrow new Error(\n\t\t\t\t`Export '${options.exportName}' must be a Composition or a builder returning one.`,\n\t\t\t);\n\t\tstage = \"schema\";\n\t\tconst spec = comp.toSpec();\n\t\tconst parsed = CompositorProgramSchema.safeParse(spec);\n\t\tif (!parsed.success) {\n\t\t\tfor (const issue of parsed.error.issues)\n\t\t\t\treport.diagnostics.push({\n\t\t\t\t\tseverity: \"error\",\n\t\t\t\t\tcode: \"invalid_spec\",\n\t\t\t\t\tstage,\n\t\t\t\t\tpath: issue.path.join(\".\"),\n\t\t\t\t\tmessage: issue.message,\n\t\t\t\t});\n\t\t} else {\n\t\t\tcomp.toVirtualMedia();\n\t\t\treport.diagnostics.push(...checkLocalAssets(parsed.data));\n\t\t\tstage = \"lint\";\n\t\t\treport.diagnostics.push(\n\t\t\t\t...comp.lint().map((d) => ({ ...d, stage: \"lint\" as const })),\n\t\t\t);\n\t\t\tstage = \"timeline\";\n\t\t\tconst durationMs = comp.durationMs ?? (await comp.computeDuration());\n\t\t\treport.timeline = {\n\t\t\t\tfps: comp.fps,\n\t\t\t\tdurationMs,\n\t\t\t\ttotalFrames: frameCount(durationMs, comp.fps),\n\t\t\t};\n\t\t\tif (options.render && !hasErrors(report)) {\n\t\t\t\tstage = \"render\";\n\t\t\t\treport.render = \"failed\";\n\t\t\t\treport.backend = await describeGpu();\n\t\t\t\tawait renderSmoke(comp, report, options.outputDir);\n\t\t\t\treport.render = \"passed\";\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\treport.diagnostics.push({\n\t\t\tseverity: \"error\",\n\t\t\tcode: `${stage}_failed`,\n\t\t\tstage,\n\t\t\tmessage:\n\t\t\t\terror instanceof Error ? (error.stack ?? error.message) : String(error),\n\t\t});\n\t}\n\tif (\n\t\thasErrors(report) ||\n\t\t(options.warningsAsErrors &&\n\t\t\treport.diagnostics.some((d) => d.severity === \"warning\"))\n\t)\n\t\treport.status = \"failed\";\n\treturn report;\n}\n\nfunction hasErrors(report: CheckReport): boolean {\n\treturn report.diagnostics.some((d) => d.severity === \"error\");\n}\n\n// Bundles can carry distinct Composition constructors; check its public contract.\nfunction isComposition(value: unknown): value is Composition {\n\treturn (\n\t\tvalue instanceof Composition ||\n\t\t(typeof value === \"object\" &&\n\t\t\tvalue !== null &&\n\t\t\t\"toSpec\" in value &&\n\t\t\ttypeof value.toSpec === \"function\" &&\n\t\t\t\"lint\" in value &&\n\t\t\ttypeof value.lint === \"function\" &&\n\t\t\t\"renderFrameGrid\" in value &&\n\t\t\ttypeof value.renderFrameGrid === \"function\" &&\n\t\t\t\"computeDuration\" in value &&\n\t\t\ttypeof value.computeDuration === \"function\")\n\t);\n}\n\nasync function renderSmoke(\n\tcomp: Composition,\n\treport: CheckReport,\n\toutputDir: string,\n): Promise<void> {\n\tconst count = report.timeline?.totalFrames ?? 1;\n\tconst frames = [...new Set([0, Math.floor((count - 1) / 2), count - 1])];\n\tawait mkdir(outputDir, { recursive: true });\n\tconst frameFile = join(outputDir, \"frame.png\");\n\tawait writeFile(frameFile, await comp.renderFrame({ frame: 0 }));\n\treport.artifacts.push(frameFile);\n\tconst gridFile = join(outputDir, \"grid.png\");\n\tawait writeFile(\n\t\tgridFile,\n\t\tawait comp.renderFrameGrid({ frames, cellWidth: 320 }),\n\t);\n\treport.artifacts.push(gridFile);\n}\n\nprocess.once(\"message\", (options: WorkerOptions) => {\n\tprocess.channel?.ref();\n\tinspect(options).then(\n\t\t(report) =>\n\t\t\tprocess.send?.(report, () =>\n\t\t\t\tprocess.exit(report.status === \"passed\" ? 0 : 1),\n\t\t\t),\n\t\t(error: unknown) => {\n\t\t\tconst report = failedCheck(\n\t\t\t\toptions.entry,\n\t\t\t\toptions.exportName,\n\t\t\t\toptions.sdkVersion,\n\t\t\t\t\"worker_failed\",\n\t\t\t\tString(error),\n\t\t\t);\n\t\t\tprocess.send?.(report, () => process.exit(1));\n\t\t},\n\t);\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"check-worker.mjs","names":["path"],"sources":["../../src/cli/check-assets.ts","../../src/cli/check-worker.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport type {\n\tCompositorProgramConfig,\n\tLayoutNode,\n} from \"@framefields/compositions/program\";\nimport type { CheckDiagnostic } from \"./check-result.js\";\n\n/** Local files only; remote availability and decoding belong to render checks. */\nexport function checkLocalAssets(\n\tspec: CompositorProgramConfig,\n): CheckDiagnostic[] {\n\tconst diagnostics: CheckDiagnostic[] = [];\n\tconst check = (source: string, path: string, layerId?: string) => {\n\t\tif (/^[a-z][a-z\\d+.-]*:/i.test(source) && !source.startsWith(\"file:\"))\n\t\t\treturn;\n\t\tconst file = source.startsWith(\"file:\") ? fileURLToPath(source) : source;\n\t\tif (!existsSync(file))\n\t\t\tdiagnostics.push({\n\t\t\t\tseverity: \"error\",\n\t\t\t\tcode: \"missing_local_asset\",\n\t\t\t\tstage: \"assets\",\n\t\t\t\tpath,\n\t\t\t\t...(layerId && { layerId }),\n\t\t\t\tmessage: `Local asset '${source}' does not exist. Restore it (\\`npx framefields assets pull\\` when framefields.json pins it) or correct the source path relative to the project working directory.`,\n\t\t\t});\n\t};\n\tfor (const [i, font] of (spec.fonts ?? []).entries())\n\t\tcheck(font, `fonts.${i}`);\n\tconst visit = (nodes: LayoutNode[], path: string) => {\n\t\tfor (const [i, node] of nodes.entries()) {\n\t\t\tconst location = `${path}.${i}`;\n\t\t\tif (node.kind === \"media\") {\n\t\t\t\tconst source = node.src ?? node.inputHandleId;\n\t\t\t\tif (\n\t\t\t\t\ttypeof source === \"string\" &&\n\t\t\t\t\t(node.src !== undefined || /[/.]/.test(source))\n\t\t\t\t)\n\t\t\t\t\tcheck(\n\t\t\t\t\t\tsource,\n\t\t\t\t\t\t`${location}.${node.src !== undefined ? \"src\" : \"inputHandleId\"}`,\n\t\t\t\t\t\tnode.id,\n\t\t\t\t\t);\n\t\t\t}\n\t\t\tif (\"children\" in node && Array.isArray(node.children))\n\t\t\t\tvisit(node.children, `${location}.children`);\n\t\t}\n\t};\n\tvisit(spec.layout, \"layout\");\n\treturn diagnostics;\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { frameCount } from \"@framefields/core\";\nimport { Composition, CompositorProgramSchema, describeGpu } from \"../index.js\";\nimport type { CheckOptions } from \"./check.js\";\nimport { checkLocalAssets } from \"./check-assets.js\";\nimport { type CheckReport, failedCheck } from \"./check-result.js\";\n\ntype WorkerOptions = CheckOptions & {\n\texportName: string;\n\tsdkVersion: string;\n\toutputDir: string;\n};\n\nasync function inspect(options: WorkerOptions): Promise<CheckReport> {\n\tconst report: CheckReport = {\n\t\tschemaVersion: 1,\n\t\tsdkVersion: options.sdkVersion,\n\t\tentry: options.entry,\n\t\texportName: options.exportName,\n\t\tstatus: \"passed\",\n\t\tdiagnostics: [],\n\t\tartifacts: [],\n\t\trender: options.render ? \"skipped\" : \"not_requested\",\n\t\truntime: {\n\t\t\tnode: process.version,\n\t\t\tplatform: process.platform,\n\t\t\tarch: process.arch,\n\t\t},\n\t};\n\tlet stage: \"build\" | \"schema\" | \"lint\" | \"timeline\" | \"render\" = \"build\";\n\ttry {\n\t\t// User-selected entry and export are necessarily loaded at runtime.\n\t\tconst mod: Record<string, unknown> = await import(\n\t\t\tpathToFileURL(options.entry).href\n\t\t);\n\t\tconst exported = mod[options.exportName];\n\t\tconst comp: unknown =\n\t\t\ttypeof exported === \"function\" ? await exported() : exported;\n\t\tif (!isComposition(comp))\n\t\t\tthrow new Error(\n\t\t\t\t`Export '${options.exportName}' must be a Composition or a builder returning one.`,\n\t\t\t);\n\t\tstage = \"schema\";\n\t\tconst spec = comp.toSpec();\n\t\tconst parsed = CompositorProgramSchema.safeParse(spec);\n\t\tif (!parsed.success) {\n\t\t\tfor (const issue of parsed.error.issues)\n\t\t\t\treport.diagnostics.push({\n\t\t\t\t\tseverity: \"error\",\n\t\t\t\t\tcode: \"invalid_spec\",\n\t\t\t\t\tstage,\n\t\t\t\t\tpath: issue.path.join(\".\"),\n\t\t\t\t\tmessage: issue.message,\n\t\t\t\t});\n\t\t} else {\n\t\t\tcomp.toVirtualMedia();\n\t\t\treport.diagnostics.push(...checkLocalAssets(parsed.data));\n\t\t\tstage = \"lint\";\n\t\t\treport.diagnostics.push(\n\t\t\t\t...comp.lint().map((d) => ({ ...d, stage: \"lint\" as const })),\n\t\t\t);\n\t\t\tstage = \"timeline\";\n\t\t\tconst durationMs = comp.durationMs ?? (await comp.computeDuration());\n\t\t\treport.timeline = {\n\t\t\t\tfps: comp.fps,\n\t\t\t\tdurationMs,\n\t\t\t\ttotalFrames: frameCount(durationMs, comp.fps),\n\t\t\t};\n\t\t\tif (options.render && !hasErrors(report)) {\n\t\t\t\tstage = \"render\";\n\t\t\t\treport.render = \"failed\";\n\t\t\t\treport.backend = await describeGpu();\n\t\t\t\tawait renderSmoke(comp, report, options.outputDir);\n\t\t\t\treport.render = \"passed\";\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\treport.diagnostics.push({\n\t\t\tseverity: \"error\",\n\t\t\tcode: `${stage}_failed`,\n\t\t\tstage,\n\t\t\tmessage:\n\t\t\t\terror instanceof Error ? (error.stack ?? error.message) : String(error),\n\t\t});\n\t}\n\tif (\n\t\thasErrors(report) ||\n\t\t(options.warningsAsErrors &&\n\t\t\treport.diagnostics.some((d) => d.severity === \"warning\"))\n\t)\n\t\treport.status = \"failed\";\n\treturn report;\n}\n\nfunction hasErrors(report: CheckReport): boolean {\n\treturn report.diagnostics.some((d) => d.severity === \"error\");\n}\n\n// Bundles can carry distinct Composition constructors; check its public contract.\nfunction isComposition(value: unknown): value is Composition {\n\treturn (\n\t\tvalue instanceof Composition ||\n\t\t(typeof value === \"object\" &&\n\t\t\tvalue !== null &&\n\t\t\t\"toSpec\" in value &&\n\t\t\ttypeof value.toSpec === \"function\" &&\n\t\t\t\"lint\" in value &&\n\t\t\ttypeof value.lint === \"function\" &&\n\t\t\t\"renderFrameGrid\" in value &&\n\t\t\ttypeof value.renderFrameGrid === \"function\" &&\n\t\t\t\"computeDuration\" in value &&\n\t\t\ttypeof value.computeDuration === \"function\")\n\t);\n}\n\nasync function renderSmoke(\n\tcomp: Composition,\n\treport: CheckReport,\n\toutputDir: string,\n): Promise<void> {\n\tconst count = report.timeline?.totalFrames ?? 1;\n\tconst frames = [...new Set([0, Math.floor((count - 1) / 2), count - 1])];\n\tawait mkdir(outputDir, { recursive: true });\n\tconst frameFile = join(outputDir, \"frame.png\");\n\tawait writeFile(frameFile, await comp.renderFrame({ frame: 0 }));\n\treport.artifacts.push(frameFile);\n\tconst gridFile = join(outputDir, \"grid.png\");\n\tawait writeFile(\n\t\tgridFile,\n\t\tawait comp.renderFrameGrid({ frames, cellWidth: 320 }),\n\t);\n\treport.artifacts.push(gridFile);\n}\n\nprocess.once(\"message\", (options: WorkerOptions) => {\n\tprocess.channel?.ref();\n\tinspect(options).then(\n\t\t(report) =>\n\t\t\tprocess.send?.(report, () =>\n\t\t\t\tprocess.exit(report.status === \"passed\" ? 0 : 1),\n\t\t\t),\n\t\t(error: unknown) => {\n\t\t\tconst report = failedCheck(\n\t\t\t\toptions.entry,\n\t\t\t\toptions.exportName,\n\t\t\t\toptions.sdkVersion,\n\t\t\t\t\"worker_failed\",\n\t\t\t\tString(error),\n\t\t\t);\n\t\t\tprocess.send?.(report, () => process.exit(1));\n\t\t},\n\t);\n});\n"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ //#region src/cli/local-worker.d.ts
2
+ interface LocalJob {
3
+ mode: "render" | "preview";
4
+ /** Absolute module path. */
5
+ entry: string;
6
+ export: string;
7
+ /** File URL of the project's framefields entry (for the preview). */
8
+ engine: string;
9
+ args?: unknown;
10
+ select?: string;
11
+ /** render: where the video goes. */
12
+ outputPath?: string;
13
+ codec?: string;
14
+ quality?: string;
15
+ /** preview: the page's title. */
16
+ title?: string;
17
+ }
18
+ type LocalResult = {
19
+ ok: true;
20
+ filePath?: string;
21
+ qaPassed?: boolean;
22
+ } | {
23
+ ok: false;
24
+ message: string;
25
+ };
26
+ //#endregion
27
+ export { LocalJob, LocalResult };
28
+ //# sourceMappingURL=local-worker.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-worker.d.mts","names":[],"sources":["../../src/cli/local-worker.ts"],"sourcesContent":[],"mappings":";UAeiB,QAAA;EAAA,IAAA,EAAA,QAAQ,GAAA,SAAA;EAiBb;;;;;;;;;;;;;;KAAA,WAAA"}
@@ -0,0 +1,83 @@
1
+ import { pathToFileURL } from "node:url";
2
+
3
+ //#region src/cli/pick-composition.ts
4
+ /**
5
+ * The composition an export yields, read the way the cloud worker reads it:
6
+ * a Composition, a function returning one (called with `args`), or several
7
+ * by name (a record, or `{ outputs: [{ name, composition }] }`) picked with
8
+ * `select`.
9
+ */
10
+ async function pickComposition(mod, job) {
11
+ if (!(job.export in mod)) throw new Error(`The module has no export named "${job.export}". Exports: ${Object.keys(mod).join(", ") || "none"}.`);
12
+ let value = mod[job.export];
13
+ if (typeof value === "function" && !isComposition(value)) value = await value(job.args);
14
+ if (isComposition(value)) return value;
15
+ const named = namedOutputs(value);
16
+ if (!named) throw new Error(`Export "${job.export}" must be a Composition, a function returning one, or compositions by name.`);
17
+ const names = Object.keys(named);
18
+ const pick = job.select ?? (names.length === 1 ? names[0] : void 0);
19
+ if (!pick || !named[pick]) throw new Error(`Export "${job.export}" returns several compositions (${names.join(", ")}): name one with "select".`);
20
+ return named[pick];
21
+ }
22
+ function namedOutputs(value) {
23
+ if (typeof value !== "object" || value === null) return void 0;
24
+ const outputs = value.outputs;
25
+ const entries = Array.isArray(outputs) ? outputs.map((o, i) => [o?.name ?? `output-${i}`, o?.composition]) : Object.entries(value);
26
+ if (!entries.length || !entries.every(([, c]) => isComposition(c))) return void 0;
27
+ return Object.fromEntries(entries);
28
+ }
29
+ /** Duck-typed: the project may load its own copy of framefields. */
30
+ function isComposition(value) {
31
+ return typeof value === "object" && value !== null && typeof value.renderVideo === "function" && typeof value.toSpec === "function";
32
+ }
33
+
34
+ //#endregion
35
+ //#region src/cli/local-worker.ts
36
+ /**
37
+ * Runs a render or a preview of the user's module in its own Node process
38
+ * (with the project's TypeScript loader), for `framefields render` and
39
+ * `framefields preview`. Its options arrive over IPC; it reports back over
40
+ * IPC and exits, since GPU and encoder threads keep Node alive otherwise.
41
+ *
42
+ * It uses the project's own framefields, as the cloud worker does: a second
43
+ * copy of the engine next to the one the film imports would not share its
44
+ * decoders.
45
+ */
46
+ async function run(job) {
47
+ if (job.mode === "preview") {
48
+ const session = await (await import(job.engine)).startPreview({
49
+ entry: job.entry,
50
+ export: job.export
51
+ }, { title: job.title });
52
+ process.stdout.write(`Preview at ${session.url}\n`);
53
+ await session.closed;
54
+ return { ok: true };
55
+ }
56
+ const result = await (await pickComposition(await import(pathToFileURL(job.entry).href), job)).renderVideo({
57
+ outputPath: job.outputPath,
58
+ ...job.codec && { codec: job.codec },
59
+ ...job.quality && { quality: job.quality },
60
+ qa: true
61
+ });
62
+ await result.cleanup?.();
63
+ if (result.qa) {
64
+ const engine = await import(job.engine);
65
+ process.stdout.write(`${engine.formatQaReport(result.qa)}\n`);
66
+ }
67
+ return {
68
+ ok: true,
69
+ filePath: result.filePath,
70
+ ...result.qa && { qaPassed: result.qa.passed }
71
+ };
72
+ }
73
+ process.once("message", (job) => {
74
+ process.channel?.ref();
75
+ run(job).then((result) => process.send?.(result, () => process.exit(0)), (error) => process.send?.({
76
+ ok: false,
77
+ message: error instanceof Error ? error.message : String(error)
78
+ }, () => process.exit(1)));
79
+ });
80
+
81
+ //#endregion
82
+ export { };
83
+ //# sourceMappingURL=local-worker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-worker.mjs","names":[],"sources":["../../src/cli/pick-composition.ts","../../src/cli/local-worker.ts"],"sourcesContent":["import type { Composition } from \"../index.js\";\n\nexport interface PickOptions {\n\texport: string;\n\targs?: unknown;\n\tselect?: string;\n}\n\n/**\n * The composition an export yields, read the way the cloud worker reads it:\n * a Composition, a function returning one (called with `args`), or several\n * by name (a record, or `{ outputs: [{ name, composition }] }`) picked with\n * `select`.\n */\nexport async function pickComposition(\n\tmod: Record<string, unknown>,\n\tjob: PickOptions,\n): Promise<Composition> {\n\tif (!(job.export in mod))\n\t\tthrow new Error(\n\t\t\t`The module has no export named \"${job.export}\". Exports: ${Object.keys(mod).join(\", \") || \"none\"}.`,\n\t\t);\n\tlet value = mod[job.export];\n\tif (typeof value === \"function\" && !isComposition(value))\n\t\tvalue = await (value as (args: unknown) => unknown)(job.args);\n\tif (isComposition(value)) return value;\n\tconst named = namedOutputs(value);\n\tif (!named)\n\t\tthrow new Error(\n\t\t\t`Export \"${job.export}\" must be a Composition, a function returning one, or compositions by name.`,\n\t\t);\n\tconst names = Object.keys(named);\n\tconst pick = job.select ?? (names.length === 1 ? names[0] : undefined);\n\tif (!pick || !named[pick])\n\t\tthrow new Error(\n\t\t\t`Export \"${job.export}\" returns several compositions (${names.join(\", \")}): name one with \"select\".`,\n\t\t);\n\treturn named[pick];\n}\n\nfunction namedOutputs(value: unknown): Record<string, Composition> | undefined {\n\tif (typeof value !== \"object\" || value === null) return undefined;\n\tconst outputs = (value as { outputs?: unknown }).outputs;\n\tconst entries = Array.isArray(outputs)\n\t\t? outputs.map((o: { name?: string; composition?: unknown }, i) => [\n\t\t\t\to?.name ?? `output-${i}`,\n\t\t\t\to?.composition,\n\t\t\t])\n\t\t: Object.entries(value);\n\tif (!entries.length || !entries.every(([, c]) => isComposition(c)))\n\t\treturn undefined;\n\treturn Object.fromEntries(entries) as Record<string, Composition>;\n}\n\n/** Duck-typed: the project may load its own copy of framefields. */\nfunction isComposition(value: unknown): value is Composition {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\ttypeof (value as Composition).renderVideo === \"function\" &&\n\t\ttypeof (value as Composition).toSpec === \"function\"\n\t);\n}\n","/**\n * Runs a render or a preview of the user's module in its own Node process\n * (with the project's TypeScript loader), for `framefields render` and\n * `framefields preview`. Its options arrive over IPC; it reports back over\n * IPC and exits, since GPU and encoder threads keep Node alive otherwise.\n *\n * It uses the project's own framefields, as the cloud worker does: a second\n * copy of the engine next to the one the film imports would not share its\n * decoders.\n */\nimport { pathToFileURL } from \"node:url\";\nimport type { formatQaReport } from \"../index.js\";\nimport type { startPreview } from \"../preview/index.js\";\nimport { pickComposition } from \"./pick-composition.js\";\n\nexport interface LocalJob {\n\tmode: \"render\" | \"preview\";\n\t/** Absolute module path. */\n\tentry: string;\n\texport: string;\n\t/** File URL of the project's framefields entry (for the preview). */\n\tengine: string;\n\targs?: unknown;\n\tselect?: string;\n\t/** render: where the video goes. */\n\toutputPath?: string;\n\tcodec?: string;\n\tquality?: string;\n\t/** preview: the page's title. */\n\ttitle?: string;\n}\n\nexport type LocalResult =\n\t| { ok: true; filePath?: string; qaPassed?: boolean }\n\t| { ok: false; message: string };\n\nasync function run(job: LocalJob): Promise<LocalResult> {\n\tif (job.mode === \"preview\") {\n\t\t// The project's framefields: known only at runtime.\n\t\tconst engine = (await import(job.engine)) as {\n\t\t\tstartPreview: typeof startPreview;\n\t\t};\n\t\tconst session = await engine.startPreview(\n\t\t\t{ entry: job.entry, export: job.export },\n\t\t\t{ title: job.title },\n\t\t);\n\t\tprocess.stdout.write(`Preview at ${session.url}\\n`);\n\t\tawait session.closed;\n\t\treturn { ok: true };\n\t}\n\tconst mod: Record<string, unknown> = await import(\n\t\tpathToFileURL(job.entry).href\n\t);\n\tconst comp = await pickComposition(mod, job);\n\tconst result = await comp.renderVideo({\n\t\toutputPath: job.outputPath,\n\t\t...(job.codec && { codec: job.codec }),\n\t\t...(job.quality && { quality: job.quality }),\n\t\t// Dropped, black or frozen frames, loudness, clipping, truncated animations.\n\t\tqa: true,\n\t});\n\tawait result.cleanup?.();\n\tif (result.qa) {\n\t\tconst engine = (await import(job.engine)) as {\n\t\t\tformatQaReport: typeof formatQaReport;\n\t\t};\n\t\tprocess.stdout.write(`${engine.formatQaReport(result.qa)}\\n`);\n\t}\n\treturn {\n\t\tok: true,\n\t\tfilePath: result.filePath,\n\t\t...(result.qa && { qaPassed: result.qa.passed }),\n\t};\n}\n\nprocess.once(\"message\", (job: LocalJob) => {\n\tprocess.channel?.ref();\n\trun(job).then(\n\t\t(result) => process.send?.(result, () => process.exit(0)),\n\t\t(error: unknown) =>\n\t\t\tprocess.send?.(\n\t\t\t\t{\n\t\t\t\t\tok: false,\n\t\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\t} satisfies LocalResult,\n\t\t\t\t() => process.exit(1),\n\t\t\t),\n\t);\n});\n"],"mappings":";;;;;;;;;AAcA,eAAsB,gBACrB,KACA,KACuB;AACvB,KAAI,EAAE,IAAI,UAAU,KACnB,OAAM,IAAI,MACT,mCAAmC,IAAI,OAAO,cAAc,OAAO,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,OAAO,GAClG;CACF,IAAI,QAAQ,IAAI,IAAI;AACpB,KAAI,OAAO,UAAU,cAAc,CAAC,cAAc,MAAM,CACvD,SAAQ,MAAO,MAAqC,IAAI,KAAK;AAC9D,KAAI,cAAc,MAAM,CAAE,QAAO;CACjC,MAAM,QAAQ,aAAa,MAAM;AACjC,KAAI,CAAC,MACJ,OAAM,IAAI,MACT,WAAW,IAAI,OAAO,6EACtB;CACF,MAAM,QAAQ,OAAO,KAAK,MAAM;CAChC,MAAM,OAAO,IAAI,WAAW,MAAM,WAAW,IAAI,MAAM,KAAK;AAC5D,KAAI,CAAC,QAAQ,CAAC,MAAM,MACnB,OAAM,IAAI,MACT,WAAW,IAAI,OAAO,kCAAkC,MAAM,KAAK,KAAK,CAAC,4BACzE;AACF,QAAO,MAAM;;AAGd,SAAS,aAAa,OAAyD;AAC9E,KAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;CACxD,MAAM,UAAW,MAAgC;CACjD,MAAM,UAAU,MAAM,QAAQ,QAAQ,GACnC,QAAQ,KAAK,GAA6C,MAAM,CAChE,GAAG,QAAQ,UAAU,KACrB,GAAG,YACH,CAAC,GACD,OAAO,QAAQ,MAAM;AACxB,KAAI,CAAC,QAAQ,UAAU,CAAC,QAAQ,OAAO,GAAG,OAAO,cAAc,EAAE,CAAC,CACjE,QAAO;AACR,QAAO,OAAO,YAAY,QAAQ;;;AAInC,SAAS,cAAc,OAAsC;AAC5D,QACC,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAAsB,gBAAgB,cAC9C,OAAQ,MAAsB,WAAW;;;;;;;;;;;;;;;ACxB3C,eAAe,IAAI,KAAqC;AACvD,KAAI,IAAI,SAAS,WAAW;EAK3B,MAAM,UAAU,OAHA,MAAM,OAAO,IAAI,SAGJ,aAC5B;GAAE,OAAO,IAAI;GAAO,QAAQ,IAAI;GAAQ,EACxC,EAAE,OAAO,IAAI,OAAO,CACpB;AACD,UAAQ,OAAO,MAAM,cAAc,QAAQ,IAAI,IAAI;AACnD,QAAM,QAAQ;AACd,SAAO,EAAE,IAAI,MAAM;;CAMpB,MAAM,SAAS,OADF,MAAM,gBAHkB,MAAM,OAC1C,cAAc,IAAI,MAAM,CAAC,OAEc,IAAI,EAClB,YAAY;EACrC,YAAY,IAAI;EAChB,GAAI,IAAI,SAAS,EAAE,OAAO,IAAI,OAAO;EACrC,GAAI,IAAI,WAAW,EAAE,SAAS,IAAI,SAAS;EAE3C,IAAI;EACJ,CAAC;AACF,OAAM,OAAO,WAAW;AACxB,KAAI,OAAO,IAAI;EACd,MAAM,SAAU,MAAM,OAAO,IAAI;AAGjC,UAAQ,OAAO,MAAM,GAAG,OAAO,eAAe,OAAO,GAAG,CAAC,IAAI;;AAE9D,QAAO;EACN,IAAI;EACJ,UAAU,OAAO;EACjB,GAAI,OAAO,MAAM,EAAE,UAAU,OAAO,GAAG,QAAQ;EAC/C;;AAGF,QAAQ,KAAK,YAAY,QAAkB;AAC1C,SAAQ,SAAS,KAAK;AACtB,KAAI,IAAI,CAAC,MACP,WAAW,QAAQ,OAAO,cAAc,QAAQ,KAAK,EAAE,CAAC,GACxD,UACA,QAAQ,OACP;EACC,IAAI;EACJ,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;EAC/D,QACK,QAAQ,KAAK,EAAE,CACrB,CACF;EACA"}