hyperframes 0.8.190 → 0.8.192

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 (222) hide show
  1. package/dist/{add-DBKN5H7H.js → add-TZU2UW7A.js} +17 -17
  2. package/dist/{animatedGifPrep-YVBKKLQY.js → animatedGifPrep-NLAXC3VV.js} +11 -10
  3. package/dist/api.js +24 -23
  4. package/dist/{appHistory-TH3TL6N6.js → appHistory-QVCSAOI4.js} +1 -1
  5. package/dist/{asset-2OHQKUMQ.js → asset-JAJXA6LB.js} +2 -2
  6. package/dist/{assetCataloger-O3QAUWIK.js → assetCataloger-4WTX3J4I.js} +13 -12
  7. package/dist/{audio-IR3JGCMM.js → audio-XLWC7JKS.js} +22 -21
  8. package/dist/{auth-J6TAJLGD.js → auth-5K6X3NPJ.js} +4 -4
  9. package/dist/{autoUpdate-D7BJJUT2.js → autoUpdate-RNV7SKGB.js} +4 -4
  10. package/dist/{backgroundChecks-AILHY2YZ.js → backgroundChecks-QXLVZVGX.js} +5 -5
  11. package/dist/backgroundChecksWorker.js +5 -5
  12. package/dist/{batchRender-QZKFVWEI.js → batchRender-THKSPDZR.js} +14 -7
  13. package/dist/{beats-6LOEKZPB.js → beats-K7CGCFVL.js} +53 -15
  14. package/dist/{benchmark-RJMHI3YW.js → benchmark-PHRDIXNL.js} +18 -14
  15. package/dist/{browser-Q3Q36FE3.js → browser-GN6R5ZSK.js} +7 -7
  16. package/dist/{bundleWithLocalizedFonts-RWHFMSFL.js → bundleWithLocalizedFonts-C325UNR4.js} +3 -3
  17. package/dist/{capture-2PNTGVYV.js → capture-6UBQFHZQ.js} +76 -68
  18. package/dist/{capture-FO3ZZCT4.js → capture-BZ7APOGQ.js} +3 -3
  19. package/dist/{captureCompositionFrame-WTMLWVEJ.js → captureCompositionFrame-VORSCTWC.js} +19 -16
  20. package/dist/{catalog-LUZYPUYT.js → catalog-PHU2RUZ3.js} +18 -18
  21. package/dist/{catch-up-TUTLUTFP.js → catch-up-HCNRM46J.js} +7 -7
  22. package/dist/{check-K2TBTJZS.js → check-TJ5ZLB4I.js} +43 -42
  23. package/dist/{checkBrowser-JT7CXDT6.js → checkBrowser-DWP7ZXJ7.js} +38 -37
  24. package/dist/{chunk-STJ2ANMF.js → chunk-2HP5GIQ3.js} +3 -3
  25. package/dist/{chunk-L34DPWY4.js → chunk-2J3NA3OB.js} +13 -13
  26. package/dist/{chunk-B2A56S5C.js → chunk-2MCXIY4B.js} +13 -10
  27. package/dist/{chunk-DCAI5DBR.js → chunk-2ST4WAFY.js} +9 -1
  28. package/dist/{chunk-TSFA2Y5C.js → chunk-2VXY3PEF.js} +99 -69
  29. package/dist/{chunk-AYFF3GX6.js → chunk-32NB4VMH.js} +1 -1
  30. package/dist/{chunk-IXLUTE6N.js → chunk-3422KMTD.js} +5 -1
  31. package/dist/{chunk-JB7LML5B.js → chunk-3CXIX6XS.js} +68 -7
  32. package/dist/{chunk-F6DNM676.js → chunk-3FV5BVWS.js} +2 -2
  33. package/dist/{chunk-OTQXYTQZ.js → chunk-4E75LHAL.js} +23 -3
  34. package/dist/{chunk-TMBUBLZB.js → chunk-4HCJOFMB.js} +166 -46
  35. package/dist/{chunk-UZ7RJDEC.js → chunk-5IPKQHOL.js} +17 -6
  36. package/dist/{chunk-WBUO6WH6.js → chunk-5TRFLZ5Z.js} +2 -2
  37. package/dist/{chunk-HRPWRZGF.js → chunk-6N65ZMC5.js} +1 -1
  38. package/dist/{chunk-XUXGIA7H.js → chunk-6NLPPKBO.js} +1 -2
  39. package/dist/{chunk-3QLT727N.js → chunk-6WNLQI63.js} +4 -4
  40. package/dist/{chunk-XNLYMHX2.js → chunk-6XVKMBUA.js} +9 -6
  41. package/dist/{chunk-JLSXXMRU.js → chunk-7JJMT6LN.js} +1 -1
  42. package/dist/{chunk-7JHTNUF2.js → chunk-7LLRMYP6.js} +2 -2
  43. package/dist/{chunk-BT64TTSE.js → chunk-7RSY7SZN.js} +2 -2
  44. package/dist/{chunk-DX7VEUBO.js → chunk-7UZC4N62.js} +1 -1
  45. package/dist/{chunk-YT5VLUHM.js → chunk-A4OI5ZNX.js} +1 -1
  46. package/dist/{chunk-TSQAPPRS.js → chunk-AEXVVABM.js} +83 -45
  47. package/dist/{chunk-Y5L5I4US.js → chunk-AMZJFCOX.js} +8 -8
  48. package/dist/{chunk-WCT6KGGT.js → chunk-AR46ND2Q.js} +1 -1
  49. package/dist/chunk-B2XLXD7V.js +3897 -0
  50. package/dist/{chunk-KNQQZRB2.js → chunk-BEOK6F26.js} +2 -2
  51. package/dist/{chunk-76ITJYXX.js → chunk-BPKLUHFT.js} +7 -7
  52. package/dist/{chunk-OOAVKK2W.js → chunk-BV6YE455.js} +2 -2
  53. package/dist/{chunk-XGHHVYC7.js → chunk-BY6OQ6XP.js} +2 -2
  54. package/dist/{chunk-JQYJXUJW.js → chunk-C6KE4AFW.js} +1 -1
  55. package/dist/{chunk-TMK4Q7JA.js → chunk-CFUCHO4T.js} +20 -5
  56. package/dist/{chunk-FANFO5HI.js → chunk-CXRZBWSH.js} +11 -11
  57. package/dist/chunk-CZGHFATT.js +31 -0
  58. package/dist/{chunk-CYBXXSC4.js → chunk-DIKAPMMF.js} +2 -2
  59. package/dist/{chunk-7L37AB57.js → chunk-E3P3LJG6.js} +9 -9
  60. package/dist/{chunk-EU5HTY3E.js → chunk-E5V6WEMK.js} +58 -23
  61. package/dist/{chunk-HJZ5CPZA.js → chunk-EKGGSAWR.js} +6 -5
  62. package/dist/{chunk-7KVVNF7B.js → chunk-ELP5QZWL.js} +1 -1
  63. package/dist/{chunk-QH3T4WI2.js → chunk-EXAX37XR.js} +8 -2
  64. package/dist/{chunk-EI7FP7F3.js → chunk-FBVUAH7N.js} +12 -2
  65. package/dist/{chunk-TTZTGXKG.js → chunk-GANST5K3.js} +2 -2
  66. package/dist/{chunk-EQF6TVWB.js → chunk-IMSI7IFW.js} +65 -29
  67. package/dist/{chunk-W64L7IFS.js → chunk-IW5G323T.js} +1 -1
  68. package/dist/{chunk-RBGNU7VD.js → chunk-J2ASTCU6.js} +2 -2
  69. package/dist/{chunk-SUSSMCWL.js → chunk-J2BSUF6X.js} +1 -1
  70. package/dist/{chunk-GGVGOY6M.js → chunk-JCDYDF54.js} +2 -2
  71. package/dist/{chunk-EPOYPP36.js → chunk-K2AKVYNR.js} +2 -2
  72. package/dist/{chunk-XBGEWNGQ.js → chunk-KZOZN4PI.js} +4 -4
  73. package/dist/{chunk-E7DXKMKU.js → chunk-L2YGSAOL.js} +3 -3
  74. package/dist/{chunk-2FFOLLU2.js → chunk-LOKCBZYF.js} +3 -3
  75. package/dist/{chunk-56IDMP37.js → chunk-MEE4NTPZ.js} +2 -2
  76. package/dist/{chunk-56IOFIYB.js → chunk-MGBUWPXX.js} +2 -2
  77. package/dist/{chunk-K4664CDS.js → chunk-MVIJTXN5.js} +35 -14
  78. package/dist/{chunk-S2IEO6TH.js → chunk-ODBYZIOH.js} +28 -16
  79. package/dist/{chunk-45U3KY7Z.js → chunk-OQL4AJ4X.js} +6 -6
  80. package/dist/{chunk-5C7R55BJ.js → chunk-P2I4RLJE.js} +1 -1
  81. package/dist/{chunk-S7C6EM7N.js → chunk-PFRG5P32.js} +1 -1
  82. package/dist/{chunk-RUOG4VB7.js → chunk-PKZ7RK5N.js} +5 -4
  83. package/dist/{chunk-LLFQA7XF.js → chunk-QFPBRZJD.js} +1 -1
  84. package/dist/{chunk-CWVSJA52.js → chunk-QWLES6YV.js} +3 -3
  85. package/dist/{chunk-OAPYPSEB.js → chunk-QX4TB4NH.js} +292 -79
  86. package/dist/{chunk-BWPY64WA.js → chunk-R2U2G4OS.js} +1 -1
  87. package/dist/{chunk-46HEFGXJ.js → chunk-REUL2KH2.js} +1 -1
  88. package/dist/{chunk-R4QASDTN.js → chunk-RHYOWDI6.js} +2 -2
  89. package/dist/{chunk-DYAPHNV6.js → chunk-RWGASWT7.js} +1 -1
  90. package/dist/chunk-RXATE6FZ.js +385 -0
  91. package/dist/{chunk-CWYS2UNQ.js → chunk-SBBQFPCJ.js} +1 -1
  92. package/dist/{chunk-RDHEG7RX.js → chunk-SK7TR7BL.js} +4 -4
  93. package/dist/{chunk-KNU5COPB.js → chunk-T2EUWCJE.js} +1 -1
  94. package/dist/{chunk-6HYHHMX3.js → chunk-T6O5OLN2.js} +3 -3
  95. package/dist/{chunk-FVD44EQX.js → chunk-ULTKB5FC.js} +65 -23
  96. package/dist/{chunk-B7JFAXDP.js → chunk-VNPADTDD.js} +3 -3
  97. package/dist/{chunk-FUHI34T4.js → chunk-VOM2HLUI.js} +4 -4
  98. package/dist/{chunk-IARWN467.js → chunk-VRAXIQ6I.js} +2 -2
  99. package/dist/{chunk-NAUKCKCJ.js → chunk-W24SZ5FL.js} +4 -4
  100. package/dist/{chunk-ZFFKWHXN.js → chunk-WOKVXK4J.js} +1 -1
  101. package/dist/{chunk-WLG4OYH7.js → chunk-XF77MK3J.js} +1 -1
  102. package/dist/{chunk-DRTIIAIZ.js → chunk-XX2PA4L3.js} +2 -2
  103. package/dist/{chunk-A5YHWTSP.js → chunk-YMQQXPD5.js} +2 -2
  104. package/dist/{chunk-KUMUK6QS.js → chunk-YWRQHRDY.js} +17 -12
  105. package/dist/{chunk-EUUHVDMN.js → chunk-ZEMDV6W2.js} +29 -59
  106. package/dist/{clean-UVTWBPXK.js → clean-2RNCTDBT.js} +40 -27
  107. package/dist/cli.js +69 -67
  108. package/dist/{cloud-M42IPKFD.js → cloud-NFIKESNZ.js} +4 -4
  109. package/dist/{cloudrun-CTNX64R6.js → cloudrun-7224BCX3.js} +9 -9
  110. package/dist/commands/contrast-audit.browser.js +1 -1
  111. package/dist/commands/layout-audit.browser.js +64 -3
  112. package/dist/{compare-MQI7TG5M.js → compare-HL44MXVX.js} +80 -48
  113. package/dist/{compiler-EJE3HLCS.js → compiler-WF5QTXV7.js} +8 -7
  114. package/dist/{component-QSYOSFVV.js → component-ZBZXSJBR.js} +3 -3
  115. package/dist/{compositions-ITDFE7K4.js → compositions-76P7LDDX.js} +19 -17
  116. package/dist/{contactSheet-CAGMKI3E.js → contactSheet-43ISAESM.js} +2 -2
  117. package/dist/{delete-NTGTENKJ.js → delete-4YZBYOHJ.js} +7 -7
  118. package/dist/{deploy-AOJOXEYX.js → deploy-UGUUGYLF.js} +1 -1
  119. package/dist/{deterministicFonts-EGAAE7QL.js → deterministicFonts-RO2TCMLZ.js} +3 -3
  120. package/dist/{dist-NHW2JQCA.js → dist-5KKCRFPT.js} +5 -5
  121. package/dist/{dist-JH32CBQL.js → dist-QQ26RUDV.js} +5 -4
  122. package/dist/docs/rendering.md +2 -2
  123. package/dist/{doctor-Q6DAYVSQ.js → doctor-GGVUK4NB.js} +20 -19
  124. package/dist/{events-BQIBYPCF.js → events-OXPTHVDB.js} +4 -4
  125. package/dist/{events-PV3CDO4A.js → events-V2VU4J3B.js} +5 -5
  126. package/dist/{feedback-BZH26JQE.js → feedback-HFZ5SCUK.js} +16 -16
  127. package/dist/{ffmpeg-KU7RNT3U.js → ffmpeg-3VHY7GO3.js} +13 -12
  128. package/dist/{figma-PBGZUEIL.js → figma-7SEZTLBJ.js} +3 -3
  129. package/dist/fontLocalizeCli.js +14 -13
  130. package/dist/{get-MM2JZ5ET.js → get-Y2S2PXCM.js} +7 -7
  131. package/dist/{gpuPolicy-DQE2CD5T.js → gpuPolicy-UHPOWRV5.js} +11 -10
  132. package/dist/{grade-compare-YTDQ7YXW.js → grade-compare-4VTXSQM5.js} +38 -37
  133. package/dist/{gsapParserAcorn-SKODXC2N.js → gsapParserAcorn-OOTY2MVN.js} +2 -2
  134. package/dist/{help-M4B2DN7E.js → help-HXNOACHI.js} +1 -1
  135. package/dist/{history-ZW4UYKAJ.js → history-XDJUI4LC.js} +39 -16
  136. package/dist/hyperframe.manifest.json +1 -1
  137. package/dist/hyperframe.runtime.iife.js +64 -64
  138. package/dist/hyperframes-player.global.js +3 -3
  139. package/dist/hyperframes-slideshow.global.js +1 -1
  140. package/dist/{info-L7LQAXLK.js → info-KYRI3EZV.js} +56 -22
  141. package/dist/{init-HTSQ535A.js → init-IL7EWMT5.js} +38 -45
  142. package/dist/{inspect-EWF2THRR.js → inspect-TBNH23UC.js} +36 -35
  143. package/dist/{installer-PQKH2S7C.js → installer-O2YMFSI4.js} +8 -8
  144. package/dist/{keyframes-X2QKJ4DP.js → keyframes-4GF62KAJ.js} +13 -14
  145. package/dist/{lambda-BURM66GP.js → lambda-JFL6M4XZ.js} +12 -12
  146. package/dist/{layout-3Z3SJGZZ.js → layout-7MAEFR65.js} +36 -35
  147. package/dist/{lint-OMNZ2K5J.js → lint-4AYHKYAM.js} +23 -16
  148. package/dist/{lintProject-XM3DLUKG.js → lintProject-52SLJPRC.js} +5 -4
  149. package/dist/{list-5ZSQEH6N.js → list-3DP3D3MW.js} +7 -7
  150. package/dist/{login-YNCQPHLA.js → login-T54WQYRQ.js} +7 -7
  151. package/dist/{logout-DDC4QLVK.js → logout-JYFWWUGK.js} +3 -3
  152. package/dist/{manager-UHWEKPXC.js → manager-MZIJY73J.js} +3 -3
  153. package/dist/{manager-N6XXRQN3.js → manager-QROK2IH3.js} +14 -13
  154. package/dist/{media-treatment-EOKBRJPY.js → media-treatment-4CXF7MSG.js} +20 -19
  155. package/dist/{models-6T4CCKUV.js → models-IS3I6JKU.js} +18 -17
  156. package/dist/{motionShot-KXKMYZ3A.js → motionShot-DVYJZOTQ.js} +21 -20
  157. package/dist/{normalize-3AYFSN2F.js → normalize-FASIPBUM.js} +1 -1
  158. package/dist/{normalize-audio-VWB7RHHA.js → normalize-audio-4527JIK4.js} +12 -8
  159. package/dist/{open-32SQCNUP.js → open-5JE46SAX.js} +18 -18
  160. package/dist/{parakeetRunner-BXW2WX6Q.js → parakeetRunner-7JIJGJJ7.js} +20 -19
  161. package/dist/{pipeline-V5ONFRCY.js → pipeline-YEN3WFD2.js} +15 -14
  162. package/dist/{play-BBL262JE.js → play-WFX67I7M.js} +27 -26
  163. package/dist/{policies-MBWGLMWB.js → policies-GHVXA5PE.js} +1 -1
  164. package/dist/{preflight-LCNGQFNY.js → preflight-D377HVUZ.js} +15 -14
  165. package/dist/{present-RY4HO4ZQ.js → present-XTSEKAC7.js} +24 -23
  166. package/dist/{preview-BLLPCCLG.js → preview-5XH7EK6O.js} +28 -26
  167. package/dist/{producer-QG4AQ35S.js → producer-TFFYF4ZM.js} +1 -1
  168. package/dist/{projectConfig-LN3NR5OM.js → projectConfig-6YUJHMCL.js} +10 -10
  169. package/dist/{publication-TXMCS4KM.js → publication-JK33Y55E.js} +5 -5
  170. package/dist/{publish-57VURD7Z.js → publish-JHDGXWXU.js} +18 -17
  171. package/dist/{refresh-RXTOPRBB.js → refresh-USSFPJAU.js} +3 -3
  172. package/dist/{remove-background-VEWVIO3A.js → remove-background-P44MYAPJ.js} +16 -15
  173. package/dist/{render-SP7WAUB4.js → render-HJ34EGMN.js} +10 -9
  174. package/dist/{render-XMN3NJIQ.js → render-RBINWWP5.js} +43 -42
  175. package/dist/{render-4E7QDVOI.js → render-RJ3I4E3A.js} +26 -25
  176. package/dist/{render-batch-7ULP5RIJ.js → render-batch-3D6XQYUC.js} +11 -10
  177. package/dist/renderSetupWorker.js +9 -8
  178. package/dist/{resolver-D3XERO6U.js → resolver-HCLTFZUW.js} +7 -7
  179. package/dist/{screenshotCapture-UBY6TT75.js → screenshotCapture-I5EDCITF.js} +6 -3
  180. package/dist/{sherpa-5B5G426W.js → sherpa-IPOUJM6Q.js} +19 -18
  181. package/dist/{sites-5PWHAMEG.js → sites-Q2S3DZY4.js} +2 -1
  182. package/dist/skills/hyperframes/references/captions.md +1 -1
  183. package/dist/skills/hyperframes/references/skill-lifecycle.md +8 -4
  184. package/dist/skills/hyperframes-cli/references/cloudrun.md +1 -1
  185. package/dist/skills/hyperframes-cli/references/init-and-scaffold.md +1 -1
  186. package/dist/skills/hyperframes-cli/references/lambda.md +1 -1
  187. package/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +2 -2
  188. package/dist/skills/hyperframes-cli/references/preview-render.md +1 -1
  189. package/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +0 -8
  190. package/dist/skills/media-use/audio/references/transcribe.md +2 -2
  191. package/dist/skills/media-use/references/audio.md +1 -1
  192. package/dist/{skills-RXHRF7O7.js → skills-P67QEERC.js} +13 -75
  193. package/dist/{skillsUpdateCheck-JOTDZJAE.js → skillsUpdateCheck-IFMLRVIF.js} +5 -5
  194. package/dist/{slideshow-YTWATJRT.js → slideshow-SJGK4RQS.js} +1 -1
  195. package/dist/{snapshot-DN4MP4VN.js → snapshot-4YM4NNWJ.js} +66 -48
  196. package/dist/{src-W6Y5ZYRQ.js → src-DCD3YMXX.js} +13 -12
  197. package/dist/{src-XSDYRKLG.js → src-SSV66L3F.js} +14 -9
  198. package/dist/{staticProjectServer-JMFGTPMX.js → staticProjectServer-C7PPGLEQ.js} +22 -21
  199. package/dist/{status-CM7IQTU2.js → status-H5WLKQDS.js} +3 -3
  200. package/dist/studio/assets/{hyperframes-player-0HXJPmYC.js → hyperframes-player-ChN3cOr0.js} +3 -3
  201. package/dist/studio/assets/{index-DsSfhjUS.js → index-BYbFcRR0.js} +1 -1
  202. package/dist/studio/assets/{index-BYw97F07.js → index-CHu83hHM.js} +126 -125
  203. package/dist/studio/assets/{index-B3vk3hfU.css → index-CYbvOVp-.css} +1 -1
  204. package/dist/studio/index.html +2 -2
  205. package/dist/{studio-api-SZ4OMFPN.js → studio-api-6YZ7PIQR.js} +17 -14
  206. package/dist/{studioServer-LWO33H7D.js → studioServer-EWHSE4GC.js} +60 -59
  207. package/dist/{telemetry-QG5AANZ4.js → telemetry-4K6CPMNT.js} +2 -2
  208. package/dist/{telemetry-K3AFDKOP.js → telemetry-GGLBHZRZ.js} +5 -5
  209. package/dist/{timeline-NYQOAQDH.js → timeline-NKHQJXJ2.js} +65 -43
  210. package/dist/{tokens-K7YWUVOK.js → tokens-FWNNDJ6R.js} +2 -2
  211. package/dist/{transcribe-QAUMODXM.js → transcribe-TRPKXZ7L.js} +27 -26
  212. package/dist/{transcribe-ANPUQDZD.js → transcribe-VD2TMMC2.js} +17 -16
  213. package/dist/{tts-A2WILYGN.js → tts-5I2AJNLM.js} +1 -1
  214. package/dist/{updateCheck-RNR4HMDI.js → updateCheck-CUPS6LU3.js} +4 -4
  215. package/dist/{upgrade-MKUGZZPA.js → upgrade-23XO6MEX.js} +4 -4
  216. package/dist/{urlDownloader-5USPXLCS.js → urlDownloader-YOAOONCK.js} +10 -9
  217. package/dist/{validate-OJHPDLC5.js → validate-BWIW24G5.js} +30 -29
  218. package/dist/{video-BCKRR6LU.js → video-XRXJS4GC.js} +12 -11
  219. package/dist/warmCheck.js +43 -42
  220. package/package.json +2 -1
  221. package/dist/chunk-DIV37NUE.js +0 -3896
  222. package/dist/chunk-I5JRXMCV.js +0 -6077
