hyperframes 0.8.184 → 0.8.186
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/dist/{add-5ZTD3MUZ.js → add-UGK7AZI6.js} +14 -14
- package/dist/{agentPromptGenerator-VIIPZCJ3.js → agentPromptGenerator-KYO5MKTW.js} +1 -1
- package/dist/{animatedGifPrep-AGASIWVA.js → animatedGifPrep-HPZPSB43.js} +9 -9
- package/dist/api.js +18 -18
- package/dist/{asset-LSTEMPIB.js → asset-X2GTFWOY.js} +2 -2
- package/dist/{assetCataloger-BKBMNL3A.js → assetCataloger-5NWEG4IU.js} +9 -9
- package/dist/audio-7PBM5F3H.js +2317 -0
- package/dist/{auth-MJWKYK77.js → auth-WABSMO46.js} +1 -1
- package/dist/{autoUpdate-2GGDKYR2.js → autoUpdate-6SCMLTSC.js} +2 -2
- package/dist/{backgroundChecks-7GRX5VQY.js → backgroundChecks-XOGPAAR3.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-BCV2LELR.js → batchRender-VR6IA77K.js} +5 -5
- package/dist/{beats-7BCFRBAL.js → beats-3IWXLMSC.js} +7 -7
- package/dist/{benchmark-2R6CN5MQ.js → benchmark-2SSYATCX.js} +10 -10
- package/dist/{browser-6AFGOI7G.js → browser-PMRN345D.js} +3 -3
- package/dist/{bundleWithLocalizedFonts-2EGPA5ZO.js → bundleWithLocalizedFonts-TT32MZBO.js} +2 -2
- package/dist/{capture-HOIAW6MO.js → capture-4VD6AKUJ.js} +13 -13
- package/dist/{capture-HA2UHLIU.js → capture-BDGYTE57.js} +2 -2
- package/dist/{captureCompositionFrame-4236FVWJ.js → captureCompositionFrame-5FVLAETA.js} +17 -13
- package/dist/{catalog-A6CZAWW4.js → catalog-HUYZO5D7.js} +14 -14
- package/dist/{catch-up-TNA4DJOA.js → catch-up-SSGTR2ZT.js} +4 -4
- package/dist/{check-5E5U2EQZ.js → check-JWUWHGM2.js} +34 -34
- package/dist/{checkBrowser-FNINXBMZ.js → checkBrowser-X7G6YNR7.js} +31 -31
- package/dist/{chunk-UJKUB2LH.js → chunk-22QKQDEE.js} +11 -11
- package/dist/{chunk-2PVE4WS2.js → chunk-27H2363S.js} +33 -6
- package/dist/{chunk-2ULXZ4PG.js → chunk-2II34JPM.js} +154 -21
- package/dist/{chunk-3QVMJ7GX.js → chunk-2PZZMAME.js} +11 -10
- package/dist/{chunk-X3CG5YQA.js → chunk-3YHGQJI6.js} +3 -3
- package/dist/{chunk-EEP5Y5IE.js → chunk-46HEFGXJ.js} +1 -1
- package/dist/{chunk-DWUGKEHR.js → chunk-4AFNEKU7.js} +1 -1
- package/dist/{chunk-R2BFTECP.js → chunk-4NTW45W5.js} +3 -3
- package/dist/{chunk-7HJALUIO.js → chunk-4XFFJAWS.js} +1 -1
- package/dist/{chunk-SN7KI5JA.js → chunk-5ZMIVTHN.js} +2 -2
- package/dist/{chunk-QL2PNIXC.js → chunk-5ZMXGNGC.js} +24 -16
- package/dist/{chunk-UKOTVJFV.js → chunk-6IOBAOU7.js} +1 -1
- package/dist/{chunk-JIUTXKWA.js → chunk-77QM6YRQ.js} +2 -1
- package/dist/{chunk-ES426XRJ.js → chunk-7AUMTARQ.js} +3 -3
- package/dist/{chunk-5CS4T6C6.js → chunk-7L37AB57.js} +1 -1
- package/dist/{chunk-RGXVEYHI.js → chunk-7M7TMM4S.js} +81 -10
- package/dist/{chunk-3TXNNBI2.js → chunk-7MLFYMFB.js} +2 -2
- package/dist/{chunk-MFAETWIF.js → chunk-7MVODWQF.js} +1 -1
- package/dist/{chunk-WHPN2TIT.js → chunk-ACLABKEF.js} +6 -6
- package/dist/{chunk-YMS5FOMC.js → chunk-B2A56S5C.js} +1 -1
- package/dist/{chunk-YALM6XN4.js → chunk-BRTDLVK3.js} +3 -3
- package/dist/{chunk-VDM3FEDP.js → chunk-DQZMJS2P.js} +1 -1
- package/dist/{chunk-PSKEKWVU.js → chunk-DTXDQ6OP.js} +1 -1
- package/dist/{chunk-Q33P4EAC.js → chunk-EZINX6HH.js} +3 -3
- package/dist/{chunk-3MDJIWOV.js → chunk-FCWFV4P7.js} +75 -35
- package/dist/{chunk-ABZYYUUH.js → chunk-FRLTKTOR.js} +1 -1
- package/dist/{chunk-E32ZQ2WO.js → chunk-GTMBII7X.js} +1 -1
- package/dist/{chunk-YOZPQCSR.js → chunk-HOFX63F2.js} +3 -3
- package/dist/{chunk-LRGYPXHF.js → chunk-HZ7M2MZA.js} +1 -1
- package/dist/{chunk-TYXH3EKP.js → chunk-I5JRXMCV.js} +16 -1
- package/dist/{chunk-LLC4CS6I.js → chunk-ID5AJ4L3.js} +3 -3
- package/dist/{chunk-FGJEUV4S.js → chunk-K6KBOORN.js} +48 -4
- package/dist/{chunk-EM7C7H7S.js → chunk-KNLSYCI5.js} +7 -7
- package/dist/{chunk-4N4P3ZWL.js → chunk-LDW3KVGK.js} +2 -2
- package/dist/{chunk-OLZENUPI.js → chunk-LLFQA7XF.js} +1 -1
- package/dist/chunk-LLMSX6V6.js +17 -0
- package/dist/{chunk-5UDRPPN2.js → chunk-MY6CVBDD.js} +7 -4
- package/dist/{chunk-7NRI7HYX.js → chunk-NPDPDEPP.js} +1 -1
- package/dist/{chunk-BCHSTE7U.js → chunk-PEIV2SOG.js} +1 -1
- package/dist/{chunk-ADDHW2FS.js → chunk-Q447CX26.js} +82 -12
- package/dist/{chunk-YWNJTZGN.js → chunk-R6IGQ5NO.js} +2 -2
- package/dist/{chunk-YWHCXIMD.js → chunk-RFJ6SX4U.js} +5 -5
- package/dist/{chunk-J3QM7AHP.js → chunk-RNZEQTWZ.js} +2 -2
- package/dist/{chunk-SAX7HQ5E.js → chunk-ROWEDRVX.js} +1 -1
- package/dist/{chunk-PFYWVUHA.js → chunk-RPUIMFHF.js} +1 -1
- package/dist/{chunk-OYLO6TYK.js → chunk-RUOG4VB7.js} +1 -1
- package/dist/{chunk-UNNXFKVG.js → chunk-RVZNSKRH.js} +2 -2
- package/dist/{chunk-VNVQGDPC.js → chunk-T4RP55P2.js} +1 -1
- package/dist/{chunk-GDEV42FA.js → chunk-TH7J3JZ5.js} +524 -42
- package/dist/{chunk-VHZ6DL3M.js → chunk-TMK4Q7JA.js} +10 -7
- package/dist/{chunk-74JMKLVU.js → chunk-TQ2RRB5V.js} +1 -1
- package/dist/{chunk-ICJEAFPD.js → chunk-U4BMRIE6.js} +16 -7
- package/dist/{chunk-HR23IKLZ.js → chunk-U7QTMRLW.js} +2 -2
- package/dist/{chunk-KN46TGHV.js → chunk-UAJCTEK2.js} +1 -1
- package/dist/{chunk-CXABAXB3.js → chunk-UJZT6HNN.js} +1 -1
- package/dist/chunk-UOZX5W5T.js +3852 -0
- package/dist/{chunk-FFJ5TDRD.js → chunk-VHBBV5DH.js} +10 -3
- package/dist/{chunk-ZRHO6YMM.js → chunk-WHMFW5ET.js} +4 -4
- package/dist/{chunk-WTFUDNW2.js → chunk-WLHNIIXU.js} +3 -3
- package/dist/{chunk-ZOCHDXDG.js → chunk-Y2M6XSNK.js} +1 -1
- package/dist/{chunk-2XA7KXQO.js → chunk-YNH6ERDL.js} +2 -2
- package/dist/{chunk-JB6ARMQS.js → chunk-YQICCAVA.js} +1 -1
- package/dist/{chunk-7MB2ZAQF.js → chunk-YRAJDFIN.js} +1 -1
- package/dist/{chunk-IWTNTUPQ.js → chunk-Z5233OAN.js} +11 -13
- package/dist/{chunk-TE427YID.js → chunk-ZKBW7NU2.js} +2 -2
- package/dist/{chunk-4KKKBEP3.js → chunk-ZVBEGBII.js} +3 -3
- package/dist/{clean-HGASSMWI.js → clean-IM2JIAUT.js} +18 -18
- package/dist/cli.js +53 -53
- package/dist/{cloud-JPDVNXHN.js → cloud-6IPBCJSX.js} +4 -4
- package/dist/{cloudrun-AMMGSDRP.js → cloudrun-MWZ6S2I2.js} +7 -7
- package/dist/commands/contrast-audit.browser.js +1 -2
- package/dist/commands/layout-audit.browser.js +196 -0
- package/dist/{compare-LHHVHUN3.js → compare-WD7A2TV5.js} +28 -28
- package/dist/{compiler-Q3N6QXMT.js → compiler-2EKSMC3I.js} +6 -6
- package/dist/{component-D72J32Q7.js → component-JKALWH36.js} +3 -3
- package/dist/{compositions-UQRJ5ROG.js → compositions-643NAG4A.js} +13 -13
- package/dist/{delete-P42VIDDA.js → delete-EASPXKHQ.js} +2 -2
- package/dist/{deploy-WZTH57O4.js → deploy-CDKCQ5MX.js} +1 -1
- package/dist/{deterministicFonts-VQ5UBMXY.js → deterministicFonts-EGAAE7QL.js} +3 -3
- package/dist/{dist-DYS24AMA.js → dist-F6FOKRSU.js} +10 -4
- package/dist/{dist-SENYPQGW.js → dist-LM7AVHOU.js} +3 -3
- package/dist/docs/data-attributes.md +1 -1
- package/dist/{doctor-KEJIG2SK.js → doctor-7XUVYDJQ.js} +13 -13
- package/dist/{events-CYKSNR7N.js → events-5TTPYBKG.js} +3 -3
- package/dist/{events-UZXFQPMT.js → events-TULV6D3G.js} +3 -3
- package/dist/{feedback-LXNQF7CA.js → feedback-4FTPWM6P.js} +8 -8
- package/dist/{ffmpeg-BYHON577.js → ffmpeg-MP7ZVYLZ.js} +9 -9
- package/dist/{figma-EIQ35PS6.js → figma-B7LFWYKO.js} +3 -3
- package/dist/fontLocalizeCli.js +12 -12
- package/dist/{get-CC2YL7QO.js → get-F7W4AQ2V.js} +2 -2
- package/dist/{gpuPolicy-VFSACUQV.js → gpuPolicy-NSNVDFXC.js} +9 -9
- package/dist/{grade-compare-TUQL7IV2.js → grade-compare-6QXDTLS2.js} +29 -29
- package/dist/{gsapParserAcorn-7NCK2LVT.js → gsapParserAcorn-SKODXC2N.js} +2 -2
- package/dist/{help-ROROO5K6.js → help-RJAA4O74.js} +1 -1
- package/dist/{history-PNELYLXX.js → history-OOQBDVV5.js} +6 -6
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +67 -67
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/{info-4FZTH6AS.js → info-5OGGYYLO.js} +9 -9
- package/dist/{init-I43GHHVP.js → init-DM3TJKW2.js} +68 -50
- package/dist/{inspect-IT4TYIZ3.js → inspect-FECQCLS5.js} +29 -29
- package/dist/{installer-CWOJVK5K.js → installer-WOG4VORV.js} +7 -7
- package/dist/{keyframes-3FBOGVD4.js → keyframes-SZHWUF5Y.js} +7 -7
- package/dist/{lambda-H3V32I7M.js → lambda-JG2ZRGMC.js} +9 -9
- package/dist/{layout-BZ5LYJ5C.js → layout-7ACF7ZKC.js} +29 -29
- package/dist/{lint-ZTNSGP2S.js → lint-ZCQGMILV.js} +9 -9
- package/dist/{lintProject-C2ONSH2U.js → lintProject-JATQKR64.js} +3 -3
- package/dist/{list-XM4GWJYY.js → list-MH2X3Y2T.js} +2 -2
- package/dist/{login-H6HYKMWX.js → login-CK46WX5U.js} +4 -4
- package/dist/{manager-TWVDSJXO.js → manager-GXTPNJVW.js} +10 -10
- package/dist/{media-treatment-N7MY5NXB.js → media-treatment-EH2AT34Z.js} +15 -15
- package/dist/{models-WEMIMYBD.js → models-D5XP2UK6.js} +13 -13
- package/dist/{motionShot-RHICTVPU.js → motionShot-UR7D3SRQ.js} +16 -16
- package/dist/{normalize-4UDISLPL.js → normalize-3AYFSN2F.js} +1 -1
- package/dist/{normalize-audio-ZFUZCJE3.js → normalize-audio-635JOR5W.js} +4 -4
- package/dist/{open-IBJ4FL3G.js → open-6WE5WFVM.js} +14 -14
- package/dist/{parakeetRunner-XXO4WSLR.js → parakeetRunner-STHZPG32.js} +14 -14
- package/dist/{pipeline-6ML3LUVK.js → pipeline-LVEKRETU.js} +10 -10
- package/dist/{play-RV4NAVF5.js → play-W6TDW4FE.js} +21 -21
- package/dist/{preflight-R3DEFMLA.js → preflight-LIMQXLR7.js} +10 -10
- package/dist/{present-5TBJGE6B.js → present-RX5QX6UR.js} +17 -17
- package/dist/{preview-FLKZ5CXJ.js → preview-KIWTWK63.js} +20 -20
- package/dist/{producer-7XYSPVKH.js → producer-TSNKSCUM.js} +1 -1
- package/dist/{projectConfig-TBU2VWZX.js → projectConfig-NCP7JRH4.js} +9 -9
- package/dist/{publication-CWWUJYJ5.js → publication-5W5UZWGC.js} +4 -4
- package/dist/{publish-FSNE4FEB.js → publish-7WR4XJ6I.js} +11 -11
- package/dist/{remove-background-MDFWRWCT.js → remove-background-43JGBRWQ.js} +11 -11
- package/dist/{render-F4JQ553X.js → render-456HCO6O.js} +31 -31
- package/dist/{render-LWZKXCLY.js → render-7T44HIM6.js} +5 -5
- package/dist/{render-DBGQZAZT.js → render-WHMLYIOI.js} +18 -30
- package/dist/{render-batch-PU7NMLIJ.js → render-batch-LURBJTBV.js} +5 -5
- package/dist/renderSetupWorker.js +3 -3
- package/dist/{resolver-RUBGFXPC.js → resolver-MBIW4VC4.js} +6 -6
- package/dist/{sherpa-X2TBNO6P.js → sherpa-5J2AALED.js} +13 -13
- package/dist/skills/hyperframes/SKILL.md +52 -174
- package/dist/skills/hyperframes/assets/frame-presets/biennale-yellow/FRAME.md +289 -0
- package/dist/skills/hyperframes/assets/frame-presets/biennale-yellow/caption-skin.html +220 -0
- package/dist/skills/hyperframes/assets/frame-presets/biennale-yellow/frame-showcase.html +1214 -0
- package/dist/skills/hyperframes/assets/frame-presets/blockframe/FRAME.md +275 -0
- package/dist/skills/hyperframes/assets/frame-presets/blockframe/caption-skin.html +223 -0
- package/dist/skills/hyperframes/assets/frame-presets/blockframe/frame-showcase.html +1347 -0
- package/dist/skills/hyperframes/assets/frame-presets/blue-professional/FRAME.md +307 -0
- package/dist/skills/hyperframes/assets/frame-presets/blue-professional/caption-skin.html +222 -0
- package/dist/skills/hyperframes/assets/frame-presets/blue-professional/frame-showcase.html +1372 -0
- package/dist/skills/hyperframes/assets/frame-presets/bold-poster/FRAME.md +275 -0
- package/dist/skills/hyperframes/assets/frame-presets/bold-poster/caption-skin.html +229 -0
- package/dist/skills/hyperframes/assets/frame-presets/bold-poster/frame-showcase.html +1140 -0
- package/dist/skills/hyperframes/assets/frame-presets/broadside/FRAME.md +284 -0
- package/dist/skills/hyperframes/assets/frame-presets/broadside/caption-skin.html +224 -0
- package/dist/skills/hyperframes/assets/frame-presets/broadside/frame-showcase.html +1166 -0
- package/dist/skills/hyperframes/assets/frame-presets/capsule/FRAME.md +284 -0
- package/dist/skills/hyperframes/assets/frame-presets/capsule/caption-skin.html +223 -0
- package/dist/skills/hyperframes/assets/frame-presets/capsule/frame-showcase.html +1465 -0
- package/dist/skills/hyperframes/assets/frame-presets/cartesian/FRAME.md +278 -0
- package/dist/skills/hyperframes/assets/frame-presets/cartesian/caption-skin.html +221 -0
- package/dist/skills/hyperframes/assets/frame-presets/cartesian/frame-showcase.html +1263 -0
- package/dist/skills/hyperframes/assets/frame-presets/cobalt-grid/FRAME.md +265 -0
- package/dist/skills/hyperframes/assets/frame-presets/cobalt-grid/caption-skin.html +237 -0
- package/dist/skills/hyperframes/assets/frame-presets/cobalt-grid/frame-showcase.html +1468 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/FRAME.md +277 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/caption-skin.html +223 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/EBGaramond-400.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/EBGaramond-700.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/Inter-400.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/Inter-700.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/JetBrainsMono-400.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/JetBrainsMono-700.woff2 +0 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/OFL-eb-garamond.txt +93 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/OFL-inter.txt +93 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/fonts/OFL-jetbrains-mono.txt +93 -0
- package/dist/skills/hyperframes/assets/frame-presets/code-editorial/frame-showcase.html +1438 -0
- package/dist/skills/hyperframes/assets/frame-presets/coral/FRAME.md +314 -0
- package/dist/skills/hyperframes/assets/frame-presets/coral/caption-skin.html +225 -0
- package/dist/skills/hyperframes/assets/frame-presets/coral/frame-showcase.html +1268 -0
- package/dist/skills/hyperframes/assets/frame-presets/creative-mode/FRAME.md +333 -0
- package/dist/skills/hyperframes/assets/frame-presets/creative-mode/caption-skin.html +226 -0
- package/dist/skills/hyperframes/assets/frame-presets/creative-mode/frame-showcase.html +1330 -0
- package/dist/skills/hyperframes/assets/frame-presets/daisy-days/FRAME.md +274 -0
- package/dist/skills/hyperframes/assets/frame-presets/daisy-days/caption-skin.html +229 -0
- package/dist/skills/hyperframes/assets/frame-presets/daisy-days/frame-showcase.html +1444 -0
- package/dist/skills/hyperframes/assets/frame-presets/editorial-forest/FRAME.md +265 -0
- package/dist/skills/hyperframes/assets/frame-presets/editorial-forest/caption-skin.html +222 -0
- package/dist/skills/hyperframes/assets/frame-presets/editorial-forest/frame-showcase.html +1273 -0
- package/dist/skills/hyperframes/references/captions.md +46 -0
- package/dist/skills/hyperframes/references/film.md +47 -0
- package/dist/skills/hyperframes/references/format.md +157 -0
- package/dist/skills/hyperframes/references/look.md +69 -0
- package/dist/skills/hyperframes/references/motion.md +94 -0
- package/dist/skills/hyperframes/references/overlays.md +39 -0
- package/dist/skills/hyperframes/references/plugin-installation.md +3 -3
- package/dist/skills/hyperframes/references/review.md +51 -0
- package/dist/skills/hyperframes/references/runtimes.md +43 -0
- package/dist/skills/hyperframes/references/skill-lifecycle.md +21 -13
- package/dist/skills/hyperframes/references/sound.md +43 -0
- package/dist/skills/hyperframes/references/spec.md +76 -0
- package/dist/skills/hyperframes/references/story.md +103 -0
- package/dist/skills/hyperframes/references/storyboard-format.md +30 -22
- package/dist/skills/hyperframes/references/storyboard.md +36 -0
- package/dist/skills/hyperframes/references/types/3d.md +25 -0
- package/dist/skills/hyperframes/references/types/character.md +20 -0
- package/dist/skills/hyperframes/references/types/data.md +19 -0
- package/dist/skills/hyperframes/references/types/explainer.md +34 -0
- package/dist/skills/hyperframes/references/types/launch.md +31 -0
- package/dist/skills/hyperframes/references/types/music.md +24 -0
- package/dist/skills/hyperframes/references/types/vertical.md +23 -0
- package/dist/skills/hyperframes/scripts/bake-basemap.mjs +324 -0
- package/dist/skills/hyperframes/scripts/lib/main-module.test.mjs +1 -6
- package/dist/skills/hyperframes/scripts/locate.mjs +228 -0
- package/dist/skills/hyperframes-cli/SKILL.md +76 -179
- package/dist/skills/hyperframes-cli/references/beats.md +1 -1
- package/dist/skills/hyperframes-cli/references/cloud.md +2 -2
- package/dist/skills/hyperframes-cli/references/cloudrun.md +1 -1
- package/dist/skills/hyperframes-cli/references/conventions.md +17 -0
- package/dist/skills/hyperframes-cli/references/feedback.md +14 -0
- package/dist/skills/hyperframes-cli/references/init-and-scaffold.md +11 -7
- package/dist/skills/hyperframes-cli/references/lambda.md +1 -1
- package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +19 -8
- package/dist/skills/hyperframes-cli/references/preview-render.md +8 -2
- package/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +8 -0
- package/dist/skills/media-use/SKILL.md +47 -91
- package/dist/skills/media-use/audio/references/bgm.md +1 -1
- package/dist/skills/media-use/audio/references/captions/authoring.md +1 -2
- package/dist/skills/media-use/audio/references/captions/motion.md +5 -5
- package/dist/skills/media-use/audio/references/tts.md +0 -3
- package/dist/skills/media-use/audio/scripts/audio.mjs +5 -6
- package/dist/skills/media-use/audio/scripts/carve.mjs +560 -0
- package/dist/skills/media-use/audio/scripts/carve.test.mjs +254 -0
- package/dist/skills/media-use/audio/scripts/extract-audio-data.py +199 -0
- package/dist/skills/media-use/references/local.md +24 -0
- package/dist/skills/media-use/references/memory.md +4 -4
- package/dist/skills/media-use/references/mixing.md +71 -0
- package/dist/skills/media-use/references/operations.md +1 -1
- package/dist/skills/media-use/scripts/compatibility.test.mjs +1 -56
- package/dist/skills/media-use/scripts/lib/prefs-store.mjs +1 -1
- package/dist/skills/media-use/scripts/lib/recipe-store.mjs +1 -1
- package/dist/skills/media-use/scripts/prefs.mjs +2 -3
- package/dist/skills/media-use/scripts/recipe.mjs +1 -3
- package/dist/{skills-WHKMWO2D.js → skills-UHOXOGGF.js} +20 -13
- package/dist/{skillsUpdateCheck-XQGZGJJG.js → skillsUpdateCheck-PDZIFUJE.js} +3 -3
- package/dist/{snapshot-M4NUUSNU.js → snapshot-PFV7ALLH.js} +462 -100
- package/dist/{src-4UYM2K3S.js → src-DCVSEODX.js} +8 -8
- package/dist/{src-6MSC62U2.js → src-XK5YIR6L.js} +11 -11
- package/dist/{staticProjectServer-ERDTFP45.js → staticProjectServer-4IE4G4JO.js} +17 -17
- package/dist/studio/assets/{hyperframes-player-DEncBxR7.js → hyperframes-player-B_skzvYC.js} +1 -1
- package/dist/studio/assets/{index-Cc22mgvY.js → index-CgLbvCUo.js} +1 -1
- package/dist/studio/assets/{index-BABXr78Q.js → index-Dn5FAk2e.js} +99 -99
- package/dist/studio/index.html +1 -1
- package/dist/{studio-api-SAKD3VKC.js → studio-api-JMWYU7KF.js} +11 -11
- package/dist/{studioServer-IRI7EVOM.js → studioServer-BWLSTGIG.js} +50 -49
- package/dist/{telemetry-F4XADVAF.js → telemetry-JCU3AV7W.js} +3 -3
- package/dist/templates/_shared/AGENTS.md +14 -19
- package/dist/templates/_shared/CLAUDE.md +14 -19
- package/dist/templates/blank/index.html +10 -4
- package/dist/{timeline-5I444RRE.js → timeline-BCIFQYOM.js} +20 -19
- package/dist/{tokens-LRRYM35A.js → tokens-7IXKALMQ.js} +2 -2
- package/dist/{transcribe-44XDFNVU.js → transcribe-HW7HGJ4V.js} +19 -19
- package/dist/{transcribe-WHYHWAB2.js → transcribe-ZUQD3B32.js} +12 -12
- package/dist/{updateCheck-7CPH3CAZ.js → updateCheck-Z6LNEK7B.js} +2 -2
- package/dist/{upgrade-WW4GQ2RI.js → upgrade-JYH72JGL.js} +2 -2
- package/dist/{urlDownloader-OHLLP45A.js → urlDownloader-WKLFHSUH.js} +8 -8
- package/dist/{validate-VNCDH2LW.js → validate-QCC27YYI.js} +23 -23
- package/dist/{video-5OHTLL2D.js → video-EZ7ONY6L.js} +9 -9
- package/dist/warmCheck.js +36 -36
- package/package.json +1 -1
- package/dist/audio-KGK44XE4.js +0 -1153
- package/dist/chunk-R2SQBPMH.js +0 -3805
- package/dist/skills/hyperframes/references/brief-contract.md +0 -108
- package/dist/skills/hyperframes/references/brief-format.md +0 -72
- package/dist/skills/hyperframes/references/capability-menu.md +0 -47
- package/dist/skills/hyperframes/references/frame-worker-core.md +0 -82
- package/dist/skills/hyperframes/references/intent-interview.md +0 -73
- package/dist/skills/hyperframes/references/pitch-round.md +0 -40
- package/dist/skills/hyperframes/references/production-loop.md +0 -26
- package/dist/skills/hyperframes/references/review-loop.md +0 -37
- package/dist/skills/hyperframes/references/route-briefs.md +0 -11
- package/dist/skills/hyperframes/references/routes/embedded-captions.md +0 -11
- package/dist/skills/hyperframes/references/routes/faceless-explainer.md +0 -12
- package/dist/skills/hyperframes/references/routes/general-video.md +0 -12
- package/dist/skills/hyperframes/references/routes/motion-graphics.md +0 -11
- package/dist/skills/hyperframes/references/routes/music-to-video.md +0 -12
- package/dist/skills/hyperframes/references/routes/pr-to-video.md +0 -28
- package/dist/skills/hyperframes/references/routes/product-launch-video.md +0 -13
- package/dist/skills/hyperframes/references/routes/remotion-to-hyperframes.md +0 -9
- package/dist/skills/hyperframes/references/routes/slideshow.md +0 -11
- package/dist/skills/hyperframes/references/routes/talking-head-recut.md +0 -11
- package/dist/skills/hyperframes/references/script-format.md +0 -52
- package/dist/skills/hyperframes/references/subagent-dispatch.md +0 -35
- package/dist/skills/hyperframes/references/workflow-catalog.md +0 -10
- package/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +0 -176
- package/dist/skills/media-use/audio/scripts/lib/host-audio.mjs +0 -28
- package/dist/skills/media-use/audio/scripts/lib/host-audio.test.mjs +0 -106
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
} from "./chunk-57GN6KWT.js";
|
|
12
12
|
import {
|
|
13
13
|
captureArtifactRevision
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-DQZMJS2P.js";
|
|
15
15
|
import {
|
|
16
16
|
loadProducer
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-PEIV2SOG.js";
|
|
18
18
|
import {
|
|
19
19
|
trackLintRun
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-EZINX6HH.js";
|
|
21
21
|
import {
|
|
22
22
|
beginCheckSnapshots,
|
|
23
23
|
checkSnapshotDirectory,
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
import {
|
|
28
28
|
CONTENT_OVERLAP_HELD_ERROR_MS,
|
|
29
29
|
DEFAULT_MAX_STATIC_SEC,
|
|
30
|
+
END_CARD_HOLD_SEC,
|
|
30
31
|
assertionTargets,
|
|
31
32
|
buildLayoutSampleTimes,
|
|
32
33
|
buildTransitionSampleTimes,
|
|
@@ -45,27 +46,27 @@ import {
|
|
|
45
46
|
mergeSampleTimes,
|
|
46
47
|
parseAt,
|
|
47
48
|
readMotionSpec
|
|
48
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-5ZMXGNGC.js";
|
|
49
50
|
import {
|
|
50
51
|
resolveProject
|
|
51
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-HZ7M2MZA.js";
|
|
52
53
|
import {
|
|
53
54
|
recordArtifacts
|
|
54
55
|
} from "./chunk-U6RXZNZE.js";
|
|
55
56
|
import {
|
|
56
57
|
BrowserCleanupError,
|
|
57
58
|
closeManagedBrowser
|
|
58
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-UAJCTEK2.js";
|
|
59
60
|
import {
|
|
60
61
|
withRemainingBudget
|
|
61
62
|
} from "./chunk-EHSBBBR2.js";
|
|
62
63
|
import {
|
|
63
64
|
resolveLocalBrowserGpuMode
|
|
64
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-RVZNSKRH.js";
|
|
65
66
|
import {
|
|
66
67
|
trackCheckReport,
|
|
67
68
|
trackCommandFailure
|
|
68
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-77QM6YRQ.js";
|
|
69
70
|
import {
|
|
70
71
|
swallowedFlagUsageError
|
|
71
72
|
} from "./chunk-HTIUNMTP.js";
|
|
@@ -85,17 +86,17 @@ import {
|
|
|
85
86
|
import {
|
|
86
87
|
extractMediaMetadata,
|
|
87
88
|
findHdrAutoPromotion
|
|
88
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-7M7TMM4S.js";
|
|
89
90
|
import {
|
|
90
91
|
lintProject,
|
|
91
92
|
shouldBlockRender
|
|
92
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-Q447CX26.js";
|
|
93
94
|
import {
|
|
94
95
|
resolveProjectRelativeSrc
|
|
95
96
|
} from "./chunk-6BNTGNGD.js";
|
|
96
97
|
import {
|
|
97
98
|
withMeta
|
|
98
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-FRLTKTOR.js";
|
|
99
100
|
import {
|
|
100
101
|
normalizeErrorMessage
|
|
101
102
|
} from "./chunk-KNU5COPB.js";
|
|
@@ -109,10 +110,20 @@ import { join as join2, resolve } from "path";
|
|
|
109
110
|
var CHECK_DEADLINE_MS = 12e4;
|
|
110
111
|
var SCRIPT_START = "[hyperframes:script:start] ";
|
|
111
112
|
var SCRIPT_FINISH = "[hyperframes:script:finish] ";
|
|
113
|
+
var PHASE_LABELS = {
|
|
114
|
+
copies: "making video copies",
|
|
115
|
+
launch: "starting Chrome",
|
|
116
|
+
load: "loading the page",
|
|
117
|
+
settle: "waiting for the page to be ready",
|
|
118
|
+
samples: "checking samples",
|
|
119
|
+
overlap: "running the overlap pass",
|
|
120
|
+
crops: "capturing finding crops"
|
|
121
|
+
};
|
|
122
|
+
var BEFORE_DEADLINE = /* @__PURE__ */ new Set(["copies", "launch"]);
|
|
112
123
|
var CheckDeadlineError = class extends Error {
|
|
113
|
-
constructor(sourceFile) {
|
|
124
|
+
constructor(sourceFile, phases = "") {
|
|
114
125
|
super(
|
|
115
|
-
sourceFile === void 0 ? "Check did not finish within its deadline
|
|
126
|
+
(sourceFile === void 0 ? "Check did not finish within its deadline" : `${sourceFile}: its script did not finish within the check deadline`) + (phases || ".")
|
|
116
127
|
);
|
|
117
128
|
this.sourceFile = sourceFile;
|
|
118
129
|
}
|
|
@@ -129,16 +140,38 @@ var CheckDeadline = class {
|
|
|
129
140
|
expiry;
|
|
130
141
|
rejectExpiry;
|
|
131
142
|
phase = "waiting";
|
|
143
|
+
work;
|
|
144
|
+
spent = /* @__PURE__ */ new Map();
|
|
132
145
|
constructor() {
|
|
133
146
|
this.expiry = new Promise((_, reject) => {
|
|
134
147
|
this.rejectExpiry = reject;
|
|
135
148
|
});
|
|
136
149
|
}
|
|
150
|
+
enter = (phase) => {
|
|
151
|
+
if (this.expired) return;
|
|
152
|
+
const now = Date.now();
|
|
153
|
+
if (this.work) this.spend(this.work.phase, now - this.work.since);
|
|
154
|
+
this.work = { phase, since: now };
|
|
155
|
+
this.spend(phase, 0);
|
|
156
|
+
};
|
|
157
|
+
spend(phase, ms) {
|
|
158
|
+
this.spent.set(phase, (this.spent.get(phase) ?? 0) + ms);
|
|
159
|
+
}
|
|
160
|
+
describe() {
|
|
161
|
+
if (!this.work) return "";
|
|
162
|
+
const open = Date.now() - this.work.since;
|
|
163
|
+
const parts = [...this.spent].map(([phase, ms]) => {
|
|
164
|
+
const seconds2 = ((phase === this.work?.phase ? ms + open : ms) / 1e3).toFixed(1);
|
|
165
|
+
return `${PHASE_LABELS[phase]} ${seconds2}${BEFORE_DEADLINE.has(phase) ? " (before the deadline)" : ""}`;
|
|
166
|
+
});
|
|
167
|
+
return ` (${CHECK_DEADLINE_MS / 1e3} s from when Chrome was ready), while ${PHASE_LABELS[this.work.phase]}. Seconds per phase: ${parts.join(", ")}.`;
|
|
168
|
+
}
|
|
137
169
|
start = () => {
|
|
138
170
|
if (this.phase !== "waiting") return;
|
|
139
171
|
this.phase = "started";
|
|
172
|
+
this.enter("load");
|
|
140
173
|
this.timer = setTimeout(() => {
|
|
141
|
-
this.expired = new CheckDeadlineError(this.scripts.at(-1));
|
|
174
|
+
this.expired = new CheckDeadlineError(this.scripts.at(-1), this.describe());
|
|
142
175
|
this.rejectExpiry(this.expired);
|
|
143
176
|
this.abort.abort(this.expired);
|
|
144
177
|
}, CHECK_DEADLINE_MS);
|
|
@@ -201,9 +234,378 @@ import { mkdirSync, writeFileSync } from "fs";
|
|
|
201
234
|
import { readFile } from "fs/promises";
|
|
202
235
|
import { join, relative } from "path";
|
|
203
236
|
|
|
237
|
+
// src/utils/craftAudit.ts
|
|
238
|
+
var CRAFT_THRESHOLDS = {
|
|
239
|
+
readHeightAt1080: 30,
|
|
240
|
+
readOpacity: 0.5,
|
|
241
|
+
shortLineWords: 2,
|
|
242
|
+
shortLineFloorSec: 0.4,
|
|
243
|
+
holdBaseSec: 0.5,
|
|
244
|
+
holdPerWordSec: 0.3,
|
|
245
|
+
holdFloorFraction: 0.75,
|
|
246
|
+
finalLineFloorSec: 2,
|
|
247
|
+
deadStretchSec: 3,
|
|
248
|
+
endCardSec: END_CARD_HOLD_SEC,
|
|
249
|
+
typeFloorFraction: 0.026,
|
|
250
|
+
typeFloorHoldSec: 0.5,
|
|
251
|
+
silentFilmSec: 15,
|
|
252
|
+
/** One video frame: a line held exactly at its floor measures a hair under it. */
|
|
253
|
+
measureToleranceSec: 1 / 30,
|
|
254
|
+
/** Halvings of a grid step when re-measuring a line's edges (0.125 s → ~8 ms). */
|
|
255
|
+
refineSteps: 4,
|
|
256
|
+
maxRefinedLines: 24
|
|
257
|
+
};
|
|
258
|
+
var T = CRAFT_THRESHOLDS;
|
|
259
|
+
var ZERO_BBOX = { x: 0, y: 0, width: 0, height: 0 };
|
|
260
|
+
var WORD_RUNS = /[\p{L}\p{M}\p{N}%$]+/gu;
|
|
261
|
+
var WORD_SEGMENTER = new Intl.Segmenter("ja", { granularity: "word" });
|
|
262
|
+
function readingWords(text) {
|
|
263
|
+
const runs = text.toLowerCase().normalize("NFC").match(WORD_RUNS) ?? [];
|
|
264
|
+
return runs.reduce(
|
|
265
|
+
(count, run) => count + Math.max(1, [...WORD_SEGMENTER.segment(run)].filter((s) => s.isWordLike).length),
|
|
266
|
+
0
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
function lineTargetSec(words) {
|
|
270
|
+
return T.holdBaseSec + T.holdPerWordSec * words;
|
|
271
|
+
}
|
|
272
|
+
function lineFloorSec(words, finalLine) {
|
|
273
|
+
const floor = words <= T.shortLineWords ? T.shortLineFloorSec : T.holdFloorFraction * lineTargetSec(words);
|
|
274
|
+
return finalLine ? Math.max(floor, T.finalLineFloorSec) : floor;
|
|
275
|
+
}
|
|
276
|
+
async function auditCraft(input, probe) {
|
|
277
|
+
const frames = [...input.frames].sort((a, b) => a.time - b.time);
|
|
278
|
+
const step = sampleStep(frames);
|
|
279
|
+
const findings = [
|
|
280
|
+
...detectFirstFrameEmpty(frames),
|
|
281
|
+
...await detectLineUnread(frames, input.duration, input.canvas, probe),
|
|
282
|
+
...input.stillnessJudgedElsewhere ? [] : detectDeadStretches(frames, input.duration),
|
|
283
|
+
...detectTextBelowFloor(frames, input.duration, input.canvas),
|
|
284
|
+
...detectFilmSilent(input.duration, input.soundSources)
|
|
285
|
+
].sort((a, b) => a.time - b.time);
|
|
286
|
+
return { enabled: true, step, samples: frames.length, findings };
|
|
287
|
+
}
|
|
288
|
+
function sampleStep(frames) {
|
|
289
|
+
const gaps = frames.slice(1).map((frame, index) => frame.time - (frames[index]?.time ?? frame.time)).filter((gap) => gap > 0).sort((a, b) => a - b);
|
|
290
|
+
return gaps[Math.floor(gaps.length / 2)] ?? 0;
|
|
291
|
+
}
|
|
292
|
+
function seconds(value) {
|
|
293
|
+
return `${value.toFixed(2)} s`;
|
|
294
|
+
}
|
|
295
|
+
function filmFinding(code, time, message, extra = {}) {
|
|
296
|
+
return {
|
|
297
|
+
code,
|
|
298
|
+
severity: "warning",
|
|
299
|
+
message,
|
|
300
|
+
selector: "[data-composition-id]",
|
|
301
|
+
dataAttributes: {},
|
|
302
|
+
sourceFile: "index.html",
|
|
303
|
+
bbox: ZERO_BBOX,
|
|
304
|
+
time,
|
|
305
|
+
...extra
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function detectFirstFrameEmpty(frames) {
|
|
309
|
+
const first = frames[0];
|
|
310
|
+
if (!first || first.time > 1e-3 || first.painted) return [];
|
|
311
|
+
return [
|
|
312
|
+
filmFinding(
|
|
313
|
+
"first_frame_empty",
|
|
314
|
+
0,
|
|
315
|
+
"Frame 0 shows only the background, and the first frame is the thumbnail on social players: have the title or key image already on screen at 0 s instead of entering from nothing; see references/review.md."
|
|
316
|
+
)
|
|
317
|
+
];
|
|
318
|
+
}
|
|
319
|
+
function detectFilmSilent(duration, soundSources) {
|
|
320
|
+
if (soundSources === null || soundSources > 0 || duration <= T.silentFilmSec) return [];
|
|
321
|
+
return [
|
|
322
|
+
filmFinding(
|
|
323
|
+
"film_silent",
|
|
324
|
+
0,
|
|
325
|
+
`This ${Math.round(duration)} s film has no sound source (no <audio>, no <video> with sound): add a music bed and sounds on the visible actions unless the person asked for silence; see references/sound.md.`
|
|
326
|
+
)
|
|
327
|
+
];
|
|
328
|
+
}
|
|
329
|
+
function detectDeadStretches(frames, duration) {
|
|
330
|
+
const endCardStart = duration - T.endCardSec;
|
|
331
|
+
const findings = [];
|
|
332
|
+
let start = null;
|
|
333
|
+
let end = 0;
|
|
334
|
+
const flush = () => {
|
|
335
|
+
if (start !== null && end - start > T.deadStretchSec) findings.push(deadStretch(start, end));
|
|
336
|
+
start = null;
|
|
337
|
+
};
|
|
338
|
+
for (let index = 1; index < frames.length; index += 1) {
|
|
339
|
+
const before = frames[index - 1];
|
|
340
|
+
const after = frames[index];
|
|
341
|
+
if (!before || !after) continue;
|
|
342
|
+
const still = before.signature !== "" && before.signature === after.signature && !before.held && !after.held && before.time < endCardStart;
|
|
343
|
+
if (!still) {
|
|
344
|
+
flush();
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
start ??= before.time;
|
|
348
|
+
end = Math.min(after.time, endCardStart);
|
|
349
|
+
}
|
|
350
|
+
flush();
|
|
351
|
+
return findings;
|
|
352
|
+
}
|
|
353
|
+
function deadStretch(start, end) {
|
|
354
|
+
const length = end - start;
|
|
355
|
+
return filmFinding(
|
|
356
|
+
"dead_stretch",
|
|
357
|
+
start,
|
|
358
|
+
`Nothing on screen changes for ${seconds(length)} (${start.toFixed(2)}\u2013${end.toFixed(2)} s): start the next move within ${T.deadStretchSec} s, or put data-hold on the element whose stillness is deliberate; see references/motion.md.`,
|
|
359
|
+
{ seconds: round(length), floorSeconds: T.deadStretchSec, until: round(end) }
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
function readableBlocks(frame, readHeight) {
|
|
363
|
+
const blocks = /* @__PURE__ */ new Map();
|
|
364
|
+
for (const part of frame.parts) {
|
|
365
|
+
if (part.captions || part.opacity < T.readOpacity) continue;
|
|
366
|
+
const rect = {
|
|
367
|
+
left: part.rect.left,
|
|
368
|
+
top: part.rect.top,
|
|
369
|
+
right: part.rect.left + part.rect.width,
|
|
370
|
+
bottom: part.rect.top + part.rect.height
|
|
371
|
+
};
|
|
372
|
+
const block = blocks.get(part.block);
|
|
373
|
+
if (!block) {
|
|
374
|
+
blocks.set(part.block, {
|
|
375
|
+
text: part.text,
|
|
376
|
+
rect,
|
|
377
|
+
selector: part.blockSelector,
|
|
378
|
+
sourceFile: part.sourceFile
|
|
379
|
+
});
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
block.text = `${block.text} ${part.text}`;
|
|
383
|
+
block.rect = {
|
|
384
|
+
left: Math.min(block.rect.left, rect.left),
|
|
385
|
+
top: Math.min(block.rect.top, rect.top),
|
|
386
|
+
right: Math.max(block.rect.right, rect.right),
|
|
387
|
+
bottom: Math.max(block.rect.bottom, rect.bottom)
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
for (const [key, block] of blocks) {
|
|
391
|
+
if (block.rect.bottom - block.rect.top < readHeight) blocks.delete(key);
|
|
392
|
+
}
|
|
393
|
+
return blocks;
|
|
394
|
+
}
|
|
395
|
+
function trackBlocks(frames, readHeight) {
|
|
396
|
+
const tracks = /* @__PURE__ */ new Map();
|
|
397
|
+
frames.forEach((frame, index) => {
|
|
398
|
+
for (const [key, block] of readableBlocks(frame, readHeight)) {
|
|
399
|
+
const track = tracks.get(key) ?? {
|
|
400
|
+
key,
|
|
401
|
+
selector: block.selector,
|
|
402
|
+
sourceFile: block.sourceFile,
|
|
403
|
+
seen: /* @__PURE__ */ new Map()
|
|
404
|
+
};
|
|
405
|
+
track.seen.set(index, { text: block.text, rect: block.rect });
|
|
406
|
+
tracks.set(key, track);
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
return [...tracks.values()];
|
|
410
|
+
}
|
|
411
|
+
function indexRuns(indices) {
|
|
412
|
+
const sorted = [...indices].sort((a, b) => a - b);
|
|
413
|
+
const runs = [];
|
|
414
|
+
for (const index of sorted) {
|
|
415
|
+
const last = runs[runs.length - 1];
|
|
416
|
+
if (last && index === last[1] + 1) last[1] = index;
|
|
417
|
+
else runs.push([index, index]);
|
|
418
|
+
}
|
|
419
|
+
return runs;
|
|
420
|
+
}
|
|
421
|
+
function windowSeconds(window2) {
|
|
422
|
+
return (window2.endIn + window2.endOut) / 2 - (window2.startOut + window2.startIn) / 2;
|
|
423
|
+
}
|
|
424
|
+
function runWindow(frames, [first, last], duration) {
|
|
425
|
+
const timeAt = (index) => frames[Math.min(Math.max(index, 0), frames.length - 1)]?.time ?? 0;
|
|
426
|
+
const reachesEnd = last === frames.length - 1;
|
|
427
|
+
return {
|
|
428
|
+
startOut: timeAt(first - 1),
|
|
429
|
+
startIn: timeAt(first),
|
|
430
|
+
endIn: reachesEnd ? duration : timeAt(last),
|
|
431
|
+
endOut: reachesEnd ? duration : timeAt(last + 1)
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
function lineCandidates(frames, duration, canvas) {
|
|
435
|
+
const readHeight = T.readHeightAt1080 * (Math.min(canvas.width, canvas.height) / 1080);
|
|
436
|
+
const tracks = trackBlocks(frames, readHeight);
|
|
437
|
+
const lastEnd = (track) => Math.max(...track.seen.keys());
|
|
438
|
+
const latest = Math.max(-1, ...tracks.map(lastEnd));
|
|
439
|
+
const candidates = [];
|
|
440
|
+
for (const track of tracks) {
|
|
441
|
+
const runs = indexRuns([...track.seen.keys()]);
|
|
442
|
+
const finalLine = lastEnd(track) === latest;
|
|
443
|
+
const windows = runs.map((run2) => runWindow(frames, run2, duration));
|
|
444
|
+
const chosen = finalLine ? windows.length - 1 : windows.reduce((best, window3, index) => {
|
|
445
|
+
const bestWindow = windows[best];
|
|
446
|
+
return bestWindow && windowSeconds(window3) > windowSeconds(bestWindow) ? index : best;
|
|
447
|
+
}, 0);
|
|
448
|
+
const window2 = windows[chosen];
|
|
449
|
+
const run = runs[chosen];
|
|
450
|
+
if (!window2 || !run) continue;
|
|
451
|
+
const texts = [...track.seen.values()].map((seen) => seen.text);
|
|
452
|
+
const text = texts.reduce(
|
|
453
|
+
(longest, next) => readingWords(next) > readingWords(longest) ? next : longest
|
|
454
|
+
);
|
|
455
|
+
const words = readingWords(text);
|
|
456
|
+
if (words === 0) continue;
|
|
457
|
+
const floor = lineFloorSec(words, finalLine);
|
|
458
|
+
if (window2.endIn - window2.startIn >= floor) continue;
|
|
459
|
+
candidates.push({ track, words, text, finalLine, floor, window: window2, firstIndex: run[0] });
|
|
460
|
+
}
|
|
461
|
+
return candidates;
|
|
462
|
+
}
|
|
463
|
+
async function refineWindow(candidate, probe, canvas) {
|
|
464
|
+
const readHeight = T.readHeightAt1080 * (Math.min(canvas.width, canvas.height) / 1080);
|
|
465
|
+
const visibleAt = async (time) => readableBlocks(await probe(time), readHeight).has(candidate.track.key);
|
|
466
|
+
const window2 = { ...candidate.window };
|
|
467
|
+
for (let step = 0; step < T.refineSteps; step += 1) {
|
|
468
|
+
if (window2.startIn > window2.startOut) {
|
|
469
|
+
const mid = (window2.startOut + window2.startIn) / 2;
|
|
470
|
+
if (await visibleAt(mid)) window2.startIn = mid;
|
|
471
|
+
else window2.startOut = mid;
|
|
472
|
+
}
|
|
473
|
+
if (window2.endOut > window2.endIn) {
|
|
474
|
+
const mid = (window2.endIn + window2.endOut) / 2;
|
|
475
|
+
if (await visibleAt(mid)) window2.endIn = mid;
|
|
476
|
+
else window2.endOut = mid;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return window2;
|
|
480
|
+
}
|
|
481
|
+
async function detectLineUnread(frames, duration, canvas, probe) {
|
|
482
|
+
const findings = [];
|
|
483
|
+
const candidates = lineCandidates(frames, duration, canvas);
|
|
484
|
+
for (const [index, candidate] of candidates.entries()) {
|
|
485
|
+
const window2 = probe && index < T.maxRefinedLines ? await refineWindow(candidate, probe, canvas) : candidate.window;
|
|
486
|
+
const held = windowSeconds(window2);
|
|
487
|
+
if (held >= candidate.floor - T.measureToleranceSec) continue;
|
|
488
|
+
const error = Math.max(window2.startIn - window2.startOut, window2.endOut - window2.endIn) / 2;
|
|
489
|
+
findings.push(lineUnreadFinding(candidate, window2, held, error));
|
|
490
|
+
}
|
|
491
|
+
return findings;
|
|
492
|
+
}
|
|
493
|
+
function lineUnreadFinding(candidate, window2, held, error) {
|
|
494
|
+
const { track, words, text, finalLine, floor } = candidate;
|
|
495
|
+
const quoted = quote(text, 60);
|
|
496
|
+
const wordLabel = `${words} word${words === 1 ? "" : "s"}`;
|
|
497
|
+
const measured = `${seconds(held)} (\xB1${Math.max(0.01, error).toFixed(2)} s)`;
|
|
498
|
+
const target = lineTargetSec(words);
|
|
499
|
+
const message = finalLine ? `The film's last line ${quoted} (${wordLabel}) is on screen ${measured}, under the ${seconds(floor)} a closing line needs: hold it about 0.5 s + 0.3 s a word and at least 2 s before the film ends; see references/motion.md.` : `${quoted} (${wordLabel}) is on screen ${measured}, under its ${seconds(floor)} floor: hold it about 0.5 s + 0.3 s a word (${seconds(target)} here) before it leaves or changes; see references/motion.md.`;
|
|
500
|
+
const firstSeen = track.seen.get(candidate.firstIndex);
|
|
501
|
+
const rect = firstSeen?.rect;
|
|
502
|
+
return {
|
|
503
|
+
code: "line_unread",
|
|
504
|
+
severity: "warning",
|
|
505
|
+
message,
|
|
506
|
+
text,
|
|
507
|
+
selector: track.selector,
|
|
508
|
+
dataAttributes: {},
|
|
509
|
+
sourceFile: track.sourceFile,
|
|
510
|
+
bbox: rect ? { x: rect.left, y: rect.top, width: rect.right - rect.left, height: rect.bottom - rect.top } : ZERO_BBOX,
|
|
511
|
+
time: round(window2.startIn),
|
|
512
|
+
words,
|
|
513
|
+
seconds: round(held),
|
|
514
|
+
floorSeconds: round(floor)
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function typeFloorPx(canvas) {
|
|
518
|
+
return Math.round(T.typeFloorFraction * Math.min(canvas.width, canvas.height));
|
|
519
|
+
}
|
|
520
|
+
function detectTextBelowFloor(frames, duration, canvas) {
|
|
521
|
+
const floorPx = typeFloorPx(canvas);
|
|
522
|
+
const step = sampleStep(frames);
|
|
523
|
+
const sightings = /* @__PURE__ */ new Map();
|
|
524
|
+
frames.forEach((frame, index) => {
|
|
525
|
+
for (const part of frame.parts) {
|
|
526
|
+
if (part.captions || part.opacity < T.readOpacity) continue;
|
|
527
|
+
if (part.fontPx >= floorPx - 0.5 || readingWords(part.text) === 0) continue;
|
|
528
|
+
const seen = sightings.get(part.key) ?? /* @__PURE__ */ new Map();
|
|
529
|
+
seen.set(index, part);
|
|
530
|
+
sightings.set(part.key, seen);
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
const small = [];
|
|
534
|
+
for (const seen of sightings.values()) {
|
|
535
|
+
const [first, last] = longestRun(indexRuns([...seen.keys()]));
|
|
536
|
+
const start = frames[first]?.time ?? 0;
|
|
537
|
+
const end = last === frames.length - 1 ? duration : (frames[last]?.time ?? start) + step;
|
|
538
|
+
if (end - start < T.typeFloorHoldSec) continue;
|
|
539
|
+
const parts = [...seen.values()];
|
|
540
|
+
const part = parts[0];
|
|
541
|
+
if (!part) continue;
|
|
542
|
+
small.push({
|
|
543
|
+
selector: part.selector,
|
|
544
|
+
sourceFile: part.sourceFile,
|
|
545
|
+
text: part.text,
|
|
546
|
+
fontPx: Math.min(...parts.map((entry) => entry.fontPx)),
|
|
547
|
+
seconds: end - start,
|
|
548
|
+
time: start,
|
|
549
|
+
bbox: {
|
|
550
|
+
x: part.rect.left,
|
|
551
|
+
y: part.rect.top,
|
|
552
|
+
width: part.rect.width,
|
|
553
|
+
height: part.rect.height
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
const shortSide = Math.min(canvas.width, canvas.height);
|
|
558
|
+
return groupBySourceFile(small).map((group) => smallTextFinding(group, floorPx, shortSide));
|
|
559
|
+
}
|
|
560
|
+
function longestRun(runs) {
|
|
561
|
+
return runs.reduce((best, run) => run[1] - run[0] > best[1] - best[0] ? run : best, [0, -1]);
|
|
562
|
+
}
|
|
563
|
+
function groupBySourceFile(small) {
|
|
564
|
+
const groups = /* @__PURE__ */ new Map();
|
|
565
|
+
for (const entry of small)
|
|
566
|
+
groups.set(entry.sourceFile, [...groups.get(entry.sourceFile) ?? [], entry]);
|
|
567
|
+
return [...groups.values()].map(
|
|
568
|
+
(group) => group.sort((a, b) => a.fontPx - b.fontPx || a.time - b.time)
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
function quote(text, max) {
|
|
572
|
+
return `"${text.length > max ? `${text.slice(0, max - 3)}...` : text}"`;
|
|
573
|
+
}
|
|
574
|
+
function smallTextFinding(group, floorPx, shortSide) {
|
|
575
|
+
const [smallest] = group;
|
|
576
|
+
if (!smallest) throw new Error("text_below_floor group is empty");
|
|
577
|
+
const subject = group.length === 1 ? `${quote(smallest.text, 48)} renders at ${Math.round(smallest.fontPx)} px for ${seconds(smallest.seconds)}` : `${group.length} text elements stay under it for 0.5 s or more, the smallest ${quote(smallest.text, 40)} at ${Math.round(smallest.fontPx)} px`;
|
|
578
|
+
const byTime = [...group].sort((a, b) => a.time - b.time);
|
|
579
|
+
return {
|
|
580
|
+
code: "text_below_floor",
|
|
581
|
+
severity: "warning",
|
|
582
|
+
message: `Type floor is ${floorPx} px (2.6% of the ${shortSide} px short side, what a phone can read) and ${subject}: set reading text to at least ${floorPx} px, or put data-layout-ignore on text that is texture rather than reading; see references/look.md.`,
|
|
583
|
+
text: smallest.text,
|
|
584
|
+
selector: smallest.selector,
|
|
585
|
+
dataAttributes: {},
|
|
586
|
+
sourceFile: smallest.sourceFile,
|
|
587
|
+
bbox: smallest.bbox,
|
|
588
|
+
time: round(smallest.time),
|
|
589
|
+
times: byTime.map((entry) => round(entry.time)),
|
|
590
|
+
fontPx: round(smallest.fontPx),
|
|
591
|
+
floorPx,
|
|
592
|
+
seconds: round(smallest.seconds),
|
|
593
|
+
elements: group.map((entry) => ({
|
|
594
|
+
selector: entry.selector,
|
|
595
|
+
text: entry.text,
|
|
596
|
+
fontPx: round(entry.fontPx),
|
|
597
|
+
time: round(entry.time),
|
|
598
|
+
seconds: round(entry.seconds)
|
|
599
|
+
}))
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
function round(value) {
|
|
603
|
+
return Math.round(value * 1e3) / 1e3;
|
|
604
|
+
}
|
|
605
|
+
|
|
204
606
|
// src/utils/hdrPromotion.ts
|
|
205
607
|
async function bundleProjectHtml(projectDir) {
|
|
206
|
-
const { bundleToSingleHtml } = await import("./compiler-
|
|
608
|
+
const { bundleToSingleHtml } = await import("./compiler-2EKSMC3I.js");
|
|
207
609
|
return bundleToSingleHtml(projectDir);
|
|
208
610
|
}
|
|
209
611
|
async function collectBundledRenderMedia(html) {
|
|
@@ -279,7 +681,7 @@ function parseColorRGBA(color) {
|
|
|
279
681
|
// src/utils/checkPipeline.ts
|
|
280
682
|
var MOTION_FPS = 20;
|
|
281
683
|
var MOTION_MAX_SAMPLES = 300;
|
|
282
|
-
var
|
|
684
|
+
var ZERO_BBOX2 = { x: 0, y: 0, width: 0, height: 0 };
|
|
283
685
|
var FRAME_BREACH_FLOOR_PX = 120;
|
|
284
686
|
var FRAME_BREACH_FLOOR_FRACTION = 0.06;
|
|
285
687
|
var DEFAULT_CHECK_OPTIONS = {
|
|
@@ -518,7 +920,8 @@ function emptyGridSamples() {
|
|
|
518
920
|
contrastMs: 0,
|
|
519
921
|
layoutStateSignatures: [],
|
|
520
922
|
rotationSamples: [],
|
|
521
|
-
indicatorFrames: []
|
|
923
|
+
indicatorFrames: [],
|
|
924
|
+
craftFrames: []
|
|
522
925
|
};
|
|
523
926
|
}
|
|
524
927
|
function appendGridSamples(into, from) {
|
|
@@ -530,6 +933,7 @@ function appendGridSamples(into, from) {
|
|
|
530
933
|
into.layoutStateSignatures.push(...from.layoutStateSignatures);
|
|
531
934
|
into.rotationSamples.push(...from.rotationSamples);
|
|
532
935
|
into.indicatorFrames.push(...from.indicatorFrames);
|
|
936
|
+
into.craftFrames.push(...from.craftFrames);
|
|
533
937
|
}
|
|
534
938
|
async function collectSampleAt(driver, options, grid, motion, sets, time) {
|
|
535
939
|
const collected = emptyGridSamples();
|
|
@@ -561,7 +965,7 @@ async function collectSampleAt(driver, options, grid, motion, sets, time) {
|
|
|
561
965
|
await collectContrastAt(driver, options, time, issuesAtTime, collected);
|
|
562
966
|
return collected;
|
|
563
967
|
}
|
|
564
|
-
async function collectGridSamples(driver, options, grid, motion, helpers) {
|
|
968
|
+
async function collectGridSamples(driver, options, grid, motion, helpers, enter) {
|
|
565
969
|
const geometryEnabled = grid.captionSamples.length > 0 || grid.frameSamples.length > 0;
|
|
566
970
|
const sets = {
|
|
567
971
|
layout: new Set(grid.layoutSamples),
|
|
@@ -605,9 +1009,20 @@ async function collectGridSamples(driver, options, grid, motion, helpers) {
|
|
|
605
1009
|
driver.markSamples?.("end");
|
|
606
1010
|
const collected = emptyGridSamples();
|
|
607
1011
|
for (const samples of perTime) appendGridSamples(collected, samples);
|
|
608
|
-
|
|
1012
|
+
enter("overlap");
|
|
1013
|
+
await collectMotionOverlapSamples(
|
|
1014
|
+
driver,
|
|
1015
|
+
grid,
|
|
1016
|
+
collected,
|
|
1017
|
+
options.range,
|
|
1018
|
+
craftEnabled(driver, options)
|
|
1019
|
+
);
|
|
1020
|
+
enter("samples");
|
|
609
1021
|
return collected;
|
|
610
1022
|
}
|
|
1023
|
+
function craftEnabled(driver, options) {
|
|
1024
|
+
return !options.range && typeof driver.collectCraftFrame === "function";
|
|
1025
|
+
}
|
|
611
1026
|
async function collectContrastAt(driver, options, time, issuesAtTime, collected) {
|
|
612
1027
|
const contrastStart = Date.now();
|
|
613
1028
|
const capture = options.snapshots ? await driver.collectContrast(time, annotationBoxesFrom(issuesAtTime)) : await driver.collectContrast(time);
|
|
@@ -683,9 +1098,16 @@ async function denseOverlapTimes(driver, grid, range) {
|
|
|
683
1098
|
const overlapTimes = buildOverlapSampleTimes(range ? range[1] - range[0] : grid.duration, edges);
|
|
684
1099
|
return range ? mergeSampleTimes(overlapTimes.map((time) => time + range[0])) : overlapTimes;
|
|
685
1100
|
}
|
|
686
|
-
async function collectMotionOverlapSamples(driver, grid, collected, range) {
|
|
1101
|
+
async function collectMotionOverlapSamples(driver, grid, collected, range, craft) {
|
|
687
1102
|
const baseTimes = new Set(grid.layoutSamples);
|
|
688
1103
|
const shiftedTimes = await denseOverlapTimes(driver, grid, range);
|
|
1104
|
+
if (craft) {
|
|
1105
|
+
for (const time of buildCraftSampleTimes(grid.duration)) {
|
|
1106
|
+
if (time >= grid.duration) continue;
|
|
1107
|
+
await driver.seekGeometry(time);
|
|
1108
|
+
collected.craftFrames.push(...await collectCraftFrame(driver, time));
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
689
1111
|
const probeHold = holdProber(driver, collected, range ? range[1] : grid.duration);
|
|
690
1112
|
const gridIssues = await driver.collectOverlapGrid(shiftedTimes.filter((t) => !baseTimes.has(t)));
|
|
691
1113
|
let sample = 0;
|
|
@@ -696,6 +1118,22 @@ async function collectMotionOverlapSamples(driver, grid, collected, range) {
|
|
|
696
1118
|
await probeHold(time, shiftedTimes[index + 1] ?? Number.POSITIVE_INFINITY, issues);
|
|
697
1119
|
}
|
|
698
1120
|
}
|
|
1121
|
+
var CRAFT_SAMPLE_FPS = 8;
|
|
1122
|
+
var CRAFT_MAX_SAMPLES = 600;
|
|
1123
|
+
function buildCraftSampleTimes(duration) {
|
|
1124
|
+
if (!Number.isFinite(duration) || duration <= 0) return [];
|
|
1125
|
+
const count = Math.min(
|
|
1126
|
+
CRAFT_MAX_SAMPLES,
|
|
1127
|
+
Math.max(2, Math.ceil(duration * CRAFT_SAMPLE_FPS) + 1)
|
|
1128
|
+
);
|
|
1129
|
+
const step = duration / (count - 1);
|
|
1130
|
+
return mergeSampleTimes(
|
|
1131
|
+
Array.from({ length: count }, (_, index) => Math.round(index * step * 1e3) / 1e3)
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1134
|
+
async function collectCraftFrame(driver, time) {
|
|
1135
|
+
return driver.collectCraftFrame ? [await driver.collectCraftFrame(time)] : [];
|
|
1136
|
+
}
|
|
699
1137
|
var SWEEP_STATIC_MIN_DURATION_SEC = 3;
|
|
700
1138
|
var ZERO_LAYOUT_RECT = {
|
|
701
1139
|
left: 0,
|
|
@@ -797,7 +1235,7 @@ function sweepStaticIssue(kind) {
|
|
|
797
1235
|
selector: "[data-composition-id]",
|
|
798
1236
|
dataAttributes: {},
|
|
799
1237
|
sourceFile: "index.html",
|
|
800
|
-
bbox:
|
|
1238
|
+
bbox: ZERO_BBOX2,
|
|
801
1239
|
rect: ZERO_LAYOUT_RECT,
|
|
802
1240
|
message: SWEEP_STATIC_MESSAGES[kind],
|
|
803
1241
|
fixHint: kind === "error" ? "An animation on the page never moved under seek. Build it on the paused GSAP timeline registered in `window.__timelines[compositionId]`, or as a CSS animation, so the seek drives it." : STILL_FIX_HINT
|
|
@@ -1131,7 +1569,17 @@ function detectOffPivotRotation(frames) {
|
|
|
1131
1569
|
function annotationBoxesFrom(issues) {
|
|
1132
1570
|
return issues.filter((issue) => issue.severity === "error" && issue.bbox.width > 0 && issue.bbox.height > 0).map((issue, index) => ({ label: `${index + 1} ${issue.code}`, bbox: issue.bbox }));
|
|
1133
1571
|
}
|
|
1134
|
-
|
|
1572
|
+
function wholeCompositionKeepsMoving(assertions) {
|
|
1573
|
+
return assertions.some(
|
|
1574
|
+
(assertion) => assertion.kind === "keepsMoving" && assertion.withinSelector === void 0
|
|
1575
|
+
);
|
|
1576
|
+
}
|
|
1577
|
+
function disabledCraft() {
|
|
1578
|
+
return { enabled: false, step: 0, samples: 0, findings: [] };
|
|
1579
|
+
}
|
|
1580
|
+
async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([]), enter = () => {
|
|
1581
|
+
}) {
|
|
1582
|
+
enter("samples");
|
|
1135
1583
|
await driver.initialize(options.contrast);
|
|
1136
1584
|
const grid = await buildSampleGrid(driver, options);
|
|
1137
1585
|
const plan = await planMotionSampling(
|
|
@@ -1140,28 +1588,24 @@ async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([
|
|
|
1140
1588
|
grid.duration
|
|
1141
1589
|
);
|
|
1142
1590
|
const seekLoopStart = Date.now();
|
|
1143
|
-
const collected = await collectGridSamples(driver, options, grid, plan, helpers);
|
|
1591
|
+
const collected = await collectGridSamples(driver, options, grid, plan, helpers, enter);
|
|
1144
1592
|
const seekLoopMs = Date.now() - seekLoopStart;
|
|
1145
1593
|
let motionIssues = plan.preflightIssues;
|
|
1146
1594
|
if (motion.kind === "valid" && plan.assertions.length > 0 && collected.motionFrames.length > 0) {
|
|
1147
1595
|
const canvas = await driver.getCanvas();
|
|
1148
|
-
let evaluated = evaluateMotion(collected.motionFrames, plan.assertions, canvas);
|
|
1596
|
+
let evaluated = evaluateMotion(collected.motionFrames, plan.assertions, canvas, grid.duration);
|
|
1149
1597
|
if (evaluated.some((issue) => issue.code === "motion_frozen")) {
|
|
1150
1598
|
const frames = await withFrameMotion(driver, collected.motionFrames, plan.assertions);
|
|
1151
|
-
evaluated = evaluateMotion(frames, plan.assertions, canvas);
|
|
1599
|
+
evaluated = evaluateMotion(frames, plan.assertions, canvas, grid.duration);
|
|
1152
1600
|
}
|
|
1153
1601
|
motionIssues = [...motionIssues, ...await driver.anchorMotionIssues(evaluated)];
|
|
1154
1602
|
}
|
|
1155
1603
|
const userPicked = new Set(grid.userPickedSamples);
|
|
1604
|
+
const noTimeline = await driver.hasNoTimelineDeclaration();
|
|
1156
1605
|
const sweepSamples = collected.layoutStateSignatures.filter(
|
|
1157
1606
|
(sample) => !userPicked.has(sample.time)
|
|
1158
1607
|
);
|
|
1159
|
-
const sweepVerdict = options.range ? [] : detectSweepStatic(
|
|
1160
|
-
grid.duration,
|
|
1161
|
-
sweepSamples,
|
|
1162
|
-
motionIssues,
|
|
1163
|
-
await driver.hasNoTimelineDeclaration()
|
|
1164
|
-
);
|
|
1608
|
+
const sweepVerdict = options.range ? [] : detectSweepStatic(grid.duration, sweepSamples, motionIssues, noTimeline);
|
|
1165
1609
|
const sweepFindings = sweepVerdict.length > 0 && await framesMoved(
|
|
1166
1610
|
driver,
|
|
1167
1611
|
sweepSamples.map((sample) => sample.time)
|
|
@@ -1172,6 +1616,20 @@ async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([
|
|
|
1172
1616
|
);
|
|
1173
1617
|
const offPivotFindings = detectOffPivotRotation(collected.indicatorFrames);
|
|
1174
1618
|
const contrast = buildContrastResults(collected.contrastEntries);
|
|
1619
|
+
const craft = craftEnabled(driver, options) ? await auditCraft(
|
|
1620
|
+
{
|
|
1621
|
+
frames: collected.craftFrames,
|
|
1622
|
+
duration: grid.duration,
|
|
1623
|
+
canvas: await driver.getCanvas(),
|
|
1624
|
+
soundSources: driver.collectCraftFilm ? (await driver.collectCraftFilm()).soundSources : null,
|
|
1625
|
+
stillnessJudgedElsewhere: noTimeline || sweepFindings.length > 0 || wholeCompositionKeepsMoving(plan.assertions)
|
|
1626
|
+
},
|
|
1627
|
+
async (time) => {
|
|
1628
|
+
await driver.seekGeometry(time);
|
|
1629
|
+
if (!driver.collectCraftFrame) throw new Error("craft sampling unavailable");
|
|
1630
|
+
return driver.collectCraftFrame(time);
|
|
1631
|
+
}
|
|
1632
|
+
) : disabledCraft();
|
|
1175
1633
|
if (options.components?.length) {
|
|
1176
1634
|
if (!driver.matchComponents)
|
|
1177
1635
|
throw new Error("Component filtering unavailable in this check driver");
|
|
@@ -1181,7 +1639,8 @@ async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([
|
|
|
1181
1639
|
...rotationFindings,
|
|
1182
1640
|
...offPivotFindings,
|
|
1183
1641
|
...motionIssues,
|
|
1184
|
-
...contrast.findings
|
|
1642
|
+
...contrast.findings,
|
|
1643
|
+
...craft.findings
|
|
1185
1644
|
];
|
|
1186
1645
|
const matches = await driver.matchComponents(options.components, findings);
|
|
1187
1646
|
findings.forEach((finding, i) => {
|
|
@@ -1206,6 +1665,7 @@ async function runAuditGrid(driver, options, motion, helpers = Promise.resolve([
|
|
|
1206
1665
|
contrastFindings: contrast.findings,
|
|
1207
1666
|
contrastChecked: collected.contrastEntries.length,
|
|
1208
1667
|
contrastPassed: contrast.passed,
|
|
1668
|
+
craft,
|
|
1209
1669
|
screenshots: collected.screenshots,
|
|
1210
1670
|
timings: { launchSettleMs: 0, seekLoopMs, contrastMs: collected.contrastMs },
|
|
1211
1671
|
skipped: false
|
|
@@ -1332,6 +1792,7 @@ async function withFindingCrops(dependencies, project, options, report, deadline
|
|
|
1332
1792
|
const cropRequests = selectFindingCropRequests(report);
|
|
1333
1793
|
if (cropRequests.length === 0) return report;
|
|
1334
1794
|
try {
|
|
1795
|
+
deadline.enter("crops");
|
|
1335
1796
|
const findingFiles = await deadline.run(
|
|
1336
1797
|
() => dependencies.captureFindingCrops(project, options, cropRequests, deadline)
|
|
1337
1798
|
);
|
|
@@ -1443,7 +1904,7 @@ function buildLintSection(result) {
|
|
|
1443
1904
|
selector: finding.selector ?? (finding.elementId ? `#${finding.elementId}` : "[data-composition-id]"),
|
|
1444
1905
|
dataAttributes: {},
|
|
1445
1906
|
sourceFile: finding.file ?? file,
|
|
1446
|
-
bbox:
|
|
1907
|
+
bbox: ZERO_BBOX2,
|
|
1447
1908
|
time: 0,
|
|
1448
1909
|
fixHint: finding.fixHint
|
|
1449
1910
|
}))
|
|
@@ -1458,10 +1919,12 @@ function buildReport(options, lint, browser, motion, extraMotionFindings, snapsh
|
|
|
1458
1919
|
const runtime = section(browser.runtimeFindings);
|
|
1459
1920
|
const motionSection = section(motionFindings);
|
|
1460
1921
|
const contrastSection = section(browser.contrastFindings);
|
|
1461
|
-
const
|
|
1462
|
-
const
|
|
1922
|
+
const craftSection = section(browser.craft.findings);
|
|
1923
|
+
const warningCount = lint.warningCount + runtime.warningCount + layout.warningCount + motionSection.warningCount + contrastSection.warningCount + craftSection.warningCount;
|
|
1924
|
+
const errorCount = lint.errorCount + runtime.errorCount + layout.errorCount + motionSection.errorCount + contrastSection.errorCount + craftSection.errorCount;
|
|
1925
|
+
const strictWarningCount = warningCount - craftSection.warningCount;
|
|
1463
1926
|
const report = {
|
|
1464
|
-
ok: errorCount === 0 && (!options.strict ||
|
|
1927
|
+
ok: errorCount === 0 && (!options.strict || strictWarningCount === 0),
|
|
1465
1928
|
strict: options.strict,
|
|
1466
1929
|
browserSkipped: browser.skipped,
|
|
1467
1930
|
lint,
|
|
@@ -1480,6 +1943,12 @@ function buildReport(options, lint, browser, motion, extraMotionFindings, snapsh
|
|
|
1480
1943
|
checked: browser.contrastChecked,
|
|
1481
1944
|
passed: browser.contrastPassed
|
|
1482
1945
|
},
|
|
1946
|
+
craft: {
|
|
1947
|
+
...craftSection,
|
|
1948
|
+
enabled: browser.craft.enabled,
|
|
1949
|
+
step: browser.craft.step,
|
|
1950
|
+
samples: browser.craft.samples
|
|
1951
|
+
},
|
|
1483
1952
|
hdr: { autoPromotion: hdrPromotion, inspection: hdrInspection },
|
|
1484
1953
|
snapshots: {
|
|
1485
1954
|
enabled: options.snapshots,
|
|
@@ -1504,6 +1973,7 @@ function buildReport(options, lint, browser, motion, extraMotionFindings, snapsh
|
|
|
1504
1973
|
motionWarnings: motionSection.warningCount,
|
|
1505
1974
|
contrastErrors: contrastSection.errorCount,
|
|
1506
1975
|
contrastWarnings: contrastSection.warningCount,
|
|
1976
|
+
craftWarnings: craftSection.warningCount,
|
|
1507
1977
|
launchSettleMs: browser.timings.launchSettleMs,
|
|
1508
1978
|
seekLoopMs: browser.timings.seekLoopMs,
|
|
1509
1979
|
contrastMs: browser.timings.contrastMs,
|
|
@@ -1525,11 +1995,11 @@ function filterComponentReport(report, options) {
|
|
|
1525
1995
|
notes: [
|
|
1526
1996
|
"Static lint and unscoped runtime failures remain project-wide.",
|
|
1527
1997
|
...options.range ? [
|
|
1528
|
-
"Whole-timeline motion assertions
|
|
1998
|
+
"Whole-timeline motion assertions, frozen-sweep detection and craft warnings are skipped for range checks."
|
|
1529
1999
|
] : []
|
|
1530
2000
|
]
|
|
1531
2001
|
};
|
|
1532
|
-
for (const group of [report.layout, report.motion, report.contrast]) {
|
|
2002
|
+
for (const group of [report.layout, report.motion, report.contrast, report.craft]) {
|
|
1533
2003
|
const before = group.findings.length;
|
|
1534
2004
|
group.findings = group.findings.filter((f) => f.componentMatch !== false);
|
|
1535
2005
|
report.scope.hiddenFindings += before - group.findings.length;
|
|
@@ -1612,6 +2082,7 @@ function emptyBrowserResult() {
|
|
|
1612
2082
|
contrastFindings: [],
|
|
1613
2083
|
contrastChecked: 0,
|
|
1614
2084
|
contrastPassed: 0,
|
|
2085
|
+
craft: disabledCraft(),
|
|
1615
2086
|
screenshots: [],
|
|
1616
2087
|
timings: { launchSettleMs: 0, seekLoopMs: 0, contrastMs: 0 },
|
|
1617
2088
|
skipped: true
|
|
@@ -1633,7 +2104,7 @@ function findingAtRoot(code, severity, message, sourceFile) {
|
|
|
1633
2104
|
selector: "[data-composition-id]",
|
|
1634
2105
|
dataAttributes: {},
|
|
1635
2106
|
sourceFile,
|
|
1636
|
-
bbox:
|
|
2107
|
+
bbox: ZERO_BBOX2,
|
|
1637
2108
|
time: 0
|
|
1638
2109
|
};
|
|
1639
2110
|
}
|
|
@@ -1662,7 +2133,7 @@ function resolveMotionSpec(projectDir) {
|
|
|
1662
2133
|
};
|
|
1663
2134
|
}
|
|
1664
2135
|
async function runBrowserCheck(project, options, motion, deadline, prelaunched) {
|
|
1665
|
-
const module = await import("./checkBrowser-
|
|
2136
|
+
const module = await import("./checkBrowser-X7G6YNR7.js");
|
|
1666
2137
|
return module.runBrowserCheck(project, options, motion, runAuditGrid, deadline, prelaunched);
|
|
1667
2138
|
}
|
|
1668
2139
|
var adoptedBrowser;
|
|
@@ -1676,7 +2147,7 @@ async function prelaunchBrowser(project, options) {
|
|
|
1676
2147
|
if (adopted) return adopted;
|
|
1677
2148
|
const html = await readFile(project.indexPath, "utf8").catch(() => void 0);
|
|
1678
2149
|
if (html === void 0) return void 0;
|
|
1679
|
-
const { prelaunchCompositionBrowser } = await import("./captureCompositionFrame-
|
|
2150
|
+
const { prelaunchCompositionBrowser } = await import("./captureCompositionFrame-5FVLAETA.js");
|
|
1680
2151
|
return prelaunchCompositionBrowser(html, options.browserGpuMode);
|
|
1681
2152
|
}
|
|
1682
2153
|
async function writeSnapshot(projectDir, index, time, pngBase64) {
|
|
@@ -1688,7 +2159,7 @@ async function writeSnapshot(projectDir, index, time, pngBase64) {
|
|
|
1688
2159
|
return relative(projectDir, path);
|
|
1689
2160
|
}
|
|
1690
2161
|
async function captureFindingCrops(project, options, requests, deadline) {
|
|
1691
|
-
const module = await import("./checkBrowser-
|
|
2162
|
+
const module = await import("./checkBrowser-X7G6YNR7.js");
|
|
1692
2163
|
return module.captureFindingCrops(project, options, requests, deadline);
|
|
1693
2164
|
}
|
|
1694
2165
|
var DEFAULT_DEPENDENCIES2 = {
|
|
@@ -2134,6 +2605,7 @@ function printHumanReport(report) {
|
|
|
2134
2605
|
printLayoutSection("Layout", report.layout);
|
|
2135
2606
|
printSection("Motion", report.motion);
|
|
2136
2607
|
printContrastSection(report);
|
|
2608
|
+
printCraftSection(report);
|
|
2137
2609
|
printSnapshotSection(report);
|
|
2138
2610
|
console.log();
|
|
2139
2611
|
const label = report.ok ? c.success("Check passed") : c.error("Check failed");
|
|
@@ -2192,6 +2664,16 @@ function printContrastSection(report) {
|
|
|
2192
2664
|
}
|
|
2193
2665
|
printCounts(section2);
|
|
2194
2666
|
}
|
|
2667
|
+
function printCraftSection(report) {
|
|
2668
|
+
const section2 = report.craft;
|
|
2669
|
+
if (!section2.enabled) {
|
|
2670
|
+
console.log();
|
|
2671
|
+
console.log(c.bold("Craft"));
|
|
2672
|
+
console.log(` ${c.dim("\u25C7")} skipped`);
|
|
2673
|
+
return;
|
|
2674
|
+
}
|
|
2675
|
+
printSection("Craft", section2);
|
|
2676
|
+
}
|
|
2195
2677
|
function printSnapshotSection(report) {
|
|
2196
2678
|
console.log();
|
|
2197
2679
|
console.log(c.bold("Snapshots"));
|