hyperframes 0.8.110 → 0.8.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/dist/{add-D7AY7MSS.js → add-NIVC2YMT.js} +15 -15
  2. package/dist/{agentPromptGenerator-QL2KAWEP.js → agentPromptGenerator-VIIPZCJ3.js} +1 -1
  3. package/dist/{animatedGifPrep-NMGFOSIL.js → animatedGifPrep-NWAJKCHG.js} +6 -6
  4. package/dist/{asset-63Q4ARX7.js → asset-O6JJKF3Z.js} +2 -2
  5. package/dist/{assetCataloger-FXEHOUA3.js → assetCataloger-DJSPW3RL.js} +2 -2
  6. package/dist/{auth-D5QNNEKM.js → auth-6XRZQQQS.js} +2 -2
  7. package/dist/{autoUpdate-25QUBTDS.js → autoUpdate-GZHLQBLS.js} +2 -2
  8. package/dist/{backgroundChecks-G2AHVDCY.js → backgroundChecks-4QQRGJ5S.js} +3 -3
  9. package/dist/backgroundChecksWorker.js +3 -3
  10. package/dist/{batchRender-ZTHFMHZY.js → batchRender-PJGNXN7F.js} +3 -3
  11. package/dist/{beats-43LEYJ76.js → beats-VYR6B4UB.js} +10 -10
  12. package/dist/{benchmark-JQ5LYY6Z.js → benchmark-CGP2NKIP.js} +12 -12
  13. package/dist/{browser-KQLNYNOH.js → browser-ZWD4ETXK.js} +9 -9
  14. package/dist/{bundleWithLocalizedFonts-4Q3ETTHW.js → bundleWithLocalizedFonts-JWHKLSZM.js} +2 -2
  15. package/dist/{capture-4OPH4PMK.js → capture-C4MPRLJV.js} +40 -42
  16. package/dist/{capture-OG6532RA.js → capture-IQ7AUK6M.js} +3 -3
  17. package/dist/{captureFile-JOPOCRU7.js → captureFile-LYOJOUIE.js} +3 -1
  18. package/dist/{catalog-EAFDIYFH.js → catalog-RZ7PWQMS.js} +15 -15
  19. package/dist/{check-VAJ6G3RU.js → check-7UU4SSO6.js} +50 -38
  20. package/dist/{checkBrowser-GUWLYPVJ.js → checkBrowser-6KYNYIU7.js} +32 -31
  21. package/dist/{chunk-CFC3EEDQ.js → chunk-2BEOCUAG.js} +1 -1
  22. package/dist/{chunk-E5OSOQKO.js → chunk-2GXKCB7J.js} +1 -1
  23. package/dist/{chunk-HQGJLZB6.js → chunk-36XLW2TP.js} +2 -2
  24. package/dist/{chunk-NH75EKOP.js → chunk-3Q7HXIXZ.js} +1 -1
  25. package/dist/{chunk-2JXJ5SGK.js → chunk-4BXTKKRD.js} +6 -6
  26. package/dist/{chunk-XYVFPDNU.js → chunk-5SDXALUQ.js} +1 -1
  27. package/dist/{chunk-ITBEN3QD.js → chunk-7G25WGTA.js} +2 -2
  28. package/dist/{chunk-YIXEH4TF.js → chunk-7OJSZTJK.js} +2 -2
  29. package/dist/{chunk-5ER3PYYP.js → chunk-7VIXEM6Q.js} +1 -1
  30. package/dist/{chunk-U4U5YVVX.js → chunk-A6GVXZZ3.js} +1 -1
  31. package/dist/{chunk-ULNKBH6B.js → chunk-BD3MHTSR.js} +2 -2
  32. package/dist/{chunk-TU7KYFS3.js → chunk-BLI5XATY.js} +1 -1
  33. package/dist/{chunk-N32ITJ7L.js → chunk-BSBIG74E.js} +15 -12
  34. package/dist/{chunk-ZU54D6MI.js → chunk-BZGWHPRW.js} +3 -3
  35. package/dist/{chunk-B25H4M4V.js → chunk-C4JINRJK.js} +1 -1
  36. package/dist/{chunk-5ON5GH3X.js → chunk-CS4IE5G7.js} +1 -1
  37. package/dist/{chunk-47TRZ6A3.js → chunk-E664L6K3.js} +3 -3
  38. package/dist/{chunk-J4RPT4QW.js → chunk-E6RPWJVC.js} +1 -1
  39. package/dist/{chunk-GLSGKTFO.js → chunk-EA4LCCJI.js} +5 -5
  40. package/dist/{chunk-E67OVYX3.js → chunk-GODQ5XA4.js} +16 -8
  41. package/dist/{chunk-LAQEZHOH.js → chunk-H3WFEPV2.js} +1 -1
  42. package/dist/{chunk-U4TDAJZE.js → chunk-J2S4MY2M.js} +2 -2
  43. package/dist/{chunk-CQRF7VU3.js → chunk-JRULOVZK.js} +1 -1
  44. package/dist/{chunk-C4TZBEHY.js → chunk-KIIKVKHB.js} +2 -2
  45. package/dist/{chunk-M224DAMG.js → chunk-KPSRL2NB.js} +1 -1
  46. package/dist/{chunk-JTTAS7N6.js → chunk-KQ3VNA6R.js} +1 -1
  47. package/dist/{chunk-MPSW7EA2.js → chunk-KS5HFREQ.js} +4 -4
  48. package/dist/{chunk-L37M3PV5.js → chunk-LYBFDHXD.js} +3 -3
  49. package/dist/{chunk-AWUZ3AUD.js → chunk-M4RYK5OF.js} +1 -1
  50. package/dist/chunk-MRF4AMKD.js +104 -0
  51. package/dist/{chunk-JWPSBANO.js → chunk-NOOBRCMC.js} +3 -3
  52. package/dist/{chunk-TIZQC44K.js → chunk-OWN3ZIIK.js} +1 -1
  53. package/dist/{chunk-WTMGUNZZ.js → chunk-OXZO4WQI.js} +9 -8
  54. package/dist/{chunk-PZXUDWPP.js → chunk-P3AQVFY2.js} +3 -3
  55. package/dist/{chunk-OF3RKOPU.js → chunk-P74PW7KR.js} +189 -111
  56. package/dist/{chunk-TQP42SFX.js → chunk-POEGJGEA.js} +1 -1
  57. package/dist/{chunk-X4FEFEP4.js → chunk-PRETPA7Z.js} +1 -1
  58. package/dist/{chunk-QJUKISYK.js → chunk-Q7U7QRC7.js} +2 -2
  59. package/dist/chunk-S6TH5G6Z.js +3541 -0
  60. package/dist/{chunk-MGFVNTIB.js → chunk-TSZU5JMC.js} +2 -2
  61. package/dist/{chunk-MR2LOG32.js → chunk-TXVN43SX.js} +8 -8
  62. package/dist/{chunk-T3HJWJGC.js → chunk-UTXMQVB2.js} +9 -9
  63. package/dist/{chunk-I5WWEBDG.js → chunk-VHRHI3CU.js} +1 -1
  64. package/dist/{chunk-E4AYSXMS.js → chunk-VW6CVKVA.js} +2 -2
  65. package/dist/{chunk-BAVM2XBR.js → chunk-YAFO7V4A.js} +209 -33
  66. package/dist/{chunk-32P7FTFC.js → chunk-YQ5MFXWG.js} +8 -7
  67. package/dist/{clean-CXX7YDBQ.js → clean-263PH5CR.js} +15 -15
  68. package/dist/cli.js +50 -50
  69. package/dist/{cloud-KRQQC5AH.js → cloud-STLYEQNN.js} +4 -4
  70. package/dist/{cloudrun-LVZ4OPPC.js → cloudrun-7ZVNB6FY.js} +3 -3
  71. package/dist/commands/layout-audit.browser.js +178 -202
  72. package/dist/commands/motion-sample.browser.js +24 -71
  73. package/dist/commands/motion-signature.browser.js +374 -0
  74. package/dist/{compare-7MMDDERQ.js → compare-33JLJ52D.js} +26 -26
  75. package/dist/{compiler-C32VXLE2.js → compiler-H3QAMMC2.js} +3 -3
  76. package/dist/{component-U57T4J2P.js → component-O5JLM26B.js} +3 -3
  77. package/dist/{compositions-HG7JA7I4.js → compositions-CN4ZVT5G.js} +11 -11
  78. package/dist/{contactSheet-54AJDSR5.js → contactSheet-27SRU7A4.js} +2 -2
  79. package/dist/{delete-HXXHYTH2.js → delete-Z23A45R3.js} +2 -2
  80. package/dist/{deploy-4T3RMA5G.js → deploy-PJLSZMUH.js} +1 -1
  81. package/dist/{destroy-EYDBVHGF.js → destroy-IPUDK6YN.js} +1 -1
  82. package/dist/{dist-YUIPB7OX.js → dist-7VEVT4NT.js} +2 -2
  83. package/dist/{dist-FMHQMEMX.js → dist-ICXYT7XK.js} +1 -1
  84. package/dist/docker/Dockerfile.render +1 -1
  85. package/dist/{doctor-GKF42LFK.js → doctor-6QLXSGPK.js} +10 -10
  86. package/dist/{events-5E4LWTM3.js → events-EAAIWITP.js} +8 -8
  87. package/dist/{events-LGPPK5FN.js → events-UA4DJUO2.js} +9 -9
  88. package/dist/{feedback-53ZU2MPJ.js → feedback-2CIRCBHY.js} +10 -10
  89. package/dist/{figma-S4LBKUIF.js → figma-DFCCII66.js} +3 -3
  90. package/dist/fontLocalizeCli.js +8 -8
  91. package/dist/{get-ELQOB66I.js → get-UQ2AAXWM.js} +2 -2
  92. package/dist/{gpuPolicy-CA6KRFQQ.js → gpuPolicy-CPCLBMS5.js} +6 -6
  93. package/dist/{grade-compare-6BDBN6IQ.js → grade-compare-THUUFHO3.js} +24 -24
  94. package/dist/{help-JNBSADTC.js → help-SR2MRL3U.js} +1 -1
  95. package/dist/{history-TY3SEJWV.js → history-WLI7KFXB.js} +15 -15
  96. package/dist/hyperframe-runtime.js +49 -49
  97. package/dist/hyperframe.manifest.json +1 -1
  98. package/dist/hyperframe.runtime.iife.js +49 -49
  99. package/dist/hyperframes-player.global.js +1 -1
  100. package/dist/{info-QG6XUPA4.js → info-DFJM3YRJ.js} +11 -11
  101. package/dist/{init-RZF2YCRD.js → init-HEAMOTGH.js} +22 -22
  102. package/dist/{inspect-HYINM6BQ.js → inspect-TO2EXJNK.js} +25 -25
  103. package/dist/{installer-NBEN3ZIP.js → installer-REA7ZASD.js} +4 -4
  104. package/dist/{keyframes-VCVFJTYP.js → keyframes-XHEBAJY7.js} +12 -12
  105. package/dist/{lambda-BFHJMMCG.js → lambda-MSWYKDNT.js} +6 -6
  106. package/dist/{layout-GGRQADMQ.js → layout-UQXCTFFV.js} +25 -25
  107. package/dist/{lint-ZBMSFLOK.js → lint-BSMZ526C.js} +12 -12
  108. package/dist/{lintProject-X7L7EZWZ.js → lintProject-VNE322A7.js} +1 -1
  109. package/dist/{list-ZKWCM7JT.js → list-RNP5EMTX.js} +2 -2
  110. package/dist/{login-CZ4DAMX2.js → login-S6V75HG5.js} +4 -4
  111. package/dist/{media-treatment-65KBTTDZ.js → media-treatment-IHEEEDUQ.js} +15 -14
  112. package/dist/{models-RILNQV3Z.js → models-OQEBKNJI.js} +7 -7
  113. package/dist/{motionShot-5F4DCMWC.js → motionShot-EAIFVJ2I.js} +10 -10
  114. package/dist/{normalize-audio-SEAAEJRQ.js → normalize-audio-4ACUR6W6.js} +11 -11
  115. package/dist/{pipeline-5UY45ELH.js → pipeline-SOQHD5YN.js} +6 -6
  116. package/dist/{play-BIKUK4NL.js → play-3WJPS3FE.js} +20 -20
  117. package/dist/{preflight-3V5IHGWQ.js → preflight-ZUADCOLZ.js} +7 -7
  118. package/dist/{present-UAM37S3Z.js → present-MU23WZZA.js} +16 -16
  119. package/dist/{preview-TVU4J6VE.js → preview-VOTNRX67.js} +17 -17
  120. package/dist/{producer-7JGAPEAF.js → producer-HKRMTCPU.js} +1 -1
  121. package/dist/{projectConfig-JHEWPAA5.js → projectConfig-H37MQGE6.js} +6 -6
  122. package/dist/{publication-7XA2H7UB.js → publication-QVDKMAKD.js} +2 -2
  123. package/dist/{publish-257VZMWI.js → publish-54IPKU5O.js} +8 -8
  124. package/dist/{remove-background-EV6XVADN.js → remove-background-KQQ2WPKP.js} +7 -7
  125. package/dist/{render-QZD733OT.js → render-HJQ44SEI.js} +12 -12
  126. package/dist/{render-B66XOY6B.js → render-P7727PLY.js} +21 -21
  127. package/dist/{render-4C3YKVZI.js → render-S2T3SLI4.js} +3 -3
  128. package/dist/{render-batch-AFDBPDMM.js → render-batch-DUFAHD6F.js} +3 -3
  129. package/dist/{renderCancellation-VIZELWDD.js → renderCancellation-BSVXXGZM.js} +6 -6
  130. package/dist/renderSetupWorker.js +1 -1
  131. package/dist/{resolver-S72XBTEQ.js → resolver-PHWKDEH2.js} +4 -4
  132. package/dist/{screenshotCapture-FA5HPN7Q.js → screenshotCapture-ECBTLCU6.js} +3 -3
  133. package/dist/{sherpa-BAADWCHB.js → sherpa-GHQOWXFV.js} +7 -7
  134. package/dist/skills/hyperframes/references/frame-worker-core.md +2 -2
  135. package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +2 -2
  136. package/dist/skills/media-use/audio/references/bgm.md +1 -1
  137. package/dist/skills/media-use/audio/references/tts.md +1 -1
  138. package/dist/skills/media-use/audio/scripts/lib/python.mjs +19 -5
  139. package/dist/skills/media-use/audio/scripts/lib/python.test.mjs +69 -1
  140. package/dist/{skills-AB55WOXL.js → skills-SOCMD66Y.js} +40 -14
  141. package/dist/{skillsUpdateCheck-VRABW6UL.js → skillsUpdateCheck-PONPICQM.js} +3 -3
  142. package/dist/{snapshot-STEHSXMQ.js → snapshot-ECXEZ4TY.js} +50 -29
  143. package/dist/{src-GD7RGV5U.js → src-LVBNYMJW.js} +5 -5
  144. package/dist/{src-GRC63B6L.js → src-RQE5HXZK.js} +7 -7
  145. package/dist/{staticProjectServer-SFINO3DE.js → staticProjectServer-TQYP44CW.js} +14 -14
  146. package/dist/{status-LXQL3L3H.js → status-HVI7QZHE.js} +6 -6
  147. package/dist/studio/assets/{hyperframes-player-c6WR3RsF.js → hyperframes-player-CBpg41JM.js} +1 -1
  148. package/dist/studio/assets/{index-BJpQzV6h.js → index-BFitquwi.js} +1 -1
  149. package/dist/studio/assets/{index-Co6W8IVk.js → index-BKy_birQ.js} +194 -194
  150. package/dist/studio/assets/{index-C0KfbPAo.js → index-CZfrSyU9.js} +1 -1
  151. package/dist/studio/assets/{index-C7apTvpr.css → index-DbfKVTId.css} +1 -1
  152. package/dist/studio/{chunk-PQFEBX32.js → chunk-BIUXP3PG.js} +2 -2
  153. package/dist/studio/{chunk-6LUNLTHR.js → chunk-K47E2ZJA.js} +13 -8
  154. package/dist/studio/chunk-K47E2ZJA.js.map +1 -0
  155. package/dist/studio/{chunk-QUXZVHOJ.js → chunk-VWT7STY3.js} +2 -2
  156. package/dist/studio/{domEditingLayers-JQPQGGT7.js → domEditingLayers-V67MS4WP.js} +3 -3
  157. package/dist/studio/index.d.ts +81 -46
  158. package/dist/studio/index.html +2 -2
  159. package/dist/studio/index.js +7295 -6844
  160. package/dist/studio/index.js.map +1 -1
  161. package/dist/studio/player.js +2 -2
  162. package/dist/studio/styles.css +1 -1
  163. package/dist/{studio-api-WRSCXPWS.js → studio-api-EKF6TFDB.js} +8 -8
  164. package/dist/{studioServer-SMBPWSNR.js → studioServer-BSNDGK63.js} +38 -38
  165. package/dist/{system-EEWYEHYX.js → system-NLNIE7PO.js} +6 -6
  166. package/dist/{telemetry-VMNHQBUG.js → telemetry-XNDAM6JU.js} +9 -9
  167. package/dist/{timeline-JWJDKHRD.js → timeline-IKWTTCNY.js} +15 -15
  168. package/dist/{tokens-DETZVKSO.js → tokens-KOTFKBAK.js} +2 -2
  169. package/dist/{transcribe-GCKJF5A6.js → transcribe-ELJHKA5B.js} +7 -7
  170. package/dist/{transcribe-E5VBY6CU.js → transcribe-STEYOXIO.js} +12 -12
  171. package/dist/{updateCheck-PAC2DBB6.js → updateCheck-OJMEQUST.js} +2 -2
  172. package/dist/{upgrade-OYMNUBW2.js → upgrade-NIS32YR6.js} +2 -2
  173. package/dist/{urlDownloader-NYXPEBUN.js → urlDownloader-KJSQAFN7.js} +5 -5
  174. package/dist/{validate-KBPMDKZO.js → validate-7MCKNH5K.js} +15 -15
  175. package/dist/{video-KWQ5TSVD.js → video-TUXP3VGQ.js} +17 -9
  176. package/package.json +1 -1
  177. package/dist/chunk-5GQAJ43Q.js +0 -31
  178. package/dist/chunk-YLVI7VL5.js +0 -3541
  179. package/dist/studio/chunk-6LUNLTHR.js.map +0 -1
  180. /package/dist/studio/{chunk-PQFEBX32.js.map → chunk-BIUXP3PG.js.map} +0 -0
  181. /package/dist/studio/{chunk-QUXZVHOJ.js.map → chunk-VWT7STY3.js.map} +0 -0
  182. /package/dist/studio/{domEditingLayers-JQPQGGT7.js.map → domEditingLayers-V67MS4WP.js.map} +0 -0