@@ -26,7 +26,7 @@ import {
26
26
  renderFrameIdForRenderId,
27
27
  resolveAuthoredTimingWindow,
28
28
  toFps
29
- } from "./chunk-56IOFIYB.js";
29
+ } from "./chunk-MGBUWPXX.js";
30
30
  import {
31
31
  AUDIO_GROUP_RENDER_ID_ATTR,
32
32
  COLOR_GRADING_SOURCE_HIDDEN_ATTR,
@@ -63,7 +63,7 @@ import {
63
63
  sourceTimeAt,
64
64
  timeAtSourceTime,
65
65
  volumeSegmentSampleCount
66
- } from "./chunk-DIV37NUE.js";
66
+ } from "./chunk-B2XLXD7V.js";
67
67
  import {
68
68
  clampAudioGain,
69
69
  clipGain,
@@ -83,7 +83,7 @@ import {
83
83
  } from "./chunk-4UMPIPCQ.js";
84
84
  import {
85
85
  resolveReferencedStart
86
- } from "./chunk-TSFA2Y5C.js";
86
+ } from "./chunk-2VXY3PEF.js";
87
87
  import {
88
88
  FFMPEG_PATH_ENV,
89
89
  FFPROBE_PATH_ENV,
@@ -3735,6 +3735,7 @@ async function produceDrawElementFrameBatch(page, times, width, height, quality
3735
3735
  const { t, fid } = frame;
3736
3736
  try {
3737
3737
  if (aw.__hf && typeof aw.__hf.seek === "function") aw.__hf.seek(t);
3738
+ await aw.__hfWaitForSeekCompletion?.();
3738
3739
  await aw.__hfDecodeDynamicCssBackgroundImages?.();
3739
3740
  aw.__hf3d?.update();
3740
3741
  const accel = (aw.__hf_accel_canvases ?? []).filter((c) => root.contains(c));
@@ -4777,8 +4778,11 @@ async function sampleProcessRss(pids, exec = defaultExec(), platform = process.p
4777
4778
  if (platform === "win32") {
4778
4779
  const results = [];
4779
4780
  for (const pid of unique) {
4780
- const { stdout: stdout2 } = await exec("tasklist", ["/FO", "CSV", "/NH", "/FI", `PID eq ${pid}`]);
4781
- results.push(...parseTasklistCsv(pid, stdout2));
4781
+ try {
4782
+ const { stdout: stdout2 } = await exec("tasklist", ["/FO", "CSV", "/NH", "/FI", `PID eq ${pid}`]);
4783
+ results.push(...parseTasklistCsv(pid, stdout2));
4784
+ } catch {
4785
+ }
4782
4786
  }
4783
4787
  return results;
4784
4788
  }
@@ -5738,16 +5742,60 @@ async function listUnregisteredTimelineIds(page) {
5738
5742
  })()`);
5739
5743
  return Array.isArray(evaluated) ? evaluated.map((id) => String(id)) : [];
5740
5744
  }
5741
- async function waitForSubCompositionTimelines(session, page, timeoutMs) {
5745
+ function isScriptFailure(session) {
5746
+ const outcome = session.subTimelineWaitOutcome;
5747
+ return outcome === "script_failure" || outcome === "timeout" && session.pageErrors.length > 0;
5748
+ }
5749
+ async function isolateUnregisteredCompositions(page) {
5750
+ const isolated = await page.evaluate(`(function() {
5751
+ var timelines = (window.__timelines = window.__timelines || {});
5752
+ var out = [];
5753
+ if (!window.gsap) return out;
5754
+ var broken = [];
5755
+ var live = 0;
5756
+ var hosts = document.querySelectorAll("[data-composition-id]");
5757
+ for (var i = 0; i < hosts.length; i++) {
5758
+ var host = hosts[i];
5759
+ var id = host.getAttribute("data-composition-id");
5760
+ if (!id || host.hasAttribute("data-no-timeline")) continue;
5761
+ var isRoot = !host.parentElement || !host.parentElement.closest("[data-composition-id]");
5762
+ if (timelines[id]) {
5763
+ if (!isRoot) live++;
5764
+ } else if (isRoot) {
5765
+ return out;
5766
+ } else {
5767
+ broken.push(host);
5768
+ }
5769
+ }
5770
+ if (live === 0) return out;
5771
+ broken.forEach(function(host) {
5772
+ var tl = window.gsap.timeline({ paused: true });
5773
+ var duration = parseFloat(host.getAttribute("data-duration"));
5774
+ if (duration > 0) tl.set({}, {}, duration);
5775
+ var id = host.getAttribute("data-composition-id");
5776
+ timelines[id] = tl;
5777
+ out.push({ compositionId: id, elementId: host.id || host.getAttribute("data-hf-id") || null });
5778
+ });
5779
+ if (out.length && typeof window.__hfForceTimelineRebind === "function") window.__hfForceTimelineRebind();
5780
+ return out;
5781
+ })()`);
5782
+ return Array.isArray(isolated) ? isolated : [];
5783
+ }
5784
+ async function waitForSubCompositionTimelines(session, page, timeoutMs, options = {}) {
5742
5785
  const memo = session.subTimelineWaitMemo;
5743
5786
  session.subTimelineWaitOutcome = await pollSubCompositionTimelines(page, timeoutMs, {
5744
5787
  getScriptLoadFailures: () => session.scriptLoadFailures,
5788
+ getPageErrors: () => session.pageErrors,
5789
+ scriptErrorGraceMs: options.scriptErrorGraceMs,
5745
5790
  onPending: (ids) => {
5746
5791
  session.pendingTimelineIds = [...ids];
5747
5792
  },
5748
5793
  shouldStop: () => session.vfxFailure !== void 0,
5749
5794
  knownUnregisteredIds: memo.unregisteredIds
5750
5795
  });
5796
+ if (isScriptFailure(session) && session.scriptLoadFailures.length === 0) {
5797
+ session.isolatedCompositions = await isolateUnregisteredCompositions(page);
5798
+ }
5751
5799
  const cleanTimeout = session.subTimelineWaitOutcome === "timeout" && session.vfxFailure === void 0 && session.pageErrors.length === 0 && session.scriptLoadFailures.length === 0;
5752
5800
  if (cleanTimeout) {
5753
5801
  memo.unregisteredIds = session.pendingTimelineIds ?? [];
@@ -5757,6 +5805,8 @@ async function pollSubCompositionTimelines(page, timeoutMs, {
5757
5805
  intervalMs = 150,
5758
5806
  getScriptLoadFailures,
5759
5807
  scriptFailureGraceMs = 2e3,
5808
+ getPageErrors,
5809
+ scriptErrorGraceMs = 5e3,
5760
5810
  onPending,
5761
5811
  shouldStop,
5762
5812
  knownUnregisteredIds = []
@@ -5778,16 +5828,22 @@ async function pollSubCompositionTimelines(page, timeoutMs, {
5778
5828
  const deadline = start + timeoutMs;
5779
5829
  let ready = false;
5780
5830
  let scriptFailureBail = false;
5831
+ let errorSeenAt;
5781
5832
  for (; ; ) {
5782
5833
  ready = Boolean(await page.evaluate(expression));
5783
5834
  if (ready || shouldStop?.()) break;
5784
5835
  const now = Date.now();
5785
5836
  if (now >= deadline) break;
5786
5837
  const failures = getScriptLoadFailures?.() ?? [];
5787
- if (failures.length > 0 && now - start >= scriptFailureGraceMs) {
5838
+ const errors = getPageErrors?.() ?? [];
5839
+ const failed = failures.length > 0 ? failures : errors;
5840
+ const graceMs = failures.length > 0 ? scriptFailureGraceMs : scriptErrorGraceMs;
5841
+ if (failed.length > 0) errorSeenAt ??= now;
5842
+ const sinceFailure = failures.length > 0 ? now - start : now - (errorSeenAt ?? now);
5843
+ if (failed.length > 0 && sinceFailure >= graceMs) {
5788
5844
  scriptFailureBail = true;
5789
5845
  console.warn(
5790
- `[FrameCapture] Sub-composition timeline wait cut short after ${now - start}ms: script resource(s) failed to load (${failures.join(", ")}), so the timeline registration they carry can never arrive. Fix the script reference; the render proceeds without those animations.`
5846
+ `[FrameCapture] Sub-composition timeline wait cut short after ${now - start}ms: script(s) failed (${failed.join(", ")}), so the timeline registration they carry can never arrive. Fix the script.`
5791
5847
  );
5792
5848
  break;
5793
5849
  }
@@ -5821,7 +5877,7 @@ async function pollVideosReady(page, skipIds, timeoutMs, intervalMs = 100) {
5821
5877
  return Boolean(
5822
5878
  await page.evaluate((skipIdList) => {
5823
5879
  const skip = new Set(skipIdList);
5824
- const vids = Array.from(document.querySelectorAll("video")).filter((v) => !skip.has(v.id));
5880
+ const vids = Array.from(document.querySelectorAll("video")).filter((v) => !skip.has(v.id)).filter((v) => !v.closest("[data-hidden]"));
5825
5881
  return vids.length === 0 || vids.every((v) => {
5826
5882
  const ve = v;
5827
5883
  if (ve.readyState >= 2) return true;
@@ -5935,15 +5991,31 @@ function recordCaptureWarnings(session, warnings) {
5935
5991
  function recordSubTimelineWarning(session, timeoutMs) {
5936
5992
  const outcome = session.subTimelineWaitOutcome;
5937
5993
  if (outcome === "ready" || !outcome) return;
5938
- const threwThenTimedOut = outcome === "timeout" && session.pageErrors.length > 0;
5939
- const scriptFailure = outcome === "script_failure" || threwThenTimedOut;
5994
+ const threwThenTimedOut = session.pageErrors.length > 0 && session.scriptLoadFailures.length === 0;
5995
+ const scriptFailure = isScriptFailure(session);
5940
5996
  const sources = [...session.scriptLoadFailures, ...session.pageErrors];
5941
5997
  const pending = session.pendingTimelineIds ?? [];
5942
5998
  const pendingSuffix = pending.length > 0 ? ` (still unregistered: ${pending.join(", ")})` : "";
5999
+ const isolated = session.isolatedCompositions ?? [];
6000
+ if (isolated.length > 0) {
6001
+ recordCaptureWarnings(session, [
6002
+ {
6003
+ code: "script_error_isolated",
6004
+ message: `A composition script failed, so its animation was skipped and the render went on: ${isolated.map((c) => c.elementId ?? c.compositionId).join(", ")} (${sources.join(", ")}).`,
6005
+ details: {
6006
+ sources,
6007
+ pendingCompositionIds: [...pending],
6008
+ isolatedElements: isolated,
6009
+ failureOwner: "user"
6010
+ }
6011
+ }
6012
+ ]);
6013
+ return;
6014
+ }
5943
6015
  recordCaptureWarnings(session, [
5944
6016
  {
5945
6017
  code: scriptFailure ? "sub_timeline_script_failure" : "sub_timeline_readiness_timeout",
5946
- message: threwThenTimedOut ? `A composition script threw and a timeline did not register within ${timeoutMs}ms${pendingSuffix} (${sources.join(", ")}). Fix the error; a composition animated by CSS or rAF rather than a GSAP timeline must mark its host with data-no-timeline.` : scriptFailure ? `A sub-composition timeline script failed to load (${sources.join(", ")})` : `Sub-composition timelines did not become ready within ${timeoutMs}ms${pendingSuffix}. This can be intentional: a composition driven by CSS animations or rAF never registers window.__timelines[id], and marking its host with data-no-timeline skips the wait entirely. Otherwise, a composition that sets up asynchronously must register window.__timelines[id] once setup completes.`,
6018
+ message: threwThenTimedOut ? `A composition script threw before its timeline registered${pendingSuffix} (${sources.join(", ")}). Fix the error; a composition animated by CSS or rAF rather than a GSAP timeline must mark its host with data-no-timeline.` : scriptFailure ? `A sub-composition timeline script failed to load (${sources.join(", ")})` : `Sub-composition timelines did not become ready within ${timeoutMs}ms${pendingSuffix}. This can be intentional: a composition driven by CSS animations or rAF never registers window.__timelines[id], and marking its host with data-no-timeline skips the wait entirely. Otherwise, a composition that sets up asynchronously must register window.__timelines[id] once setup completes.`,
5947
6019
  details: {
5948
6020
  timeoutMs,
5949
6021
  sources,
@@ -6219,7 +6291,7 @@ async function initializeSession(session) {
6219
6291
  if (!videosReady) {
6220
6292
  const failedVideos = await page.evaluate((skipIdList) => {
6221
6293
  const skip = new Set(skipIdList);
6222
- return Array.from(document.querySelectorAll("video")).filter((v) => !skip.has(v.id)).filter((v) => v.readyState < 2 && !v.error).map((v) => v.src || v.getAttribute("src") || "(no src)").join(", ");
6294
+ return Array.from(document.querySelectorAll("video")).filter((v) => !skip.has(v.id)).filter((v) => !v.closest("[data-hidden]")).filter((v) => v.readyState < 2 && !v.error).map((v) => v.src || v.getAttribute("src") || "(no src)").join(", ");
6223
6295
  }, skipVideoIds);
6224
6296
  console.warn(
6225
6297
  `[FrameCapture] Some video elements did not decode within ${pageReadyTimeout}ms: ${failedVideos}. Continuing render. Affected videos will appear as blank/black frames.`
@@ -6315,7 +6387,7 @@ async function initializeSession(session) {
6315
6387
  if (!bfVideosReady) {
6316
6388
  const failedVideos = await page.evaluate((skipIdList) => {
6317
6389
  const skip = new Set(skipIdList);
6318
- return Array.from(document.querySelectorAll("video")).filter((v) => !skip.has(v.id)).filter((v) => v.readyState < 2 && !v.error).map((v) => v.src || v.getAttribute("src") || "(no src)").join(", ");
6390
+ return Array.from(document.querySelectorAll("video")).filter((v) => !skip.has(v.id)).filter((v) => !v.closest("[data-hidden]")).filter((v) => v.readyState < 2 && !v.error).map((v) => v.src || v.getAttribute("src") || "(no src)").join(", ");
6319
6391
  }, bfSkipVideoIds);
6320
6392
  console.warn(
6321
6393
  `[FrameCapture] Some video elements did not decode within ${pageReadyTimeout}ms: ${failedVideos}. Continuing render. Affected videos will appear as blank/black frames.`
@@ -7028,6 +7100,44 @@ function resolveSessionMotionBlur(session) {
7028
7100
  }
7029
7101
  return plan;
7030
7102
  }
7103
+ async function judgeSmallDrawElementFrame(session, frameIndex, buffer, redraw) {
7104
+ const sizes = session.deFrameSizes ??= [];
7105
+ const sorted = sizes.length >= 12 ? [...sizes].sort((a, b) => a - b) : null;
7106
+ const median = sorted ? sorted[sorted.length >> 1] ?? 0 : 0;
7107
+ const floor = Math.max(session.deAbsFloor ?? 2e4, median * 0.12);
7108
+ let kept = buffer;
7109
+ if (buffer.length < floor && !session.deAcceptedSmall?.equals(buffer)) {
7110
+ const suspect = () => new DrawElementCaptureError(
7111
+ frameIndex,
7112
+ `suspect small frame (${buffer.length}B < ${Math.round(floor)}B)`
7113
+ );
7114
+ if (session.beginFrameTimeTicks > 0) throw suspect();
7115
+ const retry = await redraw();
7116
+ if (retry.equals(buffer)) {
7117
+ session.deAbsFloor = Math.min(session.deAbsFloor ?? 2e4, Math.floor(buffer.length / 2));
7118
+ session.deAcceptedSmall = buffer;
7119
+ } else if (retry.length < floor) {
7120
+ throw suspect();
7121
+ } else {
7122
+ kept = retry;
7123
+ }
7124
+ }
7125
+ if (sizes.length >= 60) sizes.shift();
7126
+ sizes.push(kept.length);
7127
+ return kept;
7128
+ }
7129
+ async function redrawDrawElementFrame(session, frameIndex, time, seekOptions, heldVideoTime) {
7130
+ const { page, options } = session;
7131
+ await prepareFrameForCapture(session, frameIndex, time, seekOptions, heldVideoTime);
7132
+ return captureDrawElementFrame(
7133
+ page,
7134
+ options.width,
7135
+ options.height,
7136
+ options.format ?? "jpeg",
7137
+ options.quality ?? 80,
7138
+ true
7139
+ );
7140
+ }
7031
7141
  async function captureFrameSurface(session, frameIndex, time, seekOptions, heldVideoTime) {
7032
7142
  const { page, options } = session;
7033
7143
  const { quantizedTime, seekMs, beforeCaptureMs } = await prepareFrameForCapture(
@@ -7087,19 +7197,12 @@ async function captureFrameSurface(session, frameIndex, time, seekOptions, heldV
7087
7197
  session.beginFrameTimeTicks === 0
7088
7198
  );
7089
7199
  if ((options.format ?? "jpeg") !== "png" && process.env.HF_FORCE_DRAWELEMENT !== "1") {
7090
- const sizes = session.deFrameSizes ??= [];
7091
- const sorted = sizes.length >= 12 ? [...sizes].sort((a, b) => a - b) : null;
7092
- const median = sorted ? sorted[sorted.length >> 1] ?? 0 : 0;
7093
- const floor = Math.max(2e4, median * 0.12);
7094
- if (screenshotBuffer.length < floor) {
7095
- throw new DrawElementCaptureError(
7096
- frameIndex,
7097
- `suspect small frame (${screenshotBuffer.length}B < ${Math.round(floor)}B)`
7098
- );
7099
- } else {
7100
- if (sizes.length >= 60) sizes.shift();
7101
- sizes.push(screenshotBuffer.length);
7102
- }
7200
+ screenshotBuffer = await judgeSmallDrawElementFrame(
7201
+ session,
7202
+ frameIndex,
7203
+ screenshotBuffer,
7204
+ () => redrawDrawElementFrame(session, frameIndex, time, seekOptions, heldVideoTime)
7205
+ );
7103
7206
  }
7104
7207
  } catch (err) {
7105
7208
  if (isRecoverableDrawElementError(err)) {
@@ -8444,6 +8547,7 @@ var videoMetadataCache = /* @__PURE__ */ new Map();
8444
8547
  var finalVideoFrameTimestampCache = /* @__PURE__ */ new Map();
8445
8548
  var finalVideoFrameTimestampSignalCaches = /* @__PURE__ */ new WeakMap();
8446
8549
  var audioMetadataCache = /* @__PURE__ */ new Map();
8550
+ var audioMetadataSignalCaches = /* @__PURE__ */ new WeakMap();
8447
8551
  var mediaProbeOutputCache = /* @__PURE__ */ new Map();
8448
8552
  var mediaProbeOutputSignalCaches = /* @__PURE__ */ new WeakMap();
8449
8553
  var MEDIA_PROBE_OUTPUT_CACHE_MAX_ENTRIES = 128;
@@ -8499,7 +8603,16 @@ function isPngImageProbe(output) {
8499
8603
  (stream) => stream.codec_type === "video" && stream.codec_name?.toLowerCase() === "png"
8500
8604
  );
8501
8605
  }
8606
+ var contentAddressedUrls = /* @__PURE__ */ new Map();
8607
+ var withoutQuery = (url) => url.split(/[?#]/, 1)[0] ?? url;
8608
+ function declareContentAddressedUrl(url, sha256) {
8609
+ contentAddressedUrls.set(withoutQuery(url), sha256);
8610
+ }
8502
8611
  function mediaFileIdentity(filePath) {
8612
+ if (/^https?:\/\//i.test(filePath)) {
8613
+ const sha256 = contentAddressedUrls.get(withoutQuery(filePath));
8614
+ return sha256 ? `sha256:${sha256}` : null;
8615
+ }
8503
8616
  try {
8504
8617
  const stat = statSync2(filePath, { bigint: true });
8505
8618
  return [stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].join(":");
@@ -8851,42 +8964,51 @@ async function extractFinalVideoFrameTimestamp(filePath, metadata, signal) {
8851
8964
  var extractVideoMetadata = extractMediaMetadata;
8852
8965
  async function extractAudioMetadata(filePath, options) {
8853
8966
  const identity = mediaFileIdentity(filePath);
8854
- const cached = options?.signal ? void 0 : readMetadataCache(audioMetadataCache, filePath, identity);
8967
+ const signal = options?.signal;
8968
+ if (signal && identity === null) return probeAudioMetadata(filePath, signal);
8969
+ let cache = audioMetadataCache;
8970
+ if (signal) {
8971
+ cache = audioMetadataSignalCaches.get(signal) ?? /* @__PURE__ */ new Map();
8972
+ audioMetadataSignalCaches.set(signal, cache);
8973
+ }
8974
+ const cached = readMetadataCache(cache, filePath, identity);
8855
8975
  if (cached) return cached;
8856
- const probePromise = (async () => {
8857
- const output = await probeMediaOutput(filePath, options?.signal);
8858
- const audioStream = output.streams.find((s) => s.codec_type === "audio");
8859
- if (!audioStream) throw new Error("[FFmpeg] No audio stream found");
8860
- let durationSeconds = output.format.duration ? parseFloat(output.format.duration) : 0;
8861
- const streamDuration = audioStream.duration ? parseFloat(audioStream.duration) : void 0;
8862
- const sampleRate = audioStream.sample_rate ? parseInt(audioStream.sample_rate) : 44100;
8863
- const audioCodec = audioStream.codec_name || "unknown";
8864
- if (sampleRate > 0) {
8865
- const decoded = await probeDecodedAudioDuration(
8866
- filePath,
8867
- sampleRate,
8868
- audioStartSeconds(audioStream, output.format),
8869
- durationSeconds,
8870
- options?.signal
8871
- );
8872
- if (decoded !== null) {
8873
- durationSeconds = reconcileAudioDuration(durationSeconds, decoded, output.format);
8874
- }
8875
- }
8876
- return {
8877
- durationSeconds,
8878
- streamDurationSeconds: streamDuration && streamDuration > 0 ? streamDuration : void 0,
8879
- sampleRate,
8880
- channels: audioStream.channels || 2,
8881
- audioCodec,
8882
- bitrate: output.format.bit_rate ? parseInt(output.format.bit_rate) : void 0,
8883
- latestStreamLeadSeconds: latestStreamLeadSeconds(output)
8884
- };
8885
- })();
8886
- if (options?.signal) return probePromise;
8887
- writeMetadataCache(audioMetadataCache, filePath, identity, probePromise);
8976
+ const probePromise = probeAudioMetadata(filePath, signal);
8977
+ writeMetadataCache(cache, filePath, identity, probePromise);
8888
8978
  return probePromise;
8889
8979
  }
8980
+ async function probeAudioMetadata(filePath, signal) {
8981
+ const output = await probeMediaOutput(filePath, signal);
8982
+ const audioStream = output.streams.find((s) => s.codec_type === "audio");
8983
+ if (!audioStream) throw new Error("[FFmpeg] No audio stream found");
8984
+ let durationSeconds = output.format.duration ? parseFloat(output.format.duration) : 0;
8985
+ const streamDuration = audioStream.duration ? parseFloat(audioStream.duration) : void 0;
8986
+ const sampleRate = audioStream.sample_rate ? parseInt(audioStream.sample_rate) : 44100;
8987
+ const audioCodec = audioStream.codec_name || "unknown";
8988
+ if (sampleRate > 0) {
8989
+ const decoded = await probeDecodedAudioDuration(
8990
+ filePath,
8991
+ sampleRate,
8992
+ audioStartSeconds(audioStream, output.format),
8993
+ durationSeconds,
8994
+ signal
8995
+ );
8996
+ if (decoded !== null) {
8997
+ durationSeconds = reconcileAudioDuration(durationSeconds, decoded, output.format);
8998
+ }
8999
+ }
9000
+ return {
9001
+ durationSeconds,
9002
+ streamDurationSeconds: streamDuration && streamDuration > 0 ? streamDuration : void 0,
9003
+ sampleRate,
9004
+ channels: audioStream.channels || 2,
9005
+ audioCodec,
9006
+ bitrate: output.format.bit_rate ? parseInt(output.format.bit_rate) : void 0,
9007
+ latestStreamLeadSeconds: latestStreamLeadSeconds(output),
9008
+ audioStreamLeadSeconds: streamLeadSeconds(output, audioStream),
9009
+ audioStreamCount: output.streams.filter((s) => s.codec_type === "audio").length
9010
+ };
9011
+ }
8890
9012
  function audioVideoStreamStarts(output) {
8891
9013
  return (output?.streams ?? []).filter(
8892
9014
  (s) => (s.codec_type === "audio" || s.codec_type === "video") && s.disposition?.attached_pic !== 1
@@ -9022,8 +9144,10 @@ async function analyzeKeyframeIntervalsUncached(filePath, videoStreamStartSecond
9022
9144
 
9023
9145
  // ../engine/src/services/softwareEncoderThreads.ts
9024
9146
  import { availableParallelism } from "os";
9025
- function appendSoftwareEncoderThreadsArg(args, parallelism = availableParallelism()) {
9026
- args.push("-threads", String(Math.max(1, Math.floor(parallelism))));
9147
+ var X265_MAX_THREADS = 16;
9148
+ function appendSoftwareEncoderThreadsArg(args, encoder, parallelism = availableParallelism()) {
9149
+ const cap = encoder === "libx265" ? X265_MAX_THREADS : Infinity;
9150
+ args.push("-threads", String(Math.min(cap, Math.max(1, Math.floor(parallelism)))));
9027
9151
  }
9028
9152
 
9029
9153
  // ../engine/src/utils/renderProvenance.ts
@@ -9250,7 +9374,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
9250
9374
  } else {
9251
9375
  const encoderName = codec === "h264" ? "libx264" : "libx265";
9252
9376
  args.push("-c:v", encoderName, "-preset", preset);
9253
- appendSoftwareEncoderThreadsArg(args);
9377
+ appendSoftwareEncoderThreadsArg(args, encoderName);
9254
9378
  if (bitrate) args.push("-b:v", bitrate);
9255
9379
  else args.push("-crf", String(quality));
9256
9380
  const gop = resolveLockedGopSize(options);
@@ -9955,7 +10079,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
9955
10079
  } else {
9956
10080
  const encoderName = codec === "h264" ? "libx264" : "libx265";
9957
10081
  args.push("-c:v", encoderName, "-preset", preset);
9958
- appendSoftwareEncoderThreadsArg(args);
10082
+ appendSoftwareEncoderThreadsArg(args, encoderName);
9959
10083
  if (bitrate) args.push("-b:v", bitrate);
9960
10084
  else args.push("-crf", String(quality));
9961
10085
  const lockedGop = resolveLockedGopSize(options);
@@ -11379,7 +11503,7 @@ function getSingleMeaningfulChild(container) {
11379
11503
  }
11380
11504
  function unwrapTemplate(html) {
11381
11505
  const lowered = html.toLowerCase();
11382
- if (!lowered.includes("<template") || !lowered.includes("</template>")) {
11506
+ if (!lowered.includes("<template") || !/<\/template[ \t\n\r\f]*>/.test(lowered)) {
11383
11507
  return html;
11384
11508
  }
11385
11509
  const { body } = parseHTMLContent(html);
@@ -11473,7 +11597,7 @@ function isTargetExistsRenameError(err) {
11473
11597
  return code === "EEXIST" || code === "ENOTEMPTY" || code === "EPERM";
11474
11598
  }
11475
11599
  function adoptPublishedWinner(entry, partialDir) {
11476
- if (!existsSync8(join9(entry.dir, COMPLETE_SENTINEL))) return null;
11600
+ if (!existsSync8(join9(entry.dir, COMPLETE_SENTINEL)) || !hasFrameFiles(entry.dir)) return null;
11477
11601
  removeDir(partialDir);
11478
11602
  return { dir: entry.dir, published: true };
11479
11603
  }
@@ -15167,6 +15291,7 @@ function legacyFilterScriptOptionIsUnsupported(stderr) {
15167
15291
  return /filter_complex_script/i.test(stderr) && /(?:unrecognized option|option (?:was )?not found)/i.test(stderr);
15168
15292
  }
15169
15293
  var inPrepareSlot = createConcurrencyLimit(Math.max(2, Math.floor(cpus2().length / 2)));
15294
+ var inRemotePrepareSlot = createConcurrencyLimit(16);
15170
15295
  var MAX_VOLUME_SEGMENTS = 32;
15171
15296
  var VOLUME_SIMPLIFY_EPSILON = 5e-3;
15172
15297
  var STEREO_CHANNEL_FILTER = "pan=stereo|FL=FL+FC|FR=FR+FC";
@@ -15383,8 +15508,11 @@ function parseAudioElements(html) {
15383
15508
  const startCache = /* @__PURE__ */ new Map();
15384
15509
  const visiting = /* @__PURE__ */ new Set();
15385
15510
  const resolveStart = (el) => el.getAttribute("data-start") ? resolveReferencedStart(document2, el, startCache, visiting) : 0;
15386
- const parseEnd = (raw) => {
15387
- return parseStrictFiniteTimingNumber(raw) ?? 0;
15511
+ const resolveEnd = (el) => {
15512
+ const end = parseStrictFiniteTimingNumber(el.getAttribute("data-end"));
15513
+ if (end != null) return end;
15514
+ const duration = parseStrictFiniteTimingNumber(el.getAttribute("data-duration"));
15515
+ return duration != null && duration > 0 ? resolveStart(el) + duration : 0;
15388
15516
  };
15389
15517
  const isHidden = isSelfOrAncestorHidden;
15390
15518
  const groupsById = new Map(
@@ -15403,9 +15531,10 @@ function parseAudioElements(html) {
15403
15531
  id,
15404
15532
  src,
15405
15533
  start: resolveStart(el),
15406
- end: parseEnd(el.getAttribute("data-end")),
15534
+ end: resolveEnd(el),
15407
15535
  mediaStart: readMediaStart(el),
15408
15536
  playbackRate: readElementRateSpec(el),
15537
+ loop: el.getAttribute("loop") !== null,
15409
15538
  layer: layerAttr ? parseInt(layerAttr) : 0,
15410
15539
  volume: volumeAttr ? parseFloat(volumeAttr) : 1,
15411
15540
  ...fades.fadeIn > 0 ? { fadeIn: fades.fadeIn } : {},
@@ -15440,7 +15569,8 @@ function parseAudioElements(html) {
15440
15569
  return elements;
15441
15570
  }
15442
15571
  var FAIL_ON_READ_ERROR_INSTEAD_OF_ENDING_THERE = ["-xerror"];
15443
- async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, duration, playbackRate = 1, signal, config) {
15572
+ var SIDECAR_WARM_UP_SECONDS = 1;
15573
+ async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, duration, playbackRate = 1, signal, config, audioSidecarUrl, options) {
15444
15574
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
15445
15575
  const outputDir = dirname7(outputPath);
15446
15576
  if (!existsSync11(outputDir)) mkdirSync7(outputDir, { recursive: true });
@@ -15450,25 +15580,86 @@ async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, durat
15450
15580
  const metadata = readsUrl ? await extractAudioMetadata(srcPath, { signal }).catch((error) => {
15451
15581
  if (signal?.aborted) throw error;
15452
15582
  return extractAudioMetadata(srcPath, { signal });
15453
- }) : await extractAudioMetadata(srcPath).catch(() => null);
15583
+ }) : await extractAudioMetadata(srcPath).catch((error) => {
15584
+ if (options?.loop) throw error;
15585
+ return null;
15586
+ });
15587
+ const loopDuration = (metadata?.durationSeconds ?? 0) - mediaStart;
15588
+ if (options?.loop && loopDuration > 0 && sourceDuration > loopDuration) {
15589
+ const cycleDir = mkdtempSync7(join14(outputDir, ".audio-loop-"));
15590
+ const cyclePath = join14(cycleDir, "cycle.wav");
15591
+ try {
15592
+ const cycle = await extractAudioSegment(
15593
+ srcPath,
15594
+ cyclePath,
15595
+ stage,
15596
+ mediaStart,
15597
+ loopDuration,
15598
+ 1,
15599
+ signal,
15600
+ config,
15601
+ audioSidecarUrl,
15602
+ { padToDuration: true }
15603
+ );
15604
+ if (!cycle.success) return { ...cycle, outputPath };
15605
+ const outputArgs2 = preparedAudioOutputArgs(metadata, normalizedPlaybackRate, duration, null);
15606
+ const result2 = await runFfmpeg(
15607
+ [
15608
+ "-stream_loop",
15609
+ "-1",
15610
+ "-t",
15611
+ String(sourceDuration),
15612
+ "-i",
15613
+ cyclePath,
15614
+ "-vn",
15615
+ "-acodec",
15616
+ "pcm_s16le",
15617
+ "-ar",
15618
+ "48000",
15619
+ ...outputArgs2,
15620
+ "-t",
15621
+ String(duration),
15622
+ "-y",
15623
+ outputPath
15624
+ ],
15625
+ { signal, timeout: ffmpegProcessTimeout }
15626
+ );
15627
+ const failure2 = result2.success ? void 0 : ffmpegFailure(stage, result2, ffmpegProcessTimeout);
15628
+ return {
15629
+ success: result2.success,
15630
+ outputPath,
15631
+ durationMs: cycle.durationMs + result2.durationMs,
15632
+ error: failure2?.detail,
15633
+ failure: failure2
15634
+ };
15635
+ } finally {
15636
+ rmSync8(cycleDir, { recursive: true, force: true });
15637
+ }
15638
+ }
15454
15639
  const inputSeek = mediaStart >= (metadata?.latestStreamLeadSeconds ?? 0);
15455
15640
  const start = formatFilterNumber(mediaStart);
15456
15641
  const timestampTrim = inputSeek ? null : `atrim=start=${start}:end=${formatFilterNumber(mediaStart + sourceDuration)},asetpts=PTS-${start}/TB,aresample=async=1:first_pts=0`;
15642
+ const fromSidecar = audioSidecarUrl !== void 0 && inputSeek && normalizedPlaybackRate === 1;
15643
+ const warmUp = fromSidecar ? Math.min(SIDECAR_WARM_UP_SECONDS, mediaStart) : 0;
15457
15644
  const outputArgs = preparedAudioOutputArgs(
15458
15645
  metadata,
15459
15646
  normalizedPlaybackRate,
15460
15647
  duration,
15461
- timestampTrim
15648
+ [
15649
+ warmUp > 0 ? `atrim=start=${warmUp},asetpts=PTS-STARTPTS` : timestampTrim,
15650
+ ...options?.padToDuration ? ["apad"] : []
15651
+ ].filter(Boolean).join(",") || null
15462
15652
  );
15653
+ const readFrom = fromSidecar ? audioSidecarUrl : srcPath;
15463
15654
  const args = [
15464
15655
  ...readsUrl ? FAIL_ON_READ_ERROR_INSTEAD_OF_ENDING_THERE : [],
15465
- ...urlInputArgs(srcPath),
15466
- ...inputSeek ? ["-ss", String(mediaStart), "-t", String(sourceDuration)] : [],
15656
+ ...urlInputArgs(readFrom),
15657
+ ...inputSeek ? ["-ss", String(mediaStart - warmUp), "-t", String(sourceDuration + warmUp)] : [],
15467
15658
  "-i",
15468
- srcPath
15659
+ readFrom
15469
15660
  ];
15470
15661
  args.push("-vn", "-acodec", "pcm_s16le", "-ar", "48000", ...outputArgs);
15471
- if (normalizedPlaybackRate !== 1) args.push("-t", String(duration));
15662
+ if (normalizedPlaybackRate !== 1 || options?.padToDuration) args.push("-t", String(duration));
15472
15663
  args.push("-y", outputPath);
15473
15664
  const result = await runFfmpeg(args, { signal, timeout: ffmpegProcessTimeout });
15474
15665
  if (signal?.aborted) {
@@ -15500,6 +15691,17 @@ async function extractAudioSegment(srcPath, outputPath, stage, mediaStart, durat
15500
15691
  failure
15501
15692
  };
15502
15693
  }
15694
+ function isRemoteElement(element, baseDir, compiledDir, config) {
15695
+ if (isHttpUrl(element.src)) return true;
15696
+ if (!config?.urlByAbsentLocalPath?.size) return false;
15697
+ try {
15698
+ return config.urlByAbsentLocalPath.has(
15699
+ resolveProjectRelativeSrc(element.src, baseDir, compiledDir)
15700
+ );
15701
+ } catch {
15702
+ return false;
15703
+ }
15704
+ }
15503
15705
  async function generateSilence(outputPath, duration, signal, config) {
15504
15706
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
15505
15707
  const outputDir = dirname7(outputPath);
@@ -15894,7 +16096,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
15894
16096
  }
15895
16097
  await Promise.all(
15896
16098
  elements.map(
15897
- (element, index) => inPrepareSlot(async () => {
16099
+ (element, index) => (isRemoteElement(element, baseDir, compiledDir, config) ? inRemotePrepareSlot : inPrepareSlot)(async () => {
15898
16100
  if (effectiveSignal.aborted) {
15899
16101
  failures.push({
15900
16102
  stage: "cancelled",
@@ -15909,10 +16111,12 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
15909
16111
  try {
15910
16112
  let srcPath = element.src;
15911
16113
  let readInPlace = false;
16114
+ let audioSidecarUrl;
15912
16115
  if (!isHttpUrl(srcPath)) {
15913
16116
  srcPath = resolveProjectRelativeSrc(element.src, baseDir, compiledDir);
15914
16117
  const remoteUrl = config?.urlByAbsentLocalPath?.get(srcPath);
15915
16118
  if (remoteUrl) {
16119
+ audioSidecarUrl = config?.audioSidecarUrlByLocalPath?.get(srcPath);
15916
16120
  srcPath = remoteUrl;
15917
16121
  readInPlace = true;
15918
16122
  }
@@ -15961,6 +16165,9 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
15961
16165
  return;
15962
16166
  }
15963
16167
  if (element.end - element.start <= 0) {
16168
+ console.warn(
16169
+ `[audioMixer] ${element.id} has no data-duration or data-end; its length is unknown, so it plays to the end of its source`
16170
+ );
15964
16171
  let metadata;
15965
16172
  try {
15966
16173
  metadata = await extractAudioMetadata(
@@ -15990,7 +16197,9 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
15990
16197
  element.end - element.start,
15991
16198
  element.playbackRate,
15992
16199
  effectiveSignal,
15993
- config
16200
+ config,
16201
+ audioSidecarUrl,
16202
+ { loop: element.loop }
15994
16203
  );
15995
16204
  if (!extractResult.success) {
15996
16205
  failures.push(
@@ -16016,7 +16225,9 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
16016
16225
  element.end - element.start,
16017
16226
  element.playbackRate,
16018
16227
  effectiveSignal,
16019
- config
16228
+ config,
16229
+ void 0,
16230
+ { loop: element.loop }
16020
16231
  );
16021
16232
  if (!prepResult.success) {
16022
16233
  failures.push(
@@ -17535,6 +17746,7 @@ export {
17535
17746
  formatFfmpegError,
17536
17747
  describeFfmpegFailure,
17537
17748
  runFfmpeg,
17749
+ declareContentAddressedUrl,
17538
17750
  probeMediaProfile,
17539
17751
  extractMediaMetadata,
17540
17752
  extractFinalVideoFrameTimestamp,
@@ -17589,6 +17801,7 @@ export {
17589
17801
  extractVideoFramesRange,
17590
17802
  resolvePlayableVideoDuration,
17591
17803
  isVideoPastTimelineEnd,
17804
+ rebaseVideoToWindow,
17592
17805
  resolveTimelineExtractionWindow,
17593
17806
  resolveFinalFrameExtractionWindow,
17594
17807
  resolveVideoExtractionWindow,
@@ -6,7 +6,7 @@ var __filename = __hf_fileURLToPath(import.meta.url);
6
6
  var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  findCompositionDimensions
9
- } from "./chunk-ZFFKWHXN.js";
9
+ } from "./chunk-WOKVXK4J.js";
10
10
  import {
11
11
  c
12
12
  } from "./chunk-ZTZA4UWZ.js";
@@ -7,7 +7,7 @@ var __dirname = __hf_dirname(__filename);
7
7
  import {
8
8
  VALID_CANVAS_RESOLUTIONS,
9
9
  resolveResolutionFlagPair
10
- } from "./chunk-B2A56S5C.js";
10
+ } from "./chunk-2MCXIY4B.js";
11
11
 
12
12
  // src/utils/parseOutputResolution.ts
13
13
  function parseOutputResolutionFlag(raw, options) {