@ignix-social/editor 0.1.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/LICENSE +190 -0
- package/NOTICE +54 -0
- package/README.md +23 -0
- package/bin/ignix-editor.mjs +8 -0
- package/package.json +53 -0
- package/patches/index.mjs +53 -0
- package/scripts/build-ffmpeg-macos.sh +35 -0
- package/scripts/build-whisper-macos.sh +21 -0
- package/scripts/vendor.mjs +41 -0
- package/skills/ignix-editor/SKILL.md +132 -0
- package/src/audio.mjs +31 -0
- package/src/binaries.json +46 -0
- package/src/binaries.mjs +83 -0
- package/src/cli.mjs +254 -0
- package/src/prepare.mjs +74 -0
- package/src/runtime/ignix-frame.js +92 -0
- package/src/transcribe.mjs +71 -0
- package/src/validate.mjs +71 -0
- package/templates/blank/index.html +41 -0
- package/vendor/hyperframes/README.md +181 -0
- package/vendor/hyperframes/UPSTREAM.json +12 -0
- package/vendor/hyperframes/bin/hyperframes-localize-fonts.mjs +12 -0
- package/vendor/hyperframes/bin/hyperframes.mjs +11 -0
- package/vendor/hyperframes/dist/add-LR3ZR2A5.js +79 -0
- package/vendor/hyperframes/dist/agentPromptGenerator-VIIPZCJ3.js +143 -0
- package/vendor/hyperframes/dist/animatedGifPrep-P2T6YM7Z.js +34 -0
- package/vendor/hyperframes/dist/asset-BE2DOV72.js +26 -0
- package/vendor/hyperframes/dist/assetCataloger-VBLPHX24.js +340 -0
- package/vendor/hyperframes/dist/auth-RCQB2ZT7.js +60 -0
- package/vendor/hyperframes/dist/autoUpdate-RJAX3DAZ.js +268 -0
- package/vendor/hyperframes/dist/backgroundChecks-H2LCUIMJ.js +61 -0
- package/vendor/hyperframes/dist/backgroundChecksWorker.js +26 -0
- package/vendor/hyperframes/dist/batchRender-FT7AP7XH.js +355 -0
- package/vendor/hyperframes/dist/beat-analyzer.global.js +338 -0
- package/vendor/hyperframes/dist/beats-Y2EOP72P.js +309 -0
- package/vendor/hyperframes/dist/benchmark-MZ7GY3JW.js +231 -0
- package/vendor/hyperframes/dist/browser-HUTAMRQE.js +237 -0
- package/vendor/hyperframes/dist/bundleWithLocalizedFonts-5QOPOB5D.js +52 -0
- package/vendor/hyperframes/dist/capture-RLZA6EMR.js +4079 -0
- package/vendor/hyperframes/dist/capture-SZZ4IYJK.js +290 -0
- package/vendor/hyperframes/dist/captureFile-LYOJOUIE.js +15 -0
- package/vendor/hyperframes/dist/captureTimeout-PA4FYWT5.js +27 -0
- package/vendor/hyperframes/dist/catalog-KYU55EWR.js +1001 -0
- package/vendor/hyperframes/dist/check-TCG4PXLR.js +1697 -0
- package/vendor/hyperframes/dist/checkBrowser-RPMO4OW5.js +1032 -0
- package/vendor/hyperframes/dist/chunk-2EAXUCCE.js +88 -0
- package/vendor/hyperframes/dist/chunk-2EGFTPWD.js +1077 -0
- package/vendor/hyperframes/dist/chunk-2PSPARWP.js +6058 -0
- package/vendor/hyperframes/dist/chunk-2YN64IN5.js +5747 -0
- package/vendor/hyperframes/dist/chunk-3GXQPCJC.js +682 -0
- package/vendor/hyperframes/dist/chunk-3ZP5DXE7.js +15 -0
- package/vendor/hyperframes/dist/chunk-4NWOGZZS.js +1990 -0
- package/vendor/hyperframes/dist/chunk-4PFZPP2N.js +587 -0
- package/vendor/hyperframes/dist/chunk-4THIAPBL.js +128 -0
- package/vendor/hyperframes/dist/chunk-4YYJOFKS.js +28 -0
- package/vendor/hyperframes/dist/chunk-54HJ63Q2.js +29 -0
- package/vendor/hyperframes/dist/chunk-5ETJX6WM.js +89 -0
- package/vendor/hyperframes/dist/chunk-5IAKAQA7.js +389 -0
- package/vendor/hyperframes/dist/chunk-5Z63TBTX.js +37 -0
- package/vendor/hyperframes/dist/chunk-6BEFEWFB.js +25 -0
- package/vendor/hyperframes/dist/chunk-6CSYCFQV.js +68 -0
- package/vendor/hyperframes/dist/chunk-6CTIGJY7.js +154 -0
- package/vendor/hyperframes/dist/chunk-7HG4BFIN.js +93 -0
- package/vendor/hyperframes/dist/chunk-7JZ4FXP2.js +118 -0
- package/vendor/hyperframes/dist/chunk-A2Z4Z4VL.js +2961 -0
- package/vendor/hyperframes/dist/chunk-AMKC3AXA.js +25 -0
- package/vendor/hyperframes/dist/chunk-AVUUN2XD.js +4847 -0
- package/vendor/hyperframes/dist/chunk-AWDFDFI3.js +46 -0
- package/vendor/hyperframes/dist/chunk-AWNBM3MZ.js +94 -0
- package/vendor/hyperframes/dist/chunk-BXCMXMJQ.js +73 -0
- package/vendor/hyperframes/dist/chunk-BZ56MTDX.js +6 -0
- package/vendor/hyperframes/dist/chunk-CFKU7HTK.js +171 -0
- package/vendor/hyperframes/dist/chunk-CWPVM2QV.js +308 -0
- package/vendor/hyperframes/dist/chunk-DPVXBVLL.js +31292 -0
- package/vendor/hyperframes/dist/chunk-DQBY7FRR.js +397 -0
- package/vendor/hyperframes/dist/chunk-E6RPWJVC.js +213 -0
- package/vendor/hyperframes/dist/chunk-EISRN4E6.js +294 -0
- package/vendor/hyperframes/dist/chunk-EOVYQ3IG.js +143 -0
- package/vendor/hyperframes/dist/chunk-F3WZGU7C.js +479 -0
- package/vendor/hyperframes/dist/chunk-FCSIGXXP.js +366 -0
- package/vendor/hyperframes/dist/chunk-FI4I7CME.js +56 -0
- package/vendor/hyperframes/dist/chunk-FLWXXDNS.js +15 -0
- package/vendor/hyperframes/dist/chunk-GK4AIFIH.js +11171 -0
- package/vendor/hyperframes/dist/chunk-GMECXFAN.js +57 -0
- package/vendor/hyperframes/dist/chunk-GULOKZLI.js +155 -0
- package/vendor/hyperframes/dist/chunk-H4YZZ2VQ.js +68 -0
- package/vendor/hyperframes/dist/chunk-H6QMKUYA.js +477 -0
- package/vendor/hyperframes/dist/chunk-HBBJFK6I.js +273 -0
- package/vendor/hyperframes/dist/chunk-HRUGC23L.js +212 -0
- package/vendor/hyperframes/dist/chunk-HVW7ABXD.js +19 -0
- package/vendor/hyperframes/dist/chunk-HW6OYASV.js +344 -0
- package/vendor/hyperframes/dist/chunk-HWKCIWQT.js +3578 -0
- package/vendor/hyperframes/dist/chunk-I465DBM6.js +1214 -0
- package/vendor/hyperframes/dist/chunk-IGLEPPTN.js +24 -0
- package/vendor/hyperframes/dist/chunk-IGNAAHS3.js +433 -0
- package/vendor/hyperframes/dist/chunk-IHFUKJOR.js +85 -0
- package/vendor/hyperframes/dist/chunk-IQ3OUQ5Z.js +213 -0
- package/vendor/hyperframes/dist/chunk-ISN5GRYI.js +20 -0
- package/vendor/hyperframes/dist/chunk-IUZFXWSV.js +446 -0
- package/vendor/hyperframes/dist/chunk-JH556Q42.js +647 -0
- package/vendor/hyperframes/dist/chunk-JTHMTOMQ.js +601 -0
- package/vendor/hyperframes/dist/chunk-K2EQN4VU.js +405 -0
- package/vendor/hyperframes/dist/chunk-K2FTXJYH.js +16044 -0
- package/vendor/hyperframes/dist/chunk-K4WIOZFP.js +32 -0
- package/vendor/hyperframes/dist/chunk-K4WKGXRC.js +18 -0
- package/vendor/hyperframes/dist/chunk-KBJUXVOJ.js +172 -0
- package/vendor/hyperframes/dist/chunk-KC5XXX3X.js +590 -0
- package/vendor/hyperframes/dist/chunk-KNU5COPB.js +29 -0
- package/vendor/hyperframes/dist/chunk-KZI44OPA.js +185 -0
- package/vendor/hyperframes/dist/chunk-L3YOGIPG.js +48 -0
- package/vendor/hyperframes/dist/chunk-LAOCA3MQ.js +189 -0
- package/vendor/hyperframes/dist/chunk-LCSMOLGX.js +312 -0
- package/vendor/hyperframes/dist/chunk-LFGJWOVA.js +61 -0
- package/vendor/hyperframes/dist/chunk-LHSR3M4M.js +498 -0
- package/vendor/hyperframes/dist/chunk-LYNI3FOL.js +123 -0
- package/vendor/hyperframes/dist/chunk-M2WBOQ2Q.js +54 -0
- package/vendor/hyperframes/dist/chunk-MRF4AMKD.js +104 -0
- package/vendor/hyperframes/dist/chunk-MWB3ZIFM.js +852 -0
- package/vendor/hyperframes/dist/chunk-NGKM64BP.js +39 -0
- package/vendor/hyperframes/dist/chunk-NXMYHJAL.js +43 -0
- package/vendor/hyperframes/dist/chunk-OAF4XJOW.js +192 -0
- package/vendor/hyperframes/dist/chunk-OFQWTKPW.js +117 -0
- package/vendor/hyperframes/dist/chunk-P6LJ4Y32.js +4662 -0
- package/vendor/hyperframes/dist/chunk-PBN6GBJE.js +108 -0
- package/vendor/hyperframes/dist/chunk-PDAMK4Q5.js +28 -0
- package/vendor/hyperframes/dist/chunk-PFCFR3KZ.js +20 -0
- package/vendor/hyperframes/dist/chunk-PJ3HDUCY.js +108 -0
- package/vendor/hyperframes/dist/chunk-PMRBLBUP.js +152 -0
- package/vendor/hyperframes/dist/chunk-PPQUYWTW.js +240 -0
- package/vendor/hyperframes/dist/chunk-Q5X2B5WT.js +29 -0
- package/vendor/hyperframes/dist/chunk-Q7IU7MOR.js +351 -0
- package/vendor/hyperframes/dist/chunk-QC4FJVLM.js +371 -0
- package/vendor/hyperframes/dist/chunk-QNYYOUU3.js +1318 -0
- package/vendor/hyperframes/dist/chunk-RDNNAKEP.js +161 -0
- package/vendor/hyperframes/dist/chunk-RMHUQGRK.js +657 -0
- package/vendor/hyperframes/dist/chunk-RQVDTPGD.js +6 -0
- package/vendor/hyperframes/dist/chunk-RVCWIIZ7.js +68 -0
- package/vendor/hyperframes/dist/chunk-S3D6GE5W.js +72 -0
- package/vendor/hyperframes/dist/chunk-S3S4TGEH.js +424 -0
- package/vendor/hyperframes/dist/chunk-S7NPLFWV.js +11395 -0
- package/vendor/hyperframes/dist/chunk-SHB5VDMH.js +51 -0
- package/vendor/hyperframes/dist/chunk-TCLGPL65.js +860 -0
- package/vendor/hyperframes/dist/chunk-THXFSPLV.js +40 -0
- package/vendor/hyperframes/dist/chunk-TJSTGSAW.js +354 -0
- package/vendor/hyperframes/dist/chunk-TQFG7HTI.js +1024 -0
- package/vendor/hyperframes/dist/chunk-TVCRUG2S.js +265 -0
- package/vendor/hyperframes/dist/chunk-TWWSYAKJ.js +24 -0
- package/vendor/hyperframes/dist/chunk-U7CZBDMV.js +27 -0
- package/vendor/hyperframes/dist/chunk-UEZXMWG3.js +139 -0
- package/vendor/hyperframes/dist/chunk-UYEZTK4U.js +61 -0
- package/vendor/hyperframes/dist/chunk-VC76R6W2.js +27 -0
- package/vendor/hyperframes/dist/chunk-VFCKXTBB.js +159 -0
- package/vendor/hyperframes/dist/chunk-VWG7OQKU.js +22 -0
- package/vendor/hyperframes/dist/chunk-VXVRPIJA.js +105 -0
- package/vendor/hyperframes/dist/chunk-WBLXWOYK.js +15 -0
- package/vendor/hyperframes/dist/chunk-WERLJGIC.js +20 -0
- package/vendor/hyperframes/dist/chunk-WMQNIQDJ.js +2057 -0
- package/vendor/hyperframes/dist/chunk-WPHMNO44.js +4528 -0
- package/vendor/hyperframes/dist/chunk-X5HWXQPU.js +113 -0
- package/vendor/hyperframes/dist/chunk-X7MTZ4T2.js +6 -0
- package/vendor/hyperframes/dist/chunk-XH4DSOS5.js +59 -0
- package/vendor/hyperframes/dist/chunk-XS4EJSKU.js +23 -0
- package/vendor/hyperframes/dist/chunk-XT5P4QMO.js +181 -0
- package/vendor/hyperframes/dist/chunk-XT7X6QCP.js +6 -0
- package/vendor/hyperframes/dist/chunk-XUHOIDKG.js +6 -0
- package/vendor/hyperframes/dist/chunk-XUXGIA7H.js +485 -0
- package/vendor/hyperframes/dist/chunk-XZABUQTX.js +113 -0
- package/vendor/hyperframes/dist/chunk-Y6W4DVPS.js +356 -0
- package/vendor/hyperframes/dist/chunk-YEIFI443.js +44 -0
- package/vendor/hyperframes/dist/chunk-YQZNILVH.js +375 -0
- package/vendor/hyperframes/dist/chunk-Z27A7NUB.js +65 -0
- package/vendor/hyperframes/dist/chunk-Z6B37SNM.js +3081 -0
- package/vendor/hyperframes/dist/chunk-ZJUKFZ2P.js +10954 -0
- package/vendor/hyperframes/dist/chunk-ZKDMAOFU.js +32 -0
- package/vendor/hyperframes/dist/chunk-ZMXUQLI2.js +17219 -0
- package/vendor/hyperframes/dist/chunk-ZTZ7NCJT.js +58 -0
- package/vendor/hyperframes/dist/chunk-ZTZA4UWZ.js +108 -0
- package/vendor/hyperframes/dist/clean-W57E5YQ3.js +293 -0
- package/vendor/hyperframes/dist/cli.js +495 -0
- package/vendor/hyperframes/dist/cloud-FFTJGZ24.js +70 -0
- package/vendor/hyperframes/dist/cloudrun-AJUTHUEA.js +763 -0
- package/vendor/hyperframes/dist/colors-HKWSZCGK.js +15 -0
- package/vendor/hyperframes/dist/commands/contrast-audit.browser.js +459 -0
- package/vendor/hyperframes/dist/commands/layout-audit.browser.js +2102 -0
- package/vendor/hyperframes/dist/commands/motion-sample.browser.js +74 -0
- package/vendor/hyperframes/dist/commands/motion-signature.browser.js +374 -0
- package/vendor/hyperframes/dist/compare-AYCTT55F.js +421 -0
- package/vendor/hyperframes/dist/compiler-QO36EXLS.js +121 -0
- package/vendor/hyperframes/dist/component-VFFR2O7T.js +176 -0
- package/vendor/hyperframes/dist/compositions-QTVN3U2A.js +228 -0
- package/vendor/hyperframes/dist/contactSheet-27SRU7A4.js +22 -0
- package/vendor/hyperframes/dist/delete-ZAKYCB7I.js +114 -0
- package/vendor/hyperframes/dist/deploy-MX76RZ36.js +101 -0
- package/vendor/hyperframes/dist/destroy-H2TZBYHH.js +42 -0
- package/vendor/hyperframes/dist/deterministicFonts-HAEMV4TM.js +50 -0
- package/vendor/hyperframes/dist/dist-EWXJGN63.js +129 -0
- package/vendor/hyperframes/dist/dist-FNNGCKFS.js +29 -0
- package/vendor/hyperframes/dist/dist-S3PJNPXQ.js +392 -0
- package/vendor/hyperframes/dist/docker/Dockerfile.render +65 -0
- package/vendor/hyperframes/dist/docs/compositions.md +67 -0
- package/vendor/hyperframes/dist/docs/data-attributes.md +27 -0
- package/vendor/hyperframes/dist/docs/examples.md +19 -0
- package/vendor/hyperframes/dist/docs/gsap.md +26 -0
- package/vendor/hyperframes/dist/docs/rendering.md +35 -0
- package/vendor/hyperframes/dist/docs/troubleshooting.md +29 -0
- package/vendor/hyperframes/dist/docs-QAPJEGLS.js +131 -0
- package/vendor/hyperframes/dist/doctor-AI7C3FON.js +67 -0
- package/vendor/hyperframes/dist/dom-IROKGVJI.js +14 -0
- package/vendor/hyperframes/dist/dotEnv-AECLXQSO.js +14 -0
- package/vendor/hyperframes/dist/events-7LALYNKZ.js +92 -0
- package/vendor/hyperframes/dist/events-FQY3HGKZ.js +88 -0
- package/vendor/hyperframes/dist/feedback-WCMDMSTK.js +472 -0
- package/vendor/hyperframes/dist/ffmpeg-QIUFEFTY.js +35 -0
- package/vendor/hyperframes/dist/figma-64WY462P.js +63 -0
- package/vendor/hyperframes/dist/fontData.generated-NXAOI4GH.js +13 -0
- package/vendor/hyperframes/dist/fontLocalizeCli.js +132 -0
- package/vendor/hyperframes/dist/get-FPOMJMZB.js +103 -0
- package/vendor/hyperframes/dist/gpuPolicy-2ZUZE5D6.js +38 -0
- package/vendor/hyperframes/dist/grade-compare-E2CKPST4.js +647 -0
- package/vendor/hyperframes/dist/gsapParser-DIYYX6JT.js +2846 -0
- package/vendor/hyperframes/dist/gsapParserAcorn-E3GEIRZB.js +28 -0
- package/vendor/hyperframes/dist/help-YRQIDDML.js +197 -0
- package/vendor/hyperframes/dist/history-PP5NDRV3.js +571 -0
- package/vendor/hyperframes/dist/hyperframe-runtime.js +1081 -0
- package/vendor/hyperframes/dist/hyperframe.manifest.json +22 -0
- package/vendor/hyperframes/dist/hyperframe.runtime.iife.js +1081 -0
- package/vendor/hyperframes/dist/hyperframes-player.global.js +474 -0
- package/vendor/hyperframes/dist/hyperframes-slideshow.global.js +149 -0
- package/vendor/hyperframes/dist/info-SEX3B7JL.js +153 -0
- package/vendor/hyperframes/dist/init-U3AKHO5B.js +1147 -0
- package/vendor/hyperframes/dist/inspect-Q3K6EDEK.js +97 -0
- package/vendor/hyperframes/dist/installer-K6O5WF44.js +37 -0
- package/vendor/hyperframes/dist/keyframes-DC64JCI3.js +2602 -0
- package/vendor/hyperframes/dist/lambda-D7UMN4DJ.js +451 -0
- package/vendor/hyperframes/dist/layout-XSPPDHOO.js +86 -0
- package/vendor/hyperframes/dist/lib-TPG2ZMAX.js +128 -0
- package/vendor/hyperframes/dist/lint-7DQZE7L3.js +164 -0
- package/vendor/hyperframes/dist/lintProject-OHBBM3DJ.js +27 -0
- package/vendor/hyperframes/dist/list-4K5MVDQX.js +162 -0
- package/vendor/hyperframes/dist/login-NTX4OWXL.js +377 -0
- package/vendor/hyperframes/dist/logout-Q654A3SI.js +100 -0
- package/vendor/hyperframes/dist/manager-67P2XFXQ.js +34 -0
- package/vendor/hyperframes/dist/manager-CT3D67CG.js +38 -0
- package/vendor/hyperframes/dist/manager-GFN75DM4.js +30 -0
- package/vendor/hyperframes/dist/media-treatment-5FYAOPNL.js +972 -0
- package/vendor/hyperframes/dist/media-use-4XXGABIL.js +113 -0
- package/vendor/hyperframes/dist/models-C4E4IWJD.js +137 -0
- package/vendor/hyperframes/dist/motionShot-S4MIGMT5.js +614 -0
- package/vendor/hyperframes/dist/normalize-O76AC4HE.js +333 -0
- package/vendor/hyperframes/dist/normalize-audio-CSFTXLXD.js +276 -0
- package/vendor/hyperframes/dist/open-2ZD6BHZG.js +115 -0
- package/vendor/hyperframes/dist/pipeline-TNGWUZQC.js +54 -0
- package/vendor/hyperframes/dist/play-CTMUXX6E.js +349 -0
- package/vendor/hyperframes/dist/policies-FSDZVS2E.js +292 -0
- package/vendor/hyperframes/dist/preflight-SMNV6RW2.js +45 -0
- package/vendor/hyperframes/dist/present-WQVHV5CR.js +350 -0
- package/vendor/hyperframes/dist/preview-JOJXTH75.js +1820 -0
- package/vendor/hyperframes/dist/producer-ECLEN5RP.js +13 -0
- package/vendor/hyperframes/dist/progress-FBIEEB7Y.js +73 -0
- package/vendor/hyperframes/dist/projectConfig-HYJMJ5BY.js +56 -0
- package/vendor/hyperframes/dist/publication-HQ5Y3KBM.js +29 -0
- package/vendor/hyperframes/dist/publish-VHDYQASC.js +430 -0
- package/vendor/hyperframes/dist/refresh-K24ETHMA.js +53 -0
- package/vendor/hyperframes/dist/remove-background-W2YX2NVH.js +253 -0
- package/vendor/hyperframes/dist/render-AO5VX3YI.js +177 -0
- package/vendor/hyperframes/dist/render-LNO62LEL.js +2367 -0
- package/vendor/hyperframes/dist/render-TTQI7TGN.js +796 -0
- package/vendor/hyperframes/dist/render-batch-YH7CTWNY.js +284 -0
- package/vendor/hyperframes/dist/renderCancellation-JPIHE47X.js +35 -0
- package/vendor/hyperframes/dist/renderSetupWorker.js +79 -0
- package/vendor/hyperframes/dist/resolver-IZ647GBZ.js +38 -0
- package/vendor/hyperframes/dist/runtimeVersion.js +18 -0
- package/vendor/hyperframes/dist/screenshotCapture-ECBTLCU6.js +179 -0
- package/vendor/hyperframes/dist/shaderTransitionWorker.js +44 -0
- package/vendor/hyperframes/dist/sherpa-KKLNW6U2.js +314 -0
- package/vendor/hyperframes/dist/sherpaWorker.js +77 -0
- package/vendor/hyperframes/dist/sites-TNVKZS73.js +52 -0
- package/vendor/hyperframes/dist/skill-ZHVLH7KX.js +15 -0
- package/vendor/hyperframes/dist/skills/hyperframes/SKILL.md +152 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/brief-contract.md +108 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/brief-format.md +72 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/capability-menu.md +47 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/frame-worker-core.md +80 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/intent-interview.md +73 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/pitch-round.md +40 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/plugin-installation.md +43 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/production-loop.md +26 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/review-loop.md +37 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/route-briefs.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/embedded-captions.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/faceless-explainer.md +12 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/general-video.md +12 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/motion-graphics.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/music-to-video.md +12 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/pr-to-video.md +28 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/product-launch-video.md +13 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/remotion-to-hyperframes.md +9 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/slideshow.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/talking-head-recut.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/script-format.md +52 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/skill-lifecycle.md +35 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/storyboard-format.md +99 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/subagent-dispatch.md +35 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/workflow-catalog.md +10 -0
- package/vendor/hyperframes/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +194 -0
- package/vendor/hyperframes/dist/skills/hyperframes/scripts/plugin-cli.mjs +88 -0
- package/vendor/hyperframes/dist/skills/hyperframes/scripts/plugin-cli.test.mjs +117 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/SKILL.md +189 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/beats.md +19 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/cloud.md +163 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/cloudrun.md +62 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/compare-and-batch.md +105 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/doctor-browser.md +57 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/init-and-scaffold.md +74 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/lambda.md +185 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +132 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/preview-render.md +193 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +134 -0
- package/vendor/hyperframes/dist/skills/media-use/SKILL.md +100 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/CREDITS.md +35 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/chime.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/click-soft.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/click.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/error.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-1.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-2.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-3.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/impact-bass-1.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/impact-bass-2.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/key-press.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/manifest.json +97 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/notification.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/ping.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/pop.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/riser.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/sparkle.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/typing.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh-cinematic.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh-short.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/bgm.md +76 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/authoring.md +163 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/motion.md +87 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/transcript-handling.md +97 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/remove-background.md +143 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/requirements.md +29 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/sfx.md +42 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/transcribe.md +52 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/tts-to-captions.md +35 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/tts.md +260 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/audio.mjs +311 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/audio.test.mjs +159 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/gemini-pipeline.test.mjs +131 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-tts.mjs +122 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-tts.test.mjs +38 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-voice.mjs +98 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-voice.test.mjs +233 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/audio-meta.mjs +39 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/audio-meta.test.mjs +136 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm-volume.mjs +4 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm.mjs +257 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm.test.mjs +74 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/concurrency.mjs +14 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/concurrency.test.mjs +41 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.mjs +43 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.py +52 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.test.mjs +86 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth_test.py +90 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-tts.mjs +122 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-tts.test.mjs +243 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/heygen.mjs +197 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/heygen.test.mjs +185 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/media-record.mjs +114 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/media-record.test.mjs +205 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/python.mjs +77 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/python.test.mjs +136 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/sfx.mjs +165 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/sfx.test.mjs +121 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.mjs +389 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.spawn.test.mjs +158 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.test.mjs +230 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lyria-recipe.py +136 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/wait-bgm.mjs +175 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/wait-bgm.test.mjs +108 -0
- package/vendor/hyperframes/dist/skills/media-use/luts/README.md +28 -0
- package/vendor/hyperframes/dist/skills/media-use/luts/index.json +57 -0
- package/vendor/hyperframes/dist/skills/media-use/references/audio.md +20 -0
- package/vendor/hyperframes/dist/skills/media-use/references/grading.md +160 -0
- package/vendor/hyperframes/dist/skills/media-use/references/media-treatment-recipes.md +929 -0
- package/vendor/hyperframes/dist/skills/media-use/references/media-treatments.md +202 -0
- package/vendor/hyperframes/dist/skills/media-use/references/memory.md +37 -0
- package/vendor/hyperframes/dist/skills/media-use/references/meta.md +61 -0
- package/vendor/hyperframes/dist/skills/media-use/references/operations.md +327 -0
- package/vendor/hyperframes/dist/skills/media-use/references/resolve.md +150 -0
- package/vendor/hyperframes/dist/skills/media-use/references/setup-providers.md +80 -0
- package/vendor/hyperframes/dist/skills/media-use/references/telemetry-dashboard.md +49 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/audio-duck.mjs +113 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/compatibility.test.mjs +96 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/dither.mjs +328 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/dither.test.mjs +176 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/eval.mjs +369 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/adopt.mjs +128 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/adopt.test.mjs +95 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bgm-provider.mjs +20 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/brand-provider.mjs +59 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bundled-sfx-provider.mjs +119 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bundled-sfx-provider.test.mjs +139 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cache.mjs +148 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/candidates.mjs +91 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/candidates.test.mjs +155 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/codex-provider.mjs +161 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/codex-provider.test.mjs +34 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.d.mts +3 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.mjs +45 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.test.mjs +79 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/coverage.test.mjs +136 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-build.mjs +181 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-build.test.mjs +80 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-validate.mjs +198 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-validate.test.mjs +125 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cutlist.mjs +184 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cutlist.test.mjs +162 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/duck.mjs +95 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/duck.test.mjs +153 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/error-diffusion.mjs +230 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/error-diffusion.test.mjs +102 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ff-binaries.mjs +37 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/freeze.mjs +72 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/freeze.test.mjs +138 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/grade-analyzer.mjs +265 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/grade-analyzer.test.mjs +285 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-cli.mjs +191 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-cli.test.mjs +301 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-search.mjs +45 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-search.test.mjs +49 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-video-provider.mjs +138 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-video-provider.test.mjs +435 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/image-provider.mjs +44 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/index-gen.mjs +63 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-media-search.mjs +32 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-models.mjs +318 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-models.test.mjs +220 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-run.mjs +78 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-run.test.mjs +121 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/logo-provider.mjs +244 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/logo-provider.test.mjs +298 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ltx-video-provider.mjs +94 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ltx-video-provider.test.mjs +316 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/lut-preset-provider.mjs +271 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/lut-preset-provider.test.mjs +199 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.d.mts +19 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.mjs +279 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.test.mjs +397 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/match.mjs +47 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-fetch.mjs +85 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-fetch.test.mjs +197 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-home.mjs +20 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-home.test.mjs +61 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-search.d.mts +9 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-search.mjs +107 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/mflux-provider.mjs +128 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/mflux-provider.test.mjs +174 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/misses.mjs +49 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/misses.test.mjs +89 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/npx-sync.mjs +31 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/npx-sync.test.mjs +50 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/parakeet-words.mjs +27 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/parakeet-words.test.mjs +44 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/prefs-store.mjs +180 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/prefs-store.test.mjs +189 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/probe.mjs +41 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/probe.test.mjs +148 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/providers.mjs +5 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/recipe-store.mjs +367 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/recipe-store.test.mjs +367 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/registry.mjs +212 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/registry.test.mjs +262 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/search.mjs +24 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/search.test.mjs +32 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/sfx-provider.mjs +23 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/specs.mjs +132 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/specs.test.mjs +157 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/stats.mjs +117 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/stats.test.mjs +165 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/svg-sanitize.mjs +21 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/telemetry.mjs +210 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/telemetry.test.mjs +437 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/test-home.test.mjs +10 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/transcriptCutFade.mjs +21 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/transcriptCutFade.test.mjs +33 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/tts-local-provider.mjs +94 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/tts-local-provider.test.mjs +72 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/usage.mjs +57 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/usage.test.mjs +54 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/voice-provider.mjs +57 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/voice-provider.test.mjs +46 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/words.mjs +18 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/prefs.mjs +70 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/recipe.mjs +103 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/resolve-plugin.test.mjs +62 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/resolve.mjs +1369 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcribe.mjs +194 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcribe.test.mjs +112 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcript-cut.mjs +270 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcript-cut.test.mjs +117 -0
- package/vendor/hyperframes/dist/skills-MJ2J4GEM.js +808 -0
- package/vendor/hyperframes/dist/skillsUpdateCheck-TKTYQN5R.js +26 -0
- package/vendor/hyperframes/dist/slideshow-EJ4IMY6P.js +24 -0
- package/vendor/hyperframes/dist/snapshot-KIVDUUMN.js +875 -0
- package/vendor/hyperframes/dist/src-6YQBJGWR.js +202 -0
- package/vendor/hyperframes/dist/src-PVYUYV3M.js +471 -0
- package/vendor/hyperframes/dist/state-KAXGHF77.js +26 -0
- package/vendor/hyperframes/dist/staticProjectServer-7EU666GS.js +49 -0
- package/vendor/hyperframes/dist/status-YM52BQ6S.js +311 -0
- package/vendor/hyperframes/dist/studio/assets/hyperframes-player-Cp8e_Zst.js +473 -0
- package/vendor/hyperframes/dist/studio/assets/index-BX3KHhGX.js +71 -0
- package/vendor/hyperframes/dist/studio/assets/index-CASEBNy2.js +1 -0
- package/vendor/hyperframes/dist/studio/assets/index-D11atkBt.css +1 -0
- package/vendor/hyperframes/dist/studio/assets/index-DMTt9nTf.js +531 -0
- package/vendor/hyperframes/dist/studio/assets/index-oE1pOdAy.js +399 -0
- package/vendor/hyperframes/dist/studio/chunk-5VSXRGIX.js +948 -0
- package/vendor/hyperframes/dist/studio/chunk-5VSXRGIX.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-7UQWVN52.js +938 -0
- package/vendor/hyperframes/dist/studio/chunk-7UQWVN52.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-EEXSYY5F.js +190 -0
- package/vendor/hyperframes/dist/studio/chunk-EEXSYY5F.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-FOEID72M.js +1441 -0
- package/vendor/hyperframes/dist/studio/chunk-FOEID72M.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-PZ5AY32C.js +10 -0
- package/vendor/hyperframes/dist/studio/chunk-PZ5AY32C.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-TDWGXBUT.js +1103 -0
- package/vendor/hyperframes/dist/studio/chunk-TDWGXBUT.js.map +1 -0
- package/vendor/hyperframes/dist/studio/domEditingLayers-IEVLO54Z.js +47 -0
- package/vendor/hyperframes/dist/studio/domEditingLayers-IEVLO54Z.js.map +1 -0
- package/vendor/hyperframes/dist/studio/favicon.svg +14 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/audio.svg +7 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/captions.svg +5 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/composition.svg +12 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/image.svg +18 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/music.svg +10 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/text.svg +3 -0
- package/vendor/hyperframes/dist/studio/index.css +165 -0
- package/vendor/hyperframes/dist/studio/index.css.map +1 -0
- package/vendor/hyperframes/dist/studio/index.d.ts +4296 -0
- package/vendor/hyperframes/dist/studio/index.html +23 -0
- package/vendor/hyperframes/dist/studio/index.js +99693 -0
- package/vendor/hyperframes/dist/studio/index.js.map +1 -0
- package/vendor/hyperframes/dist/studio/player.d.ts +30 -0
- package/vendor/hyperframes/dist/studio/player.js +10 -0
- package/vendor/hyperframes/dist/studio/player.js.map +1 -0
- package/vendor/hyperframes/dist/studio/styles/tailwind-preset.d.ts +39 -0
- package/vendor/hyperframes/dist/studio/styles/tailwind-preset.js +50 -0
- package/vendor/hyperframes/dist/studio/styles/tailwind-preset.js.map +1 -0
- package/vendor/hyperframes/dist/studio/styles.css +1 -0
- package/vendor/hyperframes/dist/studio/ui.d.ts +296 -0
- package/vendor/hyperframes/dist/studio/ui.js +66 -0
- package/vendor/hyperframes/dist/studio/ui.js.map +1 -0
- package/vendor/hyperframes/dist/studio-api-PNQZRPX5.js +136 -0
- package/vendor/hyperframes/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
- package/vendor/hyperframes/dist/studioServer-UWRBPIOJ.js +1457 -0
- package/vendor/hyperframes/dist/synthesize-K62TIZWI.js +182 -0
- package/vendor/hyperframes/dist/system-EZYZNUFD.js +44 -0
- package/vendor/hyperframes/dist/telemetry-2YC4SGQU.js +144 -0
- package/vendor/hyperframes/dist/telemetry-QMYM4WME.js +95 -0
- package/vendor/hyperframes/dist/templates/_shared/AGENTS.md +107 -0
- package/vendor/hyperframes/dist/templates/_shared/CLAUDE.md +107 -0
- package/vendor/hyperframes/dist/templates/blank/index.html +55 -0
- package/vendor/hyperframes/dist/templates/from-file/index.html +75 -0
- package/vendor/hyperframes/dist/templates/warm-grain/compositions/captions.html +154 -0
- package/vendor/hyperframes/dist/templates/warm-grain/compositions/graphics.html +162 -0
- package/vendor/hyperframes/dist/templates/warm-grain/compositions/intro.html +87 -0
- package/vendor/hyperframes/dist/templates/warm-grain/index.html +264 -0
- package/vendor/hyperframes/dist/templates/warm-grain/registry-item.json +34 -0
- package/vendor/hyperframes/dist/timeline-77Z3BBQM.js +1377 -0
- package/vendor/hyperframes/dist/tokens-OBGTYE4Z.js +92 -0
- package/vendor/hyperframes/dist/transcribe-7NVFHCGA.js +387 -0
- package/vendor/hyperframes/dist/transcribe-BNSJRR4M.js +62 -0
- package/vendor/hyperframes/dist/tts-P3LIPIL5.js +234 -0
- package/vendor/hyperframes/dist/updateCheck-UDWIJ4ZQ.js +39 -0
- package/vendor/hyperframes/dist/upgrade-CT3CPO3E.js +231 -0
- package/vendor/hyperframes/dist/urlDownloader-H6WRI2UE.js +39 -0
- package/vendor/hyperframes/dist/usage-EC3KFUIJ.js +2139 -0
- package/vendor/hyperframes/dist/validate-65QDZJWZ.js +70 -0
- package/vendor/hyperframes/dist/video-FGSGKRSV.js +261 -0
- package/vendor/hyperframes/dist/workspaceBuildCheck-TOLGAI4T.js +133 -0
- package/vendor/hyperframes/package.json +80 -0
|
@@ -0,0 +1,1377 @@
|
|
|
1
|
+
import { createRequire as __hf_createRequire } from "node:module";
|
|
2
|
+
import { fileURLToPath as __hf_fileURLToPath } from "node:url";
|
|
3
|
+
import { dirname as __hf_dirname } from "node:path";
|
|
4
|
+
var require = __hf_createRequire(import.meta.url);
|
|
5
|
+
var __filename = __hf_fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = __hf_dirname(__filename);
|
|
7
|
+
import {
|
|
8
|
+
readCompositionFps
|
|
9
|
+
} from "./chunk-YEIFI443.js";
|
|
10
|
+
import {
|
|
11
|
+
applyFileMutations,
|
|
12
|
+
duplicateElementInHtml,
|
|
13
|
+
fileContentVersion
|
|
14
|
+
} from "./chunk-S7NPLFWV.js";
|
|
15
|
+
import {
|
|
16
|
+
findSyncPartner,
|
|
17
|
+
patchElementInHtml,
|
|
18
|
+
readLinkTiming,
|
|
19
|
+
removeElementFromHtml,
|
|
20
|
+
splitElementInHtml,
|
|
21
|
+
syncOffsetFrames
|
|
22
|
+
} from "./chunk-RMHUQGRK.js";
|
|
23
|
+
import "./chunk-EOVYQ3IG.js";
|
|
24
|
+
import "./chunk-QC4FJVLM.js";
|
|
25
|
+
import "./chunk-TCLGPL65.js";
|
|
26
|
+
import {
|
|
27
|
+
resolveProject
|
|
28
|
+
} from "./chunk-S3D6GE5W.js";
|
|
29
|
+
import "./chunk-IHFUKJOR.js";
|
|
30
|
+
import {
|
|
31
|
+
ensureDOMParser
|
|
32
|
+
} from "./chunk-PFCFR3KZ.js";
|
|
33
|
+
import "./chunk-4NWOGZZS.js";
|
|
34
|
+
import "./chunk-JTHMTOMQ.js";
|
|
35
|
+
import "./chunk-EISRN4E6.js";
|
|
36
|
+
import "./chunk-VWG7OQKU.js";
|
|
37
|
+
import "./chunk-ZTZA4UWZ.js";
|
|
38
|
+
import "./chunk-IUZFXWSV.js";
|
|
39
|
+
import "./chunk-AMKC3AXA.js";
|
|
40
|
+
import {
|
|
41
|
+
defineCommand
|
|
42
|
+
} from "./chunk-S3S4TGEH.js";
|
|
43
|
+
import "./chunk-54HJ63Q2.js";
|
|
44
|
+
import {
|
|
45
|
+
setCommandExitCode
|
|
46
|
+
} from "./chunk-PBN6GBJE.js";
|
|
47
|
+
import "./chunk-KC5XXX3X.js";
|
|
48
|
+
import "./chunk-TJSTGSAW.js";
|
|
49
|
+
import {
|
|
50
|
+
HF_AUDIO_GROUP_ATTR,
|
|
51
|
+
extractAudioMetadata,
|
|
52
|
+
extractMediaMetadata,
|
|
53
|
+
resolveReferencedDuration,
|
|
54
|
+
resolveReferencedStart
|
|
55
|
+
} from "./chunk-K2FTXJYH.js";
|
|
56
|
+
import {
|
|
57
|
+
byStart,
|
|
58
|
+
fpsToNumber,
|
|
59
|
+
isInsideSpan,
|
|
60
|
+
parseFpsWithDefault,
|
|
61
|
+
resolveMediaStartSeconds,
|
|
62
|
+
sameInstant,
|
|
63
|
+
spansShareTime
|
|
64
|
+
} from "./chunk-2YN64IN5.js";
|
|
65
|
+
import {
|
|
66
|
+
topLevelElements,
|
|
67
|
+
trackKindOf
|
|
68
|
+
} from "./chunk-AVUUN2XD.js";
|
|
69
|
+
import "./chunk-DPVXBVLL.js";
|
|
70
|
+
import {
|
|
71
|
+
ensureHfIds
|
|
72
|
+
} from "./chunk-Z6B37SNM.js";
|
|
73
|
+
import {
|
|
74
|
+
HF_AUDIO_AUTOMATION_ATTR,
|
|
75
|
+
HF_AUDIO_FX_ATTR,
|
|
76
|
+
parseAudioFxChain,
|
|
77
|
+
parseAutomation,
|
|
78
|
+
resolveAutomation
|
|
79
|
+
} from "./chunk-HWKCIWQT.js";
|
|
80
|
+
import "./chunk-VC76R6W2.js";
|
|
81
|
+
import "./chunk-OFQWTKPW.js";
|
|
82
|
+
import "./chunk-TWWSYAKJ.js";
|
|
83
|
+
import "./chunk-ZJUKFZ2P.js";
|
|
84
|
+
import "./chunk-HBBJFK6I.js";
|
|
85
|
+
import "./chunk-PJ3HDUCY.js";
|
|
86
|
+
import {
|
|
87
|
+
parseNumeric,
|
|
88
|
+
readMediaOffsetSeconds,
|
|
89
|
+
readPlaybackRate,
|
|
90
|
+
resolveMediaDuration
|
|
91
|
+
} from "./chunk-TQFG7HTI.js";
|
|
92
|
+
import "./chunk-GK4AIFIH.js";
|
|
93
|
+
import "./chunk-2PSPARWP.js";
|
|
94
|
+
import {
|
|
95
|
+
withMeta
|
|
96
|
+
} from "./chunk-HW6OYASV.js";
|
|
97
|
+
import "./chunk-K4WIOZFP.js";
|
|
98
|
+
import "./chunk-XUXGIA7H.js";
|
|
99
|
+
import "./chunk-WERLJGIC.js";
|
|
100
|
+
import "./chunk-ISN5GRYI.js";
|
|
101
|
+
import "./chunk-FLWXXDNS.js";
|
|
102
|
+
import "./chunk-KNU5COPB.js";
|
|
103
|
+
import "./chunk-3GXQPCJC.js";
|
|
104
|
+
import "./chunk-RQVDTPGD.js";
|
|
105
|
+
import "./chunk-PMRBLBUP.js";
|
|
106
|
+
import "./chunk-M2WBOQ2Q.js";
|
|
107
|
+
|
|
108
|
+
// src/timeline/describeProject.ts
|
|
109
|
+
import { readFileSync, realpathSync, statSync } from "fs";
|
|
110
|
+
import { basename, dirname, isAbsolute, relative, resolve, sep } from "path";
|
|
111
|
+
var TRACK_ORDER = ["video", "graphics", "captions", "audio"];
|
|
112
|
+
function toNode(el) {
|
|
113
|
+
const attrs = {};
|
|
114
|
+
for (const { name, value } of Array.from(el.attributes)) attrs[name] = value;
|
|
115
|
+
return { tag: el.tagName, attrs, children: Array.from(el.children).map(toNode), el };
|
|
116
|
+
}
|
|
117
|
+
function safeChain(raw) {
|
|
118
|
+
try {
|
|
119
|
+
return parseAudioFxChain(raw);
|
|
120
|
+
} catch {
|
|
121
|
+
return void 0;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function readLanes(el) {
|
|
125
|
+
const raw = el.getAttribute(HF_AUDIO_AUTOMATION_ATTR);
|
|
126
|
+
if (!raw) return { lanes: [], laneError: null };
|
|
127
|
+
try {
|
|
128
|
+
const fx = el.getAttribute(HF_AUDIO_FX_ATTR);
|
|
129
|
+
const chain = fx ? safeChain(fx) : void 0;
|
|
130
|
+
const lanes = resolveAutomation(parseAutomation(raw), chain).lanes.map((lane) => ({
|
|
131
|
+
target: lane.target,
|
|
132
|
+
points: lane.points.map(({ t, v }) => ({ t, v }))
|
|
133
|
+
}));
|
|
134
|
+
return { lanes, laneError: null };
|
|
135
|
+
} catch (err) {
|
|
136
|
+
return { lanes: [], laneError: err instanceof Error ? err.message : String(err) };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
var measureWithFfprobe = async (file, tag) => (tag === "audio" ? await extractAudioMetadata(file) : await extractMediaMetadata(file)).durationSeconds;
|
|
140
|
+
var MEDIA_TAG = /^(video|audio|img)$/;
|
|
141
|
+
var PROBE_CONCURRENCY = 4;
|
|
142
|
+
function createProbeGate(max) {
|
|
143
|
+
let active = 0;
|
|
144
|
+
const waiting = [];
|
|
145
|
+
return async function withProbeSlot(fn) {
|
|
146
|
+
if (active >= max) await new Promise((wake) => waiting.push(wake));
|
|
147
|
+
else active += 1;
|
|
148
|
+
try {
|
|
149
|
+
return await fn();
|
|
150
|
+
} finally {
|
|
151
|
+
const next = waiting.shift();
|
|
152
|
+
if (next) next();
|
|
153
|
+
else active -= 1;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
async function probeSource(scope, el, tag) {
|
|
158
|
+
const src = el.getAttribute("src");
|
|
159
|
+
if (!src) return { ok: false, reason: "no src attribute" };
|
|
160
|
+
if (/^https?:\/\//i.test(src)) return { ok: false, reason: "remote source not probed" };
|
|
161
|
+
const file = realFileInside(scope.projectDir, resolve(scope.dir, src));
|
|
162
|
+
if (!file) return { ok: false, reason: "source file not found" };
|
|
163
|
+
return scope.withProbeSlot(async () => {
|
|
164
|
+
try {
|
|
165
|
+
return { ok: true, seconds: await scope.measure(file, tag) };
|
|
166
|
+
} catch (err) {
|
|
167
|
+
return { ok: false, reason: err instanceof Error ? err.message : String(err) };
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function resolveContainerDuration(authored, children) {
|
|
172
|
+
if (authored !== null)
|
|
173
|
+
return { duration: authored, durationSource: "authored", pendingReason: null };
|
|
174
|
+
if (children.length === 0) return { duration: 0, durationSource: null, pendingReason: null };
|
|
175
|
+
const inner = children.reduce((max, c) => Math.max(max, c.end), 0);
|
|
176
|
+
return { duration: inner, durationSource: "inner", pendingReason: null };
|
|
177
|
+
}
|
|
178
|
+
async function resolveMediaRowDuration(scope, el, tag, authored) {
|
|
179
|
+
const getAttr = (name) => el.getAttribute(name);
|
|
180
|
+
const input = {
|
|
181
|
+
tag,
|
|
182
|
+
authoredDurationSeconds: authored,
|
|
183
|
+
mediaStartSeconds: readMediaOffsetSeconds(getAttr),
|
|
184
|
+
playbackRate: readPlaybackRate(getAttr)
|
|
185
|
+
};
|
|
186
|
+
const unprobed = resolveMediaDuration({ ...input, sourceDurationSeconds: null });
|
|
187
|
+
if (unprobed.source !== "pending") {
|
|
188
|
+
return {
|
|
189
|
+
duration: unprobed.seconds ?? 0,
|
|
190
|
+
durationSource: unprobed.source,
|
|
191
|
+
pendingReason: null
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const probe = await probeSource(scope, el, tag);
|
|
195
|
+
const measured = probe.ok && probe.seconds > 0 ? probe.seconds : null;
|
|
196
|
+
const result = resolveMediaDuration({ ...input, sourceDurationSeconds: measured });
|
|
197
|
+
return {
|
|
198
|
+
duration: result.seconds ?? 0,
|
|
199
|
+
durationSource: result.source,
|
|
200
|
+
pendingReason: result.source === "pending" ? pendingReason(probe, result.reason) : null
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
function pendingReason(probe, resolverReason) {
|
|
204
|
+
if (!probe.ok) return probe.reason;
|
|
205
|
+
return probe.seconds > 0 ? resolverReason ?? "source duration unavailable" : "source reports no duration";
|
|
206
|
+
}
|
|
207
|
+
var roundMs = (v) => Math.round(v * 1e3) / 1e3;
|
|
208
|
+
function mainTimelineStart(scope, el, start) {
|
|
209
|
+
const ordinaryStart = () => scope.origin + start;
|
|
210
|
+
if (!/^(video|audio)$/i.test(el.tagName)) return ordinaryStart();
|
|
211
|
+
return resolveMediaStartSeconds({
|
|
212
|
+
authoredStart: parseNumeric(el.getAttribute("data-start")),
|
|
213
|
+
hostStart: scope.origin,
|
|
214
|
+
hasAutoStart: el.hasAttribute("data-hf-auto-start"),
|
|
215
|
+
basis: el.getAttribute("data-hf-media-start-basis"),
|
|
216
|
+
ordinaryStart
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async function resolveRowTiming(scope, node, depth) {
|
|
220
|
+
const { el } = node;
|
|
221
|
+
const start = resolveReferencedStart(scope.doc, el, scope.startCache, /* @__PURE__ */ new Set());
|
|
222
|
+
const authored = resolveReferencedDuration(scope.doc, el, scope.startCache, /* @__PURE__ */ new Set());
|
|
223
|
+
const host = el.getAttribute("data-composition-src");
|
|
224
|
+
const absStart = mainTimelineStart(scope, el, start);
|
|
225
|
+
const children = host && depth === 0 ? await readSubComposition(host, scope, absStart) : [];
|
|
226
|
+
const kind = el.tagName.toLowerCase();
|
|
227
|
+
const duration = MEDIA_TAG.test(kind) ? await resolveMediaRowDuration(scope, el, kind, authored) : resolveContainerDuration(authored, children);
|
|
228
|
+
return { start, authored, absStart, children, duration };
|
|
229
|
+
}
|
|
230
|
+
function describeRowFields(scope, node, timing) {
|
|
231
|
+
const { el } = node;
|
|
232
|
+
const kind = el.tagName.toLowerCase();
|
|
233
|
+
const host = el.getAttribute("data-composition-src");
|
|
234
|
+
const rate = parseNumeric(el.getAttribute("data-playback-rate"));
|
|
235
|
+
return {
|
|
236
|
+
id: el.id || el.getAttribute("data-composition-id") || kind,
|
|
237
|
+
label: null,
|
|
238
|
+
kind,
|
|
239
|
+
trackKind: trackKindOf(node).kind,
|
|
240
|
+
start: timing.start,
|
|
241
|
+
duration: timing.duration.duration,
|
|
242
|
+
end: timing.start + timing.duration.duration,
|
|
243
|
+
absStart: roundMs(timing.absStart),
|
|
244
|
+
absEnd: roundMs(timing.absStart + timing.duration.duration),
|
|
245
|
+
file: scope.file,
|
|
246
|
+
trackIndex: parseNumeric(el.getAttribute("data-track-index")) ?? 0,
|
|
247
|
+
src: el.getAttribute("src") ?? host,
|
|
248
|
+
sourceFile: host,
|
|
249
|
+
volume: parseNumeric(el.getAttribute("data-volume")),
|
|
250
|
+
...readLanes(el),
|
|
251
|
+
playbackRate: rate === 1 ? null : rate,
|
|
252
|
+
audioGroup: el.getAttribute(HF_AUDIO_GROUP_ATTR),
|
|
253
|
+
role: null,
|
|
254
|
+
durationAuthored: timing.authored !== null,
|
|
255
|
+
durationSource: timing.duration.durationSource,
|
|
256
|
+
pendingReason: timing.duration.pendingReason,
|
|
257
|
+
children: timing.children,
|
|
258
|
+
ref: "",
|
|
259
|
+
warnings: [],
|
|
260
|
+
elementId: el.id || null,
|
|
261
|
+
hfId: el.getAttribute("data-hf-id"),
|
|
262
|
+
syncOffsetFrames: syncOffsetOf(el, scope.fps)
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
function syncOffsetOf(el, fps) {
|
|
266
|
+
const partner = findSyncPartner(el);
|
|
267
|
+
return partner ? syncOffsetFrames(readLinkTiming(el), readLinkTiming(partner), fps) : null;
|
|
268
|
+
}
|
|
269
|
+
async function describeRow(scope, node, depth) {
|
|
270
|
+
return describeRowFields(scope, node, await resolveRowTiming(scope, node, depth));
|
|
271
|
+
}
|
|
272
|
+
async function readSubComposition(src, parent, origin) {
|
|
273
|
+
const authored = resolve(parent.dir, src);
|
|
274
|
+
const file = realFileInside(parent.projectDir, authored);
|
|
275
|
+
if (!file) return [];
|
|
276
|
+
const relativeFile = relative(parent.projectDir, authored).split(sep).join("/");
|
|
277
|
+
const source = parent.sourceOverrides.get(relativeFile) ?? readFileSync(file, "utf-8");
|
|
278
|
+
const doc = new DOMParser().parseFromString(source, "text/html");
|
|
279
|
+
const template = doc.querySelector("template");
|
|
280
|
+
const root = (template?.content ?? doc).querySelector("[data-composition-id]");
|
|
281
|
+
if (!root) return [];
|
|
282
|
+
const scope = {
|
|
283
|
+
doc,
|
|
284
|
+
dir: dirname(file),
|
|
285
|
+
startCache: /* @__PURE__ */ new Map(),
|
|
286
|
+
projectDir: parent.projectDir,
|
|
287
|
+
origin,
|
|
288
|
+
file: relative(parent.projectDir, authored).split(sep).join("/"),
|
|
289
|
+
withProbeSlot: parent.withProbeSlot,
|
|
290
|
+
measure: parent.measure,
|
|
291
|
+
sourceOverrides: parent.sourceOverrides,
|
|
292
|
+
fps: parent.fps
|
|
293
|
+
};
|
|
294
|
+
const rows = await Promise.all(
|
|
295
|
+
topLevelElements(toNode(root)).map((node) => describeRow(scope, node, 1))
|
|
296
|
+
);
|
|
297
|
+
return rows.sort(byStart);
|
|
298
|
+
}
|
|
299
|
+
function realFileInside(projectDir, path) {
|
|
300
|
+
try {
|
|
301
|
+
const real = realpathSync(path);
|
|
302
|
+
const inside = relative(realpathSync(projectDir), real);
|
|
303
|
+
if (inside === ".." || inside.startsWith(`..${sep}`) || isAbsolute(inside)) return null;
|
|
304
|
+
return statSync(real).isFile() ? real : null;
|
|
305
|
+
} catch {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function flatten(top) {
|
|
310
|
+
const entries = [
|
|
311
|
+
...top.map((clip) => ({ clip, host: null })),
|
|
312
|
+
...top.flatMap((host) => host.children.map((clip) => ({ clip, host })))
|
|
313
|
+
];
|
|
314
|
+
const byKind = TRACK_ORDER.map((kind) => ({
|
|
315
|
+
kind,
|
|
316
|
+
entries: entries.filter((e) => e.clip.trackKind === kind).sort((a, b) => a.clip.absStart - b.clip.absStart)
|
|
317
|
+
})).filter((t) => t.entries.length > 0);
|
|
318
|
+
const pointers = new Map(
|
|
319
|
+
byKind.flatMap((t) => t.entries.map((e, index) => [e.clip, { kind: t.kind, index }]))
|
|
320
|
+
);
|
|
321
|
+
const at = (clip) => pointers.get(clip);
|
|
322
|
+
const fileIds = /* @__PURE__ */ new Map();
|
|
323
|
+
for (const { entries: entries2 } of byKind) {
|
|
324
|
+
for (const { clip } of entries2) {
|
|
325
|
+
if (!clip.elementId) continue;
|
|
326
|
+
const ids = fileIds.get(clip.file) ?? /* @__PURE__ */ new Map();
|
|
327
|
+
ids.set(clip.elementId, (ids.get(clip.elementId) ?? 0) + 1);
|
|
328
|
+
fileIds.set(clip.file, ids);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return byKind.map(({ kind, entries: kindEntries }) => ({
|
|
332
|
+
kind,
|
|
333
|
+
rows: kindEntries.map(({ clip, host }, index) => {
|
|
334
|
+
const uniqueId = clip.elementId && fileIds.get(clip.file)?.get(clip.elementId) === 1;
|
|
335
|
+
const ref = uniqueId ? `#${clip.elementId}` : clip.hfId ? `hf:${clip.hfId}` : `${kind}/${index}`;
|
|
336
|
+
const warnings = uniqueId || clip.hfId ? [] : [
|
|
337
|
+
'row has no stable name; add id="<name>" to the element in this file, then retry with #<name>'
|
|
338
|
+
];
|
|
339
|
+
return {
|
|
340
|
+
...clip,
|
|
341
|
+
index,
|
|
342
|
+
ref,
|
|
343
|
+
warnings,
|
|
344
|
+
nested: host !== null,
|
|
345
|
+
host: host && host.id,
|
|
346
|
+
hostRow: host && at(host),
|
|
347
|
+
children: clip.children.map(at)
|
|
348
|
+
};
|
|
349
|
+
})
|
|
350
|
+
}));
|
|
351
|
+
}
|
|
352
|
+
function projectFps(source) {
|
|
353
|
+
const parsed = parseFpsWithDefault(readCompositionFps(source) ?? void 0);
|
|
354
|
+
return fpsToNumber(parsed.ok ? parsed.value : { num: 30, den: 1 });
|
|
355
|
+
}
|
|
356
|
+
async function describeProject(indexPath, measure = measureWithFfprobe, sourceOverrides = /* @__PURE__ */ new Map()) {
|
|
357
|
+
const projectDir = dirname(indexPath);
|
|
358
|
+
const source = sourceOverrides.get(basename(indexPath)) ?? readFileSync(indexPath, "utf-8");
|
|
359
|
+
const doc = new DOMParser().parseFromString(source, "text/html");
|
|
360
|
+
const root = doc.querySelector("[data-composition-id]") ?? doc.body;
|
|
361
|
+
const dir = projectDir;
|
|
362
|
+
const scope = {
|
|
363
|
+
doc,
|
|
364
|
+
dir,
|
|
365
|
+
startCache: /* @__PURE__ */ new Map(),
|
|
366
|
+
projectDir: dir,
|
|
367
|
+
origin: 0,
|
|
368
|
+
file: basename(indexPath),
|
|
369
|
+
withProbeSlot: createProbeGate(PROBE_CONCURRENCY),
|
|
370
|
+
measure,
|
|
371
|
+
sourceOverrides,
|
|
372
|
+
fps: projectFps(source)
|
|
373
|
+
};
|
|
374
|
+
const rows = (await Promise.all(topLevelElements(toNode(root)).map((node) => describeRow(scope, node, 0)))).sort(byStart);
|
|
375
|
+
const declared = parseNumeric(root.getAttribute("data-duration"));
|
|
376
|
+
return {
|
|
377
|
+
duration: declared ?? rows.reduce((max, r) => Math.max(max, r.end), 0),
|
|
378
|
+
tracks: flatten(rows)
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/timeline/formatTimeline.ts
|
|
383
|
+
var BAR_WIDTH = 40;
|
|
384
|
+
var n = (v) => String(Math.round(v * 1e3) / 1e3);
|
|
385
|
+
function bar(row, total) {
|
|
386
|
+
if (total <= 0) return " ".repeat(BAR_WIDTH);
|
|
387
|
+
const known = row.durationAuthored || row.duration > 0;
|
|
388
|
+
const from = Math.min(BAR_WIDTH - 1, Math.floor(row.absStart / total * BAR_WIDTH));
|
|
389
|
+
const to = known ? row.absEnd / total * BAR_WIDTH : BAR_WIDTH;
|
|
390
|
+
const width = Math.max(1, Math.min(BAR_WIDTH, Math.ceil(to)) - from);
|
|
391
|
+
const fill = known ? "\u2588" : "\u2591";
|
|
392
|
+
return " ".repeat(from) + fill.repeat(width) + " ".repeat(BAR_WIDTH - from - width);
|
|
393
|
+
}
|
|
394
|
+
function durationNote(row) {
|
|
395
|
+
switch (row.durationSource) {
|
|
396
|
+
case "media":
|
|
397
|
+
case "default":
|
|
398
|
+
return `duration=${row.durationSource}`;
|
|
399
|
+
case "inner":
|
|
400
|
+
return "duration=inferred";
|
|
401
|
+
case "pending":
|
|
402
|
+
return `pending: ${row.pendingReason}`;
|
|
403
|
+
case "authored":
|
|
404
|
+
case null:
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function syncNote(frames) {
|
|
409
|
+
if (!frames) return false;
|
|
410
|
+
return `out-of-sync=${frames > 0 ? "+" : ""}${frames}f`;
|
|
411
|
+
}
|
|
412
|
+
function details(row) {
|
|
413
|
+
const lanes = row.lanes.map(
|
|
414
|
+
(l) => `${l.target}[${l.points.map((p) => `${n(p.t)}:${n(p.v)}`).join(" ")}]`
|
|
415
|
+
);
|
|
416
|
+
return [
|
|
417
|
+
row.src && `src=${row.src}`,
|
|
418
|
+
row.volume !== null && `vol=${row.volume}`,
|
|
419
|
+
row.playbackRate !== null && `rate=${n(row.playbackRate)}`,
|
|
420
|
+
row.audioGroup && `group=${row.audioGroup}`,
|
|
421
|
+
syncNote(row.syncOffsetFrames),
|
|
422
|
+
durationNote(row),
|
|
423
|
+
row.sourceFile && !row.children.length && "children=unread",
|
|
424
|
+
row.laneError && `lanes unreadable: ${row.laneError}`,
|
|
425
|
+
...lanes
|
|
426
|
+
].filter(Boolean).join(" ");
|
|
427
|
+
}
|
|
428
|
+
var span = (a, b) => `${n(a)}-${n(b)}s`;
|
|
429
|
+
function line(row, total) {
|
|
430
|
+
const times = row.host ? `${span(row.absStart, row.absEnd)} (local ${span(row.start, row.end)}) nested in ${row.host} ${row.file}` : span(row.start, row.end);
|
|
431
|
+
return ` |${bar(row, total)}| ${row.ref} ${row.id} ${times} ${details(row)}`.trimEnd();
|
|
432
|
+
}
|
|
433
|
+
function header({ kind, rows }) {
|
|
434
|
+
const nested = rows.filter((r) => r.nested).length;
|
|
435
|
+
const split = nested ? `: ${rows.length - nested} top-level, ${nested} nested` : "";
|
|
436
|
+
return `${kind} (${rows.length}${split})`;
|
|
437
|
+
}
|
|
438
|
+
function formatTimeline(timeline) {
|
|
439
|
+
const out = [`timeline ${n(timeline.duration)}s`];
|
|
440
|
+
for (const track of timeline.tracks) {
|
|
441
|
+
out.push("", header(track));
|
|
442
|
+
for (const row of track.rows) out.push(line(row, timeline.duration));
|
|
443
|
+
}
|
|
444
|
+
return out.join("\n");
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// src/timeline/a2Commands.ts
|
|
448
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
449
|
+
import { join } from "path";
|
|
450
|
+
|
|
451
|
+
// src/timeline/resolveRef.ts
|
|
452
|
+
function targetFor(row) {
|
|
453
|
+
if (row.ref.startsWith("#")) return { id: row.ref.slice(1) };
|
|
454
|
+
if (row.ref.startsWith("hf:")) return { hfId: row.ref.slice(3) };
|
|
455
|
+
return row.id && row.id !== row.kind ? { id: row.id } : null;
|
|
456
|
+
}
|
|
457
|
+
function resolveRef(timeline, ref) {
|
|
458
|
+
const rows = timeline.tracks.flatMap((track) => track.rows);
|
|
459
|
+
const matches = ref.startsWith("#") ? rows.filter((row2) => row2.ref === ref || row2.id === ref.slice(1)) : ref.startsWith("hf:") ? rows.filter((row2) => row2.ref === ref) : (() => {
|
|
460
|
+
const match = /^(video|graphics|captions|audio)\/(\d+)$/.exec(ref);
|
|
461
|
+
if (!match) return [];
|
|
462
|
+
const row2 = timeline.tracks.find((track) => track.kind === match[1])?.rows.find((candidate) => candidate.index === Number(match[2]));
|
|
463
|
+
return row2 ? [row2] : [];
|
|
464
|
+
})();
|
|
465
|
+
if (matches.length !== 1) {
|
|
466
|
+
return {
|
|
467
|
+
ok: false,
|
|
468
|
+
reason: matches.length === 0 ? `${ref} was not found` : `${ref} matches ${matches.length} rows`,
|
|
469
|
+
fix: 'add id="<name>" to the element in its source file, then retry with #<name>'
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
const row = matches[0];
|
|
473
|
+
const target = targetFor(row);
|
|
474
|
+
if (!target) {
|
|
475
|
+
return {
|
|
476
|
+
ok: false,
|
|
477
|
+
reason: `${ref} has no stable element id in ${row.file}`,
|
|
478
|
+
fix: `add id="<name>" to the element in ${row.file}, then retry with #<name>`
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
return { ok: true, row, target };
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// src/timeline/timeExpr.ts
|
|
485
|
+
function parseTimeExpression(expression, context) {
|
|
486
|
+
const raw = expression.trim();
|
|
487
|
+
if (raw === "end") return { ok: true, seconds: context.duration };
|
|
488
|
+
const frames = /^(-?\d+(?:\.\d+)?)f$/.exec(raw);
|
|
489
|
+
if (frames) return { ok: true, seconds: Number(frames[1]) / context.fps };
|
|
490
|
+
const absolute = /^\d+(?:\.\d+)?$/.test(raw);
|
|
491
|
+
const relative2 = /^[+-]\d+(?:\.\d+)?$/.test(raw);
|
|
492
|
+
if (absolute) return { ok: true, seconds: Number(raw) };
|
|
493
|
+
if (relative2) return { ok: true, seconds: context.row.start + Number(raw) };
|
|
494
|
+
const anchor = /^(after|before|start-of|end-of):(.+)$/.exec(raw);
|
|
495
|
+
if (!anchor) return { ok: false, reason: `invalid time expression: ${expression}` };
|
|
496
|
+
const row = context.resolveAnchor(anchor[2]);
|
|
497
|
+
if (!row) return { ok: false, reason: `anchor ref not found: ${anchor[2]}` };
|
|
498
|
+
switch (anchor[1]) {
|
|
499
|
+
case "after":
|
|
500
|
+
case "end-of":
|
|
501
|
+
return { ok: true, seconds: row.end };
|
|
502
|
+
case "before":
|
|
503
|
+
case "start-of":
|
|
504
|
+
return { ok: true, seconds: row.start };
|
|
505
|
+
}
|
|
506
|
+
return { ok: false, reason: `invalid time anchor: ${anchor[1]}` };
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// src/timeline/a2Shared.ts
|
|
510
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
511
|
+
|
|
512
|
+
// src/timeline/a2Mutations.ts
|
|
513
|
+
function parseSetAssignments(values) {
|
|
514
|
+
const assignments = [];
|
|
515
|
+
for (const value of values) {
|
|
516
|
+
const match = /^(volume|rate|track)=(.+)$/.exec(value);
|
|
517
|
+
if (!match) {
|
|
518
|
+
return {
|
|
519
|
+
ok: false,
|
|
520
|
+
reason: `unsupported set assignment ${value}`,
|
|
521
|
+
fix: "use volume=<number>, rate=<number>, or track=<number>"
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
const fieldValue = match[1];
|
|
525
|
+
if (!fieldValue) {
|
|
526
|
+
return {
|
|
527
|
+
ok: false,
|
|
528
|
+
reason: `unsupported set assignment ${value}`,
|
|
529
|
+
fix: "use volume=<number>, rate=<number>, or track=<number>"
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
const field = parseSetField(fieldValue);
|
|
533
|
+
const number = Number(match[2]);
|
|
534
|
+
if (!Number.isFinite(number) || field === "track" && !Number.isInteger(number)) {
|
|
535
|
+
return {
|
|
536
|
+
ok: false,
|
|
537
|
+
reason: `${field} must be a valid ${field === "track" ? "integer" : "number"}`,
|
|
538
|
+
fix: `pass ${field}=<number>`
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
if (field === "rate" && number <= 0) {
|
|
542
|
+
return { ok: false, reason: "rate must be positive", fix: "pass rate=<positive number>" };
|
|
543
|
+
}
|
|
544
|
+
assignments.push({ field, value: String(number) });
|
|
545
|
+
}
|
|
546
|
+
return { ok: true, assignments };
|
|
547
|
+
}
|
|
548
|
+
function parseSetField(value) {
|
|
549
|
+
switch (value) {
|
|
550
|
+
case "volume":
|
|
551
|
+
case "rate":
|
|
552
|
+
case "track":
|
|
553
|
+
return value;
|
|
554
|
+
}
|
|
555
|
+
throw new Error(`unsupported set field ${value}`);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// src/timeline/a2Shared.ts
|
|
559
|
+
var allRows = (timeline) => timeline.tracks.flatMap((track) => track.rows);
|
|
560
|
+
function refusal(reason, fix, json) {
|
|
561
|
+
setCommandExitCode(2);
|
|
562
|
+
const payload = { ok: false, reason, fix };
|
|
563
|
+
console.error(json ? JSON.stringify(payload, null, 2) : `${reason}; ${fix}.`);
|
|
564
|
+
}
|
|
565
|
+
var isFileChanged = (error) => error instanceof Error && error.message === "file changed since the timeline was read";
|
|
566
|
+
function refuse(kind, detail, json) {
|
|
567
|
+
refusal(`${kind}: ${detail.reason}`, detail.fix, json);
|
|
568
|
+
}
|
|
569
|
+
function publicReceipt(receipt) {
|
|
570
|
+
return {
|
|
571
|
+
file: receipt.sourceFile,
|
|
572
|
+
version: receipt.version,
|
|
573
|
+
writeToken: receipt.writeToken,
|
|
574
|
+
changed: receipt.changed,
|
|
575
|
+
backupPath: receipt.backupPath
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
function fpsFor(indexPath) {
|
|
579
|
+
const parsed = parseFpsWithDefault(
|
|
580
|
+
readCompositionFps(readFileSync2(indexPath, "utf-8")) ?? void 0
|
|
581
|
+
);
|
|
582
|
+
return fpsToNumber(parsed.ok ? parsed.value : { num: 30, den: 1 });
|
|
583
|
+
}
|
|
584
|
+
function declaredFps(source) {
|
|
585
|
+
const raw = readCompositionFps(source);
|
|
586
|
+
if (raw === null) return null;
|
|
587
|
+
const parsed = parseFpsWithDefault(raw);
|
|
588
|
+
return parsed.ok ? fpsToNumber(parsed.value) : null;
|
|
589
|
+
}
|
|
590
|
+
function splitBaseId(row) {
|
|
591
|
+
return row.ref.startsWith("hf:") ? row.ref.slice(3) : row.id;
|
|
592
|
+
}
|
|
593
|
+
function nextFreeSplitId(source, base) {
|
|
594
|
+
const document = new DOMParser().parseFromString(source, "text/html");
|
|
595
|
+
const existing = new Set(Array.from(document.querySelectorAll("[id]"), (element) => element.id));
|
|
596
|
+
const match = /^(.*)-(\d+)$/.exec(base);
|
|
597
|
+
const prefix = match && existing.has(match[1]) ? match[1] : base;
|
|
598
|
+
let suffix = 2;
|
|
599
|
+
while (existing.has(`${prefix}-${suffix}`)) suffix += 1;
|
|
600
|
+
return `${prefix}-${suffix}`;
|
|
601
|
+
}
|
|
602
|
+
function parseMutationTime(context, expression, fix) {
|
|
603
|
+
const value = context.parseTime(expression);
|
|
604
|
+
if (!value.ok) return { ok: false, reason: value.reason, fix };
|
|
605
|
+
if (value.seconds < 0 || value.seconds > context.duration) {
|
|
606
|
+
return {
|
|
607
|
+
ok: false,
|
|
608
|
+
reason: `time ${value.seconds} is outside the composition duration`,
|
|
609
|
+
fix: "pass a time between 0 and the composition duration"
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
return { ok: true, seconds: value.seconds };
|
|
613
|
+
}
|
|
614
|
+
function diff(before, after) {
|
|
615
|
+
if (before === after) return "";
|
|
616
|
+
const beforeLines = before.split("\n");
|
|
617
|
+
const afterLines = after.split("\n");
|
|
618
|
+
let prefix = 0;
|
|
619
|
+
while (prefix < beforeLines.length && prefix < afterLines.length && beforeLines[prefix] === afterLines[prefix]) {
|
|
620
|
+
prefix += 1;
|
|
621
|
+
}
|
|
622
|
+
let suffix = 0;
|
|
623
|
+
while (suffix < beforeLines.length - prefix && suffix < afterLines.length - prefix && beforeLines[beforeLines.length - suffix - 1] === afterLines[afterLines.length - suffix - 1]) {
|
|
624
|
+
suffix += 1;
|
|
625
|
+
}
|
|
626
|
+
const changedBefore = beforeLines.slice(prefix, beforeLines.length - suffix);
|
|
627
|
+
const changedAfter = afterLines.slice(prefix, afterLines.length - suffix);
|
|
628
|
+
const lines = [
|
|
629
|
+
"--- before",
|
|
630
|
+
"+++ after",
|
|
631
|
+
...changedBefore.map((line2) => `-${line2}`),
|
|
632
|
+
...changedAfter.map((line2) => `+${line2}`)
|
|
633
|
+
];
|
|
634
|
+
const output = lines.join("\n");
|
|
635
|
+
return output.length <= 8e3 ? output : `${output.slice(0, 7997)}...`;
|
|
636
|
+
}
|
|
637
|
+
function overlap(row, timeline, start, end) {
|
|
638
|
+
return allRows(timeline).find(
|
|
639
|
+
(candidate) => candidate !== row && candidate.file === row.file && candidate.trackIndex === row.trackIndex && spansShareTime(start, end, candidate.start, candidate.end)
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
function moveMutation(context, args) {
|
|
643
|
+
const expression = typeof args.time === "string" ? args.time : "";
|
|
644
|
+
const time = parseMutationTime(context, expression, "pass a valid time expression");
|
|
645
|
+
if (!time.ok) return time;
|
|
646
|
+
const end = time.seconds + context.row.duration;
|
|
647
|
+
if (end > context.duration) {
|
|
648
|
+
return {
|
|
649
|
+
ok: false,
|
|
650
|
+
reason: `move would end at ${end}, beyond composition duration ${context.duration}`,
|
|
651
|
+
fix: `choose a start at or before the latest valid start ${context.duration - context.row.duration}`
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
const patched = patchElementInHtml(context.before, context.resolved.target, [
|
|
655
|
+
{ type: "html-attribute", property: "data-start", value: String(time.seconds) }
|
|
656
|
+
]);
|
|
657
|
+
if (!patched.matched) {
|
|
658
|
+
return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
|
|
659
|
+
}
|
|
660
|
+
return {
|
|
661
|
+
ok: true,
|
|
662
|
+
after: patched.html,
|
|
663
|
+
nextStart: time.seconds,
|
|
664
|
+
nextDuration: context.row.duration
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
function splitMutation(context, args) {
|
|
668
|
+
const expression = typeof args.time === "string" ? args.time : "";
|
|
669
|
+
const time = parseMutationTime(context, expression, "pass a valid time expression");
|
|
670
|
+
if (!time.ok) return time;
|
|
671
|
+
const split = splitElementInHtml(
|
|
672
|
+
context.before,
|
|
673
|
+
context.resolved.target,
|
|
674
|
+
time.seconds,
|
|
675
|
+
nextFreeSplitId(context.before, splitBaseId(context.row)),
|
|
676
|
+
{
|
|
677
|
+
start: context.row.start,
|
|
678
|
+
duration: context.row.duration,
|
|
679
|
+
track: context.row.trackIndex
|
|
680
|
+
}
|
|
681
|
+
);
|
|
682
|
+
if (!split.matched || !split.newId) {
|
|
683
|
+
return {
|
|
684
|
+
ok: false,
|
|
685
|
+
reason: `${context.ref} cannot be split at ${time.seconds}`,
|
|
686
|
+
fix: "choose a time inside the clip"
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
return {
|
|
690
|
+
ok: true,
|
|
691
|
+
after: split.html,
|
|
692
|
+
nextStart: context.row.start,
|
|
693
|
+
nextDuration: context.row.duration
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
function trimMutation(context, args) {
|
|
697
|
+
const bounds = trimBounds(context, args);
|
|
698
|
+
if (!bounds.ok) return bounds;
|
|
699
|
+
const patched = patchElementInHtml(context.before, context.resolved.target, [
|
|
700
|
+
{ type: "html-attribute", property: "data-start", value: String(bounds.nextStart) },
|
|
701
|
+
{ type: "html-attribute", property: "data-duration", value: String(bounds.nextDuration) }
|
|
702
|
+
]);
|
|
703
|
+
if (!patched.matched) {
|
|
704
|
+
return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
|
|
705
|
+
}
|
|
706
|
+
return {
|
|
707
|
+
ok: true,
|
|
708
|
+
after: patched.html,
|
|
709
|
+
nextStart: bounds.nextStart,
|
|
710
|
+
nextDuration: bounds.nextDuration
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
function trimBounds(context, args) {
|
|
714
|
+
const input = trimInput(args);
|
|
715
|
+
if (!input.ok) return input;
|
|
716
|
+
const start = trimStart(context, input.start);
|
|
717
|
+
if (!start.ok) return start;
|
|
718
|
+
return finishTrim(
|
|
719
|
+
context,
|
|
720
|
+
start.seconds,
|
|
721
|
+
trimEnd(context, input.end),
|
|
722
|
+
trimDuration(context, input.duration)
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
function trimInput(args) {
|
|
726
|
+
const input = {
|
|
727
|
+
start: typeof args.start === "string" ? args.start : void 0,
|
|
728
|
+
end: typeof args.end === "string" ? args.end : void 0,
|
|
729
|
+
duration: typeof args.duration === "string" ? args.duration : void 0
|
|
730
|
+
};
|
|
731
|
+
if (input.start || input.end || input.duration) return { ok: true, ...input };
|
|
732
|
+
return {
|
|
733
|
+
ok: false,
|
|
734
|
+
reason: "trim requires --start, --end, or --duration",
|
|
735
|
+
fix: "pass one trim option"
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
var leavesNoLength = (start, duration) => duration <= 0 || sameInstant(start, start + duration);
|
|
739
|
+
function finishTrim(context, nextStart, end, duration) {
|
|
740
|
+
if (end && !end.ok) return end;
|
|
741
|
+
if (duration && !duration.ok) return duration;
|
|
742
|
+
const nextDuration = duration?.seconds ?? (end ? durationUntil(nextStart, end.seconds) : context.row.duration);
|
|
743
|
+
if (leavesNoLength(nextStart, nextDuration)) {
|
|
744
|
+
return {
|
|
745
|
+
ok: false,
|
|
746
|
+
reason: "trim duration must be positive",
|
|
747
|
+
fix: "choose a later end or positive duration"
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
return { ok: true, nextStart, nextDuration };
|
|
751
|
+
}
|
|
752
|
+
function trimStart(context, expression) {
|
|
753
|
+
if (!expression) return { ok: true, seconds: context.row.start };
|
|
754
|
+
return parseMutationTime(context, expression, "pass a valid time expression");
|
|
755
|
+
}
|
|
756
|
+
function durationUntil(start, end) {
|
|
757
|
+
let duration = end - start;
|
|
758
|
+
while (duration > 0 && start + duration > end) duration = nextSmaller(duration);
|
|
759
|
+
return duration;
|
|
760
|
+
}
|
|
761
|
+
var float = new DataView(new ArrayBuffer(8));
|
|
762
|
+
function nextSmaller(positive) {
|
|
763
|
+
float.setFloat64(0, positive);
|
|
764
|
+
float.setBigUint64(0, float.getBigUint64(0) - 1n);
|
|
765
|
+
return float.getFloat64(0);
|
|
766
|
+
}
|
|
767
|
+
function trimEnd(context, expression) {
|
|
768
|
+
if (!expression) return void 0;
|
|
769
|
+
return parseMutationTime(context, expression, "pass a valid time expression");
|
|
770
|
+
}
|
|
771
|
+
function trimDuration(context, expression) {
|
|
772
|
+
if (!expression) return void 0;
|
|
773
|
+
return parseMutationTime(context, expression, "pass a valid duration");
|
|
774
|
+
}
|
|
775
|
+
function deleteMutation(context) {
|
|
776
|
+
return {
|
|
777
|
+
ok: true,
|
|
778
|
+
after: removeElementFromHtml(context.before, context.resolved.target),
|
|
779
|
+
nextStart: context.row.start,
|
|
780
|
+
nextDuration: context.row.duration
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
function setOperation(assignment) {
|
|
784
|
+
const property = assignment.field === "volume" ? "data-volume" : assignment.field === "rate" ? "data-playback-rate" : "data-track-index";
|
|
785
|
+
return { type: "html-attribute", property, value: assignment.value };
|
|
786
|
+
}
|
|
787
|
+
function setMutation(context, args) {
|
|
788
|
+
const positionalAssignments = positional(args).slice(1).filter((value) => typeof value === "string");
|
|
789
|
+
const namedAssignments = ["volume", "rate", "track"].flatMap((field) => {
|
|
790
|
+
const value = args[field];
|
|
791
|
+
return typeof value === "string" ? [`${field}=${value}`] : [];
|
|
792
|
+
});
|
|
793
|
+
const assignments = parseSetAssignments([...positionalAssignments, ...namedAssignments]);
|
|
794
|
+
if (!assignments.ok) return assignments;
|
|
795
|
+
const patched = patchElementInHtml(
|
|
796
|
+
context.before,
|
|
797
|
+
context.resolved.target,
|
|
798
|
+
assignments.assignments.map(setOperation)
|
|
799
|
+
);
|
|
800
|
+
if (!patched.matched) {
|
|
801
|
+
return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
|
|
802
|
+
}
|
|
803
|
+
return {
|
|
804
|
+
ok: true,
|
|
805
|
+
after: patched.html,
|
|
806
|
+
nextStart: context.row.start,
|
|
807
|
+
nextDuration: context.row.duration
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
function duplicateMutation(context, args) {
|
|
811
|
+
const expression = typeof args.at === "string" ? args.at : String(context.row.end);
|
|
812
|
+
const time = parseMutationTime(context, expression, "pass a valid insertion time");
|
|
813
|
+
if (!time.ok) return time;
|
|
814
|
+
const duplicate = duplicateElementInHtml(
|
|
815
|
+
context.before,
|
|
816
|
+
context.resolved.target,
|
|
817
|
+
`${splitBaseId(context.row)}-copy`,
|
|
818
|
+
time.seconds
|
|
819
|
+
);
|
|
820
|
+
if (!duplicate.matched) {
|
|
821
|
+
return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
|
|
822
|
+
}
|
|
823
|
+
return {
|
|
824
|
+
ok: true,
|
|
825
|
+
after: duplicate.html,
|
|
826
|
+
nextStart: time.seconds,
|
|
827
|
+
nextDuration: context.row.duration
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
function decideMutation(verb, context, args) {
|
|
831
|
+
switch (verb) {
|
|
832
|
+
case "move":
|
|
833
|
+
return moveMutation(context, args);
|
|
834
|
+
case "trim":
|
|
835
|
+
return trimMutation(context, args);
|
|
836
|
+
case "split":
|
|
837
|
+
return splitMutation(context, args);
|
|
838
|
+
case "delete":
|
|
839
|
+
return deleteMutation(context);
|
|
840
|
+
case "set":
|
|
841
|
+
return setMutation(context, args);
|
|
842
|
+
case "duplicate":
|
|
843
|
+
return duplicateMutation(context, args);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
function rowAt(timeline, pointer) {
|
|
847
|
+
const track = timeline.tracks.find((candidate) => candidate.kind === pointer.kind);
|
|
848
|
+
if (!track) throw new Error(`missing track ${pointer.kind}`);
|
|
849
|
+
const row = track.rows[pointer.index];
|
|
850
|
+
if (!row) throw new Error(`missing row ${pointer.kind}/${pointer.index}`);
|
|
851
|
+
return row;
|
|
852
|
+
}
|
|
853
|
+
function positional(args) {
|
|
854
|
+
return Array.isArray(args._) ? args._.filter((value) => typeof value === "string") : [];
|
|
855
|
+
}
|
|
856
|
+
function isRecord(value) {
|
|
857
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
858
|
+
}
|
|
859
|
+
function mutationConflict(verb, overwrite, row, timeline, nextStart, nextDuration) {
|
|
860
|
+
if (verb === "duplicate") {
|
|
861
|
+
const conflict2 = allRows(timeline).find(
|
|
862
|
+
(candidate) => candidate.file === row.file && candidate.trackIndex === row.trackIndex && isInsideSpan(nextStart, candidate.start, candidate.end)
|
|
863
|
+
);
|
|
864
|
+
if (!conflict2) return null;
|
|
865
|
+
return {
|
|
866
|
+
reason: `duplicate insertion at ${nextStart} falls inside ${conflict2.ref}`,
|
|
867
|
+
fix: "choose a clip boundary or split the spanning clip first"
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
if (verb !== "move" && verb !== "trim" || overwrite) return null;
|
|
871
|
+
const conflict = overlap(row, timeline, nextStart, nextStart + nextDuration);
|
|
872
|
+
if (!conflict) return null;
|
|
873
|
+
return {
|
|
874
|
+
reason: `${row.ref} would overlap ${conflict.ref} at ${nextStart}-${nextStart + nextDuration}`,
|
|
875
|
+
fix: "pass --overwrite or move the named neighbour"
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// src/timeline/a2Commands.ts
|
|
880
|
+
async function runIds(args) {
|
|
881
|
+
const project = resolveProject(typeof args.dir === "string" ? args.dir : void 0);
|
|
882
|
+
const json = args.json === true;
|
|
883
|
+
ensureDOMParser();
|
|
884
|
+
const beforeTimeline = await describeProject(project.indexPath);
|
|
885
|
+
const files = [.../* @__PURE__ */ new Set(["index.html", ...allRows(beforeTimeline).map((row) => row.file)])];
|
|
886
|
+
const inputs = files.flatMap((file) => {
|
|
887
|
+
const before = readFileSync3(join(project.dir, file), "utf-8");
|
|
888
|
+
const after = ensureHfIds(before);
|
|
889
|
+
return after === before ? [] : [
|
|
890
|
+
{
|
|
891
|
+
sourceFile: file,
|
|
892
|
+
absPath: join(project.dir, file),
|
|
893
|
+
before,
|
|
894
|
+
after,
|
|
895
|
+
expectedVersion: fileContentVersion(before)
|
|
896
|
+
}
|
|
897
|
+
];
|
|
898
|
+
});
|
|
899
|
+
let receipts = [];
|
|
900
|
+
try {
|
|
901
|
+
if (inputs.length > 0) receipts = applyFileMutations(project.dir, inputs);
|
|
902
|
+
} catch (error) {
|
|
903
|
+
if (isFileChanged(error))
|
|
904
|
+
return refusal(error.message, "re-run hyperframes timeline ids", json);
|
|
905
|
+
throw error;
|
|
906
|
+
}
|
|
907
|
+
const afterTimeline = await describeProject(project.indexPath);
|
|
908
|
+
const result = {
|
|
909
|
+
ok: true,
|
|
910
|
+
receipt: receipts.map((receipt) => publicReceipt(receipt)),
|
|
911
|
+
file: files,
|
|
912
|
+
before: allRows(beforeTimeline),
|
|
913
|
+
after: allRows(afterTimeline),
|
|
914
|
+
diff: "",
|
|
915
|
+
warnings: []
|
|
916
|
+
};
|
|
917
|
+
if (json) console.log(JSON.stringify(withMeta(result), null, 2));
|
|
918
|
+
else console.log(`ids: stamped ${receipts.length} file${receipts.length === 1 ? "" : "s"}`);
|
|
919
|
+
}
|
|
920
|
+
var PLAN_VERBS = /* @__PURE__ */ new Set(["move", "trim", "split", "delete", "set", "duplicate"]);
|
|
921
|
+
function preparePlanEdit(edit, timeline, sourceByFile) {
|
|
922
|
+
if (!isRecord(edit) || typeof edit.verb !== "string" || typeof edit.ref !== "string") {
|
|
923
|
+
return {
|
|
924
|
+
ok: false,
|
|
925
|
+
reason: "each edit needs a verb and ref",
|
|
926
|
+
fix: "pass {verb, ref, ...} objects"
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
if (!PLAN_VERBS.has(edit.verb)) {
|
|
930
|
+
return {
|
|
931
|
+
ok: false,
|
|
932
|
+
reason: `unsupported edit verb ${edit.verb}`,
|
|
933
|
+
fix: "use move, trim, split, delete, set, or duplicate"
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
const resolved = resolveRef(timeline, edit.ref);
|
|
937
|
+
if (!resolved.ok) return resolved;
|
|
938
|
+
const before = sourceByFile.get(resolved.row.file);
|
|
939
|
+
return before === void 0 ? { ok: false, reason: `${resolved.row.file} was not found`, fix: "choose an existing clip" } : { ok: true, edit, row: resolved.row, before, resolved };
|
|
940
|
+
}
|
|
941
|
+
function applyPlanEdit(edit, timeline, project, sourceByFile) {
|
|
942
|
+
const prepared = preparePlanEdit(edit, timeline, sourceByFile);
|
|
943
|
+
if (!prepared.ok) return prepared;
|
|
944
|
+
const { edit: planEdit, row, before, resolved } = prepared;
|
|
945
|
+
const verb = planEdit.verb;
|
|
946
|
+
const context = {
|
|
947
|
+
ref: planEdit.ref,
|
|
948
|
+
row,
|
|
949
|
+
before,
|
|
950
|
+
resolved,
|
|
951
|
+
parseTime: (expression) => parseTimeExpression(expression, {
|
|
952
|
+
row,
|
|
953
|
+
duration: timeline.duration,
|
|
954
|
+
fps: fpsFor(project.indexPath),
|
|
955
|
+
resolveAnchor: (anchorRef) => {
|
|
956
|
+
const anchor = resolveRef(timeline, anchorRef);
|
|
957
|
+
return anchor.ok ? anchor.row : void 0;
|
|
958
|
+
}
|
|
959
|
+
}),
|
|
960
|
+
duration: row.nested && row.hostRow ? rowAt(timeline, row.hostRow).duration : timeline.duration
|
|
961
|
+
};
|
|
962
|
+
const decision = decideMutation(verb, context, { ...planEdit, _: [planEdit.ref] });
|
|
963
|
+
if (!decision.ok) return { ok: false, reason: decision.reason, fix: decision.fix };
|
|
964
|
+
const conflict = mutationConflict(
|
|
965
|
+
verb,
|
|
966
|
+
planEdit.overwrite === true,
|
|
967
|
+
row,
|
|
968
|
+
timeline,
|
|
969
|
+
decision.nextStart,
|
|
970
|
+
decision.nextDuration
|
|
971
|
+
);
|
|
972
|
+
if (conflict) return { ok: false, reason: conflict.reason, fix: conflict.fix };
|
|
973
|
+
return { ok: true, file: row.file, after: decision.after };
|
|
974
|
+
}
|
|
975
|
+
function readEditPlan(file) {
|
|
976
|
+
const raw = file === "-" ? readFileSync3(0, "utf-8") : readFileSync3(file, "utf-8");
|
|
977
|
+
try {
|
|
978
|
+
const edits = JSON.parse(raw);
|
|
979
|
+
return Array.isArray(edits) ? { ok: true, edits } : { ok: false, reason: "edit plan must be a JSON array", fix: "pass a JSON array of edits" };
|
|
980
|
+
} catch {
|
|
981
|
+
return { ok: false, reason: "edit plan is not valid JSON", fix: "pass a JSON array of edits" };
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
function readPlanSources(timeline, project) {
|
|
985
|
+
const sourceByFile = /* @__PURE__ */ new Map();
|
|
986
|
+
const beforeByFile = /* @__PURE__ */ new Map();
|
|
987
|
+
for (const fileName of new Set(allRows(timeline).map((row) => row.file))) {
|
|
988
|
+
const source = readFileSync3(join(project.dir, fileName), "utf-8");
|
|
989
|
+
sourceByFile.set(fileName, source);
|
|
990
|
+
beforeByFile.set(fileName, source);
|
|
991
|
+
}
|
|
992
|
+
return { sourceByFile, beforeByFile };
|
|
993
|
+
}
|
|
994
|
+
async function applyPlanEdits(edits, timeline, project, sourceByFile) {
|
|
995
|
+
for (const edit of edits) {
|
|
996
|
+
const result = applyPlanEdit(edit, timeline, project, sourceByFile);
|
|
997
|
+
if (!result.ok) return result;
|
|
998
|
+
sourceByFile.set(result.file, result.after);
|
|
999
|
+
timeline = await describeProject(project.indexPath, void 0, sourceByFile);
|
|
1000
|
+
}
|
|
1001
|
+
return { ok: true };
|
|
1002
|
+
}
|
|
1003
|
+
async function runApply(args) {
|
|
1004
|
+
const project = resolveProject(typeof args.dir === "string" ? args.dir : void 0);
|
|
1005
|
+
const json = args.json === true;
|
|
1006
|
+
const plan = args.plan === true;
|
|
1007
|
+
const file = typeof args.file === "string" ? args.file : positional(args)[1];
|
|
1008
|
+
if (!file)
|
|
1009
|
+
return refuse(
|
|
1010
|
+
"timeline apply",
|
|
1011
|
+
{ reason: "an edit plan is required", fix: "pass an edits.json path or -" },
|
|
1012
|
+
json
|
|
1013
|
+
);
|
|
1014
|
+
const planInput = readEditPlan(file);
|
|
1015
|
+
if (!planInput.ok) return refuse("timeline apply", planInput, json);
|
|
1016
|
+
ensureDOMParser();
|
|
1017
|
+
const timeline = await describeProject(project.indexPath);
|
|
1018
|
+
const { sourceByFile, beforeByFile } = readPlanSources(timeline, project);
|
|
1019
|
+
const editsResult = await applyPlanEdits(planInput.edits, timeline, project, sourceByFile);
|
|
1020
|
+
if (!editsResult.ok) return refuse("timeline apply", editsResult, json);
|
|
1021
|
+
const inputs = [...sourceByFile].flatMap(([fileName, after]) => {
|
|
1022
|
+
const before = beforeByFile.get(fileName);
|
|
1023
|
+
return after === before ? [] : [
|
|
1024
|
+
{
|
|
1025
|
+
sourceFile: fileName,
|
|
1026
|
+
absPath: join(project.dir, fileName),
|
|
1027
|
+
before,
|
|
1028
|
+
after,
|
|
1029
|
+
expectedVersion: fileContentVersion(before)
|
|
1030
|
+
}
|
|
1031
|
+
];
|
|
1032
|
+
});
|
|
1033
|
+
const afterTimeline = await describeProject(project.indexPath, void 0, sourceByFile);
|
|
1034
|
+
const result = {
|
|
1035
|
+
ok: true,
|
|
1036
|
+
planned: plan,
|
|
1037
|
+
receipt: null,
|
|
1038
|
+
file: inputs.map((input) => input.sourceFile),
|
|
1039
|
+
before: allRows(timeline),
|
|
1040
|
+
after: allRows(afterTimeline),
|
|
1041
|
+
diff: inputs.map((input) => diff(input.before, input.after)).filter(Boolean).join("\n"),
|
|
1042
|
+
warnings: []
|
|
1043
|
+
};
|
|
1044
|
+
if (!plan) {
|
|
1045
|
+
const receipts = inputs.length > 0 ? applyFileMutations(project.dir, inputs) : [];
|
|
1046
|
+
result.receipt = receipts.map((receipt) => publicReceipt(receipt));
|
|
1047
|
+
}
|
|
1048
|
+
if (json) console.log(JSON.stringify(withMeta(result), null, 2));
|
|
1049
|
+
else
|
|
1050
|
+
console.log(
|
|
1051
|
+
`${plan ? "planned" : "applied"} ${inputs.length} file${inputs.length === 1 ? "" : "s"}`
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
1054
|
+
async function runUndo(args) {
|
|
1055
|
+
const project = resolveProject(typeof args.dir === "string" ? args.dir : void 0);
|
|
1056
|
+
const json = args.json === true;
|
|
1057
|
+
const input = typeof args.receipt === "string" ? args.receipt : positional(args)[1];
|
|
1058
|
+
if (!input)
|
|
1059
|
+
return refuse(
|
|
1060
|
+
"timeline undo",
|
|
1061
|
+
{ reason: "an undo receipt is required", fix: "pass the receipt JSON or its file" },
|
|
1062
|
+
json
|
|
1063
|
+
);
|
|
1064
|
+
let raw;
|
|
1065
|
+
try {
|
|
1066
|
+
raw = readFileSync3(input, "utf-8");
|
|
1067
|
+
} catch {
|
|
1068
|
+
raw = input;
|
|
1069
|
+
}
|
|
1070
|
+
let parsed;
|
|
1071
|
+
try {
|
|
1072
|
+
parsed = JSON.parse(raw);
|
|
1073
|
+
} catch {
|
|
1074
|
+
return refuse(
|
|
1075
|
+
"timeline undo",
|
|
1076
|
+
{ reason: "undo receipt is not valid JSON", fix: "pass the applied JSON receipt" },
|
|
1077
|
+
json
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
const value = isRecord(parsed) && isRecord(parsed.receipt) ? parsed.receipt : parsed;
|
|
1081
|
+
if (!isRecord(value) || typeof value.file !== "string" || typeof value.version !== "string" || typeof value.backupPath !== "string") {
|
|
1082
|
+
return refuse(
|
|
1083
|
+
"timeline undo",
|
|
1084
|
+
{
|
|
1085
|
+
reason: "undo receipt is missing file, version, or backupPath",
|
|
1086
|
+
fix: "pass an applied timeline receipt"
|
|
1087
|
+
},
|
|
1088
|
+
json
|
|
1089
|
+
);
|
|
1090
|
+
}
|
|
1091
|
+
const backup = join(project.dir, value.backupPath);
|
|
1092
|
+
const target = join(project.dir, value.file);
|
|
1093
|
+
const before = readFileSync3(target, "utf-8");
|
|
1094
|
+
const after = readFileSync3(backup, "utf-8");
|
|
1095
|
+
const receipts = applyFileMutations(project.dir, [
|
|
1096
|
+
{ sourceFile: value.file, absPath: target, before, after, expectedVersion: value.version }
|
|
1097
|
+
]);
|
|
1098
|
+
const result = {
|
|
1099
|
+
ok: true,
|
|
1100
|
+
receipt: receipts.map((receipt) => publicReceipt(receipt)),
|
|
1101
|
+
file: value.file
|
|
1102
|
+
};
|
|
1103
|
+
if (json) console.log(JSON.stringify(withMeta(result), null, 2));
|
|
1104
|
+
else console.log(`undid ${value.file}`);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
// src/timeline/a2MutationCommand.ts
|
|
1108
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
1109
|
+
import { join as join2 } from "path";
|
|
1110
|
+
async function runMutation(verb, args) {
|
|
1111
|
+
const setup = await prepareMutation(args);
|
|
1112
|
+
if (!setup.ok) return refusal(setup.reason, setup.fix, setup.json);
|
|
1113
|
+
const decision = decideMutation(verb, setup.context, args);
|
|
1114
|
+
if (!decision.ok) return refusal(decision.reason, decision.fix, setup.json);
|
|
1115
|
+
await finishMutation(setup, verb, decision);
|
|
1116
|
+
}
|
|
1117
|
+
async function prepareMutation(args) {
|
|
1118
|
+
const project = resolveProject(typeof args.dir === "string" ? args.dir : void 0);
|
|
1119
|
+
const ref = typeof args.ref === "string" ? args.ref : "";
|
|
1120
|
+
const json = args.json === true;
|
|
1121
|
+
const plan = args.plan === true;
|
|
1122
|
+
const overwrite = args.overwrite === true;
|
|
1123
|
+
const snap = args.snap === true;
|
|
1124
|
+
ensureDOMParser();
|
|
1125
|
+
const indexSource = readFileSync4(project.indexPath, "utf-8");
|
|
1126
|
+
const initialTimeline = await describeProject(
|
|
1127
|
+
project.indexPath,
|
|
1128
|
+
void 0,
|
|
1129
|
+
/* @__PURE__ */ new Map([["index.html", indexSource]])
|
|
1130
|
+
);
|
|
1131
|
+
const projectFps2 = declaredFps(indexSource);
|
|
1132
|
+
if (snap && projectFps2 === null) {
|
|
1133
|
+
return {
|
|
1134
|
+
ok: false,
|
|
1135
|
+
reason: "project fps is unknown",
|
|
1136
|
+
fix: "set data-fps on the project, then rerun with --snap",
|
|
1137
|
+
json
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
const initialResolved = resolveRef(initialTimeline, ref);
|
|
1141
|
+
if (!initialResolved.ok)
|
|
1142
|
+
return { ok: false, reason: initialResolved.reason, fix: initialResolved.fix, json };
|
|
1143
|
+
const initialRow = initialResolved.row;
|
|
1144
|
+
const filePath = join2(project.dir, initialRow.file);
|
|
1145
|
+
const before = readFileSync4(filePath, "utf-8");
|
|
1146
|
+
const expectedVersion = fileContentVersion(before);
|
|
1147
|
+
const sources = /* @__PURE__ */ new Map([
|
|
1148
|
+
["index.html", indexSource],
|
|
1149
|
+
[initialRow.file, before]
|
|
1150
|
+
]);
|
|
1151
|
+
const timeline = await describeProject(project.indexPath, void 0, sources);
|
|
1152
|
+
const resolved = resolveRef(timeline, ref);
|
|
1153
|
+
if (!resolved.ok) return { ok: false, reason: resolved.reason, fix: resolved.fix, json };
|
|
1154
|
+
const row = resolved.row;
|
|
1155
|
+
const anchor = (anchorRef) => {
|
|
1156
|
+
const found = resolveRef(timeline, anchorRef);
|
|
1157
|
+
return found.ok ? found.row : void 0;
|
|
1158
|
+
};
|
|
1159
|
+
const parseTime = (expression) => {
|
|
1160
|
+
const parsed = parseTimeExpression(expression, {
|
|
1161
|
+
row,
|
|
1162
|
+
duration: timeline.duration,
|
|
1163
|
+
fps: fpsFor(project.indexPath),
|
|
1164
|
+
resolveAnchor: anchor
|
|
1165
|
+
});
|
|
1166
|
+
if (!parsed.ok || !snap) return parsed;
|
|
1167
|
+
return { ok: true, seconds: Math.round(parsed.seconds * projectFps2) / projectFps2 };
|
|
1168
|
+
};
|
|
1169
|
+
return {
|
|
1170
|
+
ok: true,
|
|
1171
|
+
project,
|
|
1172
|
+
ref,
|
|
1173
|
+
json,
|
|
1174
|
+
plan,
|
|
1175
|
+
overwrite,
|
|
1176
|
+
timeline,
|
|
1177
|
+
indexSource,
|
|
1178
|
+
row,
|
|
1179
|
+
resolved,
|
|
1180
|
+
filePath,
|
|
1181
|
+
before,
|
|
1182
|
+
expectedVersion,
|
|
1183
|
+
context: {
|
|
1184
|
+
ref,
|
|
1185
|
+
row,
|
|
1186
|
+
before,
|
|
1187
|
+
resolved,
|
|
1188
|
+
parseTime,
|
|
1189
|
+
// Nested rows use the visible host clip duration as their composition bound.
|
|
1190
|
+
duration: row.nested && row.hostRow ? rowAt(timeline, row.hostRow).duration : timeline.duration
|
|
1191
|
+
}
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
async function finishMutation(setup, verb, decision) {
|
|
1195
|
+
const { after, nextStart, nextDuration } = decision;
|
|
1196
|
+
const { ref, row, timeline, json, overwrite, project, before } = setup;
|
|
1197
|
+
const refusalMessage = mutationRefusal(verb, after, before, ref);
|
|
1198
|
+
if (refusalMessage) return refusal(refusalMessage.reason, refusalMessage.fix, json);
|
|
1199
|
+
const conflict = mutationConflict(verb, overwrite, row, timeline, nextStart, nextDuration);
|
|
1200
|
+
if (conflict) return refusal(conflict.reason, conflict.fix, json);
|
|
1201
|
+
const describeSource = (source) => describeProject(
|
|
1202
|
+
project.indexPath,
|
|
1203
|
+
void 0,
|
|
1204
|
+
/* @__PURE__ */ new Map([
|
|
1205
|
+
["index.html", setup.indexSource],
|
|
1206
|
+
[row.file, source]
|
|
1207
|
+
])
|
|
1208
|
+
);
|
|
1209
|
+
const describedBefore = await describeSource(before);
|
|
1210
|
+
const result = mutationResult(row, describedBefore, setup.plan);
|
|
1211
|
+
if (setup.plan) return printPlan(result, json, timeline, describeSource, after, before);
|
|
1212
|
+
return applyAndPrint({
|
|
1213
|
+
setup,
|
|
1214
|
+
verb,
|
|
1215
|
+
json,
|
|
1216
|
+
row,
|
|
1217
|
+
nextStart,
|
|
1218
|
+
nextDuration,
|
|
1219
|
+
after,
|
|
1220
|
+
before,
|
|
1221
|
+
result,
|
|
1222
|
+
describeSource
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1225
|
+
async function applyAndPrint(args) {
|
|
1226
|
+
const receipt = applyMutation(args.setup, args.after);
|
|
1227
|
+
if (receipt && "error" in receipt)
|
|
1228
|
+
return refusal(receipt.error, "re-run hyperframes timeline", args.json);
|
|
1229
|
+
if (!receipt && args.after !== args.before) {
|
|
1230
|
+
return refusal("mutation produced no receipt", "re-run hyperframes timeline", args.json);
|
|
1231
|
+
}
|
|
1232
|
+
args.result.after = rowsForFile(await args.describeSource(args.after), args.row.file);
|
|
1233
|
+
args.result.receipt = receipt ? publicReceipt(receipt) : null;
|
|
1234
|
+
if (args.json) {
|
|
1235
|
+
console.log(JSON.stringify(withMeta(args.result), null, 2));
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
console.log(
|
|
1239
|
+
`${args.verb} ${args.row.ref}: ${args.row.start}-${args.row.end}s -> ${args.nextStart}-${args.nextStart + args.nextDuration}s
|
|
1240
|
+
receipt: ${receipt?.version ?? "unchanged"}`
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
function rowsForFile(timeline, file) {
|
|
1244
|
+
return allRows(timeline).filter((candidate) => candidate.file === file);
|
|
1245
|
+
}
|
|
1246
|
+
function mutationResult(row, before, planned) {
|
|
1247
|
+
return {
|
|
1248
|
+
ok: true,
|
|
1249
|
+
receipt: null,
|
|
1250
|
+
file: row.file,
|
|
1251
|
+
before: rowsForFile(before, row.file),
|
|
1252
|
+
after: [],
|
|
1253
|
+
warnings: row.warnings,
|
|
1254
|
+
planned
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
async function printPlan(result, json, timeline, describeSource, after, before) {
|
|
1258
|
+
const plannedTimeline = await describeSource(after);
|
|
1259
|
+
result.after = rowsForFile(plannedTimeline, result.file);
|
|
1260
|
+
if (json) console.log(JSON.stringify(withMeta(result), null, 2));
|
|
1261
|
+
else
|
|
1262
|
+
console.log(
|
|
1263
|
+
`${formatTimeline(timeline)}
|
|
1264
|
+
|
|
1265
|
+
planned:
|
|
1266
|
+
${formatTimeline(plannedTimeline)}
|
|
1267
|
+
|
|
1268
|
+
diff:
|
|
1269
|
+
${diff(before, after)}`
|
|
1270
|
+
);
|
|
1271
|
+
}
|
|
1272
|
+
function applyMutation(setup, after) {
|
|
1273
|
+
try {
|
|
1274
|
+
return applyFileMutations(setup.project.dir, [
|
|
1275
|
+
{
|
|
1276
|
+
sourceFile: setup.row.file,
|
|
1277
|
+
absPath: setup.filePath,
|
|
1278
|
+
before: setup.before,
|
|
1279
|
+
after,
|
|
1280
|
+
expectedVersion: setup.expectedVersion
|
|
1281
|
+
}
|
|
1282
|
+
])[0];
|
|
1283
|
+
} catch (error) {
|
|
1284
|
+
if (isFileChanged(error)) return { error: error.message };
|
|
1285
|
+
throw error;
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
function mutationRefusal(verb, after, before, ref) {
|
|
1289
|
+
if (verb !== "delete" || after !== before) return null;
|
|
1290
|
+
return { reason: `${ref} was not found`, fix: "choose an existing clip" };
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
// src/commands/timeline.ts
|
|
1294
|
+
var examples = [
|
|
1295
|
+
["Show every track and clip of the project in the current directory", "hyperframes timeline"],
|
|
1296
|
+
["Move a clip without writing", "hyperframes timeline move '#hero' +2 --plan"],
|
|
1297
|
+
["Delete a clip and return a receipt", "hyperframes timeline delete '#hero' --json"]
|
|
1298
|
+
];
|
|
1299
|
+
function mutationCommand(verb) {
|
|
1300
|
+
return defineCommand({
|
|
1301
|
+
meta: { name: verb, description: `${verb} a timeline clip` },
|
|
1302
|
+
args: {
|
|
1303
|
+
ref: { type: "positional", required: true },
|
|
1304
|
+
time: { type: "positional", required: verb === "move" || verb === "split" },
|
|
1305
|
+
at: { type: "string" },
|
|
1306
|
+
dir: { type: "string" },
|
|
1307
|
+
start: { type: "string" },
|
|
1308
|
+
end: { type: "string" },
|
|
1309
|
+
duration: { type: "string" },
|
|
1310
|
+
plan: { type: "boolean", default: false },
|
|
1311
|
+
json: { type: "boolean", default: false },
|
|
1312
|
+
overwrite: { type: "boolean", default: false },
|
|
1313
|
+
snap: { type: "boolean", default: false }
|
|
1314
|
+
},
|
|
1315
|
+
async run({ args }) {
|
|
1316
|
+
await runMutation(verb, args);
|
|
1317
|
+
}
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
var timeline_default = defineCommand({
|
|
1321
|
+
meta: { name: "timeline", description: "Print and edit the project's tracks and clips" },
|
|
1322
|
+
args: {
|
|
1323
|
+
dir: { type: "positional", description: "Project directory", required: false },
|
|
1324
|
+
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
1325
|
+
},
|
|
1326
|
+
subCommands: {
|
|
1327
|
+
move: () => mutationCommand("move"),
|
|
1328
|
+
trim: () => mutationCommand("trim"),
|
|
1329
|
+
split: () => mutationCommand("split"),
|
|
1330
|
+
delete: () => mutationCommand("delete"),
|
|
1331
|
+
set: () => mutationCommand("set"),
|
|
1332
|
+
duplicate: () => mutationCommand("duplicate"),
|
|
1333
|
+
ids: () => defineCommand({
|
|
1334
|
+
meta: { name: "ids", description: "Stamp stable ids on timeline clips" },
|
|
1335
|
+
args: { dir: { type: "string" }, json: { type: "boolean", default: false } },
|
|
1336
|
+
async run({ args }) {
|
|
1337
|
+
await runIds(args);
|
|
1338
|
+
}
|
|
1339
|
+
}),
|
|
1340
|
+
apply: () => defineCommand({
|
|
1341
|
+
meta: { name: "apply", description: "Apply an atomic timeline edit plan" },
|
|
1342
|
+
args: {
|
|
1343
|
+
file: { type: "positional", required: true },
|
|
1344
|
+
dir: { type: "string" },
|
|
1345
|
+
json: { type: "boolean", default: false },
|
|
1346
|
+
plan: { type: "boolean", default: false }
|
|
1347
|
+
},
|
|
1348
|
+
async run({ args }) {
|
|
1349
|
+
await runApply(args);
|
|
1350
|
+
}
|
|
1351
|
+
}),
|
|
1352
|
+
undo: () => defineCommand({
|
|
1353
|
+
meta: { name: "undo", description: "Restore a timeline mutation receipt" },
|
|
1354
|
+
args: {
|
|
1355
|
+
receipt: { type: "positional", required: true },
|
|
1356
|
+
dir: { type: "string" },
|
|
1357
|
+
json: { type: "boolean", default: false }
|
|
1358
|
+
},
|
|
1359
|
+
async run({ args }) {
|
|
1360
|
+
await runUndo(args);
|
|
1361
|
+
}
|
|
1362
|
+
})
|
|
1363
|
+
},
|
|
1364
|
+
async run({ args }) {
|
|
1365
|
+
if (args._?.[0]) return;
|
|
1366
|
+
const project = resolveProject(args.dir);
|
|
1367
|
+
ensureDOMParser();
|
|
1368
|
+
const timeline = await describeProject(project.indexPath);
|
|
1369
|
+
console.log(
|
|
1370
|
+
args.json ? JSON.stringify(withMeta({ timeline }), null, 2) : formatTimeline(timeline)
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
});
|
|
1374
|
+
export {
|
|
1375
|
+
timeline_default as default,
|
|
1376
|
+
examples
|
|
1377
|
+
};
|