framefields 2.9.3 → 2.10.0-canary.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.
- package/NOTICE.md +4 -0
- package/README.md +9 -2
- package/dist/audio/index.d.mts +5 -5
- package/dist/audio/index.mjs +13 -13
- package/dist/{audio-D6tBMbHh.d.mts → audio-1X5qNNmk.d.mts} +4 -4
- package/dist/{audio-D6tBMbHh.d.mts.map → audio-1X5qNNmk.d.mts.map} +1 -1
- package/dist/{audio-BlDbnteH.mjs → audio-KHBadECb.mjs} +1 -1
- package/dist/{audio-BlDbnteH.mjs.map → audio-KHBadECb.mjs.map} +1 -1
- package/dist/{audio-B6RmYOPe.mjs → audio-YpBRdI7r.mjs} +4 -4
- package/dist/{audio-B6RmYOPe.mjs.map → audio-YpBRdI7r.mjs.map} +1 -1
- package/dist/{check-result-Bj7g62ka.mjs → check-result-Culfu7Nx.mjs} +1 -1
- package/dist/{check-result-Bj7g62ka.mjs.map → check-result-Culfu7Nx.mjs.map} +1 -1
- package/dist/cli/check-worker.mjs +50 -50
- package/dist/cli.mjs +179 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/cloud/index.d.mts +118 -0
- package/dist/cloud/index.d.mts.map +1 -0
- package/dist/cloud/index.mjs +3 -0
- package/dist/cloud-xcfV4J03.mjs +233 -0
- package/dist/cloud-xcfV4J03.mjs.map +1 -0
- package/dist/components/index.d.mts +14 -14
- package/dist/components/index.mjs +47 -47
- package/dist/{dist-Dq5TkNDI.mjs → dist-2_lT3Dwc.mjs} +2 -2
- package/dist/{dist-Dq5TkNDI.mjs.map → dist-2_lT3Dwc.mjs.map} +1 -1
- package/dist/{dist-Cn8bDsQF.mjs → dist-BIE8fvlv.mjs} +1 -1
- package/dist/{dist-Cn8bDsQF.mjs.map → dist-BIE8fvlv.mjs.map} +1 -1
- package/dist/{dist-ByxHoMQI.mjs → dist-Bf2_efYP.mjs} +1 -1
- package/dist/{dist-ByxHoMQI.mjs.map → dist-Bf2_efYP.mjs.map} +1 -1
- package/dist/{dist-BlulwErl.mjs → dist-BwtxciN4.mjs} +1 -1
- package/dist/{dist-D12-a3-x.mjs → dist-C4Vxgm0Q.mjs} +275 -78
- package/dist/dist-C4Vxgm0Q.mjs.map +1 -0
- package/dist/{dist-DEUU6sNe.mjs → dist-Cu1fZ9Uy.mjs} +4 -4
- package/dist/{dist-DEUU6sNe.mjs.map → dist-Cu1fZ9Uy.mjs.map} +1 -1
- package/dist/{dist-DL1GwJvs.mjs → dist-CySGkG54.mjs} +2 -2
- package/dist/dist-CySGkG54.mjs.map +1 -0
- package/dist/effects/index.d.mts +6 -6
- package/dist/effects/index.mjs +36 -36
- package/dist/{effects-CViUoQSV.mjs → effects-DiWYouOK.mjs} +3 -3
- package/dist/{effects-CViUoQSV.mjs.map → effects-DiWYouOK.mjs.map} +1 -1
- package/dist/fonts/index.d.mts +1 -1
- package/dist/fonts/index.mjs +3 -3
- package/dist/{fonts-B0U2KO5I.mjs → fonts-BnV-GB1o.mjs} +2 -2
- package/dist/{fonts-B0U2KO5I.mjs.map → fonts-BnV-GB1o.mjs.map} +1 -1
- package/dist/{gpu-zFNrvhV9.mjs → gpu-Bw35AMwY.mjs} +11 -3
- package/dist/gpu-Bw35AMwY.mjs.map +1 -0
- package/dist/{index-Bzo1uj8h.d.mts → index-B7WqFBZA.d.mts} +33 -2
- package/dist/index-B7WqFBZA.d.mts.map +1 -0
- package/dist/{index-BuYtrhzL.d.mts → index-BW0Q1ygn.d.mts} +1 -1
- package/dist/{index-BuYtrhzL.d.mts.map → index-BW0Q1ygn.d.mts.map} +1 -1
- package/dist/{index-C6GcuYVA.d.mts → index-Bbv0VtxJ.d.mts} +6 -6
- package/dist/{index-C6GcuYVA.d.mts.map → index-Bbv0VtxJ.d.mts.map} +1 -1
- package/dist/{index-w28KUM9A.d.mts → index-CDQrdZ0J.d.mts} +3 -3
- package/dist/{index-w28KUM9A.d.mts.map → index-CDQrdZ0J.d.mts.map} +1 -1
- package/dist/{index-9_4X2ro1.d.mts → index-COYNQ_mf.d.mts} +1 -1
- package/dist/{index-9_4X2ro1.d.mts.map → index-COYNQ_mf.d.mts.map} +1 -1
- package/dist/{index-CgGM31I9.d.mts → index-CdCrae-I.d.mts} +2 -2
- package/dist/{index-CgGM31I9.d.mts.map → index-CdCrae-I.d.mts.map} +1 -1
- package/dist/{index-DBhswLMO.d.mts → index-DQa7mhzq.d.mts} +2 -2
- package/dist/{index-DBhswLMO.d.mts.map → index-DQa7mhzq.d.mts.map} +1 -1
- package/dist/{index-B9Lm1x8i.d.mts → index-Dyt4yS-x.d.mts} +376 -288
- package/dist/index-Dyt4yS-x.d.mts.map +1 -0
- package/dist/{index-svAgwTY_.d.mts → index-WwuuX8ZJ.d.mts} +25 -23
- package/dist/index-WwuuX8ZJ.d.mts.map +1 -0
- package/dist/{index-V0ZQ4JN6.d.mts → index-gOVtTm-P.d.mts} +125 -3
- package/dist/index-gOVtTm-P.d.mts.map +1 -0
- package/dist/{index-f4IF1vRH.d.mts → index-h7m8QgcL.d.mts} +3 -3
- package/dist/{index-f4IF1vRH.d.mts.map → index-h7m8QgcL.d.mts.map} +1 -1
- package/dist/index.d.mts +16 -16
- package/dist/index.mjs +59 -59
- package/dist/preview/index.d.mts +4 -4
- package/dist/preview/index.mjs +12 -12
- package/dist/{preview-ZKJ_zTmd.mjs → preview-BW7ilNWk.mjs} +3 -3
- package/dist/{preview-ZKJ_zTmd.mjs.map → preview-BW7ilNWk.mjs.map} +1 -1
- package/dist/preview-engine/audio.mjs +1 -1
- package/dist/preview-engine/chunk-44V4V5LD.mjs +1 -0
- package/dist/preview-engine/{chunk-5AWAOMBR.mjs → chunk-4BWBX2HM.mjs} +1 -1
- package/dist/preview-engine/{chunk-BEYA25UZ.mjs → chunk-4DSOZ5QG.mjs} +1 -1
- package/dist/preview-engine/{chunk-VVE2QHVG.mjs → chunk-4FACCLLE.mjs} +1 -1
- package/dist/preview-engine/{chunk-DMSZXG56.mjs → chunk-4N25ZU43.mjs} +1 -1
- package/dist/preview-engine/{chunk-FTCEG3SF.mjs → chunk-4RLKHFV6.mjs} +1 -1
- package/dist/preview-engine/chunk-4TPXZNVR.mjs +483 -0
- package/dist/preview-engine/chunk-4YT5YJIF.mjs +1 -0
- package/dist/preview-engine/{chunk-CC4NNNIY.mjs → chunk-57WXGYEV.mjs} +1 -1
- package/dist/preview-engine/{chunk-C4M3B2Q2.mjs → chunk-5SLBE2FX.mjs} +1 -1
- package/dist/preview-engine/{chunk-PM2W4VLT.mjs → chunk-5Y7SO37Q.mjs} +1 -1
- package/dist/preview-engine/{chunk-BJXNKMSY.mjs → chunk-64L4GUOF.mjs} +20 -6
- package/dist/preview-engine/{chunk-Y5K5LVOR.mjs → chunk-6BE3IL7L.mjs} +1 -1
- package/dist/preview-engine/{chunk-GA4HNR44.mjs → chunk-6LBFSGCI.mjs} +1 -1
- package/dist/preview-engine/{chunk-IB6GZJOL.mjs → chunk-6O55UROD.mjs} +1 -1
- package/dist/preview-engine/{chunk-SPJPM43P.mjs → chunk-6SLCECHG.mjs} +1 -1
- package/dist/preview-engine/chunk-77MT33VR.mjs +1 -0
- package/dist/preview-engine/{chunk-QCSVT73T.mjs → chunk-7A3BNAWY.mjs} +84 -25
- package/dist/preview-engine/{chunk-CN2VLYLB.mjs → chunk-7HW7GA76.mjs} +1 -1
- package/dist/preview-engine/chunk-A6OAPDIA.mjs +1 -0
- package/dist/preview-engine/chunk-ADLIF544.mjs +39 -0
- package/dist/preview-engine/{chunk-LVYVXVZO.mjs → chunk-C2GX5L5S.mjs} +1 -1
- package/dist/preview-engine/{chunk-4WYM72ZN.mjs → chunk-CHXR5XZK.mjs} +1 -1
- package/dist/preview-engine/chunk-CSLSWUUT.mjs +1 -0
- package/dist/preview-engine/{chunk-JSYG6OWZ.mjs → chunk-D7OMXGIZ.mjs} +1 -1
- package/dist/preview-engine/{chunk-RJIAES3X.mjs → chunk-EKEKYGXE.mjs} +1 -1
- package/dist/preview-engine/{chunk-TNJEZKXM.mjs → chunk-FH72KTSM.mjs} +1 -1
- package/dist/preview-engine/{chunk-P5FKRQFU.mjs → chunk-FW2UDDUT.mjs} +1 -1
- package/dist/preview-engine/{chunk-S2ABWY5G.mjs → chunk-GTMZOMAN.mjs} +1 -1
- package/dist/preview-engine/{chunk-6R3UJBL5.mjs → chunk-HGWT3RVQ.mjs} +10 -10
- package/dist/preview-engine/{chunk-34RJ7GAS.mjs → chunk-HKYENGC5.mjs} +1 -1
- package/dist/preview-engine/{chunk-7U34VKNO.mjs → chunk-HO7FXISJ.mjs} +1 -1
- package/dist/preview-engine/{chunk-73CNXGAK.mjs → chunk-HPQDCC4S.mjs} +1 -1
- package/dist/preview-engine/{chunk-ZY47XIRK.mjs → chunk-IVAA5X5H.mjs} +1 -1
- package/dist/preview-engine/chunk-JAAFSVAG.mjs +1 -0
- package/dist/preview-engine/{chunk-UXYM2G6J.mjs → chunk-JFBSNFN6.mjs} +1 -1
- package/dist/preview-engine/{chunk-GIICZZQI.mjs → chunk-JSKEVYKD.mjs} +1 -1
- package/dist/preview-engine/{chunk-EJJITH6U.mjs → chunk-K3TJJXVC.mjs} +1 -1
- package/dist/preview-engine/{chunk-GZWA5QJS.mjs → chunk-L2NTIWW5.mjs} +1 -1
- package/dist/preview-engine/{chunk-VN36PRVD.mjs → chunk-LBP7E7SJ.mjs} +1 -1
- package/dist/preview-engine/{chunk-34DL53D5.mjs → chunk-LTR5FXGU.mjs} +1 -1
- package/dist/preview-engine/{chunk-GRJJVSOV.mjs → chunk-ML7WO27M.mjs} +1 -1
- package/dist/preview-engine/{chunk-GN3NDRLI.mjs → chunk-NCQHOGZK.mjs} +1 -1
- package/dist/preview-engine/{chunk-OH5W5EL6.mjs → chunk-NTTEGJD6.mjs} +1 -1
- package/dist/preview-engine/{chunk-2B722GXM.mjs → chunk-OD4CSXZL.mjs} +15 -15
- package/dist/preview-engine/{chunk-AHQCDTD6.mjs → chunk-OOUDE4XL.mjs} +1 -1
- package/dist/preview-engine/chunk-PH3UUX6A.mjs +138 -0
- package/dist/preview-engine/chunk-PIHG6HJO.mjs +1 -0
- package/dist/preview-engine/{chunk-ZJ5SWTCW.mjs → chunk-RAW2I27S.mjs} +1 -1
- package/dist/preview-engine/{chunk-BJV2LBII.mjs → chunk-RMHL4XZ3.mjs} +1 -1
- package/dist/preview-engine/chunk-T6L3DO3H.mjs +1 -0
- package/dist/preview-engine/{chunk-2PYTDN2C.mjs → chunk-V5HU6NIW.mjs} +1 -1
- package/dist/preview-engine/{chunk-DVZITDQS.mjs → chunk-VRJBOFFY.mjs} +1 -1
- package/dist/preview-engine/{chunk-SF37HXAH.mjs → chunk-WVIDORLK.mjs} +1 -1
- package/dist/preview-engine/{chunk-35HMRW4I.mjs → chunk-XCQ7KN4S.mjs} +1 -1
- package/dist/preview-engine/{chunk-KHJZMTOS.mjs → chunk-Y2SWIWIU.mjs} +1 -1
- package/dist/preview-engine/{chunk-H7BSN7V7.mjs → chunk-YS3ROS25.mjs} +1 -1
- package/dist/preview-engine/{chunk-2DWY7UBV.mjs → chunk-YXCTOCQ2.mjs} +1 -1
- package/dist/preview-engine/{chunk-BVDWS3D2.mjs → chunk-ZA5LWHRM.mjs} +1 -1
- package/dist/preview-engine/chunk-ZGEKF34E.mjs +1974 -0
- package/dist/preview-engine/components.mjs +1 -1
- package/dist/preview-engine/effects.mjs +1 -1
- package/dist/preview-engine/fonts.mjs +1 -1
- package/dist/preview-engine/framefields.mjs +1 -1
- package/dist/preview-engine/player.mjs +1 -1
- package/dist/preview-engine/renderers-33PIDDZC.mjs +1 -0
- package/dist/preview-engine/{renderers-ZACSHGNZ.mjs → renderers-36P2TKPC.mjs} +1 -1
- package/dist/preview-engine/{renderers-TSBV4KPE.mjs → renderers-37Y5LR2S.mjs} +1 -1
- package/dist/preview-engine/renderers-3AZ3HY53.mjs +1 -0
- package/dist/preview-engine/renderers-3FGKW52B.mjs +1 -0
- package/dist/preview-engine/renderers-4A2FBS3Y.mjs +1 -0
- package/dist/preview-engine/{renderers-5TO2SXFR.mjs → renderers-4MW4NW6O.mjs} +1 -1
- package/dist/preview-engine/{renderers-ENMY4DKF.mjs → renderers-4SNAK77B.mjs} +1 -1
- package/dist/preview-engine/{renderers-Y22VSOXF.mjs → renderers-4WFRXGMR.mjs} +1 -1
- package/dist/preview-engine/{renderers-5KANN7XF.mjs → renderers-5K3BSBI6.mjs} +1 -1
- package/dist/preview-engine/renderers-65DU2F5W.mjs +1 -0
- package/dist/preview-engine/renderers-6CTPYQR6.mjs +1 -0
- package/dist/preview-engine/{renderers-NUAI4TO5.mjs → renderers-6RRWA33X.mjs} +1 -1
- package/dist/preview-engine/{renderers-4F7WLQD5.mjs → renderers-6RYIPQ7W.mjs} +1 -1
- package/dist/preview-engine/{renderers-U4M7ZCV4.mjs → renderers-AUYCQNSS.mjs} +1 -1
- package/dist/preview-engine/renderers-AWODRI3B.mjs +1 -0
- package/dist/preview-engine/renderers-BO6HHGMZ.mjs +1 -0
- package/dist/preview-engine/renderers-BSXYDEV7.mjs +1 -0
- package/dist/preview-engine/{renderers-FSI5KNGZ.mjs → renderers-CMBI4JOC.mjs} +1 -1
- package/dist/preview-engine/{renderers-6Z7DWAPH.mjs → renderers-CQIPHCIW.mjs} +1 -1
- package/dist/preview-engine/renderers-DU7KPFVV.mjs +1 -0
- package/dist/preview-engine/renderers-ECW2CGNU.mjs +1 -0
- package/dist/preview-engine/renderers-EEX22FUO.mjs +1 -0
- package/dist/preview-engine/{renderers-MOEC2XZZ.mjs → renderers-EILFSWSJ.mjs} +1 -1
- package/dist/preview-engine/{renderers-NCGH2WWJ.mjs → renderers-G2FL3IFD.mjs} +1 -1
- package/dist/preview-engine/{renderers-5XRKZHVT.mjs → renderers-GCQKGJ7W.mjs} +1 -1
- package/dist/preview-engine/{renderers-77PDUMYI.mjs → renderers-HXNSDJBY.mjs} +1 -1
- package/dist/preview-engine/renderers-HZBXLDKG.mjs +1 -0
- package/dist/preview-engine/renderers-IOXNQPQK.mjs +1 -0
- package/dist/preview-engine/renderers-IR44E4ZZ.mjs +1 -0
- package/dist/preview-engine/{renderers-TGJSOKDY.mjs → renderers-JALV3B3A.mjs} +1 -1
- package/dist/preview-engine/{renderers-IHGAWLUF.mjs → renderers-JMSAW7VY.mjs} +1 -1
- package/dist/preview-engine/{renderers-CUMVIVHI.mjs → renderers-JZYHX4XI.mjs} +1 -1
- package/dist/preview-engine/renderers-JZZ3ODOZ.mjs +1 -0
- package/dist/preview-engine/renderers-K37YL3Z7.mjs +1 -0
- package/dist/preview-engine/{renderers-RN2MHIFK.mjs → renderers-KICDB5Y6.mjs} +1 -1
- package/dist/preview-engine/renderers-KUJQV3K6.mjs +1 -0
- package/dist/preview-engine/renderers-KXVKLSSX.mjs +1 -0
- package/dist/preview-engine/{renderers-WEYAHOBK.mjs → renderers-LF6U4MR5.mjs} +1 -1
- package/dist/preview-engine/renderers-N4RVFX3G.mjs +1 -0
- package/dist/preview-engine/{renderers-PPZK6VEW.mjs → renderers-NQC4DPX4.mjs} +1 -1
- package/dist/preview-engine/renderers-NZWWEAYA.mjs +1 -0
- package/dist/preview-engine/{renderers-5UZ3YFBD.mjs → renderers-OPRXVIGT.mjs} +1 -1
- package/dist/preview-engine/{renderers-7C5RA3R5.mjs → renderers-OZKPOUMW.mjs} +1 -1
- package/dist/preview-engine/renderers-P4JJEDZB.mjs +1 -0
- package/dist/preview-engine/{renderers-V3AQO7AR.mjs → renderers-PGZDFDSC.mjs} +1 -1
- package/dist/preview-engine/renderers-Q4572F5C.mjs +1 -0
- package/dist/preview-engine/{renderers-PIIEUKFE.mjs → renderers-Q5YCUPYE.mjs} +1 -1
- package/dist/preview-engine/renderers-QAX2QWWQ.mjs +1 -0
- package/dist/preview-engine/{renderers-SEIAUKJF.mjs → renderers-RQ3JZE3L.mjs} +1 -1
- package/dist/preview-engine/renderers-SRFIEVWL.mjs +1 -0
- package/dist/preview-engine/renderers-SYC6WFTM.mjs +1 -0
- package/dist/preview-engine/{renderers-QA2HKUJJ.mjs → renderers-TKHQRERE.mjs} +1 -1
- package/dist/preview-engine/{renderers-A24KZK2Q.mjs → renderers-U4S577ON.mjs} +1 -1
- package/dist/preview-engine/{renderers-KC6ZSKCW.mjs → renderers-UBIFSF37.mjs} +1 -1
- package/dist/preview-engine/renderers-UH4WN3QN.mjs +1 -0
- package/dist/preview-engine/renderers-V4FFCAS7.mjs +1 -0
- package/dist/preview-engine/renderers-VGDEOZUU.mjs +1 -0
- package/dist/preview-engine/renderers-VJJKBX5K.mjs +1 -0
- package/dist/preview-engine/renderers-VJOKVDYW.mjs +1 -0
- package/dist/preview-engine/renderers-VUUWZUOH.mjs +1 -0
- package/dist/preview-engine/renderers-WG756VF3.mjs +228 -0
- package/dist/preview-engine/renderers-WOP5GOZP.mjs +1 -0
- package/dist/preview-engine/{renderers-T74CQCEN.mjs → renderers-XZ3XDQIN.mjs} +1 -1
- package/dist/preview-engine/renderers-Y4MGN2FR.mjs +1 -0
- package/dist/preview-engine/renderers-YAMYH7IK.mjs +1 -0
- package/dist/preview-engine/{renderers-MD3PRFZL.mjs → renderers-YJ4PJEPG.mjs} +1 -1
- package/dist/preview-engine/renderers-ZNLSAWW3.mjs +1 -0
- package/dist/preview-engine/{renderers-L6YDX6GS.mjs → renderers-ZQVKE5AO.mjs} +1 -1
- package/dist/preview-engine/signals.mjs +1 -1
- package/dist/preview-engine/{src-4IUYUKIZ.mjs → src-GPF7RIBU.mjs} +1 -1
- package/dist/{program-xjIwjKb6.mjs → program-BUjUTdxq.mjs} +44 -17
- package/dist/program-BUjUTdxq.mjs.map +1 -0
- package/dist/registry/focus-zoom.json +9 -2
- package/dist/renderer/index.d.mts +4 -4
- package/dist/renderer/index.mjs +4 -4
- package/dist/{renderer-B3IRvukr.mjs → renderer--f8JHHyT.mjs} +5 -5
- package/dist/{renderer-B3IRvukr.mjs.map → renderer--f8JHHyT.mjs.map} +1 -1
- package/dist/{renderer-BWMzjSgf.mjs → renderer-1KgHl_ls.mjs} +5 -5
- package/dist/{renderer-BWMzjSgf.mjs.map → renderer-1KgHl_ls.mjs.map} +1 -1
- package/dist/renderer-6sNr6ZRJ.mjs +6 -0
- package/dist/{renderer-CpedZNEG.mjs → renderer-7c0ecb-L.mjs} +74 -21
- package/dist/renderer-7c0ecb-L.mjs.map +1 -0
- package/dist/{renderer-B78W9uad.mjs → renderer-7w9PZmWJ.mjs} +4 -4
- package/dist/{renderer-B78W9uad.mjs.map → renderer-7w9PZmWJ.mjs.map} +1 -1
- package/dist/{renderer-CDVb4OfJ.mjs → renderer-B3WHDQeB.mjs} +5 -5
- package/dist/{renderer-CDVb4OfJ.mjs.map → renderer-B3WHDQeB.mjs.map} +1 -1
- package/dist/{renderer-BG6bkKtY.mjs → renderer-B84T5I98.mjs} +5 -5
- package/dist/{renderer-BG6bkKtY.mjs.map → renderer-B84T5I98.mjs.map} +1 -1
- package/dist/{renderer-CXLugAe8.mjs → renderer-B8i4d1Rc.mjs} +4 -4
- package/dist/{renderer-CXLugAe8.mjs.map → renderer-B8i4d1Rc.mjs.map} +1 -1
- package/dist/renderer-BDHGxD6p.mjs +5 -0
- package/dist/{renderer-ESkPj6pk.mjs → renderer-BFmVDdVs.mjs} +4 -4
- package/dist/{renderer-ESkPj6pk.mjs.map → renderer-BFmVDdVs.mjs.map} +1 -1
- package/dist/{renderer-CwVbHki6.mjs → renderer-BG_cnGbF.mjs} +5 -5
- package/dist/{renderer-CwVbHki6.mjs.map → renderer-BG_cnGbF.mjs.map} +1 -1
- package/dist/{renderer-B7kOF_Az.mjs → renderer-BIToh0CA.mjs} +3 -3
- package/dist/{renderer-B7kOF_Az.mjs.map → renderer-BIToh0CA.mjs.map} +1 -1
- package/dist/{renderer-DrWeb39d.mjs → renderer-BOg8i8eF.mjs} +11 -2
- package/dist/{renderer-DrWeb39d.mjs.map → renderer-BOg8i8eF.mjs.map} +1 -1
- package/dist/{renderer-HnSiwSW8.mjs → renderer-BSW4CGZF.mjs} +4 -4
- package/dist/{renderer-HnSiwSW8.mjs.map → renderer-BSW4CGZF.mjs.map} +1 -1
- package/dist/{renderer-BPYIqtNg.mjs → renderer-BT4im6c0.mjs} +5 -5
- package/dist/{renderer-BPYIqtNg.mjs.map → renderer-BT4im6c0.mjs.map} +1 -1
- package/dist/renderer-BT9dvpk2.mjs +5 -0
- package/dist/{renderer-BgDLCCuq.mjs → renderer-BTLZBD63.mjs} +5 -5
- package/dist/{renderer-BgDLCCuq.mjs.map → renderer-BTLZBD63.mjs.map} +1 -1
- package/dist/{renderer-CUBDxuxh.mjs → renderer-Bb_HHUQ0.mjs} +5 -5
- package/dist/{renderer-CUBDxuxh.mjs.map → renderer-Bb_HHUQ0.mjs.map} +1 -1
- package/dist/renderer-Bd-NuU3M.mjs +3 -0
- package/dist/{renderer-C7MAqpIS.mjs → renderer-BdRwbLLV.mjs} +4 -4
- package/dist/{renderer-C7MAqpIS.mjs.map → renderer-BdRwbLLV.mjs.map} +1 -1
- package/dist/{renderer-DIEmK57T.mjs → renderer-BeJoW-nG.mjs} +5 -5
- package/dist/{renderer-DIEmK57T.mjs.map → renderer-BeJoW-nG.mjs.map} +1 -1
- package/dist/renderer-BfaRh0qy.mjs +5 -0
- package/dist/{renderer-AUK_ZS3p.mjs → renderer-BhNZn2DU.mjs} +4 -4
- package/dist/{renderer-AUK_ZS3p.mjs.map → renderer-BhNZn2DU.mjs.map} +1 -1
- package/dist/{renderer-BcO7LUla.mjs → renderer-Bif8bwCq.mjs} +3 -3
- package/dist/{renderer-BcO7LUla.mjs.map → renderer-Bif8bwCq.mjs.map} +1 -1
- package/dist/renderer-BlwXKV7Y.mjs +5 -0
- package/dist/{renderer-BZmmekE8.mjs → renderer-Bm91Xv6l.mjs} +4 -4
- package/dist/{renderer-BZmmekE8.mjs.map → renderer-Bm91Xv6l.mjs.map} +1 -1
- package/dist/{renderer-mQt-y49D.mjs → renderer-BnN3JH9u.mjs} +20 -7
- package/dist/renderer-BnN3JH9u.mjs.map +1 -0
- package/dist/{renderer-C_2UDMEG.mjs → renderer-Bo5GwErU.mjs} +6 -6
- package/dist/{renderer-C_2UDMEG.mjs.map → renderer-Bo5GwErU.mjs.map} +1 -1
- package/dist/{renderer-Cl8r1LJe.mjs → renderer-Br_aJ_b7.mjs} +4 -4
- package/dist/{renderer-Cl8r1LJe.mjs.map → renderer-Br_aJ_b7.mjs.map} +1 -1
- package/dist/{renderer-Dee8ksIV.mjs → renderer-BvRaVByi.mjs} +3 -3
- package/dist/{renderer-Dee8ksIV.mjs.map → renderer-BvRaVByi.mjs.map} +1 -1
- package/dist/renderer-C40yZK3x.mjs +5 -0
- package/dist/renderer-C5MjQ7L8.mjs +5 -0
- package/dist/renderer-C8LjKYnS.mjs +5 -0
- package/dist/renderer-C9q9H_qa.mjs +5 -0
- package/dist/renderer-CC4fhNup.mjs +3 -0
- package/dist/{renderer-BRWjLiHX.mjs → renderer-CDfCaqV4.mjs} +3 -3
- package/dist/{renderer-BRWjLiHX.mjs.map → renderer-CDfCaqV4.mjs.map} +1 -1
- package/dist/renderer-CF9ta9Rm.mjs +5 -0
- package/dist/{renderer-BNbMi9CI.mjs → renderer-CKlNHDKI.mjs} +5 -5
- package/dist/{renderer-BNbMi9CI.mjs.map → renderer-CKlNHDKI.mjs.map} +1 -1
- package/dist/{renderer-D1VsqFf4.mjs → renderer-CLRrcT_3.mjs} +5 -5
- package/dist/{renderer-D1VsqFf4.mjs.map → renderer-CLRrcT_3.mjs.map} +1 -1
- package/dist/{renderer-CEfVvcw-.mjs → renderer-CO1PwItH.mjs} +4 -4
- package/dist/{renderer-CEfVvcw-.mjs.map → renderer-CO1PwItH.mjs.map} +1 -1
- package/dist/renderer-CO205Gr9.mjs +5 -0
- package/dist/renderer-CSm8UXLP.mjs +5 -0
- package/dist/renderer-CSy8HRtF.mjs +5 -0
- package/dist/{renderer-BYqrtBvd.mjs → renderer-CTSvHf6g.mjs} +5 -5
- package/dist/{renderer-BYqrtBvd.mjs.map → renderer-CTSvHf6g.mjs.map} +1 -1
- package/dist/{renderer-eT7Gp7FS.mjs → renderer-CWmlfdLb.mjs} +5 -5
- package/dist/{renderer-eT7Gp7FS.mjs.map → renderer-CWmlfdLb.mjs.map} +1 -1
- package/dist/{renderer-Dat8opUZ.mjs → renderer-CanNjQuL.mjs} +4 -4
- package/dist/{renderer-Dat8opUZ.mjs.map → renderer-CanNjQuL.mjs.map} +1 -1
- package/dist/renderer-CdNRWDsA.mjs +5 -0
- package/dist/{renderer-NTCk1Srf.mjs → renderer-CeNAgCE2.mjs} +3 -3
- package/dist/{renderer-NTCk1Srf.mjs.map → renderer-CeNAgCE2.mjs.map} +1 -1
- package/dist/{renderer-CcJyD9Q5.mjs → renderer-Ch1qZ2PT.mjs} +4 -4
- package/dist/{renderer-CcJyD9Q5.mjs.map → renderer-Ch1qZ2PT.mjs.map} +1 -1
- package/dist/{renderer-g7fF2AYk.mjs → renderer-Chfo4G9t.mjs} +5 -5
- package/dist/{renderer-g7fF2AYk.mjs.map → renderer-Chfo4G9t.mjs.map} +1 -1
- package/dist/{renderer-DIqkhsLI.mjs → renderer-Ck-NLzz0.mjs} +4 -4
- package/dist/{renderer-DIqkhsLI.mjs.map → renderer-Ck-NLzz0.mjs.map} +1 -1
- package/dist/renderer-CkAjiGRB.mjs +5 -0
- package/dist/renderer-CmryuPBm.mjs +5 -0
- package/dist/renderer-CnEwne4L.mjs +5 -0
- package/dist/{renderer-BdbI_u9w.mjs → renderer-CsRuEpR2.mjs} +3 -3
- package/dist/{renderer-BdbI_u9w.mjs.map → renderer-CsRuEpR2.mjs.map} +1 -1
- package/dist/{renderer-C4yKI8MT.mjs → renderer-CtulmkqT.mjs} +3 -3
- package/dist/{renderer-C4yKI8MT.mjs.map → renderer-CtulmkqT.mjs.map} +1 -1
- package/dist/{renderer-CyCtm0UV.mjs → renderer-CwAuWLWm.mjs} +3 -3
- package/dist/{renderer-CyCtm0UV.mjs.map → renderer-CwAuWLWm.mjs.map} +1 -1
- package/dist/{renderer-CbhnJi_8.mjs → renderer-CxabOSkk.mjs} +4 -4
- package/dist/{renderer-CbhnJi_8.mjs.map → renderer-CxabOSkk.mjs.map} +1 -1
- package/dist/{renderer-Be5hfwSd.mjs → renderer-CybBR8AL.mjs} +425 -115
- package/dist/renderer-CybBR8AL.mjs.map +1 -0
- package/dist/{renderer-B6TjJi1g.mjs → renderer-D1tDMuD0.mjs} +5 -5
- package/dist/{renderer-B6TjJi1g.mjs.map → renderer-D1tDMuD0.mjs.map} +1 -1
- package/dist/renderer-D4QDoqOG.mjs +5 -0
- package/dist/{renderer-5qJPGvVL.mjs → renderer-D7DlNOVi.mjs} +5 -5
- package/dist/{renderer-5qJPGvVL.mjs.map → renderer-D7DlNOVi.mjs.map} +1 -1
- package/dist/renderer-D7cS2a8z.mjs +5 -0
- package/dist/{renderer-C06U4c9k.mjs → renderer-D7lApyWZ.mjs} +3 -3
- package/dist/{renderer-C06U4c9k.mjs.map → renderer-D7lApyWZ.mjs.map} +1 -1
- package/dist/renderer-D85CNC-b.mjs +5 -0
- package/dist/{renderer-BJQt0RiZ.mjs → renderer-DAfCcnCz.mjs} +5 -5
- package/dist/{renderer-BJQt0RiZ.mjs.map → renderer-DAfCcnCz.mjs.map} +1 -1
- package/dist/{renderer-C3Iev6zu.mjs → renderer-DAug14gu.mjs} +4 -4
- package/dist/{renderer-C3Iev6zu.mjs.map → renderer-DAug14gu.mjs.map} +1 -1
- package/dist/{renderer-F1D9ZJ8I.mjs → renderer-DBfx6QX1.mjs} +3 -3
- package/dist/renderer-DC9IoJNz.mjs +5 -0
- package/dist/{renderer-CWLF6cAz.mjs → renderer-DCMoBppL.mjs} +58 -4
- package/dist/renderer-DCMoBppL.mjs.map +1 -0
- package/dist/renderer-DIDh0gFm.mjs +5 -0
- package/dist/{renderer-B-inTgyb.d.mts → renderer-DJuVX3c5.d.mts} +2 -2
- package/dist/{renderer-B-inTgyb.d.mts.map → renderer-DJuVX3c5.d.mts.map} +1 -1
- package/dist/{renderer-xDV2cCkX.mjs → renderer-DKptrHeL.mjs} +5 -5
- package/dist/{renderer-xDV2cCkX.mjs.map → renderer-DKptrHeL.mjs.map} +1 -1
- package/dist/renderer-DLmJ9GWE.mjs +5 -0
- package/dist/renderer-DM7PUWP9.mjs +5 -0
- package/dist/{renderer-Du-GnKLb.mjs → renderer-DMtzPqYo.mjs} +211 -72
- package/dist/renderer-DMtzPqYo.mjs.map +1 -0
- package/dist/renderer-DPWFDxIO.mjs +5 -0
- package/dist/renderer-DUCByhAk.mjs +5 -0
- package/dist/renderer-DVOtnCKH.mjs +5 -0
- package/dist/renderer-DVrN2bW8.mjs +5 -0
- package/dist/{renderer-VhkubIx_.mjs → renderer-D_rEtJAH.mjs} +5 -5
- package/dist/{renderer-VhkubIx_.mjs.map → renderer-D_rEtJAH.mjs.map} +1 -1
- package/dist/{renderer-q4zMFfnY.mjs → renderer-Dak_wVh9.mjs} +2 -2
- package/dist/{renderer-q4zMFfnY.mjs.map → renderer-Dak_wVh9.mjs.map} +1 -1
- package/dist/{renderer-DOKHd37M.mjs → renderer-Dd2XrdqA.mjs} +4 -4
- package/dist/{renderer-DOKHd37M.mjs.map → renderer-Dd2XrdqA.mjs.map} +1 -1
- package/dist/renderer-DdOVwfG4.mjs +5 -0
- package/dist/{renderer-IQ97z2rw.mjs → renderer-Dih1rtT6.mjs} +3 -3
- package/dist/{renderer-IQ97z2rw.mjs.map → renderer-Dih1rtT6.mjs.map} +1 -1
- package/dist/{renderer-DW7hbluw.mjs → renderer-DjiebKHO.mjs} +3 -3
- package/dist/{renderer-DW7hbluw.mjs.map → renderer-DjiebKHO.mjs.map} +1 -1
- package/dist/{renderer-bbaMOD4I.mjs → renderer-DkAFIpzB.mjs} +5 -5
- package/dist/{renderer-bbaMOD4I.mjs.map → renderer-DkAFIpzB.mjs.map} +1 -1
- package/dist/{renderer-BQOeeXTr.mjs → renderer-DlbSqOJR.mjs} +5 -5
- package/dist/{renderer-BQOeeXTr.mjs.map → renderer-DlbSqOJR.mjs.map} +1 -1
- package/dist/{renderer-CYX9vKZ-.mjs → renderer-DrExCXnp.mjs} +4 -4
- package/dist/{renderer-CYX9vKZ-.mjs.map → renderer-DrExCXnp.mjs.map} +1 -1
- package/dist/{renderer-BVql26Ay.mjs → renderer-DsPLMzy1.mjs} +2 -2
- package/dist/{renderer-BVql26Ay.mjs.map → renderer-DsPLMzy1.mjs.map} +1 -1
- package/dist/{renderer-BfbSvElt.mjs → renderer-Dswrn-yi.mjs} +4 -4
- package/dist/{renderer-BfbSvElt.mjs.map → renderer-Dswrn-yi.mjs.map} +1 -1
- package/dist/renderer-DtCe9ouu.mjs +5 -0
- package/dist/{renderer-sPI7aY6c.mjs → renderer-DtCmG-tT.mjs} +4 -4
- package/dist/{renderer-sPI7aY6c.mjs.map → renderer-DtCmG-tT.mjs.map} +1 -1
- package/dist/{renderer-BJKzZwyn.mjs → renderer-DxiF4O6X.mjs} +4 -4
- package/dist/{renderer-BJKzZwyn.mjs.map → renderer-DxiF4O6X.mjs.map} +1 -1
- package/dist/{renderer-CCFHnafT.mjs → renderer-DxkvDAA6.mjs} +4 -4
- package/dist/{renderer-CCFHnafT.mjs.map → renderer-DxkvDAA6.mjs.map} +1 -1
- package/dist/{renderer-CPTXJs0n.mjs → renderer-FFLnACY-.mjs} +6 -6
- package/dist/{renderer-CPTXJs0n.mjs.map → renderer-FFLnACY-.mjs.map} +1 -1
- package/dist/{renderer-US4GsamT.mjs → renderer-H4CZt3Z5.mjs} +3 -3
- package/dist/{renderer-mLlgfM7X.mjs → renderer-JASAZUyY.mjs} +4 -4
- package/dist/{renderer-mLlgfM7X.mjs.map → renderer-JASAZUyY.mjs.map} +1 -1
- package/dist/renderer-Mg0kr9Fm.mjs +5 -0
- package/dist/{renderer-D2TTDcgh.mjs → renderer-R2kLaNuR.mjs} +3 -3
- package/dist/{renderer-D2TTDcgh.mjs.map → renderer-R2kLaNuR.mjs.map} +1 -1
- package/dist/renderer-T35PsSw5.mjs +5 -0
- package/dist/{renderer-DEQeONTd.mjs → renderer-fWW0bsVl.mjs} +3 -3
- package/dist/renderer-iSZ5NT-J.mjs +5 -0
- package/dist/{renderer-DH7l5WFr.mjs → renderer-jBKpX3Xg.mjs} +4 -4
- package/dist/{renderer-DH7l5WFr.mjs.map → renderer-jBKpX3Xg.mjs.map} +1 -1
- package/dist/{renderer-C6st34I6.mjs → renderer-kFx1_MmK.mjs} +3 -3
- package/dist/{renderer-C6st34I6.mjs.map → renderer-kFx1_MmK.mjs.map} +1 -1
- package/dist/{renderer-CIB5L_C4.mjs → renderer-muB4slsV.mjs} +5 -5
- package/dist/{renderer-CIB5L_C4.mjs.map → renderer-muB4slsV.mjs.map} +1 -1
- package/dist/renderer-nEmMjQ1a.mjs +5 -0
- package/dist/{renderer-C3tVrzyT.mjs → renderer-oiDoNzhv.mjs} +3 -3
- package/dist/renderer-pG1nyfjE.mjs +5 -0
- package/dist/{renderer-DoPEPlbG.d.mts → renderer-tcypOFaB.d.mts} +23 -5
- package/dist/renderer-tcypOFaB.d.mts.map +1 -0
- package/dist/{renderer-Dss7T71q.mjs → renderer-vPxMXiv8.mjs} +5 -5
- package/dist/{renderer-Dss7T71q.mjs.map → renderer-vPxMXiv8.mjs.map} +1 -1
- package/dist/renderer-vbb9e3E3.mjs +5 -0
- package/dist/{renderer-OsQRvOle.mjs → renderer-vpsU_4XW.mjs} +5 -5
- package/dist/{renderer-OsQRvOle.mjs.map → renderer-vpsU_4XW.mjs.map} +1 -1
- package/dist/{renderer-BMP_lYMk.mjs → renderer-w7mlMSC-.mjs} +4 -4
- package/dist/{renderer-BMP_lYMk.mjs.map → renderer-w7mlMSC-.mjs.map} +1 -1
- package/dist/{renderers-CP8CFWDs-BH1gUTYa.mjs → renderers-CP8CFWDs-OgyUiyrr.mjs} +4 -4
- package/dist/{renderers-CP8CFWDs-BH1gUTYa.mjs.map → renderers-CP8CFWDs-OgyUiyrr.mjs.map} +1 -1
- package/dist/sam/index.d.mts +3 -3
- package/dist/sam/index.mjs +1 -1
- package/dist/signals/index.d.mts +7 -7
- package/dist/signals/index.mjs +8 -8
- package/dist/{signals-gOd0Ui9B.mjs → signals-BfJ1aqpT.mjs} +4 -4
- package/dist/{signals-gOd0Ui9B.mjs.map → signals-BfJ1aqpT.mjs.map} +1 -1
- package/dist/{src-Bnr8DUC--DzkRGA62.mjs → src-BU6vm9sP-DFJ3phW0.mjs} +76 -11
- package/dist/src-BU6vm9sP-DFJ3phW0.mjs.map +1 -0
- package/dist/{src-BU1VOWSk.mjs → src-C3f3zXYg.mjs} +250 -30
- package/dist/src-C3f3zXYg.mjs.map +1 -0
- package/package.json +30 -24
- package/dist/dist-D12-a3-x.mjs.map +0 -1
- package/dist/dist-DL1GwJvs.mjs.map +0 -1
- package/dist/gpu-zFNrvhV9.mjs.map +0 -1
- package/dist/index-B9Lm1x8i.d.mts.map +0 -1
- package/dist/index-Bzo1uj8h.d.mts.map +0 -1
- package/dist/index-V0ZQ4JN6.d.mts.map +0 -1
- package/dist/index-svAgwTY_.d.mts.map +0 -1
- package/dist/preview-engine/chunk-4FY4TNST.mjs +0 -1
- package/dist/preview-engine/chunk-7LDSMOO3.mjs +0 -1
- package/dist/preview-engine/chunk-AGAZJZWI.mjs +0 -1
- package/dist/preview-engine/chunk-BXPM5SJ3.mjs +0 -1
- package/dist/preview-engine/chunk-D73ZKPFN.mjs +0 -138
- package/dist/preview-engine/chunk-FKG27DVO.mjs +0 -4
- package/dist/preview-engine/chunk-KOVN277Z.mjs +0 -1
- package/dist/preview-engine/chunk-MIEH74UH.mjs +0 -480
- package/dist/preview-engine/chunk-Q62GPWGD.mjs +0 -1974
- package/dist/preview-engine/chunk-XYGDTPO7.mjs +0 -39
- package/dist/preview-engine/chunk-YGKO4NIU.mjs +0 -1
- package/dist/preview-engine/renderers-3BOQOUEU.mjs +0 -1
- package/dist/preview-engine/renderers-3M2FESR2.mjs +0 -1
- package/dist/preview-engine/renderers-6LHIWKMZ.mjs +0 -1
- package/dist/preview-engine/renderers-7XHO6M3B.mjs +0 -228
- package/dist/preview-engine/renderers-A43VCJ7X.mjs +0 -1
- package/dist/preview-engine/renderers-AKY464RY.mjs +0 -1
- package/dist/preview-engine/renderers-C5UO6PL5.mjs +0 -1
- package/dist/preview-engine/renderers-C64QSZO4.mjs +0 -1
- package/dist/preview-engine/renderers-CIRCR6NG.mjs +0 -1
- package/dist/preview-engine/renderers-CIWOPETY.mjs +0 -1
- package/dist/preview-engine/renderers-CZEZCELP.mjs +0 -1
- package/dist/preview-engine/renderers-FSQMWHQM.mjs +0 -1
- package/dist/preview-engine/renderers-FZEW5C23.mjs +0 -1
- package/dist/preview-engine/renderers-HCET2IML.mjs +0 -1
- package/dist/preview-engine/renderers-IUOOC6K7.mjs +0 -1
- package/dist/preview-engine/renderers-KYYJLVIJ.mjs +0 -1
- package/dist/preview-engine/renderers-L4GE7WV3.mjs +0 -1
- package/dist/preview-engine/renderers-LRAFWKCO.mjs +0 -1
- package/dist/preview-engine/renderers-LU3XZWEB.mjs +0 -1
- package/dist/preview-engine/renderers-MDHPQY6D.mjs +0 -1
- package/dist/preview-engine/renderers-ND2WV4K3.mjs +0 -1
- package/dist/preview-engine/renderers-NJ5CWVVH.mjs +0 -1
- package/dist/preview-engine/renderers-NKXYPR3V.mjs +0 -1
- package/dist/preview-engine/renderers-NWR66CGK.mjs +0 -1
- package/dist/preview-engine/renderers-O22WTBRM.mjs +0 -1
- package/dist/preview-engine/renderers-PBBA7LQB.mjs +0 -1
- package/dist/preview-engine/renderers-Q6LJRZ7R.mjs +0 -1
- package/dist/preview-engine/renderers-RMEACSRL.mjs +0 -1
- package/dist/preview-engine/renderers-SP42LCSI.mjs +0 -1
- package/dist/preview-engine/renderers-T7SZA3BX.mjs +0 -1
- package/dist/preview-engine/renderers-VADTDAHD.mjs +0 -1
- package/dist/preview-engine/renderers-VNNWI5C3.mjs +0 -1
- package/dist/preview-engine/renderers-WZ75MLP3.mjs +0 -1
- package/dist/preview-engine/renderers-XB5R4UQA.mjs +0 -1
- package/dist/preview-engine/renderers-YBIUZDGQ.mjs +0 -1
- package/dist/preview-engine/renderers-YESJR4O7.mjs +0 -1
- package/dist/preview-engine/renderers-YKSRZRRT.mjs +0 -1
- package/dist/program-xjIwjKb6.mjs.map +0 -1
- package/dist/renderer-129U3pc9.mjs +0 -5
- package/dist/renderer-2phFTFxQ.mjs +0 -5
- package/dist/renderer-9muKpDeE.mjs +0 -5
- package/dist/renderer-B5Dhv6j9.mjs +0 -5
- package/dist/renderer-BBUgCS3C.mjs +0 -5
- package/dist/renderer-BKXM28Mx.mjs +0 -5
- package/dist/renderer-BKqm6xdf.mjs +0 -5
- package/dist/renderer-BMfMMf0R.mjs +0 -5
- package/dist/renderer-BPsjEnnl.mjs +0 -5
- package/dist/renderer-Be5hfwSd.mjs.map +0 -1
- package/dist/renderer-Bofr6f88.mjs +0 -6
- package/dist/renderer-BqoGcujR.mjs +0 -5
- package/dist/renderer-BvuBt2aH.mjs +0 -5
- package/dist/renderer-BxTgXHu1.mjs +0 -5
- package/dist/renderer-Bz2Rrz60.mjs +0 -5
- package/dist/renderer-CBjG8rjE.mjs +0 -5
- package/dist/renderer-CS2zyPyZ.mjs +0 -5
- package/dist/renderer-CWLF6cAz.mjs.map +0 -1
- package/dist/renderer-CXnbl_jR.mjs +0 -5
- package/dist/renderer-CaF9vod_.mjs +0 -5
- package/dist/renderer-CbSBH3lp.mjs +0 -5
- package/dist/renderer-CdjuGRbO.mjs +0 -5
- package/dist/renderer-CoLbxC13.mjs +0 -5
- package/dist/renderer-CpedZNEG.mjs.map +0 -1
- package/dist/renderer-Cr9G0dXB.mjs +0 -5
- package/dist/renderer-D63l6_UC.mjs +0 -5
- package/dist/renderer-DCJqnzER.mjs +0 -5
- package/dist/renderer-DFBOR5J3.mjs +0 -5
- package/dist/renderer-DGAZSzw6.mjs +0 -5
- package/dist/renderer-DPLGk1Qk.mjs +0 -5
- package/dist/renderer-DTCUzByS.mjs +0 -5
- package/dist/renderer-DdGahYi1.mjs +0 -5
- package/dist/renderer-DhL4nNPk.mjs +0 -5
- package/dist/renderer-DkyTbiVz.mjs +0 -3
- package/dist/renderer-DnAZweRX.mjs +0 -5
- package/dist/renderer-DoPEPlbG.d.mts.map +0 -1
- package/dist/renderer-DpisVnT2.mjs +0 -5
- package/dist/renderer-Ds7pAKnE.mjs +0 -3
- package/dist/renderer-Du-GnKLb.mjs.map +0 -1
- package/dist/renderer-DxZD5B54.mjs +0 -5
- package/dist/renderer-PMHOnbnA.mjs +0 -5
- package/dist/renderer-STufNpMx.mjs +0 -5
- package/dist/renderer-SdrgfCxH.mjs +0 -5
- package/dist/renderer-mQt-y49D.mjs.map +0 -1
- package/dist/src-BU1VOWSk.mjs.map +0 -1
- package/dist/src-Bnr8DUC--DzkRGA62.mjs.map +0 -1
- /package/dist/{chunk-D8S17ehY.mjs → chunk-W71TSjRM.mjs} +0 -0
- /package/dist/{renderer-Cputd36d.mjs → renderer-B6rZUBwE.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.
|
package/README.md
CHANGED
|
@@ -42,6 +42,11 @@ Every frame is rendered by framefields directly from TypeScript in [`examples/`]
|
|
|
42
42
|
|
|
43
43
|
<table>
|
|
44
44
|
<tr>
|
|
45
|
+
<td width="33.33%" align="center">
|
|
46
|
+
<a href="https://youtu.be/3lrQdiXjlnY"><img src="https://raw.githubusercontent.com/gatewai-dev/framefields/main/assets/showcase/relay.jpg" alt="Relay product film" width="100%"></a>
|
|
47
|
+
<br><a href="https://youtu.be/3lrQdiXjlnY"><b>Relay</b></a>
|
|
48
|
+
<br><sub><a href="https://github.com/gatewai-dev/framefields/blob/main/examples/32_relay"><code>32_relay</code></a></sub>
|
|
49
|
+
</td>
|
|
45
50
|
<td width="33.33%" align="center">
|
|
46
51
|
<a href="https://youtu.be/xSowU7X48J8"><img src="https://raw.githubusercontent.com/gatewai-dev/framefields/main/assets/showcase/shard-storm.jpg" alt="Shard storm vision dancer showcase film" width="100%"></a>
|
|
47
52
|
<br><a href="https://youtu.be/xSowU7X48J8"><b>Shard storm</b></a>
|
|
@@ -52,13 +57,13 @@ Every frame is rendered by framefields directly from TypeScript in [`examples/`]
|
|
|
52
57
|
<br><a href="https://youtu.be/POC7rKnuoE4"><b>Physics dancer</b></a>
|
|
53
58
|
<br><sub><a href="https://github.com/gatewai-dev/framefields/blob/main/examples/28_physics_dancer"><code>28_physics_dancer</code></a></sub>
|
|
54
59
|
</td>
|
|
60
|
+
</tr>
|
|
61
|
+
<tr>
|
|
55
62
|
<td width="33.33%" align="center">
|
|
56
63
|
<a href="https://youtu.be/k2lgbdL6_TA"><img src="https://raw.githubusercontent.com/gatewai-dev/framefields/main/assets/showcase/mac-keyboard.jpg" alt="Mac keyboard from 3D primitives" width="100%"></a>
|
|
57
64
|
<br><a href="https://youtu.be/k2lgbdL6_TA"><b>Mac Keyboard</b></a>
|
|
58
65
|
<br><sub><a href="https://github.com/gatewai-dev/framefields/blob/main/examples/26_mac_keyboard_from_3d_primitives"><code>26_mac_keyboard_from_3d_primitives</code></a></sub>
|
|
59
66
|
</td>
|
|
60
|
-
</tr>
|
|
61
|
-
<tr>
|
|
62
67
|
<td width="33.33%" align="center">
|
|
63
68
|
<a href="https://youtu.be/FVXTqAozAv8"><img src="https://raw.githubusercontent.com/gatewai-dev/framefields/main/assets/showcase/framefields-launch.jpg" alt="Framefields launch film" width="100%"></a>
|
|
64
69
|
<br><a href="https://youtu.be/FVXTqAozAv8"><b>Framefields launch</b></a>
|
|
@@ -69,6 +74,8 @@ Every frame is rendered by framefields directly from TypeScript in [`examples/`]
|
|
|
69
74
|
<br><a href="https://youtu.be/9BF1snfmg3o"><b>Full Circle</b></a>
|
|
70
75
|
<br><sub><a href="https://github.com/gatewai-dev/framefields/blob/main/examples/21_full_circle"><code>21_full_circle</code></a></sub>
|
|
71
76
|
</td>
|
|
77
|
+
</tr>
|
|
78
|
+
<tr>
|
|
72
79
|
<td width="33.33%" align="center">
|
|
73
80
|
<a href="https://youtu.be/RQ3yi_lzPqI"><img src="https://raw.githubusercontent.com/gatewai-dev/framefields/main/assets/showcase/dancer.jpg" alt="Dancer showcase film" width="100%"></a>
|
|
74
81
|
<br><a href="https://youtu.be/RQ3yi_lzPqI"><b>Dancer showcase</b></a>
|
package/dist/audio/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import "../index-
|
|
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-
|
|
3
|
-
import { W as WebGPUAudioProcessor } from "../index-
|
|
4
|
-
import "../renderer-
|
|
5
|
-
import { t as _default$1 } from "../renderer-
|
|
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-CDQrdZ0J.mjs";
|
|
3
|
+
import { W as WebGPUAudioProcessor } from "../index-B7WqFBZA.mjs";
|
|
4
|
+
import "../renderer-tcypOFaB.mjs";
|
|
5
|
+
import { t as _default$1 } from "../renderer-DJuVX3c5.mjs";
|
|
6
6
|
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 };
|
package/dist/audio/index.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import "../chunk-
|
|
2
|
-
import { g as WebGPUAudioProcessor } from "../dist-
|
|
3
|
-
import { t as renderers_default$1 } from "../renderers-CP8CFWDs-
|
|
4
|
-
import { i as mixAudioTracks } from "../dist-
|
|
5
|
-
import { t as renderers_default$2 } from "../renderer-
|
|
6
|
-
import { t as renderers_default$3 } from "../renderer-
|
|
7
|
-
import { t as renderers_default } from "../renderer-
|
|
8
|
-
import { t as renderers_default$4 } from "../renderer-
|
|
9
|
-
import { t as renderers_default$5 } from "../renderer-
|
|
10
|
-
import { t as renderers_default$6 } from "../renderer-
|
|
11
|
-
import "../renderer-
|
|
12
|
-
import { t as renderers_default$7 } from "../renderer-
|
|
13
|
-
import { i as softLimit, n as mixSfxInto, r as renderSfx, t as encodeStereoWav } from "../audio-
|
|
1
|
+
import "../chunk-W71TSjRM.mjs";
|
|
2
|
+
import { g as WebGPUAudioProcessor } from "../dist-C4Vxgm0Q.mjs";
|
|
3
|
+
import { t as renderers_default$1 } from "../renderers-CP8CFWDs-OgyUiyrr.mjs";
|
|
4
|
+
import { i as mixAudioTracks } from "../dist-Cu1fZ9Uy.mjs";
|
|
5
|
+
import { t as renderers_default$2 } from "../renderer-CxabOSkk.mjs";
|
|
6
|
+
import { t as renderers_default$3 } from "../renderer-CO1PwItH.mjs";
|
|
7
|
+
import { t as renderers_default } from "../renderer-Dswrn-yi.mjs";
|
|
8
|
+
import { t as renderers_default$4 } from "../renderer-CanNjQuL.mjs";
|
|
9
|
+
import { t as renderers_default$5 } from "../renderer-DrExCXnp.mjs";
|
|
10
|
+
import { t as renderers_default$6 } from "../renderer-DxkvDAA6.mjs";
|
|
11
|
+
import "../renderer-B6rZUBwE.mjs";
|
|
12
|
+
import { t as renderers_default$7 } from "../renderer-jBKpX3Xg.mjs";
|
|
13
|
+
import { i as softLimit, n as mixSfxInto, r as renderSfx, t as encodeStereoWav } from "../audio-KHBadECb.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,6 @@
|
|
|
1
|
-
import { $ as FrameSignal } from "./index-
|
|
2
|
-
import { o as AudioSignalComputeConfig } from "./index-
|
|
3
|
-
import { n as NodeRendererPlugin } from "./renderer-
|
|
1
|
+
import { $ as FrameSignal } from "./index-COYNQ_mf.mjs";
|
|
2
|
+
import { o as AudioSignalComputeConfig } from "./index-B7WqFBZA.mjs";
|
|
3
|
+
import { n as NodeRendererPlugin } from "./renderer-tcypOFaB.mjs";
|
|
4
4
|
|
|
5
5
|
//#region ../../nodes/node-modulate/dist/renderer.d.mts
|
|
6
6
|
//#region src/renderers/index.d.ts
|
|
@@ -35,4 +35,4 @@ declare const AudioSignal: {
|
|
|
35
35
|
};
|
|
36
36
|
//#endregion
|
|
37
37
|
export { _default as i, AudioSignalOptions as n, ExtractedAudioSignalsBundle as r, AudioSignal as t };
|
|
38
|
-
//# sourceMappingURL=audio-
|
|
38
|
+
//# sourceMappingURL=audio-1X5qNNmk.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-
|
|
1
|
+
{"version":3,"file":"audio-1X5qNNmk.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;;;;UCShB,kBAAA,SAA2B;;;EDT9BC,WAAsE,CAAA,EAAA,UAAnDD,GAAAA,UAAAA,GAAAA,cAAD,GAAA,UAAA;;UCef,2BAAA;WACP;EAPO,IAAA,EAQV,WARU,CAAA,MAAmB,CAAA;EAMnB,IAAA,EAGV,WAHU,CAAA,MAAA,CAAA;EACP,MAAA,EAGD,WAHC,CAAA,MAAA,CAAA;EACH,WAAA,EAAA,MAAA;EACA,SAAA,EAAA,MAAA;EACE,UAAA,EAAA,MAAA;EAAW,WAAA,EAAA,OAAA;EAaP,OAAA,EAAA,OAuGZ;EArGW,aAAA,EAAA,OAAA;EAED,UAAA,EAAA,OAAA;EACC,UAAA,EAAA,OAAA;EAAR,YAAA,EAAA,OAAA;EAoFO,SAAA,CAAA,KAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;AACP,cA1FS,WA0FT,EAAA;EAAO,mBAAA,CAAA,QAAA,EAxFC,YAwFD,EAAA,EAAA,UAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAtFA,kBAsFA,CAAA,EArFP,OAqFO,CArFC,2BAqFD,CAAA;oCADA,qBACP,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-BlDbnteH.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-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,6 +1,6 @@
|
|
|
1
|
-
import { Mt as frameArraySignal } from "./dist-
|
|
2
|
-
import {
|
|
3
|
-
import { n as decodeAudioSource } from "./dist-
|
|
1
|
+
import { Mt as frameArraySignal } from "./dist-Bf2_efYP.mjs";
|
|
2
|
+
import { Ot as AudioSignalComputePipeline, j as ensureDevice } from "./dist-C4Vxgm0Q.mjs";
|
|
3
|
+
import { n as decodeAudioSource } from "./dist-Cu1fZ9Uy.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/signals/audio.ts
|
|
6
6
|
const AudioSignal = {
|
|
@@ -82,4 +82,4 @@ const AudioSignal = {
|
|
|
82
82
|
|
|
83
83
|
//#endregion
|
|
84
84
|
export { AudioSignal as t };
|
|
85
|
-
//# sourceMappingURL=audio-
|
|
85
|
+
//# sourceMappingURL=audio-YpBRdI7r.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-
|
|
1
|
+
{"version":3,"file":"audio-YpBRdI7r.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 AudioSignalComputeConfig,\n\tAudioSignalComputePipeline,\n\tensureDevice,\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 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 decodeAudioSource(source);\n\t\tif (!decoded || decoded.channels.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to decode audio source for feature extraction: ${source}`,\n\t\t\t);\n\t\t}\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"],"mappings":";;;;;AAmCA,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,kBAAkB,OAAO;AAC/C,MAAI,CAAC,WAAW,QAAQ,SAAS,WAAW,EAC3C,OAAM,IAAI,MACT,yDAAyD,SACzD;AAEF,SAAO,YAAY,oBAClB,QAAQ,UACR,QAAQ,YACR,QACA;;CAEF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-result-
|
|
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,53 +1,53 @@
|
|
|
1
|
-
import "../chunk-
|
|
2
|
-
import { Nt as frameCount } from "../dist-
|
|
3
|
-
import { t as Composition } from "../src-
|
|
4
|
-
import { x as describeGpu } from "../dist-
|
|
5
|
-
import "../renderers-CP8CFWDs-
|
|
6
|
-
import "../signals-
|
|
7
|
-
import "../renderer-
|
|
8
|
-
import "../renderer-
|
|
9
|
-
import "../renderer-
|
|
10
|
-
import "../renderer-
|
|
11
|
-
import "../renderer-
|
|
12
|
-
import "../renderer-
|
|
13
|
-
import "../renderer-
|
|
14
|
-
import "../renderer-
|
|
15
|
-
import "../renderer-
|
|
16
|
-
import "../renderer-
|
|
17
|
-
import { s as CompositorProgramSchema } from "../program-
|
|
18
|
-
import "../renderer-
|
|
19
|
-
import "../renderer-
|
|
20
|
-
import "../renderer-
|
|
21
|
-
import "../renderer-
|
|
22
|
-
import "../renderer-
|
|
23
|
-
import "../renderer-
|
|
24
|
-
import "../renderer-
|
|
25
|
-
import "../renderer-
|
|
26
|
-
import "../renderer-
|
|
27
|
-
import "../renderer-
|
|
28
|
-
import "../renderer-
|
|
29
|
-
import "../renderer-
|
|
30
|
-
import "../renderer-
|
|
31
|
-
import "../renderer-
|
|
32
|
-
import "../renderer-
|
|
33
|
-
import "../renderer-
|
|
34
|
-
import "../renderer-
|
|
35
|
-
import "../renderer-
|
|
36
|
-
import "../renderer-
|
|
37
|
-
import "../renderer-
|
|
38
|
-
import "../renderer-
|
|
39
|
-
import "../renderer-
|
|
40
|
-
import "../renderer-
|
|
41
|
-
import "../renderer-
|
|
42
|
-
import "../renderer-
|
|
43
|
-
import "../renderer-
|
|
44
|
-
import "../renderer-
|
|
45
|
-
import "../renderer-
|
|
46
|
-
import "../renderer-
|
|
47
|
-
import "../renderer-
|
|
48
|
-
import "../renderer-
|
|
49
|
-
import "../renderer-
|
|
50
|
-
import { t as failedCheck } from "../check-result-
|
|
1
|
+
import "../chunk-W71TSjRM.mjs";
|
|
2
|
+
import { Nt as frameCount } from "../dist-Bf2_efYP.mjs";
|
|
3
|
+
import { t as Composition } from "../src-C3f3zXYg.mjs";
|
|
4
|
+
import { x as describeGpu } from "../dist-C4Vxgm0Q.mjs";
|
|
5
|
+
import "../renderers-CP8CFWDs-OgyUiyrr.mjs";
|
|
6
|
+
import "../signals-BfJ1aqpT.mjs";
|
|
7
|
+
import "../renderer-BdRwbLLV.mjs";
|
|
8
|
+
import "../renderer-Dak_wVh9.mjs";
|
|
9
|
+
import "../renderer-CxabOSkk.mjs";
|
|
10
|
+
import "../renderer-CO1PwItH.mjs";
|
|
11
|
+
import "../renderer-Dswrn-yi.mjs";
|
|
12
|
+
import "../renderer-CanNjQuL.mjs";
|
|
13
|
+
import "../renderer-DrExCXnp.mjs";
|
|
14
|
+
import "../renderer-DxkvDAA6.mjs";
|
|
15
|
+
import "../renderer-B6rZUBwE.mjs";
|
|
16
|
+
import "../renderer-jBKpX3Xg.mjs";
|
|
17
|
+
import { s as CompositorProgramSchema } from "../program-BUjUTdxq.mjs";
|
|
18
|
+
import "../renderer-BnN3JH9u.mjs";
|
|
19
|
+
import "../renderer-CsRuEpR2.mjs";
|
|
20
|
+
import "../renderer-w7mlMSC-.mjs";
|
|
21
|
+
import "../renderer-CtulmkqT.mjs";
|
|
22
|
+
import "../renderer-Bif8bwCq.mjs";
|
|
23
|
+
import "../renderer-CDfCaqV4.mjs";
|
|
24
|
+
import "../renderer-DAug14gu.mjs";
|
|
25
|
+
import "../renderer-DxiF4O6X.mjs";
|
|
26
|
+
import "../renderer-DtCmG-tT.mjs";
|
|
27
|
+
import "../renderer-kFx1_MmK.mjs";
|
|
28
|
+
import "../renderer-CwAuWLWm.mjs";
|
|
29
|
+
import "../renderer-Bm91Xv6l.mjs";
|
|
30
|
+
import "../renderer-B8i4d1Rc.mjs";
|
|
31
|
+
import "../renderer-Dih1rtT6.mjs";
|
|
32
|
+
import "../renderer-7c0ecb-L.mjs";
|
|
33
|
+
import "../renderer-D1tDMuD0.mjs";
|
|
34
|
+
import "../renderer-BvRaVByi.mjs";
|
|
35
|
+
import "../renderer-BFmVDdVs.mjs";
|
|
36
|
+
import "../renderer-Dd2XrdqA.mjs";
|
|
37
|
+
import "../renderer-BIToh0CA.mjs";
|
|
38
|
+
import "../renderer-CeNAgCE2.mjs";
|
|
39
|
+
import "../renderer-BSW4CGZF.mjs";
|
|
40
|
+
import "../renderer-7w9PZmWJ.mjs";
|
|
41
|
+
import "../renderer-JASAZUyY.mjs";
|
|
42
|
+
import "../renderer-DKptrHeL.mjs";
|
|
43
|
+
import "../renderer-BhNZn2DU.mjs";
|
|
44
|
+
import "../renderer-D7lApyWZ.mjs";
|
|
45
|
+
import "../renderer-Br_aJ_b7.mjs";
|
|
46
|
+
import "../renderer-DjiebKHO.mjs";
|
|
47
|
+
import "../renderer-Ck-NLzz0.mjs";
|
|
48
|
+
import "../renderer-R2kLaNuR.mjs";
|
|
49
|
+
import "../renderer-DCMoBppL.mjs";
|
|
50
|
+
import { t as failedCheck } from "../check-result-Culfu7Nx.mjs";
|
|
51
51
|
import { existsSync } from "node:fs";
|
|
52
52
|
import { join } from "node:path";
|
|
53
53
|
import { mkdir, writeFile } from "node:fs/promises";
|
package/dist/cli.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as
|
|
2
|
+
import { i as renderCloud, t as CloudRenderError } from "./cloud-xcfV4J03.mjs";
|
|
3
|
+
import { t as failedCheck } from "./check-result-Culfu7Nx.mjs";
|
|
3
4
|
import { createRequire } from "node:module";
|
|
4
5
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
-
import { basename, dirname, join, posix, relative, resolve, sep } from "node:path";
|
|
6
|
+
import path, { basename, dirname, join, posix, relative, resolve, sep } from "node:path";
|
|
6
7
|
import { createHash } from "node:crypto";
|
|
7
8
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
9
|
import { spawn } from "node:child_process";
|
|
@@ -373,7 +374,8 @@ const SCRIPTS = {
|
|
|
373
374
|
frames: "tsx src/render.ts frames",
|
|
374
375
|
grid: "tsx src/render.ts grid",
|
|
375
376
|
preview: "tsx src/render.ts preview",
|
|
376
|
-
render: "tsx src/render.ts"
|
|
377
|
+
render: "tsx src/render.ts",
|
|
378
|
+
"render:cloud": "framefields render src/film.ts --cloud --workers auto"
|
|
377
379
|
};
|
|
378
380
|
/**
|
|
379
381
|
* The `package.json` fields a framefields project needs. npm reads
|
|
@@ -570,6 +572,7 @@ ${run("frames")} -- 0 30 60 # PNGs in output/
|
|
|
570
572
|
${run("grid")} # a contact sheet of the motion
|
|
571
573
|
${run("preview")} # play it in the browser
|
|
572
574
|
${run("render")} # output/output.mp4
|
|
575
|
+
${run("render:cloud")} # on cloud GPUs, from the pushed commit
|
|
573
576
|
\`\`\`
|
|
574
577
|
|
|
575
578
|
- \`src/film.ts\` builds the composition, \`src/theme.ts\` holds sizes, colors and fonts,
|
|
@@ -578,6 +581,9 @@ ${run("render")} # output/output.mp4
|
|
|
578
581
|
one into \`src/components/\`.
|
|
579
582
|
- Optional: the AI gateway generates images, video, music, voice and 3D from code. Copy
|
|
580
583
|
\`.env.example\` to \`.env\` and set \`FRAMEFIELDS_API_KEY\` (keys at ${AI_DASHBOARD}).
|
|
584
|
+
- \`render:cloud\` renders on framefields' GPUs with the same key, and splits a long film
|
|
585
|
+
across several (\`-- --plan\` shows workers, time and cost first). It renders the
|
|
586
|
+
commit you pushed, not uncommitted changes.
|
|
581
587
|
- Footage, audio and fonts live in \`assets/\` and are tracked with Git LFS
|
|
582
588
|
(\`git lfs install\` once per machine, \`git lfs pull\` after cloning).
|
|
583
589
|
`;
|
|
@@ -863,6 +869,131 @@ function isCheckReport(value) {
|
|
|
863
869
|
return typeof value === "object" && value !== null && "schemaVersion" in value && value.schemaVersion === 1 && "diagnostics" in value && Array.isArray(value.diagnostics);
|
|
864
870
|
}
|
|
865
871
|
|
|
872
|
+
//#endregion
|
|
873
|
+
//#region src/cli/cloud.ts
|
|
874
|
+
/**
|
|
875
|
+
* `framefields render <entry> --cloud`: renders the project on
|
|
876
|
+
* api.framefields.dev and downloads the video. Prints one plain line per
|
|
877
|
+
* phase, and a progress line at most every 10 seconds while frames render.
|
|
878
|
+
*/
|
|
879
|
+
const PROGRESS_EVERY_MS = 1e4;
|
|
880
|
+
async function runCloudRender(o, log, render = renderCloud) {
|
|
881
|
+
const workers = parseWorkers(o.workers);
|
|
882
|
+
if (workers === void 0) {
|
|
883
|
+
log(`--workers must be "auto" or a positive whole number, not "${o.workers}".`);
|
|
884
|
+
return 2;
|
|
885
|
+
}
|
|
886
|
+
if (o.codec && o.codec !== "h264" && o.codec !== "vp9") {
|
|
887
|
+
log(`--codec must be h264 or vp9, not "${o.codec}".`);
|
|
888
|
+
return 2;
|
|
889
|
+
}
|
|
890
|
+
const codec = o.codec ?? "h264";
|
|
891
|
+
const outputPath = o.output ?? path.join("output", `${path.basename(o.entry).replace(/\.[^.]+$/, "")}.${codec === "vp9" ? "webm" : "mp4"}`);
|
|
892
|
+
const controller = new AbortController();
|
|
893
|
+
const onSigint = () => {
|
|
894
|
+
log("Cancelling the cloud render…");
|
|
895
|
+
controller.abort(/* @__PURE__ */ new Error("cancelled"));
|
|
896
|
+
};
|
|
897
|
+
process.once("SIGINT", onSigint);
|
|
898
|
+
const started = Date.now();
|
|
899
|
+
const narrate = narrator(o.json ? () => {} : log, Date.now);
|
|
900
|
+
try {
|
|
901
|
+
const result = await render({
|
|
902
|
+
entry: o.entry,
|
|
903
|
+
export: o.export,
|
|
904
|
+
select: o.select,
|
|
905
|
+
workers: o.plan && workers === 1 ? "auto" : workers,
|
|
906
|
+
maxWorkers: o.maxWorkers ? Number(o.maxWorkers) : void 0,
|
|
907
|
+
codec,
|
|
908
|
+
quality: o.quality,
|
|
909
|
+
dryRun: o.plan,
|
|
910
|
+
outputPath: o.plan ? void 0 : outputPath,
|
|
911
|
+
signal: controller.signal,
|
|
912
|
+
onProgress: narrate,
|
|
913
|
+
onWarning: (m) => log(`warning: ${m}`)
|
|
914
|
+
});
|
|
915
|
+
if (o.json) {
|
|
916
|
+
log(JSON.stringify(result));
|
|
917
|
+
return 0;
|
|
918
|
+
}
|
|
919
|
+
if (result.status === "planned") {
|
|
920
|
+
log(`Render it: framefields render ${o.entry} --cloud --workers ${o.workers ?? "auto"}`);
|
|
921
|
+
return 0;
|
|
922
|
+
}
|
|
923
|
+
const bytes = result.output?.bytes;
|
|
924
|
+
log(`Done in ${duration((Date.now() - started) / 1e3)}: ${outputPath}${bytes ? ` (${(bytes / 1e6).toFixed(1)} MB)` : ""}, ${Math.round(result.gpuSeconds)} GPU seconds, ${usd(result.costUsd)}.`);
|
|
925
|
+
return 0;
|
|
926
|
+
} catch (err) {
|
|
927
|
+
if (err instanceof CloudRenderError) {
|
|
928
|
+
log(err.message);
|
|
929
|
+
if (err.status && err.status.costUsd > 0) log(`Charged ${usd(err.status.costUsd)} for the GPU time used.`);
|
|
930
|
+
if (err.code === "insufficient_credits") log("Top up at https://framefields.dev/dashboard/billing");
|
|
931
|
+
return 1;
|
|
932
|
+
}
|
|
933
|
+
throw err;
|
|
934
|
+
} finally {
|
|
935
|
+
process.removeListener("SIGINT", onSigint);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
function parseWorkers(value) {
|
|
939
|
+
if (value === void 0) return 1;
|
|
940
|
+
if (value === "auto") return "auto";
|
|
941
|
+
const n = Number(value);
|
|
942
|
+
return Number.isInteger(n) && n >= 1 ? n : void 0;
|
|
943
|
+
}
|
|
944
|
+
/** Turns status polls into log lines: one per phase, throttled frame progress. */
|
|
945
|
+
function narrator(log, now) {
|
|
946
|
+
let phase;
|
|
947
|
+
let planned = false;
|
|
948
|
+
let lastProgress = 0;
|
|
949
|
+
return (s) => {
|
|
950
|
+
if (!phase) log(`Cloud render ${s.id} started.`);
|
|
951
|
+
if (s.plan && !planned) {
|
|
952
|
+
planned = true;
|
|
953
|
+
log(describePlan(s));
|
|
954
|
+
}
|
|
955
|
+
if (s.status !== phase) {
|
|
956
|
+
phase = s.status;
|
|
957
|
+
const line = phaseLine(s);
|
|
958
|
+
if (line) log(line);
|
|
959
|
+
lastProgress = now();
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
if (s.status === "rendering" && now() - lastProgress >= PROGRESS_EVERY_MS) {
|
|
963
|
+
lastProgress = now();
|
|
964
|
+
log(progressLine(s));
|
|
965
|
+
}
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
function describePlan(s) {
|
|
969
|
+
const plan = s.plan;
|
|
970
|
+
if (!plan) return "";
|
|
971
|
+
const est = s.estimateUsd !== void 0 ? `, estimated ${usd(s.estimateUsd)}` : "";
|
|
972
|
+
return `Plan: ${plan.workers} ${plan.workers === 1 ? "worker" : "workers"}, ${duration(plan.workSec)} of render work, ready in about ${duration(plan.etaSec)}${est}.`;
|
|
973
|
+
}
|
|
974
|
+
function phaseLine(s) {
|
|
975
|
+
switch (s.status) {
|
|
976
|
+
case "probing": return "Measuring frame costs on one worker to plan the split…";
|
|
977
|
+
case "rendering": return s.workers > 1 ? `Rendering ${s.workers} chunks and the audio in parallel…` : "Rendering on one worker…";
|
|
978
|
+
case "stitching": return `Joining ${s.workers} chunks…`;
|
|
979
|
+
default: return;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
function progressLine(s) {
|
|
983
|
+
const { frames, totalFrames, etaSec } = s.progress;
|
|
984
|
+
return `Rendering ${totalFrames ? `${Math.floor(frames / totalFrames * 100)}% (${frames}/${totalFrames} frames)` : `${frames} frames`}${etaSec ? `, about ${duration(etaSec)} left` : ""}, ${usd(s.costUsd)} so far.`;
|
|
985
|
+
}
|
|
986
|
+
function duration(sec) {
|
|
987
|
+
const s = Math.max(0, Math.round(sec));
|
|
988
|
+
if (s < 90) return `${s} s`;
|
|
989
|
+
const m = Math.round(s / 60);
|
|
990
|
+
if (m < 90) return `${m} min`;
|
|
991
|
+
return `${Math.floor(m / 60)} h ${m % 60} min`;
|
|
992
|
+
}
|
|
993
|
+
function usd(value) {
|
|
994
|
+
return value > 0 && value < .01 ? "<$0.01" : `$${value.toFixed(2)}`;
|
|
995
|
+
}
|
|
996
|
+
|
|
866
997
|
//#endregion
|
|
867
998
|
//#region src/cli/registry.ts
|
|
868
999
|
/**
|
|
@@ -913,6 +1044,7 @@ function openRegistry(source, cwd = process.cwd()) {
|
|
|
913
1044
|
* npx framefields list the components you can add
|
|
914
1045
|
* npx framefields fonts add <role...> install fonts (emoji)
|
|
915
1046
|
* npx framefields fonts list the fonts you can install
|
|
1047
|
+
* npx framefields render <entry> --cloud render on api.framefields.dev
|
|
916
1048
|
*/
|
|
917
1049
|
const HELP = `Usage: framefields <command> [options]
|
|
918
1050
|
|
|
@@ -932,6 +1064,10 @@ Commands:
|
|
|
932
1064
|
Install fonts (pinned, hash-checked, with their license)
|
|
933
1065
|
and register them in the generated <components>/fonts.ts.
|
|
934
1066
|
fonts list List the fonts you can install.
|
|
1067
|
+
render <entry> --cloud
|
|
1068
|
+
Render on api.framefields.dev from the pushed commit of
|
|
1069
|
+
this git repo, and download the video. Needs
|
|
1070
|
+
FRAMEFIELDS_API_KEY. --export defaults to buildFilm.
|
|
935
1071
|
|
|
936
1072
|
Options for check:
|
|
937
1073
|
--export <name> Composition or builder export (default buildFilm).
|
|
@@ -941,6 +1077,20 @@ Options for check:
|
|
|
941
1077
|
--warnings-as-errors Fail on lint warnings.
|
|
942
1078
|
--json Machine-readable check, component list, or font list result.
|
|
943
1079
|
|
|
1080
|
+
Options for render --cloud:
|
|
1081
|
+
--workers <n|auto> 1 (default) renders on one GPU. auto measures the film
|
|
1082
|
+
first and splits it across as many GPUs as stay
|
|
1083
|
+
efficient; a number splits it into that many.
|
|
1084
|
+
--max-workers <n> Upper bound for auto.
|
|
1085
|
+
--plan Measure and plan only: prints workers, time and the
|
|
1086
|
+
estimated cost, renders nothing.
|
|
1087
|
+
--output <file> Where the video goes (default output/<entry>.mp4).
|
|
1088
|
+
--codec <codec> h264 (default) or vp9.
|
|
1089
|
+
--quality <q> very_low, low, high or very_high (default).
|
|
1090
|
+
--select <name> When the export returns several compositions.
|
|
1091
|
+
--json Print the final status as JSON.
|
|
1092
|
+
Ctrl-C cancels the render; GPU time already used is charged.
|
|
1093
|
+
|
|
944
1094
|
Options for init:
|
|
945
1095
|
--name <name> Package name (default: the folder's name).
|
|
946
1096
|
--pm <manager> npm, pnpm, yarn or bun (default: the one running this).
|
|
@@ -968,6 +1118,7 @@ Examples:
|
|
|
968
1118
|
npx framefields init my-film --install
|
|
969
1119
|
npx framefields add mouse-pointer focus-zoom
|
|
970
1120
|
npx framefields fonts add emoji
|
|
1121
|
+
npx framefields render src/film.ts --cloud --workers auto --plan
|
|
971
1122
|
`;
|
|
972
1123
|
async function main(argv) {
|
|
973
1124
|
const { values, positionals } = parseArgs({
|
|
@@ -992,6 +1143,13 @@ async function main(argv) {
|
|
|
992
1143
|
output: { type: "string" },
|
|
993
1144
|
timeout: { type: "string" },
|
|
994
1145
|
"warnings-as-errors": { type: "boolean" },
|
|
1146
|
+
cloud: { type: "boolean" },
|
|
1147
|
+
workers: { type: "string" },
|
|
1148
|
+
"max-workers": { type: "string" },
|
|
1149
|
+
plan: { type: "boolean" },
|
|
1150
|
+
codec: { type: "string" },
|
|
1151
|
+
quality: { type: "string" },
|
|
1152
|
+
select: { type: "string" },
|
|
995
1153
|
help: {
|
|
996
1154
|
type: "boolean",
|
|
997
1155
|
short: "h"
|
|
@@ -1034,6 +1192,24 @@ async function main(argv) {
|
|
|
1034
1192
|
}
|
|
1035
1193
|
return report$1.status === "passed" ? 0 : 1;
|
|
1036
1194
|
}
|
|
1195
|
+
if (command === "render") {
|
|
1196
|
+
if (names.length !== 1 || !values.cloud) {
|
|
1197
|
+
process.stderr.write("Usage: framefields render <entry> --cloud [--workers auto] [--plan]\nLocal renders run your project's render script (`npm run render`).\n");
|
|
1198
|
+
return 2;
|
|
1199
|
+
}
|
|
1200
|
+
return runCloudRender({
|
|
1201
|
+
entry: names[0],
|
|
1202
|
+
export: values.export,
|
|
1203
|
+
select: values.select,
|
|
1204
|
+
workers: values.workers,
|
|
1205
|
+
maxWorkers: values["max-workers"],
|
|
1206
|
+
codec: values.codec,
|
|
1207
|
+
quality: values.quality,
|
|
1208
|
+
output: values.output,
|
|
1209
|
+
plan: values.plan,
|
|
1210
|
+
json: values.json
|
|
1211
|
+
}, log);
|
|
1212
|
+
}
|
|
1037
1213
|
if (command === "fonts") return fonts(names, cwd, values, log);
|
|
1038
1214
|
if (command === "init") {
|
|
1039
1215
|
if (names.length > 1) {
|