@@ -8,7 +8,7 @@ import {
8
8
  firstFrameColourArgs,
9
9
  hdrToSdrToneMapFilter,
10
10
  parseFirstFrameColour
11
- } from "./chunk-B25H4M4V.js";
11
+ } from "./chunk-C4JINRJK.js";
12
12
  import {
13
13
  mkdirWithinProject,
14
14
  realProjectRoot,
@@ -21,7 +21,7 @@ import {
21
21
  isUnresolvedAssetPlaceholder,
22
22
  maskNonScannableRanges,
23
23
  resolveLocalAssetCandidates
24
- } from "./chunk-BAVM2XBR.js";
24
+ } from "./chunk-YAFO7V4A.js";
25
25
  import {
26
26
  findFfBinary
27
27
  } from "./chunk-PJ3HDUCY.js";
@@ -18,7 +18,7 @@ import {
18
18
  splitElementInHtml,
19
19
  unwrapElementsFromHtml,
20
20
  wrapElementsInHtml
21
- } from "./chunk-ZU54D6MI.js";
21
+ } from "./chunk-BZGWHPRW.js";
22
22
  import {
23
23
  atomicTempPath,
24
24
  createFileAtomically,
@@ -31,7 +31,7 @@ import {
31
31
  measureAudio,
32
32
  requiredFfmpeg,
33
33
  resolveLocalAudioPath
34
- } from "./chunk-5ON5GH3X.js";
34
+ } from "./chunk-CS4IE5G7.js";
35
35
  import {
36
36
  PROXY_PARAMS_VERSION,
37
37
  PROXY_PENDING_RETRY_AFTER_SECONDS,
@@ -57,7 +57,7 @@ import {
57
57
  shouldPrewarmProxy,
58
58
  waitForProxy,
59
59
  walkDir
60
- } from "./chunk-MGFVNTIB.js";
60
+ } from "./chunk-TSZU5JMC.js";
61
61
  import {
62
62
  findTimelineScript,
63
63
  parseGsapScriptAcorn
@@ -76,7 +76,7 @@ import {
76
76
  formatRenderOutputTimestamp,
77
77
  parseFps,
78
78
  sameInstant
79
- } from "./chunk-B25H4M4V.js";
79
+ } from "./chunk-C4JINRJK.js";
80
80
  import {
81
81
  MagicString,
82
82
  VALID_CANVAS_RESOLUTIONS,
@@ -85,7 +85,7 @@ import {
85
85
  import {
86
86
  addScenePartsManifest,
87
87
  ensureHfIds
88
- } from "./chunk-U4TDAJZE.js";
88
+ } from "./chunk-J2S4MY2M.js";
89
89
  import {
90
90
  findStartTags,
91
91
  injectScriptsIntoHtml,
@@ -95,7 +95,7 @@ import {
95
95
  resolveRateSpec,
96
96
  sourceTimeAt,
97
97
  stripEmbeddedRuntimeScripts
98
- } from "./chunk-YLVI7VL5.js";
98
+ } from "./chunk-S6TH5G6Z.js";
99
99
  import {
100
100
  ProjectRootMissingError,
101
101
  folderGone,
@@ -108,7 +108,7 @@ import {
108
108
  import {
109
109
  isWithinProjectRoot,
110
110
  readProjectFile
111
- } from "./chunk-BAVM2XBR.js";
111
+ } from "./chunk-YAFO7V4A.js";
112
112
  import {
113
113
  FFPROBE_PATH_ENV,
114
114
  findFfBinary
@@ -6388,7 +6388,7 @@ async function prepareGsapMutationScript(c, res, firstMutation) {
6388
6388
  let block = extractGsapScriptBlock(html);
6389
6389
  if (!block && (firstMutation.type === "add" || firstMutation.type === "add-with-keyframes")) {
6390
6390
  const compId = html.match(/data-composition-id="([^"]+)"/)?.[1] ?? "main";
6391
- const { GSAP_CDN } = await import("./dist-YUIPB7OX.js");
6391
+ const { GSAP_CDN } = await import("./dist-7VEVT4NT.js");
6392
6392
  const bootstrap = [
6393
6393
  `<script src="${GSAP_CDN}"></script>`,
6394
6394
  "<script>",
@@ -8,13 +8,13 @@ import {
8
8
  installPageFunctionGuard,
9
9
  resolveCliChromeGpuMode,
10
10
  seekCompositionTimeline
11
- } from "./chunk-32P7FTFC.js";
11
+ } from "./chunk-YQ5MFXWG.js";
12
12
  import {
13
13
  resolveCompositionViewportFromHtml
14
14
  } from "./chunk-5Z63TBTX.js";
15
15
  import {
16
16
  resolveProject
17
- } from "./chunk-U4U5YVVX.js";
17
+ } from "./chunk-A6GVXZZ3.js";
18
18
  import {
19
19
  c
20
20
  } from "./chunk-ZTZA4UWZ.js";
@@ -28,7 +28,7 @@ import {
28
28
  import {
29
29
  printDeprecationNotice,
30
30
  withMeta
31
- } from "./chunk-TU7KYFS3.js";
31
+ } from "./chunk-BLI5XATY.js";
32
32
  import {
33
33
  normalizeErrorMessage
34
34
  } from "./chunk-KNU5COPB.js";
@@ -217,7 +217,7 @@ function extractCompositionErrorsFromLint(lintResult) {
217
217
  async function localizeRemoteAssets(html) {
218
218
  let dir;
219
219
  try {
220
- const { loadProducer } = await import("./producer-7JGAPEAF.js");
220
+ const { loadProducer } = await import("./producer-HKRMTCPU.js");
221
221
  const { localizeRemoteMediaSources, localizeRemoteImageSources, localizeRemoteFontFaces } = await loadProducer();
222
222
  dir = mkdtempSync(join(tmpdir(), "hf-validate-assets-"));
223
223
  const assetDir = dir;
@@ -238,10 +238,10 @@ async function localizeRemoteAssets(html) {
238
238
  }
239
239
  async function validateInBrowser(project, opts) {
240
240
  const projectDir = project.dir;
241
- const { bundleToSingleHtml } = await import("./compiler-C32VXLE2.js");
241
+ const { bundleToSingleHtml } = await import("./compiler-H3QAMMC2.js");
242
242
  const { ensureBrowser } = await import("./manager-NEVLEZK3.js");
243
- const { serveStaticProjectHtml } = await import("./staticProjectServer-SFINO3DE.js");
244
- const { lintProject } = await import("./lintProject-X7L7EZWZ.js");
243
+ const { serveStaticProjectHtml } = await import("./staticProjectServer-TQYP44CW.js");
244
+ const { lintProject } = await import("./lintProject-VNE322A7.js");
245
245
  const lintResult = await lintProject(projectDir);
246
246
  const compositionErrors = extractCompositionErrorsFromLint(lintResult);
247
247
  const html = await bundleToSingleHtml(projectDir);
@@ -262,13 +262,13 @@ async function validateInBrowser(project, opts) {
262
262
  try {
263
263
  const browser = await ensureBrowser();
264
264
  const puppeteer = await import("puppeteer-core");
265
- const { buildChromeArgs, analyzeClipMediaFit } = await import("./src-GD7RGV5U.js");
265
+ const { buildChromeArgs, analyzeClipMediaFit } = await import("./src-LVBNYMJW.js");
266
266
  const requestedGpuMode = resolveCliChromeGpuMode();
267
267
  const {
268
268
  assertWebGpuAdapterAvailable,
269
269
  compositionRequiresWebGpu,
270
270
  resolveCaptureBrowserGpuMode
271
- } = await import("./gpuPolicy-CA6KRFQQ.js");
271
+ } = await import("./gpuPolicy-CPCLBMS5.js");
272
272
  const resolvedGpuMode = await resolveCaptureBrowserGpuMode(
273
273
  requestedGpuMode,
274
274
  browser.executablePath
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-TVCRUG2S.js";
18
18
  import {
19
19
  stoppedByCancelSignal
20
- } from "./chunk-JTTAS7N6.js";
20
+ } from "./chunk-KQ3VNA6R.js";
21
21
 
22
22
  // src/whisper/transcribe.ts
23
23
  import { execFileSync } from "child_process";
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-TVCRUG2S.js";
14
14
  import {
15
15
  getFreeDiskMb
16
- } from "./chunk-CQRF7VU3.js";
16
+ } from "./chunk-JRULOVZK.js";
17
17
  import {
18
18
  ensureBrowser,
19
19
  findBrowser
@@ -113,7 +113,7 @@ async function checkFFmpeg(signal) {
113
113
  level: "error",
114
114
  title: "FFmpeg cannot start",
115
115
  detail: version.detail,
116
- hint: "Install a working 64-bit FFmpeg build with all required runtime DLLs.",
116
+ hint: process.platform === "win32" ? "Install a working 64-bit FFmpeg build with all required runtime DLLs." : getFFmpegInstallHint(),
117
117
  path
118
118
  };
119
119
  }
@@ -3903,7 +3903,7 @@ var TIMELINE_REGISTRY_OBJECT_LITERAL_PATTERN = /window\.__timelines\s*=\s*\{\s*(
3903
3903
  var TIMELINE_REGISTRY_ASSIGN_PATTERN = /window\.__timelines(?:\[[^\]]+\]|\.[A-Za-z_$][\w$]*)\s*=/i;
3904
3904
  var WINDOW_TIMELINE_ASSIGN_PATTERN = /window\.__timelines(?:\[\s*(?:["']([^"']+)["']|[A-Za-z_$][\w$.]*)\s*\]|\.\s*([A-Za-z_$][\w$]*))\s*=\s*([A-Za-z_$][\w$]*)/i;
3905
3905
  var INVALID_SCRIPT_CLOSE_PATTERN = /<script[^>]*>[\s\S]*?<\s*\/\s*script(?!>)/i;
3906
- var TIMELINE_REGISTRY_KEY_PATTERN = /window\.__timelines(?:\[\s*["']([^"']+)["']\s*\]|\.\s*([A-Za-z_$][\w$]*))\s*=/g;
3906
+ var TIMELINE_REGISTRY_KEY_PATTERN = /window\.__timelines(?:\[\s*["']([^"']+)["']\s*\]|\.\s*([A-Za-z_$][\w$]*))\s*(?:\?\?|\|\||&&)?=/g;
3907
3907
  var TIMELINE_REGISTRY_OBJECT_OPEN_PATTERN = /window\.__timelines\s*=\s*\{/i;
3908
3908
  var TIMELINE_REGISTRY_OBJECT_ENTRY_PATTERN = /(?:["']([^"']+)["']|([A-Za-z_$][\w$]*))\s*:\s*[A-Za-z_$][\w$]*/g;
3909
3909
  function parseHtmlStructure(source) {
@@ -4007,9 +4007,7 @@ function readAttr(tagSource, attr) {
4007
4007
  return match?.[1] || null;
4008
4008
  }
4009
4009
  function hasAttrName(tagSource, attr) {
4010
- const escaped = attr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4011
- const attrs = tagSource.replace(/^<\s*[a-z][\w:-]*/i, "");
4012
- return new RegExp(`(?:^|\\s)${escaped}(?:\\s*=|\\s|/?>)`, "i").test(attrs);
4010
+ return readDecodedAttr(tagSource, attr) !== null;
4013
4011
  }
4014
4012
  function isAudibleVideoTag(tagSource) {
4015
4013
  if (hasAttrName(tagSource, "muted")) return false;
@@ -4677,6 +4675,34 @@ function repeatedDescendantId(selector) {
4677
4675
  }
4678
4676
  return repeated;
4679
4677
  }
4678
+ function addUnescapedDigitIds(selector, ids) {
4679
+ try {
4680
+ (0, import_postcss_selector_parser.default)((root) => {
4681
+ root.walkIds((node) => {
4682
+ if (/^#\d/.test(node.toString().trim())) ids.add(node.value);
4683
+ });
4684
+ }).processSync(selector);
4685
+ } catch {
4686
+ }
4687
+ }
4688
+ var SELECTOR_CALL_PATTERN = /\.(?:querySelector(?:All)?|closest|matches|to|from|fromTo|set)\s*\(\s*(["'`])((?:\\.|(?!\1)[^\\])*)\1/g;
4689
+ function digitIdsTargetedBySelectors(styles, scripts) {
4690
+ const ids = /* @__PURE__ */ new Set();
4691
+ for (const style of styles) {
4692
+ try {
4693
+ postcss.parse(style.content).walkRules((rule) => {
4694
+ for (const selector of rule.selectors) addUnescapedDigitIds(selector, ids);
4695
+ });
4696
+ } catch {
4697
+ }
4698
+ }
4699
+ for (const script of scripts) {
4700
+ for (const match of stripJsComments(script.content).matchAll(SELECTOR_CALL_PATTERN)) {
4701
+ addUnescapedDigitIds(match[2] ?? "", ids);
4702
+ }
4703
+ }
4704
+ return ids;
4705
+ }
4680
4706
  function resolvedRuleSelectors(rule) {
4681
4707
  let ancestor = rule.parent;
4682
4708
  while (ancestor && ancestor.type !== "rule") ancestor = ancestor.parent;
@@ -4695,16 +4721,20 @@ function resolvedRuleSelectors(rule) {
4695
4721
  })
4696
4722
  );
4697
4723
  }
4724
+ function rightmostCompoundNodes(selectorNode) {
4725
+ const subject = [];
4726
+ selectorNode.each((node) => {
4727
+ if (node.type === "combinator") subject.length = 0;
4728
+ else subject.push(node);
4729
+ });
4730
+ return subject;
4731
+ }
4698
4732
  function selectorAliasesRuntimeHiddenStyle(selector) {
4699
4733
  let unsafe = false;
4700
4734
  try {
4701
4735
  (0, import_postcss_selector_parser.default)((root) => {
4702
4736
  root.each((selectorNode) => {
4703
- const subject = [];
4704
- selectorNode.each((node) => {
4705
- if (node.type === "combinator") subject.length = 0;
4706
- else subject.push(node);
4707
- });
4737
+ const subject = rightmostCompoundNodes(selectorNode);
4708
4738
  const hostScoped = subject.some(
4709
4739
  (node) => node.type === "attribute" && ["data-composition-src", "data-composition-file"].includes(
4710
4740
  node.attribute.toLowerCase()
@@ -4727,6 +4757,57 @@ function selectorAliasesRuntimeHiddenStyle(selector) {
4727
4757
  }
4728
4758
  return unsafe;
4729
4759
  }
4760
+ var POSITION_PROPERTIES = /* @__PURE__ */ new Set(["left", "top", "right", "bottom", "inset"]);
4761
+ function weakIdOf(node) {
4762
+ if (node.type === "attribute" && node.attribute.toLowerCase() === "id") {
4763
+ return node.operator === "=" && node.value ? node.value : null;
4764
+ }
4765
+ if (node.type !== "pseudo" || node.value.toLowerCase() !== ":where") return null;
4766
+ const inner = node.nodes.flatMap((option) => option.nodes).find((n) => n.type === "id");
4767
+ return inner ? inner.value : null;
4768
+ }
4769
+ function reducedSpecificityId(selector) {
4770
+ let matched = null;
4771
+ try {
4772
+ (0, import_postcss_selector_parser.default)((root) => {
4773
+ root.each((selectorNode) => {
4774
+ const subject = rightmostCompoundNodes(selectorNode);
4775
+ if (subject.some((node) => node.type === "id")) return;
4776
+ for (const node of subject) matched = weakIdOf(node) ?? matched;
4777
+ });
4778
+ }).processSync(selector);
4779
+ } catch {
4780
+ return null;
4781
+ }
4782
+ return matched;
4783
+ }
4784
+ function cssIdSelector(id) {
4785
+ return `#${id.replace(
4786
+ /[^a-zA-Z0-9_-]|^-?\d/g,
4787
+ (match) => Array.from(match, (char) => `\\${char.codePointAt(0)?.toString(16)} `).join("")
4788
+ )}`;
4789
+ }
4790
+ function reducedSpecificityIdFindings(rule, reported) {
4791
+ const positionProps = rule.nodes.flatMap(
4792
+ (node) => node.type === "decl" && !node.important && POSITION_PROPERTIES.has(node.prop.toLowerCase()) ? [node.prop] : []
4793
+ );
4794
+ if (positionProps.length === 0) return [];
4795
+ const findings = [];
4796
+ for (const selector of resolvedRuleSelectors(rule)) {
4797
+ const id = reported.has(selector) ? null : reducedSpecificityId(selector);
4798
+ if (id === null) continue;
4799
+ reported.add(selector);
4800
+ findings.push({
4801
+ code: "id_override_reduced_specificity",
4802
+ severity: "warning",
4803
+ message: `Selector "${selector}" sets ${positionProps.join("/")} through [id=...] or :where(#id), which has class-level or zero specificity, so a compound class rule (e.g. ".parent .row") on the same element can silently win over this override.`,
4804
+ selector,
4805
+ fixHint: `Use \`${cssIdSelector(id)}\` instead; id specificity beats any selector built only from classes.`,
4806
+ snippet: truncateSnippet(rule.toString())
4807
+ });
4808
+ }
4809
+ return findings;
4810
+ }
4730
4811
  function ruleForcesOpacityZero(rule) {
4731
4812
  let forcesOpacityZero = false;
4732
4813
  rule.walkDecls(/^opacity$/i, (declaration) => {
@@ -4734,6 +4815,34 @@ function ruleForcesOpacityZero(rule) {
4734
4815
  });
4735
4816
  return forcesOpacityZero;
4736
4817
  }
4818
+ var CSS_TRANSITION_PROPERTY_PATTERN = /^(?:-webkit-)?transition(?:-[a-z][a-z-]*)?$/i;
4819
+ var TRANSITION_NONE_PROPERTIES = /* @__PURE__ */ new Set(["transition", "transition-property"]);
4820
+ var TRANSITION_TIME_PROPERTIES = /* @__PURE__ */ new Set([
4821
+ "transition",
4822
+ "transition-duration",
4823
+ "transition-delay"
4824
+ ]);
4825
+ function hasNonZeroTime(value) {
4826
+ const times = value.match(/[+-]?(?:\d*\.)?\d+m?s\b/g) ?? [];
4827
+ return value.includes("var(") || times.some((time) => Number.parseFloat(time) !== 0);
4828
+ }
4829
+ function isSeekUnsafeTransition(declaration) {
4830
+ const property = declaration.prop.trim().toLowerCase();
4831
+ if (!CSS_TRANSITION_PROPERTY_PATTERN.test(property)) return false;
4832
+ const name = property.replace(/^-webkit-/, "");
4833
+ const value = declaration.value.trim().toLowerCase();
4834
+ if (value === "none" && TRANSITION_NONE_PROPERTIES.has(name)) return false;
4835
+ return !TRANSITION_TIME_PROPERTIES.has(name) || hasNonZeroTime(value);
4836
+ }
4837
+ function cssTransitionFinding(declaration, details) {
4838
+ return {
4839
+ code: "css_transition_used",
4840
+ severity: "warning",
4841
+ message: `CSS declaration \`${declaration.prop}: ${declaration.value}\` runs on the browser clock and cannot be seeked deterministically across render workers.`,
4842
+ fixHint: "Keep the class or attribute swap for state; put the visual change on the paused GSAP timeline.",
4843
+ ...details
4844
+ };
4845
+ }
4737
4846
  function isStudioTimelineElement(tag) {
4738
4847
  if (["script", "style", "link", "meta", "template", "noscript"].includes(tag.name)) {
4739
4848
  return false;
@@ -4852,15 +4961,18 @@ function describeRootDimensionsDrift(source, dataWidth, dataHeight) {
4852
4961
  }
4853
4962
  var coreRules = [
4854
4963
  // id_requires_css_escape
4855
- ({ tags }) => {
4964
+ ({ tags, styles, scripts }) => {
4856
4965
  const findings = [];
4966
+ let targeted;
4857
4967
  for (const tag of tags) {
4858
4968
  const id = readAttr(tag.raw, "id");
4859
4969
  if (!id || !/^\d/.test(id)) continue;
4970
+ targeted ??= digitIdsTargetedBySelectors(styles, scripts);
4971
+ const used = targeted.has(id);
4860
4972
  findings.push({
4861
4973
  code: "id_requires_css_escape",
4862
- severity: "warning",
4863
- message: `id="${id}" starts with a digit, so the common selector \`#${id}\` throws a SyntaxError in querySelector().`,
4974
+ severity: used ? "error" : "warning",
4975
+ message: used ? `id="${id}" starts with a digit, and the selector \`#${id}\` used in this composition is invalid: querySelector and GSAP throw a SyntaxError, and CSS drops the rule.` : `id="${id}" starts with a digit, so the common selector \`#${id}\` throws a SyntaxError in querySelector().`,
4864
4976
  elementId: id,
4865
4977
  fixHint: "Rename the id to start with a letter (recommended), or build selectors with `#${CSS.escape(id)}` at runtime.",
4866
4978
  snippet: truncateSnippet(tag.raw)
@@ -5004,11 +5116,55 @@ var coreRules = [
5004
5116
  }
5005
5117
  return findings;
5006
5118
  },
5119
+ // css_transition_used
5120
+ ({ styles, tags }) => {
5121
+ const findings = [];
5122
+ for (const style of styles) {
5123
+ if (!/transition/i.test(style.content)) continue;
5124
+ let root;
5125
+ try {
5126
+ root = postcss.parse(style.content);
5127
+ } catch {
5128
+ continue;
5129
+ }
5130
+ root.walkDecls((declaration) => {
5131
+ if (!isSeekUnsafeTransition(declaration)) return;
5132
+ const selector = declaration.parent?.type === "rule" ? declaration.parent.selector : void 0;
5133
+ findings.push(
5134
+ cssTransitionFinding(declaration, {
5135
+ selector,
5136
+ snippet: truncateSnippet(declaration.toString())
5137
+ })
5138
+ );
5139
+ });
5140
+ }
5141
+ for (const tag of tags) {
5142
+ const inlineStyle = readDecodedAttr(tag.raw, "style");
5143
+ if (!inlineStyle || !/transition/i.test(inlineStyle)) continue;
5144
+ let root;
5145
+ try {
5146
+ root = postcss.parse(inlineStyle);
5147
+ } catch {
5148
+ continue;
5149
+ }
5150
+ root.walkDecls((declaration) => {
5151
+ if (!isSeekUnsafeTransition(declaration)) return;
5152
+ findings.push(
5153
+ cssTransitionFinding(declaration, {
5154
+ elementId: readDecodedAttr(tag.raw, "id") || void 0,
5155
+ snippet: truncateSnippet(tag.raw)
5156
+ })
5157
+ );
5158
+ });
5159
+ }
5160
+ return findings;
5161
+ },
5007
5162
  // CSS selector safety
5008
5163
  ({ styles, locate }) => {
5009
5164
  const findings = [];
5010
5165
  const reportedRepeatedIds = /* @__PURE__ */ new Set();
5011
5166
  const reportedHiddenStyleSelectors = /* @__PURE__ */ new Set();
5167
+ const reportedReducedIdSelectors = /* @__PURE__ */ new Set();
5012
5168
  for (const style of styles) {
5013
5169
  let root;
5014
5170
  try {
@@ -5027,6 +5183,7 @@ var coreRules = [
5027
5183
  }
5028
5184
  root.walkRules((rule) => {
5029
5185
  const forcesOpacityZero = ruleForcesOpacityZero(rule);
5186
+ findings.push(...reducedSpecificityIdFindings(rule, reportedReducedIdSelectors));
5030
5187
  for (const selector of resolvedRuleSelectors(rule)) {
5031
5188
  const repeatedId = repeatedDescendantId(selector);
5032
5189
  if (repeatedId && !reportedRepeatedIds.has(repeatedId)) {
@@ -6242,6 +6399,7 @@ var HEAVY_OVERLAY_EXEMPT_TAGS = /* @__PURE__ */ new Set([
6242
6399
  ]);
6243
6400
  var HEAVY_OVERLAY_CSS_PATTERN = /(?:filter\s*:[^;}]*\bblur\s*\()|(?:clip-path\s*:(?!\s*(?:none|inherit|initial|unset)\b)\s*[^;}]+)|(?:radial-gradient\s*\()/i;
6244
6401
  var INLINE_STYLE_DISPLAY_NONE_PATTERN = /(?:^|;)\s*display\s*:\s*none\b/i;
6402
+ var COMPUTED_TIMELINE_REGISTRATION_PATTERN = /window\.__timelines\s*\[(?!\s*["'])(?:[^\r\n[\]]|\[[^\r\n\]]*\])+\]\s*(?:\?\?|\|\||&&)?=/;
6245
6403
  function readTagTiming(rawTag) {
6246
6404
  return readClipTiming({ getAttribute: (name) => readAttr(rawTag, name) });
6247
6405
  }
@@ -6550,6 +6708,26 @@ function negativeZIndexFinding(match, selector) {
6550
6708
  snippet: truncateSnippet(match[0])
6551
6709
  };
6552
6710
  }
6711
+ function hasComputedTimelineRegistration(scripts) {
6712
+ return scripts.some(
6713
+ (script) => COMPUTED_TIMELINE_REGISTRATION_PATTERN.test(stripJsCode(script.content))
6714
+ );
6715
+ }
6716
+ function mountsSource(tag) {
6717
+ return Boolean(
6718
+ readAttr(tag.raw, "data-composition-src") || readAttr(tag.raw, "data-composition-file")
6719
+ );
6720
+ }
6721
+ function missingTimelineFinding(tag, compositionId, isRoot) {
6722
+ return {
6723
+ code: "missing_data_no_timeline",
6724
+ severity: "warning",
6725
+ message: isRoot ? "This composition has no `window.__timelines` registration but is missing `data-no-timeline`. The producer polls for timeline registration for up to 45 seconds before timing out, adding 45 s to every render." : `Composition host "${compositionId}" has neither a matching \`window.__timelines\` registration nor \`data-no-timeline\`. The producer waits up to 45 seconds for every \`data-composition-id\` before rendering.`,
6726
+ elementId: readAttr(tag.raw, "id") || void 0,
6727
+ fixHint: isRoot ? 'Add `data-no-timeline` to the root element to skip the poll: `<div data-composition-id="..." data-no-timeline ...>`.' : "If this is a static section, use a plain `id` instead of `data-composition-id`, or add `data-no-timeline`. Otherwise, register its timeline or mount it with `data-composition-src`.",
6728
+ snippet: truncateSnippet(tag.raw)
6729
+ };
6730
+ }
6553
6731
  var compositionRules = [
6554
6732
  // duplicate_composition_id catches meta-tag/root collisions that create duplicate composition entries.
6555
6733
  ({ tags }) => {
@@ -6818,27 +6996,25 @@ var compositionRules = [
6818
6996
  return findings;
6819
6997
  },
6820
6998
  // missing_data_no_timeline
6821
- // The producer polls window.__timelines[id] with a 45-second timeout waiting
6822
- // for GSAP timeline registration. Compositions that never call
6823
- // window.__timelines[id] = tl stall for 45 s every render. Adding
6824
- // data-no-timeline to the root element tells the producer to skip the poll.
6825
- ({ rootTag, rootCompositionId, scripts, rawSource, options }) => {
6826
- if (options.isSubComposition) return [];
6999
+ // The producer polls window.__timelines[id] for every composition id in the
7000
+ // rendered document. A timeline-free root or bare nested composition host
7001
+ // therefore spends the full 45-second readiness budget unless it explicitly
7002
+ // opts out with data-no-timeline.
7003
+ ({ rootTag, rootCompositionId, tags, scripts, rawSource, options }) => {
6827
7004
  if (!rootCompositionId || !rootTag) return [];
6828
- const tagNoValues = rootTag.raw.replace(/"[^"]*"|'[^']*'/g, '""');
6829
- if (/(?:^|\s)data-no-timeline(?=[\s>=/]|$)/i.test(tagNoValues)) return [];
6830
7005
  if (/<script\b[^>]*\bsrc\s*=/i.test(rawSource)) return [];
6831
- const registersTimeline = scripts.some((s) => s.content.includes("window.__timelines["));
6832
- if (registersTimeline) return [];
6833
- return [
6834
- {
6835
- code: "missing_data_no_timeline",
6836
- severity: "warning",
6837
- message: "This composition has no `window.__timelines` registration but is missing `data-no-timeline`. The producer polls for timeline registration for up to 45 seconds before timing out, adding 45 s to every render.",
6838
- fixHint: 'Add `data-no-timeline` to the root element to skip the poll: `<div data-composition-id="..." data-no-timeline ...>`.',
6839
- snippet: truncateSnippet(rootTag.raw)
6840
- }
6841
- ];
7006
+ if (hasComputedTimelineRegistration(scripts)) return [];
7007
+ const registeredIds = new Set(
7008
+ scripts.flatMap((script) => extractTimelineRegistryKeys(stripJsComments(script.content)))
7009
+ );
7010
+ return tags.flatMap((tag) => {
7011
+ const compositionId = readDecodedAttr(tag.raw, "data-composition-id");
7012
+ if (!compositionId || registeredIds.has(compositionId)) return [];
7013
+ const isRoot = tag.index === rootTag.index;
7014
+ if (isRoot ? options.isSubComposition : isInsideInertTemplate(tag, tags)) return [];
7015
+ if (readDecodedAttr(tag.raw, "data-no-timeline") !== null || mountsSource(tag)) return [];
7016
+ return [missingTimelineFinding(tag, compositionId, isRoot)];
7017
+ });
6842
7018
  },
6843
7019
  // negative_z_index
6844
7020
  // An element at a negative z-index is silently absent from both `snapshot`
@@ -8139,7 +8315,7 @@ ${right.raw}`)
8139
8315
  severity: "warning",
8140
8316
  message: `${fromToWindows.length} tl.fromTo() calls target "${selector}" with no stable baseline. The last-authored fromTo "from" values become the element's resting state for any seek before the first tween actually runs, because GSAP applies fromTo from-values at authoring time (immediateRender), not at tween position.`,
8141
8317
  selector,
8142
- fixHint: `Add \`immediateRender: false\` to the destination vars of each future fromTo, or set a safe resting state with an earlier \`tl.set("${selector}", { ... }, 0)\`. Pre-first-tween seeks must not inherit whichever fromTo call happened to author last.`,
8318
+ fixHint: `Add \`immediateRender: false\` to every fromTo except the earliest-positioned one (at ${firstFromToPosition}s), so pre-first-tween seeks keep its "from" values. A hiding \`tl.set(..., 0)\` baseline trips gsap_timeline_set_initial_hide, and a \`gsap.set\` authored before the fromTo calls is overwritten by them.`,
8143
8319
  snippet: truncateSnippet(fromToWindows.map((win) => win.raw).join("\n"))
8144
8320
  });
8145
8321
  }
@@ -8272,7 +8448,7 @@ ${right.raw}`)
8272
8448
  const cssFromScale = scaleProps.length > 0 ? matchCssTransform(sel, cssScaleSelectors) : void 0;
8273
8449
  if (!cssFromTranslate && !cssFromScale) continue;
8274
8450
  const existing = conflicts.get(sel) ?? {
8275
- cssTransform: [cssFromTranslate, cssFromScale].filter(Boolean).join(" "),
8451
+ cssTransform: [...new Set([cssFromTranslate, cssFromScale].filter(Boolean))].join(" "),
8276
8452
  props: /* @__PURE__ */ new Set(),
8277
8453
  raw: call.raw
8278
8454
  };
@@ -12,18 +12,18 @@ import {
12
12
  } from "./chunk-262C25DQ.js";
13
13
  import {
14
14
  resolveDiagnosticNavigationTimeoutMs
15
- } from "./chunk-TIZQC44K.js";
15
+ } from "./chunk-OWN3ZIIK.js";
16
16
  import {
17
17
  resolveCaptureBrowserGpuMode,
18
18
  resolveLocalBrowserGpuMode
19
- } from "./chunk-M224DAMG.js";
19
+ } from "./chunk-KPSRL2NB.js";
20
20
  import {
21
21
  c
22
22
  } from "./chunk-ZTZA4UWZ.js";
23
23
  import {
24
24
  assertWebGpuAdapterAvailable,
25
25
  compositionRequiresWebGpu
26
- } from "./chunk-OF3RKOPU.js";
26
+ } from "./chunk-P74PW7KR.js";
27
27
  import {
28
28
  normalizeErrorMessage
29
29
  } from "./chunk-KNU5COPB.js";
@@ -99,7 +99,7 @@ async function openSettledCompositionPage(html, url, options) {
99
99
  const { ensureBrowser, findSystemBrowser } = await import("./manager-NEVLEZK3.js");
100
100
  const browser = await ensureBrowser();
101
101
  const puppeteer = await import("puppeteer-core");
102
- const { buildChromeArgs } = await import("./src-GD7RGV5U.js");
102
+ const { buildChromeArgs } = await import("./src-LVBNYMJW.js");
103
103
  const requestedGpuMode = options.browserGpuMode ?? resolveCliChromeGpuMode();
104
104
  const requiresWebGpu = compositionRequiresWebGpu(html);
105
105
  const launch = async (executablePath) => {
@@ -165,7 +165,7 @@ async function seekCompositionTimeline(page, timeSeconds, options = {}) {
165
165
  await page.evaluate(
166
166
  // Serialized into the page; the seek-target cascade must stay one function.
167
167
  // fallow-ignore-next-line complexity
168
- (t, fallbackToBridgeAndTimelines) => {
168
+ (t, fallbackToBridgeAndTimelines, exactTime) => {
169
169
  const getProperty = (target, key) => {
170
170
  if ((typeof target !== "object" || target === null) && typeof target !== "function") {
171
171
  return void 0;
@@ -184,7 +184,7 @@ async function seekCompositionTimeline(page, timeSeconds, options = {}) {
184
184
  const playerSeek = getProperty(player, "seek");
185
185
  const hf = Reflect.get(window, "__hf");
186
186
  const bridgeSeek = getProperty(hf, "seek");
187
- if (call(renderSeek, player, [safe])) {
187
+ if (call(renderSeek, player, exactTime ? [safe, { exact: true }] : [safe])) {
188
188
  } else if (fallbackToBridgeAndTimelines && call(bridgeSeek, hf, [safe])) {
189
189
  } else if (call(playerSeek, player, [safe])) {
190
190
  } else if (fallbackToBridgeAndTimelines) {
@@ -202,7 +202,8 @@ async function seekCompositionTimeline(page, timeSeconds, options = {}) {
202
202
  call(getProperty(ticker, "tick"), ticker, []);
203
203
  },
204
204
  timeSeconds,
205
- options.fallbackToBridgeAndTimelines === true
205
+ options.fallbackToBridgeAndTimelines === true,
206
+ options.exactTime === true
206
207
  );
207
208
  await page.evaluate(async () => {
208
209
  const waitForCompletion = Reflect.get(window, "__hfWaitForSeekCompletion");