@omnimedia/omnitool 1.1.0-7 → 1.1.0-70

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 (410) hide show
  1. package/README.md +143 -80
  2. package/package.json +18 -17
  3. package/s/context.ts +0 -7
  4. package/s/demo/demo.bundle.ts +104 -43
  5. package/s/demo/demo.css +244 -14
  6. package/s/demo/routines/export-test.ts +16 -0
  7. package/s/demo/routines/filmstrip-test.ts +22 -18
  8. package/s/demo/routines/load-video.ts +2 -3
  9. package/s/demo/routines/playback-test.ts +61 -0
  10. package/s/demo/routines/timeline-setup.ts +24 -0
  11. package/s/demo/routines/transcode-test.ts +19 -5
  12. package/s/demo/routines/transitions-test.ts +2 -2
  13. package/s/demo/routines/waveform-test.ts +35 -8
  14. package/s/driver/driver-worker.ts +9 -0
  15. package/s/driver/driver.test.ts +1 -1
  16. package/s/driver/driver.ts +43 -42
  17. package/s/driver/fns/schematic.ts +11 -5
  18. package/s/driver/fns/work.ts +65 -189
  19. package/s/driver/parts/compositor.ts +187 -0
  20. package/s/driver/parts/machina.ts +19 -20
  21. package/s/index.html.ts +103 -25
  22. package/s/index.ts +1 -0
  23. package/s/tests.bundle.ts +11 -0
  24. package/s/tests.html.ts +28 -0
  25. package/s/timeline/index.ts +5 -0
  26. package/s/timeline/parts/filmstrip.ts +43 -16
  27. package/s/timeline/parts/item.ts +27 -6
  28. package/s/timeline/parts/media.ts +12 -2
  29. package/s/timeline/parts/resource-pool.ts +8 -5
  30. package/s/timeline/parts/resource.ts +3 -0
  31. package/s/timeline/parts/waveform/parts/collect.ts +72 -0
  32. package/s/timeline/parts/waveform/parts/render.ts +45 -0
  33. package/s/timeline/parts/waveform/parts/types.ts +24 -0
  34. package/s/timeline/parts/waveform/waveform.ts +161 -0
  35. package/s/timeline/renderers/export/parts/audio-gain.ts +17 -0
  36. package/s/timeline/renderers/export/parts/audio-mix.ts +133 -0
  37. package/s/timeline/renderers/export/parts/cursor.ts +129 -0
  38. package/s/timeline/renderers/export/parts/produce-audio.ts +64 -0
  39. package/s/timeline/renderers/export/parts/produce-video.ts +49 -0
  40. package/s/timeline/renderers/export/parts/resamplers.ts +48 -0
  41. package/s/timeline/renderers/export/produce.ts +28 -0
  42. package/s/timeline/renderers/parts/handy.ts +360 -0
  43. package/s/timeline/renderers/parts/samplers/audio/parts/find.ts +19 -0
  44. package/s/timeline/renderers/parts/samplers/audio/parts/init.ts +60 -0
  45. package/s/timeline/renderers/parts/samplers/audio/parts/sink.ts +38 -0
  46. package/s/timeline/renderers/parts/samplers/audio/parts/types.ts +16 -0
  47. package/s/timeline/renderers/parts/samplers/audio/sampler.ts +35 -0
  48. package/s/timeline/renderers/parts/samplers/visual/parts/defaults.ts +16 -0
  49. package/s/timeline/renderers/parts/samplers/visual/parts/sample.ts +59 -0
  50. package/s/timeline/renderers/parts/samplers/visual/parts/sequence.ts +111 -0
  51. package/s/timeline/renderers/parts/samplers/visual/parts/sink.ts +38 -0
  52. package/s/timeline/renderers/parts/samplers/visual/parts/transition.ts +28 -0
  53. package/s/timeline/renderers/parts/samplers/visual/parts/types.ts +10 -0
  54. package/s/timeline/renderers/parts/samplers/visual/sampler.ts +28 -0
  55. package/s/timeline/renderers/parts/schedulers.ts +96 -0
  56. package/s/timeline/renderers/player/parts/playback.ts +159 -0
  57. package/s/timeline/renderers/player/player.ts +77 -0
  58. package/s/timeline/renderers/renderers.test.ts +385 -0
  59. package/s/timeline/sugar/helpers.ts +85 -0
  60. package/s/timeline/sugar/o.ts +138 -57
  61. package/s/timeline/sugar/omni.test.ts +210 -0
  62. package/s/timeline/sugar/omni.ts +35 -12
  63. package/s/timeline/utils/checksum.ts +3 -1
  64. package/s/timeline/utils/datafile.ts +15 -4
  65. package/s/timeline/utils/dummy-data.ts +3 -3
  66. package/s/units/fps.ts +8 -0
  67. package/s/units/ms.ts +8 -0
  68. package/s/units/seconds.ts +8 -0
  69. package/x/WebGLRenderer-7X274AYV.js +2 -0
  70. package/x/WebGLRenderer-7X274AYV.js.map +7 -0
  71. package/x/WebGPURenderer-XMCMEXAO.js +2 -0
  72. package/x/WebGPURenderer-XMCMEXAO.js.map +7 -0
  73. package/x/browserAll-6TVTCHHE.js +2 -0
  74. package/x/browserAll-6TVTCHHE.js.map +7 -0
  75. package/x/chunk-4ONWQOPX.js +157 -0
  76. package/x/chunk-4ONWQOPX.js.map +7 -0
  77. package/x/chunk-63NSCXPX.js +2 -0
  78. package/x/chunk-63NSCXPX.js.map +7 -0
  79. package/x/chunk-A45M2HJC.js +2 -0
  80. package/x/chunk-A45M2HJC.js.map +7 -0
  81. package/x/chunk-OTQK6FAJ.js +15 -0
  82. package/x/chunk-OTQK6FAJ.js.map +7 -0
  83. package/x/chunk-Q7JBQNE4.js +42 -0
  84. package/x/chunk-Q7JBQNE4.js.map +7 -0
  85. package/x/chunk-W33LM336.js +393 -0
  86. package/x/chunk-W33LM336.js.map +7 -0
  87. package/x/chunk-W5CN46AR.js +327 -0
  88. package/x/chunk-W5CN46AR.js.map +7 -0
  89. package/x/chunk-WFT3KTZG.js +269 -0
  90. package/x/chunk-WFT3KTZG.js.map +7 -0
  91. package/x/context.d.ts +1 -4
  92. package/x/context.js +1 -5
  93. package/x/context.js.map +1 -1
  94. package/x/demo/WebGLRenderer-NLGJGAXK.js +2 -0
  95. package/x/demo/WebGLRenderer-NLGJGAXK.js.map +7 -0
  96. package/x/demo/WebGPURenderer-RBOFXPL5.js +2 -0
  97. package/x/demo/WebGPURenderer-RBOFXPL5.js.map +7 -0
  98. package/x/demo/browserAll-5AZHDDG6.js +2 -0
  99. package/x/demo/browserAll-5AZHDDG6.js.map +7 -0
  100. package/x/demo/chunk-5ZZYIILO.js +393 -0
  101. package/x/demo/chunk-5ZZYIILO.js.map +7 -0
  102. package/x/demo/chunk-P3PTHHFE.js +42 -0
  103. package/x/demo/chunk-P3PTHHFE.js.map +7 -0
  104. package/x/demo/chunk-PYG4RZZ2.js +269 -0
  105. package/x/demo/chunk-PYG4RZZ2.js.map +7 -0
  106. package/x/demo/chunk-Q4MWBZHL.js +157 -0
  107. package/x/demo/chunk-Q4MWBZHL.js.map +7 -0
  108. package/x/demo/chunk-T3METYEY.js +15 -0
  109. package/x/demo/chunk-T3METYEY.js.map +7 -0
  110. package/x/demo/chunk-USLRKDKD.js +2 -0
  111. package/x/demo/chunk-USLRKDKD.js.map +7 -0
  112. package/x/demo/chunk-YISSXWBT.js +327 -0
  113. package/x/demo/chunk-YISSXWBT.js.map +7 -0
  114. package/x/demo/chunk-YJQWVIHX.js +2 -0
  115. package/x/demo/chunk-YJQWVIHX.js.map +7 -0
  116. package/x/demo/demo.bundle.js +94 -40
  117. package/x/demo/demo.bundle.js.map +1 -1
  118. package/x/demo/demo.bundle.min.js +2421 -81
  119. package/x/demo/demo.bundle.min.js.map +4 -4
  120. package/x/demo/demo.css +244 -14
  121. package/x/demo/routines/export-test.d.ts +2 -0
  122. package/x/demo/routines/export-test.js +10 -0
  123. package/x/demo/routines/export-test.js.map +1 -0
  124. package/x/demo/routines/filmstrip-test.d.ts +1 -1
  125. package/x/demo/routines/filmstrip-test.js +20 -17
  126. package/x/demo/routines/filmstrip-test.js.map +1 -1
  127. package/x/demo/routines/load-video.d.ts +1 -1
  128. package/x/demo/routines/load-video.js +1 -2
  129. package/x/demo/routines/load-video.js.map +1 -1
  130. package/x/demo/routines/playback-test.d.ts +2 -0
  131. package/x/demo/routines/playback-test.js +51 -0
  132. package/x/demo/routines/playback-test.js.map +1 -0
  133. package/x/demo/routines/timeline-setup.d.ts +6 -0
  134. package/x/demo/routines/timeline-setup.js +13 -0
  135. package/x/demo/routines/timeline-setup.js.map +1 -0
  136. package/x/demo/routines/transcode-test.js +15 -5
  137. package/x/demo/routines/transcode-test.js.map +1 -1
  138. package/x/demo/routines/transitions-test.js +2 -2
  139. package/x/demo/routines/transitions-test.js.map +1 -1
  140. package/x/demo/routines/waveform-test.d.ts +2 -1
  141. package/x/demo/routines/waveform-test.js +29 -8
  142. package/x/demo/routines/waveform-test.js.map +1 -1
  143. package/x/demo/webworkerAll-QKIC5O27.js +2 -0
  144. package/x/demo/webworkerAll-QKIC5O27.js.map +7 -0
  145. package/x/driver/driver-worker.d.ts +1 -0
  146. package/x/driver/driver-worker.js +6 -0
  147. package/x/driver/driver-worker.js.map +1 -0
  148. package/x/driver/driver.d.ts +25 -8
  149. package/x/driver/driver.js +43 -39
  150. package/x/driver/driver.js.map +1 -1
  151. package/x/driver/driver.test.js +1 -1
  152. package/x/driver/driver.test.js.map +1 -1
  153. package/x/driver/driver.worker.bundle.min.js +117 -3506
  154. package/x/driver/driver.worker.bundle.min.js.map +4 -4
  155. package/x/driver/fns/host.d.ts +3 -2
  156. package/x/driver/fns/schematic.d.ts +11 -4
  157. package/x/driver/fns/work.d.ts +4 -4
  158. package/x/driver/fns/work.js +55 -155
  159. package/x/driver/fns/work.js.map +1 -1
  160. package/x/driver/parts/compositor.d.ts +20 -0
  161. package/x/driver/parts/compositor.js +159 -0
  162. package/x/driver/parts/compositor.js.map +1 -0
  163. package/x/driver/parts/machina.d.ts +0 -20
  164. package/x/driver/parts/machina.js +6 -10
  165. package/x/driver/parts/machina.js.map +1 -1
  166. package/x/features/speech/transcribe/parts/prep-audio.d.ts +1 -1
  167. package/x/features/speech/transcribe/worker.bundle.min.js +899 -899
  168. package/x/features/speech/transcribe/worker.bundle.min.js.map +4 -4
  169. package/x/index.d.ts +1 -0
  170. package/x/index.html +347 -38
  171. package/x/index.html.js +103 -24
  172. package/x/index.html.js.map +1 -1
  173. package/x/index.js +1 -0
  174. package/x/index.js.map +1 -1
  175. package/x/tests.bundle.js +8 -0
  176. package/x/tests.bundle.js.map +1 -0
  177. package/x/tests.bundle.min.js +2464 -0
  178. package/x/tests.bundle.min.js.map +7 -0
  179. package/x/tests.html +316 -0
  180. package/x/tests.html.d.ts +2 -0
  181. package/x/tests.html.js +22 -0
  182. package/x/tests.html.js.map +1 -0
  183. package/x/timeline/index.d.ts +4 -0
  184. package/x/timeline/index.js +4 -0
  185. package/x/timeline/index.js.map +1 -1
  186. package/x/timeline/parts/filmstrip.d.ts +4 -3
  187. package/x/timeline/parts/filmstrip.js +29 -10
  188. package/x/timeline/parts/filmstrip.js.map +1 -1
  189. package/x/timeline/parts/item.d.ts +20 -3
  190. package/x/timeline/parts/item.js +1 -0
  191. package/x/timeline/parts/item.js.map +1 -1
  192. package/x/timeline/parts/media.d.ts +2 -0
  193. package/x/timeline/parts/media.js +11 -2
  194. package/x/timeline/parts/media.js.map +1 -1
  195. package/x/timeline/parts/resource-pool.d.ts +3 -0
  196. package/x/timeline/parts/resource-pool.js +7 -4
  197. package/x/timeline/parts/resource-pool.js.map +1 -1
  198. package/x/timeline/parts/resource.d.ts +3 -0
  199. package/x/timeline/parts/waveform/parts/collect.d.ts +11 -0
  200. package/x/timeline/parts/waveform/parts/collect.js +56 -0
  201. package/x/timeline/parts/waveform/parts/collect.js.map +1 -0
  202. package/x/timeline/parts/waveform/parts/render.d.ts +5 -0
  203. package/x/timeline/parts/waveform/parts/render.js +29 -0
  204. package/x/timeline/parts/waveform/parts/render.js.map +1 -0
  205. package/x/timeline/parts/waveform/parts/types.d.ts +21 -0
  206. package/x/timeline/parts/waveform/parts/types.js.map +1 -0
  207. package/x/timeline/parts/waveform/waveform.d.ts +19 -0
  208. package/x/timeline/parts/waveform/waveform.js +133 -0
  209. package/x/timeline/parts/waveform/waveform.js.map +1 -0
  210. package/x/timeline/renderers/export/parts/audio-gain.d.ts +1 -0
  211. package/x/timeline/renderers/export/parts/audio-gain.js +13 -0
  212. package/x/timeline/renderers/export/parts/audio-gain.js.map +1 -0
  213. package/x/timeline/renderers/export/parts/audio-mix.d.ts +21 -0
  214. package/x/timeline/renderers/export/parts/audio-mix.js +89 -0
  215. package/x/timeline/renderers/export/parts/audio-mix.js.map +1 -0
  216. package/x/timeline/renderers/export/parts/cursor.d.ts +18 -0
  217. package/x/timeline/renderers/export/parts/cursor.js +99 -0
  218. package/x/timeline/renderers/export/parts/cursor.js.map +1 -0
  219. package/x/timeline/renderers/export/parts/produce-audio.d.ts +6 -0
  220. package/x/timeline/renderers/export/parts/produce-audio.js +41 -0
  221. package/x/timeline/renderers/export/parts/produce-audio.js.map +1 -0
  222. package/x/timeline/renderers/export/parts/produce-video.d.ts +10 -0
  223. package/x/timeline/renderers/export/parts/produce-video.js +26 -0
  224. package/x/timeline/renderers/export/parts/produce-video.js.map +1 -0
  225. package/x/timeline/renderers/export/parts/resamplers.d.ts +12 -0
  226. package/x/timeline/renderers/export/parts/resamplers.js +29 -0
  227. package/x/timeline/renderers/export/parts/resamplers.js.map +1 -0
  228. package/x/timeline/renderers/export/produce.d.ts +13 -0
  229. package/x/timeline/renderers/export/produce.js +15 -0
  230. package/x/timeline/renderers/export/produce.js.map +1 -0
  231. package/x/timeline/renderers/parts/handy.d.ts +30 -0
  232. package/x/timeline/renderers/parts/handy.js +219 -0
  233. package/x/timeline/renderers/parts/handy.js.map +1 -0
  234. package/x/timeline/renderers/parts/samplers/audio/parts/find.d.ts +6 -0
  235. package/x/timeline/renderers/parts/samplers/audio/parts/find.js +15 -0
  236. package/x/timeline/renderers/parts/samplers/audio/parts/find.js.map +1 -0
  237. package/x/timeline/renderers/parts/samplers/audio/parts/init.d.ts +5 -0
  238. package/x/timeline/renderers/parts/samplers/audio/parts/init.js +40 -0
  239. package/x/timeline/renderers/parts/samplers/audio/parts/init.js.map +1 -0
  240. package/x/timeline/renderers/parts/samplers/audio/parts/sink.d.ts +8 -0
  241. package/x/timeline/renderers/parts/samplers/audio/parts/sink.js +24 -0
  242. package/x/timeline/renderers/parts/samplers/audio/parts/sink.js.map +1 -0
  243. package/x/timeline/renderers/parts/samplers/audio/parts/types.d.ts +14 -0
  244. package/x/timeline/renderers/parts/samplers/audio/parts/types.js +2 -0
  245. package/x/timeline/renderers/parts/samplers/audio/parts/types.js.map +1 -0
  246. package/x/timeline/renderers/parts/samplers/audio/sampler.d.ts +11 -0
  247. package/x/timeline/renderers/parts/samplers/audio/sampler.js +22 -0
  248. package/x/timeline/renderers/parts/samplers/audio/sampler.js.map +1 -0
  249. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.d.ts +5 -0
  250. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.js +10 -0
  251. package/x/timeline/renderers/parts/samplers/visual/parts/defaults.js.map +1 -0
  252. package/x/timeline/renderers/parts/samplers/visual/parts/sample.d.ts +5 -0
  253. package/x/timeline/renderers/parts/samplers/visual/parts/sample.js +38 -0
  254. package/x/timeline/renderers/parts/samplers/visual/parts/sample.js.map +1 -0
  255. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.d.ts +5 -0
  256. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.js +75 -0
  257. package/x/timeline/renderers/parts/samplers/visual/parts/sequence.js.map +1 -0
  258. package/x/timeline/renderers/parts/samplers/visual/parts/sink.d.ts +8 -0
  259. package/x/timeline/renderers/parts/samplers/visual/parts/sink.js +24 -0
  260. package/x/timeline/renderers/parts/samplers/visual/parts/sink.js.map +1 -0
  261. package/x/timeline/renderers/parts/samplers/visual/parts/transition.d.ts +3 -0
  262. package/x/timeline/renderers/parts/samplers/visual/parts/transition.js +18 -0
  263. package/x/timeline/renderers/parts/samplers/visual/parts/transition.js.map +1 -0
  264. package/x/timeline/renderers/parts/samplers/visual/parts/types.d.ts +8 -0
  265. package/x/timeline/renderers/parts/samplers/visual/parts/types.js +2 -0
  266. package/x/timeline/renderers/parts/samplers/visual/parts/types.js.map +1 -0
  267. package/x/timeline/renderers/parts/samplers/visual/sampler.d.ts +7 -0
  268. package/x/timeline/renderers/parts/samplers/visual/sampler.js +17 -0
  269. package/x/timeline/renderers/parts/samplers/visual/sampler.js.map +1 -0
  270. package/x/timeline/renderers/parts/schedulers.d.ts +17 -0
  271. package/x/timeline/renderers/parts/schedulers.js +64 -0
  272. package/x/timeline/renderers/parts/schedulers.js.map +1 -0
  273. package/x/timeline/renderers/player/parts/playback.d.ts +36 -0
  274. package/x/timeline/renderers/player/parts/playback.js +113 -0
  275. package/x/timeline/renderers/player/parts/playback.js.map +1 -0
  276. package/x/timeline/renderers/player/player.d.ts +25 -0
  277. package/x/timeline/renderers/player/player.js +56 -0
  278. package/x/timeline/renderers/player/player.js.map +1 -0
  279. package/x/timeline/renderers/renderers.test.d.ts +32 -0
  280. package/x/timeline/renderers/renderers.test.js +305 -0
  281. package/x/timeline/renderers/renderers.test.js.map +1 -0
  282. package/x/timeline/sugar/helpers.d.ts +30 -0
  283. package/x/timeline/sugar/helpers.js +46 -0
  284. package/x/timeline/sugar/helpers.js.map +1 -0
  285. package/x/timeline/sugar/o.d.ts +28 -13
  286. package/x/timeline/sugar/o.js +108 -51
  287. package/x/timeline/sugar/o.js.map +1 -1
  288. package/x/timeline/sugar/omni.d.ts +11 -6
  289. package/x/timeline/sugar/omni.js +28 -8
  290. package/x/timeline/sugar/omni.js.map +1 -1
  291. package/x/timeline/sugar/omni.test.d.ts +27 -0
  292. package/x/timeline/sugar/omni.test.js +128 -0
  293. package/x/timeline/sugar/omni.test.js.map +1 -0
  294. package/x/timeline/utils/checksum.d.ts +3 -2
  295. package/x/timeline/utils/checksum.js.map +1 -1
  296. package/x/timeline/utils/datafile.d.ts +5 -3
  297. package/x/timeline/utils/datafile.js +18 -5
  298. package/x/timeline/utils/datafile.js.map +1 -1
  299. package/x/timeline/utils/dummy-data.d.ts +1 -2
  300. package/x/timeline/utils/dummy-data.js +4 -2
  301. package/x/timeline/utils/dummy-data.js.map +1 -1
  302. package/x/units/fps.d.ts +6 -0
  303. package/x/units/fps.js +2 -0
  304. package/x/units/fps.js.map +1 -0
  305. package/x/units/ms.d.ts +6 -0
  306. package/x/units/ms.js +2 -0
  307. package/x/units/ms.js.map +1 -0
  308. package/x/units/seconds.d.ts +6 -0
  309. package/x/units/seconds.js +2 -0
  310. package/x/units/seconds.js.map +1 -0
  311. package/x/webworkerAll-VVIU3M54.js +2 -0
  312. package/x/webworkerAll-VVIU3M54.js.map +7 -0
  313. package/s/tests.test.ts +0 -8
  314. package/s/timeline/parts/compositor/export.ts +0 -77
  315. package/s/timeline/parts/compositor/parts/html-tree.ts +0 -37
  316. package/s/timeline/parts/compositor/parts/schedulers.ts +0 -85
  317. package/s/timeline/parts/compositor/parts/tree-builder.ts +0 -184
  318. package/s/timeline/parts/compositor/parts/webcodecs-tree.ts +0 -30
  319. package/s/timeline/parts/compositor/playback.ts +0 -81
  320. package/s/timeline/parts/compositor/samplers/html.ts +0 -115
  321. package/s/timeline/parts/compositor/samplers/webcodecs.ts +0 -60
  322. package/s/timeline/parts/waveform.ts +0 -62
  323. package/s/timeline/sugar/builders.ts +0 -102
  324. package/s/timeline/sugar/omni-test.ts +0 -38
  325. package/s/timeline/timeline.ts +0 -22
  326. package/s/timeline/utils/audio-stream.ts +0 -15
  327. package/s/timeline/utils/video-cursor.ts +0 -40
  328. package/s/tools/common/loader.ts +0 -26
  329. package/s/tools/common/transformer-pipeline.ts +0 -26
  330. package/s/tools/speech-recognition/common/model.ts +0 -26
  331. package/s/tools/speech-recognition/whisper/fns/host.ts +0 -25
  332. package/s/tools/speech-recognition/whisper/fns/schematic.ts +0 -23
  333. package/s/tools/speech-recognition/whisper/fns/work.ts +0 -91
  334. package/s/tools/speech-recognition/whisper/parts/types.ts +0 -38
  335. package/s/tools/speech-recognition/whisper/parts/worker.bundle.ts +0 -7
  336. package/s/tools/speech-recognition/whisper/tool.ts +0 -70
  337. package/x/tests.test.js +0 -6
  338. package/x/tests.test.js.map +0 -1
  339. package/x/timeline/parts/compositor/export.d.ts +0 -9
  340. package/x/timeline/parts/compositor/export.js +0 -64
  341. package/x/timeline/parts/compositor/export.js.map +0 -1
  342. package/x/timeline/parts/compositor/parts/html-tree.d.ts +0 -3
  343. package/x/timeline/parts/compositor/parts/html-tree.js +0 -40
  344. package/x/timeline/parts/compositor/parts/html-tree.js.map +0 -1
  345. package/x/timeline/parts/compositor/parts/schedulers.d.ts +0 -15
  346. package/x/timeline/parts/compositor/parts/schedulers.js +0 -64
  347. package/x/timeline/parts/compositor/parts/schedulers.js.map +0 -1
  348. package/x/timeline/parts/compositor/parts/tree-builder.d.ts +0 -37
  349. package/x/timeline/parts/compositor/parts/tree-builder.js +0 -147
  350. package/x/timeline/parts/compositor/parts/tree-builder.js.map +0 -1
  351. package/x/timeline/parts/compositor/parts/webcodecs-tree.d.ts +0 -3
  352. package/x/timeline/parts/compositor/parts/webcodecs-tree.js +0 -28
  353. package/x/timeline/parts/compositor/parts/webcodecs-tree.js.map +0 -1
  354. package/x/timeline/parts/compositor/playback.d.ts +0 -19
  355. package/x/timeline/parts/compositor/playback.js +0 -71
  356. package/x/timeline/parts/compositor/playback.js.map +0 -1
  357. package/x/timeline/parts/compositor/samplers/html.d.ts +0 -3
  358. package/x/timeline/parts/compositor/samplers/html.js +0 -106
  359. package/x/timeline/parts/compositor/samplers/html.js.map +0 -1
  360. package/x/timeline/parts/compositor/samplers/webcodecs.d.ts +0 -2
  361. package/x/timeline/parts/compositor/samplers/webcodecs.js +0 -55
  362. package/x/timeline/parts/compositor/samplers/webcodecs.js.map +0 -1
  363. package/x/timeline/parts/waveform.d.ts +0 -8
  364. package/x/timeline/parts/waveform.js +0 -51
  365. package/x/timeline/parts/waveform.js.map +0 -1
  366. package/x/timeline/sugar/builders.d.ts +0 -96
  367. package/x/timeline/sugar/builders.js +0 -108
  368. package/x/timeline/sugar/builders.js.map +0 -1
  369. package/x/timeline/sugar/omni-test.d.ts +0 -1
  370. package/x/timeline/sugar/omni-test.js +0 -22
  371. package/x/timeline/sugar/omni-test.js.map +0 -1
  372. package/x/timeline/timeline.d.ts +0 -9
  373. package/x/timeline/timeline.js +0 -22
  374. package/x/timeline/timeline.js.map +0 -1
  375. package/x/timeline/utils/audio-stream.d.ts +0 -6
  376. package/x/timeline/utils/audio-stream.js +0 -17
  377. package/x/timeline/utils/audio-stream.js.map +0 -1
  378. package/x/timeline/utils/video-cursor.d.ts +0 -10
  379. package/x/timeline/utils/video-cursor.js +0 -36
  380. package/x/timeline/utils/video-cursor.js.map +0 -1
  381. package/x/tools/common/loader.d.ts +0 -19
  382. package/x/tools/common/loader.js +0 -18
  383. package/x/tools/common/loader.js.map +0 -1
  384. package/x/tools/common/transformer-pipeline.d.ts +0 -8
  385. package/x/tools/common/transformer-pipeline.js +0 -24
  386. package/x/tools/common/transformer-pipeline.js.map +0 -1
  387. package/x/tools/speech-recognition/common/model.d.ts +0 -14
  388. package/x/tools/speech-recognition/common/model.js +0 -16
  389. package/x/tools/speech-recognition/common/model.js.map +0 -1
  390. package/x/tools/speech-recognition/whisper/fns/host.d.ts +0 -13
  391. package/x/tools/speech-recognition/whisper/fns/host.js +0 -19
  392. package/x/tools/speech-recognition/whisper/fns/host.js.map +0 -1
  393. package/x/tools/speech-recognition/whisper/fns/schematic.d.ts +0 -19
  394. package/x/tools/speech-recognition/whisper/fns/schematic.js +0 -2
  395. package/x/tools/speech-recognition/whisper/fns/schematic.js.map +0 -1
  396. package/x/tools/speech-recognition/whisper/fns/work.d.ts +0 -12
  397. package/x/tools/speech-recognition/whisper/fns/work.js +0 -74
  398. package/x/tools/speech-recognition/whisper/fns/work.js.map +0 -1
  399. package/x/tools/speech-recognition/whisper/parts/types.d.ts +0 -31
  400. package/x/tools/speech-recognition/whisper/parts/types.js.map +0 -1
  401. package/x/tools/speech-recognition/whisper/parts/worker.bundle.d.ts +0 -1
  402. package/x/tools/speech-recognition/whisper/parts/worker.bundle.js +0 -4
  403. package/x/tools/speech-recognition/whisper/parts/worker.bundle.js.map +0 -1
  404. package/x/tools/speech-recognition/whisper/parts/worker.bundle.min.js +0 -8
  405. package/x/tools/speech-recognition/whisper/parts/worker.bundle.min.js.map +0 -7
  406. package/x/tools/speech-recognition/whisper/tool.d.ts +0 -12
  407. package/x/tools/speech-recognition/whisper/tool.js +0 -63
  408. package/x/tools/speech-recognition/whisper/tool.js.map +0 -1
  409. /package/x/{tests.test.d.ts → tests.bundle.d.ts} +0 -0
  410. /package/x/{tools/speech-recognition/whisper → timeline/parts/waveform}/parts/types.js +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../node_modules/gl-transitions/index.js", "../node_modules/@e280/science/s/parts/index.ts", "../node_modules/@e280/science/s/parts/execution/utils.ts", "../node_modules/@e280/science/s/parts/expectation/errors.ts", "../node_modules/@e280/science/s/parts/expectation/expectations.ts", "../node_modules/@e280/science/s/parts/expectation/utils.ts", "../node_modules/@e280/science/s/parts/types.ts", "../node_modules/@e280/science/s/parts/execution/flatten-tests.ts", "../node_modules/@e280/science/s/parts/execution/execute.ts", "../node_modules/@e280/science/s/parts/expectation/expect.ts", "../node_modules/@e280/science/s/parts/presentation/coloring.ts", "../node_modules/@e280/science/s/parts/presentation/types.ts", "../node_modules/@e280/science/s/parts/presentation/supports.ts", "../node_modules/@e280/science/s/parts/presentation/deliver.ts", "../node_modules/@e280/science/s/parts/presentation/summarize.ts", "../node_modules/@e280/science/s/parts/presentation/themes.ts", "../node_modules/@e280/science/s/parts/spycraft/spy.ts", "../node_modules/@e280/science/s/parts/running/get-args.ts", "../node_modules/@e280/science/s/parts/running/consider-color-support.ts", "../node_modules/@e280/science/s/parts/run.ts", "../node_modules/@e280/science/s/parts/test.ts", "../node_modules/@e280/science/s/parts/tests.ts", "../node_modules/@e280/stz/s/data/bytes.ts", "../node_modules/@e280/stz/s/data/base-x.ts", "../node_modules/@e280/stz/s/data/base-x-codecs.ts", "../node_modules/@e280/stz/s/data/bytename/utils/prefixes.ts", "../node_modules/@e280/stz/s/data/bytename/utils/suffixes.ts", "../node_modules/@e280/stz/s/data/bytename/bytename.ts", "../node_modules/@e280/stz/s/data/bytename/thumbprint.ts", "../node_modules/@e280/stz/s/data/legacy/hex.ts", "../node_modules/@e280/stz/s/defer.ts", "../node_modules/@e280/stz/s/is.ts", "../node_modules/@e280/stz/s/g/map.ts", "../node_modules/@e280/stz/s/deadline.ts", "../node_modules/@e280/stz/s/disposer.ts", "../node_modules/@e280/stz/s/drill.ts", "../node_modules/@e280/stz/s/pubsub.ts", "../s/timeline/parts/item.ts", "../s/timeline/sugar/o.ts", "../s/units/fps.ts", "../node_modules/mediabunny/dist/modules/src/misc.js", "../node_modules/mediabunny/dist/modules/src/metadata.js", "../node_modules/mediabunny/dist/modules/src/codec.js", "../node_modules/mediabunny/dist/modules/src/codec-data.js", "../node_modules/mediabunny/dist/modules/src/demuxer.js", "../node_modules/mediabunny/dist/modules/src/custom-coder.js", "../node_modules/mediabunny/dist/modules/src/packet.js", "../node_modules/mediabunny/dist/modules/src/pcm.js", "../node_modules/mediabunny/dist/modules/src/sample.js", "../node_modules/mediabunny/dist/modules/src/media-sink.js", "../node_modules/mediabunny/dist/modules/src/input-track.js", "../node_modules/mediabunny/dist/modules/src/isobmff/isobmff-misc.js", "../node_modules/mediabunny/dist/modules/src/isobmff/isobmff-reader.js", "../node_modules/mediabunny/dist/modules/src/isobmff/isobmff-demuxer.js", "../node_modules/mediabunny/dist/modules/src/matroska/ebml.js", "../node_modules/mediabunny/dist/modules/src/matroska/matroska-misc.js", "../node_modules/mediabunny/dist/modules/src/matroska/matroska-demuxer.js", "../node_modules/mediabunny/dist/modules/shared/mp3-misc.js", "../node_modules/mediabunny/dist/modules/src/id3.js", "../node_modules/mediabunny/dist/modules/src/mp3/mp3-reader.js", "../node_modules/mediabunny/dist/modules/src/mp3/mp3-demuxer.js", "../node_modules/mediabunny/dist/modules/src/ogg/ogg-misc.js", "../node_modules/mediabunny/dist/modules/src/ogg/ogg-reader.js", "../node_modules/mediabunny/dist/modules/src/ogg/ogg-demuxer.js", "../node_modules/mediabunny/dist/modules/src/wave/wave-demuxer.js", "../node_modules/mediabunny/dist/modules/src/adts/adts-reader.js", "../node_modules/mediabunny/dist/modules/src/adts/adts-demuxer.js", "../node_modules/mediabunny/dist/modules/src/flac/flac-misc.js", "../node_modules/mediabunny/dist/modules/src/flac/flac-demuxer.js", "../node_modules/mediabunny/dist/modules/src/input-format.js", "../node_modules/mediabunny/dist/modules/src/source.js", "../node_modules/mediabunny/dist/modules/src/input.js", "../node_modules/mediabunny/dist/modules/src/reader.js", "../s/driver/utils/load-decoder-source.ts", "../s/timeline/parts/media.ts", "../s/timeline/parts/resource-pool.ts", "../s/units/ms.ts", "../s/timeline/renderers/parts/schedulers.ts", "../node_modules/pixi.js/src/environment-browser/browserExt.ts", "../node_modules/pixi.js/src/environment-webworker/webworkerExt.ts", "../node_modules/pixi.js/src/utils/browser/isWebGLSupported.ts", "../node_modules/pixi.js/src/utils/browser/isWebGPUSupported.ts", "../node_modules/pixi.js/src/rendering/renderers/autoDetectRenderer.ts", "../node_modules/pixi.js/src/scene/text/AbstractText.ts", "../node_modules/pixi.js/src/scene/text/Text.ts", "../node_modules/pixi.js/src/index.ts", "../s/timeline/utils/matrix.ts", "../s/timeline/renderers/parts/handy.ts", "../s/units/seconds.ts", "../s/timeline/renderers/parts/samplers/visual/parts/sink.ts", "../s/timeline/renderers/parts/samplers/visual/parts/transition.ts", "../s/timeline/renderers/parts/samplers/visual/parts/sequence.ts", "../s/timeline/renderers/parts/samplers/visual/parts/sample.ts", "../s/timeline/renderers/parts/samplers/visual/parts/defaults.ts", "../s/timeline/renderers/parts/samplers/visual/sampler.ts", "../s/timeline/renderers/export/parts/cursor.ts", "../s/timeline/renderers/parts/samplers/audio/parts/init.ts", "../s/timeline/renderers/parts/samplers/audio/parts/sink.ts", "../s/timeline/renderers/parts/samplers/audio/parts/find.ts", "../s/timeline/renderers/parts/samplers/audio/sampler.ts", "../s/timeline/renderers/player/parts/playback.ts", "../s/timeline/renderers/player/player.ts", "../s/timeline/renderers/export/parts/audio-mix.ts", "../s/timeline/renderers/export/parts/resamplers.ts", "../s/timeline/renderers/export/parts/audio-gain.ts", "../s/timeline/renderers/export/parts/produce-audio.ts", "../s/timeline/renderers/export/parts/produce-video.ts", "../s/timeline/renderers/export/produce.ts", "../s/timeline/sugar/omni.ts", "../node_modules/@e280/renraku/s/core/taps/bind.ts", "../node_modules/@e280/sten/s/themes/basic.ts", "../node_modules/@e280/sten/s/themes/auto.ts", "../node_modules/@e280/sten/s/colors/parts/codes.ts", "../node_modules/@e280/sten/s/colors/parts/color-fns.ts", "../node_modules/@e280/sten/s/colors/colorless.ts", "../node_modules/@e280/sten/s/colors/colorful.ts", "../node_modules/@e280/sten/s/utils/supports.ts", "../node_modules/@e280/sten/s/colors/auto.ts", "../node_modules/@e280/sten/s/shapers/errors.ts", "../node_modules/@e280/sten/s/shapers/shaper.ts", "../node_modules/@e280/sten/s/shapers/timestamp.ts", "../node_modules/@e280/sten/s/shapers/auto.ts", "../node_modules/@e280/sten/s/writers/deno.ts", "../node_modules/@e280/sten/s/writers/node.ts", "../node_modules/@e280/sten/s/writers/console.ts", "../node_modules/@e280/sten/s/writers/auto.ts", "../node_modules/@e280/sten/s/writers/void.ts", "../node_modules/@e280/sten/s/shapers/none.ts", "../node_modules/@e280/sten/s/logger.ts", "../node_modules/@e280/renraku/s/core/taps/logger.ts", "../node_modules/@e280/renraku/s/core/taps/error.ts", "../node_modules/@e280/renraku/s/core/json-rpc.ts", "../node_modules/@e280/renraku/s/core/errors.ts", "../node_modules/@e280/renraku/s/core/execute.ts", "../node_modules/@e280/renraku/s/core/endpoint.ts", "../node_modules/@e280/renraku/s/core/remote-proxy.ts", "../node_modules/@e280/renraku/s/core/remote.ts", "../node_modules/@e280/renraku/s/core/mock.ts", "../node_modules/@e280/renraku/s/transports/messenger/conduits/conduit.ts", "../node_modules/@e280/renraku/s/transports/messenger/parts/helpers.ts", "../node_modules/@e280/renraku/s/transports/messenger/conduits/postable.ts", "../node_modules/@e280/renraku/s/transports/messenger/parts/meta.ts", "../node_modules/@e280/renraku/s/defaults.ts", "../node_modules/@e280/renraku/s/transports/messenger/parts/response-waiter.ts", "../node_modules/@e280/renraku/s/transports/messenger/messenger.ts", "../node_modules/@e280/comrade/s/parts/shells.ts", "../node_modules/@e280/comrade/s/parts/default-tap.ts", "../node_modules/@e280/comrade/s/parts/worker.ts", "../node_modules/@e280/comrade/s/parts/thread.ts", "../node_modules/@e280/comrade/s/parts/cluster.ts", "../node_modules/@e280/comrade/s/comrade.ts", "../node_modules/@e280/comrade/s/compat/browser.ts", "../node_modules/@e280/comrade/s/index.browser.ts", "../s/driver/parts/machina.ts", "../s/features/transition/transition.ts", "../s/features/transition/parts/vertex.ts", "../s/features/transition/parts/uniforms.ts", "../s/features/transition/parts/fragment.ts", "../s/driver/parts/compositor.ts", "../s/driver/fns/host.ts", "../s/driver/driver.ts", "../s/timeline/utils/checksum.ts", "../s/timeline/utils/datafile.ts", "../s/demo/routines/load-video.ts", "../s/timeline/sugar/omni.test.ts", "../s/timeline/renderers/renderers.test.ts", "../s/tests.bundle.ts"],
4
+ "sourcesContent": ["module.exports=\n[{\"name\":\"Bounce\",\"paramsTypes\":{\"shadow_colour\":\"vec4\",\"shadow_height\":\"float\",\"bounces\":\"float\"},\"defaultParams\":{\"shadow_colour\":[0,0,0,0.6],\"shadow_height\":0.075,\"bounces\":3},\"glsl\":\"// Author: Adrian Purser\\n// License: MIT\\n\\nuniform vec4 shadow_colour; // = vec4(0.,0.,0.,.6)\\nuniform float shadow_height; // = 0.075\\nuniform float bounces; // = 3.0\\n\\nconst float PI = 3.14159265358;\\n\\nvec4 transition (vec2 uv) {\\n float time = progress;\\n float stime = sin(time * PI / 2.);\\n float phase = time * PI * bounces;\\n float y = (abs(cos(phase))) * (1.0 - stime);\\n float d = uv.y - y;\\n return mix(\\n mix(\\n getToColor(uv),\\n shadow_colour,\\n step(d, shadow_height) * (1. - mix(\\n ((d / shadow_height) * shadow_colour.a) + (1.0 - shadow_colour.a),\\n 1.0,\\n smoothstep(0.95, 1., progress) // fade-out the shadow at the end\\n ))\\n ),\\n getFromColor(vec2(uv.x, uv.y + (1.0 - y))),\\n step(d, 0.0)\\n );\\n}\\n\",\"author\":\"Adrian Purser\",\"license\":\"MIT\",\"createdAt\":\"Fri, 10 Nov 2017 17:01:45 +0000\",\"updatedAt\":\"Sat, 11 Nov 2017 08:50:40 +0100\"},{\"name\":\"BowTieHorizontal\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: huynx\\n// License: MIT\\n\\nvec2 bottom_left = vec2(0.0, 1.0);\\nvec2 bottom_right = vec2(1.0, 1.0);\\nvec2 top_left = vec2(0.0, 0.0);\\nvec2 top_right = vec2(1.0, 0.0);\\nvec2 center = vec2(0.5, 0.5);\\n\\nfloat check(vec2 p1, vec2 p2, vec2 p3)\\n{\\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\\n}\\n\\nbool PointInTriangle (vec2 pt, vec2 p1, vec2 p2, vec2 p3)\\n{\\n bool b1, b2, b3;\\n b1 = check(pt, p1, p2) < 0.0;\\n b2 = check(pt, p2, p3) < 0.0;\\n b3 = check(pt, p3, p1) < 0.0;\\n return ((b1 == b2) && (b2 == b3));\\n}\\n\\nbool in_left_triangle(vec2 p){\\n vec2 vertex1, vertex2, vertex3;\\n vertex1 = vec2(progress, 0.5);\\n vertex2 = vec2(0.0, 0.5-progress);\\n vertex3 = vec2(0.0, 0.5+progress);\\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\\n {\\n return true;\\n }\\n return false;\\n}\\n\\nbool in_right_triangle(vec2 p){\\n vec2 vertex1, vertex2, vertex3;\\n vertex1 = vec2(1.0-progress, 0.5);\\n vertex2 = vec2(1.0, 0.5-progress);\\n vertex3 = vec2(1.0, 0.5+progress);\\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\\n {\\n return true;\\n }\\n return false;\\n}\\n\\nfloat blur_edge(vec2 bot1, vec2 bot2, vec2 top, vec2 testPt)\\n{\\n vec2 lineDir = bot1 - top;\\n vec2 perpDir = vec2(lineDir.y, -lineDir.x);\\n vec2 dirToPt1 = bot1 - testPt;\\n float dist1 = abs(dot(normalize(perpDir), dirToPt1));\\n \\n lineDir = bot2 - top;\\n perpDir = vec2(lineDir.y, -lineDir.x);\\n dirToPt1 = bot2 - testPt;\\n float min_dist = min(abs(dot(normalize(perpDir), dirToPt1)), dist1);\\n \\n if (min_dist < 0.005) {\\n return min_dist / 0.005;\\n }\\n else {\\n return 1.0;\\n };\\n}\\n\\n\\nvec4 transition (vec2 uv) {\\n if (in_left_triangle(uv))\\n {\\n if (progress < 0.1)\\n {\\n return getFromColor(uv);\\n }\\n if (uv.x < 0.5)\\n {\\n vec2 vertex1 = vec2(progress, 0.5);\\n vec2 vertex2 = vec2(0.0, 0.5-progress);\\n vec2 vertex3 = vec2(0.0, 0.5+progress);\\n return mix(\\n getFromColor(uv),\\n getToColor(uv),\\n blur_edge(vertex2, vertex3, vertex1, uv)\\n );\\n }\\n else\\n {\\n if (progress > 0.0)\\n {\\n return getToColor(uv);\\n }\\n else\\n {\\n return getFromColor(uv);\\n }\\n } \\n }\\n else if (in_right_triangle(uv))\\n {\\n if (uv.x >= 0.5)\\n {\\n vec2 vertex1 = vec2(1.0-progress, 0.5);\\n vec2 vertex2 = vec2(1.0, 0.5-progress);\\n vec2 vertex3 = vec2(1.0, 0.5+progress);\\n return mix(\\n getFromColor(uv),\\n getToColor(uv),\\n blur_edge(vertex2, vertex3, vertex1, uv)\\n ); \\n }\\n else\\n {\\n return getFromColor(uv);\\n }\\n }\\n else {\\n return getFromColor(uv);\\n }\\n}\",\"author\":\"huynx\",\"license\":\"MIT\",\"createdAt\":\"Sat, 24 Mar 2018 12:54:26 +0100\",\"updatedAt\":\"Sat, 24 Mar 2018 12:54:26 +0100\"},{\"name\":\"BowTieVertical\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: huynx\\r\\n// License: MIT\\r\\n\\r\\nfloat check(vec2 p1, vec2 p2, vec2 p3)\\r\\n{\\r\\n return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);\\r\\n}\\r\\n\\r\\nbool PointInTriangle (vec2 pt, vec2 p1, vec2 p2, vec2 p3)\\r\\n{\\r\\n bool b1, b2, b3;\\r\\n b1 = check(pt, p1, p2) < 0.0;\\r\\n b2 = check(pt, p2, p3) < 0.0;\\r\\n b3 = check(pt, p3, p1) < 0.0;\\r\\n return ((b1 == b2) && (b2 == b3));\\r\\n}\\r\\n\\r\\nbool in_top_triangle(vec2 p){\\r\\n vec2 vertex1, vertex2, vertex3;\\r\\n vertex1 = vec2(0.5, progress);\\r\\n vertex2 = vec2(0.5-progress, 0.0);\\r\\n vertex3 = vec2(0.5+progress, 0.0);\\r\\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\\r\\n {\\r\\n return true;\\r\\n }\\r\\n return false;\\r\\n}\\r\\n\\r\\nbool in_bottom_triangle(vec2 p){\\r\\n vec2 vertex1, vertex2, vertex3;\\r\\n vertex1 = vec2(0.5, 1.0 - progress);\\r\\n vertex2 = vec2(0.5-progress, 1.0);\\r\\n vertex3 = vec2(0.5+progress, 1.0);\\r\\n if (PointInTriangle(p, vertex1, vertex2, vertex3))\\r\\n {\\r\\n return true;\\r\\n }\\r\\n return false;\\r\\n}\\r\\n\\r\\nfloat blur_edge(vec2 bot1, vec2 bot2, vec2 top, vec2 testPt)\\r\\n{\\r\\n vec2 lineDir = bot1 - top;\\r\\n vec2 perpDir = vec2(lineDir.y, -lineDir.x);\\r\\n vec2 dirToPt1 = bot1 - testPt;\\r\\n float dist1 = abs(dot(normalize(perpDir), dirToPt1));\\r\\n \\r\\n lineDir = bot2 - top;\\r\\n perpDir = vec2(lineDir.y, -lineDir.x);\\r\\n dirToPt1 = bot2 - testPt;\\r\\n float min_dist = min(abs(dot(normalize(perpDir), dirToPt1)), dist1);\\r\\n \\r\\n if (min_dist < 0.005) {\\r\\n return min_dist / 0.005;\\r\\n }\\r\\n else {\\r\\n return 1.0;\\r\\n };\\r\\n}\\r\\n\\r\\n\\r\\nvec4 transition (vec2 uv) {\\r\\n if (in_top_triangle(uv))\\r\\n {\\r\\n if (progress < 0.1)\\r\\n {\\r\\n return getFromColor(uv);\\r\\n }\\r\\n if (uv.y < 0.5)\\r\\n {\\r\\n vec2 vertex1 = vec2(0.5, progress);\\r\\n vec2 vertex2 = vec2(0.5-progress, 0.0);\\r\\n vec2 vertex3 = vec2(0.5+progress, 0.0);\\r\\n return mix(\\r\\n getFromColor(uv),\\r\\n getToColor(uv),\\r\\n blur_edge(vertex2, vertex3, vertex1, uv)\\r\\n );\\r\\n }\\r\\n else\\r\\n {\\r\\n if (progress > 0.0)\\r\\n {\\r\\n return getToColor(uv);\\r\\n }\\r\\n else\\r\\n {\\r\\n return getFromColor(uv);\\r\\n }\\r\\n } \\r\\n }\\r\\n else if (in_bottom_triangle(uv))\\r\\n {\\r\\n if (uv.y >= 0.5)\\r\\n {\\r\\n vec2 vertex1 = vec2(0.5, 1.0-progress);\\r\\n vec2 vertex2 = vec2(0.5-progress, 1.0);\\r\\n vec2 vertex3 = vec2(0.5+progress, 1.0);\\r\\n return mix(\\r\\n getFromColor(uv),\\r\\n getToColor(uv),\\r\\n blur_edge(vertex2, vertex3, vertex1, uv)\\r\\n ); \\r\\n }\\r\\n else\\r\\n {\\r\\n return getFromColor(uv);\\r\\n }\\r\\n }\\r\\n else {\\r\\n return getFromColor(uv);\\r\\n }\\r\\n}\",\"author\":\"huynx\",\"license\":\"MIT\",\"createdAt\":\"Tue, 27 Mar 2018 10:07:54 +0700\",\"updatedAt\":\"Tue, 27 Mar 2018 10:07:54 +0700\"},{\"name\":\"ButterflyWaveScrawler\",\"paramsTypes\":{\"amplitude\":\"float\",\"waves\":\"float\",\"colorSeparation\":\"float\"},\"defaultParams\":{\"amplitude\":1,\"waves\":30,\"colorSeparation\":0.3},\"glsl\":\"// Author: mandubian\\n// License: MIT\\nuniform float amplitude; // = 1.0\\nuniform float waves; // = 30.0\\nuniform float colorSeparation; // = 0.3\\nfloat PI = 3.14159265358979323846264;\\nfloat compute(vec2 p, float progress, vec2 center) {\\nvec2 o = p*sin(progress * amplitude)-center;\\n// horizontal vector\\nvec2 h = vec2(1., 0.);\\n// butterfly polar function (don't ask me why this one :))\\nfloat theta = acos(dot(o, h)) * waves;\\nreturn (exp(cos(theta)) - 2.*cos(4.*theta) + pow(sin((2.*theta - PI) / 24.), 5.)) / 10.;\\n}\\nvec4 transition(vec2 uv) {\\n vec2 p = uv.xy / vec2(1.0).xy;\\n float inv = 1. - progress;\\n vec2 dir = p - vec2(.5);\\n float dist = length(dir);\\n float disp = compute(p, progress, vec2(0.5, 0.5)) ;\\n vec4 texTo = getToColor(p + inv*disp);\\n vec4 texFrom = vec4(\\n getFromColor(p + progress*disp*(1.0 - colorSeparation)).r,\\n getFromColor(p + progress*disp).g,\\n getFromColor(p + progress*disp*(1.0 + colorSeparation)).b,\\n 1.0);\\n return texTo*progress + texFrom*inv;\\n}\\n\",\"author\":\"mandubian\",\"license\":\"MIT\",\"createdAt\":\"Thu, 1 Jun 2017 11:47:17 +0200\",\"updatedAt\":\"Thu, 1 Jun 2017 11:47:17 +0200\"},{\"name\":\"CircleCrop\",\"paramsTypes\":{\"bgcolor\":\"vec4\"},\"defaultParams\":{\"bgcolor\":[0,0,0,1]},\"glsl\":\"// License: MIT\\n// Author: fkuteken\\n// ported by gre from https://gist.github.com/fkuteken/f63e3009c1143950dee9063c3b83fb88\\n\\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\\n\\nvec2 ratio2 = vec2(1.0, 1.0 / ratio);\\nfloat s = pow(2.0 * abs(progress - 0.5), 3.0);\\n\\nvec4 transition(vec2 p) {\\n float dist = length((vec2(p) - 0.5) * ratio2);\\n return mix(\\n progress < 0.5 ? getFromColor(p) : getToColor(p), // branching is ok here as we statically depend on progress uniform (branching won't change over pixels)\\n bgcolor,\\n step(s, dist)\\n );\\n}\\n\",\"license\":\"MIT\",\"author\":\"fkuteken\",\"createdAt\":\"Mon, 12 Jun 2017 12:52:34 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 12:52:34 +0800\"},{\"name\":\"ColourDistance\",\"paramsTypes\":{\"power\":\"float\"},\"defaultParams\":{\"power\":5},\"glsl\":\"// License: MIT\\n// Author: P-Seebauer\\n// ported by gre from https://gist.github.com/P-Seebauer/2a5fa2f77c883dd661f9\\n\\nuniform float power; // = 5.0\\n\\nvec4 transition(vec2 p) {\\n vec4 fTex = getFromColor(p);\\n vec4 tTex = getToColor(p);\\n float m = step(distance(fTex, tTex), progress);\\n return mix(\\n mix(fTex, tTex, m),\\n tTex,\\n pow(progress, power)\\n );\\n}\\n\",\"license\":\"MIT\",\"author\":\"P-Seebauer\",\"createdAt\":\"Mon, 12 Jun 2017 12:57:42 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 12:57:42 +0800\"},{\"name\":\"CrazyParametricFun\",\"paramsTypes\":{\"a\":\"float\",\"b\":\"float\",\"amplitude\":\"float\",\"smoothness\":\"float\"},\"defaultParams\":{\"a\":4,\"b\":1,\"amplitude\":120,\"smoothness\":0.1},\"glsl\":\"// Author: mandubian\\n// License: MIT\\n\\nuniform float a; // = 4\\nuniform float b; // = 1\\nuniform float amplitude; // = 120\\nuniform float smoothness; // = 0.1\\n\\nvec4 transition(vec2 uv) {\\n vec2 p = uv.xy / vec2(1.0).xy;\\n vec2 dir = p - vec2(.5);\\n float dist = length(dir);\\n float x = (a - b) * cos(progress) + b * cos(progress * ((a / b) - 1.) );\\n float y = (a - b) * sin(progress) - b * sin(progress * ((a / b) - 1.));\\n vec2 offset = dir * vec2(sin(progress * dist * amplitude * x), sin(progress * dist * amplitude * y)) / smoothness;\\n return mix(getFromColor(p + offset), getToColor(p), smoothstep(0.2, 1.0, progress));\\n}\\n\",\"author\":\"mandubian\",\"license\":\"MIT\",\"createdAt\":\"Thu, 1 Jun 2017 13:03:12 +0200\",\"updatedAt\":\"Thu, 1 Jun 2017 13:03:12 +0200\"},{\"name\":\"CrossZoom\",\"paramsTypes\":{\"strength\":\"float\"},\"defaultParams\":{\"strength\":0.4},\"glsl\":\"// License: MIT\\n// Author: rectalogic\\n// ported by gre from https://gist.github.com/rectalogic/b86b90161503a0023231\\n\\n// Converted from https://github.com/rectalogic/rendermix-basic-effects/blob/master/assets/com/rendermix/CrossZoom/CrossZoom.frag\\n// Which is based on https://github.com/evanw/glfx.js/blob/master/src/filters/blur/zoomblur.js\\n// With additional easing functions from https://github.com/rectalogic/rendermix-basic-effects/blob/master/assets/com/rendermix/Easing/Easing.glsllib\\n\\nuniform float strength; // = 0.4\\n\\nconst float PI = 3.141592653589793;\\n\\nfloat Linear_ease(in float begin, in float change, in float duration, in float time) {\\n return change * time / duration + begin;\\n}\\n\\nfloat Exponential_easeInOut(in float begin, in float change, in float duration, in float time) {\\n if (time == 0.0)\\n return begin;\\n else if (time == duration)\\n return begin + change;\\n time = time / (duration / 2.0);\\n if (time < 1.0)\\n return change / 2.0 * pow(2.0, 10.0 * (time - 1.0)) + begin;\\n return change / 2.0 * (-pow(2.0, -10.0 * (time - 1.0)) + 2.0) + begin;\\n}\\n\\nfloat Sinusoidal_easeInOut(in float begin, in float change, in float duration, in float time) {\\n return -change / 2.0 * (cos(PI * time / duration) - 1.0) + begin;\\n}\\n\\nfloat rand (vec2 co) {\\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\\n}\\n\\nvec3 crossFade(in vec2 uv, in float dissolve) {\\n return mix(getFromColor(uv).rgb, getToColor(uv).rgb, dissolve);\\n}\\n\\nvec4 transition(vec2 uv) {\\n vec2 texCoord = uv.xy / vec2(1.0).xy;\\n\\n // Linear interpolate center across center half of the image\\n vec2 center = vec2(Linear_ease(0.25, 0.5, 1.0, progress), 0.5);\\n float dissolve = Exponential_easeInOut(0.0, 1.0, 1.0, progress);\\n\\n // Mirrored sinusoidal loop. 0->strength then strength->0\\n float strength = Sinusoidal_easeInOut(0.0, strength, 0.5, progress);\\n\\n vec3 color = vec3(0.0);\\n float total = 0.0;\\n vec2 toCenter = center - texCoord;\\n\\n /* randomize the lookup values to hide the fixed number of samples */\\n float offset = rand(uv);\\n\\n for (float t = 0.0; t <= 40.0; t++) {\\n float percent = (t + offset) / 40.0;\\n float weight = 4.0 * (percent - percent * percent);\\n color += crossFade(texCoord + toCenter * percent * strength, dissolve) * weight;\\n total += weight;\\n }\\n return vec4(color / total, 1.0);\\n}\\n\",\"license\":\"MIT\",\"author\":\"rectalogic\",\"createdAt\":\"Mon, 12 Jun 2017 12:33:07 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 12:33:07 +0800\"},{\"name\":\"Directional\",\"paramsTypes\":{\"direction\":\"vec2\"},\"defaultParams\":{\"direction\":[0,1]},\"glsl\":\"// Author: Ga\u00EBtan Renaudeau\\n// License: MIT\\n\\nuniform vec2 direction; // = vec2(0.0, 1.0)\\n\\nvec4 transition (vec2 uv) {\\n vec2 p = uv + progress * sign(direction);\\n vec2 f = fract(p);\\n return mix(\\n getToColor(f),\\n getFromColor(f),\\n step(0.0, p.y) * step(p.y, 1.0) * step(0.0, p.x) * step(p.x, 1.0)\\n );\\n}\\n\",\"author\":\"Ga\u00EBtan Renaudeau\",\"license\":\"MIT\",\"createdAt\":\"Thu, 19 Apr 2018 12:20:29 +0200\",\"updatedAt\":\"Thu, 19 Apr 2018 12:20:29 +0200\"},{\"name\":\"DoomScreenTransition\",\"paramsTypes\":{\"bars\":\"int\",\"amplitude\":\"float\",\"noise\":\"float\",\"frequency\":\"float\",\"dripScale\":\"float\"},\"defaultParams\":{\"bars\":30,\"amplitude\":2,\"noise\":0.1,\"frequency\":0.5,\"dripScale\":0.5},\"glsl\":\"// Author: Zeh Fernando\\n// License: MIT\\n\\n\\n// Transition parameters --------\\n\\n// Number of total bars/columns\\nuniform int bars; // = 30\\n\\n// Multiplier for speed ratio. 0 = no variation when going down, higher = some elements go much faster\\nuniform float amplitude; // = 2\\n\\n// Further variations in speed. 0 = no noise, 1 = super noisy (ignore frequency)\\nuniform float noise; // = 0.1\\n\\n// Speed variation horizontally. the bigger the value, the shorter the waves\\nuniform float frequency; // = 0.5\\n\\n// How much the bars seem to \\\"run\\\" from the middle of the screen first (sticking to the sides). 0 = no drip, 1 = curved drip\\nuniform float dripScale; // = 0.5\\n\\n\\n// The code proper --------\\n\\nfloat rand(int num) {\\n return fract(mod(float(num) * 67123.313, 12.0) * sin(float(num) * 10.3) * cos(float(num)));\\n}\\n\\nfloat wave(int num) {\\n float fn = float(num) * frequency * 0.1 * float(bars);\\n return cos(fn * 0.5) * cos(fn * 0.13) * sin((fn+10.0) * 0.3) / 2.0 + 0.5;\\n}\\n\\nfloat drip(int num) {\\n return sin(float(num) / float(bars - 1) * 3.141592) * dripScale;\\n}\\n\\nfloat pos(int num) {\\n return (noise == 0.0 ? wave(num) : mix(wave(num), rand(num), noise)) + (dripScale == 0.0 ? 0.0 : drip(num));\\n}\\n\\nvec4 transition(vec2 uv) {\\n int bar = int(uv.x * (float(bars)));\\n float scale = 1.0 + pos(bar) * amplitude;\\n float phase = progress * scale;\\n float posY = uv.y / vec2(1.0).y;\\n vec2 p;\\n vec4 c;\\n if (phase + posY < 1.0) {\\n p = vec2(uv.x, uv.y + mix(0.0, vec2(1.0).y, phase)) / vec2(1.0).xy;\\n c = getFromColor(p);\\n } else {\\n p = uv.xy / vec2(1.0).xy;\\n c = getToColor(p);\\n }\\n\\n // Finally, apply the color\\n return c;\\n}\\n\",\"author\":\"Zeh Fernando\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 09:39:09 -0700\",\"updatedAt\":\"Tue, 30 May 2017 09:39:09 -0700\"},{\"name\":\"Dreamy\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: mikolalysenko\\n// License: MIT\\n\\nvec2 offset(float progress, float x, float theta) {\\n float phase = progress*progress + progress + theta;\\n float shifty = 0.03*progress*cos(10.0*(progress+x));\\n return vec2(0, shifty);\\n}\\nvec4 transition(vec2 p) {\\n return mix(getFromColor(p + offset(progress, p.x, 0.0)), getToColor(p + offset(1.0-progress, p.x, 3.14)), progress);\\n}\\n\",\"author\":\"mikolalysenko\",\"license\":\"MIT\",\"createdAt\":\"Mon, 12 Jun 2017 12:27:38 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 12:27:38 +0800\"},{\"name\":\"DreamyZoom\",\"paramsTypes\":{\"rotation\":\"float\",\"scale\":\"float\"},\"defaultParams\":{\"rotation\":6,\"scale\":1.2},\"glsl\":\"// Author: Zeh Fernando\\n// License: MIT\\n\\n// Definitions --------\\n#define DEG2RAD 0.03926990816987241548078304229099 // 1/180*PI\\n\\n\\n// Transition parameters --------\\n\\n// In degrees\\nuniform float rotation; // = 6\\n\\n// Multiplier\\nuniform float scale; // = 1.2\\n\\n\\n// The code proper --------\\n\\nvec4 transition(vec2 uv) {\\n // Massage parameters\\n float phase = progress < 0.5 ? progress * 2.0 : (progress - 0.5) * 2.0;\\n float angleOffset = progress < 0.5 ? mix(0.0, rotation * DEG2RAD, phase) : mix(-rotation * DEG2RAD, 0.0, phase);\\n float newScale = progress < 0.5 ? mix(1.0, scale, phase) : mix(scale, 1.0, phase);\\n \\n vec2 center = vec2(0, 0);\\n\\n // Calculate the source point\\n vec2 assumedCenter = vec2(0.5, 0.5);\\n vec2 p = (uv.xy - vec2(0.5, 0.5)) / newScale * vec2(ratio, 1.0);\\n\\n // This can probably be optimized (with distance())\\n float angle = atan(p.y, p.x) + angleOffset;\\n float dist = distance(center, p);\\n p.x = cos(angle) * dist / ratio + 0.5;\\n p.y = sin(angle) * dist + 0.5;\\n vec4 c = progress < 0.5 ? getFromColor(p) : getToColor(p);\\n\\n // Finally, apply the color\\n return c + (progress < 0.5 ? mix(0.0, 1.0, phase) : mix(1.0, 0.0, phase));\\n}\\n\",\"author\":\"Zeh Fernando\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 10:44:06 -0700\",\"updatedAt\":\"Tue, 30 May 2017 10:44:06 -0700\"},{\"name\":\"GlitchDisplace\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: Matt DesLauriers\\n// License: MIT\\n\\nhighp float random(vec2 co)\\n{\\n highp float a = 12.9898;\\n highp float b = 78.233;\\n highp float c = 43758.5453;\\n highp float dt= dot(co.xy ,vec2(a,b));\\n highp float sn= mod(dt,3.14);\\n return fract(sin(sn) * c);\\n}\\nfloat voronoi( in vec2 x ) {\\n vec2 p = floor( x );\\n vec2 f = fract( x );\\n float res = 8.0;\\n for( float j=-1.; j<=1.; j++ )\\n for( float i=-1.; i<=1.; i++ ) {\\n vec2 b = vec2( i, j );\\n vec2 r = b - f + random( p + b );\\n float d = dot( r, r );\\n res = min( res, d );\\n }\\n return sqrt( res );\\n}\\n\\nvec2 displace(vec4 tex, vec2 texCoord, float dotDepth, float textureDepth, float strength) {\\n float b = voronoi(.003 * texCoord + 2.0);\\n float g = voronoi(0.2 * texCoord);\\n float r = voronoi(texCoord - 1.0);\\n vec4 dt = tex * 1.0;\\n vec4 dis = dt * dotDepth + 1.0 - tex * textureDepth;\\n\\n dis.x = dis.x - 1.0 + textureDepth*dotDepth;\\n dis.y = dis.y - 1.0 + textureDepth*dotDepth;\\n dis.x *= strength;\\n dis.y *= strength;\\n vec2 res_uv = texCoord ;\\n res_uv.x = res_uv.x + dis.x - 0.0;\\n res_uv.y = res_uv.y + dis.y;\\n return res_uv;\\n}\\n\\nfloat ease1(float t) {\\n return t == 0.0 || t == 1.0\\n ? t\\n : t < 0.5\\n ? +0.5 * pow(2.0, (20.0 * t) - 10.0)\\n : -0.5 * pow(2.0, 10.0 - (t * 20.0)) + 1.0;\\n}\\nfloat ease2(float t) {\\n return t == 1.0 ? t : 1.0 - pow(2.0, -10.0 * t);\\n}\\n\\n\\n\\nvec4 transition(vec2 uv) {\\n vec2 p = uv.xy / vec2(1.0).xy;\\n vec4 color1 = getFromColor(p);\\n vec4 color2 = getToColor(p);\\n vec2 disp = displace(color1, p, 0.33, 0.7, 1.0-ease1(progress));\\n vec2 disp2 = displace(color2, p, 0.33, 0.5, ease2(progress));\\n vec4 dColor1 = getToColor(disp);\\n vec4 dColor2 = getFromColor(disp2);\\n float val = ease1(progress);\\n vec3 gray = vec3(dot(min(dColor2, dColor1).rgb, vec3(0.299, 0.587, 0.114)));\\n dColor2 = vec4(gray, 1.0);\\n dColor2 *= 2.0;\\n color1 = mix(color1, dColor2, smoothstep(0.0, 0.5, progress));\\n color2 = mix(color2, dColor1, smoothstep(1.0, 0.5, progress));\\n return mix(color1, color2, val);\\n //gl_FragColor = mix(gl_FragColor, dColor, smoothstep(0.0, 0.5, progress));\\n \\n //gl_FragColor = mix(texture2D(from, p), texture2D(to, p), progress);\\n}\\n\",\"author\":\"Matt DesLauriers\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:53:04 -0400\",\"updatedAt\":\"Tue, 30 May 2017 14:53:04 -0400\"},{\"name\":\"GlitchMemories\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// author: Gunnar Roth\\n// based on work from natewave\\n// license: MIT\\nvec4 transition(vec2 p) {\\n vec2 block = floor(p.xy / vec2(16));\\n vec2 uv_noise = block / vec2(64);\\n uv_noise += floor(vec2(progress) * vec2(1200.0, 3500.0)) / vec2(64);\\n vec2 dist = progress > 0.0 ? (fract(uv_noise) - 0.5) * 0.3 *(1.0 -progress) : vec2(0.0);\\n vec2 red = p + dist * 0.2;\\n vec2 green = p + dist * .3;\\n vec2 blue = p + dist * .5;\\n\\n return vec4(mix(getFromColor(red), getToColor(red), progress).r,mix(getFromColor(green), getToColor(green), progress).g,mix(getFromColor(blue), getToColor(blue), progress).b,1.0);\\n}\\n\\n\",\"author\":\"Gunnar Roth\",\"license\":\"MIT\",\"createdAt\":\"Wed, 21 Feb 2018 00:52:15 +0100\",\"updatedAt\":\"Wed, 21 Feb 2018 19:32:02 +0100\"},{\"name\":\"GridFlip\",\"paramsTypes\":{\"size\":\"ivec2\",\"pause\":\"float\",\"dividerWidth\":\"float\",\"bgcolor\":\"vec4\",\"randomness\":\"float\"},\"defaultParams\":{\"size\":[4,4],\"pause\":0.1,\"dividerWidth\":0.05,\"bgcolor\":[0,0,0,1],\"randomness\":0.1},\"glsl\":\"// License: MIT\\n// Author: TimDonselaar\\n// ported by gre from https://gist.github.com/TimDonselaar/9bcd1c4b5934ba60087bdb55c2ea92e5\\n\\nuniform ivec2 size; // = ivec2(4)\\nuniform float pause; // = 0.1\\nuniform float dividerWidth; // = 0.05\\nuniform vec4 bgcolor; // = vec4(0.0, 0.0, 0.0, 1.0)\\nuniform float randomness; // = 0.1\\n \\nfloat rand (vec2 co) {\\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\\n}\\n\\nfloat getDelta(vec2 p) {\\n vec2 rectanglePos = floor(vec2(size) * p);\\n vec2 rectangleSize = vec2(1.0 / vec2(size).x, 1.0 / vec2(size).y);\\n float top = rectangleSize.y * (rectanglePos.y + 1.0);\\n float bottom = rectangleSize.y * rectanglePos.y;\\n float left = rectangleSize.x * rectanglePos.x;\\n float right = rectangleSize.x * (rectanglePos.x + 1.0);\\n float minX = min(abs(p.x - left), abs(p.x - right));\\n float minY = min(abs(p.y - top), abs(p.y - bottom));\\n return min(minX, minY);\\n}\\n\\nfloat getDividerSize() {\\n vec2 rectangleSize = vec2(1.0 / vec2(size).x, 1.0 / vec2(size).y);\\n return min(rectangleSize.x, rectangleSize.y) * dividerWidth;\\n}\\n\\nvec4 transition(vec2 p) {\\n if(progress < pause) {\\n float currentProg = progress / pause;\\n float a = 1.0;\\n if(getDelta(p) < getDividerSize()) {\\n a = 1.0 - currentProg;\\n }\\n return mix(bgcolor, getFromColor(p), a);\\n }\\n else if(progress < 1.0 - pause){\\n if(getDelta(p) < getDividerSize()) {\\n return bgcolor;\\n } else {\\n float currentProg = (progress - pause) / (1.0 - pause * 2.0);\\n vec2 q = p;\\n vec2 rectanglePos = floor(vec2(size) * q);\\n \\n float r = rand(rectanglePos) - randomness;\\n float cp = smoothstep(0.0, 1.0 - r, currentProg);\\n \\n float rectangleSize = 1.0 / vec2(size).x;\\n float delta = rectanglePos.x * rectangleSize;\\n float offset = rectangleSize / 2.0 + delta;\\n \\n p.x = (p.x - offset)/abs(cp - 0.5)*0.5 + offset;\\n vec4 a = getFromColor(p);\\n vec4 b = getToColor(p);\\n \\n float s = step(abs(vec2(size).x * (q.x - delta) - 0.5), abs(cp - 0.5));\\n return mix(bgcolor, mix(b, a, step(cp, 0.5)), s);\\n }\\n }\\n else {\\n float currentProg = (progress - 1.0 + pause) / pause;\\n float a = 1.0;\\n if(getDelta(p) < getDividerSize()) {\\n a = currentProg;\\n }\\n return mix(bgcolor, getToColor(p), a);\\n }\\n}\\n\",\"license\":\"MIT\",\"author\":\"TimDonselaar\",\"createdAt\":\"Mon, 12 Jun 2017 11:32:51 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 11:32:51 +0800\"},{\"name\":\"InvertedPageCurl\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// author: Hewlett-Packard\\n// license: BSD 3 Clause\\n// Adapted by Sergey Kosarevsky from:\\n// http://rectalogic.github.io/webvfx/examples_2transition-shader-pagecurl_8html-example.html\\n\\n/*\\nCopyright (c) 2010 Hewlett-Packard Development Company, L.P. All rights reserved.\\n\\nRedistribution and use in source and binary forms, with or without\\nmodification, are permitted provided that the following conditions are\\nmet:\\n\\n * Redistributions of source code must retain the above copyright\\n notice, this list of conditions and the following disclaimer.\\n * Redistributions in binary form must reproduce the above\\n copyright notice, this list of conditions and the following disclaimer\\n in the documentation and/or other materials provided with the\\n distribution.\\n * Neither the name of Hewlett-Packard nor the names of its\\n contributors may be used to endorse or promote products derived from\\n this software without specific prior written permission.\\n\\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\\n\\\"AS IS\\\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\\nin vec2 texCoord;\\n*/\\n\\nconst float MIN_AMOUNT = -0.16;\\nconst float MAX_AMOUNT = 1.5;\\nfloat amount = progress * (MAX_AMOUNT - MIN_AMOUNT) + MIN_AMOUNT;\\n\\nconst float PI = 3.141592653589793;\\n\\nconst float scale = 512.0;\\nconst float sharpness = 3.0;\\n\\nfloat cylinderCenter = amount;\\n// 360 degrees * amount\\nfloat cylinderAngle = 2.0 * PI * amount;\\n\\nconst float cylinderRadius = 1.0 / PI / 2.0;\\n\\nvec3 hitPoint(float hitAngle, float yc, vec3 point, mat3 rrotation)\\n{\\n float hitPoint = hitAngle / (2.0 * PI);\\n point.y = hitPoint;\\n return rrotation * point;\\n}\\n\\nvec4 antiAlias(vec4 color1, vec4 color2, float distanc)\\n{\\n distanc *= scale;\\n if (distanc < 0.0) return color2;\\n if (distanc > 2.0) return color1;\\n float dd = pow(1.0 - distanc / 2.0, sharpness);\\n return ((color2 - color1) * dd) + color1;\\n}\\n\\nfloat distanceToEdge(vec3 point)\\n{\\n float dx = abs(point.x > 0.5 ? 1.0 - point.x : point.x);\\n float dy = abs(point.y > 0.5 ? 1.0 - point.y : point.y);\\n if (point.x < 0.0) dx = -point.x;\\n if (point.x > 1.0) dx = point.x - 1.0;\\n if (point.y < 0.0) dy = -point.y;\\n if (point.y > 1.0) dy = point.y - 1.0;\\n if ((point.x < 0.0 || point.x > 1.0) && (point.y < 0.0 || point.y > 1.0)) return sqrt(dx * dx + dy * dy);\\n return min(dx, dy);\\n}\\n\\nvec4 seeThrough(float yc, vec2 p, mat3 rotation, mat3 rrotation)\\n{\\n float hitAngle = PI - (acos(yc / cylinderRadius) - cylinderAngle);\\n vec3 point = hitPoint(hitAngle, yc, rotation * vec3(p, 1.0), rrotation);\\n if (yc <= 0.0 && (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0))\\n {\\n return getToColor(p);\\n }\\n\\n if (yc > 0.0) return getFromColor(p);\\n\\n vec4 color = getFromColor(point.xy);\\n vec4 tcolor = vec4(0.0);\\n\\n return antiAlias(color, tcolor, distanceToEdge(point));\\n}\\n\\nvec4 seeThroughWithShadow(float yc, vec2 p, vec3 point, mat3 rotation, mat3 rrotation)\\n{\\n float shadow = distanceToEdge(point) * 30.0;\\n shadow = (1.0 - shadow) / 3.0;\\n\\n if (shadow < 0.0) shadow = 0.0; else shadow *= amount;\\n\\n vec4 shadowColor = seeThrough(yc, p, rotation, rrotation);\\n shadowColor.r -= shadow;\\n shadowColor.g -= shadow;\\n shadowColor.b -= shadow;\\n\\n return shadowColor;\\n}\\n\\nvec4 backside(float yc, vec3 point)\\n{\\n vec4 color = getFromColor(point.xy);\\n float gray = (color.r + color.b + color.g) / 15.0;\\n gray += (8.0 / 10.0) * (pow(1.0 - abs(yc / cylinderRadius), 2.0 / 10.0) / 2.0 + (5.0 / 10.0));\\n color.rgb = vec3(gray);\\n return color;\\n}\\n\\nvec4 behindSurface(vec2 p, float yc, vec3 point, mat3 rrotation)\\n{\\n float shado = (1.0 - ((-cylinderRadius - yc) / amount * 7.0)) / 6.0;\\n shado *= 1.0 - abs(point.x - 0.5);\\n\\n yc = (-cylinderRadius - cylinderRadius - yc);\\n\\n float hitAngle = (acos(yc / cylinderRadius) + cylinderAngle) - PI;\\n point = hitPoint(hitAngle, yc, point, rrotation);\\n\\n if (yc < 0.0 && point.x >= 0.0 && point.y >= 0.0 && point.x <= 1.0 && point.y <= 1.0 && (hitAngle < PI || amount > 0.5))\\n {\\n shado = 1.0 - (sqrt(pow(point.x - 0.5, 2.0) + pow(point.y - 0.5, 2.0)) / (71.0 / 100.0));\\n shado *= pow(-yc / cylinderRadius, 3.0);\\n shado *= 0.5;\\n }\\n else\\n {\\n shado = 0.0;\\n }\\n return vec4(getToColor(p).rgb - shado, 1.0);\\n}\\n\\nvec4 transition(vec2 p) {\\n\\n const float angle = 100.0 * PI / 180.0;\\n float c = cos(-angle);\\n float s = sin(-angle);\\n\\n mat3 rotation = mat3( c, s, 0,\\n -s, c, 0,\\n -0.801, 0.8900, 1\\n );\\n c = cos(angle);\\n s = sin(angle);\\n\\n mat3 rrotation = mat3(\\tc, s, 0,\\n -s, c, 0,\\n 0.98500, 0.985, 1\\n );\\n\\n vec3 point = rotation * vec3(p, 1.0);\\n\\n float yc = point.y - cylinderCenter;\\n\\n if (yc < -cylinderRadius)\\n {\\n // Behind surface\\n return behindSurface(p,yc, point, rrotation);\\n }\\n\\n if (yc > cylinderRadius)\\n {\\n // Flat surface\\n return getFromColor(p);\\n }\\n\\n float hitAngle = (acos(yc / cylinderRadius) + cylinderAngle) - PI;\\n\\n float hitAngleMod = mod(hitAngle, 2.0 * PI);\\n if ((hitAngleMod > PI && amount < 0.5) || (hitAngleMod > PI/2.0 && amount < 0.0))\\n {\\n return seeThrough(yc, p, rotation, rrotation);\\n }\\n\\n point = hitPoint(hitAngle, yc, point, rrotation);\\n\\n if (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0)\\n {\\n return seeThroughWithShadow(yc, p, point, rotation, rrotation);\\n }\\n\\n vec4 color = backside(yc, point);\\n\\n vec4 otherColor;\\n if (yc < 0.0)\\n {\\n float shado = 1.0 - (sqrt(pow(point.x - 0.5, 2.0) + pow(point.y - 0.5, 2.0)) / 0.71);\\n shado *= pow(-yc / cylinderRadius, 3.0);\\n shado *= 0.5;\\n otherColor = vec4(0.0, 0.0, 0.0, shado);\\n }\\n else\\n {\\n otherColor = getFromColor(p);\\n }\\n\\n color = antiAlias(color, otherColor, cylinderRadius - abs(yc));\\n\\n vec4 cl = seeThroughWithShadow(yc, p, point, rotation, rrotation);\\n float dist = distanceToEdge(point);\\n\\n return antiAlias(color, cl, dist);\\n}\\n\",\"author\":\"Hewlett-Packard\",\"license\":\"BSD 3 Clause\",\"createdAt\":\"Wed, 21 Feb 2018 01:13:49 +0100\",\"updatedAt\":\"Wed, 21 Feb 2018 16:00:02 +0100\"},{\"name\":\"LinearBlur\",\"paramsTypes\":{\"intensity\":\"float\"},\"defaultParams\":{\"intensity\":0.1},\"glsl\":\"// author: gre\\n// license: MIT\\nuniform float intensity; // = 0.1\\nconst int passes = 6;\\n\\nvec4 transition(vec2 uv) {\\n vec4 c1 = vec4(0.0);\\n vec4 c2 = vec4(0.0);\\n\\n float disp = intensity*(0.5-distance(0.5, progress));\\n for (int xi=0; xi<passes; xi++)\\n {\\n float x = float(xi) / float(passes) - 0.5;\\n for (int yi=0; yi<passes; yi++)\\n {\\n float y = float(yi) / float(passes) - 0.5;\\n vec2 v = vec2(x,y);\\n float d = disp;\\n c1 += getFromColor( uv + d*v);\\n c2 += getToColor( uv + d*v);\\n }\\n }\\n c1 /= float(passes*passes);\\n c2 /= float(passes*passes);\\n return mix(c1, c2, progress);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Fri, 23 Feb 2018 15:18:22 +0100\",\"updatedAt\":\"Fri, 23 Feb 2018 15:18:22 +0100\"},{\"name\":\"Mosaic\",\"paramsTypes\":{\"endx\":\"int\",\"endy\":\"int\"},\"defaultParams\":{\"endx\":2,\"endy\":-1},\"glsl\":\"// License: MIT\\n// Author: Xaychru\\n// ported by gre from https://gist.github.com/Xaychru/130bb7b7affedbda9df5\\n\\n#define PI 3.14159265358979323\\n#define POW2(X) X*X\\n#define POW3(X) X*X*X\\nuniform int endx; // = 2\\nuniform int endy; // = -1\\n\\nfloat Rand(vec2 v) {\\n return fract(sin(dot(v.xy ,vec2(12.9898,78.233))) * 43758.5453);\\n}\\nvec2 Rotate(vec2 v, float a) {\\n mat2 rm = mat2(cos(a), -sin(a),\\n sin(a), cos(a));\\n return rm*v;\\n}\\nfloat CosInterpolation(float x) {\\n return -cos(x*PI)/2.+.5;\\n}\\nvec4 transition(vec2 uv) {\\n vec2 p = uv.xy / vec2(1.0).xy - .5;\\n vec2 rp = p;\\n float rpr = (progress*2.-1.);\\n float z = -(rpr*rpr*2.) + 3.;\\n float az = abs(z);\\n rp *= az;\\n rp += mix(vec2(.5, .5), vec2(float(endx) + .5, float(endy) + .5), POW2(CosInterpolation(progress)));\\n vec2 mrp = mod(rp, 1.);\\n vec2 crp = rp;\\n bool onEnd = int(floor(crp.x))==endx&&int(floor(crp.y))==endy;\\n if(!onEnd) {\\n float ang = float(int(Rand(floor(crp))*4.))*.5*PI;\\n mrp = vec2(.5) + Rotate(mrp-vec2(.5), ang);\\n }\\n if(onEnd || Rand(floor(crp))>.5) {\\n return getToColor(mrp);\\n } else {\\n return getFromColor(mrp);\\n }\\n}\\n\",\"license\":\"MIT\",\"author\":\"Xaychru\",\"createdAt\":\"Mon, 12 Jun 2017 10:26:51 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 10:26:51 +0800\"},{\"name\":\"PolkaDotsCurtain\",\"paramsTypes\":{\"dots\":\"float\",\"center\":\"vec2\"},\"defaultParams\":{\"dots\":20,\"center\":[0,0]},\"glsl\":\"// author: bobylito\\n// license: MIT\\nconst float SQRT_2 = 1.414213562373;\\nuniform float dots;// = 20.0;\\nuniform vec2 center;// = vec2(0, 0);\\n\\nvec4 transition(vec2 uv) {\\n bool nextImage = distance(fract(uv * dots), vec2(0.5, 0.5)) < ( progress / distance(uv, center));\\n return nextImage ? getToColor(uv) : getFromColor(uv);\\n}\\n\",\"author\":\"bobylito\",\"license\":\"MIT\",\"createdAt\":\"Tue, 20 Feb 2018 23:41:45 +0100\",\"updatedAt\":\"Tue, 20 Feb 2018 23:41:45 +0100\"},{\"name\":\"Radial\",\"paramsTypes\":{\"smoothness\":\"float\"},\"defaultParams\":{\"smoothness\":1},\"glsl\":\"// License: MIT\\n// Author: Xaychru\\n// ported by gre from https://gist.github.com/Xaychru/ce1d48f0ce00bb379750\\n\\nuniform float smoothness; // = 1.0\\n\\nconst float PI = 3.141592653589;\\n\\nvec4 transition(vec2 p) {\\n vec2 rp = p*2.-1.;\\n return mix(\\n getToColor(p),\\n getFromColor(p),\\n smoothstep(0., smoothness, atan(rp.y,rp.x) - (progress-.5) * PI * 2.5)\\n );\\n}\\n\",\"license\":\"MIT\",\"author\":\"Xaychru\",\"createdAt\":\"Mon, 12 Jun 2017 10:36:24 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 10:36:24 +0800\"},{\"name\":\"SimpleZoom\",\"paramsTypes\":{\"zoom_quickness\":\"float\"},\"defaultParams\":{\"zoom_quickness\":0.8},\"glsl\":\"// Author: 0gust1\\n// License: MIT\\n\\nuniform float zoom_quickness; // = 0.8\\nfloat nQuick = clamp(zoom_quickness,0.2,1.0);\\n\\nvec2 zoom(vec2 uv, float amount) {\\n return 0.5 + ((uv - 0.5) * (1.0-amount));\\t\\n}\\n\\nvec4 transition (vec2 uv) {\\n return mix(\\n getFromColor(zoom(uv, smoothstep(0.0, nQuick, progress))),\\n getToColor(uv),\\n smoothstep(nQuick-0.2, 1.0, progress)\\n );\\n}\",\"author\":\"0gust1\",\"license\":\"MIT\",\"createdAt\":\"Tue, 6 Mar 2018 00:43:47 +0100\",\"updatedAt\":\"Tue, 6 Mar 2018 00:43:47 +0100\"},{\"name\":\"StereoViewer\",\"paramsTypes\":{\"zoom\":\"float\",\"corner_radius\":\"float\"},\"defaultParams\":{\"zoom\":0.88,\"corner_radius\":0.22},\"glsl\":\"// Tunable parameters\\n// How much to zoom (out) for the effect ~ 0.5 - 1.0\\nuniform float zoom; // = 0.88\\n// Corner radius as a fraction of the image height\\nuniform float corner_radius; // = 0.22\\n\\n// author: Ted Schundler\\n// license: BSD 2 Clause\\n// Free for use and modification by anyone with credit\\n\\n// Copyright (c) 2016, Theodore K Schundler\\n// All rights reserved.\\n\\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\\n\\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\\n\\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\\n\\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \\\"AS IS\\\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\\n\\n///////////////////////////////////////////////////////////////////////////////\\n// Stereo Viewer Toy Transition //\\n// //\\n// Inspired by ViewMaster / Image3D image viewer devices. //\\n// This effect is similar to what you see when you press the device's lever. //\\n// There is a quick zoom in / out to make the transition 'valid' for GLSL.io //\\n///////////////////////////////////////////////////////////////////////////////\\n\\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\\nconst vec2 c00 = vec2(0.0, 0.0); // the four corner points\\nconst vec2 c01 = vec2(0.0, 1.0);\\nconst vec2 c11 = vec2(1.0, 1.0);\\nconst vec2 c10 = vec2(1.0, 0.0);\\n\\n// Check if a point is within a given corner\\nbool in_corner(vec2 p, vec2 corner, vec2 radius) {\\n // determine the direction we want to be filled\\n vec2 axis = (c11 - corner) - corner;\\n\\n // warp the point so we are always testing the bottom left point with the\\n // circle centered on the origin\\n p = p - (corner + axis * radius);\\n p *= axis / radius;\\n return (p.x > 0.0 && p.y > -1.0) || (p.y > 0.0 && p.x > -1.0) || dot(p, p) < 1.0;\\n}\\n\\n// Check all four corners\\n// return a float for v2 for anti-aliasing?\\nbool test_rounded_mask(vec2 p, vec2 corner_size) {\\n return\\n in_corner(p, c00, corner_size) &&\\n in_corner(p, c01, corner_size) &&\\n in_corner(p, c10, corner_size) &&\\n in_corner(p, c11, corner_size);\\n}\\n\\n// Screen blend mode - https://en.wikipedia.org/wiki/Blend_modes\\n// This more closely approximates what you see than linear blending\\nvec4 screen(vec4 a, vec4 b) {\\n return 1.0 - (1.0 - a) * (1.0 -b);\\n}\\n\\n// Given RGBA, find a value that when screened with itself\\n// will yield the original value.\\nvec4 unscreen(vec4 c) {\\n return 1.0 - sqrt(1.0 - c);\\n}\\n\\n// Grab a pixel, only if it isn't masked out by the rounded corners\\nvec4 sample_with_corners_from(vec2 p, vec2 corner_size) {\\n p = (p - 0.5) / zoom + 0.5;\\n if (!test_rounded_mask(p, corner_size)) {\\n return black;\\n }\\n return unscreen(getFromColor(p));\\n}\\n\\nvec4 sample_with_corners_to(vec2 p, vec2 corner_size) {\\n p = (p - 0.5) / zoom + 0.5;\\n if (!test_rounded_mask(p, corner_size)) {\\n return black;\\n }\\n return unscreen(getToColor(p));\\n}\\n\\n// special sampling used when zooming - extra zoom parameter and don't unscreen\\nvec4 simple_sample_with_corners_from(vec2 p, vec2 corner_size, float zoom_amt) {\\n p = (p - 0.5) / (1.0 - zoom_amt + zoom * zoom_amt) + 0.5;\\n if (!test_rounded_mask(p, corner_size)) {\\n return black;\\n }\\n return getFromColor(p);\\n}\\n\\nvec4 simple_sample_with_corners_to(vec2 p, vec2 corner_size, float zoom_amt) {\\n p = (p - 0.5) / (1.0 - zoom_amt + zoom * zoom_amt) + 0.5;\\n if (!test_rounded_mask(p, corner_size)) {\\n return black;\\n }\\n return getToColor(p);\\n}\\n\\n// Basic 2D affine transform matrix helpers\\n// These really shouldn't be used in a fragment shader - I should work out the\\n// the math for a translate & rotate function as a pair of dot products instead\\n\\nmat3 rotate2d(float angle, float ratio) {\\n float s = sin(angle);\\n float c = cos(angle);\\n return mat3(\\n c, s ,0.0,\\n -s, c, 0.0,\\n 0.0, 0.0, 1.0);\\n}\\n\\nmat3 translate2d(float x, float y) {\\n return mat3(\\n 1.0, 0.0, 0,\\n 0.0, 1.0, 0,\\n -x, -y, 1.0);\\n}\\n\\nmat3 scale2d(float x, float y) {\\n return mat3(\\n x, 0.0, 0,\\n 0.0, y, 0,\\n 0, 0, 1.0);\\n}\\n\\n// Split an image and rotate one up and one down along off screen pivot points\\nvec4 get_cross_rotated(vec3 p3, float angle, vec2 corner_size, float ratio) {\\n angle = angle * angle; // easing\\n angle /= 2.4; // works out to be a good number of radians\\n\\n mat3 center_and_scale = translate2d(-0.5, -0.5) * scale2d(1.0, ratio);\\n mat3 unscale_and_uncenter = scale2d(1.0, 1.0/ratio) * translate2d(0.5,0.5);\\n mat3 slide_left = translate2d(-2.0,0.0);\\n mat3 slide_right = translate2d(2.0,0.0);\\n mat3 rotate = rotate2d(angle, ratio);\\n\\n mat3 op_a = center_and_scale * slide_right * rotate * slide_left * unscale_and_uncenter;\\n mat3 op_b = center_and_scale * slide_left * rotate * slide_right * unscale_and_uncenter;\\n\\n vec4 a = sample_with_corners_from((op_a * p3).xy, corner_size);\\n vec4 b = sample_with_corners_from((op_b * p3).xy, corner_size);\\n\\n return screen(a, b);\\n}\\n\\n// Image stays put, but this time move two masks\\nvec4 get_cross_masked(vec3 p3, float angle, vec2 corner_size, float ratio) {\\n angle = 1.0 - angle;\\n angle = angle * angle; // easing\\n angle /= 2.4;\\n\\n vec4 img;\\n\\n mat3 center_and_scale = translate2d(-0.5, -0.5) * scale2d(1.0, ratio);\\n mat3 unscale_and_uncenter = scale2d(1.0 / zoom, 1.0 / (zoom * ratio)) * translate2d(0.5,0.5);\\n mat3 slide_left = translate2d(-2.0,0.0);\\n mat3 slide_right = translate2d(2.0,0.0);\\n mat3 rotate = rotate2d(angle, ratio);\\n\\n mat3 op_a = center_and_scale * slide_right * rotate * slide_left * unscale_and_uncenter;\\n mat3 op_b = center_and_scale * slide_left * rotate * slide_right * unscale_and_uncenter;\\n\\n bool mask_a = test_rounded_mask((op_a * p3).xy, corner_size);\\n bool mask_b = test_rounded_mask((op_b * p3).xy, corner_size);\\n\\n if (mask_a || mask_b) {\\n img = sample_with_corners_to(p3.xy, corner_size);\\n return screen(mask_a ? img : black, mask_b ? img : black);\\n } else {\\n return black;\\n }\\n}\\n\\nvec4 transition(vec2 uv) {\\n float a;\\n vec2 p=uv.xy/vec2(1.0).xy;\\n vec3 p3 = vec3(p.xy, 1.0); // for 2D matrix transforms\\n\\n // corner is warped to represent to size after mapping to 1.0, 1.0\\n vec2 corner_size = vec2(corner_radius / ratio, corner_radius);\\n\\n if (progress <= 0.0) {\\n // 0.0: start with the base frame always\\n return getFromColor(p);\\n } else if (progress < 0.1) {\\n // 0.0-0.1: zoom out and add rounded corners\\n a = progress / 0.1;\\n return simple_sample_with_corners_from(p, corner_size * a, a);\\n } else if (progress < 0.48) {\\n // 0.1-0.48: Split original image apart\\n a = (progress - 0.1)/0.38;\\n return get_cross_rotated(p3, a, corner_size, ratio);\\n } else if (progress < 0.9) {\\n // 0.48-0.52: black\\n // 0.52 - 0.9: unmask new image\\n return get_cross_masked(p3, (progress - 0.52)/0.38, corner_size, ratio);\\n } else if (progress < 1.0) {\\n // zoom out and add rounded corners\\n a = (1.0 - progress) / 0.1;\\n return simple_sample_with_corners_to(p, corner_size * a, a);\\n } else {\\n // 1.0 end with base frame\\n return getToColor(p);\\n }\\n}\\n\",\"author\":\"Ted Schundler\",\"license\":\"BSD 2 Clause\",\"createdAt\":\"Tue, 20 Feb 2018 23:20:29 +0100\",\"updatedAt\":\"Wed, 21 Feb 2018 15:42:00 +0100\"},{\"name\":\"Swirl\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// License: MIT\\n// Author: Sergey Kosarevsky\\n// ( http://www.linderdaum.com )\\n// ported by gre from https://gist.github.com/corporateshark/cacfedb8cca0f5ce3f7c\\n\\nvec4 transition(vec2 UV)\\n{\\n\\tfloat Radius = 1.0;\\n\\n\\tfloat T = progress;\\n\\n\\tUV -= vec2( 0.5, 0.5 );\\n\\n\\tfloat Dist = length(UV);\\n\\n\\tif ( Dist < Radius )\\n\\t{\\n\\t\\tfloat Percent = (Radius - Dist) / Radius;\\n\\t\\tfloat A = ( T <= 0.5 ) ? mix( 0.0, 1.0, T/0.5 ) : mix( 1.0, 0.0, (T-0.5)/0.5 );\\n\\t\\tfloat Theta = Percent * Percent * A * 8.0 * 3.14159;\\n\\t\\tfloat S = sin( Theta );\\n\\t\\tfloat C = cos( Theta );\\n\\t\\tUV = vec2( dot(UV, vec2(C, -S)), dot(UV, vec2(S, C)) );\\n\\t}\\n\\tUV += vec2( 0.5, 0.5 );\\n\\n\\tvec4 C0 = getFromColor(UV);\\n\\tvec4 C1 = getToColor(UV);\\n\\n\\treturn mix( C0, C1, T );\\n}\\n\",\"license\":\"MIT\",\"author\":\"Sergey Kosarevsky\",\"createdAt\":\"Mon, 12 Jun 2017 12:38:27 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 12:38:27 +0800\"},{\"name\":\"WaterDrop\",\"paramsTypes\":{\"amplitude\":\"float\",\"speed\":\"float\"},\"defaultParams\":{\"amplitude\":30,\"speed\":30},\"glsl\":\"// author: Pawe\u0142 P\u0142\u00F3ciennik\\n// license: MIT\\nuniform float amplitude; // = 30\\nuniform float speed; // = 30\\n\\nvec4 transition(vec2 p) {\\n vec2 dir = p - vec2(.5);\\n float dist = length(dir);\\n\\n if (dist > progress) {\\n return mix(getFromColor( p), getToColor( p), progress);\\n } else {\\n vec2 offset = dir * sin(dist * amplitude - progress * speed);\\n return mix(getFromColor( p + offset), getToColor( p), progress);\\n }\\n}\\n\",\"author\":\"Pawe\u0142 P\u0142\u00F3ciennik\",\"license\":\"MIT\",\"createdAt\":\"Wed, 21 Feb 2018 19:37:15 +0100\",\"updatedAt\":\"Wed, 21 Feb 2018 19:37:15 +0100\"},{\"name\":\"ZoomInCircles\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// License: MIT\\n// Author: dycm8009\\n// ported by gre from https://gist.github.com/dycm8009/948e99b1800e81ad909a\\n\\nvec2 zoom(vec2 uv, float amount) {\\n return 0.5 + ((uv - 0.5) * amount);\\t\\n}\\n\\nvec2 ratio2 = vec2(1.0, 1.0 / ratio);\\n\\nvec4 transition(vec2 uv) {\\n // TODO: some timing are hardcoded but should be one or many parameters\\n // TODO: should also be able to configure how much circles\\n // TODO: if() branching should be avoided when possible, prefer use of step() & other functions\\n vec2 r = 2.0 * ((vec2(uv.xy) - 0.5) * ratio2);\\n float pro = progress / 0.8;\\n float z = pro * 0.2;\\n float t = 0.0;\\n if (pro > 1.0) {\\n z = 0.2 + (pro - 1.0) * 5.;\\n t = clamp((progress - 0.8) / 0.07, 0.0, 1.0);\\n }\\n if (length(r) < 0.5+z) {\\n // uv = zoom(uv, 0.9 - 0.1 * pro);\\n }\\n else if (length(r) < 0.8+z*1.5) {\\n uv = zoom(uv, 1.0 - 0.15 * pro);\\n t = t * 0.5;\\n }\\n else if (length(r) < 1.2+z*2.5) {\\n uv = zoom(uv, 1.0 - 0.2 * pro);\\n t = t * 0.2;\\n }\\n else {\\n uv = zoom(uv, 1.0 - 0.25 * pro);\\n }\\n return mix(getFromColor(uv), getToColor(uv), t);\\n}\\n\",\"license\":\"MIT\",\"author\":\"dycm8009\",\"createdAt\":\"Mon, 12 Jun 2017 11:24:34 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 11:24:34 +0800\"},{\"name\":\"angular\",\"paramsTypes\":{\"startingAngle\":\"float\"},\"defaultParams\":{\"startingAngle\":90},\"glsl\":\"// Author: Fernando Kuteken\\n// License: MIT\\n\\n#define PI 3.141592653589\\n\\nuniform float startingAngle; // = 90;\\n\\nvec4 transition (vec2 uv) {\\n \\n float offset = startingAngle * PI / 180.0;\\n float angle = atan(uv.y - 0.5, uv.x - 0.5) + offset;\\n float normalizedAngle = (angle + PI) / (2.0 * PI);\\n \\n normalizedAngle = normalizedAngle - floor(normalizedAngle);\\n\\n return mix(\\n getFromColor(uv),\\n getToColor(uv),\\n step(normalizedAngle, progress)\\n );\\n}\\n\",\"author\":\"Fernando Kuteken\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"burn\",\"paramsTypes\":{\"color\":\"vec3\"},\"defaultParams\":{\"color\":[0.9,0.4,0.2]},\"glsl\":\"// author: gre\\n// License: MIT\\nuniform vec3 color /* = vec3(0.9, 0.4, 0.2) */;\\nvec4 transition (vec2 uv) {\\n return mix(\\n getFromColor(uv) + vec4(progress*color, 1.0),\\n getToColor(uv) + vec4((1.0-progress)*color, 1.0),\\n progress\\n );\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"cannabisleaf\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: @Flexi23\\n// License: MIT\\n\\n// inspired by http://www.wolframalpha.com/input/?i=cannabis+curve\\n\\nvec4 transition (vec2 uv) {\\n if(progress == 0.0){\\n return getFromColor(uv);\\n }\\n vec2 leaf_uv = (uv - vec2(0.5))/10./pow(progress,3.5);\\n\\tleaf_uv.y += 0.35;\\n\\tfloat r = 0.18;\\n\\tfloat o = atan(leaf_uv.y, leaf_uv.x);\\n return mix(getFromColor(uv), getToColor(uv), 1.-step(1. - length(leaf_uv)+r*(1.+sin(o))*(1.+0.9 * cos(8.*o))*(1.+0.1*cos(24.*o))*(0.9+0.05*cos(200.*o)), 1.));\\n}\\n\",\"author\":\"@Flexi23\",\"license\":\"MIT\",\"createdAt\":\"Thu, 1 Jun 2017 15:58:58 +0200\",\"updatedAt\":\"Thu, 1 Jun 2017 15:58:58 +0200\"},{\"name\":\"circle\",\"paramsTypes\":{\"center\":\"vec2\",\"backColor\":\"vec3\"},\"defaultParams\":{\"center\":[0.5,0.5],\"backColor\":[0.1,0.1,0.1]},\"glsl\":\"// Author: Fernando Kuteken\\n// License: MIT\\n\\nuniform vec2 center; // = vec2(0.5, 0.5);\\nuniform vec3 backColor; // = vec3(0.1, 0.1, 0.1);\\n\\nvec4 transition (vec2 uv) {\\n \\n float distance = length(uv - center);\\n float radius = sqrt(8.0) * abs(progress - 0.5);\\n \\n if (distance > radius) {\\n return vec4(backColor, 1.0);\\n }\\n else {\\n if (progress < 0.5) return getFromColor(uv);\\n else return getToColor(uv);\\n }\\n}\\n\",\"author\":\"Fernando Kuteken\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"circleopen\",\"paramsTypes\":{\"smoothness\":\"float\",\"opening\":\"bool\"},\"defaultParams\":{\"smoothness\":0.3,\"opening\":true},\"glsl\":\"// author: gre\\n// License: MIT\\nuniform float smoothness; // = 0.3\\nuniform bool opening; // = true\\n\\nconst vec2 center = vec2(0.5, 0.5);\\nconst float SQRT_2 = 1.414213562373;\\n\\nvec4 transition (vec2 uv) {\\n float x = opening ? progress : 1.-progress;\\n float m = smoothstep(-smoothness, 0.0, SQRT_2*distance(center, uv) - x*(1.+smoothness));\\n return mix(getFromColor(uv), getToColor(uv), opening ? 1.-m : m);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"colorphase\",\"paramsTypes\":{\"fromStep\":\"vec4\",\"toStep\":\"vec4\"},\"defaultParams\":{\"fromStep\":[0,0.2,0.4,0],\"toStep\":[0.6,0.8,1,1]},\"glsl\":\"// Author: gre\\n// License: MIT\\n\\n// Usage: fromStep and toStep must be in [0.0, 1.0] range \\n// and all(fromStep) must be < all(toStep)\\n\\nuniform vec4 fromStep; // = vec4(0.0, 0.2, 0.4, 0.0)\\nuniform vec4 toStep; // = vec4(0.6, 0.8, 1.0, 1.0)\\n\\nvec4 transition (vec2 uv) {\\n vec4 a = getFromColor(uv);\\n vec4 b = getToColor(uv);\\n return mix(a, b, smoothstep(fromStep, toStep, vec4(progress)));\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"crosshatch\",\"paramsTypes\":{\"center\":\"vec2\",\"threshold\":\"float\",\"fadeEdge\":\"float\"},\"defaultParams\":{\"center\":[0.5,0.5],\"threshold\":3,\"fadeEdge\":0.1},\"glsl\":\"// License: MIT\\n// Author: pthrasher\\n// adapted by gre from https://gist.github.com/pthrasher/04fd9a7de4012cbb03f6\\n\\nuniform vec2 center; // = vec2(0.5)\\nuniform float threshold; // = 3.0\\nuniform float fadeEdge; // = 0.1\\n\\nfloat rand(vec2 co) {\\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\\n}\\nvec4 transition(vec2 p) {\\n float dist = distance(center, p) / threshold;\\n float r = progress - min(rand(vec2(p.y, 0.0)), rand(vec2(0.0, p.x)));\\n return mix(getFromColor(p), getToColor(p), mix(0.0, mix(step(dist, r), 1.0, smoothstep(1.0-fadeEdge, 1.0, progress)), smoothstep(0.0, fadeEdge, progress))); \\n}\\n\",\"license\":\"MIT\",\"author\":\"pthrasher\",\"createdAt\":\"Mon, 12 Jun 2017 10:02:12 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 10:02:12 +0800\"},{\"name\":\"crosswarp\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: Eke P\u00E9ter <peterekepeter@gmail.com>\\n// License: MIT\\nvec4 transition(vec2 p) {\\n float x = progress;\\n x=smoothstep(.0,1.0,(x*2.0+p.x-1.0));\\n return mix(getFromColor((p-.5)*(1.-x)+.5), getToColor((p-.5)*x+.5), x);\\n}\\n\",\"author\":\"Eke P\u00E9ter <peterekepeter@gmail.com>\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"cube\",\"paramsTypes\":{\"persp\":\"float\",\"unzoom\":\"float\",\"reflection\":\"float\",\"floating\":\"float\"},\"defaultParams\":{\"persp\":0.7,\"unzoom\":0.3,\"reflection\":0.4,\"floating\":3},\"glsl\":\"// Author: gre\\n// License: MIT\\nuniform float persp; // = 0.7\\nuniform float unzoom; // = 0.3\\nuniform float reflection; // = 0.4\\nuniform float floating; // = 3.0\\n\\nvec2 project (vec2 p) {\\n return p * vec2(1.0, -1.2) + vec2(0.0, -floating/100.);\\n}\\n\\nbool inBounds (vec2 p) {\\n return all(lessThan(vec2(0.0), p)) && all(lessThan(p, vec2(1.0)));\\n}\\n\\nvec4 bgColor (vec2 p, vec2 pfr, vec2 pto) {\\n vec4 c = vec4(0.0, 0.0, 0.0, 1.0);\\n pfr = project(pfr);\\n // FIXME avoid branching might help perf!\\n if (inBounds(pfr)) {\\n c += mix(vec4(0.0), getFromColor(pfr), reflection * mix(1.0, 0.0, pfr.y));\\n }\\n pto = project(pto);\\n if (inBounds(pto)) {\\n c += mix(vec4(0.0), getToColor(pto), reflection * mix(1.0, 0.0, pto.y));\\n }\\n return c;\\n}\\n\\n// p : the position\\n// persp : the perspective in [ 0, 1 ]\\n// center : the xcenter in [0, 1] \\\\ 0.5 excluded\\nvec2 xskew (vec2 p, float persp, float center) {\\n float x = mix(p.x, 1.0-p.x, center);\\n return (\\n (\\n vec2( x, (p.y - 0.5*(1.0-persp) * x) / (1.0+(persp-1.0)*x) )\\n - vec2(0.5-distance(center, 0.5), 0.0)\\n )\\n * vec2(0.5 / distance(center, 0.5) * (center<0.5 ? 1.0 : -1.0), 1.0)\\n + vec2(center<0.5 ? 0.0 : 1.0, 0.0)\\n );\\n}\\n\\nvec4 transition(vec2 op) {\\n float uz = unzoom * 2.0*(0.5-distance(0.5, progress));\\n vec2 p = -uz*0.5+(1.0+uz) * op;\\n vec2 fromP = xskew(\\n (p - vec2(progress, 0.0)) / vec2(1.0-progress, 1.0),\\n 1.0-mix(progress, 0.0, persp),\\n 0.0\\n );\\n vec2 toP = xskew(\\n p / vec2(progress, 1.0),\\n mix(pow(progress, 2.0), 1.0, persp),\\n 1.0\\n );\\n // FIXME avoid branching might help perf!\\n if (inBounds(fromP)) {\\n return getFromColor(fromP);\\n }\\n else if (inBounds(toP)) {\\n return getToColor(toP);\\n }\\n return bgColor(op, fromP, toP);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"directionalwarp\",\"paramsTypes\":{\"direction\":\"vec2\"},\"defaultParams\":{\"direction\":[-1,1]},\"glsl\":\"// Author: pschroen\\n// License: MIT\\n\\nuniform vec2 direction; // = vec2(-1.0, 1.0)\\n\\nconst float smoothness = 0.5;\\nconst vec2 center = vec2(0.5, 0.5);\\n\\nvec4 transition (vec2 uv) {\\n vec2 v = normalize(direction);\\n v /= abs(v.x) + abs(v.y);\\n float d = v.x * center.x + v.y * center.y;\\n float m = 1.0 - smoothstep(-smoothness, 0.0, v.x * uv.x + v.y * uv.y - (d - 0.5 + progress * (1.0 + smoothness)));\\n return mix(getFromColor((uv - 0.5) * (1.0 - m) + 0.5), getToColor((uv - 0.5) * m + 0.5), m);\\n}\\n\",\"author\":\"pschroen\",\"license\":\"MIT\",\"createdAt\":\"Wed, 13 Dec 2017 12:08:49 -0500\",\"updatedAt\":\"Wed, 13 Dec 2017 12:08:49 -0500\"},{\"name\":\"directionalwipe\",\"paramsTypes\":{\"direction\":\"vec2\",\"smoothness\":\"float\"},\"defaultParams\":{\"direction\":[1,-1],\"smoothness\":0.5},\"glsl\":\"// Author: gre\\n// License: MIT\\n\\nuniform vec2 direction; // = vec2(1.0, -1.0)\\nuniform float smoothness; // = 0.5\\n \\nconst vec2 center = vec2(0.5, 0.5);\\n \\nvec4 transition (vec2 uv) {\\n vec2 v = normalize(direction);\\n v /= abs(v.x)+abs(v.y);\\n float d = v.x * center.x + v.y * center.y;\\n float m =\\n (1.0-step(progress, 0.0)) * // there is something wrong with our formula that makes m not equals 0.0 with progress is 0.0\\n (1.0 - smoothstep(-smoothness, 0.0, v.x * uv.x + v.y * uv.y - (d-0.5+progress*(1.+smoothness))));\\n return mix(getFromColor(uv), getToColor(uv), m);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"displacement\",\"paramsTypes\":{\"displacementMap\":\"sampler2D\",\"strength\":\"float\"},\"defaultParams\":{\"displacementMap\":null,\"strength\":0.5},\"glsl\":\"// Author: Travis Fischer\\n// License: MIT\\n//\\n// Adapted from a Codrops article by Robin Delaporte\\n// https://tympanus.net/Development/DistortionHoverEffect\\n\\nuniform sampler2D displacementMap;\\n\\nuniform float strength; // = 0.5\\n\\nvec4 transition (vec2 uv) {\\n float displacement = texture2D(displacementMap, uv).r * strength;\\n\\n vec2 uvFrom = vec2(uv.x + progress * displacement, uv.y);\\n vec2 uvTo = vec2(uv.x - (1.0 - progress) * displacement, uv.y);\\n\\n return mix(\\n getFromColor(uvFrom),\\n getToColor(uvTo),\\n progress\\n );\\n}\\n\",\"author\":\"Travis Fischer\",\"license\":\"MIT\",\"createdAt\":\"Tue, 10 Apr 2018 23:03:38 -0400\",\"updatedAt\":\"Tue, 10 Apr 2018 23:03:38 -0400\"},{\"name\":\"doorway\",\"paramsTypes\":{\"reflection\":\"float\",\"perspective\":\"float\",\"depth\":\"float\"},\"defaultParams\":{\"reflection\":0.4,\"perspective\":0.4,\"depth\":3},\"glsl\":\"// author: gre\\n// License: MIT \\nuniform float reflection; // = 0.4\\nuniform float perspective; // = 0.4\\nuniform float depth; // = 3\\n\\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\\nconst vec2 boundMin = vec2(0.0, 0.0);\\nconst vec2 boundMax = vec2(1.0, 1.0);\\n\\nbool inBounds (vec2 p) {\\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\\n}\\n\\nvec2 project (vec2 p) {\\n return p * vec2(1.0, -1.2) + vec2(0.0, -0.02);\\n}\\n\\nvec4 bgColor (vec2 p, vec2 pto) {\\n vec4 c = black;\\n pto = project(pto);\\n if (inBounds(pto)) {\\n c += mix(black, getToColor(pto), reflection * mix(1.0, 0.0, pto.y));\\n }\\n return c;\\n}\\n\\n\\nvec4 transition (vec2 p) {\\n vec2 pfr = vec2(-1.), pto = vec2(-1.);\\n float middleSlit = 2.0 * abs(p.x-0.5) - progress;\\n if (middleSlit > 0.0) {\\n pfr = p + (p.x > 0.5 ? -1.0 : 1.0) * vec2(0.5*progress, 0.0);\\n float d = 1.0/(1.0+perspective*progress*(1.0-middleSlit));\\n pfr.y -= d/2.;\\n pfr.y *= d;\\n pfr.y += d/2.;\\n }\\n float size = mix(1.0, depth, 1.-progress);\\n pto = (p + vec2(-0.5, -0.5)) * vec2(size, size) + vec2(0.5, 0.5);\\n if (inBounds(pfr)) {\\n return getFromColor(pfr);\\n }\\n else if (inBounds(pto)) {\\n return getToColor(pto);\\n }\\n else {\\n return bgColor(p, pto);\\n }\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"fade\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// author: gre\\n// license: MIT\\n\\nvec4 transition (vec2 uv) {\\n return mix(\\n getFromColor(uv),\\n getToColor(uv),\\n progress\\n );\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"fadecolor\",\"paramsTypes\":{\"color\":\"vec3\",\"colorPhase\":\"float\"},\"defaultParams\":{\"color\":[0,0,0],\"colorPhase\":0.4},\"glsl\":\"// author: gre\\n// License: MIT\\nuniform vec3 color;// = vec3(0.0)\\nuniform float colorPhase/* = 0.4 */; // if 0.0, there is no black phase, if 0.9, the black phase is very important\\nvec4 transition (vec2 uv) {\\n return mix(\\n mix(vec4(color, 1.0), getFromColor(uv), smoothstep(1.0-colorPhase, 0.0, progress)),\\n mix(vec4(color, 1.0), getToColor(uv), smoothstep( colorPhase, 1.0, progress)),\\n progress);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"fadegrayscale\",\"paramsTypes\":{\"intensity\":\"float\"},\"defaultParams\":{\"intensity\":0.3},\"glsl\":\"// Author: gre\\n// License: MIT\\n\\nuniform float intensity; // = 0.3; // if 0.0, the image directly turn grayscale, if 0.9, the grayscale transition phase is very important\\n \\nvec3 grayscale (vec3 color) {\\n return vec3(0.2126*color.r + 0.7152*color.g + 0.0722*color.b);\\n}\\n \\nvec4 transition (vec2 uv) {\\n vec4 fc = getFromColor(uv);\\n vec4 tc = getToColor(uv);\\n return mix(\\n mix(vec4(grayscale(fc.rgb), 1.0), fc, smoothstep(1.0-intensity, 0.0, progress)),\\n mix(vec4(grayscale(tc.rgb), 1.0), tc, smoothstep( intensity, 1.0, progress)),\\n progress);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"flyeye\",\"paramsTypes\":{\"size\":\"float\",\"zoom\":\"float\",\"colorSeparation\":\"float\"},\"defaultParams\":{\"size\":0.04,\"zoom\":50,\"colorSeparation\":0.3},\"glsl\":\"// Author: gre\\n// License: MIT\\nuniform float size; // = 0.04\\nuniform float zoom; // = 50.0\\nuniform float colorSeparation; // = 0.3\\n\\nvec4 transition(vec2 p) {\\n float inv = 1. - progress;\\n vec2 disp = size*vec2(cos(zoom*p.x), sin(zoom*p.y));\\n vec4 texTo = getToColor(p + inv*disp);\\n vec4 texFrom = vec4(\\n getFromColor(p + progress*disp*(1.0 - colorSeparation)).r,\\n getFromColor(p + progress*disp).g,\\n getFromColor(p + progress*disp*(1.0 + colorSeparation)).b,\\n 1.0);\\n return texTo*progress + texFrom*inv;\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"heart\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: gre\\n// License: MIT\\n\\nfloat inHeart (vec2 p, vec2 center, float size) {\\n if (size==0.0) return 0.0;\\n vec2 o = (p-center)/(1.6*size);\\n float a = o.x*o.x+o.y*o.y-0.3;\\n return step(a*a*a, o.x*o.x*o.y*o.y*o.y);\\n}\\nvec4 transition (vec2 uv) {\\n return mix(\\n getFromColor(uv),\\n getToColor(uv),\\n inHeart(uv, vec2(0.5, 0.4), progress)\\n );\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"hexagonalize\",\"paramsTypes\":{\"steps\":\"int\",\"horizontalHexagons\":\"float\"},\"defaultParams\":{\"steps\":50,\"horizontalHexagons\":20},\"glsl\":\"// Author: Fernando Kuteken\\n// License: MIT\\n// Hexagonal math from: http://www.redblobgames.com/grids/hexagons/\\n\\nuniform int steps; // = 50;\\nuniform float horizontalHexagons; //= 20;\\n\\nstruct Hexagon {\\n float q;\\n float r;\\n float s;\\n};\\n\\nHexagon createHexagon(float q, float r){\\n Hexagon hex;\\n hex.q = q;\\n hex.r = r;\\n hex.s = -q - r;\\n return hex;\\n}\\n\\nHexagon roundHexagon(Hexagon hex){\\n \\n float q = floor(hex.q + 0.5);\\n float r = floor(hex.r + 0.5);\\n float s = floor(hex.s + 0.5);\\n\\n float deltaQ = abs(q - hex.q);\\n float deltaR = abs(r - hex.r);\\n float deltaS = abs(s - hex.s);\\n\\n if (deltaQ > deltaR && deltaQ > deltaS)\\n q = -r - s;\\n else if (deltaR > deltaS)\\n r = -q - s;\\n else\\n s = -q - r;\\n\\n return createHexagon(q, r);\\n}\\n\\nHexagon hexagonFromPoint(vec2 point, float size) {\\n \\n point.y /= ratio;\\n point = (point - 0.5) / size;\\n \\n float q = (sqrt(3.0) / 3.0) * point.x + (-1.0 / 3.0) * point.y;\\n float r = 0.0 * point.x + 2.0 / 3.0 * point.y;\\n\\n Hexagon hex = createHexagon(q, r);\\n return roundHexagon(hex);\\n \\n}\\n\\nvec2 pointFromHexagon(Hexagon hex, float size) {\\n \\n float x = (sqrt(3.0) * hex.q + (sqrt(3.0) / 2.0) * hex.r) * size + 0.5;\\n float y = (0.0 * hex.q + (3.0 / 2.0) * hex.r) * size + 0.5;\\n \\n return vec2(x, y * ratio);\\n}\\n\\nvec4 transition (vec2 uv) {\\n \\n float dist = 2.0 * min(progress, 1.0 - progress);\\n dist = steps > 0 ? ceil(dist * float(steps)) / float(steps) : dist;\\n \\n float size = (sqrt(3.0) / 3.0) * dist / horizontalHexagons;\\n \\n vec2 point = dist > 0.0 ? pointFromHexagon(hexagonFromPoint(uv, size), size) : uv;\\n\\n return mix(getFromColor(point), getToColor(point), progress);\\n \\n}\\n\",\"author\":\"Fernando Kuteken\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 21:55:47 -0300\",\"updatedAt\":\"Tue, 30 May 2017 21:55:47 -0300\"},{\"name\":\"kaleidoscope\",\"paramsTypes\":{\"speed\":\"float\",\"angle\":\"float\",\"power\":\"float\"},\"defaultParams\":{\"speed\":1,\"angle\":1,\"power\":1.5},\"glsl\":\"// Author: nwoeanhinnogaehr\\n// License: MIT\\n\\nuniform float speed; // = 1.0;\\nuniform float angle; // = 1.0;\\nuniform float power; // = 1.5;\\n\\nvec4 transition(vec2 uv) {\\n vec2 p = uv.xy / vec2(1.0).xy;\\n vec2 q = p;\\n float t = pow(progress, power)*speed;\\n p = p -0.5;\\n for (int i = 0; i < 7; i++) {\\n p = vec2(sin(t)*p.x + cos(t)*p.y, sin(t)*p.y - cos(t)*p.x);\\n t += angle;\\n p = abs(mod(p, 2.0) - 1.0);\\n }\\n abs(mod(p, 1.0));\\n return mix(\\n mix(getFromColor(q), getToColor(q), progress),\\n mix(getFromColor(p), getToColor(p), progress), 1.0 - 2.0*abs(progress - 0.5));\\n}\\n\",\"author\":\"nwoeanhinnogaehr\",\"license\":\"MIT\",\"createdAt\":\"Wed, 31 May 2017 21:48:26 -0400\",\"updatedAt\":\"Wed, 31 May 2017 21:48:26 -0400\"},{\"name\":\"luma\",\"paramsTypes\":{\"luma\":\"sampler2D\"},\"defaultParams\":{\"luma\":null},\"glsl\":\"// Author: gre\\n// License: MIT\\n\\nuniform sampler2D luma;\\n\\nvec4 transition(vec2 uv) {\\n return mix(\\n getToColor(uv),\\n getFromColor(uv),\\n step(progress, texture2D(luma, uv).r)\\n );\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"luminance_melt\",\"paramsTypes\":{\"direction\":\"bool\",\"l_threshold\":\"float\",\"above\":\"bool\"},\"defaultParams\":{\"direction\":true,\"l_threshold\":0.8,\"above\":false},\"glsl\":\"// Author: 0gust1\\n// License: MIT\\n//My own first transition \u2014 based on crosshatch code (from pthrasher), using simplex noise formula (copied and pasted)\\n//-> cooler with high contrasted images (isolated dark subject on light background f.e.)\\n//TODO : try to rebase it on DoomTransition (from zeh)?\\n//optimizations :\\n//luminance (see http://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color#answer-596241)\\n// Y = (R+R+B+G+G+G)/6\\n//or Y = (R+R+R+B+G+G+G+G)>>3 \\n\\n\\n//direction of movement : 0 : up, 1, down\\nuniform bool direction; // = 1 \\n//luminance threshold\\nuniform float l_threshold; // = 0.8 \\n//does the movement takes effect above or below luminance threshold ?\\nuniform bool above; // = false \\n\\n\\n//Random function borrowed from everywhere\\nfloat rand(vec2 co){\\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\\n}\\n\\n\\n// Simplex noise :\\n// Description : Array and textureless GLSL 2D simplex noise function.\\n// Author : Ian McEwan, Ashima Arts.\\n// Maintainer : ijm\\n// Lastmod : 20110822 (ijm)\\n// License : MIT \\n// 2011 Ashima Arts. All rights reserved.\\n// Distributed under the MIT License. See LICENSE file.\\n// https://github.com/ashima/webgl-noise\\n// \\n\\nvec3 mod289(vec3 x) {\\n return x - floor(x * (1.0 / 289.0)) * 289.0;\\n}\\n\\nvec2 mod289(vec2 x) {\\n return x - floor(x * (1.0 / 289.0)) * 289.0;\\n}\\n\\nvec3 permute(vec3 x) {\\n return mod289(((x*34.0)+1.0)*x);\\n}\\n\\nfloat snoise(vec2 v)\\n {\\n const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0\\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\\n -0.577350269189626, // -1.0 + 2.0 * C.x\\n 0.024390243902439); // 1.0 / 41.0\\n// First corner\\n vec2 i = floor(v + dot(v, C.yy) );\\n vec2 x0 = v - i + dot(i, C.xx);\\n\\n// Other corners\\n vec2 i1;\\n //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0\\n //i1.y = 1.0 - i1.x;\\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\\n // x0 = x0 - 0.0 + 0.0 * C.xx ;\\n // x1 = x0 - i1 + 1.0 * C.xx ;\\n // x2 = x0 - 1.0 + 2.0 * C.xx ;\\n vec4 x12 = x0.xyxy + C.xxzz;\\n x12.xy -= i1;\\n\\n// Permutations\\n i = mod289(i); // Avoid truncation effects in permutation\\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\\n\\t\\t+ i.x + vec3(0.0, i1.x, 1.0 ));\\n\\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\\n m = m*m ;\\n m = m*m ;\\n\\n// Gradients: 41 points uniformly over a line, mapped onto a diamond.\\n// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)\\n\\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\\n vec3 h = abs(x) - 0.5;\\n vec3 ox = floor(x + 0.5);\\n vec3 a0 = x - ox;\\n\\n// Normalise gradients implicitly by scaling m\\n// Approximation of: m *= inversesqrt( a0*a0 + h*h );\\n m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\\n\\n// Compute final noise value at P\\n vec3 g;\\n g.x = a0.x * x0.x + h.x * x0.y;\\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\\n return 130.0 * dot(m, g);\\n}\\n\\n// Simplex noise -- end\\n\\nfloat luminance(vec4 color){\\n //(0.299*R + 0.587*G + 0.114*B)\\n return color.r*0.299+color.g*0.587+color.b*0.114;\\n}\\n\\nvec2 center = vec2(1.0, direction);\\n\\nvec4 transition(vec2 uv) {\\n vec2 p = uv.xy / vec2(1.0).xy;\\n if (progress == 0.0) {\\n return getFromColor(p);\\n } else if (progress == 1.0) {\\n return getToColor(p);\\n } else {\\n float x = progress;\\n float dist = distance(center, p)- progress*exp(snoise(vec2(p.x, 0.0)));\\n float r = x - rand(vec2(p.x, 0.1));\\n float m;\\n if(above){\\n m = dist <= r && luminance(getFromColor(p))>l_threshold ? 1.0 : (progress*progress*progress);\\n }\\n else{\\n m = dist <= r && luminance(getFromColor(p))<l_threshold ? 1.0 : (progress*progress*progress); \\n }\\n return mix(getFromColor(p), getToColor(p), m); \\n }\\n}\\n\",\"author\":\"0gust1\",\"license\":\"MIT\",\"createdAt\":\"Wed, 24 Jan 2018 19:02:32 +0100\",\"updatedAt\":\"Wed, 24 Jan 2018 19:02:32 +0100\"},{\"name\":\"morph\",\"paramsTypes\":{\"strength\":\"float\"},\"defaultParams\":{\"strength\":0.1},\"glsl\":\"// Author: paniq\\n// License: MIT\\nuniform float strength; // = 0.1\\n\\nvec4 transition(vec2 p) {\\n vec4 ca = getFromColor(p);\\n vec4 cb = getToColor(p);\\n \\n vec2 oa = (((ca.rg+ca.b)*0.5)*2.0-1.0);\\n vec2 ob = (((cb.rg+cb.b)*0.5)*2.0-1.0);\\n vec2 oc = mix(oa,ob,0.5)*strength;\\n \\n float w0 = progress;\\n float w1 = 1.0-w0;\\n return mix(getFromColor(p+oc*w0), getToColor(p-oc*w1), progress);\\n}\\n\",\"author\":\"paniq\",\"license\":\"MIT\",\"createdAt\":\"Thu, 10 Aug 2017 00:27:36 +0200\",\"updatedAt\":\"Thu, 10 Aug 2017 00:32:01 +0200\"},{\"name\":\"multiply_blend\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: Fernando Kuteken\\n// License: MIT\\n\\nvec4 blend(vec4 a, vec4 b) {\\n return a * b;\\n}\\n\\nvec4 transition (vec2 uv) {\\n \\n vec4 blended = blend(getFromColor(uv), getToColor(uv));\\n \\n if (progress < 0.5)\\n return mix(getFromColor(uv), blended, 2.0 * progress);\\n else\\n return mix(blended, getToColor(uv), 2.0 * progress - 1.0);\\n}\\n\\n\",\"author\":\"Fernando Kuteken\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"perlin\",\"paramsTypes\":{\"scale\":\"float\",\"smoothness\":\"float\",\"seed\":\"float\"},\"defaultParams\":{\"scale\":4,\"smoothness\":0.01,\"seed\":12.9898},\"glsl\":\"// Author: Rich Harris\\n// License: MIT\\n\\n#ifdef GL_ES\\nprecision mediump float;\\n#endif\\n\\nuniform float scale; // = 4.0\\nuniform float smoothness; // = 0.01\\n\\nuniform float seed; // = 12.9898\\n\\n// http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/\\nfloat random(vec2 co)\\n{\\n highp float a = seed;\\n highp float b = 78.233;\\n highp float c = 43758.5453;\\n highp float dt= dot(co.xy ,vec2(a,b));\\n highp float sn= mod(dt,3.14);\\n return fract(sin(sn) * c);\\n}\\n\\n// 2D Noise based on Morgan McGuire @morgan3d\\n// https://www.shadertoy.com/view/4dS3Wd\\nfloat noise (in vec2 st) {\\n vec2 i = floor(st);\\n vec2 f = fract(st);\\n\\n // Four corners in 2D of a tile\\n float a = random(i);\\n float b = random(i + vec2(1.0, 0.0));\\n float c = random(i + vec2(0.0, 1.0));\\n float d = random(i + vec2(1.0, 1.0));\\n\\n // Smooth Interpolation\\n\\n // Cubic Hermine Curve. Same as SmoothStep()\\n vec2 u = f*f*(3.0-2.0*f);\\n // u = smoothstep(0.,1.,f);\\n\\n // Mix 4 coorners porcentages\\n return mix(a, b, u.x) +\\n (c - a)* u.y * (1.0 - u.x) +\\n (d - b) * u.x * u.y;\\n}\\n\\nvec4 transition (vec2 uv) {\\n vec4 from = getFromColor(uv);\\n vec4 to = getToColor(uv);\\n float n = noise(uv * scale);\\n \\n float p = mix(-smoothness, 1.0 + smoothness, progress);\\n float lower = p - smoothness;\\n float higher = p + smoothness;\\n \\n float q = smoothstep(lower, higher, n);\\n \\n return mix(\\n from,\\n to,\\n 1.0 - q\\n );\\n}\\n\",\"author\":\"Rich Harris\",\"license\":\"MIT\",\"createdAt\":\"Tue, 23 Jan 2018 21:35:10 -0500\",\"updatedAt\":\"Wed, 24 Jan 2018 07:35:04 -0500\"},{\"name\":\"pinwheel\",\"paramsTypes\":{\"speed\":\"float\"},\"defaultParams\":{\"speed\":2},\"glsl\":\"// Author: Mr Speaker\\n// License: MIT\\n\\nuniform float speed; // = 2.0;\\n\\nvec4 transition(vec2 uv) {\\n \\n vec2 p = uv.xy / vec2(1.0).xy;\\n \\n float circPos = atan(p.y - 0.5, p.x - 0.5) + progress * speed;\\n float modPos = mod(circPos, 3.1415 / 4.);\\n float signed = sign(progress - modPos);\\n \\n return mix(getToColor(p), getFromColor(p), step(signed, 0.5));\\n \\n}\\n\",\"author\":\"Mr Speaker\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 09:04:31 -0400\",\"updatedAt\":\"Tue, 30 May 2017 09:04:31 -0400\"},{\"name\":\"pixelize\",\"paramsTypes\":{\"squaresMin\":\"ivec2\",\"steps\":\"int\"},\"defaultParams\":{\"squaresMin\":[20,20],\"steps\":50},\"glsl\":\"// Author: gre\\n// License: MIT\\n// forked from https://gist.github.com/benraziel/c528607361d90a072e98\\n\\nuniform ivec2 squaresMin/* = ivec2(20) */; // minimum number of squares (when the effect is at its higher level)\\nuniform int steps /* = 50 */; // zero disable the stepping\\n\\nfloat d = min(progress, 1.0 - progress);\\nfloat dist = steps>0 ? ceil(d * float(steps)) / float(steps) : d;\\nvec2 squareSize = 2.0 * dist / vec2(squaresMin);\\n\\nvec4 transition(vec2 uv) {\\n vec2 p = dist>0.0 ? (floor(uv / squareSize) + 0.5) * squareSize : uv;\\n return mix(getFromColor(p), getToColor(p), progress);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Wed, 31 May 2017 10:58:26 +0200\"},{\"name\":\"polar_function\",\"paramsTypes\":{\"segments\":\"int\"},\"defaultParams\":{\"segments\":5},\"glsl\":\"// Author: Fernando Kuteken\\n// License: MIT\\n\\n#define PI 3.14159265359\\n\\nuniform int segments; // = 5;\\n\\nvec4 transition (vec2 uv) {\\n \\n float angle = atan(uv.y - 0.5, uv.x - 0.5) - 0.5 * PI;\\n float normalized = (angle + 1.5 * PI) * (2.0 * PI);\\n \\n float radius = (cos(float(segments) * angle) + 4.0) / 4.0;\\n float difference = length(uv - vec2(0.5, 0.5));\\n \\n if (difference > radius * progress)\\n return getFromColor(uv);\\n else\\n return getToColor(uv);\\n}\\n\",\"author\":\"Fernando Kuteken\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"randomsquares\",\"paramsTypes\":{\"size\":\"ivec2\",\"smoothness\":\"float\"},\"defaultParams\":{\"size\":[10,10],\"smoothness\":0.5},\"glsl\":\"// Author: gre\\n// License: MIT\\n\\nuniform ivec2 size; // = ivec2(10, 10)\\nuniform float smoothness; // = 0.5\\n \\nfloat rand (vec2 co) {\\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\\n}\\n\\nvec4 transition(vec2 p) {\\n float r = rand(floor(vec2(size) * p));\\n float m = smoothstep(0.0, -smoothness, r - (progress * (1.0 + smoothness)));\\n return mix(getFromColor(p), getToColor(p), m);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"ripple\",\"paramsTypes\":{\"amplitude\":\"float\",\"speed\":\"float\"},\"defaultParams\":{\"amplitude\":100,\"speed\":50},\"glsl\":\"// Author: gre\\n// License: MIT\\nuniform float amplitude; // = 100.0\\nuniform float speed; // = 50.0\\n\\nvec4 transition (vec2 uv) {\\n vec2 dir = uv - vec2(.5);\\n float dist = length(dir);\\n vec2 offset = dir * (sin(progress * dist * amplitude - progress * speed) + .5) / 30.;\\n return mix(\\n getFromColor(uv + offset),\\n getToColor(uv),\\n smoothstep(0.2, 1.0, progress)\\n );\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 15:15:27 +0200\",\"updatedAt\":\"Tue, 30 May 2017 15:15:27 +0200\"},{\"name\":\"rotate_scale_fade\",\"paramsTypes\":{\"center\":\"vec2\",\"rotations\":\"float\",\"scale\":\"float\",\"backColor\":\"vec4\"},\"defaultParams\":{\"center\":[0.5,0.5],\"rotations\":1,\"scale\":8,\"backColor\":[0.15,0.15,0.15,1]},\"glsl\":\"// Author: Fernando Kuteken\\n// License: MIT\\n\\n#define PI 3.14159265359\\n\\nuniform vec2 center; // = vec2(0.5, 0.5);\\nuniform float rotations; // = 1;\\nuniform float scale; // = 8;\\nuniform vec4 backColor; // = vec4(0.15, 0.15, 0.15, 1.0);\\n\\nvec4 transition (vec2 uv) {\\n \\n vec2 difference = uv - center;\\n vec2 dir = normalize(difference);\\n float dist = length(difference);\\n \\n float angle = 2.0 * PI * rotations * progress;\\n \\n float c = cos(angle);\\n float s = sin(angle);\\n \\n float currentScale = mix(scale, 1.0, 2.0 * abs(progress - 0.5));\\n \\n vec2 rotatedDir = vec2(dir.x * c - dir.y * s, dir.x * s + dir.y * c);\\n vec2 rotatedUv = center + rotatedDir * dist / currentScale;\\n \\n if (rotatedUv.x < 0.0 || rotatedUv.x > 1.0 ||\\n rotatedUv.y < 0.0 || rotatedUv.y > 1.0)\\n return backColor;\\n \\n return mix(getFromColor(rotatedUv), getToColor(rotatedUv), progress);\\n}\\n\",\"author\":\"Fernando Kuteken\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"squareswire\",\"paramsTypes\":{\"squares\":\"ivec2\",\"direction\":\"vec2\",\"smoothness\":\"float\"},\"defaultParams\":{\"squares\":[10,10],\"direction\":[1,-0.5],\"smoothness\":1.6},\"glsl\":\"// Author: gre\\n// License: MIT\\n \\nuniform ivec2 squares;// = ivec2(10,10)\\nuniform vec2 direction;// = vec2(1.0, -0.5)\\nuniform float smoothness; // = 1.6\\n\\nconst vec2 center = vec2(0.5, 0.5);\\nvec4 transition (vec2 p) {\\n vec2 v = normalize(direction);\\n v /= abs(v.x)+abs(v.y);\\n float d = v.x * center.x + v.y * center.y;\\n float offset = smoothness;\\n float pr = smoothstep(-offset, 0.0, v.x * p.x + v.y * p.y - (d-0.5+progress*(1.+offset)));\\n vec2 squarep = fract(p*vec2(squares));\\n vec2 squaremin = vec2(pr/2.0);\\n vec2 squaremax = vec2(1.0 - pr/2.0);\\n float a = (1.0 - step(progress, 0.0)) * step(squaremin.x, squarep.x) * step(squaremin.y, squarep.y) * step(squarep.x, squaremax.x) * step(squarep.y, squaremax.y);\\n return mix(getFromColor(p), getToColor(p), a);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"squeeze\",\"paramsTypes\":{\"colorSeparation\":\"float\"},\"defaultParams\":{\"colorSeparation\":0.04},\"glsl\":\"// Author: gre\\n// License: MIT\\n \\nuniform float colorSeparation; // = 0.04\\n \\nvec4 transition (vec2 uv) {\\n float y = 0.5 + (uv.y-0.5) / (1.0-progress);\\n if (y < 0.0 || y > 1.0) {\\n return getToColor(uv);\\n }\\n else {\\n vec2 fp = vec2(uv.x, y);\\n vec2 off = progress * vec2(0.0, colorSeparation);\\n vec4 c = getFromColor(fp);\\n vec4 cn = getFromColor(fp - off);\\n vec4 cp = getFromColor(fp + off);\\n return vec4(cn.r, c.g, cp.b, c.a);\\n }\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"swap\",\"paramsTypes\":{\"reflection\":\"float\",\"perspective\":\"float\",\"depth\":\"float\"},\"defaultParams\":{\"reflection\":0.4,\"perspective\":0.2,\"depth\":3},\"glsl\":\"// Author: gre\\n// License: MIT\\n// General parameters\\nuniform float reflection; // = 0.4\\nuniform float perspective; // = 0.2\\nuniform float depth; // = 3.0\\n \\nconst vec4 black = vec4(0.0, 0.0, 0.0, 1.0);\\nconst vec2 boundMin = vec2(0.0, 0.0);\\nconst vec2 boundMax = vec2(1.0, 1.0);\\n \\nbool inBounds (vec2 p) {\\n return all(lessThan(boundMin, p)) && all(lessThan(p, boundMax));\\n}\\n \\nvec2 project (vec2 p) {\\n return p * vec2(1.0, -1.2) + vec2(0.0, -0.02);\\n}\\n \\nvec4 bgColor (vec2 p, vec2 pfr, vec2 pto) {\\n vec4 c = black;\\n pfr = project(pfr);\\n if (inBounds(pfr)) {\\n c += mix(black, getFromColor(pfr), reflection * mix(1.0, 0.0, pfr.y));\\n }\\n pto = project(pto);\\n if (inBounds(pto)) {\\n c += mix(black, getToColor(pto), reflection * mix(1.0, 0.0, pto.y));\\n }\\n return c;\\n}\\n \\nvec4 transition(vec2 p) {\\n vec2 pfr, pto = vec2(-1.);\\n \\n float size = mix(1.0, depth, progress);\\n float persp = perspective * progress;\\n pfr = (p + vec2(-0.0, -0.5)) * vec2(size/(1.0-perspective*progress), size/(1.0-size*persp*p.x)) + vec2(0.0, 0.5);\\n \\n size = mix(1.0, depth, 1.-progress);\\n persp = perspective * (1.-progress);\\n pto = (p + vec2(-1.0, -0.5)) * vec2(size/(1.0-perspective*(1.0-progress)), size/(1.0-size*persp*(0.5-p.x))) + vec2(1.0, 0.5);\\n\\n if (progress < 0.5) {\\n if (inBounds(pfr)) {\\n return getFromColor(pfr);\\n }\\n if (inBounds(pto)) {\\n return getToColor(pto);\\n } \\n }\\n if (inBounds(pto)) {\\n return getToColor(pto);\\n }\\n if (inBounds(pfr)) {\\n return getFromColor(pfr);\\n }\\n return bgColor(p, pfr, pto);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Sun, 18 Feb 2018 17:45:50 +0100\"},{\"name\":\"undulatingBurnOut\",\"paramsTypes\":{\"smoothness\":\"float\",\"center\":\"vec2\",\"color\":\"vec3\"},\"defaultParams\":{\"smoothness\":0.03,\"center\":[0.5,0.5],\"color\":[0,0,0]},\"glsl\":\"// License: MIT\\n// Author: pthrasher\\n// adapted by gre from https://gist.github.com/pthrasher/8e6226b215548ba12734\\n\\nuniform float smoothness; // = 0.03\\nuniform vec2 center; // = vec2(0.5)\\nuniform vec3 color; // = vec3(0.0)\\n\\nconst float M_PI = 3.14159265358979323846;\\n\\nfloat quadraticInOut(float t) {\\n float p = 2.0 * t * t;\\n return t < 0.5 ? p : -p + (4.0 * t) - 1.0;\\n}\\n\\nfloat getGradient(float r, float dist) {\\n float d = r - dist;\\n return mix(\\n smoothstep(-smoothness, 0.0, r - dist * (1.0 + smoothness)),\\n -1.0 - step(0.005, d),\\n step(-0.005, d) * step(d, 0.01)\\n );\\n}\\n\\nfloat getWave(vec2 p){\\n vec2 _p = p - center; // offset from center\\n float rads = atan(_p.y, _p.x);\\n float degs = degrees(rads) + 180.0;\\n vec2 range = vec2(0.0, M_PI * 30.0);\\n vec2 domain = vec2(0.0, 360.0);\\n float ratio = (M_PI * 30.0) / 360.0;\\n degs = degs * ratio;\\n float x = progress;\\n float magnitude = mix(0.02, 0.09, smoothstep(0.0, 1.0, x));\\n float offset = mix(40.0, 30.0, smoothstep(0.0, 1.0, x));\\n float ease_degs = quadraticInOut(sin(degs));\\n float deg_wave_pos = (ease_degs * magnitude) * sin(x * offset);\\n return x + deg_wave_pos;\\n}\\n\\nvec4 transition(vec2 p) {\\n float dist = distance(center, p);\\n float m = getGradient(getWave(p), dist);\\n vec4 cfrom = getFromColor(p);\\n vec4 cto = getToColor(p);\\n return mix(mix(cfrom, cto, m), mix(cfrom, vec4(color, 1.0), 0.75), step(m, -2.0));\\n}\\n\",\"license\":\"MIT\",\"author\":\"pthrasher\",\"createdAt\":\"Mon, 12 Jun 2017 10:23:37 +0800\",\"updatedAt\":\"Mon, 12 Jun 2017 10:23:37 +0800\"},{\"name\":\"wind\",\"paramsTypes\":{\"size\":\"float\"},\"defaultParams\":{\"size\":0.2},\"glsl\":\"// Author: gre\\n// License: MIT\\n\\n// Custom parameters\\nuniform float size; // = 0.2\\n\\nfloat rand (vec2 co) {\\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\\n}\\n\\nvec4 transition (vec2 uv) {\\n float r = rand(vec2(0, uv.y));\\n float m = smoothstep(0.0, -size, uv.x*(1.0-size) + size*r - (progress * (1.0 + size)));\\n return mix(\\n getFromColor(uv),\\n getToColor(uv),\\n m\\n );\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Tue, 30 May 2017 14:26:44 +0200\",\"updatedAt\":\"Tue, 30 May 2017 14:26:44 +0200\"},{\"name\":\"windowblinds\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: Fabien Benetou\\n// License: MIT\\n\\nvec4 transition (vec2 uv) {\\n float t = progress;\\n \\n if (mod(floor(uv.y*100.*progress),2.)==0.)\\n t*=2.-.5;\\n \\n return mix(\\n getFromColor(uv),\\n getToColor(uv),\\n mix(t, progress, smoothstep(0.8, 1.0, progress))\\n );\\n}\\n\",\"author\":\"Fabien Benetou\",\"license\":\"MIT\",\"createdAt\":\"Wed, 31 May 2017 14:11:48 +0200\",\"updatedAt\":\"Wed, 31 May 2017 14:11:48 +0200\"},{\"name\":\"windowslice\",\"paramsTypes\":{\"count\":\"float\",\"smoothness\":\"float\"},\"defaultParams\":{\"count\":10,\"smoothness\":0.5},\"glsl\":\"// Author: gre\\n// License: MIT\\n\\nuniform float count; // = 10.0\\nuniform float smoothness; // = 0.5\\n\\nvec4 transition (vec2 p) {\\n float pr = smoothstep(-smoothness, 0.0, p.x - progress * (1.0 + smoothness));\\n float s = step(pr, fract(count * p.x));\\n return mix(getFromColor(p), getToColor(p), s);\\n}\\n\",\"author\":\"gre\",\"license\":\"MIT\",\"createdAt\":\"Wed, 28 Mar 2018 17:23:26 +0200\",\"updatedAt\":\"Wed, 28 Mar 2018 17:23:26 +0200\"},{\"name\":\"wipeDown\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: Jake Nelson\\n// License: MIT\\n\\nvec4 transition(vec2 uv) {\\n vec2 p=uv.xy/vec2(1.0).xy;\\n vec4 a=getFromColor(p);\\n vec4 b=getToColor(p);\\n return mix(a, b, step(1.0-p.y,progress));\\n}\\n\",\"author\":\"Jake Nelson\",\"license\":\"MIT\",\"createdAt\":\"Wed, 1 Nov 2017 15:26:01 -0500\",\"updatedAt\":\"Thu, 2 Nov 2017 18:39:26 -0500\"},{\"name\":\"wipeLeft\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: Jake Nelson\\n// License: MIT\\n\\nvec4 transition(vec2 uv) {\\n vec2 p=uv.xy/vec2(1.0).xy;\\n vec4 a=getFromColor(p);\\n vec4 b=getToColor(p);\\n return mix(a, b, step(1.0-p.x,progress));\\n}\\n\",\"author\":\"Jake Nelson\",\"license\":\"MIT\",\"createdAt\":\"Wed, 1 Nov 2017 15:26:28 -0500\",\"updatedAt\":\"Fri, 3 Nov 2017 18:03:50 +0100\"},{\"name\":\"wipeRight\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: Jake Nelson\\n// License: MIT\\n\\nvec4 transition(vec2 uv) {\\n vec2 p=uv.xy/vec2(1.0).xy;\\n vec4 a=getFromColor(p);\\n vec4 b=getToColor(p);\\n return mix(a, b, step(0.0+p.x,progress));\\n}\\n\",\"author\":\"Jake Nelson\",\"license\":\"MIT\",\"createdAt\":\"Wed, 1 Nov 2017 15:27:02 -0500\",\"updatedAt\":\"Thu, 2 Nov 2017 18:40:22 -0500\"},{\"name\":\"wipeUp\",\"paramsTypes\":{},\"defaultParams\":{},\"glsl\":\"// Author: Jake Nelson\\n// License: MIT\\n\\nvec4 transition(vec2 uv) {\\n vec2 p=uv.xy/vec2(1.0).xy;\\n vec4 a=getFromColor(p);\\n vec4 b=getToColor(p);\\n return mix(a, b, step(0.0+p.y,progress));\\n}\\n\",\"author\":\"Jake Nelson\",\"license\":\"MIT\",\"createdAt\":\"Wed, 1 Nov 2017 15:24:36 -0500\",\"updatedAt\":\"Thu, 2 Nov 2017 18:37:42 -0500\"}]", "\nexport * from \"./execution/execute.js\"\n\nexport * from \"./expectation/errors.js\"\nexport * from \"./expectation/expect.js\"\n\nexport * from \"./presentation/coloring.js\"\nexport * from \"./presentation/deliver.js\"\nexport * from \"./presentation/summarize.js\"\nexport * from \"./presentation/supports.js\"\nexport * from \"./presentation/themes.js\"\nexport * from \"./presentation/types.js\"\n\nexport * from \"./spycraft/spy.js\"\n\nexport * from \"./run.js\"\nexport * from \"./test.js\"\nexport * from \"./tests.js\"\nexport * from \"./types.js\"\n\n", "\nexport function plural(x: number, one = \"\", many = \"s\") {\n\treturn (x === 1) ? one : many\n}\n\nexport function ms(t: number) {\n\treturn `${t.toFixed(0)} ms`\n}\n\nexport function chunkify<I>(array: I[], size: number): I[][] {\n\tconst chunks: I[][] = []\n\tlet currentChunk: I[] = []\n\n\tfunction commit() {\n\t\tif (currentChunk.length > 0) {\n\t\t\tchunks.push(currentChunk)\n\t\t\tcurrentChunk = []\n\t\t}\n\t}\n\n\tfor (const item of array) {\n\t\tcurrentChunk.push(item)\n\t\tif (currentChunk.length >= size)\n\t\t\tcommit()\n\t}\n\n\tcommit()\n\treturn chunks\n}\n\n", "\nexport class Fail extends Error {\n\tname = this.constructor.name\n}\n\n", "\nimport {Fail} from \"./errors.js\"\n\nexport const makeExpectations = (a: any) => ({\n\tok: () => !!a,\n\tavailable: () => a !== undefined && a !== null,\n\tnullish: () => a === undefined || a === null,\n\thappy: () => a !== undefined && a !== null,\n\tsad: () => a === undefined || a === null,\n\tis: (b: any) => a === b,\n\tisnt: (b: any) => a !== b,\n\tgt: (b: any) => a > b,\n\tgte: (b: any) => a >= b,\n\tlt: (b: any) => a < b,\n\tlte: (b: any) => a <= b,\n\n\tthrows: (ErrorClass?: new(...a: any[]) => any) => {\n\t\ttry {\n\t\t\tif (typeof a !== \"function\")\n\t\t\t\tthrow new Fail(\".throws() requires a function\")\n\t\t\ta()\n\t\t\treturn false\n\t\t}\n\t\tcatch (error) {\n\t\t\tif (ErrorClass && !(error instanceof ErrorClass))\n\t\t\t\treturn false\n\t\t\treturn true\n\t\t}\n\t},\n\n\tthrowsAsync: async(ErrorClass?: new(...params: any[]) => any) => {\n\t\ttry {\n\t\t\tif (typeof a !== \"function\")\n\t\t\t\tthrow new Fail(\".throwsAsync() requires an async function\")\n\t\t\tconst promise = a()\n\t\t\tif (!(promise instanceof Promise))\n\t\t\t\tthrow new Fail(\".throwsAsync() requires an *async* function\")\n\t\t\tawait promise\n\t\t\treturn false\n\t\t}\n\t\tcatch (error) {\n\t\t\tif (ErrorClass && !(error instanceof ErrorClass))\n\t\t\t\treturn false\n\t\t\treturn true\n\t\t}\n\t},\n})\n\n", "\nimport {Fail} from \"./errors.js\"\nimport {makeExpectations} from \"./expectations.js\"\n\nexport function expectancy<E extends Record<string, (...p: any[]) => (boolean | Promise<boolean>)>>(\n\t\tnot: boolean,\n\t\ta: any,\n\t\texpectations: E,\n\t\tmessage?: string,\n\t) {\n\treturn Object.fromEntries(\n\t\tObject.entries(expectations).map(([key, fn]) => {\n\t\t\tconst fn1 = fn as (...b: any[]) => (boolean | Promise<boolean>)\n\t\t\tconst fn2 = (...b: any[]) => {\n\t\t\t\tconst result = fn1(...b)\n\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\treturn result.then(r => {\n\t\t\t\t\t\tif (!r) throw new Fail(message ?? expectmessage(not, key, a, b))\n\t\t\t\t\t\treturn r\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tif (!result) throw new Fail(message ?? expectmessage(not, key, a, b))\n\t\t\t\t\treturn result\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn [key, fn2]\n\t\t})\n\t) as E\n}\n\nexport const inverseExpectations = (a: any) => {\n\tconst originals = makeExpectations(a)\n\treturn Object.fromEntries(\n\t\tObject.entries(originals).map(([key, fn]) => {\n\t\t\tconst fn1 = fn as (...p: any[]) => (boolean | Promise<boolean>)\n\t\t\tconst fn2 = (...p: any[]) => {\n\t\t\t\tconst result = fn1(...p)\n\t\t\t\treturn (result instanceof Promise)\n\t\t\t\t\t? result.then(r => !r)\n\t\t\t\t\t: !result\n\t\t\t}\n\t\t\treturn [key, fn2]\n\t\t})\n\t) as ReturnType<typeof makeExpectations>\n}\n\nfunction trunc(s: string, max = 16) {\n\treturn s.length > max\n\t\t? `${s.slice(0, max)}..`\n\t\t: s\n}\n\nexport function display(x: any) {\n\tif (typeof x === \"undefined\")\n\t\treturn \"undefined\"\n\telse if (x === null)\n\t\treturn \"null\"\n\telse if (typeof x === \"string\")\n\t\treturn `\"${trunc(x)}\"`\n\telse if (typeof x === \"number\")\n\t\treturn trunc(x.toString())\n\telse if (typeof x === \"boolean\")\n\t\treturn x ? \"true\" : \"false\"\n\telse if (typeof x === \"bigint\")\n\t\treturn trunc(x.toString())\n\telse if (typeof x === \"symbol\")\n\t\treturn trunc(x.toString())\n\telse if (typeof x === \"object\")\n\t\treturn \"obj\"\n\telse if (typeof x === \"function\")\n\t\treturn \"fn\"\n\telse\n\t\treturn \"unknown\"\n}\n\nfunction displays(p: any[]) {\n\treturn p.map(display).join(\", \")\n}\n\nfunction expectmessage(not: boolean, key: string, a: any, b: any[]) {\n\treturn not\n\t\t? `expect(${display(a)}).not.${key}(${displays(b)})`\n\t\t: `expect(${display(a)}).${key}(${displays(b)})`\n}\n\n", "\nimport {Theme} from \"./presentation/themes.js\"\n\nexport const meta = Symbol(\"meta\")\n\nexport type Options = {\n\ttheme: Theme\n\tverbose: boolean\n}\n\nexport function options(o: Partial<Options>) {\n\treturn o\n}\n\nexport type Meta = {\n\tkind?: \"only\" | \"skip\"\n}\n\nexport type Test = {\n\t(): Promise<void | boolean | string>\n\t[meta]?: Meta\n}\n\nexport class Experiment {\n\tconstructor(\n\t\tpublic time: number,\n\t\tpublic fail?: string,\n\t) {}\n}\n\nexport class Tube {\n\tconstructor(\n\t\tpublic label: string,\n\t\tpublic fn: Test,\n\t\tpublic path: string[],\n\t) {}\n\n\tget skip() {\n\t\treturn this.fn[meta]?.kind === \"skip\"\n\t}\n\n\tget only() {\n\t\treturn this.fn[meta]?.kind === \"only\"\n\t}\n}\n\nexport type Suite = {\n\t[key: string]: Test | Suite\n\t[meta]?: Meta\n}\n\n", "\nimport {meta, Suite, Test, Tube} from \"../types.js\"\n\nexport function flattenTests(tree: Suite) {\n\tconst tubes: Tube[] = []\n\n\tfunction recurse(s: Suite, path: string[]) {\n\t\tfor (const [label, value] of Object.entries(s)) {\n\t\t\tif (typeof value === \"function\") {\n\t\t\t\tconst fn = value as Test\n\t\t\t\tfn[meta] ??= s[meta] // fn inherits meta from parent suite\n\t\t\t\ttubes.push(new Tube(label, fn, path))\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconst childSuite = value as Suite\n\t\t\t\tchildSuite[meta] ??= s[meta] // suite inherits meta from parent suite\n\t\t\t\trecurse(value as Suite, [...path, label])\n\t\t\t}\n\t\t}\n\t}\n\n\trecurse(tree, [])\n\treturn tubes\n}\n\n", "\nimport {chunkify} from \"./utils.js\"\nimport {Fail} from \"../expectation/errors.js\"\nimport {display} from \"../expectation/utils.js\"\nimport {flattenTests} from \"./flatten-tests.js\"\nimport {workloadSize} from \"./workload-size.js\"\nimport {Suite, Tube, Experiment} from \"../types.js\"\n\nexport type Execution = Awaited<ReturnType<typeof execute>>\n\nexport async function execute(tree: Suite) {\n\tconst tubes = flattenTests(tree)\n\tconst nonSkipped = tubes.filter(tube => !tube.skip)\n\tconst only = nonSkipped.filter(tube => tube.only)\n\n\tconst selectedTubes = only.length > 0\n\t\t? only\n\t\t: nonSkipped\n\n\ttype Execution = {\n\t\ttube: Tube\n\t\texperiment: Experiment\n\t}\n\n\tasync function executeTube(tube: Tube): Promise<Execution> {\n\t\tconst start = performance.now()\n\t\treturn tube.fn()\n\n\t\t\t.then(result => {\n\t\t\t\tconst time = performance.now() - start\n\t\t\t\treturn {tube, experiment: {\n\t\t\t\t\ttime,\n\t\t\t\t\tfail: (\n\t\t\t\t\t\t(result === undefined) ?\n\t\t\t\t\t\t\tundefined :\n\n\t\t\t\t\t\t(result === true) ?\n\t\t\t\t\t\t\tundefined :\n\n\t\t\t\t\t\t(result === false) ?\n\t\t\t\t\t\t\t\"test returned false\" :\n\n\t\t\t\t\t\t(typeof result === \"string\") ?\n\t\t\t\t\t\t\tresult :\n\t\t\t\t\t\t\t\"test returned unknown type\"\n\t\t\t\t\t),\n\t\t\t\t}}\n\t\t\t})\n\n\t\t\t.catch(reason => {\n\t\t\t\tconst time = performance.now() - start\n\t\t\t\treturn {tube, experiment: {\n\t\t\t\t\ttime,\n\t\t\t\t\tfail: (\n\t\t\t\t\t\t(typeof reason === \"string\") ?\n\t\t\t\t\t\t\treason :\n\n\t\t\t\t\t\t(reason instanceof Fail) ?\n\t\t\t\t\t\t\treason.message :\n\n\t\t\t\t\t\t(reason instanceof Error) ?\n\t\t\t\t\t\t\t`${reason.name}: ${reason.message}` :\n\t\t\t\t\t\t\tdisplay(reason)\n\t\t\t\t\t),\n\t\t\t\t}}\n\t\t\t})\n\t}\n\n\tconst totalStart = performance.now()\n\tconst experiments = new Map<Tube, Experiment>()\n\n\tfor (const workload of chunkify([...selectedTubes], workloadSize)) {\n\t\tconst group = await Promise.all(workload.map(executeTube))\n\t\tfor (const {tube, experiment} of group)\n\t\t\texperiments.set(tube, experiment)\n\t}\n\n\tconst time = performance.now() - totalStart\n\treturn {tubes, selectedTubes, experiments, time}\n}\n\n", "\nimport {makeExpectations} from \"./expectations.js\"\nimport {expectancy, inverseExpectations} from \"./utils.js\"\n\nexport const expect = (a: any, note?: string) => ({\n\t...expectancy(false, a, makeExpectations(a), note),\n\tnot: expectancy(true, a, inverseExpectations(a), note),\n\n\tnote: (note2: string) => ({\n\t\t...expectancy(false, a, makeExpectations(a), note2),\n\t\tnot: expectancy(true, a, inverseExpectations(a), note2),\n\t}),\n})\n\n", "\nconst codes = Object.freeze({\n\n\t// regular colors\n\tblack: \"\\u001b[30m\",\n\tred: \"\\u001b[31m\",\n\tgreen: \"\\u001b[32m\",\n\tyellow: \"\\u001b[33m\",\n\tblue: \"\\u001b[34m\",\n\tmagenta: \"\\u001b[35m\",\n\tcyan: \"\\u001b[36m\",\n\twhite: \"\\u001b[37m\",\n\n\t// bright colors\n\tbrightBlack: \"\\u001b[90m\",\n\tbrightRed: \"\\u001b[91m\",\n\tbrightGreen: \"\\u001b[92m\",\n\tbrightYellow: \"\\u001b[93m\",\n\tbrightBlue: \"\\u001b[94m\",\n\tbrightMagenta: \"\\u001b[95m\",\n\tbrightCyan: \"\\u001b[96m\",\n\tbrightWhite: \"\\u001b[97m\",\n\n\t// background colors\n\tbgBlack: \"\\u001b[40m\",\n\tbgRed: \"\\u001b[41m\",\n\tbgGreen: \"\\u001b[42m\",\n\tbgYellow: \"\\u001b[43m\",\n\tbgBlue: \"\\u001b[44m\",\n\tbgMagenta: \"\\u001b[45m\",\n\tbgCyan: \"\\u001b[46m\",\n\tbgWhite: \"\\u001b[47m\",\n\n\t// bright background colors\n\tbgBrightBlack: \"\\u001b[100m\",\n\tbgBrightRed: \"\\u001b[101m\",\n\tbgBrightGreen: \"\\u001b[102m\",\n\tbgBrightYellow: \"\\u001b[103m\",\n\tbgBrightBlue: \"\\u001b[104m\",\n\tbgBrightMagenta: \"\\u001b[105m\",\n\tbgBrightCyan: \"\\u001b[106m\",\n\tbgBrightWhite: \"\\u001b[107m\",\n\n\t// styles\n\tbold: \"\\u001b[1m\",\n\tdim: \"\\u001b[2m\",\n\titalic: \"\\u001b[3m\",\n\tunderline: \"\\u001b[4m\",\n\tinverse: \"\\u001b[7m\",\n\thidden: \"\\u001b[8m\",\n\tstrikethrough: \"\\u001b[9m\",\n\n\t// reset\n\treset: \"\\u001b[0m\",\n})\n\nexport function colorHex(hex: string) {\n\thex = hex.replace(/^#/, \"\")\n\tlet bigint: number\n\tlet r: number\n\tlet g: number\n\tlet b: number\n\n\tif (hex.length === 3)\n\t\tbigint = parseInt(hex.split('').map(c => c + c).join(''), 16)\n\telse if (hex.length === 6)\n\t\tbigint = parseInt(hex, 16)\n\telse\n\t\tthrow new Error('Invalid hex color')\n\n\tr = (bigint >> 16) & 255\n\tg = (bigint >> 8) & 255\n\tb = bigint & 255\n\treturn colorRgb(r, g, b)\n}\n\nexport function colorRgb(r: number, g: number, b: number) {\n\tconst code = `\\u001b[38;2;${r};${g};${b}m`\n\treturn (s: string) => `${code}${s}${codes.reset}`\n}\n\nexport function colorBgRgb(r: number, g: number, b: number) {\n\tconst code = `\\u001b[48;2;${r};${g};${b}m`\n\treturn (s: string) => `${code}${s}${codes.reset}`\n}\n\nexport const color = {\n\tnone: (s: string) => s,\n\t...<{[key in keyof typeof codes]: (s: string) => string}>(\n\t\tObject.fromEntries(\n\t\t\tObject.entries(codes)\n\t\t\t\t.map(([key, code]) => [\n\t\t\t\t\tkey,\n\t\t\t\t\t(s: string) => `${code}${s}${codes.reset}`,\n\t\t\t\t])\n\t\t)\n\t),\n}\n\nexport function uncolor(s: string) {\n\treturn s.replace(\n\t\t/[\\u001b\\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,\n\t\t\"\",\n\t)\n}\n\n", "\nimport {Execution} from \"../execution/execute.js\"\n\nexport class Stdout {\n\tconstructor(public line: string) {}\n}\n\nexport class Stderr {\n\tconstructor(public line: string) {}\n}\n\nexport type Output = (Stdout | Stderr)\n\nexport type Summary = {\n\tcode: 0 | 1\n\toutputs: Output[]\n\texecution: Execution\n}\n\n", "\ndeclare const Deno: any\n\nexport function isDeno() {\n\treturn typeof Deno !== \"undefined\" && typeof Deno.version !== \"undefined\"\n}\n\nexport function isNode() {\n\treturn (\n\t\ttypeof process !== \"undefined\" &&\n\t\tprocess.versions &&\n\t\tprocess.versions.node\n\t)\n}\n\nexport function isColorSupported() {\n\tif (isNode())\n\t\treturn (process.env.FORCE_COLOR) || (\n\t\t\tprocess.stdout.isTTY &&\n\t\t\tprocess.env.TERM !== \"dumb\"\n\t\t)\n\n\telse if (isDeno())\n\t\treturn (Deno.env.get(\"FORCE_COLOR\")) || (\n\t\t\tDeno.isatty(Deno.stdout.rid) &&\n\t\t\tDeno.env.get(\"TERM\") !== \"dumb\"\n\t\t)\n\n\telse\n\t\treturn false\n}\n\nexport function exit(code: number) {\n\tif (isNode()) process.exit(code)\n\telse if (isDeno()) Deno.exit(code)\n}\n\nexport function setExitCode(code: number) {\n\tif (isNode()) process.exitCode = code\n\telse if (isDeno()) Deno.exitCode = code\n}\n\nexport function hasEnv(name: string): boolean {\n\tif (isNode())\n\t\treturn name in process.env\n\telse if (isDeno())\n\t\treturn Deno.env.get(name) !== undefined\n\treturn false\n}\n\nexport function hasArg(arg: string): boolean {\n\tif (isNode())\n\t\treturn process.argv.slice(1).includes(arg)\n\telse if (isDeno())\n\t\treturn Deno.args.includes(arg)\n\telse\n\t\treturn false\n}\n\nfunction findArgValue(name: string, args: string[]) {\n\tfor (const arg of args) {\n\t\tif (arg.includes(\"=\")) {\n\t\t\tconst [first, ...rest] = arg.split(\"=\")\n\t\t\tif (first === name)\n\t\t\t\treturn rest.join(\"=\")\n\t\t}\n\t}\n}\n\nexport function getArg(name: string) {\n\tif (isNode())\n\t\treturn findArgValue(name, process.argv.slice(1))\n\telse if (isDeno())\n\t\treturn findArgValue(name, Deno.args)\n}\n\nexport function getEnv(name: string): string | undefined {\n\tif (isNode())\n\t\treturn process.env[name]\n\telse if (isDeno())\n\t\treturn Deno.env.get(name)\n}\n\nexport async function writeStdout(line: string) {\n\tif (isNode())\n\t\tprocess.stdout.write(line + \"\\n\")\n\telse if (isDeno())\n\t\tawait Deno.stdout.write(new TextEncoder().encode(line + \"\\n\"))\n\telse\n\t\tconsole.log(line)\n}\n\nexport async function writeStderr(line: string) {\n\tif (isNode())\n\t\tprocess.stderr.write(line + \"\\n\")\n\telse if (isDeno())\n\t\tawait Deno.stderr.write(new TextEncoder().encode(line + \"\\n\"))\n\telse\n\t\tconsole.error(line)\n}\n\n", "\nimport {Summary, Stderr} from \"./types.js\"\nimport {setExitCode, writeStderr, writeStdout} from \"./supports.js\"\n\nexport async function deliver(summary: Summary) {\n\tfor (const output of summary.outputs) {\n\t\tif (output instanceof Stderr)\n\t\t\tawait writeStderr(output.line)\n\t\telse\n\t\t\tawait writeStdout(output.line)\n\t}\n\tsetExitCode(summary.code)\n}\n\n", "\nimport {ms, plural} from \"../execution/utils.js\"\nimport {Execution} from \"../execution/execute.js\"\nimport {Tube, Experiment, Options} from \"../types.js\"\nimport {Summary, Output, Stderr, Stdout} from \"./types.js\"\n\nexport function summarize(ex: Execution, options: Options): Summary {\n\tconst {verbose, theme: {icons, colors}} = options\n\n\tconst failures = [...ex.experiments.values()].filter(r => r.fail)\n\tconst successes = [...ex.experiments.values()].filter(r => !r.fail)\n\tconst allCount = ex.tubes.length\n\tconst happyCount = successes.length\n\tconst angryCount = failures.length\n\tconst skipCount = ex.tubes.filter(t => t.skip).length\n\tconst onlyCount = ex.tubes.filter(t => t.only).length\n\n\tconst outputs: Output[] = []\n\tconst log = (line: string) => outputs.push(new Stdout(line))\n\tconst err = (line: string) => outputs.push(new Stderr(line))\n\tlet loggedCaseCount = 0\n\n\tfunction pickIntro(tube: Tube, experiment: Experiment | undefined) {\n\t\tconst suffix = tube.only\n\t\t\t? colors.only(` ${icons.only} [ONLY]`)\n\t\t\t: tube.skip\n\t\t\t\t? colors.skip(` ${icons.skip} [SKIP]`)\n\t\t\t\t: \"\"\n\t\tif (experiment && experiment.fail) return colors.errorLabel(icons.testFail) + suffix\n\t\telse if (experiment) return colors.successLabel(icons.testSuccess) + suffix\n\t\telse return colors.neutral(icons.testNeutral) + suffix\n\t}\n\n\tfunction errFailedTest(tube: Tube, experiment: Experiment) {\n\t\tloggedCaseCount += 1\n\t\tconst path = tube.path\n\t\tconst label = colors.errorLabel(tube.label)\n\t\tconst breadcrumb = [...path.map(colors.errorPath), label].join(colors.errorGrammar(icons.pathSeparator))\n\t\tconst message = colors.errorMessage(experiment.fail ?? \"unknown fail\")\n\t\tconst timely = colors.errorTime(`${icons.timeSeparator}${ms(experiment.time)}`)\n\t\tconst intro = pickIntro(tube, experiment)\n\t\terr(`${intro} ${breadcrumb}${colors.errorGrammar(icons.messageSeparator)}${message}${timely}`)\n\t}\n\n\tfunction logHappyTest(tube: Tube, experiment: Experiment) {\n\t\tloggedCaseCount += 1\n\t\tconst path = tube.path\n\t\tconst label = colors.successLabel(tube.label)\n\t\tconst breadcrumb = [...path.map(colors.successPath), label].join(colors.successGrammar(icons.pathSeparator))\n\t\tconst timely = colors.successTime(`${icons.timeSeparator}${ms(experiment.time)}`)\n\t\tconst intro = pickIntro(tube, experiment)\n\t\tlog(`${intro} ${breadcrumb}${timely}`)\n\t}\n\n\tfunction logLameTest(tube: Tube) {\n\t\tloggedCaseCount += 1\n\t\tconst path = tube.path\n\t\tconst label = colors.neutralLabel(tube.label)\n\t\tconst breadcrumb = [...path.map(colors.neutral), label].join(colors.neutral(icons.pathSeparator))\n\t\tconst intro = pickIntro(tube, undefined)\n\t\tlog(`${intro} ${breadcrumb}`)\n\t}\n\n\tfor (const tube of ex.tubes) {\n\t\tconst experiment = ex.experiments.get(tube)\n\t\tif (experiment) {\n\t\t\tif (experiment.fail) errFailedTest(tube, experiment)\n\t\t\telse if (verbose) logHappyTest(tube, experiment)\n\t\t}\n\t\telse if (verbose) {\n\t\t\tlogLameTest(tube)\n\t\t}\n\t}\n\n\tif (loggedCaseCount > 0)\n\t\tlog(\"\")\n\n\tif (onlyCount) {\n\t\tconst ignored = allCount - onlyCount\n\t\tlog(colors.only(`${icons.only} only ran ${onlyCount} test${plural(onlyCount)} (${ignored} ignored)`))\n\t}\n\telse if (skipCount) {\n\t\tlog(colors.skip(`${icons.skip} skipped ${skipCount} test${plural(skipCount)}`))\n\t}\n\n\tif (angryCount === 0) {\n\t\tconst x = colors.successSuite(icons.suiteSuccess)\n\t\tconst happy = colors.successLabel(`${happyCount} happy tests`)\n\t\tconst time = colors.successTime(`- ${ms(ex.time)}`)\n\t\tlog(`${x} ${happy} ${time}`)\n\t}\n\telse {\n\t\tconst x = colors.errorSuite(icons.suiteFail)\n\t\tconst failures = colors.errorSuite(`${angryCount} failure${plural(angryCount)}`)\n\t\tconst didnt = colors.errorDidnt(`(${happyCount} succeeded)`)\n\t\tconst time = colors.errorTime(`- ${ms(ex.time)}`)\n\t\terr(`${x} ${failures} ${didnt} ${time}`)\n\t}\n\n\treturn {\n\t\texecution: ex,\n\t\toutputs,\n\t\tcode: angryCount > 0 ? 1 : 0,\n\t}\n}\n\n", "\nimport {color} from \"./coloring.js\"\n\nexport type Theme = {\n\tcolors: ThemeColors\n\ticons: ThemeIcons\n}\n\nexport function asTheme(theme: Theme) {\n\treturn theme\n}\n\nexport type ColorFn = (s: string) => string\n\nexport type ThemeColors = {\n\tskip: ColorFn\n\tonly: ColorFn\n\tneutral: ColorFn\n\tneutralLabel: ColorFn\n\n\tsuccessSuite: ColorFn\n\tsuccessGrammar: ColorFn\n\tsuccessPath: ColorFn\n\tsuccessLabel: ColorFn\n\tsuccessTime: ColorFn\n\n\terrorSuite: ColorFn\n\terrorDidnt: ColorFn\n\terrorPath: ColorFn\n\terrorGrammar: ColorFn\n\terrorLabel: ColorFn\n\terrorMessage: ColorFn\n\terrorTime: ColorFn\n}\n\nexport type ThemeIcons = {\n\tskip: string\n\tonly: string\n\ttestFail: string\n\ttestSuccess: string\n\ttestNeutral: string\n\tsuiteFail: string\n\tsuiteSuccess: string\n\ttimeSeparator: string\n\tpathSeparator: string\n\tmessageSeparator: string\n}\n\nexport const themes = {\n\tplain: asTheme({\n\t\tcolors: {\n\t\t\tskip: color.none,\n\t\t\tonly: color.none,\n\t\t\tneutral: color.none,\n\t\t\tneutralLabel: color.none,\n\n\t\t\tsuccessSuite: color.none,\n\t\t\tsuccessPath: color.none,\n\t\t\tsuccessGrammar: color.none,\n\t\t\tsuccessLabel: color.none,\n\t\t\tsuccessTime: color.none,\n\n\t\t\terrorSuite: color.none,\n\t\t\terrorDidnt: color.none,\n\t\t\terrorPath: color.none,\n\t\t\terrorLabel: color.none,\n\t\t\terrorGrammar: color.none,\n\t\t\terrorMessage: color.none,\n\t\t\terrorTime: color.none,\n\t\t},\n\t\ticons: {\n\t\t\tskip: \"\u23ED\",\n\t\t\tonly: \"*\",\n\t\t\ttestFail: \"\u2718 \",\n\t\t\ttestSuccess: \" \u2022\",\n\t\t\ttestNeutral: \" \u2022\",\n\t\t\tsuiteFail: \"FAIL!!\",\n\t\t\tsuiteSuccess: \"good:\",\n\t\t\ttimeSeparator: \" - \",\n\t\t\tpathSeparator: \" > \",\n\t\t\tmessageSeparator: \" :: \",\n\t\t},\n\t}),\n\n\tredgreen: asTheme({\n\t\tcolors: {\n\t\t\tskip: color.yellow,\n\t\t\tonly: color.yellow,\n\t\t\tneutral: s => color.dim(color.white(s)),\n\t\t\tneutralLabel: color.white,\n\n\t\t\tsuccessSuite: color.brightGreen,\n\t\t\tsuccessPath: color.green,\n\t\t\tsuccessGrammar: s => color.dim(color.green(s)),\n\t\t\tsuccessLabel: s => color.bold(color.brightGreen(s)),\n\t\t\tsuccessTime: s => color.dim(color.green(s)),\n\n\t\t\terrorSuite: color.brightRed,\n\t\t\terrorDidnt: color.red,\n\t\t\terrorPath: color.red,\n\t\t\terrorLabel: s => color.bold(color.brightRed(s)),\n\t\t\terrorGrammar: s => color.dim(color.red(s)),\n\t\t\terrorMessage: color.red,\n\t\t\terrorTime: s => color.dim(color.red(s)),\n\t\t},\n\t\ticons: {\n\t\t\tskip: \"\uD83D\uDC7B\",\n\t\t\tonly: \"\uD83D\uDEA7\",\n\t\t\ttestFail: \"\u274C\",\n\t\t\ttestSuccess: \" \u2022\",\n\t\t\ttestNeutral: \" \u2022\",\n\t\t\tsuiteFail: \"\uD83D\uDD25\",\n\t\t\tsuiteSuccess: \"\u2705\",\n\t\t\ttimeSeparator: \" - \",\n\t\t\tpathSeparator: \" > \",\n\t\t\tmessageSeparator: \" :: \",\n\t\t},\n\t}),\n\n\tseaside: asTheme({\n\t\tcolors: {\n\t\t\tskip: color.yellow,\n\t\t\tonly: color.yellow,\n\t\t\tneutral: s => color.dim(color.white(s)),\n\t\t\tneutralLabel: color.white,\n\n\t\t\tsuccessSuite: color.brightBlue,\n\t\t\tsuccessPath: color.blue,\n\t\t\tsuccessGrammar: s => color.dim(color.blue(s)),\n\t\t\tsuccessLabel: s => color.bold(color.brightBlue(s)),\n\t\t\tsuccessTime: s => color.dim(color.blue(s)),\n\n\t\t\terrorSuite: color.brightRed,\n\t\t\terrorDidnt: color.red,\n\t\t\terrorPath: color.red,\n\t\t\terrorLabel: s => color.bold(color.brightRed(s)),\n\t\t\terrorGrammar: s => color.dim(color.red(s)),\n\t\t\terrorMessage: color.red,\n\t\t\terrorTime: s => color.dim(color.red(s)),\n\t\t},\n\t\ticons: {\n\t\t\tskip: \"\uD83D\uDC7B\",\n\t\t\tonly: \"\uD83D\uDEA7\",\n\t\t\ttestFail: \"\u274C\",\n\t\t\ttestSuccess: \" \u2022\",\n\t\t\ttestNeutral: \" \u2022\",\n\t\t\tsuiteFail: \"\uD83D\uDD25\",\n\t\t\tsuiteSuccess: \"\u2705\",\n\t\t\ttimeSeparator: \" - \",\n\t\t\tpathSeparator: \" > \",\n\t\t\tmessageSeparator: \" :: \",\n\t\t},\n\t}),\n}\n\n", "\nexport function spy<Fn extends (...args: any[]) => any>(fn: Fn) {\n\tconst calls: {args: Parameters<Fn>, ret: ReturnType<Fn>}[] = []\n\n\tfunction spyFn(...args: Parameters<Fn>) {\n\t\tconst ret = fn(...args)\n\t\tif (ret !== undefined && ret !== null && typeof ret.then === \"function\")\n\t\t\treturn ret.then((r: any) => {\n\t\t\t\tcalls.push({args, ret: r})\n\t\t\t\treturn r\n\t\t\t})\n\t\telse {\n\t\t\tcalls.push({args, ret})\n\t\t\treturn ret\n\t\t}\n\t}\n\n\tspyFn.spy = {\n\t\tcalls,\n\t\tget args() {\n\t\t\treturn calls.map(c => c.args)\n\t\t},\n\t\tget rets() {\n\t\t\treturn calls.map(c => c.ret)\n\t\t},\n\t}\n\n\treturn spyFn\n}\n\n", "\nimport {Options} from \"../types.js\"\nimport {themes} from \"../presentation/themes.js\"\nimport {getArg, getEnv, hasArg} from \"../presentation/supports.js\"\n\nexport const getArgs = (options: Partial<Options>) => ({\n\tverbose: options.verbose ?? (\n\t\thasArg(\"--verbose\") ||\n\t\tgetArg(\"--verbose\") === \"1\" ||\n\t\thasArg(\"-v\") ||\n\t\tgetEnv(\"SCIENCE_VERBOSE\") === \"1\"\n\t),\n\n\ttheme: options.theme ?? (() => {\n\t\tconst themeName = getArg(\"--theme\") || getEnv(\"SCIENCE_THEME\")\n\t\tif (themeName) {\n\t\t\tconst theme = themes[themeName as keyof typeof themes]\n\t\t\tif (!theme)\n\t\t\t\tthrow new Error(`theme not found \"${themeName}\"`)\n\t\t\treturn theme\n\t\t}\n\t\treturn themes.redgreen\n\t})(),\n})\n\n", "\nimport {Theme, themes} from \"../presentation/themes.js\"\nimport {isColorSupported} from \"../presentation/supports.js\"\n\nexport const considerColorSupport = (theme: Theme) => ({\n\t...theme,\n\tcolors: isColorSupported()\n\t\t? theme.colors\n\t\t: themes.plain.colors,\n})\n\n", "\nimport {Options, Suite} from \"./types.js\"\nimport {getArgs} from \"./running/get-args.js\"\nimport {execute} from \"./execution/execute.js\"\nimport {deliver} from \"./presentation/deliver.js\"\nimport {summarize} from \"./presentation/summarize.js\"\nimport {considerColorSupport} from \"./running/consider-color-support.js\"\n\nexport async function run(tests: Suite, options: Partial<Options> = {}) {\n\tconst {verbose, theme} = getArgs(options)\n\tconst theme2 = considerColorSupport(theme)\n\tconst report = await execute(tests)\n\tconst summary = summarize(report, {verbose, theme: theme2})\n\tawait deliver(summary)\n}\n\n", "\nimport {meta, Test} from \"./types.js\"\n\nexport function test(fn: Test) {\n\treturn fn\n}\n\ntest.only = (fn: Test) => (fn[meta] = {kind: \"only\"}, fn)\ntest.skip = (fn: Test) => (fn[meta] = {kind: \"skip\"}, fn)\n\n", "\nimport {meta, Suite} from \"./types.js\"\n\nexport function suite<S extends Suite>(suite: S): S {\n\treturn suite\n}\n\nsuite.only = <S extends Suite>(suite: S): S => (suite[meta] = {kind: \"only\"}, suite)\nsuite.skip = <S extends Suite>(suite: S): S => (suite[meta] = {kind: \"skip\"}, suite)\n\n", "\nexport const bytes = Object.freeze({\n\teq(a: Uint8Array, b: Uint8Array) {\n\t\tif (a.length !== b.length)\n\t\t\treturn false\n\t\tfor (let i = 0; i <= a.length; i++) {\n\t\t\tif (a.at(i) !== b.at(i))\n\t\t\t\treturn false\n\t\t}\n\t\treturn true\n\t},\n\n\trandom(count: number) {\n\t\treturn crypto.getRandomValues(new Uint8Array(count))\n\t},\n})\n\n/** @deprecated renamed to `bytes` */\nexport const Bytes = bytes\n\n", "\nimport {bytes} from \"./bytes.js\"\n\nexport type Lexicon = {\n\tcharacters: string\n\tnegativePrefix?: string\n\tpadding?: {\n\t\tcharacter: string\n\t\tsize: number\n\t}\n}\n\nexport class BaseX {\n\tstatic lexicons = Object.freeze({\n\t\tbase2: {characters: \"01\"},\n\t\thex: {characters: \"0123456789abcdef\"},\n\t\tbase36: {characters: \"0123456789abcdefghijklmnopqrstuvwxyz\"},\n\t\tbase58: {characters: \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"},\n\t\tbase62: {characters: \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\"},\n\t\tbase64url: {\n\t\t\tnegativePrefix: \"~\",\n\t\t\tcharacters: \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\",\n\t\t},\n\t\tbase64: {\n\t\t\tcharacters: \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",\n\t\t\tpadding: {character: \"=\", size: 4},\n\t\t},\n\t})\n\n\tprivate lookup: Record<string, number>\n\tprivate negativePrefix: string\n\n\tconstructor(public lexicon: Lexicon) {\n\t\tthis.lookup = Object.fromEntries(\n\t\t\t[...lexicon.characters].map((char, i) => [char, i])\n\t\t)\n\t\tthis.negativePrefix = lexicon.negativePrefix ?? \"-\"\n\t}\n\n\ttoBytes(s: string): Uint8Array {\n\t\tconst bitsPerChar = Math.log2(this.lexicon.characters.length)\n\t\tif (Number.isInteger(bitsPerChar)) {\n\t\t\t// Bitstream mode (for power-of-2 lexicons)\n\t\t\tlet bitBuffer = 0\n\t\t\tlet bitCount = 0\n\t\t\tconst output: number[] = []\n\n\t\t\tfor (const char of s) {\n\t\t\t\tif (char === this.lexicon.padding?.character) continue\n\t\t\t\tconst val = this.lookup[char]\n\t\t\t\tif (val === undefined) throw new Error(`Invalid character: ${char}`)\n\t\t\t\tbitBuffer = (bitBuffer << bitsPerChar) | val\n\t\t\t\tbitCount += bitsPerChar\n\n\t\t\t\twhile (bitCount >= 8) {\n\t\t\t\t\tbitCount -= 8\n\t\t\t\t\toutput.push((bitBuffer >> bitCount) & 0xFF)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new Uint8Array(output)\n\t\t}\n\n\t\t// Radix mode fallback\n\t\tlet num = 0n\n\t\tconst base = BigInt(this.lexicon.characters.length)\n\t\tlet negative = false\n\t\tif (s.startsWith(this.negativePrefix)) {\n\t\t\ts = s.slice(this.negativePrefix.length)\n\t\t\tnegative = true\n\t\t}\n\t\tfor (const char of s) {\n\t\t\tconst val = this.lookup[char]\n\t\t\tif (val === undefined) throw new Error(`Invalid character: ${char}`)\n\t\t\tnum = num * base + BigInt(val)\n\t\t}\n\t\tconst out: number[] = []\n\t\twhile (num > 0n) {\n\t\t\tout.unshift(Number(num % 256n))\n\t\t\tnum = num / 256n\n\t\t}\n\t\treturn new Uint8Array(out)\n\t}\n\n\tfromBytes(bytes: Uint8Array): string {\n\t\tconst bitsPerChar = Math.log2(this.lexicon.characters.length)\n\t\tif (Number.isInteger(bitsPerChar)) {\n\t\t\t// Bitstream mode (for power-of-2 lexicons)\n\t\t\tlet bitBuffer = 0\n\t\t\tlet bitCount = 0\n\t\t\tlet out = \"\"\n\n\t\t\tfor (const byte of bytes) {\n\t\t\t\tbitBuffer = (bitBuffer << 8) | byte\n\t\t\t\tbitCount += 8\n\n\t\t\t\twhile (bitCount >= bitsPerChar) {\n\t\t\t\t\tbitCount -= bitsPerChar\n\t\t\t\t\tconst index = (bitBuffer >> bitCount) & ((1 << bitsPerChar) - 1)\n\t\t\t\t\tout += this.lexicon.characters[index]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// \uD83E\uDE79 flush remaining bits\n\t\t\tif (bitCount > 0) {\n\t\t\t\tconst index = (bitBuffer << (bitsPerChar - bitCount)) & ((1 << bitsPerChar) - 1)\n\t\t\t\tout += this.lexicon.characters[index]\n\t\t\t}\n\n\t\t\t// Add padding if applicable\n\t\t\tif (this.lexicon.padding) {\n\t\t\t\twhile (out.length % this.lexicon.padding.size !== 0)\n\t\t\t\t\tout += this.lexicon.padding.character\n\t\t\t}\n\n\t\t\treturn out\n\t\t}\n\n\t\t// Radix mode fallback\n\t\tlet num = 0n\n\t\tfor (const byte of bytes)\n\t\t\tnum = (num << 8n) + BigInt(byte)\n\n\t\tif (num === 0n) return this.lexicon.characters[0]\n\n\t\tconst base = BigInt(this.lexicon.characters.length)\n\t\tlet out = \"\"\n\t\twhile (num > 0n) {\n\t\t\tout = this.lexicon.characters[Number(num % base)] + out\n\t\t\tnum = num / base\n\t\t}\n\t\treturn out\n\t}\n\n\ttoInteger(s: string) {\n\t\tif (!s) return 0\n\t\tlet n = 0n\n\t\tlet negative = false\n\t\tconst base = BigInt(this.lexicon.characters.length)\n\t\tif (s.startsWith(this.negativePrefix)) {\n\t\t\ts = s.slice(this.negativePrefix.length)\n\t\t\tnegative = true\n\t\t}\n\t\tfor (const char of s) {\n\t\t\tconst value = this.lookup[char]\n\t\t\tif (value === undefined) throw new Error(`Invalid character: ${char}`)\n\t\t\tn = n * base + BigInt(value)\n\t\t}\n\t\treturn Number(negative ? -n : n)\n\t}\n\n\tfromInteger(n: number) {\n\t\tn = Math.floor(n)\n\t\tconst negative = n < 0\n\t\tlet num = BigInt(negative ? -n : n)\n\t\tif (num === 0n) return this.lexicon.characters[0]\n\t\tconst base = BigInt(this.lexicon.characters.length)\n\t\tlet out = \"\"\n\t\twhile (num > 0n) {\n\t\t\tout = this.lexicon.characters[Number(num % base)] + out\n\t\t\tnum = num / base\n\t\t}\n\t\treturn negative ? `${this.negativePrefix}${out}` : out\n\t}\n\n\trandom(count = 32) {\n\t\treturn this.fromBytes(bytes.random(count))\n\t}\n}\n\n", "\nimport {BaseX} from \"./base-x.js\"\n\nexport const hex = new BaseX(BaseX.lexicons.hex)\nexport const base2 = new BaseX(BaseX.lexicons.base2)\nexport const base36 = new BaseX(BaseX.lexicons.base36)\nexport const base58 = new BaseX(BaseX.lexicons.base58)\nexport const base62 = new BaseX(BaseX.lexicons.base62)\nexport const base64 = new BaseX(BaseX.lexicons.base64)\nexport const base64url = new BaseX(BaseX.lexicons.base64url)\n\n", "\nexport const prefixes = [\n\t\"doz\",\"mar\",\"bin\",\"wan\",\"sam\",\"lit\",\"sig\",\"hid\",\"fid\",\"lis\",\"sog\",\"dir\",\"wac\",\"sab\",\"wis\",\"sib\",\n\t\"rig\",\"sol\",\"dop\",\"mod\",\"fog\",\"lid\",\"hop\",\"dar\",\"dor\",\"lor\",\"hod\",\"fol\",\"rin\",\"tog\",\"sil\",\"mir\",\n\t\"hol\",\"pas\",\"lac\",\"rov\",\"liv\",\"dal\",\"sat\",\"lib\",\"tab\",\"han\",\"tic\",\"pid\",\"tor\",\"bol\",\"fos\",\"dot\",\n\t\"los\",\"dil\",\"for\",\"pil\",\"ram\",\"tir\",\"win\",\"tad\",\"bic\",\"dif\",\"roc\",\"wid\",\"bis\",\"das\",\"mid\",\"lop\",\n\t\"ril\",\"nar\",\"dap\",\"mol\",\"san\",\"loc\",\"nov\",\"sit\",\"nid\",\"tip\",\"sic\",\"rop\",\"wit\",\"nat\",\"pan\",\"min\",\n\t\"rit\",\"pod\",\"mot\",\"tam\",\"tol\",\"sav\",\"pos\",\"nap\",\"nop\",\"som\",\"fin\",\"fon\",\"ban\",\"mor\",\"wor\",\"sip\",\n\t\"ron\",\"nor\",\"bot\",\"wic\",\"soc\",\"wat\",\"dol\",\"mag\",\"pic\",\"dav\",\"bid\",\"bal\",\"tim\",\"tas\",\"mal\",\"lig\",\n\t\"siv\",\"tag\",\"pad\",\"sal\",\"div\",\"dac\",\"tan\",\"sid\",\"fab\",\"tar\",\"mon\",\"ran\",\"nis\",\"wol\",\"mis\",\"pal\",\n\t\"las\",\"dis\",\"map\",\"rab\",\"tob\",\"rol\",\"lat\",\"lon\",\"nod\",\"nav\",\"fig\",\"nom\",\"nib\",\"pag\",\"sop\",\"ral\",\n\t\"bil\",\"had\",\"doc\",\"rid\",\"moc\",\"pac\",\"rav\",\"rip\",\"fal\",\"tod\",\"til\",\"tin\",\"hap\",\"mic\",\"fan\",\"pat\",\n\t\"tac\",\"lab\",\"mog\",\"sim\",\"son\",\"pin\",\"lom\",\"ric\",\"tap\",\"fir\",\"has\",\"bos\",\"bat\",\"poc\",\"hac\",\"tid\",\n\t\"hav\",\"sap\",\"lin\",\"dib\",\"hos\",\"dab\",\"bit\",\"bar\",\"rac\",\"par\",\"lod\",\"dos\",\"bor\",\"toc\",\"hil\",\"mac\",\n\t\"tom\",\"dig\",\"fil\",\"fas\",\"mit\",\"hob\",\"har\",\"mig\",\"hin\",\"rad\",\"mas\",\"hal\",\"rag\",\"lag\",\"fad\",\"top\",\n\t\"mop\",\"hab\",\"nil\",\"nos\",\"mil\",\"fop\",\"fam\",\"dat\",\"nol\",\"din\",\"hat\",\"nac\",\"ris\",\"fot\",\"rib\",\"hoc\",\n\t\"nim\",\"lar\",\"fit\",\"wal\",\"rap\",\"sar\",\"nal\",\"mos\",\"lan\",\"don\",\"dan\",\"lad\",\"dov\",\"riv\",\"bac\",\"pol\",\n\t\"lap\",\"tal\",\"pit\",\"nam\",\"bon\",\"ros\",\"ton\",\"fod\",\"pon\",\"sov\",\"noc\",\"sor\",\"lav\",\"mat\",\"mip\",\"fip\",\n]\n\n", "\nexport const suffixes = [\n\t\"zod\",\"nec\",\"bud\",\"wes\",\"sev\",\"per\",\"sut\",\"let\",\"ful\",\"pen\",\"syt\",\"dur\",\"wep\",\"ser\",\"wyl\",\"sun\",\n\t\"ryp\",\"syx\",\"dyr\",\"nup\",\"heb\",\"peg\",\"lup\",\"dep\",\"dys\",\"put\",\"lug\",\"hec\",\"ryt\",\"tyv\",\"syd\",\"nex\",\n\t\"lun\",\"mep\",\"lut\",\"sep\",\"pes\",\"del\",\"sul\",\"ped\",\"tem\",\"led\",\"tul\",\"met\",\"wen\",\"byn\",\"hex\",\"feb\",\n\t\"pyl\",\"dul\",\"het\",\"mev\",\"rut\",\"tyl\",\"wyd\",\"tep\",\"bes\",\"dex\",\"sef\",\"wyc\",\"bur\",\"der\",\"nep\",\"pur\",\n\t\"rys\",\"reb\",\"den\",\"nut\",\"sub\",\"pet\",\"rul\",\"syn\",\"reg\",\"tyd\",\"sup\",\"sem\",\"wyn\",\"rec\",\"meg\",\"net\",\n\t\"sec\",\"mul\",\"nym\",\"tev\",\"web\",\"sum\",\"mut\",\"nyx\",\"rex\",\"teb\",\"fus\",\"hep\",\"ben\",\"mus\",\"wyx\",\"sym\",\n\t\"sel\",\"ruc\",\"dec\",\"wex\",\"syr\",\"wet\",\"dyl\",\"myn\",\"mes\",\"det\",\"bet\",\"bel\",\"tux\",\"tug\",\"myr\",\"pel\",\n\t\"syp\",\"ter\",\"meb\",\"set\",\"dut\",\"deg\",\"tex\",\"sur\",\"fel\",\"tud\",\"nux\",\"rux\",\"ren\",\"wyt\",\"nub\",\"med\",\n\t\"lyt\",\"dus\",\"neb\",\"rum\",\"tyn\",\"seg\",\"lyx\",\"pun\",\"res\",\"red\",\"fun\",\"rev\",\"ref\",\"mec\",\"ted\",\"rus\",\n\t\"bex\",\"leb\",\"dux\",\"ryn\",\"num\",\"pyx\",\"ryg\",\"ryx\",\"fep\",\"tyr\",\"tus\",\"tyc\",\"leg\",\"nem\",\"fer\",\"mer\",\n\t\"ten\",\"lus\",\"nus\",\"syl\",\"tec\",\"mex\",\"pub\",\"rym\",\"tuc\",\"fyl\",\"lep\",\"deb\",\"ber\",\"mug\",\"hut\",\"tun\",\n\t\"byl\",\"sud\",\"pem\",\"dev\",\"lur\",\"def\",\"bus\",\"bep\",\"run\",\"mel\",\"pex\",\"dyt\",\"byt\",\"typ\",\"lev\",\"myl\",\n\t\"wed\",\"duc\",\"fur\",\"fex\",\"nul\",\"luc\",\"len\",\"ner\",\"lex\",\"rup\",\"ned\",\"lec\",\"ryd\",\"lyd\",\"fen\",\"wel\",\n\t\"nyd\",\"hus\",\"rel\",\"rud\",\"nes\",\"hes\",\"fet\",\"des\",\"ret\",\"dun\",\"ler\",\"nyr\",\"seb\",\"hul\",\"ryl\",\"lud\",\n\t\"rem\",\"lys\",\"fyn\",\"wer\",\"ryc\",\"sug\",\"nys\",\"nyl\",\"lyn\",\"dyn\",\"dem\",\"lux\",\"fed\",\"sed\",\"bec\",\"mun\",\n\t\"lyr\",\"tes\",\"mud\",\"nyt\",\"byr\",\"sen\",\"weg\",\"fyr\",\"mur\",\"tel\",\"rep\",\"teg\",\"pec\",\"nel\",\"nev\",\"fes\",\n]\n\n", "\nimport {bytes} from \"../bytes.js\"\nimport {hex} from \"../base-x-codecs.js\"\nimport {prefixes} from \"./utils/prefixes.js\"\nimport {suffixes} from \"./utils/suffixes.js\"\n\nexport type BytenameOptions = {\n\tgroupSize: number\n\twordSeparator: string\n\tgroupSeparator: string\n}\n\n/**\n * Bytename is a friendly presentation format for arbitrary binary data.\n * - looks like \"midsen.picmyn.widrep.baclut dotreg.filtyp.nosnus.siptev\"\n * - each byte maps to a three-letter triplet\n * - all delimiters are just sugar, parser doesn't care\n */\nexport const bytename = {\n\tdefaults: (<BytenameOptions>{\n\t\tgroupSize: 4,\n\t\twordSeparator: \".\",\n\t\tgroupSeparator: \" \",\n\t}),\n\n\trandom(byteCount: number, options?: Partial<BytenameOptions>) {\n\t\tconst b = bytes.random(byteCount)\n\t\treturn this.fromBytes(b, options)\n\t},\n\n\tfromBytes(b: Uint8Array, options: Partial<BytenameOptions> = {}) {\n\t\tconst {\n\t\t\tgroupSize = bytename.defaults.groupSize,\n\t\t\twordSeparator = bytename.defaults.wordSeparator,\n\t\t\tgroupSeparator = bytename.defaults.groupSeparator,\n\t\t} = options\n\n\t\tconst words: string[] = []\n\t\tlet currentWord: string[] = []\n\n\t\tb.forEach((byte, index) => {\n\t\t\tconst source = ((index % 2) === 0) ? prefixes : suffixes\n\t\t\tcurrentWord.push(source[byte]!)\n\t\t\tif (currentWord.length === 2) {\n\t\t\t\twords.push(currentWord.join(\"\"))\n\t\t\t\tcurrentWord = []\n\t\t\t}\n\t\t})\n\n\t\tif (currentWord.length)\n\t\t\twords.push(currentWord.join(\"\"))\n\n\t\tconst grouped = []\n\t\tfor (let i = 0; i < words.length; i += groupSize)\n\t\t\tgrouped.push(words.slice(i, i + groupSize).join(wordSeparator))\n\n\t\treturn grouped.join(groupSeparator)\n\t},\n\n\ttoBytes(bname: string) {\n\t\tconst letters = bname\n\t\t\t.toLowerCase()\n\t\t\t.replace(/[^a-z]/g, \"\") // strip everything except letters\n\n\t\tconst count = letters.length / 3\n\t\tif ((count % 1) !== 0)\n\t\t\tthrow new Error(`invalid triplet count, ${letters.length} does not divide into triplets`)\n\n\t\tconst triplets: string[] = []\n\t\tfor (let i = 0; i < letters.length; i += 3)\n\t\t\ttriplets.push(letters.slice(i, i + 3))\n\n\t\treturn new Uint8Array(triplets.map((triplet, index) => {\n\t\t\tconst source = ((index % 2) === 0) ? prefixes : suffixes\n\t\t\tconst number = source.findIndex(t => t === triplet)\n\t\t\tif (number === -1)\n\t\t\t\tthrow new Error(`unknown triplet ${triplet}`)\n\t\t\treturn number\n\t\t}))\n\t},\n\n\ttoHex(bname: string) {\n\t\treturn hex.fromBytes(bytename.toBytes(bname))\n\t},\n\n\tfromHex(h: string, options?: Partial<BytenameOptions>) {\n\t\treturn bytename.fromBytes(hex.toBytes(h), options)\n\t},\n}\n\n/** @deprecated renamed to `bytename` */\nexport const Bytename = bytename\n\n", "\nimport {bytename} from \"./bytename.js\"\nimport {base58, hex} from \"../base-x-codecs.js\"\n\nexport type ThumbprintOptions = {\n\tdelimiter: string\n\tsigilBytes: number\n\tpreviewBytes: number\n}\n\nexport type ThumbprintData = {\n\traw: Uint8Array\n\tfull: string\n\tpreview: string\n\tbulk: string\n\tsigil: string\n\n\t/** @deprecated renamed to `raw` */\n\treadonly bytes: Uint8Array\n\n\t/** @deprecated renamed to `full` */\n\treadonly thumbprint: string\n}\n\n/**\n * Thumbprint is a friendly presentation format for arbitrary binary data.\n * - looks like \"nodlyn.fasrep.habbud.ralwel.Avo7gFmdWMRHkwsD149mcaBoZdS69iXuJ\"\n * - the preview: \"nodlyn.fasrep.habbud.ralwel\" (bytename format)\n * - the bulk: \"Avo7gFmdWMRHkwsD149mcaBoZdS69iXuJ\" (base58 format)\n * - the sigil: \"nodlyn.fasrep\" (shorter part of the bytename)\n * - originally designed to be a nice way to present 256-bit ids, but can actually represent any number of bytes\n */\nexport const thumbprint = {\n\tdefaults: (<ThumbprintOptions>{\n\t\tdelimiter: \".\",\n\t\tsigilBytes: 4,\n\t\tpreviewBytes: 8,\n\t}),\n\n\ttoBytes(tstring: string) {\n\t\ttstring = tstring.trim()\n\t\tconst beans = tstring.split(/[^a-zA-Z0-9]+/m)\n\t\t\t.filter(Boolean)\n\t\t\t.map(s => s.trim())\n\n\t\tif (beans.length < 2)\n\t\t\treturn bytename.toBytes(beans.join(\"\"))\n\n\t\tconst bulk = beans.pop()!\n\t\tconst preview = beans.join(\"\")\n\n\t\treturn new Uint8Array([\n\t\t\t...bytename.toBytes(preview),\n\t\t\t...base58.toBytes(bulk),\n\t\t])\n\t},\n\n\tparse(tstring: string, options?: Partial<ThumbprintOptions>): ThumbprintData {\n\t\tconst bytes = thumbprint.toBytes(tstring)\n\t\treturn thumbprint.build.fromBytes(bytes, options)\n\t},\n\n\tbuild: {\n\t\tfromBytes(raw: Uint8Array, options: Partial<ThumbprintOptions> = {}): ThumbprintData {\n\t\t\tconst {delimiter, previewBytes, sigilBytes}\n\t\t\t\t= {...thumbprint.defaults, ...options}\n\n\t\t\tconst yoink = (len: number) => (raw.length > 0)\n\t\t\t\t? bytename.fromBytes(raw.slice(0, len), {\n\t\t\t\t\twordSeparator: delimiter,\n\t\t\t\t\tgroupSeparator: delimiter,\n\t\t\t\t})\n\t\t\t\t: \"\"\n\n\t\t\tconst sigil = yoink(sigilBytes)\n\t\t\tconst preview = yoink(previewBytes)\n\n\t\t\tconst bulk = (raw.length > previewBytes)\n\t\t\t\t? base58.fromBytes(raw.slice(previewBytes))\n\t\t\t\t: \"\"\n\n\t\t\tconst full = [preview, bulk]\n\t\t\t\t.filter(s => s.length > 0)\n\t\t\t\t.join(delimiter)\n\n\t\t\treturn {\n\t\t\t\traw,\n\t\t\t\tfull,\n\t\t\t\tpreview,\n\t\t\t\tbulk,\n\t\t\t\tsigil,\n\n\t\t\t\tbytes: raw,\n\t\t\t\tthumbprint: full,\n\t\t\t}\n\t\t},\n\n\t\tfromHex(hstring: string, options?: Partial<ThumbprintOptions>) {\n\t\t\tconst bytes = hex.toBytes(hstring)\n\t\t\treturn thumbprint.build.fromBytes(bytes, options)\n\t\t},\n\t},\n\n\ttoHex(tstring: string) {\n\t\tconst bytes = thumbprint.toBytes(tstring)\n\t\treturn hex.fromBytes(bytes)\n\t},\n\n\tfromBytes(b: Uint8Array, options?: Partial<ThumbprintOptions>) {\n\t\treturn thumbprint.build.fromBytes(b, options).full\n\t},\n\n\tfromHex(h: string, options?: Partial<ThumbprintOptions>) {\n\t\treturn thumbprint.fromBytes(hex.toBytes(h), options)\n\t},\n\n\tsigil: {\n\t\tfromHex(h: string, options?: Partial<ThumbprintOptions>) {\n\t\t\treturn thumbprint.build.fromHex(h, options).sigil\n\t\t},\n\t\tfromBytes(b: Uint8Array, options?: Partial<ThumbprintOptions>) {\n\t\t\treturn thumbprint.build.fromBytes(b, options).sigil\n\t\t},\n\t},\n}\n\n/** @deprecated renamed to `thumbprint` */\nexport const Thumbprint = thumbprint\n\n", "\n/*\n\n256-bit hex ids look like this:\n\n\t8ff8dfbc7c994c5439d2dd327b9898aa6796f97fb396e262985f03f868707e32\n\t6b99284a2c4a1c5f101502bd009f9fb592ca4427e4375155e411ddd07ed9da6b\n\t2eb73fb00a2b9e38c855b5aa353b530d820a3a2dcea5013b7e4e277ddfe9d0ad\n\n*/\n\nimport {bytes} from \"../bytes.js\"\n\n/** @deprecated use `hex` instead */\nexport const Hex = Object.freeze({\n\tfromBytes(bytes: Uint8Array) {\n\t\treturn [...bytes]\n\t\t\t.map(byte => byte.toString(16).padStart(2, \"0\"))\n\t\t\t.join(\"\")\n\t},\n\n\ttoBytes(string: string) {\n\t\tif (string.length % 2 !== 0)\n\t\t\tthrow new Error(\"must have even number of hex characters\")\n\t\tconst bytes = new Uint8Array(string.length / 2)\n\t\tfor (let i = 0; i < string.length; i += 2)\n\t\t\tbytes[i / 2] = parseInt(string.slice(i, i + 2), 16)\n\t\treturn bytes\n\t},\n\n\t/** generate a random hex string. byteCount defaults to 32. */\n\trandom(byteCount = 32) {\n\t\treturn this.fromBytes(bytes.random(byteCount))\n\t},\n\n\t/** @deprecated renamed to `fromBytes` */\n\tstring(bytes: Uint8Array) {\n\t\treturn Hex.fromBytes(bytes)\n\t},\n\n\t/** @deprecated renamed to `toBytes` */\n\tbytes(string: string) {\n\t\treturn Hex.toBytes(string)\n\t},\n})\n\n", "\n/** a promise which can be resolved from the outside */\nexport type Deferred<R = void> = {\n\tpromise: Promise<R>\n\tresolve: (result: R) => void\n\treject: (reason: any) => void\n\n\t/** ties the fate of this deferred promise to the outcome of the provided outsidePromise */\n\tentangle: (outsidePromise: Promise<R>) => Promise<R>\n}\n\n/** returns a deferred promise with exposed resolve and reject fns */\nexport function defer<R = void>(): Deferred<R> {\n\tlet resolve!: (result: R) => void\n\tlet reject!: (reason: any) => void\n\n\tconst promise = new Promise<R>((res, rej) => {\n\t\tresolve = res\n\t\treject = rej\n\t})\n\n\tfunction entangle(outside: Promise<R>) {\n\t\toutside.then(resolve).catch(reject)\n\t\treturn promise\n\t}\n\n\treturn {promise, resolve, reject, entangle}\n}\n\n", "\nexport const is = Object.freeze({\n\n\t/** not undefined or null */\n\thappy: <X>(x: X): x is NonNullable<X> =>\n\t\tx !== undefined && x !== null,\n\n\t/** undefined or null */\n\tsad: (x: any): x is (undefined | null) =>\n\t\tx === undefined || x === null,\n\n\tboolean: (x: any): x is boolean =>\n\t\ttypeof x === \"boolean\",\n\n\tnumber: (x: any): x is number =>\n\t\ttypeof x === \"number\",\n\n\tstring: (x: any): x is string =>\n\t\ttypeof x === \"string\",\n\n\tbigint: (x: any): x is bigint =>\n\t\ttypeof x === \"bigint\",\n\n\tobject: <X>(x: X): x is object & NonNullable<X> =>\n\t\ttypeof x === \"object\" && x !== null,\n\n\tarray: (x: any | any[]): x is any[] =>\n\t\tArray.isArray(x),\n\n\tfn: (x: any): x is (...a: any[]) => any =>\n\t\ttypeof x === \"function\",\n\n\tsymbol: (x: any): x is symbol =>\n\t\ttypeof x === \"symbol\",\n})\n\n", "\n/** extended js map with handy methods like `require` and `guarantee` */\nexport class GMap<K, V> extends Map<K, V> {\n\tstatic require<K, V>(map: Map<K, V>, key: K) {\n\t\tif (map.has(key))\n\t\t\treturn map.get(key) as V\n\t\telse\n\t\t\tthrow new Error(`required key not found: \"${key}\"`)\n\t}\n\n\tstatic guarantee<K, V>(map: Map<K, V>, key: K, make: () => V) {\n\t\tif (map.has(key))\n\t\t\treturn map.get(key)!\n\t\telse {\n\t\t\tconst value = make()\n\t\t\tmap.set(key, value)\n\t\t\treturn value\n\t\t}\n\t}\n\n\tarray() {\n\t\treturn [...this]\n\t}\n\n\trequire(key: K) {\n\t\treturn GMap.require(this, key)\n\t}\n\n\tguarantee(key: K, make: () => V) {\n\t\treturn GMap.guarantee(this, key, make)\n\t}\n}\n\n/** @deprecated renamed to `GMap` */\nexport const MapG = GMap\n\n", "\nexport class DeadlineError extends Error {\n\tname = this.constructor.name\n\tconstructor(public milliseconds: number) {\n\t\tsuper(`deadline exceeded (${(milliseconds / 1000).toFixed(1)} seconds)`)\n\t}\n}\n\n/** set a deadline for a fn to do something, will reject with a `DeadlineError` if it takes too long */\nexport function deadline<R>(milliseconds: number, fn: () => Promise<R>) {\n\tif (milliseconds <= 0 || milliseconds === Infinity)\n\t\treturn fn()\n\n\treturn new Promise<R>((resolve, reject) => {\n\t\tconst id = setTimeout(\n\t\t\t() => reject(new DeadlineError(milliseconds)),\n\t\t\tmilliseconds,\n\t\t)\n\t\tfn()\n\t\t\t.then(resolve)\n\t\t\t.catch(reject)\n\t\t\t.finally(() => clearTimeout(id))\n\t})\n}\n\n", "\nexport type Disposer = {\n\t(): void\n\tschedule: (...fns: (() => void)[]) => Disposer\n}\n\nexport function disposer(): Disposer {\n\tlet fns: (() => void)[] = []\n\n\tfunction d() {\n\t\tfor (const fn of fns) fn()\n\t\tfns = []\n\t}\n\n\td.schedule = (...newFns: (() => void)[]) => {\n\t\tfns.push(...newFns)\n\t\treturn d\n\t}\n\n\treturn d\n}\n\n", "\nimport {is} from \"./is.js\"\n\n/** return a value within an object tree, found at the given path. */\nexport function drill<xResult>(\n\t\tobject: {[key: string]: any},\n\t\tpath: string[],\n\t): xResult {\n\n\tlet current: any = object\n\n\tfor (const key of path) {\n\t\tcurrent = current[key]\n\t\tif (is.sad(current))\n\t\t\tbreak\n\t}\n\n\treturn current\n}\n\n", "\nimport {defer} from \"./defer.js\"\n\nexport type Listener<A extends any[]> = (...a: A) => (void | Promise<void>)\n\nexport interface Xub<A extends any[] = []> {\n\n\t/** publish to all subscribed listeners. */\n\tpublish(...a: A): Promise<void>\n\n\t/** subscribe a listener function. */\n\tsubscribe(fn: Listener<A>): () => void\n\n\t/** publish to all subscribed listeners, with pubsub facilities. */\n\tpub: Pub<A>\n\n\t/** subscribe a listener function, with pubsub facilities. */\n\tsub: Sub<A>\n\n\t/**\n\t * subscribe a listener function.\n\t * @alias subscribe\n\t */\n\ton(fn: Listener<A>): () => void\n\n\t/** wait for the next published value */\n\tnext(fn?: Listener<A>): Promise<A>\n\n\t/** wipe all listeners attached to this. */\n\tclear(): void\n}\n\n/** subscriber fn that can be published to. */\nexport interface Sub<A extends any[] = []> extends Xub<A> {\n\t(fn: Listener<A>): () => void\n}\n\n/** publisher fn that can be published to. */\nexport interface Pub<A extends any[] = []> extends Xub<A> {\n\t(...a: A): Promise<void>\n}\n\n/** make pubsub facilities */\nexport function xub<A extends any[] = []>() {\n\tconst set = new Set<Listener<A>>()\n\n\tasync function publish(...a: A) {\n\t\tawait Promise.all([...set].map(fn => fn(...a)))\n\t}\n\n\tfunction subscribe(fn: Listener<A>) {\n\t\tset.add(fn)\n\t\treturn () => { set.delete(fn) }\n\t}\n\n\tasync function pub(...a: A) {\n\t\treturn publish(...a)\n\t}\n\n\tfunction sub(fn: Listener<A>) {\n\t\treturn subscribe(fn)\n\t}\n\n\tasync function next(fn?: Listener<A>) {\n\t\tconst {promise, resolve} = defer<A>()\n\t\tconst unsubscribe = sub(async(...a) => {\n\t\t\tif (fn) await fn(...a)\n\t\t\tresolve(a)\n\t\t\tunsubscribe()\n\t\t})\n\t\treturn promise\n\t}\n\n\tfunction clear() {\n\t\tset.clear()\n\t}\n\n\tconst x = {\n\t\tpub,\n\t\tsub,\n\t\tpublish,\n\t\tsubscribe,\n\t\ton: subscribe,\n\t\tnext,\n\t\tclear,\n\t} as Xub<A>\n\n\tObject.assign(sub, x)\n\tObject.assign(pub, x)\n\treturn x\n}\n\n/** create a subscriber fn that also has pubsub facilities */\nexport function sub<A extends any[] = []>(listener?: Listener<A>): Sub<A> {\n\tconst x = xub<A>()\n\tif (listener) x.sub(listener)\n\treturn x.sub\n}\n\n/** create a publisher fn that also has pubsub facilities */\nexport function pub<A extends any[] = []>(listener?: Listener<A>): Pub<A> {\n\tconst x = xub<A>()\n\tif (listener) x.sub(listener)\n\treturn x.pub\n}\n\n", "\nimport {TextStyleOptions} from \"pixi.js\"\n\nimport {Id, Hash} from \"./basics.js\"\nimport {Transform} from \"../types.js\"\nimport {Ms} from \"../../units/ms.js\"\n\nexport enum Kind {\n\tSequence,\n\tStack,\n\tVideo,\n\tAudio,\n\tText,\n\tGap,\n\tSpatial,\n\tTransition,\n\tTextStyle\n}\n\nexport enum Effect {\n\tCrossfade,\n}\n\nexport namespace Item {\n\texport type TextStyle = {\n\t\tid: Id\n\t\tkind: Kind.TextStyle\n\t\tstyle: TextStyleOptions\n\t}\n\n\texport type Spatial = {\n\t\tid: Id\n\t\tkind: Kind.Spatial\n\t\ttransform: Transform\n\t\tenabled: boolean\n\t}\n\n\texport type Gap = {\n\t\tid: Id\n\t\tkind: Kind.Gap\n\t\tduration: number\n\t}\n\n\texport type Sequence = {\n\t\tid: Id\n\t\tkind: Kind.Sequence\n\t\tchildrenIds: Id[]\n\t\tspatialId?: Id\n\t}\n\n\texport type Stack = {\n\t\tid: Id\n\t\tkind: Kind.Stack\n\t\tchildrenIds: Id[]\n\t\tspatialId?: Id\n\t}\n\n\texport type Video = {\n\t\tid: Id\n\t\tkind: Kind.Video\n\t\tmediaHash: Hash\n\t\tstart: number\n\t\tduration: number\n\t\tspatialId?: Id\n\t}\n\n\texport type Audio = {\n\t\tid: Id\n\t\tkind: Kind.Audio\n\t\tmediaHash: Hash\n\t\tstart: number\n\t\tduration: number\n\t\tgain?: number\n\t}\n\n\texport type Text = {\n\t\tid: Id\n\t\tkind: Kind.Text\n\t\tcontent: string\n\t\tduration: number\n\t\tspatialId?: Id\n\t\tstyleId?: Id\n\t}\n\n\texport type Transition = {\n\t\tid: Id\n\t\tkind: Kind.Transition\n\t\teffect: Effect.Crossfade\n\t\tduration: number\n\t}\n\n\texport type Any = (\n\t\t| Sequence\n\t\t| Stack\n\t\t| Video\n\t\t| Audio\n\t\t| Text\n\t\t| Gap\n\t\t| Transition\n\t\t| Spatial\n\t\t| TextStyle\n\t)\n}\n\nexport type ContainerItem = Item.Sequence | Item.Stack\nexport type NonContainerItem = Exclude<Item.Any, ContainerItem>\n\nexport type PlayableItem = Item.Any & {\n\tstart: Ms\n\tduration: Ms\n}\n", "import {hex} from \"@e280/stz\"\nimport {TextStyleOptions} from \"pixi.js\"\n\nimport {Media} from \"../parts/media.js\"\nimport {Id, TimelineFile} from \"../parts/basics.js\"\nimport {Effect, Item, Kind} from \"../parts/item.js\"\nimport {Transform, TransformOptions, Vec2} from \"../types.js\"\n\nexport class O {\n\tconstructor(public state: {timeline: TimelineFile}) {}\n\n\trequire<T extends Item.Any>(id: Id | undefined) {\n if (id === undefined)\n \treturn undefined\n const item = this.state.timeline.items.find(item => item.id === id)\n return item as T | undefined\n\t}\n\n\tget timeline() {\n\t\treturn this.state.timeline\n\t}\n\n\tgetId() {\n\t\treturn hex.toInteger(hex.random())\n\t}\n\n #mutate(fn: (project: TimelineFile) => TimelineFile) {\n this.state.timeline = fn(this.state.timeline)\n }\n\n\tregister(item: Item.Any) {\n\t\tthis.#mutate(state => ({\n\t\t\t...state,\n\t\t\titems: [...state.items, item]\n\t\t}))\n\t}\n\n textStyle = (style: TextStyleOptions): Item.TextStyle => {\n\t\tconst item = {\n\t\t\tid: this.getId(),\n\t\t\tkind: Kind.TextStyle,\n\t\t\tstyle\n\t\t} as Item.TextStyle\n\t\tthis.register(item)\n\t\treturn item\n }\n\n spatial = (transform: Transform): Item.Spatial => {\n \tconst item: Item.Spatial = {\n \t\tid: this.getId(),\n \t\tkind: Kind.Spatial,\n \t\ttransform,\n \t\tenabled: true\n \t}\n\t\tthis.register(item)\n \treturn item\n }\n\n\tsequence = (...items: Item.Any[]): Item.Sequence => {\n\t\tconst item = {\n\t\t\tid: this.getId(),\n\t\t\tkind: Kind.Sequence,\n\t\t\tchildrenIds: items.map(item => item.id)\n\t\t} as Item.Sequence\n\t\tthis.register(item)\n\t\treturn item\n\t}\n\n\tstack = (...items: Item.Any[]): Item.Stack => {\n\t\tconst item = {\n\t\t\tkind: Kind.Stack,\n\t\t\tid: this.getId(),\n\t\t\tchildrenIds: items.map(item => item.id)\n\t\t} as Item.Stack\n\t\tthis.register(item)\n\t\treturn item\n\t}\n\n\tvideo = (\n\t\tmedia: Media,\n\t\toptions?: {\n\t\t\tstart?: number,\n\t\t\tduration?: number\n\t\t}): Item.Video => {\n\n\t\tif(!media.hasVideo)\n\t\t\tthrow new Error(`Video clip error: media \"${media.datafile.filename}\" has no video track.`)\n\n\t\tconst item: Item.Video = {\n\t\t\tkind: Kind.Video,\n\t\t\tid: this.getId(),\n\t\t\tmediaHash: media.datafile.checksum.hash,\n\t\t\tstart: options?.start ?? 0,\n\t\t\tduration: options?.duration ?? media.duration\n\t\t}\n\t\tthis.register(item)\n\t\treturn item\n\t}\n\n\taudio = (\n\t\tmedia: Media,\n\t\toptions?: {\n\t\t\tstart?: number,\n\t\t\tduration?: number,\n\t\t\tgain?: number\n\t\t}): Item.Audio => {\n\n\t\tif(!media.hasAudio)\n\t\t\tthrow new Error(`Audio clip error: media \"${media.datafile.filename}\" has no audio track.`)\n\n\t\tconst item: Item.Audio = {\n\t\t\tkind: Kind.Audio,\n\t\t\tid: this.getId(),\n\t\t\tmediaHash: media.datafile.checksum.hash,\n\t\t\tstart: options?.start ?? 0,\n\t\t\tduration: options?.duration ?? media.duration,\n\t\t\tgain: options?.gain ?? 1\n\t\t}\n\t\tthis.register(item)\n\t\treturn item\n\t}\n\n\ttext = (content: string, options?: {\n\t\t\tduration?: number,\n\t\t\tstyles?: TextStyleOptions\n\t\t}): Item.Text => {\n\n\t\tconst item = {\n\t\t\tid: this.getId(),\n\t\t\tcontent,\n\t\t\tkind: Kind.Text,\n\t\t\tduration: options?.duration ?? 2000\n\t\t} as Item.Text\n\n\t\tif(options?.styles)\n\t\t\titem.styleId = this.textStyle(options.styles).id\n\n\t\tthis.register(item)\n\t\treturn item\n\t}\n\n\tgap = (duration: number): Item.Gap => {\n\t\tconst item = {\n\t\t\tid: this.getId(),\n\t\t\tkind: Kind.Gap,\n\t\t\tduration\n\t\t} as Item.Gap\n\t\tthis.register(item)\n\t\treturn item\n\t}\n\n\ttransition = {\n\t\tcrossfade: (duration: number): Item.Transition => {\n\t\t\tconst item = {\n\t\t\t\tid: this.getId(),\n\t\t\t\tkind: Kind.Transition,\n\t\t\t\teffect: Effect.Crossfade,\n\t\t\t\tduration,\n\t\t\t} as Item.Transition\n\t\t\tthis.register(item)\n\t\t\treturn item\n\t\t},\n\t}\n\n transform = (options?: TransformOptions): Transform => {\n const position: Vec2 = [\n \toptions?.position?.[0] ?? 0,\n \toptions?.position?.[1] ?? 0\n ]\n const scale: Vec2 = [\n \toptions?.scale?.[0] ?? 1,\n \toptions?.scale?.[1] ?? 1\n ]\n const rotation = options?.rotation ?? 0\n return [position, scale, rotation]\n }\n\n addChildren(parent: Item.Stack | Item.Sequence, ...items: Item.Any[]) {\n\t\tthis.#mutate(state => {\n\t\t\tconst parentItem = state.items.find(({id}) => id === parent.id) as Item.Stack\n\t\t\tparentItem.childrenIds.push(...items.map(item => item.id))\n\t\t\treturn state\n\t\t})\n }\n\n\tset = <K extends Item.Any>(\n\t\tid: Id,\n\t\tpartial: Partial<K>\n\t) => {\n\t\tthis.#mutate(project => ({\n\t\t\t...project,\n\t\t\titems: project.items.map(item =>\n\t\t\t\titem.id === id\n\t\t\t\t\t? { ...item, ...partial }\n\t\t\t\t\t: item\n\t\t\t)\n\t\t}))\n\t}\n}\n\n", "declare const FpsBrand: unique symbol\n\nexport type Fps = number & {\n\treadonly [FpsBrand]: \"fps\"\n}\n\nexport const fps = (value: number): Fps =>\n\tvalue as Fps\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nexport function assert(x) {\n if (!x) {\n throw new Error('Assertion failed.');\n }\n}\nexport const normalizeRotation = (rotation) => {\n const mappedRotation = (rotation % 360 + 360) % 360;\n if (mappedRotation === 0 || mappedRotation === 90 || mappedRotation === 180 || mappedRotation === 270) {\n return mappedRotation;\n }\n else {\n throw new Error(`Invalid rotation ${rotation}.`);\n }\n};\nexport const last = (arr) => {\n return arr && arr[arr.length - 1];\n};\nexport const isU32 = (value) => {\n return value >= 0 && value < 2 ** 32;\n};\nexport class Bitstream {\n constructor(bytes) {\n this.bytes = bytes;\n /** Current offset in bits. */\n this.pos = 0;\n }\n seekToByte(byteOffset) {\n this.pos = 8 * byteOffset;\n }\n readBit() {\n const byteIndex = Math.floor(this.pos / 8);\n const byte = this.bytes[byteIndex] ?? 0;\n const bitIndex = 0b111 - (this.pos & 0b111);\n const bit = (byte & (1 << bitIndex)) >> bitIndex;\n this.pos++;\n return bit;\n }\n readBits(n) {\n if (n === 1) {\n return this.readBit();\n }\n let result = 0;\n for (let i = 0; i < n; i++) {\n result <<= 1;\n result |= this.readBit();\n }\n return result;\n }\n writeBits(n, value) {\n const end = this.pos + n;\n for (let i = this.pos; i < end; i++) {\n const byteIndex = Math.floor(i / 8);\n let byte = this.bytes[byteIndex];\n const bitIndex = 0b111 - (i & 0b111);\n byte &= ~(1 << bitIndex);\n byte |= ((value & (1 << (end - i - 1))) >> (end - i - 1)) << bitIndex;\n this.bytes[byteIndex] = byte;\n }\n this.pos = end;\n }\n ;\n readAlignedByte() {\n // Ensure we're byte-aligned\n if (this.pos % 8 !== 0) {\n throw new Error('Bitstream is not byte-aligned.');\n }\n const byteIndex = this.pos / 8;\n const byte = this.bytes[byteIndex] ?? 0;\n this.pos += 8;\n return byte;\n }\n skipBits(n) {\n this.pos += n;\n }\n getBitsLeft() {\n return this.bytes.length * 8 - this.pos;\n }\n clone() {\n const clone = new Bitstream(this.bytes);\n clone.pos = this.pos;\n return clone;\n }\n}\n/** Reads an exponential-Golomb universal code from a Bitstream. */\nexport const readExpGolomb = (bitstream) => {\n let leadingZeroBits = 0;\n while (bitstream.readBits(1) === 0 && leadingZeroBits < 32) {\n leadingZeroBits++;\n }\n if (leadingZeroBits >= 32) {\n throw new Error('Invalid exponential-Golomb code.');\n }\n const result = (1 << leadingZeroBits) - 1 + bitstream.readBits(leadingZeroBits);\n return result;\n};\n/** Reads a signed exponential-Golomb universal code from a Bitstream. */\nexport const readSignedExpGolomb = (bitstream) => {\n const codeNum = readExpGolomb(bitstream);\n return ((codeNum & 1) === 0)\n ? -(codeNum >> 1)\n : ((codeNum + 1) >> 1);\n};\nexport const writeBits = (bytes, start, end, value) => {\n for (let i = start; i < end; i++) {\n const byteIndex = Math.floor(i / 8);\n let byte = bytes[byteIndex];\n const bitIndex = 0b111 - (i & 0b111);\n byte &= ~(1 << bitIndex);\n byte |= ((value & (1 << (end - i - 1))) >> (end - i - 1)) << bitIndex;\n bytes[byteIndex] = byte;\n }\n};\nexport const toUint8Array = (source) => {\n if (source.constructor === Uint8Array) { // We want a true Uint8Array, not something that extends it like Buffer\n return source;\n }\n else if (ArrayBuffer.isView(source)) {\n return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);\n }\n else {\n return new Uint8Array(source);\n }\n};\nexport const toDataView = (source) => {\n if (source.constructor === DataView) {\n return source;\n }\n else if (ArrayBuffer.isView(source)) {\n return new DataView(source.buffer, source.byteOffset, source.byteLength);\n }\n else {\n return new DataView(source);\n }\n};\nexport const textDecoder = /* #__PURE__ */ new TextDecoder();\nexport const textEncoder = /* #__PURE__ */ new TextEncoder();\nexport const isIso88591Compatible = (text) => {\n for (let i = 0; i < text.length; i++) {\n const code = text.charCodeAt(i);\n if (code > 255) {\n return false;\n }\n }\n return true;\n};\nconst invertObject = (object) => {\n return Object.fromEntries(Object.entries(object).map(([key, value]) => [value, key]));\n};\n// For the color space mappings, see Rec. ITU-T H.273.\nexport const COLOR_PRIMARIES_MAP = {\n bt709: 1, // ITU-R BT.709\n bt470bg: 5, // ITU-R BT.470BG\n smpte170m: 6, // ITU-R BT.601 525 - SMPTE 170M\n bt2020: 9, // ITU-R BT.202\n smpte432: 12, // SMPTE EG 432-1\n};\nexport const COLOR_PRIMARIES_MAP_INVERSE = /* #__PURE__ */ invertObject(COLOR_PRIMARIES_MAP);\nexport const TRANSFER_CHARACTERISTICS_MAP = {\n 'bt709': 1, // ITU-R BT.709\n 'smpte170m': 6, // SMPTE 170M\n 'linear': 8, // Linear transfer characteristics\n 'iec61966-2-1': 13, // IEC 61966-2-1\n 'pq': 16, // Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system\n 'hlg': 18, // Rec. ITU-R BT.2100-2 hybrid loggamma (HLG) system\n};\nexport const TRANSFER_CHARACTERISTICS_MAP_INVERSE = /* #__PURE__ */ invertObject(TRANSFER_CHARACTERISTICS_MAP);\nexport const MATRIX_COEFFICIENTS_MAP = {\n 'rgb': 0, // Identity\n 'bt709': 1, // ITU-R BT.709\n 'bt470bg': 5, // ITU-R BT.470BG\n 'smpte170m': 6, // SMPTE 170M\n 'bt2020-ncl': 9, // ITU-R BT.2020-2 (non-constant luminance)\n};\nexport const MATRIX_COEFFICIENTS_MAP_INVERSE = /* #__PURE__ */ invertObject(MATRIX_COEFFICIENTS_MAP);\nexport const colorSpaceIsComplete = (colorSpace) => {\n return (!!colorSpace\n && !!colorSpace.primaries\n && !!colorSpace.transfer\n && !!colorSpace.matrix\n && colorSpace.fullRange !== undefined);\n};\nexport const isAllowSharedBufferSource = (x) => {\n return (x instanceof ArrayBuffer\n || (typeof SharedArrayBuffer !== 'undefined' && x instanceof SharedArrayBuffer)\n || ArrayBuffer.isView(x));\n};\nexport class AsyncMutex {\n constructor() {\n this.currentPromise = Promise.resolve();\n }\n async acquire() {\n let resolver;\n const nextPromise = new Promise((resolve) => {\n resolver = resolve;\n });\n const currentPromiseAlias = this.currentPromise;\n this.currentPromise = nextPromise;\n await currentPromiseAlias;\n return resolver;\n }\n}\nexport const bytesToHexString = (bytes) => {\n return [...bytes].map(x => x.toString(16).padStart(2, '0')).join('');\n};\nexport const reverseBitsU32 = (x) => {\n x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);\n x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);\n x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);\n x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);\n x = ((x >> 16) & 0x0000ffff) | ((x & 0x0000ffff) << 16);\n return x >>> 0; // Ensure it's treated as an unsigned 32-bit integer\n};\n/** Returns the smallest index i such that val[i] === key, or -1 if no such index exists. */\nexport const binarySearchExact = (arr, key, valueGetter) => {\n let low = 0;\n let high = arr.length - 1;\n let ans = -1;\n while (low <= high) {\n const mid = (low + high) >> 1;\n const midVal = valueGetter(arr[mid]);\n if (midVal === key) {\n ans = mid;\n high = mid - 1; // Continue searching left to find the lowest index\n }\n else if (midVal < key) {\n low = mid + 1;\n }\n else {\n high = mid - 1;\n }\n }\n return ans;\n};\n/** Returns the largest index i such that val[i] <= key, or -1 if no such index exists. */\nexport const binarySearchLessOrEqual = (arr, key, valueGetter) => {\n let low = 0;\n let high = arr.length - 1;\n let ans = -1;\n while (low <= high) {\n const mid = (low + (high - low + 1) / 2) | 0;\n const midVal = valueGetter(arr[mid]);\n if (midVal <= key) {\n ans = mid;\n low = mid + 1;\n }\n else {\n high = mid - 1;\n }\n }\n return ans;\n};\n/** Assumes the array is already sorted. */\nexport const insertSorted = (arr, item, valueGetter) => {\n const insertionIndex = binarySearchLessOrEqual(arr, valueGetter(item), valueGetter);\n arr.splice(insertionIndex + 1, 0, item); // This even behaves correctly for the -1 case\n};\nexport const promiseWithResolvers = () => {\n let resolve;\n let reject;\n const promise = new Promise((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve: resolve, reject: reject };\n};\nexport const removeItem = (arr, item) => {\n const index = arr.indexOf(item);\n if (index !== -1) {\n arr.splice(index, 1);\n }\n};\nexport const findLast = (arr, predicate) => {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (predicate(arr[i])) {\n return arr[i];\n }\n }\n return undefined;\n};\nexport const findLastIndex = (arr, predicate) => {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (predicate(arr[i])) {\n return i;\n }\n }\n return -1;\n};\nexport const toAsyncIterator = async function* (source) {\n if (Symbol.iterator in source) {\n // @ts-expect-error Trust me\n yield* source[Symbol.iterator]();\n }\n else {\n // @ts-expect-error Trust me\n yield* source[Symbol.asyncIterator]();\n }\n};\nexport const validateAnyIterable = (iterable) => {\n if (!(Symbol.iterator in iterable) && !(Symbol.asyncIterator in iterable)) {\n throw new TypeError('Argument must be an iterable or async iterable.');\n }\n};\nexport const assertNever = (x) => {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unexpected value: ${x}`);\n};\nexport const getUint24 = (view, byteOffset, littleEndian) => {\n const byte1 = view.getUint8(byteOffset);\n const byte2 = view.getUint8(byteOffset + 1);\n const byte3 = view.getUint8(byteOffset + 2);\n if (littleEndian) {\n return byte1 | (byte2 << 8) | (byte3 << 16);\n }\n else {\n return (byte1 << 16) | (byte2 << 8) | byte3;\n }\n};\nexport const getInt24 = (view, byteOffset, littleEndian) => {\n // The left shift pushes the most significant bit into the sign bit region, and the subsequent right shift\n // then correctly interprets the sign bit.\n return getUint24(view, byteOffset, littleEndian) << 8 >> 8;\n};\nexport const setUint24 = (view, byteOffset, value, littleEndian) => {\n // Ensure the value is within 24-bit unsigned range (0 to 16777215)\n value = value >>> 0; // Convert to unsigned 32-bit\n value = value & 0xFFFFFF; // Mask to 24 bits\n if (littleEndian) {\n view.setUint8(byteOffset, value & 0xFF);\n view.setUint8(byteOffset + 1, (value >>> 8) & 0xFF);\n view.setUint8(byteOffset + 2, (value >>> 16) & 0xFF);\n }\n else {\n view.setUint8(byteOffset, (value >>> 16) & 0xFF);\n view.setUint8(byteOffset + 1, (value >>> 8) & 0xFF);\n view.setUint8(byteOffset + 2, value & 0xFF);\n }\n};\nexport const setInt24 = (view, byteOffset, value, littleEndian) => {\n // Ensure the value is within 24-bit signed range (-8388608 to 8388607)\n value = clamp(value, -8388608, 8388607);\n // Convert negative values to their 24-bit representation\n if (value < 0) {\n value = (value + 0x1000000) & 0xFFFFFF;\n }\n setUint24(view, byteOffset, value, littleEndian);\n};\nexport const setInt64 = (view, byteOffset, value, littleEndian) => {\n if (littleEndian) {\n view.setUint32(byteOffset + 0, value, true);\n view.setInt32(byteOffset + 4, Math.floor(value / 2 ** 32), true);\n }\n else {\n view.setInt32(byteOffset + 0, Math.floor(value / 2 ** 32), true);\n view.setUint32(byteOffset + 4, value, true);\n }\n};\n/**\n * Calls a function on each value spat out by an async generator. The reason for writing this manually instead of\n * using a generator function is that the generator function queues return() calls - here, we forward them immediately.\n */\nexport const mapAsyncGenerator = (generator, map) => {\n return {\n async next() {\n const result = await generator.next();\n if (result.done) {\n return { value: undefined, done: true };\n }\n else {\n return { value: map(result.value), done: false };\n }\n },\n return() {\n return generator.return();\n },\n throw(error) {\n return generator.throw(error);\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n};\nexport const clamp = (value, min, max) => {\n return Math.max(min, Math.min(max, value));\n};\nexport const UNDETERMINED_LANGUAGE = 'und';\nexport const roundIfAlmostInteger = (value) => {\n const rounded = Math.round(value);\n if (Math.abs(value / rounded - 1) < 10 * Number.EPSILON) {\n return rounded;\n }\n else {\n return value;\n }\n};\nexport const roundToMultiple = (value, multiple) => {\n return Math.round(value / multiple) * multiple;\n};\nexport const ilog = (x) => {\n let ret = 0;\n while (x) {\n ret++;\n x >>= 1;\n }\n return ret;\n};\nconst ISO_639_2_REGEX = /^[a-z]{3}$/;\nexport const isIso639Dash2LanguageCode = (x) => {\n return ISO_639_2_REGEX.test(x);\n};\n// Since the result will be truncated, add a bit of eps to compensate for floating point errors\nexport const SECOND_TO_MICROSECOND_FACTOR = 1e6 * (1 + Number.EPSILON);\n/**\n * Merges two RequestInit objects with special handling for headers.\n * Headers are merged case-insensitively, but original casing is preserved.\n * init2 headers take precedence and will override case-insensitive matches from init1.\n */\nexport const mergeRequestInit = (init1, init2) => {\n const merged = { ...init1, ...init2 };\n // Special handling for headers\n if (init1.headers || init2.headers) {\n const headers1 = init1.headers ? normalizeHeaders(init1.headers) : {};\n const headers2 = init2.headers ? normalizeHeaders(init2.headers) : {};\n const mergedHeaders = { ...headers1 };\n // For each header in headers2, check if a case-insensitive match exists in mergedHeaders\n Object.entries(headers2).forEach(([key2, value2]) => {\n const existingKey = Object.keys(mergedHeaders).find(key1 => key1.toLowerCase() === key2.toLowerCase());\n if (existingKey) {\n delete mergedHeaders[existingKey];\n }\n mergedHeaders[key2] = value2;\n });\n merged.headers = mergedHeaders;\n }\n return merged;\n};\n/** Normalizes HeadersInit to a Record<string, string> format. */\nconst normalizeHeaders = (headers) => {\n if (headers instanceof Headers) {\n const result = {};\n headers.forEach((value, key) => {\n result[key] = value;\n });\n return result;\n }\n if (Array.isArray(headers)) {\n const result = {};\n headers.forEach(([key, value]) => {\n result[key] = value;\n });\n return result;\n }\n return headers;\n};\nexport const retriedFetch = async (fetchFn, url, requestInit, getRetryDelay, shouldStop) => {\n let attempts = 0;\n while (true) {\n try {\n return await fetchFn(url, requestInit);\n }\n catch (error) {\n if (shouldStop()) {\n throw error;\n }\n attempts++;\n const retryDelayInSeconds = getRetryDelay(attempts, error, url);\n if (retryDelayInSeconds === null) {\n throw error;\n }\n console.error('Retrying failed fetch. Error:', error);\n if (!Number.isFinite(retryDelayInSeconds) || retryDelayInSeconds < 0) {\n throw new TypeError('Retry delay must be a non-negative finite number.');\n }\n if (retryDelayInSeconds > 0) {\n await new Promise(resolve => setTimeout(resolve, 1000 * retryDelayInSeconds));\n }\n if (shouldStop()) {\n throw error;\n }\n }\n }\n};\nexport const computeRationalApproximation = (x, maxDenominator) => {\n // Handle negative numbers\n const sign = x < 0 ? -1 : 1;\n x = Math.abs(x);\n let prevNumerator = 0, prevDenominator = 1;\n let currNumerator = 1, currDenominator = 0;\n // Continued fraction algorithm\n let remainder = x;\n while (true) {\n const integer = Math.floor(remainder);\n // Calculate next convergent\n const nextNumerator = integer * currNumerator + prevNumerator;\n const nextDenominator = integer * currDenominator + prevDenominator;\n if (nextDenominator > maxDenominator) {\n return {\n numerator: sign * currNumerator,\n denominator: currDenominator,\n };\n }\n prevNumerator = currNumerator;\n prevDenominator = currDenominator;\n currNumerator = nextNumerator;\n currDenominator = nextDenominator;\n remainder = 1 / (remainder - integer);\n // Guard against precision issues\n if (!isFinite(remainder)) {\n break;\n }\n }\n return {\n numerator: sign * currNumerator,\n denominator: currDenominator,\n };\n};\nexport class CallSerializer {\n constructor() {\n this.currentPromise = Promise.resolve();\n }\n call(fn) {\n return this.currentPromise = this.currentPromise.then(fn);\n }\n}\nlet isWebKitCache = null;\nexport const isWebKit = () => {\n if (isWebKitCache !== null) {\n return isWebKitCache;\n }\n // This even returns true for WebKit-wrapping browsers such as Chrome on iOS\n return isWebKitCache = !!(typeof navigator !== 'undefined'\n && (navigator.vendor?.match(/apple/i)\n // Or, in workers:\n || (/AppleWebKit/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent))\n || /\\b(iPad|iPhone|iPod)\\b/.test(navigator.userAgent)));\n};\nlet isFirefoxCache = null;\nexport const isFirefox = () => {\n if (isFirefoxCache !== null) {\n return isFirefoxCache;\n }\n return isFirefoxCache = typeof navigator !== 'undefined' && navigator.userAgent?.includes('Firefox');\n};\nlet isChromiumCache = null;\nexport const isChromium = () => {\n if (isChromiumCache !== null) {\n return isChromiumCache;\n }\n return isChromiumCache = !!(typeof navigator !== 'undefined'\n && (navigator.vendor?.includes('Google Inc') || /Chrome/.test(navigator.userAgent)));\n};\nlet chromiumVersionCache = null;\nexport const getChromiumVersion = () => {\n if (chromiumVersionCache !== null) {\n return chromiumVersionCache;\n }\n if (typeof navigator === 'undefined') {\n return null;\n }\n const match = /\\bChrome\\/(\\d+)/.exec(navigator.userAgent);\n if (!match) {\n return null;\n }\n return chromiumVersionCache = Number(match[1]);\n};\n/** Acts like `??` except the condition is -1 and not null/undefined. */\nexport const coalesceIndex = (a, b) => {\n return a !== -1 ? a : b;\n};\nexport const closedIntervalsOverlap = (startA, endA, startB, endB) => {\n return startA <= endB && startB <= endA;\n};\nexport const keyValueIterator = function* (object) {\n for (const key in object) {\n const value = object[key];\n if (value === undefined) {\n continue;\n }\n yield { key, value };\n }\n};\nexport const imageMimeTypeToExtension = (mimeType) => {\n switch (mimeType.toLowerCase()) {\n case 'image/jpeg':\n case 'image/jpg':\n return '.jpg';\n case 'image/png':\n return '.png';\n case 'image/gif':\n return '.gif';\n case 'image/webp':\n return '.webp';\n case 'image/bmp':\n return '.bmp';\n case 'image/svg+xml':\n return '.svg';\n case 'image/tiff':\n return '.tiff';\n case 'image/avif':\n return '.avif';\n case 'image/x-icon':\n case 'image/vnd.microsoft.icon':\n return '.ico';\n default:\n return null;\n }\n};\nexport const base64ToBytes = (base64) => {\n const decoded = atob(base64);\n const bytes = new Uint8Array(decoded.length);\n for (let i = 0; i < decoded.length; i++) {\n bytes[i] = decoded.charCodeAt(i);\n }\n return bytes;\n};\nexport const bytesToBase64 = (bytes) => {\n let string = '';\n for (let i = 0; i < bytes.length; i++) {\n string += String.fromCharCode(bytes[i]);\n }\n return btoa(string);\n};\nexport const uint8ArraysAreEqual = (a, b) => {\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n};\nexport const polyfillSymbolDispose = () => {\n // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html\n // @ts-expect-error Readonly\n Symbol.dispose ??= Symbol('Symbol.dispose');\n};\nexport const isNumber = (x) => {\n return typeof x === 'number' && !Number.isNaN(x);\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n/**\n * Image data with additional metadata.\n *\n * @group Metadata tags\n * @public\n */\nexport class RichImageData {\n /** Creates a new {@link RichImageData}. */\n constructor(\n /** The raw image data. */\n data, \n /** An RFC 6838 MIME type (e.g. image/jpeg, image/png, etc.) */\n mimeType) {\n this.data = data;\n this.mimeType = mimeType;\n if (!(data instanceof Uint8Array)) {\n throw new TypeError('data must be a Uint8Array.');\n }\n if (typeof mimeType !== 'string') {\n throw new TypeError('mimeType must be a string.');\n }\n }\n}\n/**\n * A file attached to a media file.\n *\n * @group Metadata tags\n * @public\n */\nexport class AttachedFile {\n /** Creates a new {@link AttachedFile}. */\n constructor(\n /** The raw file data. */\n data, \n /** An RFC 6838 MIME type (e.g. image/jpeg, image/png, font/ttf, etc.) */\n mimeType, \n /** The name of the file. */\n name, \n /** A description of the file. */\n description) {\n this.data = data;\n this.mimeType = mimeType;\n this.name = name;\n this.description = description;\n if (!(data instanceof Uint8Array)) {\n throw new TypeError('data must be a Uint8Array.');\n }\n if (mimeType !== undefined && typeof mimeType !== 'string') {\n throw new TypeError('mimeType, when provided, must be a string.');\n }\n if (name !== undefined && typeof name !== 'string') {\n throw new TypeError('name, when provided, must be a string.');\n }\n if (description !== undefined && typeof description !== 'string') {\n throw new TypeError('description, when provided, must be a string.');\n }\n }\n}\n;\nexport const validateMetadataTags = (tags) => {\n if (!tags || typeof tags !== 'object') {\n throw new TypeError('tags must be an object.');\n }\n if (tags.title !== undefined && typeof tags.title !== 'string') {\n throw new TypeError('tags.title, when provided, must be a string.');\n }\n if (tags.description !== undefined && typeof tags.description !== 'string') {\n throw new TypeError('tags.description, when provided, must be a string.');\n }\n if (tags.artist !== undefined && typeof tags.artist !== 'string') {\n throw new TypeError('tags.artist, when provided, must be a string.');\n }\n if (tags.album !== undefined && typeof tags.album !== 'string') {\n throw new TypeError('tags.album, when provided, must be a string.');\n }\n if (tags.albumArtist !== undefined && typeof tags.albumArtist !== 'string') {\n throw new TypeError('tags.albumArtist, when provided, must be a string.');\n }\n if (tags.trackNumber !== undefined && (!Number.isInteger(tags.trackNumber) || tags.trackNumber <= 0)) {\n throw new TypeError('tags.trackNumber, when provided, must be a positive integer.');\n }\n if (tags.tracksTotal !== undefined\n && (!Number.isInteger(tags.tracksTotal) || tags.tracksTotal <= 0)) {\n throw new TypeError('tags.tracksTotal, when provided, must be a positive integer.');\n }\n if (tags.discNumber !== undefined && (!Number.isInteger(tags.discNumber) || tags.discNumber <= 0)) {\n throw new TypeError('tags.discNumber, when provided, must be a positive integer.');\n }\n if (tags.discsTotal !== undefined\n && (!Number.isInteger(tags.discsTotal) || tags.discsTotal <= 0)) {\n throw new TypeError('tags.discsTotal, when provided, must be a positive integer.');\n }\n if (tags.genre !== undefined && typeof tags.genre !== 'string') {\n throw new TypeError('tags.genre, when provided, must be a string.');\n }\n if (tags.date !== undefined && (!(tags.date instanceof Date) || Number.isNaN(tags.date.getTime()))) {\n throw new TypeError('tags.date, when provided, must be a valid Date.');\n }\n if (tags.lyrics !== undefined && typeof tags.lyrics !== 'string') {\n throw new TypeError('tags.lyrics, when provided, must be a string.');\n }\n if (tags.images !== undefined) {\n if (!Array.isArray(tags.images)) {\n throw new TypeError('tags.images, when provided, must be an array.');\n }\n for (const image of tags.images) {\n if (!image || typeof image !== 'object') {\n throw new TypeError('Each image in tags.images must be an object.');\n }\n if (!(image.data instanceof Uint8Array)) {\n throw new TypeError('Each image.data must be a Uint8Array.');\n }\n if (typeof image.mimeType !== 'string') {\n throw new TypeError('Each image.mimeType must be a string.');\n }\n if (!['coverFront', 'coverBack', 'unknown'].includes(image.kind)) {\n throw new TypeError('Each image.kind must be \\'coverFront\\', \\'coverBack\\', or \\'unknown\\'.');\n }\n }\n }\n if (tags.comment !== undefined && typeof tags.comment !== 'string') {\n throw new TypeError('tags.comment, when provided, must be a string.');\n }\n if (tags.raw !== undefined) {\n if (!tags.raw || typeof tags.raw !== 'object') {\n throw new TypeError('tags.raw, when provided, must be an object.');\n }\n for (const value of Object.values(tags.raw)) {\n if (value !== null\n && typeof value !== 'string'\n && !(value instanceof Uint8Array)\n && !(value instanceof RichImageData)\n && !(value instanceof AttachedFile)) {\n throw new TypeError('Each value in tags.raw must be a string, Uint8Array, RichImageData, AttachedFile, or null.');\n }\n }\n }\n};\nexport const metadataTagsAreEmpty = (tags) => {\n return tags.title === undefined\n && tags.description === undefined\n && tags.artist === undefined\n && tags.album === undefined\n && tags.albumArtist === undefined\n && tags.trackNumber === undefined\n && tags.tracksTotal === undefined\n && tags.discNumber === undefined\n && tags.discsTotal === undefined\n && tags.genre === undefined\n && tags.date === undefined\n && tags.lyrics === undefined\n && (!tags.images || tags.images.length === 0)\n && tags.comment === undefined\n && (tags.raw === undefined || Object.keys(tags.raw).length === 0);\n};\nexport const DEFAULT_TRACK_DISPOSITION = {\n default: true,\n forced: false,\n original: false,\n commentary: false,\n hearingImpaired: false,\n visuallyImpaired: false,\n};\nexport const validateTrackDisposition = (disposition) => {\n if (!disposition || typeof disposition !== 'object') {\n throw new TypeError('disposition must be an object.');\n }\n if (disposition.default !== undefined && typeof disposition.default !== 'boolean') {\n throw new TypeError('disposition.default must be a boolean.');\n }\n if (disposition.forced !== undefined && typeof disposition.forced !== 'boolean') {\n throw new TypeError('disposition.forced must be a boolean.');\n }\n if (disposition.original !== undefined && typeof disposition.original !== 'boolean') {\n throw new TypeError('disposition.original must be a boolean.');\n }\n if (disposition.commentary !== undefined && typeof disposition.commentary !== 'boolean') {\n throw new TypeError('disposition.commentary must be a boolean.');\n }\n if (disposition.hearingImpaired !== undefined && typeof disposition.hearingImpaired !== 'boolean') {\n throw new TypeError('disposition.hearingImpaired must be a boolean.');\n }\n if (disposition.visuallyImpaired !== undefined && typeof disposition.visuallyImpaired !== 'boolean') {\n throw new TypeError('disposition.visuallyImpaired must be a boolean.');\n }\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { Bitstream, COLOR_PRIMARIES_MAP, MATRIX_COEFFICIENTS_MAP, TRANSFER_CHARACTERISTICS_MAP, assert, bytesToHexString, isAllowSharedBufferSource, last, reverseBitsU32, toDataView, } from './misc.js';\n/**\n * List of known video codecs, ordered by encoding preference.\n * @group Codecs\n * @public\n */\nexport const VIDEO_CODECS = [\n 'avc',\n 'hevc',\n 'vp9',\n 'av1',\n 'vp8',\n];\n/**\n * List of known PCM (uncompressed) audio codecs, ordered by encoding preference.\n * @group Codecs\n * @public\n */\nexport const PCM_AUDIO_CODECS = [\n 'pcm-s16', // We don't prefix 'le' so we're compatible with the WebCodecs-registered PCM codec strings\n 'pcm-s16be',\n 'pcm-s24',\n 'pcm-s24be',\n 'pcm-s32',\n 'pcm-s32be',\n 'pcm-f32',\n 'pcm-f32be',\n 'pcm-f64',\n 'pcm-f64be',\n 'pcm-u8',\n 'pcm-s8',\n 'ulaw',\n 'alaw',\n];\n/**\n * List of known compressed audio codecs, ordered by encoding preference.\n * @group Codecs\n * @public\n */\nexport const NON_PCM_AUDIO_CODECS = [\n 'aac',\n 'opus',\n 'mp3',\n 'vorbis',\n 'flac',\n];\n/**\n * List of known audio codecs, ordered by encoding preference.\n * @group Codecs\n * @public\n */\nexport const AUDIO_CODECS = [\n ...NON_PCM_AUDIO_CODECS,\n ...PCM_AUDIO_CODECS,\n];\n/**\n * List of known subtitle codecs, ordered by encoding preference.\n * @group Codecs\n * @public\n */\nexport const SUBTITLE_CODECS = [\n 'webvtt',\n]; // TODO add the rest\n// https://en.wikipedia.org/wiki/Advanced_Video_Coding\nconst AVC_LEVEL_TABLE = [\n { maxMacroblocks: 99, maxBitrate: 64000, level: 0x0A }, // Level 1\n { maxMacroblocks: 396, maxBitrate: 192000, level: 0x0B }, // Level 1.1\n { maxMacroblocks: 396, maxBitrate: 384000, level: 0x0C }, // Level 1.2\n { maxMacroblocks: 396, maxBitrate: 768000, level: 0x0D }, // Level 1.3\n { maxMacroblocks: 396, maxBitrate: 2000000, level: 0x14 }, // Level 2\n { maxMacroblocks: 792, maxBitrate: 4000000, level: 0x15 }, // Level 2.1\n { maxMacroblocks: 1620, maxBitrate: 4000000, level: 0x16 }, // Level 2.2\n { maxMacroblocks: 1620, maxBitrate: 10000000, level: 0x1E }, // Level 3\n { maxMacroblocks: 3600, maxBitrate: 14000000, level: 0x1F }, // Level 3.1\n { maxMacroblocks: 5120, maxBitrate: 20000000, level: 0x20 }, // Level 3.2\n { maxMacroblocks: 8192, maxBitrate: 20000000, level: 0x28 }, // Level 4\n { maxMacroblocks: 8192, maxBitrate: 50000000, level: 0x29 }, // Level 4.1\n { maxMacroblocks: 8704, maxBitrate: 50000000, level: 0x2A }, // Level 4.2\n { maxMacroblocks: 22080, maxBitrate: 135000000, level: 0x32 }, // Level 5\n { maxMacroblocks: 36864, maxBitrate: 240000000, level: 0x33 }, // Level 5.1\n { maxMacroblocks: 36864, maxBitrate: 240000000, level: 0x34 }, // Level 5.2\n { maxMacroblocks: 139264, maxBitrate: 240000000, level: 0x3C }, // Level 6\n { maxMacroblocks: 139264, maxBitrate: 480000000, level: 0x3D }, // Level 6.1\n { maxMacroblocks: 139264, maxBitrate: 800000000, level: 0x3E }, // Level 6.2\n];\n// https://en.wikipedia.org/wiki/High_Efficiency_Video_Coding\nconst HEVC_LEVEL_TABLE = [\n { maxPictureSize: 36864, maxBitrate: 128000, tier: 'L', level: 30 }, // Level 1 (Low Tier)\n { maxPictureSize: 122880, maxBitrate: 1500000, tier: 'L', level: 60 }, // Level 2 (Low Tier)\n { maxPictureSize: 245760, maxBitrate: 3000000, tier: 'L', level: 63 }, // Level 2.1 (Low Tier)\n { maxPictureSize: 552960, maxBitrate: 6000000, tier: 'L', level: 90 }, // Level 3 (Low Tier)\n { maxPictureSize: 983040, maxBitrate: 10000000, tier: 'L', level: 93 }, // Level 3.1 (Low Tier)\n { maxPictureSize: 2228224, maxBitrate: 12000000, tier: 'L', level: 120 }, // Level 4 (Low Tier)\n { maxPictureSize: 2228224, maxBitrate: 30000000, tier: 'H', level: 120 }, // Level 4 (High Tier)\n { maxPictureSize: 2228224, maxBitrate: 20000000, tier: 'L', level: 123 }, // Level 4.1 (Low Tier)\n { maxPictureSize: 2228224, maxBitrate: 50000000, tier: 'H', level: 123 }, // Level 4.1 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 25000000, tier: 'L', level: 150 }, // Level 5 (Low Tier)\n { maxPictureSize: 8912896, maxBitrate: 100000000, tier: 'H', level: 150 }, // Level 5 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 40000000, tier: 'L', level: 153 }, // Level 5.1 (Low Tier)\n { maxPictureSize: 8912896, maxBitrate: 160000000, tier: 'H', level: 153 }, // Level 5.1 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 60000000, tier: 'L', level: 156 }, // Level 5.2 (Low Tier)\n { maxPictureSize: 8912896, maxBitrate: 240000000, tier: 'H', level: 156 }, // Level 5.2 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 60000000, tier: 'L', level: 180 }, // Level 6 (Low Tier)\n { maxPictureSize: 35651584, maxBitrate: 240000000, tier: 'H', level: 180 }, // Level 6 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 120000000, tier: 'L', level: 183 }, // Level 6.1 (Low Tier)\n { maxPictureSize: 35651584, maxBitrate: 480000000, tier: 'H', level: 183 }, // Level 6.1 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 240000000, tier: 'L', level: 186 }, // Level 6.2 (Low Tier)\n { maxPictureSize: 35651584, maxBitrate: 800000000, tier: 'H', level: 186 }, // Level 6.2 (High Tier)\n];\n// https://en.wikipedia.org/wiki/VP9\nexport const VP9_LEVEL_TABLE = [\n { maxPictureSize: 36864, maxBitrate: 200000, level: 10 }, // Level 1\n { maxPictureSize: 73728, maxBitrate: 800000, level: 11 }, // Level 1.1\n { maxPictureSize: 122880, maxBitrate: 1800000, level: 20 }, // Level 2\n { maxPictureSize: 245760, maxBitrate: 3600000, level: 21 }, // Level 2.1\n { maxPictureSize: 552960, maxBitrate: 7200000, level: 30 }, // Level 3\n { maxPictureSize: 983040, maxBitrate: 12000000, level: 31 }, // Level 3.1\n { maxPictureSize: 2228224, maxBitrate: 18000000, level: 40 }, // Level 4\n { maxPictureSize: 2228224, maxBitrate: 30000000, level: 41 }, // Level 4.1\n { maxPictureSize: 8912896, maxBitrate: 60000000, level: 50 }, // Level 5\n { maxPictureSize: 8912896, maxBitrate: 120000000, level: 51 }, // Level 5.1\n { maxPictureSize: 8912896, maxBitrate: 180000000, level: 52 }, // Level 5.2\n { maxPictureSize: 35651584, maxBitrate: 180000000, level: 60 }, // Level 6\n { maxPictureSize: 35651584, maxBitrate: 240000000, level: 61 }, // Level 6.1\n { maxPictureSize: 35651584, maxBitrate: 480000000, level: 62 }, // Level 6.2\n];\n// https://en.wikipedia.org/wiki/AV1\nconst AV1_LEVEL_TABLE = [\n { maxPictureSize: 147456, maxBitrate: 1500000, tier: 'M', level: 0 }, // Level 2.0 (Main Tier)\n { maxPictureSize: 278784, maxBitrate: 3000000, tier: 'M', level: 1 }, // Level 2.1 (Main Tier)\n { maxPictureSize: 665856, maxBitrate: 6000000, tier: 'M', level: 4 }, // Level 3.0 (Main Tier)\n { maxPictureSize: 1065024, maxBitrate: 10000000, tier: 'M', level: 5 }, // Level 3.1 (Main Tier)\n { maxPictureSize: 2359296, maxBitrate: 12000000, tier: 'M', level: 8 }, // Level 4.0 (Main Tier)\n { maxPictureSize: 2359296, maxBitrate: 30000000, tier: 'H', level: 8 }, // Level 4.0 (High Tier)\n { maxPictureSize: 2359296, maxBitrate: 20000000, tier: 'M', level: 9 }, // Level 4.1 (Main Tier)\n { maxPictureSize: 2359296, maxBitrate: 50000000, tier: 'H', level: 9 }, // Level 4.1 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 30000000, tier: 'M', level: 12 }, // Level 5.0 (Main Tier)\n { maxPictureSize: 8912896, maxBitrate: 100000000, tier: 'H', level: 12 }, // Level 5.0 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 40000000, tier: 'M', level: 13 }, // Level 5.1 (Main Tier)\n { maxPictureSize: 8912896, maxBitrate: 160000000, tier: 'H', level: 13 }, // Level 5.1 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 60000000, tier: 'M', level: 14 }, // Level 5.2 (Main Tier)\n { maxPictureSize: 8912896, maxBitrate: 240000000, tier: 'H', level: 14 }, // Level 5.2 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 60000000, tier: 'M', level: 15 }, // Level 5.3 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 240000000, tier: 'H', level: 15 }, // Level 5.3 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 60000000, tier: 'M', level: 16 }, // Level 6.0 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 240000000, tier: 'H', level: 16 }, // Level 6.0 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 100000000, tier: 'M', level: 17 }, // Level 6.1 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 480000000, tier: 'H', level: 17 }, // Level 6.1 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 160000000, tier: 'M', level: 18 }, // Level 6.2 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 800000000, tier: 'H', level: 18 }, // Level 6.2 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 160000000, tier: 'M', level: 19 }, // Level 6.3 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 800000000, tier: 'H', level: 19 }, // Level 6.3 (High Tier)\n];\nconst VP9_DEFAULT_SUFFIX = '.01.01.01.01.00';\nconst AV1_DEFAULT_SUFFIX = '.0.110.01.01.01.0';\nexport const buildVideoCodecString = (codec, width, height, bitrate) => {\n if (codec === 'avc') {\n const profileIndication = 0x64; // High Profile\n const totalMacroblocks = Math.ceil(width / 16) * Math.ceil(height / 16);\n // Determine the level based on the table\n const levelInfo = AVC_LEVEL_TABLE.find(level => totalMacroblocks <= level.maxMacroblocks && bitrate <= level.maxBitrate) ?? last(AVC_LEVEL_TABLE);\n const levelIndication = levelInfo ? levelInfo.level : 0;\n const hexProfileIndication = profileIndication.toString(16).padStart(2, '0');\n const hexProfileCompatibility = '00';\n const hexLevelIndication = levelIndication.toString(16).padStart(2, '0');\n return `avc1.${hexProfileIndication}${hexProfileCompatibility}${hexLevelIndication}`;\n }\n else if (codec === 'hevc') {\n const profilePrefix = ''; // Profile space 0\n const profileIdc = 1; // Main Profile\n const compatibilityFlags = '6'; // Taken from the example in ISO 14496-15\n const pictureSize = width * height;\n const levelInfo = HEVC_LEVEL_TABLE.find(level => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? last(HEVC_LEVEL_TABLE);\n const constraintFlags = 'B0'; // Progressive source flag\n return 'hev1.'\n + `${profilePrefix}${profileIdc}.`\n + `${compatibilityFlags}.`\n + `${levelInfo.tier}${levelInfo.level}.`\n + `${constraintFlags}`;\n }\n else if (codec === 'vp8') {\n return 'vp8'; // Easy, this one\n }\n else if (codec === 'vp9') {\n const profile = '00'; // Profile 0\n const pictureSize = width * height;\n const levelInfo = VP9_LEVEL_TABLE.find(level => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? last(VP9_LEVEL_TABLE);\n const bitDepth = '08'; // 8-bit\n return `vp09.${profile}.${levelInfo.level.toString().padStart(2, '0')}.${bitDepth}`;\n }\n else if (codec === 'av1') {\n const profile = 0; // Main Profile, single digit\n const pictureSize = width * height;\n const levelInfo = AV1_LEVEL_TABLE.find(level => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? last(AV1_LEVEL_TABLE);\n const level = levelInfo.level.toString().padStart(2, '0');\n const bitDepth = '08'; // 8-bit\n return `av01.${profile}.${level}${levelInfo.tier}.${bitDepth}`;\n }\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new TypeError(`Unhandled codec '${codec}'.`);\n};\nexport const generateVp9CodecConfigurationFromCodecString = (codecString) => {\n // Reference: https://www.webmproject.org/docs/container/#vp9-codec-feature-metadata-codecprivate\n const parts = codecString.split('.'); // We can derive the required values from the codec string\n const profile = Number(parts[1]);\n const level = Number(parts[2]);\n const bitDepth = Number(parts[3]);\n const chromaSubsampling = parts[4] ? Number(parts[4]) : 1;\n return [\n 1, 1, profile,\n 2, 1, level,\n 3, 1, bitDepth,\n 4, 1, chromaSubsampling,\n ];\n};\nexport const generateAv1CodecConfigurationFromCodecString = (codecString) => {\n // Reference: https://aomediacodec.github.io/av1-isobmff/\n const parts = codecString.split('.'); // We can derive the required values from the codec string\n const marker = 1;\n const version = 1;\n const firstByte = (marker << 7) + version;\n const profile = Number(parts[1]);\n const levelAndTier = parts[2];\n const level = Number(levelAndTier.slice(0, -1));\n const secondByte = (profile << 5) + level;\n const tier = levelAndTier.slice(-1) === 'H' ? 1 : 0;\n const bitDepth = Number(parts[3]);\n const highBitDepth = bitDepth === 8 ? 0 : 1;\n const twelveBit = 0;\n const monochrome = parts[4] ? Number(parts[4]) : 0;\n const chromaSubsamplingX = parts[5] ? Number(parts[5][0]) : 1;\n const chromaSubsamplingY = parts[5] ? Number(parts[5][1]) : 1;\n const chromaSamplePosition = parts[5] ? Number(parts[5][2]) : 0; // CSP_UNKNOWN\n const thirdByte = (tier << 7)\n + (highBitDepth << 6)\n + (twelveBit << 5)\n + (monochrome << 4)\n + (chromaSubsamplingX << 3)\n + (chromaSubsamplingY << 2)\n + chromaSamplePosition;\n const initialPresentationDelayPresent = 0; // Should be fine\n const fourthByte = initialPresentationDelayPresent;\n return [firstByte, secondByte, thirdByte, fourthByte];\n};\nexport const extractVideoCodecString = (trackInfo) => {\n const { codec, codecDescription, colorSpace, avcCodecInfo, hevcCodecInfo, vp9CodecInfo, av1CodecInfo } = trackInfo;\n if (codec === 'avc') {\n assert(trackInfo.avcType !== null);\n if (avcCodecInfo) {\n const bytes = new Uint8Array([\n avcCodecInfo.avcProfileIndication,\n avcCodecInfo.profileCompatibility,\n avcCodecInfo.avcLevelIndication,\n ]);\n return `avc${trackInfo.avcType}.${bytesToHexString(bytes)}`;\n }\n if (!codecDescription || codecDescription.byteLength < 4) {\n throw new TypeError('AVC decoder description is not provided or is not at least 4 bytes long.');\n }\n return `avc${trackInfo.avcType}.${bytesToHexString(codecDescription.subarray(1, 4))}`;\n }\n else if (codec === 'hevc') {\n let generalProfileSpace;\n let generalProfileIdc;\n let compatibilityFlags;\n let generalTierFlag;\n let generalLevelIdc;\n let constraintFlags;\n if (hevcCodecInfo) {\n generalProfileSpace = hevcCodecInfo.generalProfileSpace;\n generalProfileIdc = hevcCodecInfo.generalProfileIdc;\n compatibilityFlags = reverseBitsU32(hevcCodecInfo.generalProfileCompatibilityFlags);\n generalTierFlag = hevcCodecInfo.generalTierFlag;\n generalLevelIdc = hevcCodecInfo.generalLevelIdc;\n constraintFlags = [...hevcCodecInfo.generalConstraintIndicatorFlags];\n }\n else {\n if (!codecDescription || codecDescription.byteLength < 23) {\n throw new TypeError('HEVC decoder description is not provided or is not at least 23 bytes long.');\n }\n const view = toDataView(codecDescription);\n const profileByte = view.getUint8(1);\n generalProfileSpace = (profileByte >> 6) & 0x03;\n generalProfileIdc = profileByte & 0x1F;\n compatibilityFlags = reverseBitsU32(view.getUint32(2));\n generalTierFlag = (profileByte >> 5) & 0x01;\n generalLevelIdc = view.getUint8(12);\n constraintFlags = [];\n for (let i = 0; i < 6; i++) {\n constraintFlags.push(view.getUint8(6 + i));\n }\n }\n let codecString = 'hev1.';\n codecString += ['', 'A', 'B', 'C'][generalProfileSpace] + generalProfileIdc;\n codecString += '.';\n codecString += compatibilityFlags.toString(16).toUpperCase();\n codecString += '.';\n codecString += generalTierFlag === 0 ? 'L' : 'H';\n codecString += generalLevelIdc;\n while (constraintFlags.length > 0 && constraintFlags[constraintFlags.length - 1] === 0) {\n constraintFlags.pop();\n }\n if (constraintFlags.length > 0) {\n codecString += '.';\n codecString += constraintFlags.map(x => x.toString(16).toUpperCase()).join('.');\n }\n return codecString;\n }\n else if (codec === 'vp8') {\n return 'vp8'; // Easy, this one\n }\n else if (codec === 'vp9') {\n if (!vp9CodecInfo) {\n // Calculate level based on dimensions\n const pictureSize = trackInfo.width * trackInfo.height;\n let level = last(VP9_LEVEL_TABLE).level; // Default to highest level\n for (const entry of VP9_LEVEL_TABLE) {\n if (pictureSize <= entry.maxPictureSize) {\n level = entry.level;\n break;\n }\n }\n // We don't really know better, so let's return a general-purpose, common codec string and hope for the best\n return `vp09.00.${level.toString().padStart(2, '0')}.08`;\n }\n const profile = vp9CodecInfo.profile.toString().padStart(2, '0');\n const level = vp9CodecInfo.level.toString().padStart(2, '0');\n const bitDepth = vp9CodecInfo.bitDepth.toString().padStart(2, '0');\n const chromaSubsampling = vp9CodecInfo.chromaSubsampling.toString().padStart(2, '0');\n const colourPrimaries = vp9CodecInfo.colourPrimaries.toString().padStart(2, '0');\n const transferCharacteristics = vp9CodecInfo.transferCharacteristics.toString().padStart(2, '0');\n const matrixCoefficients = vp9CodecInfo.matrixCoefficients.toString().padStart(2, '0');\n const videoFullRangeFlag = vp9CodecInfo.videoFullRangeFlag.toString().padStart(2, '0');\n let string = `vp09.${profile}.${level}.${bitDepth}.${chromaSubsampling}`;\n string += `.${colourPrimaries}.${transferCharacteristics}.${matrixCoefficients}.${videoFullRangeFlag}`;\n if (string.endsWith(VP9_DEFAULT_SUFFIX)) {\n string = string.slice(0, -VP9_DEFAULT_SUFFIX.length);\n }\n return string;\n }\n else if (codec === 'av1') {\n if (!av1CodecInfo) {\n // Calculate level based on dimensions\n const pictureSize = trackInfo.width * trackInfo.height;\n let level = last(VP9_LEVEL_TABLE).level; // Default to highest level\n for (const entry of VP9_LEVEL_TABLE) {\n if (pictureSize <= entry.maxPictureSize) {\n level = entry.level;\n break;\n }\n }\n // We don't really know better, so let's return a general-purpose, common codec string and hope for the best\n return `av01.0.${level.toString().padStart(2, '0')}M.08`;\n }\n // https://aomediacodec.github.io/av1-isobmff/#codecsparam\n const profile = av1CodecInfo.profile; // Single digit\n const level = av1CodecInfo.level.toString().padStart(2, '0');\n const tier = av1CodecInfo.tier ? 'H' : 'M';\n const bitDepth = av1CodecInfo.bitDepth.toString().padStart(2, '0');\n const monochrome = av1CodecInfo.monochrome ? '1' : '0';\n const chromaSubsampling = 100 * av1CodecInfo.chromaSubsamplingX\n + 10 * av1CodecInfo.chromaSubsamplingY\n + 1 * (av1CodecInfo.chromaSubsamplingX && av1CodecInfo.chromaSubsamplingY\n ? av1CodecInfo.chromaSamplePosition\n : 0);\n // The defaults are 1 (ITU-R BT.709)\n const colorPrimaries = colorSpace?.primaries ? COLOR_PRIMARIES_MAP[colorSpace.primaries] : 1;\n const transferCharacteristics = colorSpace?.transfer ? TRANSFER_CHARACTERISTICS_MAP[colorSpace.transfer] : 1;\n const matrixCoefficients = colorSpace?.matrix ? MATRIX_COEFFICIENTS_MAP[colorSpace.matrix] : 1;\n const videoFullRangeFlag = colorSpace?.fullRange ? 1 : 0;\n let string = `av01.${profile}.${level}${tier}.${bitDepth}`;\n string += `.${monochrome}.${chromaSubsampling.toString().padStart(3, '0')}`;\n string += `.${colorPrimaries.toString().padStart(2, '0')}`;\n string += `.${transferCharacteristics.toString().padStart(2, '0')}`;\n string += `.${matrixCoefficients.toString().padStart(2, '0')}`;\n string += `.${videoFullRangeFlag}`;\n if (string.endsWith(AV1_DEFAULT_SUFFIX)) {\n string = string.slice(0, -AV1_DEFAULT_SUFFIX.length);\n }\n return string;\n }\n throw new TypeError(`Unhandled codec '${codec}'.`);\n};\nexport const buildAudioCodecString = (codec, numberOfChannels, sampleRate) => {\n if (codec === 'aac') {\n // If stereo or higher channels and lower sample rate, likely using HE-AAC v2 with PS\n if (numberOfChannels >= 2 && sampleRate <= 24000) {\n return 'mp4a.40.29'; // HE-AAC v2 (AAC LC + SBR + PS)\n }\n // If sample rate is low, likely using HE-AAC v1 with SBR\n if (sampleRate <= 24000) {\n return 'mp4a.40.5'; // HE-AAC v1 (AAC LC + SBR)\n }\n // Default to standard AAC-LC for higher sample rates\n return 'mp4a.40.2'; // AAC-LC\n }\n else if (codec === 'mp3') {\n return 'mp3';\n }\n else if (codec === 'opus') {\n return 'opus';\n }\n else if (codec === 'vorbis') {\n return 'vorbis';\n }\n else if (codec === 'flac') {\n return 'flac';\n }\n else if (PCM_AUDIO_CODECS.includes(codec)) {\n return codec;\n }\n throw new TypeError(`Unhandled codec '${codec}'.`);\n};\nexport const extractAudioCodecString = (trackInfo) => {\n const { codec, codecDescription, aacCodecInfo } = trackInfo;\n if (codec === 'aac') {\n if (!aacCodecInfo) {\n throw new TypeError('AAC codec info must be provided.');\n }\n if (aacCodecInfo.isMpeg2) {\n return 'mp4a.67';\n }\n else {\n const audioSpecificConfig = parseAacAudioSpecificConfig(codecDescription);\n return `mp4a.40.${audioSpecificConfig.objectType}`;\n }\n }\n else if (codec === 'mp3') {\n return 'mp3';\n }\n else if (codec === 'opus') {\n return 'opus';\n }\n else if (codec === 'vorbis') {\n return 'vorbis';\n }\n else if (codec === 'flac') {\n return 'flac';\n }\n else if (codec && PCM_AUDIO_CODECS.includes(codec)) {\n return codec;\n }\n throw new TypeError(`Unhandled codec '${codec}'.`);\n};\nexport const aacFrequencyTable = [\n 96000, 88200, 64000, 48000, 44100, 32000,\n 24000, 22050, 16000, 12000, 11025, 8000, 7350,\n];\nexport const aacChannelMap = [-1, 1, 2, 3, 4, 5, 6, 8];\nexport const parseAacAudioSpecificConfig = (bytes) => {\n if (!bytes || bytes.byteLength < 2) {\n throw new TypeError('AAC description must be at least 2 bytes long.');\n }\n const bitstream = new Bitstream(bytes);\n let objectType = bitstream.readBits(5);\n if (objectType === 31) {\n objectType = 32 + bitstream.readBits(6);\n }\n const frequencyIndex = bitstream.readBits(4);\n let sampleRate = null;\n if (frequencyIndex === 15) {\n sampleRate = bitstream.readBits(24);\n }\n else {\n if (frequencyIndex < aacFrequencyTable.length) {\n sampleRate = aacFrequencyTable[frequencyIndex];\n }\n }\n const channelConfiguration = bitstream.readBits(4);\n let numberOfChannels = null;\n if (channelConfiguration >= 1 && channelConfiguration <= 7) {\n numberOfChannels = aacChannelMap[channelConfiguration];\n }\n return {\n objectType,\n frequencyIndex,\n sampleRate,\n channelConfiguration,\n numberOfChannels,\n };\n};\nexport const buildAacAudioSpecificConfig = (config) => {\n let frequencyIndex = aacFrequencyTable.indexOf(config.sampleRate);\n let customSampleRate = null;\n if (frequencyIndex === -1) {\n frequencyIndex = 15;\n customSampleRate = config.sampleRate;\n }\n const channelConfiguration = aacChannelMap.indexOf(config.numberOfChannels);\n if (channelConfiguration === -1) {\n throw new TypeError(`Unsupported number of channels: ${config.numberOfChannels}`);\n }\n let bitCount = 5 + 4 + 4;\n if (config.objectType >= 32) {\n bitCount += 6;\n }\n if (frequencyIndex === 15) {\n bitCount += 24;\n }\n const byteCount = Math.ceil(bitCount / 8);\n const bytes = new Uint8Array(byteCount);\n const bitstream = new Bitstream(bytes);\n if (config.objectType < 32) {\n bitstream.writeBits(5, config.objectType);\n }\n else {\n bitstream.writeBits(5, 31);\n bitstream.writeBits(6, config.objectType - 32);\n }\n bitstream.writeBits(4, frequencyIndex);\n if (frequencyIndex === 15) {\n bitstream.writeBits(24, customSampleRate);\n }\n bitstream.writeBits(4, channelConfiguration);\n return bytes;\n};\nexport const OPUS_SAMPLE_RATE = 48_000;\nconst PCM_CODEC_REGEX = /^pcm-([usf])(\\d+)+(be)?$/;\nexport const parsePcmCodec = (codec) => {\n assert(PCM_AUDIO_CODECS.includes(codec));\n if (codec === 'ulaw') {\n return { dataType: 'ulaw', sampleSize: 1, littleEndian: true, silentValue: 255 };\n }\n else if (codec === 'alaw') {\n return { dataType: 'alaw', sampleSize: 1, littleEndian: true, silentValue: 213 };\n }\n const match = PCM_CODEC_REGEX.exec(codec);\n assert(match);\n let dataType;\n if (match[1] === 'u') {\n dataType = 'unsigned';\n }\n else if (match[1] === 's') {\n dataType = 'signed';\n }\n else {\n dataType = 'float';\n }\n const sampleSize = (Number(match[2]) / 8);\n const littleEndian = match[3] !== 'be';\n const silentValue = codec === 'pcm-u8' ? 2 ** 7 : 0;\n return { dataType, sampleSize, littleEndian, silentValue };\n};\nexport const inferCodecFromCodecString = (codecString) => {\n // Video codecs\n if (codecString.startsWith('avc1') || codecString.startsWith('avc3')) {\n return 'avc';\n }\n else if (codecString.startsWith('hev1') || codecString.startsWith('hvc1')) {\n return 'hevc';\n }\n else if (codecString === 'vp8') {\n return 'vp8';\n }\n else if (codecString.startsWith('vp09')) {\n return 'vp9';\n }\n else if (codecString.startsWith('av01')) {\n return 'av1';\n }\n // Audio codecs\n if (codecString.startsWith('mp4a.40') || codecString === 'mp4a.67') {\n return 'aac';\n }\n else if (codecString === 'mp3'\n || codecString === 'mp4a.69'\n || codecString === 'mp4a.6B'\n || codecString === 'mp4a.6b') {\n return 'mp3';\n }\n else if (codecString === 'opus') {\n return 'opus';\n }\n else if (codecString === 'vorbis') {\n return 'vorbis';\n }\n else if (codecString === 'flac') {\n return 'flac';\n }\n else if (codecString === 'ulaw') {\n return 'ulaw';\n }\n else if (codecString === 'alaw') {\n return 'alaw';\n }\n else if (PCM_CODEC_REGEX.test(codecString)) {\n return codecString;\n }\n // Subtitle codecs\n if (codecString === 'webvtt') {\n return 'webvtt';\n }\n return null;\n};\nexport const getVideoEncoderConfigExtension = (codec) => {\n if (codec === 'avc') {\n return {\n avc: {\n format: 'avc', // Ensure the format is not Annex B\n },\n };\n }\n else if (codec === 'hevc') {\n return {\n hevc: {\n format: 'hevc', // Ensure the format is not Annex B\n },\n };\n }\n return {};\n};\nexport const getAudioEncoderConfigExtension = (codec) => {\n if (codec === 'aac') {\n return {\n aac: {\n format: 'aac', // Ensure the format is not ADTS\n },\n };\n }\n else if (codec === 'opus') {\n return {\n opus: {\n format: 'opus',\n },\n };\n }\n return {};\n};\nconst VALID_VIDEO_CODEC_STRING_PREFIXES = ['avc1', 'avc3', 'hev1', 'hvc1', 'vp8', 'vp09', 'av01'];\nconst AVC_CODEC_STRING_REGEX = /^(avc1|avc3)\\.[0-9a-fA-F]{6}$/;\nconst HEVC_CODEC_STRING_REGEX = /^(hev1|hvc1)\\.(?:[ABC]?\\d+)\\.[0-9a-fA-F]{1,8}\\.[LH]\\d+(?:\\.[0-9a-fA-F]{1,2}){0,6}$/;\nconst VP9_CODEC_STRING_REGEX = /^vp09(?:\\.\\d{2}){3}(?:(?:\\.\\d{2}){5})?$/;\nconst AV1_CODEC_STRING_REGEX = /^av01\\.\\d\\.\\d{2}[MH]\\.\\d{2}(?:\\.\\d\\.\\d{3}\\.\\d{2}\\.\\d{2}\\.\\d{2}\\.\\d)?$/;\nexport const validateVideoChunkMetadata = (metadata) => {\n if (!metadata) {\n throw new TypeError('Video chunk metadata must be provided.');\n }\n if (typeof metadata !== 'object') {\n throw new TypeError('Video chunk metadata must be an object.');\n }\n if (!metadata.decoderConfig) {\n throw new TypeError('Video chunk metadata must include a decoder configuration.');\n }\n if (typeof metadata.decoderConfig !== 'object') {\n throw new TypeError('Video chunk metadata decoder configuration must be an object.');\n }\n if (typeof metadata.decoderConfig.codec !== 'string') {\n throw new TypeError('Video chunk metadata decoder configuration must specify a codec string.');\n }\n if (!VALID_VIDEO_CODEC_STRING_PREFIXES.some(prefix => metadata.decoderConfig.codec.startsWith(prefix))) {\n throw new TypeError('Video chunk metadata decoder configuration codec string must be a valid video codec string as specified in'\n + ' the WebCodecs Codec Registry.');\n }\n if (!Number.isInteger(metadata.decoderConfig.codedWidth) || metadata.decoderConfig.codedWidth <= 0) {\n throw new TypeError('Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer).');\n }\n if (!Number.isInteger(metadata.decoderConfig.codedHeight) || metadata.decoderConfig.codedHeight <= 0) {\n throw new TypeError('Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).');\n }\n if (metadata.decoderConfig.description !== undefined) {\n if (!isAllowSharedBufferSource(metadata.decoderConfig.description)) {\n throw new TypeError('Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an'\n + ' ArrayBuffer view.');\n }\n }\n if (metadata.decoderConfig.colorSpace !== undefined) {\n const { colorSpace } = metadata.decoderConfig;\n if (typeof colorSpace !== 'object') {\n throw new TypeError('Video chunk metadata decoder configuration colorSpace, when provided, must be an object.');\n }\n const primariesValues = Object.keys(COLOR_PRIMARIES_MAP);\n if (colorSpace.primaries != null && !primariesValues.includes(colorSpace.primaries)) {\n throw new TypeError(`Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of`\n + ` ${primariesValues.join(', ')}.`);\n }\n const transferValues = Object.keys(TRANSFER_CHARACTERISTICS_MAP);\n if (colorSpace.transfer != null && !transferValues.includes(colorSpace.transfer)) {\n throw new TypeError(`Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of`\n + ` ${transferValues.join(', ')}.`);\n }\n const matrixValues = Object.keys(MATRIX_COEFFICIENTS_MAP);\n if (colorSpace.matrix != null && !matrixValues.includes(colorSpace.matrix)) {\n throw new TypeError(`Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of`\n + ` ${matrixValues.join(', ')}.`);\n }\n if (colorSpace.fullRange != null && typeof colorSpace.fullRange !== 'boolean') {\n throw new TypeError('Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean.');\n }\n }\n if (metadata.decoderConfig.codec.startsWith('avc1') || metadata.decoderConfig.codec.startsWith('avc3')) {\n // AVC-specific validation\n if (!AVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {\n throw new TypeError('Video chunk metadata decoder configuration codec string for AVC must be a valid AVC codec string as'\n + ' specified in Section 3.4 of RFC 6381.');\n }\n // `description` may or may not be set, depending on if the format is AVCC or Annex B, so don't perform any\n // validation for it.\n // https://www.w3.org/TR/webcodecs-avc-codec-registration\n }\n else if (metadata.decoderConfig.codec.startsWith('hev1') || metadata.decoderConfig.codec.startsWith('hvc1')) {\n // HEVC-specific validation\n if (!HEVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {\n throw new TypeError('Video chunk metadata decoder configuration codec string for HEVC must be a valid HEVC codec string as'\n + ' specified in Section E.3 of ISO 14496-15.');\n }\n // `description` may or may not be set, depending on if the format is HEVC or Annex B, so don't perform any\n // validation for it.\n // https://www.w3.org/TR/webcodecs-hevc-codec-registration\n }\n else if (metadata.decoderConfig.codec.startsWith('vp8')) {\n // VP8-specific validation\n if (metadata.decoderConfig.codec !== 'vp8') {\n throw new TypeError('Video chunk metadata decoder configuration codec string for VP8 must be \"vp8\".');\n }\n }\n else if (metadata.decoderConfig.codec.startsWith('vp09')) {\n // VP9-specific validation\n if (!VP9_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {\n throw new TypeError('Video chunk metadata decoder configuration codec string for VP9 must be a valid VP9 codec string as'\n + ' specified in Section \"Codecs Parameter String\" of https://www.webmproject.org/vp9/mp4/.');\n }\n }\n else if (metadata.decoderConfig.codec.startsWith('av01')) {\n // AV1-specific validation\n if (!AV1_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {\n throw new TypeError('Video chunk metadata decoder configuration codec string for AV1 must be a valid AV1 codec string as'\n + ' specified in Section \"Codecs Parameter String\" of https://aomediacodec.github.io/av1-isobmff/.');\n }\n }\n};\nconst VALID_AUDIO_CODEC_STRING_PREFIXES = ['mp4a', 'mp3', 'opus', 'vorbis', 'flac', 'ulaw', 'alaw', 'pcm'];\nexport const validateAudioChunkMetadata = (metadata) => {\n if (!metadata) {\n throw new TypeError('Audio chunk metadata must be provided.');\n }\n if (typeof metadata !== 'object') {\n throw new TypeError('Audio chunk metadata must be an object.');\n }\n if (!metadata.decoderConfig) {\n throw new TypeError('Audio chunk metadata must include a decoder configuration.');\n }\n if (typeof metadata.decoderConfig !== 'object') {\n throw new TypeError('Audio chunk metadata decoder configuration must be an object.');\n }\n if (typeof metadata.decoderConfig.codec !== 'string') {\n throw new TypeError('Audio chunk metadata decoder configuration must specify a codec string.');\n }\n if (!VALID_AUDIO_CODEC_STRING_PREFIXES.some(prefix => metadata.decoderConfig.codec.startsWith(prefix))) {\n throw new TypeError('Audio chunk metadata decoder configuration codec string must be a valid audio codec string as specified in'\n + ' the WebCodecs Codec Registry.');\n }\n if (!Number.isInteger(metadata.decoderConfig.sampleRate) || metadata.decoderConfig.sampleRate <= 0) {\n throw new TypeError('Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer).');\n }\n if (!Number.isInteger(metadata.decoderConfig.numberOfChannels) || metadata.decoderConfig.numberOfChannels <= 0) {\n throw new TypeError('Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer).');\n }\n if (metadata.decoderConfig.description !== undefined) {\n if (!isAllowSharedBufferSource(metadata.decoderConfig.description)) {\n throw new TypeError('Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an'\n + ' ArrayBuffer view.');\n }\n }\n if (metadata.decoderConfig.codec.startsWith('mp4a')\n // These three refer to MP3:\n && metadata.decoderConfig.codec !== 'mp4a.69'\n && metadata.decoderConfig.codec !== 'mp4a.6B'\n && metadata.decoderConfig.codec !== 'mp4a.6b') {\n // AAC-specific validation\n const validStrings = ['mp4a.40.2', 'mp4a.40.02', 'mp4a.40.5', 'mp4a.40.05', 'mp4a.40.29', 'mp4a.67'];\n if (!validStrings.includes(metadata.decoderConfig.codec)) {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for AAC must be a valid AAC codec string as'\n + ' specified in https://www.w3.org/TR/webcodecs-aac-codec-registration/.');\n }\n if (!metadata.decoderConfig.description) {\n throw new TypeError('Audio chunk metadata decoder configuration for AAC must include a description, which is expected to be'\n + ' an AudioSpecificConfig as specified in ISO 14496-3.');\n }\n }\n else if (metadata.decoderConfig.codec.startsWith('mp3') || metadata.decoderConfig.codec.startsWith('mp4a')) {\n // MP3-specific validation\n if (metadata.decoderConfig.codec !== 'mp3'\n && metadata.decoderConfig.codec !== 'mp4a.69'\n && metadata.decoderConfig.codec !== 'mp4a.6B'\n && metadata.decoderConfig.codec !== 'mp4a.6b') {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for MP3 must be \"mp3\", \"mp4a.69\" or'\n + ' \"mp4a.6B\".');\n }\n }\n else if (metadata.decoderConfig.codec.startsWith('opus')) {\n // Opus-specific validation\n if (metadata.decoderConfig.codec !== 'opus') {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for Opus must be \"opus\".');\n }\n if (metadata.decoderConfig.description && metadata.decoderConfig.description.byteLength < 18) {\n // Description is optional for Opus per-spec, so we shouldn't enforce it\n throw new TypeError('Audio chunk metadata decoder configuration description, when specified, is expected to be an'\n + ' Identification Header as specified in Section 5.1 of RFC 7845.');\n }\n }\n else if (metadata.decoderConfig.codec.startsWith('vorbis')) {\n // Vorbis-specific validation\n if (metadata.decoderConfig.codec !== 'vorbis') {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for Vorbis must be \"vorbis\".');\n }\n if (!metadata.decoderConfig.description) {\n throw new TypeError('Audio chunk metadata decoder configuration for Vorbis must include a description, which is expected to'\n + ' adhere to the format described in https://www.w3.org/TR/webcodecs-vorbis-codec-registration/.');\n }\n }\n else if (metadata.decoderConfig.codec.startsWith('flac')) {\n // FLAC-specific validation\n if (metadata.decoderConfig.codec !== 'flac') {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for FLAC must be \"flac\".');\n }\n const minDescriptionSize = 4 + 4 + 34; // 'fLaC' + metadata block header + STREAMINFO block\n if (!metadata.decoderConfig.description || metadata.decoderConfig.description.byteLength < minDescriptionSize) {\n throw new TypeError('Audio chunk metadata decoder configuration for FLAC must include a description, which is expected to'\n + ' adhere to the format described in https://www.w3.org/TR/webcodecs-flac-codec-registration/.');\n }\n }\n else if (metadata.decoderConfig.codec.startsWith('pcm')\n || metadata.decoderConfig.codec.startsWith('ulaw')\n || metadata.decoderConfig.codec.startsWith('alaw')) {\n // PCM-specific validation\n if (!PCM_AUDIO_CODECS.includes(metadata.decoderConfig.codec)) {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for PCM must be one of the supported PCM'\n + ` codecs (${PCM_AUDIO_CODECS.join(', ')}).`);\n }\n }\n};\nexport const validateSubtitleMetadata = (metadata) => {\n if (!metadata) {\n throw new TypeError('Subtitle metadata must be provided.');\n }\n if (typeof metadata !== 'object') {\n throw new TypeError('Subtitle metadata must be an object.');\n }\n if (!metadata.config) {\n throw new TypeError('Subtitle metadata must include a config object.');\n }\n if (typeof metadata.config !== 'object') {\n throw new TypeError('Subtitle metadata config must be an object.');\n }\n if (typeof metadata.config.description !== 'string') {\n throw new TypeError('Subtitle metadata config description must be a string.');\n }\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { VP9_LEVEL_TABLE } from './codec.js';\nimport { assert, assertNever, base64ToBytes, Bitstream, bytesToBase64, keyValueIterator, getUint24, last, readExpGolomb, readSignedExpGolomb, textDecoder, textEncoder, toDataView, toUint8Array, getChromiumVersion, isChromium, setUint24, } from './misc.js';\n// References for AVC/HEVC code:\n// ISO 14496-15\n// Rec. ITU-T H.264\n// Rec. ITU-T H.265\n// https://stackoverflow.com/questions/24884827\nexport var AvcNalUnitType;\n(function (AvcNalUnitType) {\n AvcNalUnitType[AvcNalUnitType[\"IDR\"] = 5] = \"IDR\";\n AvcNalUnitType[AvcNalUnitType[\"SEI\"] = 6] = \"SEI\";\n AvcNalUnitType[AvcNalUnitType[\"SPS\"] = 7] = \"SPS\";\n AvcNalUnitType[AvcNalUnitType[\"PPS\"] = 8] = \"PPS\";\n AvcNalUnitType[AvcNalUnitType[\"SPS_EXT\"] = 13] = \"SPS_EXT\";\n})(AvcNalUnitType || (AvcNalUnitType = {}));\nexport var HevcNalUnitType;\n(function (HevcNalUnitType) {\n HevcNalUnitType[HevcNalUnitType[\"RASL_N\"] = 8] = \"RASL_N\";\n HevcNalUnitType[HevcNalUnitType[\"RASL_R\"] = 9] = \"RASL_R\";\n HevcNalUnitType[HevcNalUnitType[\"BLA_W_LP\"] = 16] = \"BLA_W_LP\";\n HevcNalUnitType[HevcNalUnitType[\"RSV_IRAP_VCL23\"] = 23] = \"RSV_IRAP_VCL23\";\n HevcNalUnitType[HevcNalUnitType[\"VPS_NUT\"] = 32] = \"VPS_NUT\";\n HevcNalUnitType[HevcNalUnitType[\"SPS_NUT\"] = 33] = \"SPS_NUT\";\n HevcNalUnitType[HevcNalUnitType[\"PPS_NUT\"] = 34] = \"PPS_NUT\";\n HevcNalUnitType[HevcNalUnitType[\"PREFIX_SEI_NUT\"] = 39] = \"PREFIX_SEI_NUT\";\n HevcNalUnitType[HevcNalUnitType[\"SUFFIX_SEI_NUT\"] = 40] = \"SUFFIX_SEI_NUT\";\n})(HevcNalUnitType || (HevcNalUnitType = {}));\n/** Finds all NAL units in an AVC packet in Annex B format. */\nexport const findNalUnitsInAnnexB = (packetData) => {\n const nalUnits = [];\n let i = 0;\n while (i < packetData.length) {\n let startCodePos = -1;\n let startCodeLength = 0;\n for (let j = i; j < packetData.length - 3; j++) {\n // Check for 3-byte start code (0x000001)\n if (packetData[j] === 0 && packetData[j + 1] === 0 && packetData[j + 2] === 1) {\n startCodePos = j;\n startCodeLength = 3;\n break;\n }\n // Check for 4-byte start code (0x00000001)\n if (j < packetData.length - 4\n && packetData[j] === 0\n && packetData[j + 1] === 0\n && packetData[j + 2] === 0\n && packetData[j + 3] === 1) {\n startCodePos = j;\n startCodeLength = 4;\n break;\n }\n }\n if (startCodePos === -1) {\n break; // No more start codes found\n }\n // If this isn't the first start code, extract the previous NAL unit\n if (i > 0 && startCodePos > i) {\n const nalData = packetData.subarray(i, startCodePos);\n if (nalData.length > 0) {\n nalUnits.push(nalData);\n }\n }\n i = startCodePos + startCodeLength;\n }\n // Extract the last NAL unit if there is one\n if (i < packetData.length) {\n const nalData = packetData.subarray(i);\n if (nalData.length > 0) {\n nalUnits.push(nalData);\n }\n }\n return nalUnits;\n};\n/** Finds all NAL units in an AVC packet in length-prefixed format. */\nconst findNalUnitsInLengthPrefixed = (packetData, lengthSize) => {\n const nalUnits = [];\n let offset = 0;\n const dataView = new DataView(packetData.buffer, packetData.byteOffset, packetData.byteLength);\n while (offset + lengthSize <= packetData.length) {\n let nalUnitLength;\n if (lengthSize === 1) {\n nalUnitLength = dataView.getUint8(offset);\n }\n else if (lengthSize === 2) {\n nalUnitLength = dataView.getUint16(offset, false);\n }\n else if (lengthSize === 3) {\n nalUnitLength = getUint24(dataView, offset, false);\n }\n else if (lengthSize === 4) {\n nalUnitLength = dataView.getUint32(offset, false);\n }\n else {\n assertNever(lengthSize);\n assert(false);\n }\n offset += lengthSize;\n const nalUnit = packetData.subarray(offset, offset + nalUnitLength);\n nalUnits.push(nalUnit);\n offset += nalUnitLength;\n }\n return nalUnits;\n};\nconst removeEmulationPreventionBytes = (data) => {\n const result = [];\n const len = data.length;\n for (let i = 0; i < len; i++) {\n // Look for the 0x000003 pattern\n if (i + 2 < len && data[i] === 0x00 && data[i + 1] === 0x00 && data[i + 2] === 0x03) {\n result.push(0x00, 0x00); // Push the first two bytes\n i += 2; // Skip the 0x03 byte\n }\n else {\n result.push(data[i]);\n }\n }\n return new Uint8Array(result);\n};\nconst ANNEX_B_START_CODE = new Uint8Array([0, 0, 0, 1]);\nexport const concatNalUnitsInAnnexB = (nalUnits) => {\n const totalLength = nalUnits.reduce((a, b) => a + ANNEX_B_START_CODE.byteLength + b.byteLength, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const nalUnit of nalUnits) {\n result.set(ANNEX_B_START_CODE, offset);\n offset += ANNEX_B_START_CODE.byteLength;\n result.set(nalUnit, offset);\n offset += nalUnit.byteLength;\n }\n return result;\n};\nexport const concatNalUnitsInLengthPrefixed = (nalUnits, lengthSize) => {\n const totalLength = nalUnits.reduce((a, b) => a + lengthSize + b.byteLength, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const nalUnit of nalUnits) {\n const dataView = new DataView(result.buffer, result.byteOffset, result.byteLength);\n switch (lengthSize) {\n case 1:\n dataView.setUint8(offset, nalUnit.byteLength);\n break;\n case 2:\n dataView.setUint16(offset, nalUnit.byteLength, false);\n break;\n case 3:\n setUint24(dataView, offset, nalUnit.byteLength, false);\n break;\n case 4:\n dataView.setUint32(offset, nalUnit.byteLength, false);\n break;\n }\n offset += lengthSize;\n result.set(nalUnit, offset);\n offset += nalUnit.byteLength;\n }\n return result;\n};\nexport const extractAvcNalUnits = (packetData, decoderConfig) => {\n if (decoderConfig.description) {\n // Stream is length-prefixed. Let's extract the size of the length prefix from the decoder config\n const bytes = toUint8Array(decoderConfig.description);\n const lengthSizeMinusOne = bytes[4] & 0b11;\n const lengthSize = (lengthSizeMinusOne + 1);\n return findNalUnitsInLengthPrefixed(packetData, lengthSize);\n }\n else {\n // Stream is in Annex B format\n return findNalUnitsInAnnexB(packetData);\n }\n};\nexport const concatAvcNalUnits = (nalUnits, decoderConfig) => {\n if (decoderConfig.description) {\n // Stream is length-prefixed. Let's extract the size of the length prefix from the decoder config\n const bytes = toUint8Array(decoderConfig.description);\n const lengthSizeMinusOne = bytes[4] & 0b11;\n const lengthSize = (lengthSizeMinusOne + 1);\n return concatNalUnitsInLengthPrefixed(nalUnits, lengthSize);\n }\n else {\n // Stream is in Annex B format\n return concatNalUnitsInAnnexB(nalUnits);\n }\n};\nexport const extractNalUnitTypeForAvc = (data) => {\n return data[0] & 0x1F;\n};\n/** Builds an AvcDecoderConfigurationRecord from an AVC packet in Annex B format. */\nexport const extractAvcDecoderConfigurationRecord = (packetData) => {\n try {\n const nalUnits = findNalUnitsInAnnexB(packetData);\n const spsUnits = nalUnits.filter(unit => extractNalUnitTypeForAvc(unit) === AvcNalUnitType.SPS);\n const ppsUnits = nalUnits.filter(unit => extractNalUnitTypeForAvc(unit) === AvcNalUnitType.PPS);\n const spsExtUnits = nalUnits.filter(unit => extractNalUnitTypeForAvc(unit) === AvcNalUnitType.SPS_EXT);\n if (spsUnits.length === 0) {\n return null;\n }\n if (ppsUnits.length === 0) {\n return null;\n }\n // Let's get the first SPS for profile and level information\n const spsData = spsUnits[0];\n const spsInfo = parseAvcSps(spsData);\n assert(spsInfo !== null);\n const hasExtendedData = spsInfo.profileIdc === 100\n || spsInfo.profileIdc === 110\n || spsInfo.profileIdc === 122\n || spsInfo.profileIdc === 144;\n return {\n configurationVersion: 1,\n avcProfileIndication: spsInfo.profileIdc,\n profileCompatibility: spsInfo.constraintFlags,\n avcLevelIndication: spsInfo.levelIdc,\n lengthSizeMinusOne: 3, // Typically 4 bytes for length field\n sequenceParameterSets: spsUnits,\n pictureParameterSets: ppsUnits,\n chromaFormat: hasExtendedData ? spsInfo.chromaFormatIdc : null,\n bitDepthLumaMinus8: hasExtendedData ? spsInfo.bitDepthLumaMinus8 : null,\n bitDepthChromaMinus8: hasExtendedData ? spsInfo.bitDepthChromaMinus8 : null,\n sequenceParameterSetExt: hasExtendedData ? spsExtUnits : null,\n };\n }\n catch (error) {\n console.error('Error building AVC Decoder Configuration Record:', error);\n return null;\n }\n};\n/** Serializes an AvcDecoderConfigurationRecord into the format specified in Section 5.3.3.1 of ISO 14496-15. */\nexport const serializeAvcDecoderConfigurationRecord = (record) => {\n const bytes = [];\n // Write header\n bytes.push(record.configurationVersion);\n bytes.push(record.avcProfileIndication);\n bytes.push(record.profileCompatibility);\n bytes.push(record.avcLevelIndication);\n bytes.push(0xFC | (record.lengthSizeMinusOne & 0x03)); // Reserved bits (6) + lengthSizeMinusOne (2)\n // Reserved bits (3) + numOfSequenceParameterSets (5)\n bytes.push(0xE0 | (record.sequenceParameterSets.length & 0x1F));\n // Write SPS\n for (const sps of record.sequenceParameterSets) {\n const length = sps.byteLength;\n bytes.push(length >> 8); // High byte\n bytes.push(length & 0xFF); // Low byte\n for (let i = 0; i < length; i++) {\n bytes.push(sps[i]);\n }\n }\n bytes.push(record.pictureParameterSets.length);\n // Write PPS\n for (const pps of record.pictureParameterSets) {\n const length = pps.byteLength;\n bytes.push(length >> 8); // High byte\n bytes.push(length & 0xFF); // Low byte\n for (let i = 0; i < length; i++) {\n bytes.push(pps[i]);\n }\n }\n if (record.avcProfileIndication === 100\n || record.avcProfileIndication === 110\n || record.avcProfileIndication === 122\n || record.avcProfileIndication === 144) {\n assert(record.chromaFormat !== null);\n assert(record.bitDepthLumaMinus8 !== null);\n assert(record.bitDepthChromaMinus8 !== null);\n assert(record.sequenceParameterSetExt !== null);\n bytes.push(0xFC | (record.chromaFormat & 0x03)); // Reserved bits + chroma_format\n bytes.push(0xF8 | (record.bitDepthLumaMinus8 & 0x07)); // Reserved bits + bit_depth_luma_minus8\n bytes.push(0xF8 | (record.bitDepthChromaMinus8 & 0x07)); // Reserved bits + bit_depth_chroma_minus8\n bytes.push(record.sequenceParameterSetExt.length);\n // Write SPS Ext\n for (const spsExt of record.sequenceParameterSetExt) {\n const length = spsExt.byteLength;\n bytes.push(length >> 8); // High byte\n bytes.push(length & 0xFF); // Low byte\n for (let i = 0; i < length; i++) {\n bytes.push(spsExt[i]);\n }\n }\n }\n return new Uint8Array(bytes);\n};\n/** Deserializes an AvcDecoderConfigurationRecord from the format specified in Section 5.3.3.1 of ISO 14496-15. */\nexport const deserializeAvcDecoderConfigurationRecord = (data) => {\n try {\n const view = toDataView(data);\n let offset = 0;\n // Read header\n const configurationVersion = view.getUint8(offset++);\n const avcProfileIndication = view.getUint8(offset++);\n const profileCompatibility = view.getUint8(offset++);\n const avcLevelIndication = view.getUint8(offset++);\n const lengthSizeMinusOne = view.getUint8(offset++) & 0x03;\n const numOfSequenceParameterSets = view.getUint8(offset++) & 0x1F;\n // Read SPS\n const sequenceParameterSets = [];\n for (let i = 0; i < numOfSequenceParameterSets; i++) {\n const length = view.getUint16(offset, false);\n offset += 2;\n sequenceParameterSets.push(data.subarray(offset, offset + length));\n offset += length;\n }\n const numOfPictureParameterSets = view.getUint8(offset++);\n // Read PPS\n const pictureParameterSets = [];\n for (let i = 0; i < numOfPictureParameterSets; i++) {\n const length = view.getUint16(offset, false);\n offset += 2;\n pictureParameterSets.push(data.subarray(offset, offset + length));\n offset += length;\n }\n const record = {\n configurationVersion,\n avcProfileIndication,\n profileCompatibility,\n avcLevelIndication,\n lengthSizeMinusOne,\n sequenceParameterSets,\n pictureParameterSets,\n chromaFormat: null,\n bitDepthLumaMinus8: null,\n bitDepthChromaMinus8: null,\n sequenceParameterSetExt: null,\n };\n // Check if there are extended profile fields\n if ((avcProfileIndication === 100\n || avcProfileIndication === 110\n || avcProfileIndication === 122\n || avcProfileIndication === 144)\n && offset + 4 <= data.length) {\n const chromaFormat = view.getUint8(offset++) & 0x03;\n const bitDepthLumaMinus8 = view.getUint8(offset++) & 0x07;\n const bitDepthChromaMinus8 = view.getUint8(offset++) & 0x07;\n const numOfSequenceParameterSetExt = view.getUint8(offset++);\n record.chromaFormat = chromaFormat;\n record.bitDepthLumaMinus8 = bitDepthLumaMinus8;\n record.bitDepthChromaMinus8 = bitDepthChromaMinus8;\n // Read SPS Ext\n const sequenceParameterSetExt = [];\n for (let i = 0; i < numOfSequenceParameterSetExt; i++) {\n const length = view.getUint16(offset, false);\n offset += 2;\n sequenceParameterSetExt.push(data.subarray(offset, offset + length));\n offset += length;\n }\n record.sequenceParameterSetExt = sequenceParameterSetExt;\n }\n return record;\n }\n catch (error) {\n console.error('Error deserializing AVC Decoder Configuration Record:', error);\n return null;\n }\n};\n/** Parses an AVC SPS (Sequence Parameter Set) to extract basic information. */\nexport const parseAvcSps = (sps) => {\n try {\n const bitstream = new Bitstream(removeEmulationPreventionBytes(sps));\n bitstream.skipBits(1); // forbidden_zero_bit\n bitstream.skipBits(2); // nal_ref_idc\n const nalUnitType = bitstream.readBits(5);\n if (nalUnitType !== 7) { // SPS NAL unit type is 7\n return null;\n }\n const profileIdc = bitstream.readAlignedByte();\n const constraintFlags = bitstream.readAlignedByte();\n const levelIdc = bitstream.readAlignedByte();\n readExpGolomb(bitstream); // seq_parameter_set_id\n let chromaFormatIdc = null;\n let bitDepthLumaMinus8 = null;\n let bitDepthChromaMinus8 = null;\n // Handle high profile chroma_format_idc\n if (profileIdc === 100\n || profileIdc === 110\n || profileIdc === 122\n || profileIdc === 244\n || profileIdc === 44\n || profileIdc === 83\n || profileIdc === 86\n || profileIdc === 118\n || profileIdc === 128) {\n chromaFormatIdc = readExpGolomb(bitstream);\n if (chromaFormatIdc === 3) {\n bitstream.skipBits(1); // separate_colour_plane_flag\n }\n bitDepthLumaMinus8 = readExpGolomb(bitstream);\n bitDepthChromaMinus8 = readExpGolomb(bitstream);\n bitstream.skipBits(1); // qpprime_y_zero_transform_bypass_flag\n const seqScalingMatrixPresentFlag = bitstream.readBits(1);\n if (seqScalingMatrixPresentFlag) {\n for (let i = 0; i < (chromaFormatIdc !== 3 ? 8 : 12); i++) {\n const seqScalingListPresentFlag = bitstream.readBits(1);\n if (seqScalingListPresentFlag) {\n const sizeOfScalingList = i < 6 ? 16 : 64;\n let lastScale = 8;\n let nextScale = 8;\n for (let j = 0; j < sizeOfScalingList; j++) {\n if (nextScale !== 0) {\n const deltaScale = readSignedExpGolomb(bitstream);\n nextScale = (lastScale + deltaScale + 256) % 256;\n }\n lastScale = nextScale === 0 ? lastScale : nextScale;\n }\n }\n }\n }\n }\n readExpGolomb(bitstream); // log2_max_frame_num_minus4\n const picOrderCntType = readExpGolomb(bitstream);\n if (picOrderCntType === 0) {\n readExpGolomb(bitstream); // log2_max_pic_order_cnt_lsb_minus4\n }\n else if (picOrderCntType === 1) {\n bitstream.skipBits(1); // delta_pic_order_always_zero_flag\n readSignedExpGolomb(bitstream); // offset_for_non_ref_pic\n readSignedExpGolomb(bitstream); // offset_for_top_to_bottom_field\n const numRefFramesInPicOrderCntCycle = readExpGolomb(bitstream);\n for (let i = 0; i < numRefFramesInPicOrderCntCycle; i++) {\n readSignedExpGolomb(bitstream); // offset_for_ref_frame[i]\n }\n }\n readExpGolomb(bitstream); // max_num_ref_frames\n bitstream.skipBits(1); // gaps_in_frame_num_value_allowed_flag\n readExpGolomb(bitstream); // pic_width_in_mbs_minus1\n readExpGolomb(bitstream); // pic_height_in_map_units_minus1\n const frameMbsOnlyFlag = bitstream.readBits(1);\n return {\n profileIdc,\n constraintFlags,\n levelIdc,\n frameMbsOnlyFlag,\n chromaFormatIdc,\n bitDepthLumaMinus8,\n bitDepthChromaMinus8,\n };\n }\n catch (error) {\n console.error('Error parsing AVC SPS:', error);\n return null;\n }\n};\nexport const extractHevcNalUnits = (packetData, decoderConfig) => {\n if (decoderConfig.description) {\n // Stream is length-prefixed. Let's extract the size of the length prefix from the decoder config\n const bytes = toUint8Array(decoderConfig.description);\n const lengthSizeMinusOne = bytes[21] & 0b11;\n const lengthSize = (lengthSizeMinusOne + 1);\n return findNalUnitsInLengthPrefixed(packetData, lengthSize);\n }\n else {\n // Stream is in Annex B format\n return findNalUnitsInAnnexB(packetData);\n }\n};\nexport const extractNalUnitTypeForHevc = (data) => {\n return (data[0] >> 1) & 0x3F;\n};\n/** Builds a HevcDecoderConfigurationRecord from an HEVC packet in Annex B format. */\nexport const extractHevcDecoderConfigurationRecord = (packetData) => {\n try {\n const nalUnits = findNalUnitsInAnnexB(packetData);\n const vpsUnits = nalUnits.filter(unit => extractNalUnitTypeForHevc(unit) === HevcNalUnitType.VPS_NUT);\n const spsUnits = nalUnits.filter(unit => extractNalUnitTypeForHevc(unit) === HevcNalUnitType.SPS_NUT);\n const ppsUnits = nalUnits.filter(unit => extractNalUnitTypeForHevc(unit) === HevcNalUnitType.PPS_NUT);\n const seiUnits = nalUnits.filter(unit => extractNalUnitTypeForHevc(unit) === HevcNalUnitType.PREFIX_SEI_NUT\n || extractNalUnitTypeForHevc(unit) === HevcNalUnitType.SUFFIX_SEI_NUT);\n if (spsUnits.length === 0 || ppsUnits.length === 0)\n return null;\n const sps = spsUnits[0];\n const bitstream = new Bitstream(removeEmulationPreventionBytes(sps));\n bitstream.skipBits(16); // NAL header\n bitstream.readBits(4); // sps_video_parameter_set_id\n const sps_max_sub_layers_minus1 = bitstream.readBits(3);\n const sps_temporal_id_nesting_flag = bitstream.readBits(1);\n const { general_profile_space, general_tier_flag, general_profile_idc, general_profile_compatibility_flags, general_constraint_indicator_flags, general_level_idc, } = parseProfileTierLevel(bitstream, sps_max_sub_layers_minus1);\n readExpGolomb(bitstream); // sps_seq_parameter_set_id\n const chroma_format_idc = readExpGolomb(bitstream);\n if (chroma_format_idc === 3)\n bitstream.skipBits(1); // separate_colour_plane_flag\n readExpGolomb(bitstream); // pic_width_in_luma_samples\n readExpGolomb(bitstream); // pic_height_in_luma_samples\n if (bitstream.readBits(1)) { // conformance_window_flag\n readExpGolomb(bitstream); // conf_win_left_offset\n readExpGolomb(bitstream); // conf_win_right_offset\n readExpGolomb(bitstream); // conf_win_top_offset\n readExpGolomb(bitstream); // conf_win_bottom_offset\n }\n const bit_depth_luma_minus8 = readExpGolomb(bitstream);\n const bit_depth_chroma_minus8 = readExpGolomb(bitstream);\n readExpGolomb(bitstream); // log2_max_pic_order_cnt_lsb_minus4\n const sps_sub_layer_ordering_info_present_flag = bitstream.readBits(1);\n const maxNum = sps_sub_layer_ordering_info_present_flag ? 0 : sps_max_sub_layers_minus1;\n for (let i = maxNum; i <= sps_max_sub_layers_minus1; i++) {\n readExpGolomb(bitstream); // sps_max_dec_pic_buffering_minus1[i]\n readExpGolomb(bitstream); // sps_max_num_reorder_pics[i]\n readExpGolomb(bitstream); // sps_max_latency_increase_plus1[i]\n }\n readExpGolomb(bitstream); // log2_min_luma_coding_block_size_minus3\n readExpGolomb(bitstream); // log2_diff_max_min_luma_coding_block_size\n readExpGolomb(bitstream); // log2_min_luma_transform_block_size_minus2\n readExpGolomb(bitstream); // log2_diff_max_min_luma_transform_block_size\n readExpGolomb(bitstream); // max_transform_hierarchy_depth_inter\n readExpGolomb(bitstream); // max_transform_hierarchy_depth_intra\n if (bitstream.readBits(1)) { // scaling_list_enabled_flag\n if (bitstream.readBits(1)) {\n skipScalingListData(bitstream);\n }\n }\n bitstream.skipBits(1); // amp_enabled_flag\n bitstream.skipBits(1); // sample_adaptive_offset_enabled_flag\n if (bitstream.readBits(1)) { // pcm_enabled_flag\n bitstream.skipBits(4); // pcm_sample_bit_depth_luma_minus1\n bitstream.skipBits(4); // pcm_sample_bit_depth_chroma_minus1\n readExpGolomb(bitstream); // log2_min_pcm_luma_coding_block_size_minus3\n readExpGolomb(bitstream); // log2_diff_max_min_pcm_luma_coding_block_size\n bitstream.skipBits(1); // pcm_loop_filter_disabled_flag\n }\n const num_short_term_ref_pic_sets = readExpGolomb(bitstream);\n skipAllStRefPicSets(bitstream, num_short_term_ref_pic_sets);\n if (bitstream.readBits(1)) { // long_term_ref_pics_present_flag\n const num_long_term_ref_pics_sps = readExpGolomb(bitstream);\n for (let i = 0; i < num_long_term_ref_pics_sps; i++) {\n readExpGolomb(bitstream); // lt_ref_pic_poc_lsb_sps[i]\n bitstream.skipBits(1); // used_by_curr_pic_lt_sps_flag[i]\n }\n }\n bitstream.skipBits(1); // sps_temporal_mvp_enabled_flag\n bitstream.skipBits(1); // strong_intra_smoothing_enabled_flag\n let min_spatial_segmentation_idc = 0;\n if (bitstream.readBits(1)) { // vui_parameters_present_flag\n min_spatial_segmentation_idc = parseVuiForMinSpatialSegmentationIdc(bitstream, sps_max_sub_layers_minus1);\n }\n // Parse PPS for parallelismType\n let parallelismType = 0;\n if (ppsUnits.length > 0) {\n const pps = ppsUnits[0];\n const ppsBitstream = new Bitstream(removeEmulationPreventionBytes(pps));\n ppsBitstream.skipBits(16); // NAL header\n readExpGolomb(ppsBitstream); // pps_pic_parameter_set_id\n readExpGolomb(ppsBitstream); // pps_seq_parameter_set_id\n ppsBitstream.skipBits(1); // dependent_slice_segments_enabled_flag\n ppsBitstream.skipBits(1); // output_flag_present_flag\n ppsBitstream.skipBits(3); // num_extra_slice_header_bits\n ppsBitstream.skipBits(1); // sign_data_hiding_enabled_flag\n ppsBitstream.skipBits(1); // cabac_init_present_flag\n readExpGolomb(ppsBitstream); // num_ref_idx_l0_default_active_minus1\n readExpGolomb(ppsBitstream); // num_ref_idx_l1_default_active_minus1\n readSignedExpGolomb(ppsBitstream); // init_qp_minus26\n ppsBitstream.skipBits(1); // constrained_intra_pred_flag\n ppsBitstream.skipBits(1); // transform_skip_enabled_flag\n if (ppsBitstream.readBits(1)) { // cu_qp_delta_enabled_flag\n readExpGolomb(ppsBitstream); // diff_cu_qp_delta_depth\n }\n readSignedExpGolomb(ppsBitstream); // pps_cb_qp_offset\n readSignedExpGolomb(ppsBitstream); // pps_cr_qp_offset\n ppsBitstream.skipBits(1); // pps_slice_chroma_qp_offsets_present_flag\n ppsBitstream.skipBits(1); // weighted_pred_flag\n ppsBitstream.skipBits(1); // weighted_bipred_flag\n ppsBitstream.skipBits(1); // transquant_bypass_enabled_flag\n const tiles_enabled_flag = ppsBitstream.readBits(1);\n const entropy_coding_sync_enabled_flag = ppsBitstream.readBits(1);\n if (!tiles_enabled_flag && !entropy_coding_sync_enabled_flag)\n parallelismType = 0;\n else if (tiles_enabled_flag && !entropy_coding_sync_enabled_flag)\n parallelismType = 2;\n else if (!tiles_enabled_flag && entropy_coding_sync_enabled_flag)\n parallelismType = 3;\n else\n parallelismType = 0;\n }\n const arrays = [\n ...(vpsUnits.length\n ? [\n {\n arrayCompleteness: 1,\n nalUnitType: HevcNalUnitType.VPS_NUT,\n nalUnits: vpsUnits,\n },\n ]\n : []),\n ...(spsUnits.length\n ? [\n {\n arrayCompleteness: 1,\n nalUnitType: HevcNalUnitType.SPS_NUT,\n nalUnits: spsUnits,\n },\n ]\n : []),\n ...(ppsUnits.length\n ? [\n {\n arrayCompleteness: 1,\n nalUnitType: HevcNalUnitType.PPS_NUT,\n nalUnits: ppsUnits,\n },\n ]\n : []),\n ...(seiUnits.length\n ? [\n {\n arrayCompleteness: 1,\n nalUnitType: extractNalUnitTypeForHevc(seiUnits[0]),\n nalUnits: seiUnits,\n },\n ]\n : []),\n ];\n const record = {\n configurationVersion: 1,\n generalProfileSpace: general_profile_space,\n generalTierFlag: general_tier_flag,\n generalProfileIdc: general_profile_idc,\n generalProfileCompatibilityFlags: general_profile_compatibility_flags,\n generalConstraintIndicatorFlags: general_constraint_indicator_flags,\n generalLevelIdc: general_level_idc,\n minSpatialSegmentationIdc: min_spatial_segmentation_idc,\n parallelismType,\n chromaFormatIdc: chroma_format_idc,\n bitDepthLumaMinus8: bit_depth_luma_minus8,\n bitDepthChromaMinus8: bit_depth_chroma_minus8,\n avgFrameRate: 0,\n constantFrameRate: 0,\n numTemporalLayers: sps_max_sub_layers_minus1 + 1,\n temporalIdNested: sps_temporal_id_nesting_flag,\n lengthSizeMinusOne: 3,\n arrays,\n };\n return record;\n }\n catch (error) {\n console.error('Error building HEVC Decoder Configuration Record:', error);\n return null;\n }\n};\nconst parseProfileTierLevel = (bitstream, maxNumSubLayersMinus1) => {\n const general_profile_space = bitstream.readBits(2);\n const general_tier_flag = bitstream.readBits(1);\n const general_profile_idc = bitstream.readBits(5);\n let general_profile_compatibility_flags = 0;\n for (let i = 0; i < 32; i++) {\n general_profile_compatibility_flags = (general_profile_compatibility_flags << 1) | bitstream.readBits(1);\n }\n const general_constraint_indicator_flags = new Uint8Array(6);\n for (let i = 0; i < 6; i++) {\n general_constraint_indicator_flags[i] = bitstream.readBits(8);\n }\n const general_level_idc = bitstream.readBits(8);\n const sub_layer_profile_present_flag = [];\n const sub_layer_level_present_flag = [];\n for (let i = 0; i < maxNumSubLayersMinus1; i++) {\n sub_layer_profile_present_flag.push(bitstream.readBits(1));\n sub_layer_level_present_flag.push(bitstream.readBits(1));\n }\n if (maxNumSubLayersMinus1 > 0) {\n for (let i = maxNumSubLayersMinus1; i < 8; i++) {\n bitstream.skipBits(2); // reserved_zero_2bits\n }\n }\n for (let i = 0; i < maxNumSubLayersMinus1; i++) {\n if (sub_layer_profile_present_flag[i])\n bitstream.skipBits(88);\n if (sub_layer_level_present_flag[i])\n bitstream.skipBits(8);\n }\n return {\n general_profile_space,\n general_tier_flag,\n general_profile_idc,\n general_profile_compatibility_flags,\n general_constraint_indicator_flags,\n general_level_idc,\n };\n};\nconst skipScalingListData = (bitstream) => {\n for (let sizeId = 0; sizeId < 4; sizeId++) {\n for (let matrixId = 0; matrixId < (sizeId === 3 ? 2 : 6); matrixId++) {\n const scaling_list_pred_mode_flag = bitstream.readBits(1);\n if (!scaling_list_pred_mode_flag) {\n readExpGolomb(bitstream); // scaling_list_pred_matrix_id_delta\n }\n else {\n const coefNum = Math.min(64, 1 << (4 + (sizeId << 1)));\n if (sizeId > 1) {\n readSignedExpGolomb(bitstream); // scaling_list_dc_coef_minus8\n }\n for (let i = 0; i < coefNum; i++) {\n readSignedExpGolomb(bitstream); // scaling_list_delta_coef\n }\n }\n }\n }\n};\nconst skipAllStRefPicSets = (bitstream, num_short_term_ref_pic_sets) => {\n const NumDeltaPocs = [];\n for (let stRpsIdx = 0; stRpsIdx < num_short_term_ref_pic_sets; stRpsIdx++) {\n NumDeltaPocs[stRpsIdx] = skipStRefPicSet(bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs);\n }\n};\nconst skipStRefPicSet = (bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs) => {\n let NumDeltaPocsThis = 0;\n let inter_ref_pic_set_prediction_flag = 0;\n let RefRpsIdx = 0;\n if (stRpsIdx !== 0) {\n inter_ref_pic_set_prediction_flag = bitstream.readBits(1);\n }\n if (inter_ref_pic_set_prediction_flag) {\n if (stRpsIdx === num_short_term_ref_pic_sets) {\n const delta_idx_minus1 = readExpGolomb(bitstream);\n RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);\n }\n else {\n RefRpsIdx = stRpsIdx - 1;\n }\n bitstream.readBits(1); // delta_rps_sign\n readExpGolomb(bitstream); // abs_delta_rps_minus1\n // The number of iterations is NumDeltaPocs[RefRpsIdx] + 1\n const numDelta = NumDeltaPocs[RefRpsIdx] ?? 0;\n for (let j = 0; j <= numDelta; j++) {\n const used_by_curr_pic_flag = bitstream.readBits(1);\n if (!used_by_curr_pic_flag) {\n bitstream.readBits(1); // use_delta_flag\n }\n }\n NumDeltaPocsThis = NumDeltaPocs[RefRpsIdx];\n }\n else {\n const num_negative_pics = readExpGolomb(bitstream);\n const num_positive_pics = readExpGolomb(bitstream);\n for (let i = 0; i < num_negative_pics; i++) {\n readExpGolomb(bitstream); // delta_poc_s0_minus1[i]\n bitstream.readBits(1); // used_by_curr_pic_s0_flag[i]\n }\n for (let i = 0; i < num_positive_pics; i++) {\n readExpGolomb(bitstream); // delta_poc_s1_minus1[i]\n bitstream.readBits(1); // used_by_curr_pic_s1_flag[i]\n }\n NumDeltaPocsThis = num_negative_pics + num_positive_pics;\n }\n return NumDeltaPocsThis;\n};\nconst parseVuiForMinSpatialSegmentationIdc = (bitstream, sps_max_sub_layers_minus1) => {\n if (bitstream.readBits(1)) { // aspect_ratio_info_present_flag\n const aspect_ratio_idc = bitstream.readBits(8);\n if (aspect_ratio_idc === 255) {\n bitstream.readBits(16); // sar_width\n bitstream.readBits(16); // sar_height\n }\n }\n if (bitstream.readBits(1)) { // overscan_info_present_flag\n bitstream.readBits(1); // overscan_appropriate_flag\n }\n if (bitstream.readBits(1)) { // video_signal_type_present_flag\n bitstream.readBits(3); // video_format\n bitstream.readBits(1); // video_full_range_flag\n if (bitstream.readBits(1)) {\n bitstream.readBits(8); // colour_primaries\n bitstream.readBits(8); // transfer_characteristics\n bitstream.readBits(8); // matrix_coeffs\n }\n }\n if (bitstream.readBits(1)) { // chroma_loc_info_present_flag\n readExpGolomb(bitstream); // chroma_sample_loc_type_top_field\n readExpGolomb(bitstream); // chroma_sample_loc_type_bottom_field\n }\n bitstream.readBits(1); // neutral_chroma_indication_flag\n bitstream.readBits(1); // field_seq_flag\n bitstream.readBits(1); // frame_field_info_present_flag\n if (bitstream.readBits(1)) { // default_display_window_flag\n readExpGolomb(bitstream); // def_disp_win_left_offset\n readExpGolomb(bitstream); // def_disp_win_right_offset\n readExpGolomb(bitstream); // def_disp_win_top_offset\n readExpGolomb(bitstream); // def_disp_win_bottom_offset\n }\n if (bitstream.readBits(1)) { // vui_timing_info_present_flag\n bitstream.readBits(32); // vui_num_units_in_tick\n bitstream.readBits(32); // vui_time_scale\n if (bitstream.readBits(1)) { // vui_poc_proportional_to_timing_flag\n readExpGolomb(bitstream); // vui_num_ticks_poc_diff_one_minus1\n }\n if (bitstream.readBits(1)) {\n skipHrdParameters(bitstream, true, sps_max_sub_layers_minus1);\n }\n }\n if (bitstream.readBits(1)) { // bitstream_restriction_flag\n bitstream.readBits(1); // tiles_fixed_structure_flag\n bitstream.readBits(1); // motion_vectors_over_pic_boundaries_flag\n bitstream.readBits(1); // restricted_ref_pic_lists_flag\n const min_spatial_segmentation_idc = readExpGolomb(bitstream);\n // skip the rest\n readExpGolomb(bitstream); // max_bytes_per_pic_denom\n readExpGolomb(bitstream); // max_bits_per_min_cu_denom\n readExpGolomb(bitstream); // log2_max_mv_length_horizontal\n readExpGolomb(bitstream); // log2_max_mv_length_vertical\n return min_spatial_segmentation_idc;\n }\n return 0;\n};\nconst skipHrdParameters = (bitstream, commonInfPresentFlag, maxNumSubLayersMinus1) => {\n let nal_hrd_parameters_present_flag = false;\n let vcl_hrd_parameters_present_flag = false;\n let sub_pic_hrd_params_present_flag = false;\n if (commonInfPresentFlag) {\n nal_hrd_parameters_present_flag = bitstream.readBits(1) === 1;\n vcl_hrd_parameters_present_flag = bitstream.readBits(1) === 1;\n if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {\n sub_pic_hrd_params_present_flag = bitstream.readBits(1) === 1;\n if (sub_pic_hrd_params_present_flag) {\n bitstream.readBits(8); // tick_divisor_minus2\n bitstream.readBits(5); // du_cpb_removal_delay_increment_length_minus1\n bitstream.readBits(1); // sub_pic_cpb_params_in_pic_timing_sei_flag\n bitstream.readBits(5); // dpb_output_delay_du_length_minus1\n }\n bitstream.readBits(4); // bit_rate_scale\n bitstream.readBits(4); // cpb_size_scale\n if (sub_pic_hrd_params_present_flag) {\n bitstream.readBits(4); // cpb_size_du_scale\n }\n bitstream.readBits(5); // initial_cpb_removal_delay_length_minus1\n bitstream.readBits(5); // au_cpb_removal_delay_length_minus1\n bitstream.readBits(5); // dpb_output_delay_length_minus1\n }\n }\n for (let i = 0; i <= maxNumSubLayersMinus1; i++) {\n const fixed_pic_rate_general_flag = bitstream.readBits(1) === 1;\n let fixed_pic_rate_within_cvs_flag = true; // Default assumption if general is true\n if (!fixed_pic_rate_general_flag) {\n fixed_pic_rate_within_cvs_flag = bitstream.readBits(1) === 1;\n }\n let low_delay_hrd_flag = false; // Default assumption\n if (fixed_pic_rate_within_cvs_flag) {\n readExpGolomb(bitstream); // elemental_duration_in_tc_minus1[i]\n }\n else {\n low_delay_hrd_flag = bitstream.readBits(1) === 1;\n }\n let CpbCnt = 1; // Default if low_delay is true\n if (!low_delay_hrd_flag) {\n const cpb_cnt_minus1 = readExpGolomb(bitstream); // cpb_cnt_minus1[i]\n CpbCnt = cpb_cnt_minus1 + 1;\n }\n if (nal_hrd_parameters_present_flag) {\n skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);\n }\n if (vcl_hrd_parameters_present_flag) {\n skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);\n }\n }\n};\nconst skipSubLayerHrdParameters = (bitstream, CpbCnt, sub_pic_hrd_params_present_flag) => {\n for (let i = 0; i < CpbCnt; i++) {\n readExpGolomb(bitstream); // bit_rate_value_minus1[i]\n readExpGolomb(bitstream); // cpb_size_value_minus1[i]\n if (sub_pic_hrd_params_present_flag) {\n readExpGolomb(bitstream); // cpb_size_du_value_minus1[i]\n readExpGolomb(bitstream); // bit_rate_du_value_minus1[i]\n }\n bitstream.readBits(1); // cbr_flag[i]\n }\n};\n/** Serializes an HevcDecoderConfigurationRecord into the format specified in Section 8.3.3.1 of ISO 14496-15. */\nexport const serializeHevcDecoderConfigurationRecord = (record) => {\n const bytes = [];\n bytes.push(record.configurationVersion);\n bytes.push(((record.generalProfileSpace & 0x3) << 6)\n | ((record.generalTierFlag & 0x1) << 5)\n | (record.generalProfileIdc & 0x1F));\n bytes.push((record.generalProfileCompatibilityFlags >>> 24) & 0xFF);\n bytes.push((record.generalProfileCompatibilityFlags >>> 16) & 0xFF);\n bytes.push((record.generalProfileCompatibilityFlags >>> 8) & 0xFF);\n bytes.push(record.generalProfileCompatibilityFlags & 0xFF);\n bytes.push(...record.generalConstraintIndicatorFlags);\n bytes.push(record.generalLevelIdc & 0xFF);\n bytes.push(0xF0 | ((record.minSpatialSegmentationIdc >> 8) & 0x0F)); // Reserved + high nibble\n bytes.push(record.minSpatialSegmentationIdc & 0xFF); // Low byte\n bytes.push(0xFC | (record.parallelismType & 0x03));\n bytes.push(0xFC | (record.chromaFormatIdc & 0x03));\n bytes.push(0xF8 | (record.bitDepthLumaMinus8 & 0x07));\n bytes.push(0xF8 | (record.bitDepthChromaMinus8 & 0x07));\n bytes.push((record.avgFrameRate >> 8) & 0xFF); // High byte\n bytes.push(record.avgFrameRate & 0xFF); // Low byte\n bytes.push(((record.constantFrameRate & 0x03) << 6)\n | ((record.numTemporalLayers & 0x07) << 3)\n | ((record.temporalIdNested & 0x01) << 2)\n | (record.lengthSizeMinusOne & 0x03));\n bytes.push(record.arrays.length & 0xFF);\n for (const arr of record.arrays) {\n bytes.push(((arr.arrayCompleteness & 0x01) << 7)\n | (0 << 6)\n | (arr.nalUnitType & 0x3F));\n bytes.push((arr.nalUnits.length >> 8) & 0xFF); // High byte\n bytes.push(arr.nalUnits.length & 0xFF); // Low byte\n for (const nal of arr.nalUnits) {\n bytes.push((nal.length >> 8) & 0xFF); // High byte\n bytes.push(nal.length & 0xFF); // Low byte\n for (let i = 0; i < nal.length; i++) {\n bytes.push(nal[i]);\n }\n }\n }\n return new Uint8Array(bytes);\n};\nexport const extractVp9CodecInfoFromPacket = (packet) => {\n // eslint-disable-next-line @stylistic/max-len\n // https://storage.googleapis.com/downloads.webmproject.org/docs/vp9/vp9-bitstream-specification-v0.7-20170222-draft.pdf\n // http://downloads.webmproject.org/docs/vp9/vp9-bitstream_superframe-and-uncompressed-header_v1.0.pdf\n const bitstream = new Bitstream(packet);\n // Frame marker (0b10)\n const frameMarker = bitstream.readBits(2);\n if (frameMarker !== 2) {\n return null;\n }\n // Profile\n const profileLowBit = bitstream.readBits(1);\n const profileHighBit = bitstream.readBits(1);\n const profile = (profileHighBit << 1) + profileLowBit;\n // Skip reserved bit for profile 3\n if (profile === 3) {\n bitstream.skipBits(1);\n }\n // show_existing_frame\n const showExistingFrame = bitstream.readBits(1);\n if (showExistingFrame === 1) {\n return null;\n }\n // frame_type (0 = key frame)\n const frameType = bitstream.readBits(1);\n if (frameType !== 0) {\n return null;\n }\n // Skip show_frame and error_resilient_mode\n bitstream.skipBits(2);\n // Sync code (0x498342)\n const syncCode = bitstream.readBits(24);\n if (syncCode !== 0x498342) {\n return null;\n }\n // Color config\n let bitDepth = 8;\n if (profile >= 2) {\n const tenOrTwelveBit = bitstream.readBits(1);\n bitDepth = tenOrTwelveBit ? 12 : 10;\n }\n // Color space\n const colorSpace = bitstream.readBits(3);\n let chromaSubsampling = 0;\n let videoFullRangeFlag = 0;\n if (colorSpace !== 7) { // 7 is CS_RGB\n const colorRange = bitstream.readBits(1);\n videoFullRangeFlag = colorRange;\n if (profile === 1 || profile === 3) {\n const subsamplingX = bitstream.readBits(1);\n const subsamplingY = bitstream.readBits(1);\n // 0 = 4:2:0 vertical\n // 1 = 4:2:0 colocated\n // 2 = 4:2:2\n // 3 = 4:4:4\n chromaSubsampling = !subsamplingX && !subsamplingY\n ? 3 // 0,0 = 4:4:4\n : subsamplingX && !subsamplingY\n ? 2 // 1,0 = 4:2:2\n : 1; // 1,1 = 4:2:0 colocated (default)\n // Skip reserved bit\n bitstream.skipBits(1);\n }\n else {\n // For profile 0 and 2, always 4:2:0\n chromaSubsampling = 1; // Using colocated as default\n }\n }\n else {\n // RGB is always 4:4:4\n chromaSubsampling = 3;\n videoFullRangeFlag = 1;\n }\n // Parse frame size\n const widthMinusOne = bitstream.readBits(16);\n const heightMinusOne = bitstream.readBits(16);\n const width = widthMinusOne + 1;\n const height = heightMinusOne + 1;\n // Calculate level based on dimensions\n const pictureSize = width * height;\n let level = last(VP9_LEVEL_TABLE).level; // Default to highest level\n for (const entry of VP9_LEVEL_TABLE) {\n if (pictureSize <= entry.maxPictureSize) {\n level = entry.level;\n break;\n }\n }\n // Map color_space to standard values\n const matrixCoefficients = colorSpace === 7\n ? 0\n : colorSpace === 2\n ? 1\n : colorSpace === 1\n ? 6\n : 2;\n const colourPrimaries = colorSpace === 2\n ? 1\n : colorSpace === 1\n ? 6\n : 2;\n const transferCharacteristics = colorSpace === 2\n ? 1\n : colorSpace === 1\n ? 6\n : 2;\n return {\n profile,\n level,\n bitDepth,\n chromaSubsampling,\n videoFullRangeFlag,\n colourPrimaries,\n transferCharacteristics,\n matrixCoefficients,\n };\n};\n/** Iterates over all OBUs in an AV1 packet bistream. */\nexport const iterateAv1PacketObus = function* (packet) {\n // https://aomediacodec.github.io/av1-spec/av1-spec.pdf\n const bitstream = new Bitstream(packet);\n const readLeb128 = () => {\n let value = 0;\n for (let i = 0; i < 8; i++) {\n const byte = bitstream.readAlignedByte();\n value |= ((byte & 0x7f) << (i * 7));\n if (!(byte & 0x80)) {\n break;\n }\n // Spec requirement\n if (i === 7 && (byte & 0x80)) {\n return null;\n }\n }\n // Spec requirement\n if (value >= 2 ** 32 - 1) {\n return null;\n }\n return value;\n };\n while (bitstream.getBitsLeft() >= 8) {\n // Parse OBU header\n bitstream.skipBits(1);\n const obuType = bitstream.readBits(4);\n const obuExtension = bitstream.readBits(1);\n const obuHasSizeField = bitstream.readBits(1);\n bitstream.skipBits(1);\n // Skip extension header if present\n if (obuExtension) {\n bitstream.skipBits(8);\n }\n // Read OBU size if present\n let obuSize;\n if (obuHasSizeField) {\n const obuSizeValue = readLeb128();\n if (obuSizeValue === null)\n return; // It was invalid\n obuSize = obuSizeValue;\n }\n else {\n // Calculate remaining bits and convert to bytes, rounding down\n obuSize = Math.floor(bitstream.getBitsLeft() / 8);\n }\n assert(bitstream.pos % 8 === 0);\n yield {\n type: obuType,\n data: packet.subarray(bitstream.pos / 8, bitstream.pos / 8 + obuSize),\n };\n // Move to next OBU\n bitstream.skipBits(obuSize * 8);\n }\n};\n/**\n * When AV1 codec information is not provided by the container, we can still try to extract the information by digging\n * into the AV1 bitstream.\n */\nexport const extractAv1CodecInfoFromPacket = (packet) => {\n // https://aomediacodec.github.io/av1-spec/av1-spec.pdf\n for (const { type, data } of iterateAv1PacketObus(packet)) {\n if (type !== 1) {\n continue; // 1 == OBU_SEQUENCE_HEADER\n }\n const bitstream = new Bitstream(data);\n // Read sequence header fields\n const seqProfile = bitstream.readBits(3);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const stillPicture = bitstream.readBits(1);\n const reducedStillPictureHeader = bitstream.readBits(1);\n let seqLevel = 0;\n let seqTier = 0;\n let bufferDelayLengthMinus1 = 0;\n if (reducedStillPictureHeader) {\n seqLevel = bitstream.readBits(5);\n }\n else {\n // Parse timing_info_present_flag\n const timingInfoPresentFlag = bitstream.readBits(1);\n if (timingInfoPresentFlag) {\n // Skip timing info (num_units_in_display_tick, time_scale, equal_picture_interval)\n bitstream.skipBits(32); // num_units_in_display_tick\n bitstream.skipBits(32); // time_scale\n const equalPictureInterval = bitstream.readBits(1);\n if (equalPictureInterval) {\n // Skip num_ticks_per_picture_minus_1 (uvlc)\n // Since this is variable length, we'd need to implement uvlc reading\n // For now, we'll return null as this is rare\n return null;\n }\n }\n // Parse decoder_model_info_present_flag\n const decoderModelInfoPresentFlag = bitstream.readBits(1);\n if (decoderModelInfoPresentFlag) {\n // Store buffer_delay_length_minus_1 instead of just skipping\n bufferDelayLengthMinus1 = bitstream.readBits(5);\n bitstream.skipBits(32); // num_units_in_decoding_tick\n bitstream.skipBits(5); // buffer_removal_time_length_minus_1\n bitstream.skipBits(5); // frame_presentation_time_length_minus_1\n }\n // Parse operating_points_cnt_minus_1\n const operatingPointsCntMinus1 = bitstream.readBits(5);\n // For each operating point\n for (let i = 0; i <= operatingPointsCntMinus1; i++) {\n // operating_point_idc[i]\n bitstream.skipBits(12);\n // seq_level_idx[i]\n const seqLevelIdx = bitstream.readBits(5);\n if (i === 0) {\n seqLevel = seqLevelIdx;\n }\n if (seqLevelIdx > 7) {\n // seq_tier[i]\n const seqTierTemp = bitstream.readBits(1);\n if (i === 0) {\n seqTier = seqTierTemp;\n }\n }\n if (decoderModelInfoPresentFlag) {\n // decoder_model_present_for_this_op[i]\n const decoderModelPresentForThisOp = bitstream.readBits(1);\n if (decoderModelPresentForThisOp) {\n const n = bufferDelayLengthMinus1 + 1;\n bitstream.skipBits(n); // decoder_buffer_delay[op]\n bitstream.skipBits(n); // encoder_buffer_delay[op]\n bitstream.skipBits(1); // low_delay_mode_flag[op]\n }\n }\n // initial_display_delay_present_flag\n const initialDisplayDelayPresentFlag = bitstream.readBits(1);\n if (initialDisplayDelayPresentFlag) {\n // initial_display_delay_minus_1[i]\n bitstream.skipBits(4);\n }\n }\n }\n // Frame size\n const frameWidthBitsMinus1 = bitstream.readBits(4);\n const frameHeightBitsMinus1 = bitstream.readBits(4);\n const n1 = frameWidthBitsMinus1 + 1;\n bitstream.skipBits(n1); // max_frame_width_minus_1\n const n2 = frameHeightBitsMinus1 + 1;\n bitstream.skipBits(n2); // max_frame_height_minus_1\n // Frame IDs\n let frameIdNumbersPresentFlag = 0;\n if (reducedStillPictureHeader) {\n frameIdNumbersPresentFlag = 0;\n }\n else {\n frameIdNumbersPresentFlag = bitstream.readBits(1);\n }\n if (frameIdNumbersPresentFlag) {\n bitstream.skipBits(4); // delta_frame_id_length_minus_2\n bitstream.skipBits(3); // additional_frame_id_length_minus_1\n }\n bitstream.skipBits(1); // use_128x128_superblock\n bitstream.skipBits(1); // enable_filter_intra\n bitstream.skipBits(1); // enable_intra_edge_filter\n if (!reducedStillPictureHeader) {\n bitstream.skipBits(1); // enable_interintra_compound\n bitstream.skipBits(1); // enable_masked_compound\n bitstream.skipBits(1); // enable_warped_motion\n bitstream.skipBits(1); // enable_dual_filter\n const enableOrderHint = bitstream.readBits(1);\n if (enableOrderHint) {\n bitstream.skipBits(1); // enable_jnt_comp\n bitstream.skipBits(1); // enable_ref_frame_mvs\n }\n const seqChooseScreenContentTools = bitstream.readBits(1);\n let seqForceScreenContentTools = 0;\n if (seqChooseScreenContentTools) {\n seqForceScreenContentTools = 2; // SELECT_SCREEN_CONTENT_TOOLS\n }\n else {\n seqForceScreenContentTools = bitstream.readBits(1);\n }\n if (seqForceScreenContentTools > 0) {\n const seqChooseIntegerMv = bitstream.readBits(1);\n if (!seqChooseIntegerMv) {\n bitstream.skipBits(1); // seq_force_integer_mv\n }\n }\n if (enableOrderHint) {\n bitstream.skipBits(3); // order_hint_bits_minus_1\n }\n }\n bitstream.skipBits(1); // enable_superres\n bitstream.skipBits(1); // enable_cdef\n bitstream.skipBits(1); // enable_restoration\n // color_config()\n const highBitdepth = bitstream.readBits(1);\n let bitDepth = 8;\n if (seqProfile === 2 && highBitdepth) {\n const twelveBit = bitstream.readBits(1);\n bitDepth = twelveBit ? 12 : 10;\n }\n else if (seqProfile <= 2) {\n bitDepth = highBitdepth ? 10 : 8;\n }\n let monochrome = 0;\n if (seqProfile !== 1) {\n monochrome = bitstream.readBits(1);\n }\n let chromaSubsamplingX = 1;\n let chromaSubsamplingY = 1;\n let chromaSamplePosition = 0;\n if (!monochrome) {\n if (seqProfile === 0) {\n chromaSubsamplingX = 1;\n chromaSubsamplingY = 1;\n }\n else if (seqProfile === 1) {\n chromaSubsamplingX = 0;\n chromaSubsamplingY = 0;\n }\n else {\n if (bitDepth === 12) {\n chromaSubsamplingX = bitstream.readBits(1);\n if (chromaSubsamplingX) {\n chromaSubsamplingY = bitstream.readBits(1);\n }\n }\n }\n if (chromaSubsamplingX && chromaSubsamplingY) {\n chromaSamplePosition = bitstream.readBits(2);\n }\n }\n return {\n profile: seqProfile,\n level: seqLevel,\n tier: seqTier,\n bitDepth,\n monochrome,\n chromaSubsamplingX,\n chromaSubsamplingY,\n chromaSamplePosition,\n };\n }\n return null;\n};\nexport const parseOpusIdentificationHeader = (bytes) => {\n const view = toDataView(bytes);\n const outputChannelCount = view.getUint8(9);\n const preSkip = view.getUint16(10, true);\n const inputSampleRate = view.getUint32(12, true);\n const outputGain = view.getInt16(16, true);\n const channelMappingFamily = view.getUint8(18);\n let channelMappingTable = null;\n if (channelMappingFamily) {\n channelMappingTable = bytes.subarray(19, 19 + 2 + outputChannelCount);\n }\n return {\n outputChannelCount,\n preSkip,\n inputSampleRate,\n outputGain,\n channelMappingFamily,\n channelMappingTable,\n };\n};\n// From https://datatracker.ietf.org/doc/html/rfc6716, in 48 kHz samples\nconst OPUS_FRAME_DURATION_TABLE = [\n 480, 960, 1920, 2880,\n 480, 960, 1920, 2880,\n 480, 960, 1920, 2880,\n 480, 960,\n 480, 960,\n 120, 240, 480, 960,\n 120, 240, 480, 960,\n 120, 240, 480, 960,\n 120, 240, 480, 960,\n];\nexport const parseOpusTocByte = (packet) => {\n const config = packet[0] >> 3;\n return {\n durationInSamples: OPUS_FRAME_DURATION_TABLE[config],\n };\n};\n// Based on vorbis_parser.c from FFmpeg.\nexport const parseModesFromVorbisSetupPacket = (setupHeader) => {\n // Verify that this is a Setup header.\n if (setupHeader.length < 7) {\n throw new Error('Setup header is too short.');\n }\n if (setupHeader[0] !== 5) {\n throw new Error('Wrong packet type in Setup header.');\n }\n const signature = String.fromCharCode(...setupHeader.slice(1, 7));\n if (signature !== 'vorbis') {\n throw new Error('Invalid packet signature in Setup header.');\n }\n // Reverse the entire buffer.\n const bufSize = setupHeader.length;\n const revBuffer = new Uint8Array(bufSize);\n for (let i = 0; i < bufSize; i++) {\n revBuffer[i] = setupHeader[bufSize - 1 - i];\n }\n // Initialize a Bitstream on the reversed buffer.\n const bitstream = new Bitstream(revBuffer);\n // --- Find the framing bit.\n // In FFmpeg code, we scan until get_bits1() returns 1.\n let gotFramingBit = 0;\n while (bitstream.getBitsLeft() > 97) {\n if (bitstream.readBits(1) === 1) {\n gotFramingBit = bitstream.pos;\n break;\n }\n }\n if (gotFramingBit === 0) {\n throw new Error('Invalid Setup header: framing bit not found.');\n }\n // --- Search backwards for a valid mode header.\n // We try to \u201Cguess\u201D the number of modes by reading a fixed pattern.\n let modeCount = 0;\n let gotModeHeader = false;\n let lastModeCount = 0;\n while (bitstream.getBitsLeft() >= 97) {\n const tempPos = bitstream.pos;\n const a = bitstream.readBits(8);\n const b = bitstream.readBits(16);\n const c = bitstream.readBits(16);\n // If a > 63 or b or c nonzero, assume we\u2019ve gone too far.\n if (a > 63 || b !== 0 || c !== 0) {\n bitstream.pos = tempPos;\n break;\n }\n bitstream.skipBits(1);\n modeCount++;\n if (modeCount > 64) {\n break;\n }\n const bsClone = bitstream.clone();\n const candidate = bsClone.readBits(6) + 1;\n if (candidate === modeCount) {\n gotModeHeader = true;\n lastModeCount = modeCount;\n }\n }\n if (!gotModeHeader) {\n throw new Error('Invalid Setup header: mode header not found.');\n }\n if (lastModeCount > 63) {\n throw new Error(`Unsupported mode count: ${lastModeCount}.`);\n }\n const finalModeCount = lastModeCount;\n // --- Reinitialize the bitstream.\n bitstream.pos = 0;\n // Skip the bits up to the found framing bit.\n bitstream.skipBits(gotFramingBit);\n // --- Now read, for each mode (in reverse order), 40 bits then one bit.\n // That one bit is the mode blockflag.\n const modeBlockflags = Array(finalModeCount).fill(0);\n for (let i = finalModeCount - 1; i >= 0; i--) {\n bitstream.skipBits(40);\n modeBlockflags[i] = bitstream.readBits(1);\n }\n return { modeBlockflags };\n};\n/** Determines a packet's type (key or delta) by digging into the packet bitstream. */\nexport const determineVideoPacketType = (codec, decoderConfig, packetData) => {\n switch (codec) {\n case 'avc':\n {\n const nalUnits = extractAvcNalUnits(packetData, decoderConfig);\n let isKeyframe = nalUnits.some(x => extractNalUnitTypeForAvc(x) === AvcNalUnitType.IDR);\n if (!isKeyframe && (!isChromium() || getChromiumVersion() >= 144)) {\n // In addition to IDR, Recovery Point SEI also counts as a valid H.264 keyframe by current consensus.\n // See https://github.com/w3c/webcodecs/issues/650 for the relevant discussion. WebKit and Firefox have\n // always supported them, but Chromium hasn't, therefore the (admittedly dirty) version check.\n for (const nalUnit of nalUnits) {\n const type = extractNalUnitTypeForAvc(nalUnit);\n if (type !== AvcNalUnitType.SEI) {\n continue;\n }\n const bytes = removeEmulationPreventionBytes(nalUnit);\n let pos = 1; // Skip NALU header\n // sei_rbsp()\n do {\n // sei_message()\n let payloadType = 0;\n while (true) {\n const nextByte = bytes[pos++];\n if (nextByte === undefined)\n break;\n payloadType += nextByte;\n if (nextByte < 255) {\n break;\n }\n }\n let payloadSize = 0;\n while (true) {\n const nextByte = bytes[pos++];\n if (nextByte === undefined)\n break;\n payloadSize += nextByte;\n if (nextByte < 255) {\n break;\n }\n }\n // sei_payload()\n const PAYLOAD_TYPE_RECOVERY_POINT = 6;\n if (payloadType === PAYLOAD_TYPE_RECOVERY_POINT) {\n const bitstream = new Bitstream(bytes);\n bitstream.pos = 8 * pos;\n const recoveryFrameCount = readExpGolomb(bitstream);\n const exactMatchFlag = bitstream.readBits(1);\n if (recoveryFrameCount === 0 && exactMatchFlag === 1) {\n // https://github.com/w3c/webcodecs/pull/910\n // \"recovery_frame_cnt == 0 and exact_match_flag=1 in the SEI recovery payload\"\n isKeyframe = true;\n break;\n }\n }\n pos += payloadSize;\n } while (pos < bytes.length - 1);\n }\n }\n return isKeyframe ? 'key' : 'delta';\n }\n ;\n case 'hevc':\n {\n const nalUnits = extractHevcNalUnits(packetData, decoderConfig);\n const isKeyframe = nalUnits.some((x) => {\n const type = extractNalUnitTypeForHevc(x);\n return HevcNalUnitType.BLA_W_LP <= type && type <= HevcNalUnitType.RSV_IRAP_VCL23;\n });\n return isKeyframe ? 'key' : 'delta';\n }\n ;\n case 'vp8':\n {\n // VP8, once again, by far the easiest to deal with.\n const frameType = packetData[0] & 0b1;\n return frameType === 0 ? 'key' : 'delta';\n }\n ;\n case 'vp9':\n {\n const bitstream = new Bitstream(packetData);\n if (bitstream.readBits(2) !== 2) {\n return null;\n }\n ;\n const profileLowBit = bitstream.readBits(1);\n const profileHighBit = bitstream.readBits(1);\n const profile = (profileHighBit << 1) + profileLowBit;\n // Skip reserved bit for profile 3\n if (profile === 3) {\n bitstream.skipBits(1);\n }\n const showExistingFrame = bitstream.readBits(1);\n if (showExistingFrame) {\n return null;\n }\n const frameType = bitstream.readBits(1);\n return frameType === 0 ? 'key' : 'delta';\n }\n ;\n case 'av1':\n {\n let reducedStillPictureHeader = false;\n for (const { type, data } of iterateAv1PacketObus(packetData)) {\n if (type === 1) { // OBU_SEQUENCE_HEADER\n const bitstream = new Bitstream(data);\n bitstream.skipBits(4);\n reducedStillPictureHeader = !!bitstream.readBits(1);\n }\n else if (type === 3 // OBU_FRAME_HEADER\n || type === 6 // OBU_FRAME\n || type === 7 // OBU_REDUNDANT_FRAME_HEADER\n ) {\n if (reducedStillPictureHeader) {\n return 'key';\n }\n const bitstream = new Bitstream(data);\n const showExistingFrame = bitstream.readBits(1);\n if (showExistingFrame) {\n return null;\n }\n const frameType = bitstream.readBits(2);\n return frameType === 0 ? 'key' : 'delta';\n }\n }\n return null;\n }\n ;\n default:\n {\n assertNever(codec);\n assert(false);\n }\n ;\n }\n};\nexport var FlacBlockType;\n(function (FlacBlockType) {\n FlacBlockType[FlacBlockType[\"STREAMINFO\"] = 0] = \"STREAMINFO\";\n FlacBlockType[FlacBlockType[\"VORBIS_COMMENT\"] = 4] = \"VORBIS_COMMENT\";\n FlacBlockType[FlacBlockType[\"PICTURE\"] = 6] = \"PICTURE\";\n})(FlacBlockType || (FlacBlockType = {}));\nexport const readVorbisComments = (bytes, metadataTags) => {\n // https://datatracker.ietf.org/doc/html/rfc7845#section-5.2\n const commentView = toDataView(bytes);\n let commentPos = 0;\n const vendorStringLength = commentView.getUint32(commentPos, true);\n commentPos += 4;\n const vendorString = textDecoder.decode(bytes.subarray(commentPos, commentPos + vendorStringLength));\n commentPos += vendorStringLength;\n if (vendorStringLength > 0) {\n // Expose the vendor string in the raw metadata\n metadataTags.raw ??= {};\n metadataTags.raw['vendor'] ??= vendorString;\n }\n const listLength = commentView.getUint32(commentPos, true);\n commentPos += 4;\n // Loop over all metadata tags\n for (let i = 0; i < listLength; i++) {\n const stringLength = commentView.getUint32(commentPos, true);\n commentPos += 4;\n const string = textDecoder.decode(bytes.subarray(commentPos, commentPos + stringLength));\n commentPos += stringLength;\n const separatorIndex = string.indexOf('=');\n if (separatorIndex === -1) {\n continue;\n }\n const key = string.slice(0, separatorIndex).toUpperCase();\n const value = string.slice(separatorIndex + 1);\n metadataTags.raw ??= {};\n metadataTags.raw[key] ??= value;\n switch (key) {\n case 'TITLE':\n {\n metadataTags.title ??= value;\n }\n ;\n break;\n case 'DESCRIPTION':\n {\n metadataTags.description ??= value;\n }\n ;\n break;\n case 'ARTIST':\n {\n metadataTags.artist ??= value;\n }\n ;\n break;\n case 'ALBUM':\n {\n metadataTags.album ??= value;\n }\n ;\n break;\n case 'ALBUMARTIST':\n {\n metadataTags.albumArtist ??= value;\n }\n ;\n break;\n case 'COMMENT':\n {\n metadataTags.comment ??= value;\n }\n ;\n break;\n case 'LYRICS':\n {\n metadataTags.lyrics ??= value;\n }\n ;\n break;\n case 'TRACKNUMBER':\n {\n const parts = value.split('/');\n const trackNum = Number.parseInt(parts[0], 10);\n const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);\n if (Number.isInteger(trackNum) && trackNum > 0) {\n metadataTags.trackNumber ??= trackNum;\n }\n if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {\n metadataTags.tracksTotal ??= tracksTotal;\n }\n }\n ;\n break;\n case 'TRACKTOTAL':\n {\n const tracksTotal = Number.parseInt(value, 10);\n if (Number.isInteger(tracksTotal) && tracksTotal > 0) {\n metadataTags.tracksTotal ??= tracksTotal;\n }\n }\n ;\n break;\n case 'DISCNUMBER':\n {\n const parts = value.split('/');\n const discNum = Number.parseInt(parts[0], 10);\n const discsTotal = parts[1] && Number.parseInt(parts[1], 10);\n if (Number.isInteger(discNum) && discNum > 0) {\n metadataTags.discNumber ??= discNum;\n }\n if (discsTotal && Number.isInteger(discsTotal) && discsTotal > 0) {\n metadataTags.discsTotal ??= discsTotal;\n }\n }\n ;\n break;\n case 'DISCTOTAL':\n {\n const discsTotal = Number.parseInt(value, 10);\n if (Number.isInteger(discsTotal) && discsTotal > 0) {\n metadataTags.discsTotal ??= discsTotal;\n }\n }\n ;\n break;\n case 'DATE':\n {\n const date = new Date(value);\n if (!Number.isNaN(date.getTime())) {\n metadataTags.date ??= date;\n }\n }\n ;\n break;\n case 'GENRE':\n {\n metadataTags.genre ??= value;\n }\n ;\n break;\n case 'METADATA_BLOCK_PICTURE':\n {\n // https://datatracker.ietf.org/doc/rfc9639/ Section 8.8\n const decoded = base64ToBytes(value);\n const view = toDataView(decoded);\n const pictureType = view.getUint32(0, false);\n const mediaTypeLength = view.getUint32(4, false);\n const mediaType = String.fromCharCode(...decoded.subarray(8, 8 + mediaTypeLength)); // ASCII\n const descriptionLength = view.getUint32(8 + mediaTypeLength, false);\n const description = textDecoder.decode(decoded.subarray(12 + mediaTypeLength, 12 + mediaTypeLength + descriptionLength));\n const dataLength = view.getUint32(mediaTypeLength + descriptionLength + 28);\n const data = decoded.subarray(mediaTypeLength + descriptionLength + 32, mediaTypeLength + descriptionLength + 32 + dataLength);\n metadataTags.images ??= [];\n metadataTags.images.push({\n data,\n mimeType: mediaType,\n kind: pictureType === 3 ? 'coverFront' : pictureType === 4 ? 'coverBack' : 'unknown',\n name: undefined,\n description: description || undefined,\n });\n }\n ;\n break;\n }\n }\n};\nexport const createVorbisComments = (headerBytes, tags, writeImages) => {\n // https://datatracker.ietf.org/doc/html/rfc7845#section-5.2\n const commentHeaderParts = [\n headerBytes,\n ];\n const vendorString = 'Mediabunny';\n const encodedVendorString = textEncoder.encode(vendorString);\n let currentBuffer = new Uint8Array(4 + encodedVendorString.length);\n let currentView = new DataView(currentBuffer.buffer);\n currentView.setUint32(0, encodedVendorString.length, true);\n currentBuffer.set(encodedVendorString, 4);\n commentHeaderParts.push(currentBuffer);\n const writtenTags = new Set();\n const addCommentTag = (key, value) => {\n const joined = `${key}=${value}`;\n const encoded = textEncoder.encode(joined);\n currentBuffer = new Uint8Array(4 + encoded.length);\n currentView = new DataView(currentBuffer.buffer);\n currentView.setUint32(0, encoded.length, true);\n currentBuffer.set(encoded, 4);\n commentHeaderParts.push(currentBuffer);\n writtenTags.add(key);\n };\n for (const { key, value } of keyValueIterator(tags)) {\n switch (key) {\n case 'title':\n {\n addCommentTag('TITLE', value);\n }\n ;\n break;\n case 'description':\n {\n addCommentTag('DESCRIPTION', value);\n }\n ;\n break;\n case 'artist':\n {\n addCommentTag('ARTIST', value);\n }\n ;\n break;\n case 'album':\n {\n addCommentTag('ALBUM', value);\n }\n ;\n break;\n case 'albumArtist':\n {\n addCommentTag('ALBUMARTIST', value);\n }\n ;\n break;\n case 'genre':\n {\n addCommentTag('GENRE', value);\n }\n ;\n break;\n case 'date':\n {\n const rawVersion = tags.raw?.['DATE'] ?? tags.raw?.['date'];\n if (rawVersion && typeof rawVersion === 'string') {\n addCommentTag('DATE', rawVersion);\n }\n else {\n addCommentTag('DATE', value.toISOString().slice(0, 10));\n }\n }\n ;\n break;\n case 'comment':\n {\n addCommentTag('COMMENT', value);\n }\n ;\n break;\n case 'lyrics':\n {\n addCommentTag('LYRICS', value);\n }\n ;\n break;\n case 'trackNumber':\n {\n addCommentTag('TRACKNUMBER', value.toString());\n }\n ;\n break;\n case 'tracksTotal':\n {\n addCommentTag('TRACKTOTAL', value.toString());\n }\n ;\n break;\n case 'discNumber':\n {\n addCommentTag('DISCNUMBER', value.toString());\n }\n ;\n break;\n case 'discsTotal':\n {\n addCommentTag('DISCTOTAL', value.toString());\n }\n ;\n break;\n case 'images':\n {\n // For example, in .flac, we put the pictures in a different section,\n // not in the Vorbis comment header.\n if (!writeImages) {\n break;\n }\n for (const image of value) {\n // https://datatracker.ietf.org/doc/rfc9639/ Section 8.8\n const pictureType = image.kind === 'coverFront' ? 3 : image.kind === 'coverBack' ? 4 : 0;\n const encodedMediaType = new Uint8Array(image.mimeType.length);\n for (let i = 0; i < image.mimeType.length; i++) {\n encodedMediaType[i] = image.mimeType.charCodeAt(i);\n }\n const encodedDescription = textEncoder.encode(image.description ?? '');\n const buffer = new Uint8Array(4 // Picture type\n + 4 // MIME type length\n + encodedMediaType.length // MIME type\n + 4 // Description length\n + encodedDescription.length // Description\n + 16 // Width, height, color depth, number of colors\n + 4 // Picture data length\n + image.data.length);\n const view = toDataView(buffer);\n view.setUint32(0, pictureType, false);\n view.setUint32(4, encodedMediaType.length, false);\n buffer.set(encodedMediaType, 8);\n view.setUint32(8 + encodedMediaType.length, encodedDescription.length, false);\n buffer.set(encodedDescription, 12 + encodedMediaType.length);\n // Skip a bunch of fields (width, height, color depth, number of colors)\n view.setUint32(28 + encodedMediaType.length + encodedDescription.length, image.data.length, false);\n buffer.set(image.data, 32 + encodedMediaType.length + encodedDescription.length);\n const encoded = bytesToBase64(buffer);\n addCommentTag('METADATA_BLOCK_PICTURE', encoded);\n }\n }\n ;\n break;\n case 'raw':\n {\n // Handled later\n }\n ;\n break;\n default: assertNever(key);\n }\n }\n if (tags.raw) {\n for (const key in tags.raw) {\n const value = tags.raw[key] ?? tags.raw[key.toLowerCase()];\n if (key === 'vendor' || value == null || writtenTags.has(key)) {\n continue;\n }\n if (typeof value === 'string') {\n addCommentTag(key, value);\n }\n }\n }\n const listLengthBuffer = new Uint8Array(4);\n toDataView(listLengthBuffer).setUint32(0, writtenTags.size, true);\n commentHeaderParts.splice(2, 0, listLengthBuffer); // Insert after the header and vendor section\n // Merge all comment header parts into a single buffer\n const commentHeaderLength = commentHeaderParts.reduce((a, b) => a + b.length, 0);\n const commentHeader = new Uint8Array(commentHeaderLength);\n let pos = 0;\n for (const part of commentHeaderParts) {\n commentHeader.set(part, pos);\n pos += part.length;\n }\n return commentHeader;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nexport class Demuxer {\n constructor(input) {\n this.input = input;\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n/**\n * Base class for custom video decoders. To add your own custom video decoder, extend this class, implement the\n * abstract methods and static `supports` method, and register the decoder using {@link registerDecoder}.\n * @group Custom coders\n * @public\n */\nexport class CustomVideoDecoder {\n /** Returns true if and only if the decoder can decode the given codec configuration. */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static supports(codec, config) {\n return false;\n }\n}\n/**\n * Base class for custom audio decoders. To add your own custom audio decoder, extend this class, implement the\n * abstract methods and static `supports` method, and register the decoder using {@link registerDecoder}.\n * @group Custom coders\n * @public\n */\nexport class CustomAudioDecoder {\n /** Returns true if and only if the decoder can decode the given codec configuration. */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static supports(codec, config) {\n return false;\n }\n}\n/**\n * Base class for custom video encoders. To add your own custom video encoder, extend this class, implement the\n * abstract methods and static `supports` method, and register the encoder using {@link registerEncoder}.\n * @group Custom coders\n * @public\n */\nexport class CustomVideoEncoder {\n /** Returns true if and only if the encoder can encode the given codec configuration. */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static supports(codec, config) {\n return false;\n }\n}\n/**\n * Base class for custom audio encoders. To add your own custom audio encoder, extend this class, implement the\n * abstract methods and static `supports` method, and register the encoder using {@link registerEncoder}.\n * @group Custom coders\n * @public\n */\nexport class CustomAudioEncoder {\n /** Returns true if and only if the encoder can encode the given codec configuration. */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n static supports(codec, config) {\n return false;\n }\n}\nexport const customVideoDecoders = [];\nexport const customAudioDecoders = [];\nexport const customVideoEncoders = [];\nexport const customAudioEncoders = [];\n/**\n * Registers a custom video or audio decoder. Registered decoders will automatically be used for decoding whenever\n * possible.\n * @group Custom coders\n * @public\n */\nexport const registerDecoder = (decoder) => {\n if (decoder.prototype instanceof CustomVideoDecoder) {\n const casted = decoder;\n if (customVideoDecoders.includes(casted)) {\n console.warn('Video decoder already registered.');\n return;\n }\n customVideoDecoders.push(casted);\n }\n else if (decoder.prototype instanceof CustomAudioDecoder) {\n const casted = decoder;\n if (customAudioDecoders.includes(casted)) {\n console.warn('Audio decoder already registered.');\n return;\n }\n customAudioDecoders.push(casted);\n }\n else {\n throw new TypeError('Decoder must be a CustomVideoDecoder or CustomAudioDecoder.');\n }\n};\n/**\n * Registers a custom video or audio encoder. Registered encoders will automatically be used for encoding whenever\n * possible.\n * @group Custom coders\n * @public\n */\nexport const registerEncoder = (encoder) => {\n if (encoder.prototype instanceof CustomVideoEncoder) {\n const casted = encoder;\n if (customVideoEncoders.includes(casted)) {\n console.warn('Video encoder already registered.');\n return;\n }\n customVideoEncoders.push(casted);\n }\n else if (encoder.prototype instanceof CustomAudioEncoder) {\n const casted = encoder;\n if (customAudioEncoders.includes(casted)) {\n console.warn('Audio encoder already registered.');\n return;\n }\n customAudioEncoders.push(casted);\n }\n else {\n throw new TypeError('Encoder must be a CustomVideoEncoder or CustomAudioEncoder.');\n }\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { SECOND_TO_MICROSECOND_FACTOR } from './misc.js';\nexport const PLACEHOLDER_DATA = /* #__PURE__ */ new Uint8Array(0);\n/**\n * Represents an encoded chunk of media. Mainly used as an expressive wrapper around WebCodecs API's\n * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) and\n * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk), but can also be used\n * standalone.\n * @group Packets\n * @public\n */\nexport class EncodedPacket {\n /** Creates a new {@link EncodedPacket} from raw bytes and timing information. */\n constructor(\n /** The encoded data of this packet. */\n data, \n /** The type of this packet. */\n type, \n /**\n * The presentation timestamp of this packet in seconds. May be negative. Samples with negative end timestamps\n * should not be presented.\n */\n timestamp, \n /** The duration of this packet in seconds. */\n duration, \n /**\n * The sequence number indicates the decode order of the packets. Packet A must be decoded before packet B if A\n * has a lower sequence number than B. If two packets have the same sequence number, they are the same packet.\n * Otherwise, sequence numbers are arbitrary and are not guaranteed to have any meaning besides their relative\n * ordering. Negative sequence numbers mean the sequence number is undefined.\n */\n sequenceNumber = -1, byteLength, sideData) {\n this.data = data;\n this.type = type;\n this.timestamp = timestamp;\n this.duration = duration;\n this.sequenceNumber = sequenceNumber;\n if (data === PLACEHOLDER_DATA && byteLength === undefined) {\n throw new Error('Internal error: byteLength must be explicitly provided when constructing metadata-only packets.');\n }\n if (byteLength === undefined) {\n byteLength = data.byteLength;\n }\n if (!(data instanceof Uint8Array)) {\n throw new TypeError('data must be a Uint8Array.');\n }\n if (type !== 'key' && type !== 'delta') {\n throw new TypeError('type must be either \"key\" or \"delta\".');\n }\n if (!Number.isFinite(timestamp)) {\n throw new TypeError('timestamp must be a number.');\n }\n if (!Number.isFinite(duration) || duration < 0) {\n throw new TypeError('duration must be a non-negative number.');\n }\n if (!Number.isFinite(sequenceNumber)) {\n throw new TypeError('sequenceNumber must be a number.');\n }\n if (!Number.isInteger(byteLength) || byteLength < 0) {\n throw new TypeError('byteLength must be a non-negative integer.');\n }\n if (sideData !== undefined && (typeof sideData !== 'object' || !sideData)) {\n throw new TypeError('sideData, when provided, must be an object.');\n }\n if (sideData?.alpha !== undefined && !(sideData.alpha instanceof Uint8Array)) {\n throw new TypeError('sideData.alpha, when provided, must be a Uint8Array.');\n }\n if (sideData?.alphaByteLength !== undefined\n && (!Number.isInteger(sideData.alphaByteLength) || sideData.alphaByteLength < 0)) {\n throw new TypeError('sideData.alphaByteLength, when provided, must be a non-negative integer.');\n }\n this.byteLength = byteLength;\n this.sideData = sideData ?? {};\n if (this.sideData.alpha && this.sideData.alphaByteLength === undefined) {\n this.sideData.alphaByteLength = this.sideData.alpha.byteLength;\n }\n }\n /**\n * If this packet is a metadata-only packet. Metadata-only packets don't contain their packet data. They are the\n * result of retrieving packets with {@link PacketRetrievalOptions.metadataOnly} set to `true`.\n */\n get isMetadataOnly() {\n return this.data === PLACEHOLDER_DATA;\n }\n /** The timestamp of this packet in microseconds. */\n get microsecondTimestamp() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);\n }\n /** The duration of this packet in microseconds. */\n get microsecondDuration() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);\n }\n /** Converts this packet to an\n * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the\n * WebCodecs API. */\n toEncodedVideoChunk() {\n if (this.isMetadataOnly) {\n throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');\n }\n if (typeof EncodedVideoChunk === 'undefined') {\n throw new Error('Your browser does not support EncodedVideoChunk.');\n }\n return new EncodedVideoChunk({\n data: this.data,\n type: this.type,\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration,\n });\n }\n /**\n * Converts this packet to an\n * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the\n * WebCodecs API, using the alpha side data instead of the color data. Throws if no alpha side data is defined.\n */\n alphaToEncodedVideoChunk(type = this.type) {\n if (!this.sideData.alpha) {\n throw new TypeError('This packet does not contain alpha side data.');\n }\n if (this.isMetadataOnly) {\n throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');\n }\n if (typeof EncodedVideoChunk === 'undefined') {\n throw new Error('Your browser does not support EncodedVideoChunk.');\n }\n return new EncodedVideoChunk({\n data: this.sideData.alpha,\n type,\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration,\n });\n }\n /** Converts this packet to an\n * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk) for use with the\n * WebCodecs API. */\n toEncodedAudioChunk() {\n if (this.isMetadataOnly) {\n throw new TypeError('Metadata-only packets cannot be converted to an audio chunk.');\n }\n if (typeof EncodedAudioChunk === 'undefined') {\n throw new Error('Your browser does not support EncodedAudioChunk.');\n }\n return new EncodedAudioChunk({\n data: this.data,\n type: this.type,\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration,\n });\n }\n /**\n * Creates an {@link EncodedPacket} from an\n * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) or\n * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk). This method is useful\n * for converting chunks from the WebCodecs API to `EncodedPacket` instances.\n */\n static fromEncodedChunk(chunk, sideData) {\n if (!(chunk instanceof EncodedVideoChunk || chunk instanceof EncodedAudioChunk)) {\n throw new TypeError('chunk must be an EncodedVideoChunk or EncodedAudioChunk.');\n }\n const data = new Uint8Array(chunk.byteLength);\n chunk.copyTo(data);\n return new EncodedPacket(data, chunk.type, chunk.timestamp / 1e6, (chunk.duration ?? 0) / 1e6, undefined, undefined, sideData);\n }\n /** Clones this packet while optionally updating timing information. */\n clone(options) {\n if (options !== undefined && (typeof options !== 'object' || options === null)) {\n throw new TypeError('options, when provided, must be an object.');\n }\n if (options?.timestamp !== undefined && !Number.isFinite(options.timestamp)) {\n throw new TypeError('options.timestamp, when provided, must be a number.');\n }\n if (options?.duration !== undefined && !Number.isFinite(options.duration)) {\n throw new TypeError('options.duration, when provided, must be a number.');\n }\n return new EncodedPacket(this.data, this.type, options?.timestamp ?? this.timestamp, options?.duration ?? this.duration, this.sequenceNumber, this.byteLength);\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\n// https://github.com/dystopiancode/pcm-g711/blob/master/pcm-g711/g711.c\nexport const toUlaw = (s16) => {\n const MULAW_MAX = 0x1FFF;\n const MULAW_BIAS = 33;\n let number = s16;\n let mask = 0x1000;\n let sign = 0;\n let position = 12;\n let lsb = 0;\n if (number < 0) {\n number = -number;\n sign = 0x80;\n }\n number += MULAW_BIAS;\n if (number > MULAW_MAX) {\n number = MULAW_MAX;\n }\n while ((number & mask) !== mask && position >= 5) {\n mask >>= 1;\n position--;\n }\n lsb = (number >> (position - 4)) & 0x0f;\n return ~(sign | ((position - 5) << 4) | lsb) & 0xFF;\n};\nexport const fromUlaw = (u8) => {\n const MULAW_BIAS = 33;\n let sign = 0;\n let position = 0;\n let number = ~u8;\n if (number & 0x80) {\n number &= ~(1 << 7);\n sign = -1;\n }\n position = ((number & 0xF0) >> 4) + 5;\n const decoded = ((1 << position) | ((number & 0x0F) << (position - 4))\n | (1 << (position - 5))) - MULAW_BIAS;\n return (sign === 0) ? decoded : -decoded;\n};\nexport const toAlaw = (s16) => {\n const ALAW_MAX = 0xFFF;\n let mask = 0x800;\n let sign = 0;\n let position = 11;\n let lsb = 0;\n let number = s16;\n if (number < 0) {\n number = -number;\n sign = 0x80;\n }\n if (number > ALAW_MAX) {\n number = ALAW_MAX;\n }\n while ((number & mask) !== mask && position >= 5) {\n mask >>= 1;\n position--;\n }\n lsb = (number >> ((position === 4) ? 1 : (position - 4))) & 0x0f;\n return (sign | ((position - 4) << 4) | lsb) ^ 0x55;\n};\nexport const fromAlaw = (u8) => {\n let sign = 0x00;\n let position = 0;\n let number = u8 ^ 0x55;\n if (number & 0x80) {\n number &= ~(1 << 7);\n sign = -1;\n }\n position = ((number & 0xF0) >> 4) + 4;\n let decoded = 0;\n if (position !== 4) {\n decoded = ((1 << position) | ((number & 0x0F) << (position - 4))\n | (1 << (position - 5)));\n }\n else {\n decoded = (number << 1) | 1;\n }\n return (sign === 0) ? decoded : -decoded;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { assert, clamp, isAllowSharedBufferSource, SECOND_TO_MICROSECOND_FACTOR, toDataView, toUint8Array, isFirefox, polyfillSymbolDispose, assertNever, isWebKit, } from './misc.js';\npolyfillSymbolDispose();\n// Let's manually handle logging the garbage collection errors that are typically logged by the browser. This way, they\n// also kick for audio samples (which is normally not the case), making sure any incorrect code is quickly caught.\nlet lastVideoGcErrorLog = -Infinity;\nlet lastAudioGcErrorLog = -Infinity;\nlet finalizationRegistry = null;\nif (typeof FinalizationRegistry !== 'undefined') {\n finalizationRegistry = new FinalizationRegistry((value) => {\n const now = Date.now();\n if (value.type === 'video') {\n if (now - lastVideoGcErrorLog >= 1000) {\n // This error is annoying but oh so important\n console.error(`A VideoSample was garbage collected without first being closed. For proper resource management,`\n + ` make sure to call close() on all your VideoSamples as soon as you're done using them.`);\n lastVideoGcErrorLog = now;\n }\n if (typeof VideoFrame !== 'undefined' && value.data instanceof VideoFrame) {\n value.data.close(); // Prevent the browser error since we're logging our own\n }\n }\n else {\n if (now - lastAudioGcErrorLog >= 1000) {\n console.error(`An AudioSample was garbage collected without first being closed. For proper resource management,`\n + ` make sure to call close() on all your AudioSamples as soon as you're done using them.`);\n lastAudioGcErrorLog = now;\n }\n if (typeof AudioData !== 'undefined' && value.data instanceof AudioData) {\n value.data.close();\n }\n }\n });\n}\n/**\n * The list of {@link VideoSample} pixel formats.\n * @group Samples\n * @public\n */\nexport const VIDEO_SAMPLE_PIXEL_FORMATS = [\n // 4:2:0 Y, U, V\n 'I420',\n 'I420P10',\n 'I420P12',\n // 4:2:0 Y, U, V, A\n 'I420A',\n 'I420AP10',\n 'I420AP12',\n // 4:2:2 Y, U, V\n 'I422',\n 'I422P10',\n 'I422P12',\n // 4:2:2 Y, U, V, A\n 'I422A',\n 'I422AP10',\n 'I422AP12',\n // 4:4:4 Y, U, V\n 'I444',\n 'I444P10',\n 'I444P12',\n // 4:4:4 Y, U, V, A\n 'I444A',\n 'I444AP10',\n 'I444AP12',\n // 4:2:0 Y, UV\n 'NV12',\n // 4:4:4 RGBA\n 'RGBA',\n // 4:4:4 RGBX (opaque)\n 'RGBX',\n // 4:4:4 BGRA\n 'BGRA',\n // 4:4:4 BGRX (opaque)\n 'BGRX',\n];\nconst VIDEO_SAMPLE_PIXEL_FORMATS_SET = new Set(VIDEO_SAMPLE_PIXEL_FORMATS);\n/**\n * Represents a raw, unencoded video sample (frame). Mainly used as an expressive wrapper around WebCodecs API's\n * [`VideoFrame`](https://developer.mozilla.org/en-US/docs/Web/API/VideoFrame), but can also be used standalone.\n * @group Samples\n * @public\n */\nexport class VideoSample {\n /** The width of the frame in pixels after rotation. */\n get displayWidth() {\n return this.rotation % 180 === 0 ? this.codedWidth : this.codedHeight;\n }\n /** The height of the frame in pixels after rotation. */\n get displayHeight() {\n return this.rotation % 180 === 0 ? this.codedHeight : this.codedWidth;\n }\n /** The presentation timestamp of the frame in microseconds. */\n get microsecondTimestamp() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);\n }\n /** The duration of the frame in microseconds. */\n get microsecondDuration() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);\n }\n /**\n * Whether this sample uses a pixel format that can hold transparency data. Note that this doesn't necessarily mean\n * that the sample is transparent.\n */\n get hasAlpha() {\n return this.format && this.format.includes('A');\n }\n constructor(data, init) {\n /** @internal */\n this._closed = false;\n if (data instanceof ArrayBuffer\n || (typeof SharedArrayBuffer !== 'undefined' && data instanceof SharedArrayBuffer)\n || ArrayBuffer.isView(data)) {\n if (!init || typeof init !== 'object') {\n throw new TypeError('init must be an object.');\n }\n if (init.format === undefined || !VIDEO_SAMPLE_PIXEL_FORMATS_SET.has(init.format)) {\n throw new TypeError('init.format must be one of: ' + VIDEO_SAMPLE_PIXEL_FORMATS.join(', '));\n }\n if (!Number.isInteger(init.codedWidth) || init.codedWidth <= 0) {\n throw new TypeError('init.codedWidth must be a positive integer.');\n }\n if (!Number.isInteger(init.codedHeight) || init.codedHeight <= 0) {\n throw new TypeError('init.codedHeight must be a positive integer.');\n }\n if (init.rotation !== undefined && ![0, 90, 180, 270].includes(init.rotation)) {\n throw new TypeError('init.rotation, when provided, must be 0, 90, 180, or 270.');\n }\n if (!Number.isFinite(init.timestamp)) {\n throw new TypeError('init.timestamp must be a number.');\n }\n if (init.duration !== undefined && (!Number.isFinite(init.duration) || init.duration < 0)) {\n throw new TypeError('init.duration, when provided, must be a non-negative number.');\n }\n this._data = toUint8Array(data).slice(); // Copy it\n this._layout = init.layout ?? createDefaultPlaneLayout(init.format, init.codedWidth, init.codedHeight);\n this.format = init.format;\n this.codedWidth = init.codedWidth;\n this.codedHeight = init.codedHeight;\n this.rotation = init.rotation ?? 0;\n this.timestamp = init.timestamp;\n this.duration = init.duration ?? 0;\n this.colorSpace = new VideoSampleColorSpace(init.colorSpace);\n }\n else if (typeof VideoFrame !== 'undefined' && data instanceof VideoFrame) {\n if (init?.rotation !== undefined && ![0, 90, 180, 270].includes(init.rotation)) {\n throw new TypeError('init.rotation, when provided, must be 0, 90, 180, or 270.');\n }\n if (init?.timestamp !== undefined && !Number.isFinite(init?.timestamp)) {\n throw new TypeError('init.timestamp, when provided, must be a number.');\n }\n if (init?.duration !== undefined && (!Number.isFinite(init.duration) || init.duration < 0)) {\n throw new TypeError('init.duration, when provided, must be a non-negative number.');\n }\n this._data = data;\n this._layout = null;\n this.format = data.format;\n // Copying the display dimensions here, assuming no innate VideoFrame rotation\n this.codedWidth = data.displayWidth;\n this.codedHeight = data.displayHeight;\n // The VideoFrame's rotation is ignored here. It's still a new field, and I'm not sure of any application\n // where the browser makes use of it. If a case gets found, I'll add it.\n this.rotation = init?.rotation ?? 0;\n this.timestamp = init?.timestamp ?? data.timestamp / 1e6;\n this.duration = init?.duration ?? (data.duration ?? 0) / 1e6;\n this.colorSpace = new VideoSampleColorSpace(data.colorSpace);\n }\n else if ((typeof HTMLImageElement !== 'undefined' && data instanceof HTMLImageElement)\n || (typeof SVGImageElement !== 'undefined' && data instanceof SVGImageElement)\n || (typeof ImageBitmap !== 'undefined' && data instanceof ImageBitmap)\n || (typeof HTMLVideoElement !== 'undefined' && data instanceof HTMLVideoElement)\n || (typeof HTMLCanvasElement !== 'undefined' && data instanceof HTMLCanvasElement)\n || (typeof OffscreenCanvas !== 'undefined' && data instanceof OffscreenCanvas)) {\n if (!init || typeof init !== 'object') {\n throw new TypeError('init must be an object.');\n }\n if (init.rotation !== undefined && ![0, 90, 180, 270].includes(init.rotation)) {\n throw new TypeError('init.rotation, when provided, must be 0, 90, 180, or 270.');\n }\n if (!Number.isFinite(init.timestamp)) {\n throw new TypeError('init.timestamp must be a number.');\n }\n if (init.duration !== undefined && (!Number.isFinite(init.duration) || init.duration < 0)) {\n throw new TypeError('init.duration, when provided, must be a non-negative number.');\n }\n if (typeof VideoFrame !== 'undefined') {\n return new VideoSample(new VideoFrame(data, {\n timestamp: Math.trunc(init.timestamp * SECOND_TO_MICROSECOND_FACTOR),\n // Drag 0 to undefined\n duration: Math.trunc((init.duration ?? 0) * SECOND_TO_MICROSECOND_FACTOR) || undefined,\n }), init);\n }\n let width = 0;\n let height = 0;\n // Determine the dimensions of the thing\n if ('naturalWidth' in data) {\n width = data.naturalWidth;\n height = data.naturalHeight;\n }\n else if ('videoWidth' in data) {\n width = data.videoWidth;\n height = data.videoHeight;\n }\n else if ('width' in data) {\n width = Number(data.width);\n height = Number(data.height);\n }\n if (!width || !height) {\n throw new TypeError('Could not determine dimensions.');\n }\n const canvas = new OffscreenCanvas(width, height);\n const context = canvas.getContext('2d', {\n alpha: isFirefox(), // Firefox has VideoFrame glitches with opaque canvases\n willReadFrequently: true,\n });\n assert(context);\n // Draw it to a canvas\n context.drawImage(data, 0, 0);\n this._data = canvas;\n this._layout = null;\n this.format = 'RGBX';\n this.codedWidth = width;\n this.codedHeight = height;\n this.rotation = init.rotation ?? 0;\n this.timestamp = init.timestamp;\n this.duration = init.duration ?? 0;\n this.colorSpace = new VideoSampleColorSpace({\n matrix: 'rgb',\n primaries: 'bt709',\n transfer: 'iec61966-2-1',\n fullRange: true,\n });\n }\n else {\n throw new TypeError('Invalid data type: Must be a BufferSource or CanvasImageSource.');\n }\n finalizationRegistry?.register(this, { type: 'video', data: this._data }, this);\n }\n /** Clones this video sample. */\n clone() {\n if (this._closed) {\n throw new Error('VideoSample is closed.');\n }\n assert(this._data !== null);\n if (isVideoFrame(this._data)) {\n return new VideoSample(this._data.clone(), {\n timestamp: this.timestamp,\n duration: this.duration,\n rotation: this.rotation,\n });\n }\n else if (this._data instanceof Uint8Array) {\n assert(this._layout);\n return new VideoSample(this._data, {\n format: this.format,\n layout: this._layout,\n codedWidth: this.codedWidth,\n codedHeight: this.codedHeight,\n timestamp: this.timestamp,\n duration: this.duration,\n colorSpace: this.colorSpace,\n rotation: this.rotation,\n });\n }\n else {\n return new VideoSample(this._data, {\n format: this.format,\n codedWidth: this.codedWidth,\n codedHeight: this.codedHeight,\n timestamp: this.timestamp,\n duration: this.duration,\n colorSpace: this.colorSpace,\n rotation: this.rotation,\n });\n }\n }\n /**\n * Closes this video sample, releasing held resources. Video samples should be closed as soon as they are not\n * needed anymore.\n */\n close() {\n if (this._closed) {\n return;\n }\n finalizationRegistry?.unregister(this);\n if (isVideoFrame(this._data)) {\n this._data.close();\n }\n else {\n this._data = null; // GC that shit\n }\n this._closed = true;\n }\n /**\n * Returns the number of bytes required to hold this video sample's pixel data. Throws if `format` is `null`;\n * specify an explicit RGB format in the options in this case.\n */\n allocationSize(options = {}) {\n validateVideoFrameCopyToOptions(options);\n if (this._closed) {\n throw new Error('VideoSample is closed.');\n }\n if ((options.format ?? this.format) === null) {\n throw new Error('Cannot get allocation size when format is null. Please manually provide an RGB pixel format in the'\n + ' options instead.');\n }\n assert(this._data !== null);\n if (!isVideoFrame(this._data)) {\n if (options.colorSpace\n || (options.format && options.format !== this.format)\n || options.layout\n || options.rect) {\n // Temporarily convert to VideoFrame to get it done\n const videoFrame = this.toVideoFrame();\n const size = videoFrame.allocationSize(options);\n videoFrame.close();\n return size;\n }\n }\n if (isVideoFrame(this._data)) {\n return this._data.allocationSize(options);\n }\n else if (this._data instanceof Uint8Array) {\n return this._data.byteLength;\n }\n else {\n return this.codedWidth * this.codedHeight * 4; // RGBX\n }\n }\n /**\n * Copies this video sample's pixel data to an ArrayBuffer or ArrayBufferView. Throws if `format` is `null`;\n * specify an explicit RGB format in the options in this case.\n * @returns The byte layout of the planes of the copied data.\n */\n async copyTo(destination, options = {}) {\n if (!isAllowSharedBufferSource(destination)) {\n throw new TypeError('destination must be an ArrayBuffer or an ArrayBuffer view.');\n }\n validateVideoFrameCopyToOptions(options);\n if (this._closed) {\n throw new Error('VideoSample is closed.');\n }\n if ((options.format ?? this.format) === null) {\n throw new Error('Cannot copy video sample data when format is null. Please manually provide an RGB pixel format in the'\n + ' options instead.');\n }\n assert(this._data !== null);\n if (!isVideoFrame(this._data)) {\n if (options.colorSpace\n || (options.format && options.format !== this.format)\n || options.layout\n || options.rect) {\n // Temporarily convert to VideoFrame to get it done\n const videoFrame = this.toVideoFrame();\n const layout = await videoFrame.copyTo(destination, options);\n videoFrame.close();\n return layout;\n }\n }\n if (isVideoFrame(this._data)) {\n return this._data.copyTo(destination, options);\n }\n else if (this._data instanceof Uint8Array) {\n assert(this._layout);\n const dest = toUint8Array(destination);\n dest.set(this._data);\n return this._layout;\n }\n else {\n const canvas = this._data;\n const context = canvas.getContext('2d');\n assert(context);\n const imageData = context.getImageData(0, 0, this.codedWidth, this.codedHeight);\n const dest = toUint8Array(destination);\n dest.set(imageData.data);\n return [{\n offset: 0,\n stride: 4 * this.codedWidth,\n }];\n }\n }\n /**\n * Converts this video sample to a VideoFrame for use with the WebCodecs API. The VideoFrame returned by this\n * method *must* be closed separately from this video sample.\n */\n toVideoFrame() {\n if (this._closed) {\n throw new Error('VideoSample is closed.');\n }\n assert(this._data !== null);\n if (isVideoFrame(this._data)) {\n return new VideoFrame(this._data, {\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration || undefined, // Drag 0 duration to undefined, glitches some codecs\n });\n }\n else if (this._data instanceof Uint8Array) {\n return new VideoFrame(this._data, {\n format: this.format,\n codedWidth: this.codedWidth,\n codedHeight: this.codedHeight,\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration || undefined,\n colorSpace: this.colorSpace,\n });\n }\n else {\n return new VideoFrame(this._data, {\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration || undefined,\n });\n }\n }\n draw(context, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) {\n let sx = 0;\n let sy = 0;\n let sWidth = this.displayWidth;\n let sHeight = this.displayHeight;\n let dx = 0;\n let dy = 0;\n let dWidth = this.displayWidth;\n let dHeight = this.displayHeight;\n if (arg5 !== undefined) {\n sx = arg1;\n sy = arg2;\n sWidth = arg3;\n sHeight = arg4;\n dx = arg5;\n dy = arg6;\n if (arg7 !== undefined) {\n dWidth = arg7;\n dHeight = arg8;\n }\n else {\n dWidth = sWidth;\n dHeight = sHeight;\n }\n }\n else {\n dx = arg1;\n dy = arg2;\n if (arg3 !== undefined) {\n dWidth = arg3;\n dHeight = arg4;\n }\n }\n if (!((typeof CanvasRenderingContext2D !== 'undefined' && context instanceof CanvasRenderingContext2D)\n || (typeof OffscreenCanvasRenderingContext2D !== 'undefined'\n && context instanceof OffscreenCanvasRenderingContext2D))) {\n throw new TypeError('context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.');\n }\n if (!Number.isFinite(sx)) {\n throw new TypeError('sx must be a number.');\n }\n if (!Number.isFinite(sy)) {\n throw new TypeError('sy must be a number.');\n }\n if (!Number.isFinite(sWidth) || sWidth < 0) {\n throw new TypeError('sWidth must be a non-negative number.');\n }\n if (!Number.isFinite(sHeight) || sHeight < 0) {\n throw new TypeError('sHeight must be a non-negative number.');\n }\n if (!Number.isFinite(dx)) {\n throw new TypeError('dx must be a number.');\n }\n if (!Number.isFinite(dy)) {\n throw new TypeError('dy must be a number.');\n }\n if (!Number.isFinite(dWidth) || dWidth < 0) {\n throw new TypeError('dWidth must be a non-negative number.');\n }\n if (!Number.isFinite(dHeight) || dHeight < 0) {\n throw new TypeError('dHeight must be a non-negative number.');\n }\n if (this._closed) {\n throw new Error('VideoSample is closed.');\n }\n ({ sx, sy, sWidth, sHeight } = this._rotateSourceRegion(sx, sy, sWidth, sHeight, this.rotation));\n const source = this.toCanvasImageSource();\n context.save();\n const centerX = dx + dWidth / 2;\n const centerY = dy + dHeight / 2;\n context.translate(centerX, centerY);\n context.rotate(this.rotation * Math.PI / 180);\n const aspectRatioChange = this.rotation % 180 === 0 ? 1 : dWidth / dHeight;\n // Scale to compensate for aspect ratio changes when rotated\n context.scale(1 / aspectRatioChange, aspectRatioChange);\n context.drawImage(source, sx, sy, sWidth, sHeight, -dWidth / 2, -dHeight / 2, dWidth, dHeight);\n context.restore();\n }\n /**\n * Draws the sample in the middle of the canvas corresponding to the context with the specified fit behavior.\n */\n drawWithFit(context, options) {\n if (!((typeof CanvasRenderingContext2D !== 'undefined' && context instanceof CanvasRenderingContext2D)\n || (typeof OffscreenCanvasRenderingContext2D !== 'undefined'\n && context instanceof OffscreenCanvasRenderingContext2D))) {\n throw new TypeError('context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.');\n }\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (!['fill', 'contain', 'cover'].includes(options.fit)) {\n throw new TypeError('options.fit must be \\'fill\\', \\'contain\\', or \\'cover\\'.');\n }\n if (options.rotation !== undefined && ![0, 90, 180, 270].includes(options.rotation)) {\n throw new TypeError('options.rotation, when provided, must be 0, 90, 180, or 270.');\n }\n if (options.crop !== undefined) {\n validateCropRectangle(options.crop, 'options.');\n }\n const canvasWidth = context.canvas.width;\n const canvasHeight = context.canvas.height;\n const rotation = options.rotation ?? this.rotation;\n const [rotatedWidth, rotatedHeight] = rotation % 180 === 0\n ? [this.codedWidth, this.codedHeight]\n : [this.codedHeight, this.codedWidth];\n if (options.crop) {\n clampCropRectangle(options.crop, rotatedWidth, rotatedHeight);\n }\n // These variables specify where the final sample will be drawn on the canvas\n let dx;\n let dy;\n let newWidth;\n let newHeight;\n const { sx, sy, sWidth, sHeight } = this._rotateSourceRegion(options.crop?.left ?? 0, options.crop?.top ?? 0, options.crop?.width ?? rotatedWidth, options.crop?.height ?? rotatedHeight, rotation);\n if (options.fit === 'fill') {\n dx = 0;\n dy = 0;\n newWidth = canvasWidth;\n newHeight = canvasHeight;\n }\n else {\n const [sampleWidth, sampleHeight] = options.crop\n ? [options.crop.width, options.crop.height]\n : [rotatedWidth, rotatedHeight];\n const scale = options.fit === 'contain'\n ? Math.min(canvasWidth / sampleWidth, canvasHeight / sampleHeight)\n : Math.max(canvasWidth / sampleWidth, canvasHeight / sampleHeight);\n newWidth = sampleWidth * scale;\n newHeight = sampleHeight * scale;\n dx = (canvasWidth - newWidth) / 2;\n dy = (canvasHeight - newHeight) / 2;\n }\n context.save();\n const aspectRatioChange = rotation % 180 === 0 ? 1 : newWidth / newHeight;\n context.translate(canvasWidth / 2, canvasHeight / 2);\n context.rotate(rotation * Math.PI / 180);\n // This aspect ratio compensation is done so that we can draw the sample with the intended dimensions and\n // don't need to think about how those dimensions change after the rotation\n context.scale(1 / aspectRatioChange, aspectRatioChange);\n context.translate(-canvasWidth / 2, -canvasHeight / 2);\n // Important that we don't use .draw() here since that would take rotation into account, but we wanna handle it\n // ourselves here\n context.drawImage(this.toCanvasImageSource(), sx, sy, sWidth, sHeight, dx, dy, newWidth, newHeight);\n context.restore();\n }\n /** @internal */\n _rotateSourceRegion(sx, sy, sWidth, sHeight, rotation) {\n // The provided sx,sy,sWidth,sHeight refer to the final rotated image, but that's not actually how the image is\n // stored. Therefore, we must map these back onto the original, pre-rotation image.\n if (rotation === 90) {\n [sx, sy, sWidth, sHeight] = [\n sy,\n this.codedHeight - sx - sWidth,\n sHeight,\n sWidth,\n ];\n }\n else if (rotation === 180) {\n [sx, sy] = [\n this.codedWidth - sx - sWidth,\n this.codedHeight - sy - sHeight,\n ];\n }\n else if (rotation === 270) {\n [sx, sy, sWidth, sHeight] = [\n this.codedWidth - sy - sHeight,\n sx,\n sHeight,\n sWidth,\n ];\n }\n return { sx, sy, sWidth, sHeight };\n }\n /**\n * Converts this video sample to a\n * [`CanvasImageSource`](https://udn.realityripple.com/docs/Web/API/CanvasImageSource) for drawing to a canvas.\n *\n * You must use the value returned by this method immediately, as any VideoFrame created internally will\n * automatically be closed in the next microtask.\n */\n toCanvasImageSource() {\n if (this._closed) {\n throw new Error('VideoSample is closed.');\n }\n assert(this._data !== null);\n if (this._data instanceof Uint8Array) {\n // Requires VideoFrame to be defined\n const videoFrame = this.toVideoFrame();\n queueMicrotask(() => videoFrame.close()); // Let's automatically close the frame in the next microtask\n return videoFrame;\n }\n else {\n return this._data;\n }\n }\n /** Sets the rotation metadata of this video sample. */\n setRotation(newRotation) {\n if (![0, 90, 180, 270].includes(newRotation)) {\n throw new TypeError('newRotation must be 0, 90, 180, or 270.');\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n this.rotation = newRotation;\n }\n /** Sets the presentation timestamp of this video sample, in seconds. */\n setTimestamp(newTimestamp) {\n if (!Number.isFinite(newTimestamp)) {\n throw new TypeError('newTimestamp must be a number.');\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n this.timestamp = newTimestamp;\n }\n /** Sets the duration of this video sample, in seconds. */\n setDuration(newDuration) {\n if (!Number.isFinite(newDuration) || newDuration < 0) {\n throw new TypeError('newDuration must be a non-negative number.');\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n this.duration = newDuration;\n }\n /** Calls `.close()`. */\n [Symbol.dispose]() {\n this.close();\n }\n}\n/**\n * Describes the color space of a {@link VideoSample}. Corresponds to the WebCodecs API's VideoColorSpace.\n * @group Samples\n * @public\n */\nexport class VideoSampleColorSpace {\n /** Creates a new VideoSampleColorSpace. */\n constructor(init) {\n this.primaries = init?.primaries ?? null;\n this.transfer = init?.transfer ?? null;\n this.matrix = init?.matrix ?? null;\n this.fullRange = init?.fullRange ?? null;\n }\n /** Serializes the color space to a JSON object. */\n toJSON() {\n return {\n primaries: this.primaries,\n transfer: this.transfer,\n matrix: this.matrix,\n fullRange: this.fullRange,\n };\n }\n}\nconst isVideoFrame = (x) => {\n return typeof VideoFrame !== 'undefined' && x instanceof VideoFrame;\n};\nexport const clampCropRectangle = (crop, outerWidth, outerHeight) => {\n crop.left = Math.min(crop.left, outerWidth);\n crop.top = Math.min(crop.top, outerHeight);\n crop.width = Math.min(crop.width, outerWidth - crop.left);\n crop.height = Math.min(crop.height, outerHeight - crop.top);\n assert(crop.width >= 0);\n assert(crop.height >= 0);\n};\nexport const validateCropRectangle = (crop, prefix) => {\n if (!crop || typeof crop !== 'object') {\n throw new TypeError(prefix + 'crop, when provided, must be an object.');\n }\n if (!Number.isInteger(crop.left) || crop.left < 0) {\n throw new TypeError(prefix + 'crop.left must be a non-negative integer.');\n }\n if (!Number.isInteger(crop.top) || crop.top < 0) {\n throw new TypeError(prefix + 'crop.top must be a non-negative integer.');\n }\n if (!Number.isInteger(crop.width) || crop.width < 0) {\n throw new TypeError(prefix + 'crop.width must be a non-negative integer.');\n }\n if (!Number.isInteger(crop.height) || crop.height < 0) {\n throw new TypeError(prefix + 'crop.height must be a non-negative integer.');\n }\n};\nconst validateVideoFrameCopyToOptions = (options) => {\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (options.colorSpace !== undefined && !['display-p3', 'srgb'].includes(options.colorSpace)) {\n throw new TypeError('options.colorSpace, when provided, must be \\'display-p3\\' or \\'srgb\\'.');\n }\n if (options.format !== undefined && typeof options.format !== 'string') {\n throw new TypeError('options.format, when provided, must be a string.');\n }\n if (options.layout !== undefined) {\n if (!Array.isArray(options.layout)) {\n throw new TypeError('options.layout, when provided, must be an array.');\n }\n for (const plane of options.layout) {\n if (!plane || typeof plane !== 'object') {\n throw new TypeError('Each entry in options.layout must be an object.');\n }\n if (!Number.isInteger(plane.offset) || plane.offset < 0) {\n throw new TypeError('plane.offset must be a non-negative integer.');\n }\n if (!Number.isInteger(plane.stride) || plane.stride < 0) {\n throw new TypeError('plane.stride must be a non-negative integer.');\n }\n }\n }\n if (options.rect !== undefined) {\n if (!options.rect || typeof options.rect !== 'object') {\n throw new TypeError('options.rect, when provided, must be an object.');\n }\n if (options.rect.x !== undefined && (!Number.isInteger(options.rect.x) || options.rect.x < 0)) {\n throw new TypeError('options.rect.x, when provided, must be a non-negative integer.');\n }\n if (options.rect.y !== undefined && (!Number.isInteger(options.rect.y) || options.rect.y < 0)) {\n throw new TypeError('options.rect.y, when provided, must be a non-negative integer.');\n }\n if (options.rect.width !== undefined && (!Number.isInteger(options.rect.width) || options.rect.width < 0)) {\n throw new TypeError('options.rect.width, when provided, must be a non-negative integer.');\n }\n if (options.rect.height !== undefined && (!Number.isInteger(options.rect.height) || options.rect.height < 0)) {\n throw new TypeError('options.rect.height, when provided, must be a non-negative integer.');\n }\n }\n};\n/** Implements logic from WebCodecs \u00A7 9.4.6 \"Compute Layout and Allocation Size\" */\nconst createDefaultPlaneLayout = (format, codedWidth, codedHeight) => {\n const planes = getPlaneConfigs(format);\n const layouts = [];\n let currentOffset = 0;\n for (const plane of planes) {\n // Per \u00A7 9.8, dimensions are usually \"rounded up to the nearest integer\".\n const planeWidth = Math.ceil(codedWidth / plane.widthDivisor);\n const planeHeight = Math.ceil(codedHeight / plane.heightDivisor);\n const stride = planeWidth * plane.sampleBytes;\n // Tight packing\n const planeSize = stride * planeHeight;\n layouts.push({\n offset: currentOffset,\n stride: stride,\n });\n currentOffset += planeSize;\n }\n return layouts;\n};\n/** Helper to retrieve plane configurations based on WebCodecs \u00A7 9.8 Pixel Format definitions. */\nconst getPlaneConfigs = (format) => {\n // Helper for standard YUV planes\n const yuv = (yBytes, uvBytes, subX, subY, hasAlpha) => {\n const configs = [\n { sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 },\n { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY },\n { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY },\n ];\n if (hasAlpha) {\n // Match luma dimensions\n configs.push({ sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 });\n }\n return configs;\n };\n switch (format) {\n case 'I420':\n return yuv(1, 1, 2, 2, false);\n case 'I420P10':\n case 'I420P12':\n return yuv(2, 2, 2, 2, false);\n case 'I420A':\n return yuv(1, 1, 2, 2, true);\n case 'I420AP10':\n case 'I420AP12':\n return yuv(2, 2, 2, 2, true);\n case 'I422':\n return yuv(1, 1, 2, 1, false);\n case 'I422P10':\n case 'I422P12':\n return yuv(2, 2, 2, 1, false);\n case 'I422A':\n return yuv(1, 1, 2, 1, true);\n case 'I422AP10':\n case 'I422AP12':\n return yuv(2, 2, 2, 1, true);\n case 'I444':\n return yuv(1, 1, 1, 1, false);\n case 'I444P10':\n case 'I444P12':\n return yuv(2, 2, 1, 1, false);\n case 'I444A':\n return yuv(1, 1, 1, 1, true);\n case 'I444AP10':\n case 'I444AP12':\n return yuv(2, 2, 1, 1, true);\n case 'NV12':\n return [\n { sampleBytes: 1, widthDivisor: 1, heightDivisor: 1 },\n { sampleBytes: 2, widthDivisor: 2, heightDivisor: 2 }, // Interleaved U and V\n ];\n case 'RGBA':\n case 'RGBX':\n case 'BGRA':\n case 'BGRX':\n return [\n { sampleBytes: 4, widthDivisor: 1, heightDivisor: 1 },\n ];\n default:\n assertNever(format);\n assert(false);\n }\n};\nconst AUDIO_SAMPLE_FORMATS = new Set(['f32', 'f32-planar', 's16', 's16-planar', 's32', 's32-planar', 'u8', 'u8-planar']);\n/**\n * Represents a raw, unencoded audio sample. Mainly used as an expressive wrapper around WebCodecs API's\n * [`AudioData`](https://developer.mozilla.org/en-US/docs/Web/API/AudioData), but can also be used standalone.\n * @group Samples\n * @public\n */\nexport class AudioSample {\n /** The presentation timestamp of the sample in microseconds. */\n get microsecondTimestamp() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);\n }\n /** The duration of the sample in microseconds. */\n get microsecondDuration() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);\n }\n /**\n * Creates a new {@link AudioSample}, either from an existing\n * [`AudioData`](https://developer.mozilla.org/en-US/docs/Web/API/AudioData) or from raw bytes specified in\n * {@link AudioSampleInit}.\n */\n constructor(init) {\n /** @internal */\n this._closed = false;\n if (isAudioData(init)) {\n if (init.format === null) {\n throw new TypeError('AudioData with null format is not supported.');\n }\n this._data = init;\n this.format = init.format;\n this.sampleRate = init.sampleRate;\n this.numberOfFrames = init.numberOfFrames;\n this.numberOfChannels = init.numberOfChannels;\n this.timestamp = init.timestamp / 1e6;\n this.duration = init.numberOfFrames / init.sampleRate;\n }\n else {\n if (!init || typeof init !== 'object') {\n throw new TypeError('Invalid AudioDataInit: must be an object.');\n }\n if (!AUDIO_SAMPLE_FORMATS.has(init.format)) {\n throw new TypeError('Invalid AudioDataInit: invalid format.');\n }\n if (!Number.isFinite(init.sampleRate) || init.sampleRate <= 0) {\n throw new TypeError('Invalid AudioDataInit: sampleRate must be > 0.');\n }\n if (!Number.isInteger(init.numberOfChannels) || init.numberOfChannels === 0) {\n throw new TypeError('Invalid AudioDataInit: numberOfChannels must be an integer > 0.');\n }\n if (!Number.isFinite(init?.timestamp)) {\n throw new TypeError('init.timestamp must be a number.');\n }\n const numberOfFrames = init.data.byteLength / (getBytesPerSample(init.format) * init.numberOfChannels);\n if (!Number.isInteger(numberOfFrames)) {\n throw new TypeError('Invalid AudioDataInit: data size is not a multiple of frame size.');\n }\n this.format = init.format;\n this.sampleRate = init.sampleRate;\n this.numberOfFrames = numberOfFrames;\n this.numberOfChannels = init.numberOfChannels;\n this.timestamp = init.timestamp;\n this.duration = numberOfFrames / init.sampleRate;\n let dataBuffer;\n if (init.data instanceof ArrayBuffer) {\n dataBuffer = new Uint8Array(init.data);\n }\n else if (ArrayBuffer.isView(init.data)) {\n dataBuffer = new Uint8Array(init.data.buffer, init.data.byteOffset, init.data.byteLength);\n }\n else {\n throw new TypeError('Invalid AudioDataInit: data is not a BufferSource.');\n }\n const expectedSize = this.numberOfFrames * this.numberOfChannels * getBytesPerSample(this.format);\n if (dataBuffer.byteLength < expectedSize) {\n throw new TypeError('Invalid AudioDataInit: insufficient data size.');\n }\n this._data = dataBuffer;\n }\n finalizationRegistry?.register(this, { type: 'audio', data: this._data }, this);\n }\n /** Returns the number of bytes required to hold the audio sample's data as specified by the given options. */\n allocationSize(options) {\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (!Number.isInteger(options.planeIndex) || options.planeIndex < 0) {\n throw new TypeError('planeIndex must be a non-negative integer.');\n }\n if (options.format !== undefined && !AUDIO_SAMPLE_FORMATS.has(options.format)) {\n throw new TypeError('Invalid format.');\n }\n if (options.frameOffset !== undefined && (!Number.isInteger(options.frameOffset) || options.frameOffset < 0)) {\n throw new TypeError('frameOffset must be a non-negative integer.');\n }\n if (options.frameCount !== undefined && (!Number.isInteger(options.frameCount) || options.frameCount < 0)) {\n throw new TypeError('frameCount must be a non-negative integer.');\n }\n if (this._closed) {\n throw new Error('AudioSample is closed.');\n }\n const destFormat = options.format ?? this.format;\n const frameOffset = options.frameOffset ?? 0;\n if (frameOffset >= this.numberOfFrames) {\n throw new RangeError('frameOffset out of range');\n }\n const copyFrameCount = options.frameCount !== undefined ? options.frameCount : (this.numberOfFrames - frameOffset);\n if (copyFrameCount > (this.numberOfFrames - frameOffset)) {\n throw new RangeError('frameCount out of range');\n }\n const bytesPerSample = getBytesPerSample(destFormat);\n const isPlanar = formatIsPlanar(destFormat);\n if (isPlanar && options.planeIndex >= this.numberOfChannels) {\n throw new RangeError('planeIndex out of range');\n }\n if (!isPlanar && options.planeIndex !== 0) {\n throw new RangeError('planeIndex out of range');\n }\n const elementCount = isPlanar ? copyFrameCount : copyFrameCount * this.numberOfChannels;\n return elementCount * bytesPerSample;\n }\n /** Copies the audio sample's data to an ArrayBuffer or ArrayBufferView as specified by the given options. */\n copyTo(destination, options) {\n if (!isAllowSharedBufferSource(destination)) {\n throw new TypeError('destination must be an ArrayBuffer or an ArrayBuffer view.');\n }\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (!Number.isInteger(options.planeIndex) || options.planeIndex < 0) {\n throw new TypeError('planeIndex must be a non-negative integer.');\n }\n if (options.format !== undefined && !AUDIO_SAMPLE_FORMATS.has(options.format)) {\n throw new TypeError('Invalid format.');\n }\n if (options.frameOffset !== undefined && (!Number.isInteger(options.frameOffset) || options.frameOffset < 0)) {\n throw new TypeError('frameOffset must be a non-negative integer.');\n }\n if (options.frameCount !== undefined && (!Number.isInteger(options.frameCount) || options.frameCount < 0)) {\n throw new TypeError('frameCount must be a non-negative integer.');\n }\n if (this._closed) {\n throw new Error('AudioSample is closed.');\n }\n const { planeIndex, format, frameCount: optFrameCount, frameOffset: optFrameOffset } = options;\n const srcFormat = this.format;\n const destFormat = format ?? this.format;\n if (!destFormat)\n throw new Error('Destination format not determined');\n const numFrames = this.numberOfFrames;\n const numChannels = this.numberOfChannels;\n const frameOffset = optFrameOffset ?? 0;\n if (frameOffset >= numFrames) {\n throw new RangeError('frameOffset out of range');\n }\n const copyFrameCount = optFrameCount !== undefined ? optFrameCount : (numFrames - frameOffset);\n if (copyFrameCount > (numFrames - frameOffset)) {\n throw new RangeError('frameCount out of range');\n }\n const destBytesPerSample = getBytesPerSample(destFormat);\n const destIsPlanar = formatIsPlanar(destFormat);\n if (destIsPlanar && planeIndex >= numChannels) {\n throw new RangeError('planeIndex out of range');\n }\n if (!destIsPlanar && planeIndex !== 0) {\n throw new RangeError('planeIndex out of range');\n }\n const destElementCount = destIsPlanar ? copyFrameCount : copyFrameCount * numChannels;\n const requiredSize = destElementCount * destBytesPerSample;\n if (destination.byteLength < requiredSize) {\n throw new RangeError('Destination buffer is too small');\n }\n const destView = toDataView(destination);\n const writeFn = getWriteFunction(destFormat);\n if (isAudioData(this._data)) {\n if (isWebKit() && numChannels > 2 && destFormat !== srcFormat) {\n // WebKit bug workaround\n doAudioDataCopyToWebKitWorkaround(this._data, destView, srcFormat, destFormat, numChannels, planeIndex, frameOffset, copyFrameCount);\n }\n else {\n // Per spec, only f32-planar conversion must be supported, but in practice, all browsers support all\n // destination formats, so let's just delegate here:\n this._data.copyTo(destination, {\n planeIndex,\n frameOffset,\n frameCount: copyFrameCount,\n format: destFormat,\n });\n }\n }\n else {\n const uint8Data = this._data;\n const srcView = toDataView(uint8Data);\n const readFn = getReadFunction(srcFormat);\n const srcBytesPerSample = getBytesPerSample(srcFormat);\n const srcIsPlanar = formatIsPlanar(srcFormat);\n for (let i = 0; i < copyFrameCount; i++) {\n if (destIsPlanar) {\n const destOffset = i * destBytesPerSample;\n let srcOffset;\n if (srcIsPlanar) {\n srcOffset = (planeIndex * numFrames + (i + frameOffset)) * srcBytesPerSample;\n }\n else {\n srcOffset = (((i + frameOffset) * numChannels) + planeIndex) * srcBytesPerSample;\n }\n const normalized = readFn(srcView, srcOffset);\n writeFn(destView, destOffset, normalized);\n }\n else {\n for (let ch = 0; ch < numChannels; ch++) {\n const destIndex = i * numChannels + ch;\n const destOffset = destIndex * destBytesPerSample;\n let srcOffset;\n if (srcIsPlanar) {\n srcOffset = (ch * numFrames + (i + frameOffset)) * srcBytesPerSample;\n }\n else {\n srcOffset = (((i + frameOffset) * numChannels) + ch) * srcBytesPerSample;\n }\n const normalized = readFn(srcView, srcOffset);\n writeFn(destView, destOffset, normalized);\n }\n }\n }\n }\n }\n /** Clones this audio sample. */\n clone() {\n if (this._closed) {\n throw new Error('AudioSample is closed.');\n }\n if (isAudioData(this._data)) {\n const sample = new AudioSample(this._data.clone());\n sample.setTimestamp(this.timestamp); // Make sure the timestamp is precise (beyond microsecond accuracy)\n return sample;\n }\n else {\n return new AudioSample({\n format: this.format,\n sampleRate: this.sampleRate,\n numberOfFrames: this.numberOfFrames,\n numberOfChannels: this.numberOfChannels,\n timestamp: this.timestamp,\n data: this._data,\n });\n }\n }\n /**\n * Closes this audio sample, releasing held resources. Audio samples should be closed as soon as they are not\n * needed anymore.\n */\n close() {\n if (this._closed) {\n return;\n }\n finalizationRegistry?.unregister(this);\n if (isAudioData(this._data)) {\n this._data.close();\n }\n else {\n this._data = new Uint8Array(0);\n }\n this._closed = true;\n }\n /**\n * Converts this audio sample to an AudioData for use with the WebCodecs API. The AudioData returned by this\n * method *must* be closed separately from this audio sample.\n */\n toAudioData() {\n if (this._closed) {\n throw new Error('AudioSample is closed.');\n }\n if (isAudioData(this._data)) {\n if (this._data.timestamp === this.microsecondTimestamp) {\n // Timestamp matches, let's just return the data (but cloned)\n return this._data.clone();\n }\n else {\n // It's impossible to simply change an AudioData's timestamp, so we'll need to create a new one\n if (formatIsPlanar(this.format)) {\n const size = this.allocationSize({ planeIndex: 0, format: this.format });\n const data = new ArrayBuffer(size * this.numberOfChannels);\n // We gotta read out each plane individually\n for (let i = 0; i < this.numberOfChannels; i++) {\n this.copyTo(new Uint8Array(data, i * size, size), { planeIndex: i, format: this.format });\n }\n return new AudioData({\n format: this.format,\n sampleRate: this.sampleRate,\n numberOfFrames: this.numberOfFrames,\n numberOfChannels: this.numberOfChannels,\n timestamp: this.microsecondTimestamp,\n data,\n });\n }\n else {\n const data = new ArrayBuffer(this.allocationSize({ planeIndex: 0, format: this.format }));\n this.copyTo(data, { planeIndex: 0, format: this.format });\n return new AudioData({\n format: this.format,\n sampleRate: this.sampleRate,\n numberOfFrames: this.numberOfFrames,\n numberOfChannels: this.numberOfChannels,\n timestamp: this.microsecondTimestamp,\n data,\n });\n }\n }\n }\n else {\n return new AudioData({\n format: this.format,\n sampleRate: this.sampleRate,\n numberOfFrames: this.numberOfFrames,\n numberOfChannels: this.numberOfChannels,\n timestamp: this.microsecondTimestamp,\n data: this._data.buffer instanceof ArrayBuffer\n ? this._data.buffer\n : this._data.slice(), // In the case of SharedArrayBuffer, convert to ArrayBuffer\n });\n }\n }\n /** Convert this audio sample to an AudioBuffer for use with the Web Audio API. */\n toAudioBuffer() {\n if (this._closed) {\n throw new Error('AudioSample is closed.');\n }\n const audioBuffer = new AudioBuffer({\n numberOfChannels: this.numberOfChannels,\n length: this.numberOfFrames,\n sampleRate: this.sampleRate,\n });\n const dataBytes = new Float32Array(this.allocationSize({ planeIndex: 0, format: 'f32-planar' }) / 4);\n for (let i = 0; i < this.numberOfChannels; i++) {\n this.copyTo(dataBytes, { planeIndex: i, format: 'f32-planar' });\n audioBuffer.copyToChannel(dataBytes, i);\n }\n return audioBuffer;\n }\n /** Sets the presentation timestamp of this audio sample, in seconds. */\n setTimestamp(newTimestamp) {\n if (!Number.isFinite(newTimestamp)) {\n throw new TypeError('newTimestamp must be a number.');\n }\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n this.timestamp = newTimestamp;\n }\n /** Calls `.close()`. */\n [Symbol.dispose]() {\n this.close();\n }\n /** @internal */\n static *_fromAudioBuffer(audioBuffer, timestamp) {\n if (!(audioBuffer instanceof AudioBuffer)) {\n throw new TypeError('audioBuffer must be an AudioBuffer.');\n }\n const MAX_FLOAT_COUNT = 48000 * 5; // 5 seconds of mono 48 kHz audio per sample\n const numberOfChannels = audioBuffer.numberOfChannels;\n const sampleRate = audioBuffer.sampleRate;\n const totalFrames = audioBuffer.length;\n const maxFramesPerChunk = Math.floor(MAX_FLOAT_COUNT / numberOfChannels);\n let currentRelativeFrame = 0;\n let remainingFrames = totalFrames;\n // Create AudioSamples in a chunked fashion so we don't create huge Float32Arrays\n while (remainingFrames > 0) {\n const framesToCopy = Math.min(maxFramesPerChunk, remainingFrames);\n const chunkData = new Float32Array(numberOfChannels * framesToCopy);\n for (let channel = 0; channel < numberOfChannels; channel++) {\n audioBuffer.copyFromChannel(chunkData.subarray(channel * framesToCopy, (channel + 1) * framesToCopy), channel, currentRelativeFrame);\n }\n yield new AudioSample({\n format: 'f32-planar',\n sampleRate,\n numberOfFrames: framesToCopy,\n numberOfChannels,\n timestamp: timestamp + currentRelativeFrame / sampleRate,\n data: chunkData,\n });\n currentRelativeFrame += framesToCopy;\n remainingFrames -= framesToCopy;\n }\n }\n /**\n * Creates AudioSamples from an AudioBuffer, starting at the given timestamp in seconds. Typically creates exactly\n * one sample, but may create multiple if the AudioBuffer is exceedingly large.\n */\n static fromAudioBuffer(audioBuffer, timestamp) {\n if (!(audioBuffer instanceof AudioBuffer)) {\n throw new TypeError('audioBuffer must be an AudioBuffer.');\n }\n const MAX_FLOAT_COUNT = 48000 * 5; // 5 seconds of mono 48 kHz audio per sample\n const numberOfChannels = audioBuffer.numberOfChannels;\n const sampleRate = audioBuffer.sampleRate;\n const totalFrames = audioBuffer.length;\n const maxFramesPerChunk = Math.floor(MAX_FLOAT_COUNT / numberOfChannels);\n let currentRelativeFrame = 0;\n let remainingFrames = totalFrames;\n const result = [];\n // Create AudioSamples in a chunked fashion so we don't create huge Float32Arrays\n while (remainingFrames > 0) {\n const framesToCopy = Math.min(maxFramesPerChunk, remainingFrames);\n const chunkData = new Float32Array(numberOfChannels * framesToCopy);\n for (let channel = 0; channel < numberOfChannels; channel++) {\n audioBuffer.copyFromChannel(chunkData.subarray(channel * framesToCopy, (channel + 1) * framesToCopy), channel, currentRelativeFrame);\n }\n const audioSample = new AudioSample({\n format: 'f32-planar',\n sampleRate,\n numberOfFrames: framesToCopy,\n numberOfChannels,\n timestamp: timestamp + currentRelativeFrame / sampleRate,\n data: chunkData,\n });\n result.push(audioSample);\n currentRelativeFrame += framesToCopy;\n remainingFrames -= framesToCopy;\n }\n return result;\n }\n}\nconst getBytesPerSample = (format) => {\n switch (format) {\n case 'u8':\n case 'u8-planar':\n return 1;\n case 's16':\n case 's16-planar':\n return 2;\n case 's32':\n case 's32-planar':\n return 4;\n case 'f32':\n case 'f32-planar':\n return 4;\n default:\n throw new Error('Unknown AudioSampleFormat');\n }\n};\nconst formatIsPlanar = (format) => {\n switch (format) {\n case 'u8-planar':\n case 's16-planar':\n case 's32-planar':\n case 'f32-planar':\n return true;\n default:\n return false;\n }\n};\nconst getReadFunction = (format) => {\n switch (format) {\n case 'u8':\n case 'u8-planar':\n return (view, offset) => (view.getUint8(offset) - 128) / 128;\n case 's16':\n case 's16-planar':\n return (view, offset) => view.getInt16(offset, true) / 32768;\n case 's32':\n case 's32-planar':\n return (view, offset) => view.getInt32(offset, true) / 2147483648;\n case 'f32':\n case 'f32-planar':\n return (view, offset) => view.getFloat32(offset, true);\n }\n};\nconst getWriteFunction = (format) => {\n switch (format) {\n case 'u8':\n case 'u8-planar':\n return (view, offset, value) => view.setUint8(offset, clamp((value + 1) * 127.5, 0, 255));\n case 's16':\n case 's16-planar':\n return (view, offset, value) => view.setInt16(offset, clamp(Math.round(value * 32767), -32768, 32767), true);\n case 's32':\n case 's32-planar':\n return (view, offset, value) => view.setInt32(offset, clamp(Math.round(value * 2147483647), -2147483648, 2147483647), true);\n case 'f32':\n case 'f32-planar':\n return (view, offset, value) => view.setFloat32(offset, value, true);\n }\n};\nconst isAudioData = (x) => {\n return typeof AudioData !== 'undefined' && x instanceof AudioData;\n};\n/**\n * WebKit has a bug where calling AudioData.copyTo with a format different from the source format\n * crashes the tab when there are more than 2 channels. This function works around that by always\n * copying with the source format and then manually converting to the destination format.\n *\n * See https://bugs.webkit.org/show_bug.cgi?id=302521.\n */\nconst doAudioDataCopyToWebKitWorkaround = (audioData, destView, srcFormat, destFormat, numChannels, planeIndex, frameOffset, copyFrameCount) => {\n const readFn = getReadFunction(srcFormat);\n const writeFn = getWriteFunction(destFormat);\n const srcBytesPerSample = getBytesPerSample(srcFormat);\n const destBytesPerSample = getBytesPerSample(destFormat);\n const srcIsPlanar = formatIsPlanar(srcFormat);\n const destIsPlanar = formatIsPlanar(destFormat);\n if (destIsPlanar) {\n if (srcIsPlanar) {\n // src planar -> dest planar: copy single plane and convert\n const data = new ArrayBuffer(copyFrameCount * srcBytesPerSample);\n const dataView = toDataView(data);\n audioData.copyTo(data, {\n planeIndex,\n frameOffset,\n frameCount: copyFrameCount,\n format: srcFormat,\n });\n for (let i = 0; i < copyFrameCount; i++) {\n const srcOffset = i * srcBytesPerSample;\n const destOffset = i * destBytesPerSample;\n const sample = readFn(dataView, srcOffset);\n writeFn(destView, destOffset, sample);\n }\n }\n else {\n // src interleaved -> dest planar: copy all interleaved data, extract one channel\n const data = new ArrayBuffer(copyFrameCount * numChannels * srcBytesPerSample);\n const dataView = toDataView(data);\n audioData.copyTo(data, {\n planeIndex: 0,\n frameOffset,\n frameCount: copyFrameCount,\n format: srcFormat,\n });\n for (let i = 0; i < copyFrameCount; i++) {\n const srcOffset = (i * numChannels + planeIndex) * srcBytesPerSample;\n const destOffset = i * destBytesPerSample;\n const sample = readFn(dataView, srcOffset);\n writeFn(destView, destOffset, sample);\n }\n }\n }\n else {\n if (srcIsPlanar) {\n // src planar -> dest interleaved: copy each plane and interleave\n const planeSize = copyFrameCount * srcBytesPerSample;\n const data = new ArrayBuffer(planeSize);\n const dataView = toDataView(data);\n for (let ch = 0; ch < numChannels; ch++) {\n audioData.copyTo(data, {\n planeIndex: ch,\n frameOffset,\n frameCount: copyFrameCount,\n format: srcFormat,\n });\n for (let i = 0; i < copyFrameCount; i++) {\n const srcOffset = i * srcBytesPerSample;\n const destOffset = (i * numChannels + ch) * destBytesPerSample;\n const sample = readFn(dataView, srcOffset);\n writeFn(destView, destOffset, sample);\n }\n }\n }\n else {\n // src interleaved -> dest interleaved: copy all and convert\n const data = new ArrayBuffer(copyFrameCount * numChannels * srcBytesPerSample);\n const dataView = toDataView(data);\n audioData.copyTo(data, {\n planeIndex: 0,\n frameOffset,\n frameCount: copyFrameCount,\n format: srcFormat,\n });\n for (let i = 0; i < copyFrameCount; i++) {\n for (let ch = 0; ch < numChannels; ch++) {\n const idx = i * numChannels + ch;\n const srcOffset = idx * srcBytesPerSample;\n const destOffset = idx * destBytesPerSample;\n const sample = readFn(dataView, srcOffset);\n writeFn(destView, destOffset, sample);\n }\n }\n }\n }\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { parsePcmCodec, PCM_AUDIO_CODECS } from './codec.js';\nimport { concatAvcNalUnits, deserializeAvcDecoderConfigurationRecord, determineVideoPacketType, extractAvcNalUnits, extractHevcNalUnits, extractNalUnitTypeForAvc, extractNalUnitTypeForHevc, HevcNalUnitType, parseAvcSps, } from './codec-data.js';\nimport { customVideoDecoders, customAudioDecoders } from './custom-coder.js';\nimport { InputDisposedError } from './input.js';\nimport { InputAudioTrack, InputTrack, InputVideoTrack } from './input-track.js';\nimport { assert, assertNever, CallSerializer, getInt24, getUint24, insertSorted, isChromium, isFirefox, isNumber, isWebKit, last, mapAsyncGenerator, promiseWithResolvers, toAsyncIterator, toDataView, toUint8Array, validateAnyIterable, } from './misc.js';\nimport { EncodedPacket } from './packet.js';\nimport { fromAlaw, fromUlaw } from './pcm.js';\nimport { AudioSample, clampCropRectangle, validateCropRectangle, VideoSample } from './sample.js';\nconst validatePacketRetrievalOptions = (options) => {\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (options.metadataOnly !== undefined && typeof options.metadataOnly !== 'boolean') {\n throw new TypeError('options.metadataOnly, when defined, must be a boolean.');\n }\n if (options.verifyKeyPackets !== undefined && typeof options.verifyKeyPackets !== 'boolean') {\n throw new TypeError('options.verifyKeyPackets, when defined, must be a boolean.');\n }\n if (options.verifyKeyPackets && options.metadataOnly) {\n throw new TypeError('options.verifyKeyPackets and options.metadataOnly cannot be enabled together.');\n }\n};\nconst validateTimestamp = (timestamp) => {\n if (!isNumber(timestamp)) {\n throw new TypeError('timestamp must be a number.'); // It can be non-finite, that's fine\n }\n};\nconst maybeFixPacketType = (track, promise, options) => {\n if (options.verifyKeyPackets) {\n return promise.then(async (packet) => {\n if (!packet || packet.type === 'delta') {\n return packet;\n }\n const determinedType = await track.determinePacketType(packet);\n if (determinedType) {\n // @ts-expect-error Technically readonly\n packet.type = determinedType;\n }\n return packet;\n });\n }\n else {\n return promise;\n }\n};\n/**\n * Sink for retrieving encoded packets from an input track.\n * @group Media sinks\n * @public\n */\nexport class EncodedPacketSink {\n /** Creates a new {@link EncodedPacketSink} for the given {@link InputTrack}. */\n constructor(track) {\n if (!(track instanceof InputTrack)) {\n throw new TypeError('track must be an InputTrack.');\n }\n this._track = track;\n }\n /**\n * Retrieves the track's first packet (in decode order), or null if it has no packets. The first packet is very\n * likely to be a key packet.\n */\n getFirstPacket(options = {}) {\n validatePacketRetrievalOptions(options);\n if (this._track.input._disposed) {\n throw new InputDisposedError();\n }\n return maybeFixPacketType(this._track, this._track._backing.getFirstPacket(options), options);\n }\n /**\n * Retrieves the packet corresponding to the given timestamp, in seconds. More specifically, returns the last packet\n * (in presentation order) with a start timestamp less than or equal to the given timestamp. This method can be\n * used to retrieve a track's last packet using `getPacket(Infinity)`. The method returns null if the timestamp\n * is before the first packet in the track.\n *\n * @param timestamp - The timestamp used for retrieval, in seconds.\n */\n getPacket(timestamp, options = {}) {\n validateTimestamp(timestamp);\n validatePacketRetrievalOptions(options);\n if (this._track.input._disposed) {\n throw new InputDisposedError();\n }\n return maybeFixPacketType(this._track, this._track._backing.getPacket(timestamp, options), options);\n }\n /**\n * Retrieves the packet following the given packet (in decode order), or null if the given packet is the\n * last packet.\n */\n getNextPacket(packet, options = {}) {\n if (!(packet instanceof EncodedPacket)) {\n throw new TypeError('packet must be an EncodedPacket.');\n }\n validatePacketRetrievalOptions(options);\n if (this._track.input._disposed) {\n throw new InputDisposedError();\n }\n return maybeFixPacketType(this._track, this._track._backing.getNextPacket(packet, options), options);\n }\n /**\n * Retrieves the key packet corresponding to the given timestamp, in seconds. More specifically, returns the last\n * key packet (in presentation order) with a start timestamp less than or equal to the given timestamp. A key packet\n * is a packet that doesn't require previous packets to be decoded. This method can be used to retrieve a track's\n * last key packet using `getKeyPacket(Infinity)`. The method returns null if the timestamp is before the first\n * key packet in the track.\n *\n * To ensure that the returned packet is guaranteed to be a real key frame, enable `options.verifyKeyPackets`.\n *\n * @param timestamp - The timestamp used for retrieval, in seconds.\n */\n async getKeyPacket(timestamp, options = {}) {\n validateTimestamp(timestamp);\n validatePacketRetrievalOptions(options);\n if (this._track.input._disposed) {\n throw new InputDisposedError();\n }\n if (!options.verifyKeyPackets) {\n return this._track._backing.getKeyPacket(timestamp, options);\n }\n const packet = await this._track._backing.getKeyPacket(timestamp, options);\n if (!packet) {\n return packet;\n }\n assert(packet.type === 'key');\n const determinedType = await this._track.determinePacketType(packet);\n if (determinedType === 'delta') {\n // Try returning the previous key packet (in hopes that it's actually a key packet)\n return this.getKeyPacket(packet.timestamp - 1 / this._track.timeResolution, options);\n }\n return packet;\n }\n /**\n * Retrieves the key packet following the given packet (in decode order), or null if the given packet is the last\n * key packet.\n *\n * To ensure that the returned packet is guaranteed to be a real key frame, enable `options.verifyKeyPackets`.\n */\n async getNextKeyPacket(packet, options = {}) {\n if (!(packet instanceof EncodedPacket)) {\n throw new TypeError('packet must be an EncodedPacket.');\n }\n validatePacketRetrievalOptions(options);\n if (this._track.input._disposed) {\n throw new InputDisposedError();\n }\n if (!options.verifyKeyPackets) {\n return this._track._backing.getNextKeyPacket(packet, options);\n }\n const nextPacket = await this._track._backing.getNextKeyPacket(packet, options);\n if (!nextPacket) {\n return nextPacket;\n }\n assert(nextPacket.type === 'key');\n const determinedType = await this._track.determinePacketType(nextPacket);\n if (determinedType === 'delta') {\n // Try returning the next key packet (in hopes that it's actually a key packet)\n return this.getNextKeyPacket(nextPacket, options);\n }\n return nextPacket;\n }\n /**\n * Creates an async iterator that yields the packets in this track in decode order. To enable fast iteration, this\n * method will intelligently preload packets based on the speed of the consumer.\n *\n * @param startPacket - (optional) The packet from which iteration should begin. This packet will also be yielded.\n * @param endTimestamp - (optional) The timestamp at which iteration should end. This packet will _not_ be yielded.\n */\n packets(startPacket, endPacket, options = {}) {\n if (startPacket !== undefined && !(startPacket instanceof EncodedPacket)) {\n throw new TypeError('startPacket must be an EncodedPacket.');\n }\n if (startPacket !== undefined && startPacket.isMetadataOnly && !options?.metadataOnly) {\n throw new TypeError('startPacket can only be metadata-only if options.metadataOnly is enabled.');\n }\n if (endPacket !== undefined && !(endPacket instanceof EncodedPacket)) {\n throw new TypeError('endPacket must be an EncodedPacket.');\n }\n validatePacketRetrievalOptions(options);\n if (this._track.input._disposed) {\n throw new InputDisposedError();\n }\n const packetQueue = [];\n let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers();\n let { promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers();\n let ended = false;\n let terminated = false;\n // This stores errors that are \"out of band\" in the sense that they didn't occur in the normal flow of this\n // method but instead in a different context. This error should not go unnoticed and must be bubbled up to\n // the consumer.\n let outOfBandError = null;\n const timestamps = [];\n // The queue should always be big enough to hold 1 second worth of packets\n const maxQueueSize = () => Math.max(2, timestamps.length);\n // The following is the \"pump\" process that keeps pumping packets into the queue\n (async () => {\n let packet = startPacket ?? await this.getFirstPacket(options);\n while (packet && !terminated && !this._track.input._disposed) {\n if (endPacket && packet.sequenceNumber >= endPacket?.sequenceNumber) {\n break;\n }\n if (packetQueue.length > maxQueueSize()) {\n ({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());\n await queueDequeue;\n continue;\n }\n packetQueue.push(packet);\n onQueueNotEmpty();\n ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers());\n packet = await this.getNextPacket(packet, options);\n }\n ended = true;\n onQueueNotEmpty();\n })().catch((error) => {\n if (!outOfBandError) {\n outOfBandError = error;\n onQueueNotEmpty();\n }\n });\n const track = this._track;\n return {\n async next() {\n while (true) {\n if (track.input._disposed) {\n throw new InputDisposedError();\n }\n else if (terminated) {\n return { value: undefined, done: true };\n }\n else if (outOfBandError) {\n throw outOfBandError;\n }\n else if (packetQueue.length > 0) {\n const value = packetQueue.shift();\n const now = performance.now();\n timestamps.push(now);\n while (timestamps.length > 0 && now - timestamps[0] >= 1000) {\n timestamps.shift();\n }\n onQueueDequeue();\n return { value, done: false };\n }\n else if (ended) {\n return { value: undefined, done: true };\n }\n else {\n await queueNotEmpty;\n }\n }\n },\n async return() {\n terminated = true;\n onQueueDequeue();\n onQueueNotEmpty();\n return { value: undefined, done: true };\n },\n async throw(error) {\n throw error;\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n }\n}\nclass DecoderWrapper {\n constructor(onSample, onError) {\n this.onSample = onSample;\n this.onError = onError;\n }\n}\n/**\n * Base class for decoded media sample sinks.\n * @group Media sinks\n * @public\n */\nexport class BaseMediaSampleSink {\n /** @internal */\n mediaSamplesInRange(startTimestamp = 0, endTimestamp = Infinity) {\n validateTimestamp(startTimestamp);\n validateTimestamp(endTimestamp);\n const sampleQueue = [];\n let firstSampleQueued = false;\n let lastSample = null;\n let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers();\n let { promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers();\n let decoderIsFlushed = false;\n let ended = false;\n let terminated = false;\n // This stores errors that are \"out of band\" in the sense that they didn't occur in the normal flow of this\n // method but instead in a different context. This error should not go unnoticed and must be bubbled up to\n // the consumer.\n let outOfBandError = null;\n // The following is the \"pump\" process that keeps pumping packets into the decoder\n (async () => {\n const decoder = await this._createDecoder((sample) => {\n onQueueDequeue();\n if (sample.timestamp >= endTimestamp) {\n ended = true;\n }\n if (ended) {\n sample.close();\n return;\n }\n if (lastSample) {\n if (sample.timestamp > startTimestamp) {\n // We don't know ahead of time what the first first is. This is because the first first is the\n // last first whose timestamp is less than or equal to the start timestamp. Therefore we need to\n // wait for the first first after the start timestamp, and then we'll know that the previous\n // first was the first first.\n sampleQueue.push(lastSample);\n firstSampleQueued = true;\n }\n else {\n lastSample.close();\n }\n }\n if (sample.timestamp >= startTimestamp) {\n sampleQueue.push(sample);\n firstSampleQueued = true;\n }\n lastSample = firstSampleQueued ? null : sample;\n if (sampleQueue.length > 0) {\n onQueueNotEmpty();\n ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers());\n }\n }, (error) => {\n if (!outOfBandError) {\n outOfBandError = error;\n onQueueNotEmpty();\n }\n });\n const packetSink = this._createPacketSink();\n const keyPacket = await packetSink.getKeyPacket(startTimestamp, { verifyKeyPackets: true })\n ?? await packetSink.getFirstPacket();\n let currentPacket = keyPacket;\n let endPacket = undefined;\n if (endTimestamp < Infinity) {\n // When an end timestamp is set, we cannot simply use that for the packet iterator due to out-of-order\n // frames (B-frames). Instead, we'll need to keep decoding packets until we get a frame that exceeds\n // this end time. However, we can still put a bound on it: Since key frames are by definition never\n // out of order, we can stop at the first key frame after the end timestamp.\n const packet = await packetSink.getPacket(endTimestamp);\n const keyPacket = !packet\n ? null\n : packet.type === 'key' && packet.timestamp === endTimestamp\n ? packet\n : await packetSink.getNextKeyPacket(packet, { verifyKeyPackets: true });\n if (keyPacket) {\n endPacket = keyPacket;\n }\n }\n const packets = packetSink.packets(keyPacket ?? undefined, endPacket);\n await packets.next(); // Skip the start packet as we already have it\n while (currentPacket && !ended && !this._track.input._disposed) {\n const maxQueueSize = computeMaxQueueSize(sampleQueue.length);\n if (sampleQueue.length + decoder.getDecodeQueueSize() > maxQueueSize) {\n ({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());\n await queueDequeue;\n continue;\n }\n decoder.decode(currentPacket);\n const packetResult = await packets.next();\n if (packetResult.done) {\n break;\n }\n currentPacket = packetResult.value;\n }\n await packets.return();\n if (!terminated && !this._track.input._disposed) {\n await decoder.flush();\n }\n decoder.close();\n if (!firstSampleQueued && lastSample) {\n sampleQueue.push(lastSample);\n }\n decoderIsFlushed = true;\n onQueueNotEmpty(); // To unstuck the generator\n })().catch((error) => {\n if (!outOfBandError) {\n outOfBandError = error;\n onQueueNotEmpty();\n }\n });\n const track = this._track;\n const closeSamples = () => {\n lastSample?.close();\n for (const sample of sampleQueue) {\n sample.close();\n }\n };\n return {\n async next() {\n while (true) {\n if (track.input._disposed) {\n closeSamples();\n throw new InputDisposedError();\n }\n else if (terminated) {\n return { value: undefined, done: true };\n }\n else if (outOfBandError) {\n closeSamples();\n throw outOfBandError;\n }\n else if (sampleQueue.length > 0) {\n const value = sampleQueue.shift();\n onQueueDequeue();\n return { value, done: false };\n }\n else if (!decoderIsFlushed) {\n await queueNotEmpty;\n }\n else {\n return { value: undefined, done: true };\n }\n }\n },\n async return() {\n terminated = true;\n ended = true;\n onQueueDequeue();\n onQueueNotEmpty();\n closeSamples();\n return { value: undefined, done: true };\n },\n async throw(error) {\n throw error;\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n }\n /** @internal */\n mediaSamplesAtTimestamps(timestamps) {\n validateAnyIterable(timestamps);\n const timestampIterator = toAsyncIterator(timestamps);\n const timestampsOfInterest = [];\n const sampleQueue = [];\n let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers();\n let { promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers();\n let decoderIsFlushed = false;\n let terminated = false;\n // This stores errors that are \"out of band\" in the sense that they didn't occur in the normal flow of this\n // method but instead in a different context. This error should not go unnoticed and must be bubbled up to\n // the consumer.\n let outOfBandError = null;\n const pushToQueue = (sample) => {\n sampleQueue.push(sample);\n onQueueNotEmpty();\n ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers());\n };\n // The following is the \"pump\" process that keeps pumping packets into the decoder\n (async () => {\n const decoder = await this._createDecoder((sample) => {\n onQueueDequeue();\n if (terminated) {\n sample.close();\n return;\n }\n let sampleUses = 0;\n while (timestampsOfInterest.length > 0\n && sample.timestamp - timestampsOfInterest[0] > -1e-10 // Give it a little epsilon\n ) {\n sampleUses++;\n timestampsOfInterest.shift();\n }\n if (sampleUses > 0) {\n for (let i = 0; i < sampleUses; i++) {\n // Clone the sample if we need to emit it multiple times\n pushToQueue((i < sampleUses - 1 ? sample.clone() : sample));\n }\n }\n else {\n sample.close();\n }\n }, (error) => {\n if (!outOfBandError) {\n outOfBandError = error;\n onQueueNotEmpty();\n }\n });\n const packetSink = this._createPacketSink();\n let lastPacket = null;\n let lastKeyPacket = null;\n // The end sequence number (inclusive) in the next batch of packets that will be decoded. The batch starts\n // at the last key frame and goes until this sequence number.\n let maxSequenceNumber = -1;\n const decodePackets = async () => {\n assert(lastKeyPacket);\n // Start at the current key packet\n let currentPacket = lastKeyPacket;\n decoder.decode(currentPacket);\n while (currentPacket.sequenceNumber < maxSequenceNumber) {\n const maxQueueSize = computeMaxQueueSize(sampleQueue.length);\n while (sampleQueue.length + decoder.getDecodeQueueSize() > maxQueueSize && !terminated) {\n ({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());\n await queueDequeue;\n }\n if (terminated) {\n break;\n }\n const nextPacket = await packetSink.getNextPacket(currentPacket);\n assert(nextPacket);\n decoder.decode(nextPacket);\n currentPacket = nextPacket;\n }\n maxSequenceNumber = -1;\n };\n const flushDecoder = async () => {\n await decoder.flush();\n // We don't expect this list to have any elements in it anymore, but in case it does, let's emit\n // nulls for every remaining element, then clear it.\n for (let i = 0; i < timestampsOfInterest.length; i++) {\n pushToQueue(null);\n }\n timestampsOfInterest.length = 0;\n };\n for await (const timestamp of timestampIterator) {\n validateTimestamp(timestamp);\n if (terminated || this._track.input._disposed) {\n break;\n }\n const targetPacket = await packetSink.getPacket(timestamp);\n const keyPacket = targetPacket && await packetSink.getKeyPacket(timestamp, { verifyKeyPackets: true });\n if (!keyPacket) {\n if (maxSequenceNumber !== -1) {\n await decodePackets();\n await flushDecoder();\n }\n pushToQueue(null);\n lastPacket = null;\n continue;\n }\n // Check if the key packet has changed or if we're going back in time\n if (lastPacket\n && (keyPacket.sequenceNumber !== lastKeyPacket.sequenceNumber\n || targetPacket.timestamp < lastPacket.timestamp)) {\n await decodePackets();\n await flushDecoder(); // Always flush here, improves decoder compatibility\n }\n timestampsOfInterest.push(targetPacket.timestamp);\n maxSequenceNumber = Math.max(targetPacket.sequenceNumber, maxSequenceNumber);\n lastPacket = targetPacket;\n lastKeyPacket = keyPacket;\n }\n if (!terminated && !this._track.input._disposed) {\n if (maxSequenceNumber !== -1) {\n // We still need to decode packets\n await decodePackets();\n }\n await flushDecoder();\n }\n decoder.close();\n decoderIsFlushed = true;\n onQueueNotEmpty(); // To unstuck the generator\n })().catch((error) => {\n if (!outOfBandError) {\n outOfBandError = error;\n onQueueNotEmpty();\n }\n });\n const track = this._track;\n const closeSamples = () => {\n for (const sample of sampleQueue) {\n sample?.close();\n }\n };\n return {\n async next() {\n while (true) {\n if (track.input._disposed) {\n closeSamples();\n throw new InputDisposedError();\n }\n else if (terminated) {\n return { value: undefined, done: true };\n }\n else if (outOfBandError) {\n closeSamples();\n throw outOfBandError;\n }\n else if (sampleQueue.length > 0) {\n const value = sampleQueue.shift();\n assert(value !== undefined);\n onQueueDequeue();\n return { value, done: false };\n }\n else if (!decoderIsFlushed) {\n await queueNotEmpty;\n }\n else {\n return { value: undefined, done: true };\n }\n }\n },\n async return() {\n terminated = true;\n onQueueDequeue();\n onQueueNotEmpty();\n closeSamples();\n return { value: undefined, done: true };\n },\n async throw(error) {\n throw error;\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n };\n }\n}\nconst computeMaxQueueSize = (decodedSampleQueueSize) => {\n // If we have decoded samples lying around, limit the total queue size to a small value (decoded samples can use up\n // a lot of memory). If not, we're fine with a much bigger queue of encoded packets waiting to be decoded. In fact,\n // some decoders only start flushing out decoded chunks when the packet queue is large enough.\n return decodedSampleQueueSize === 0 ? 40 : 8;\n};\nclass VideoDecoderWrapper extends DecoderWrapper {\n constructor(onSample, onError, codec, decoderConfig, rotation, timeResolution) {\n super(onSample, onError);\n this.codec = codec;\n this.decoderConfig = decoderConfig;\n this.rotation = rotation;\n this.timeResolution = timeResolution;\n this.decoder = null;\n this.customDecoder = null;\n this.customDecoderCallSerializer = new CallSerializer();\n this.customDecoderQueueSize = 0;\n this.inputTimestamps = []; // Timestamps input into the decoder, sorted.\n this.sampleQueue = []; // Safari-specific thing, check usage.\n this.currentPacketIndex = 0;\n this.raslSkipped = false; // For HEVC stuff\n // Alpha stuff\n this.alphaDecoder = null;\n this.alphaHadKeyframe = false;\n this.colorQueue = [];\n this.alphaQueue = [];\n this.merger = null;\n this.mergerCreationFailed = false;\n this.decodedAlphaChunkCount = 0;\n this.alphaDecoderQueueSize = 0;\n /** Each value is the number of decoded alpha chunks at which a null alpha frame should be added. */\n this.nullAlphaFrameQueue = [];\n this.currentAlphaPacketIndex = 0;\n this.alphaRaslSkipped = false; // For HEVC stuff\n const MatchingCustomDecoder = customVideoDecoders.find(x => x.supports(codec, decoderConfig));\n if (MatchingCustomDecoder) {\n // @ts-expect-error \"Can't create instance of abstract class \uD83E\uDD13\"\n this.customDecoder = new MatchingCustomDecoder();\n // @ts-expect-error It's technically readonly\n this.customDecoder.codec = codec;\n // @ts-expect-error It's technically readonly\n this.customDecoder.config = decoderConfig;\n // @ts-expect-error It's technically readonly\n this.customDecoder.onSample = (sample) => {\n if (!(sample instanceof VideoSample)) {\n throw new TypeError('The argument passed to onSample must be a VideoSample.');\n }\n this.finalizeAndEmitSample(sample);\n };\n void this.customDecoderCallSerializer.call(() => this.customDecoder.init());\n }\n else {\n const colorHandler = (frame) => {\n if (this.alphaQueue.length > 0) {\n // Even when no alpha data is present (most of the time), there will be nulls in this queue\n const alphaFrame = this.alphaQueue.shift();\n assert(alphaFrame !== undefined);\n this.mergeAlpha(frame, alphaFrame);\n }\n else {\n this.colorQueue.push(frame);\n }\n };\n if (codec === 'avc' && this.decoderConfig.description && isChromium()) {\n // Chromium has/had a bug with playing interlaced AVC (https://issues.chromium.org/issues/456919096)\n // which can be worked around by requesting that software decoding be used. So, here we peek into the\n // AVC description, if present, and switch to software decoding if we find interlaced content.\n const record = deserializeAvcDecoderConfigurationRecord(toUint8Array(this.decoderConfig.description));\n if (record && record.sequenceParameterSets.length > 0) {\n const sps = parseAvcSps(record.sequenceParameterSets[0]);\n if (sps && sps.frameMbsOnlyFlag === 0) {\n this.decoderConfig = {\n ...this.decoderConfig,\n hardwareAcceleration: 'prefer-software',\n };\n }\n }\n }\n const stack = new Error('Decoding error').stack;\n this.decoder = new VideoDecoder({\n output: (frame) => {\n try {\n colorHandler(frame);\n }\n catch (error) {\n this.onError(error);\n }\n },\n error: (error) => {\n error.stack = stack; // Provide a more useful stack trace, the default one sucks\n this.onError(error);\n },\n });\n this.decoder.configure(this.decoderConfig);\n }\n }\n getDecodeQueueSize() {\n if (this.customDecoder) {\n return this.customDecoderQueueSize;\n }\n else {\n assert(this.decoder);\n return Math.max(this.decoder.decodeQueueSize, this.alphaDecoder?.decodeQueueSize ?? 0);\n }\n }\n decode(packet) {\n if (this.codec === 'hevc' && this.currentPacketIndex > 0 && !this.raslSkipped) {\n if (this.hasHevcRaslPicture(packet.data)) {\n return; // Drop\n }\n this.raslSkipped = true;\n }\n if (this.customDecoder) {\n this.customDecoderQueueSize++;\n void this.customDecoderCallSerializer\n .call(() => this.customDecoder.decode(packet))\n .then(() => this.customDecoderQueueSize--);\n }\n else {\n assert(this.decoder);\n if (!isWebKit()) {\n insertSorted(this.inputTimestamps, packet.timestamp, x => x);\n }\n // Workaround for https://issues.chromium.org/issues/470109459\n if (isChromium() && this.currentPacketIndex === 0 && this.codec === 'avc') {\n const nalUnits = extractAvcNalUnits(packet.data, this.decoderConfig);\n const filteredNalUnits = nalUnits.filter((x) => {\n const type = extractNalUnitTypeForAvc(x);\n // These trip up Chromium's key frame detection, so let's strip them\n return !(type >= 20 && type <= 31);\n });\n const newData = concatAvcNalUnits(filteredNalUnits, this.decoderConfig);\n packet = new EncodedPacket(newData, packet.type, packet.timestamp, packet.duration);\n }\n this.decoder.decode(packet.toEncodedVideoChunk());\n this.decodeAlphaData(packet);\n }\n this.currentPacketIndex++;\n }\n decodeAlphaData(packet) {\n if (!packet.sideData.alpha || this.mergerCreationFailed) {\n // No alpha side data in the packet, most common case\n this.pushNullAlphaFrame();\n return;\n }\n if (!this.merger) {\n try {\n this.merger = new ColorAlphaMerger();\n }\n catch (error) {\n console.error('Due to an error, only color data will be decoded.', error);\n this.mergerCreationFailed = true;\n this.decodeAlphaData(packet); // Go again\n return;\n }\n }\n // Check if we need to set up the alpha decoder\n if (!this.alphaDecoder) {\n const alphaHandler = (frame) => {\n this.alphaDecoderQueueSize--;\n if (this.colorQueue.length > 0) {\n const colorFrame = this.colorQueue.shift();\n assert(colorFrame !== undefined);\n this.mergeAlpha(colorFrame, frame);\n }\n else {\n this.alphaQueue.push(frame);\n }\n // Check if any null frames have been queued for this point\n this.decodedAlphaChunkCount++;\n while (this.nullAlphaFrameQueue.length > 0\n && this.nullAlphaFrameQueue[0] === this.decodedAlphaChunkCount) {\n this.nullAlphaFrameQueue.shift();\n if (this.colorQueue.length > 0) {\n const colorFrame = this.colorQueue.shift();\n assert(colorFrame !== undefined);\n this.mergeAlpha(colorFrame, null);\n }\n else {\n this.alphaQueue.push(null);\n }\n }\n };\n const stack = new Error('Decoding error').stack;\n this.alphaDecoder = new VideoDecoder({\n output: (frame) => {\n try {\n alphaHandler(frame);\n }\n catch (error) {\n this.onError(error);\n }\n },\n error: (error) => {\n error.stack = stack; // Provide a more useful stack trace, the default one sucks\n this.onError(error);\n },\n });\n this.alphaDecoder.configure(this.decoderConfig);\n }\n const type = determineVideoPacketType(this.codec, this.decoderConfig, packet.sideData.alpha);\n // Alpha packets might follow a different key frame rhythm than the main packets. Therefore, before we start\n // decoding, we must first find a packet that's actually a key frame. Until then, we treat the image as opaque.\n if (!this.alphaHadKeyframe) {\n this.alphaHadKeyframe = type === 'key';\n }\n if (this.alphaHadKeyframe) {\n // Same RASL skipping logic as for color, unlikely to be hit (since who uses HEVC with separate alpha??) but\n // here for symmetry.\n if (this.codec === 'hevc' && this.currentAlphaPacketIndex > 0 && !this.alphaRaslSkipped) {\n if (this.hasHevcRaslPicture(packet.sideData.alpha)) {\n this.pushNullAlphaFrame();\n return;\n }\n this.alphaRaslSkipped = true;\n }\n this.currentAlphaPacketIndex++;\n this.alphaDecoder.decode(packet.alphaToEncodedVideoChunk(type ?? packet.type));\n this.alphaDecoderQueueSize++;\n }\n else {\n this.pushNullAlphaFrame();\n }\n }\n pushNullAlphaFrame() {\n if (this.alphaDecoderQueueSize === 0) {\n // Easy\n this.alphaQueue.push(null);\n }\n else {\n // There are still alpha chunks being decoded, so pushing `null` immediately would result in out-of-order\n // data and be incorrect. Instead, we need to enqueue a \"null frame\" for when the current decoder workload\n // has finished.\n this.nullAlphaFrameQueue.push(this.decodedAlphaChunkCount + this.alphaDecoderQueueSize);\n }\n }\n /**\n * If we're using HEVC, we need to make sure to skip any RASL slices that follow a non-IDR key frame such as\n * CRA_NUT. This is because RASL slices cannot be decoded without data before the CRA_NUT. Browsers behave\n * differently here: Chromium drops the packets, Safari throws a decoder error. Either way, it's not good\n * and causes bugs upstream. So, let's take the dropping into our own hands.\n */\n hasHevcRaslPicture(packetData) {\n const nalUnits = extractHevcNalUnits(packetData, this.decoderConfig);\n return nalUnits.some((x) => {\n const type = extractNalUnitTypeForHevc(x);\n return type === HevcNalUnitType.RASL_N || type === HevcNalUnitType.RASL_R;\n });\n }\n /** Handler for the WebCodecs VideoDecoder for ironing out browser differences. */\n sampleHandler(sample) {\n if (isWebKit()) {\n // For correct B-frame handling, we don't just hand over the frames directly but instead add them to\n // a queue, because we want to ensure frames are emitted in presentation order. We flush the queue\n // each time we receive a frame with a timestamp larger than the highest we've seen so far, as we\n // can sure that is not a B-frame. Typically, WebCodecs automatically guarantees that frames are\n // emitted in presentation order, but Safari doesn't always follow this rule.\n if (this.sampleQueue.length > 0 && (sample.timestamp >= last(this.sampleQueue).timestamp)) {\n for (const sample of this.sampleQueue) {\n this.finalizeAndEmitSample(sample);\n }\n this.sampleQueue.length = 0;\n }\n insertSorted(this.sampleQueue, sample, x => x.timestamp);\n }\n else {\n // Assign it the next earliest timestamp from the input. We do this because browsers, by spec, are\n // required to emit decoded frames in presentation order *while* retaining the timestamp of their\n // originating EncodedVideoChunk. For files with B-frames but no out-of-order timestamps (like a\n // missing ctts box, for example), this causes a mismatch. We therefore fix the timestamps and\n // ensure they are sorted by doing this.\n const timestamp = this.inputTimestamps.shift();\n // There's no way we'd have more decoded frames than encoded packets we passed in. Actually, the\n // correspondence should be 1:1.\n assert(timestamp !== undefined);\n sample.setTimestamp(timestamp);\n this.finalizeAndEmitSample(sample);\n }\n }\n finalizeAndEmitSample(sample) {\n // Round the timestamps to the time resolution\n sample.setTimestamp(Math.round(sample.timestamp * this.timeResolution) / this.timeResolution);\n sample.setDuration(Math.round(sample.duration * this.timeResolution) / this.timeResolution);\n sample.setRotation(this.rotation);\n this.onSample(sample);\n }\n mergeAlpha(color, alpha) {\n if (!alpha) {\n // Nothing needs to be merged\n const finalSample = new VideoSample(color);\n this.sampleHandler(finalSample);\n return;\n }\n assert(this.merger);\n this.merger.update(color, alpha);\n color.close();\n alpha.close();\n const finalFrame = new VideoFrame(this.merger.canvas, {\n timestamp: color.timestamp,\n duration: color.duration ?? undefined,\n });\n const finalSample = new VideoSample(finalFrame);\n this.sampleHandler(finalSample);\n }\n async flush() {\n if (this.customDecoder) {\n await this.customDecoderCallSerializer.call(() => this.customDecoder.flush());\n }\n else {\n assert(this.decoder);\n await Promise.all([\n this.decoder.flush(),\n this.alphaDecoder?.flush(),\n ]);\n this.colorQueue.forEach(x => x.close());\n this.colorQueue.length = 0;\n this.alphaQueue.forEach(x => x?.close());\n this.alphaQueue.length = 0;\n this.alphaHadKeyframe = false;\n this.decodedAlphaChunkCount = 0;\n this.alphaDecoderQueueSize = 0;\n this.nullAlphaFrameQueue.length = 0;\n this.currentAlphaPacketIndex = 0;\n this.alphaRaslSkipped = false;\n }\n if (isWebKit()) {\n for (const sample of this.sampleQueue) {\n this.finalizeAndEmitSample(sample);\n }\n this.sampleQueue.length = 0;\n }\n this.currentPacketIndex = 0;\n this.raslSkipped = false;\n }\n close() {\n if (this.customDecoder) {\n void this.customDecoderCallSerializer.call(() => this.customDecoder.close());\n }\n else {\n assert(this.decoder);\n this.decoder.close();\n this.alphaDecoder?.close();\n this.colorQueue.forEach(x => x.close());\n this.colorQueue.length = 0;\n this.alphaQueue.forEach(x => x?.close());\n this.alphaQueue.length = 0;\n this.merger?.close();\n }\n for (const sample of this.sampleQueue) {\n sample.close();\n }\n this.sampleQueue.length = 0;\n }\n}\n/** Utility class that merges together color and alpha information using simple WebGL 2 shaders. */\nclass ColorAlphaMerger {\n constructor() {\n // Canvas will be resized later\n if (typeof OffscreenCanvas !== 'undefined') {\n // Prefer OffscreenCanvas for Worker environments\n this.canvas = new OffscreenCanvas(300, 150);\n }\n else {\n this.canvas = document.createElement('canvas');\n }\n const gl = this.canvas.getContext('webgl2', {\n premultipliedAlpha: false,\n }); // Casting because of some TypeScript weirdness\n if (!gl) {\n throw new Error('Couldn\\'t acquire WebGL 2 context.');\n }\n this.gl = gl;\n this.program = this.createProgram();\n this.vao = this.createVAO();\n this.colorTexture = this.createTexture();\n this.alphaTexture = this.createTexture();\n this.gl.useProgram(this.program);\n this.gl.uniform1i(this.gl.getUniformLocation(this.program, 'u_colorTexture'), 0);\n this.gl.uniform1i(this.gl.getUniformLocation(this.program, 'u_alphaTexture'), 1);\n }\n createProgram() {\n const vertexShader = this.createShader(this.gl.VERTEX_SHADER, `#version 300 es\n\t\t\tin vec2 a_position;\n\t\t\tin vec2 a_texCoord;\n\t\t\tout vec2 v_texCoord;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tgl_Position = vec4(a_position, 0.0, 1.0);\n\t\t\t\tv_texCoord = a_texCoord;\n\t\t\t}\n\t\t`);\n const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `#version 300 es\n\t\t\tprecision highp float;\n\t\t\t\n\t\t\tuniform sampler2D u_colorTexture;\n\t\t\tuniform sampler2D u_alphaTexture;\n\t\t\tin vec2 v_texCoord;\n\t\t\tout vec4 fragColor;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec3 color = texture(u_colorTexture, v_texCoord).rgb;\n\t\t\t\tfloat alpha = texture(u_alphaTexture, v_texCoord).r;\n\t\t\t\tfragColor = vec4(color, alpha);\n\t\t\t}\n\t\t`);\n const program = this.gl.createProgram();\n this.gl.attachShader(program, vertexShader);\n this.gl.attachShader(program, fragmentShader);\n this.gl.linkProgram(program);\n return program;\n }\n createShader(type, source) {\n const shader = this.gl.createShader(type);\n this.gl.shaderSource(shader, source);\n this.gl.compileShader(shader);\n return shader;\n }\n createVAO() {\n const vao = this.gl.createVertexArray();\n this.gl.bindVertexArray(vao);\n const vertices = new Float32Array([\n -1, -1, 0, 1,\n 1, -1, 1, 1,\n -1, 1, 0, 0,\n 1, 1, 1, 0,\n ]);\n const buffer = this.gl.createBuffer();\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);\n this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);\n const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');\n const texCoordLocation = this.gl.getAttribLocation(this.program, 'a_texCoord');\n this.gl.enableVertexAttribArray(positionLocation);\n this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 16, 0);\n this.gl.enableVertexAttribArray(texCoordLocation);\n this.gl.vertexAttribPointer(texCoordLocation, 2, this.gl.FLOAT, false, 16, 8);\n return vao;\n }\n createTexture() {\n const texture = this.gl.createTexture();\n this.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n return texture;\n }\n update(color, alpha) {\n if (color.displayWidth !== this.canvas.width || color.displayHeight !== this.canvas.height) {\n this.canvas.width = color.displayWidth;\n this.canvas.height = color.displayHeight;\n }\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.colorTexture);\n this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, color);\n this.gl.activeTexture(this.gl.TEXTURE1);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.alphaTexture);\n this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, alpha);\n this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);\n this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n this.gl.bindVertexArray(this.vao);\n this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);\n }\n close() {\n this.gl.getExtension('WEBGL_lose_context')?.loseContext();\n this.gl = null;\n }\n}\n/**\n * A sink that retrieves decoded video samples (video frames) from a video track.\n * @group Media sinks\n * @public\n */\nexport class VideoSampleSink extends BaseMediaSampleSink {\n /** Creates a new {@link VideoSampleSink} for the given {@link InputVideoTrack}. */\n constructor(videoTrack) {\n if (!(videoTrack instanceof InputVideoTrack)) {\n throw new TypeError('videoTrack must be an InputVideoTrack.');\n }\n super();\n this._track = videoTrack;\n }\n /** @internal */\n async _createDecoder(onSample, onError) {\n if (!(await this._track.canDecode())) {\n throw new Error('This video track cannot be decoded by this browser. Make sure to check decodability before using'\n + ' a track.');\n }\n const codec = this._track.codec;\n const rotation = this._track.rotation;\n const decoderConfig = await this._track.getDecoderConfig();\n const timeResolution = this._track.timeResolution;\n assert(codec && decoderConfig);\n return new VideoDecoderWrapper(onSample, onError, codec, decoderConfig, rotation, timeResolution);\n }\n /** @internal */\n _createPacketSink() {\n return new EncodedPacketSink(this._track);\n }\n /**\n * Retrieves the video sample (frame) corresponding to the given timestamp, in seconds. More specifically, returns\n * the last video sample (in presentation order) with a start timestamp less than or equal to the given timestamp.\n * Returns null if the timestamp is before the track's first timestamp.\n *\n * @param timestamp - The timestamp used for retrieval, in seconds.\n */\n async getSample(timestamp) {\n validateTimestamp(timestamp);\n for await (const sample of this.mediaSamplesAtTimestamps([timestamp])) {\n return sample;\n }\n throw new Error('Internal error: Iterator returned nothing.');\n }\n /**\n * Creates an async iterator that yields the video samples (frames) of this track in presentation order. This method\n * will intelligently pre-decode a few frames ahead to enable fast iteration.\n *\n * @param startTimestamp - The timestamp in seconds at which to start yielding samples (inclusive).\n * @param endTimestamp - The timestamp in seconds at which to stop yielding samples (exclusive).\n */\n samples(startTimestamp = 0, endTimestamp = Infinity) {\n return this.mediaSamplesInRange(startTimestamp, endTimestamp);\n }\n /**\n * Creates an async iterator that yields a video sample (frame) for each timestamp in the argument. This method\n * uses an optimized decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most\n * once, and is therefore more efficient than manually getting the sample for every timestamp. The iterator may\n * yield null if no frame is available for a given timestamp.\n *\n * @param timestamps - An iterable or async iterable of timestamps in seconds.\n */\n samplesAtTimestamps(timestamps) {\n return this.mediaSamplesAtTimestamps(timestamps);\n }\n}\n/**\n * A sink that renders video samples (frames) of the given video track to canvases. This is often more useful than\n * directly retrieving frames, as it comes with common preprocessing steps such as resizing or applying rotation\n * metadata.\n *\n * This sink will yield `HTMLCanvasElement`s when in a DOM context, and `OffscreenCanvas`es otherwise.\n *\n * @group Media sinks\n * @public\n */\nexport class CanvasSink {\n /** Creates a new {@link CanvasSink} for the given {@link InputVideoTrack}. */\n constructor(videoTrack, options = {}) {\n /** @internal */\n this._nextCanvasIndex = 0;\n if (!(videoTrack instanceof InputVideoTrack)) {\n throw new TypeError('videoTrack must be an InputVideoTrack.');\n }\n if (options && typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (options.alpha !== undefined && typeof options.alpha !== 'boolean') {\n throw new TypeError('options.alpha, when provided, must be a boolean.');\n }\n if (options.width !== undefined && (!Number.isInteger(options.width) || options.width <= 0)) {\n throw new TypeError('options.width, when defined, must be a positive integer.');\n }\n if (options.height !== undefined && (!Number.isInteger(options.height) || options.height <= 0)) {\n throw new TypeError('options.height, when defined, must be a positive integer.');\n }\n if (options.fit !== undefined && !['fill', 'contain', 'cover'].includes(options.fit)) {\n throw new TypeError('options.fit, when provided, must be one of \"fill\", \"contain\", or \"cover\".');\n }\n if (options.width !== undefined\n && options.height !== undefined\n && options.fit === undefined) {\n throw new TypeError('When both options.width and options.height are provided, options.fit must also be provided.');\n }\n if (options.rotation !== undefined && ![0, 90, 180, 270].includes(options.rotation)) {\n throw new TypeError('options.rotation, when provided, must be 0, 90, 180 or 270.');\n }\n if (options.crop !== undefined) {\n validateCropRectangle(options.crop, 'options.');\n }\n if (options.poolSize !== undefined\n && (typeof options.poolSize !== 'number' || !Number.isInteger(options.poolSize) || options.poolSize < 0)) {\n throw new TypeError('poolSize must be a non-negative integer.');\n }\n const rotation = options.rotation ?? videoTrack.rotation;\n const [rotatedWidth, rotatedHeight] = rotation % 180 === 0\n ? [videoTrack.codedWidth, videoTrack.codedHeight]\n : [videoTrack.codedHeight, videoTrack.codedWidth];\n const crop = options.crop;\n if (crop) {\n clampCropRectangle(crop, rotatedWidth, rotatedHeight);\n }\n let [width, height] = crop\n ? [crop.width, crop.height]\n : [rotatedWidth, rotatedHeight];\n const originalAspectRatio = width / height;\n // If width and height aren't defined together, deduce the missing value using the aspect ratio\n if (options.width !== undefined && options.height === undefined) {\n width = options.width;\n height = Math.round(width / originalAspectRatio);\n }\n else if (options.width === undefined && options.height !== undefined) {\n height = options.height;\n width = Math.round(height * originalAspectRatio);\n }\n else if (options.width !== undefined && options.height !== undefined) {\n width = options.width;\n height = options.height;\n }\n this._videoTrack = videoTrack;\n this._alpha = options.alpha ?? false;\n this._width = width;\n this._height = height;\n this._rotation = rotation;\n this._crop = crop;\n this._fit = options.fit ?? 'fill';\n this._videoSampleSink = new VideoSampleSink(videoTrack);\n this._canvasPool = Array.from({ length: options.poolSize ?? 0 }, () => null);\n }\n /** @internal */\n _videoSampleToWrappedCanvas(sample) {\n let canvas = this._canvasPool[this._nextCanvasIndex];\n let canvasIsNew = false;\n if (!canvas) {\n if (typeof document !== 'undefined') {\n // Prefer an HTMLCanvasElement\n canvas = document.createElement('canvas');\n canvas.width = this._width;\n canvas.height = this._height;\n }\n else {\n canvas = new OffscreenCanvas(this._width, this._height);\n }\n if (this._canvasPool.length > 0) {\n this._canvasPool[this._nextCanvasIndex] = canvas;\n }\n canvasIsNew = true;\n }\n if (this._canvasPool.length > 0) {\n this._nextCanvasIndex = (this._nextCanvasIndex + 1) % this._canvasPool.length;\n }\n const context = canvas.getContext('2d', {\n alpha: this._alpha || isFirefox(), // Firefox has VideoFrame glitches with opaque canvases\n });\n assert(context);\n context.resetTransform();\n if (!canvasIsNew) {\n if (!this._alpha && isFirefox()) {\n context.fillStyle = 'black';\n context.fillRect(0, 0, this._width, this._height);\n }\n else {\n context.clearRect(0, 0, this._width, this._height);\n }\n }\n sample.drawWithFit(context, {\n fit: this._fit,\n rotation: this._rotation,\n crop: this._crop,\n });\n const result = {\n canvas,\n timestamp: sample.timestamp,\n duration: sample.duration,\n };\n sample.close();\n return result;\n }\n /**\n * Retrieves a canvas with the video frame corresponding to the given timestamp, in seconds. More specifically,\n * returns the last video frame (in presentation order) with a start timestamp less than or equal to the given\n * timestamp. Returns null if the timestamp is before the track's first timestamp.\n *\n * @param timestamp - The timestamp used for retrieval, in seconds.\n */\n async getCanvas(timestamp) {\n validateTimestamp(timestamp);\n const sample = await this._videoSampleSink.getSample(timestamp);\n return sample && this._videoSampleToWrappedCanvas(sample);\n }\n /**\n * Creates an async iterator that yields canvases with the video frames of this track in presentation order. This\n * method will intelligently pre-decode a few frames ahead to enable fast iteration.\n *\n * @param startTimestamp - The timestamp in seconds at which to start yielding canvases (inclusive).\n * @param endTimestamp - The timestamp in seconds at which to stop yielding canvases (exclusive).\n */\n canvases(startTimestamp = 0, endTimestamp = Infinity) {\n return mapAsyncGenerator(this._videoSampleSink.samples(startTimestamp, endTimestamp), sample => this._videoSampleToWrappedCanvas(sample));\n }\n /**\n * Creates an async iterator that yields a canvas for each timestamp in the argument. This method uses an optimized\n * decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most once, and is\n * therefore more efficient than manually getting the canvas for every timestamp. The iterator may yield null if\n * no frame is available for a given timestamp.\n *\n * @param timestamps - An iterable or async iterable of timestamps in seconds.\n */\n canvasesAtTimestamps(timestamps) {\n return mapAsyncGenerator(this._videoSampleSink.samplesAtTimestamps(timestamps), sample => sample && this._videoSampleToWrappedCanvas(sample));\n }\n}\nclass AudioDecoderWrapper extends DecoderWrapper {\n constructor(onSample, onError, codec, decoderConfig) {\n super(onSample, onError);\n this.decoder = null;\n this.customDecoder = null;\n this.customDecoderCallSerializer = new CallSerializer();\n this.customDecoderQueueSize = 0;\n // Internal state to accumulate a precise current timestamp based on audio durations, not the (potentially\n // inaccurate) packet timestamps.\n this.currentTimestamp = null;\n const sampleHandler = (sample) => {\n if (this.currentTimestamp === null\n || Math.abs(sample.timestamp - this.currentTimestamp) >= sample.duration) {\n // We need to sync with the sample timestamp again\n this.currentTimestamp = sample.timestamp;\n }\n const preciseTimestamp = this.currentTimestamp;\n this.currentTimestamp += sample.duration;\n if (sample.numberOfFrames === 0) {\n // We skip zero-data (empty) AudioSamples. These are sometimes emitted, for example, by Firefox when it\n // decodes Vorbis (at the start).\n sample.close();\n return;\n }\n // Round the timestamp to the sample rate\n const sampleRate = decoderConfig.sampleRate;\n sample.setTimestamp(Math.round(preciseTimestamp * sampleRate) / sampleRate);\n onSample(sample);\n };\n const MatchingCustomDecoder = customAudioDecoders.find(x => x.supports(codec, decoderConfig));\n if (MatchingCustomDecoder) {\n // @ts-expect-error \"Can't create instance of abstract class \uD83E\uDD13\"\n this.customDecoder = new MatchingCustomDecoder();\n // @ts-expect-error It's technically readonly\n this.customDecoder.codec = codec;\n // @ts-expect-error It's technically readonly\n this.customDecoder.config = decoderConfig;\n // @ts-expect-error It's technically readonly\n this.customDecoder.onSample = (sample) => {\n if (!(sample instanceof AudioSample)) {\n throw new TypeError('The argument passed to onSample must be an AudioSample.');\n }\n sampleHandler(sample);\n };\n void this.customDecoderCallSerializer.call(() => this.customDecoder.init());\n }\n else {\n const stack = new Error('Decoding error').stack;\n this.decoder = new AudioDecoder({\n output: (data) => {\n try {\n sampleHandler(new AudioSample(data));\n }\n catch (error) {\n this.onError(error);\n }\n },\n error: (error) => {\n error.stack = stack; // Provide a more useful stack trace, the default one sucks\n this.onError(error);\n },\n });\n this.decoder.configure(decoderConfig);\n }\n }\n getDecodeQueueSize() {\n if (this.customDecoder) {\n return this.customDecoderQueueSize;\n }\n else {\n assert(this.decoder);\n return this.decoder.decodeQueueSize;\n }\n }\n decode(packet) {\n if (this.customDecoder) {\n this.customDecoderQueueSize++;\n void this.customDecoderCallSerializer\n .call(() => this.customDecoder.decode(packet))\n .then(() => this.customDecoderQueueSize--);\n }\n else {\n assert(this.decoder);\n this.decoder.decode(packet.toEncodedAudioChunk());\n }\n }\n flush() {\n if (this.customDecoder) {\n return this.customDecoderCallSerializer.call(() => this.customDecoder.flush());\n }\n else {\n assert(this.decoder);\n return this.decoder.flush();\n }\n }\n close() {\n if (this.customDecoder) {\n void this.customDecoderCallSerializer.call(() => this.customDecoder.close());\n }\n else {\n assert(this.decoder);\n this.decoder.close();\n }\n }\n}\n// There are a lot of PCM variants not natively supported by the browser and by AudioData. Therefore we need a simple\n// decoder that maps any input PCM format into a PCM format supported by the browser.\nclass PcmAudioDecoderWrapper extends DecoderWrapper {\n constructor(onSample, onError, decoderConfig) {\n super(onSample, onError);\n this.decoderConfig = decoderConfig;\n // Internal state to accumulate a precise current timestamp based on audio durations, not the (potentially\n // inaccurate) packet timestamps.\n this.currentTimestamp = null;\n assert(PCM_AUDIO_CODECS.includes(decoderConfig.codec));\n this.codec = decoderConfig.codec;\n const { dataType, sampleSize, littleEndian } = parsePcmCodec(this.codec);\n this.inputSampleSize = sampleSize;\n switch (sampleSize) {\n case 1:\n {\n if (dataType === 'unsigned') {\n this.readInputValue = (view, byteOffset) => view.getUint8(byteOffset) - 2 ** 7;\n }\n else if (dataType === 'signed') {\n this.readInputValue = (view, byteOffset) => view.getInt8(byteOffset);\n }\n else if (dataType === 'ulaw') {\n this.readInputValue = (view, byteOffset) => fromUlaw(view.getUint8(byteOffset));\n }\n else if (dataType === 'alaw') {\n this.readInputValue = (view, byteOffset) => fromAlaw(view.getUint8(byteOffset));\n }\n else {\n assert(false);\n }\n }\n ;\n break;\n case 2:\n {\n if (dataType === 'unsigned') {\n this.readInputValue = (view, byteOffset) => view.getUint16(byteOffset, littleEndian) - 2 ** 15;\n }\n else if (dataType === 'signed') {\n this.readInputValue = (view, byteOffset) => view.getInt16(byteOffset, littleEndian);\n }\n else {\n assert(false);\n }\n }\n ;\n break;\n case 3:\n {\n if (dataType === 'unsigned') {\n this.readInputValue = (view, byteOffset) => getUint24(view, byteOffset, littleEndian) - 2 ** 23;\n }\n else if (dataType === 'signed') {\n this.readInputValue = (view, byteOffset) => getInt24(view, byteOffset, littleEndian);\n }\n else {\n assert(false);\n }\n }\n ;\n break;\n case 4:\n {\n if (dataType === 'unsigned') {\n this.readInputValue = (view, byteOffset) => view.getUint32(byteOffset, littleEndian) - 2 ** 31;\n }\n else if (dataType === 'signed') {\n this.readInputValue = (view, byteOffset) => view.getInt32(byteOffset, littleEndian);\n }\n else if (dataType === 'float') {\n this.readInputValue = (view, byteOffset) => view.getFloat32(byteOffset, littleEndian);\n }\n else {\n assert(false);\n }\n }\n ;\n break;\n case 8:\n {\n if (dataType === 'float') {\n this.readInputValue = (view, byteOffset) => view.getFloat64(byteOffset, littleEndian);\n }\n else {\n assert(false);\n }\n }\n ;\n break;\n default:\n {\n assertNever(sampleSize);\n assert(false);\n }\n ;\n }\n switch (sampleSize) {\n case 1:\n {\n if (dataType === 'ulaw' || dataType === 'alaw') {\n this.outputSampleSize = 2;\n this.outputFormat = 's16';\n this.writeOutputValue = (view, byteOffset, value) => view.setInt16(byteOffset, value, true);\n }\n else {\n this.outputSampleSize = 1;\n this.outputFormat = 'u8';\n this.writeOutputValue = (view, byteOffset, value) => view.setUint8(byteOffset, value + 2 ** 7);\n }\n }\n ;\n break;\n case 2:\n {\n this.outputSampleSize = 2;\n this.outputFormat = 's16';\n this.writeOutputValue = (view, byteOffset, value) => view.setInt16(byteOffset, value, true);\n }\n ;\n break;\n case 3:\n {\n this.outputSampleSize = 4;\n this.outputFormat = 's32';\n // From https://www.w3.org/TR/webcodecs:\n // AudioData containing 24-bit samples SHOULD store those samples in s32 or f32. When samples are\n // stored in s32, each sample MUST be left-shifted by 8 bits.\n this.writeOutputValue = (view, byteOffset, value) => view.setInt32(byteOffset, value << 8, true);\n }\n ;\n break;\n case 4:\n {\n this.outputSampleSize = 4;\n if (dataType === 'float') {\n this.outputFormat = 'f32';\n this.writeOutputValue = (view, byteOffset, value) => view.setFloat32(byteOffset, value, true);\n }\n else {\n this.outputFormat = 's32';\n this.writeOutputValue = (view, byteOffset, value) => view.setInt32(byteOffset, value, true);\n }\n }\n ;\n break;\n case 8:\n {\n this.outputSampleSize = 4;\n this.outputFormat = 'f32';\n this.writeOutputValue = (view, byteOffset, value) => view.setFloat32(byteOffset, value, true);\n }\n ;\n break;\n default:\n {\n assertNever(sampleSize);\n assert(false);\n }\n ;\n }\n ;\n }\n getDecodeQueueSize() {\n return 0;\n }\n decode(packet) {\n const inputView = toDataView(packet.data);\n const numberOfFrames = packet.byteLength / this.decoderConfig.numberOfChannels / this.inputSampleSize;\n const outputBufferSize = numberOfFrames * this.decoderConfig.numberOfChannels * this.outputSampleSize;\n const outputBuffer = new ArrayBuffer(outputBufferSize);\n const outputView = new DataView(outputBuffer);\n for (let i = 0; i < numberOfFrames * this.decoderConfig.numberOfChannels; i++) {\n const inputIndex = i * this.inputSampleSize;\n const outputIndex = i * this.outputSampleSize;\n const value = this.readInputValue(inputView, inputIndex);\n this.writeOutputValue(outputView, outputIndex, value);\n }\n const preciseDuration = numberOfFrames / this.decoderConfig.sampleRate;\n if (this.currentTimestamp === null || Math.abs(packet.timestamp - this.currentTimestamp) >= preciseDuration) {\n // We need to sync with the packet timestamp again\n this.currentTimestamp = packet.timestamp;\n }\n const preciseTimestamp = this.currentTimestamp;\n this.currentTimestamp += preciseDuration;\n const audioSample = new AudioSample({\n format: this.outputFormat,\n data: outputBuffer,\n numberOfChannels: this.decoderConfig.numberOfChannels,\n sampleRate: this.decoderConfig.sampleRate,\n numberOfFrames,\n timestamp: preciseTimestamp,\n });\n this.onSample(audioSample);\n }\n async flush() {\n // Do nothing\n }\n close() {\n // Do nothing\n }\n}\n/**\n * Sink for retrieving decoded audio samples from an audio track.\n * @group Media sinks\n * @public\n */\nexport class AudioSampleSink extends BaseMediaSampleSink {\n /** Creates a new {@link AudioSampleSink} for the given {@link InputAudioTrack}. */\n constructor(audioTrack) {\n if (!(audioTrack instanceof InputAudioTrack)) {\n throw new TypeError('audioTrack must be an InputAudioTrack.');\n }\n super();\n this._track = audioTrack;\n }\n /** @internal */\n async _createDecoder(onSample, onError) {\n if (!(await this._track.canDecode())) {\n throw new Error('This audio track cannot be decoded by this browser. Make sure to check decodability before using'\n + ' a track.');\n }\n const codec = this._track.codec;\n const decoderConfig = await this._track.getDecoderConfig();\n assert(codec && decoderConfig);\n if (PCM_AUDIO_CODECS.includes(decoderConfig.codec)) {\n return new PcmAudioDecoderWrapper(onSample, onError, decoderConfig);\n }\n else {\n return new AudioDecoderWrapper(onSample, onError, codec, decoderConfig);\n }\n }\n /** @internal */\n _createPacketSink() {\n return new EncodedPacketSink(this._track);\n }\n /**\n * Retrieves the audio sample corresponding to the given timestamp, in seconds. More specifically, returns\n * the last audio sample (in presentation order) with a start timestamp less than or equal to the given timestamp.\n * Returns null if the timestamp is before the track's first timestamp.\n *\n * @param timestamp - The timestamp used for retrieval, in seconds.\n */\n async getSample(timestamp) {\n validateTimestamp(timestamp);\n for await (const sample of this.mediaSamplesAtTimestamps([timestamp])) {\n return sample;\n }\n throw new Error('Internal error: Iterator returned nothing.');\n }\n /**\n * Creates an async iterator that yields the audio samples of this track in presentation order. This method\n * will intelligently pre-decode a few samples ahead to enable fast iteration.\n *\n * @param startTimestamp - The timestamp in seconds at which to start yielding samples (inclusive).\n * @param endTimestamp - The timestamp in seconds at which to stop yielding samples (exclusive).\n */\n samples(startTimestamp = 0, endTimestamp = Infinity) {\n return this.mediaSamplesInRange(startTimestamp, endTimestamp);\n }\n /**\n * Creates an async iterator that yields an audio sample for each timestamp in the argument. This method\n * uses an optimized decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most\n * once, and is therefore more efficient than manually getting the sample for every timestamp. The iterator may\n * yield null if no sample is available for a given timestamp.\n *\n * @param timestamps - An iterable or async iterable of timestamps in seconds.\n */\n samplesAtTimestamps(timestamps) {\n return this.mediaSamplesAtTimestamps(timestamps);\n }\n}\n/**\n * A sink that retrieves decoded audio samples from an audio track and converts them to `AudioBuffer` instances. This is\n * often more useful than directly retrieving audio samples, as audio buffers can be directly used with the\n * Web Audio API.\n * @group Media sinks\n * @public\n */\nexport class AudioBufferSink {\n /** Creates a new {@link AudioBufferSink} for the given {@link InputAudioTrack}. */\n constructor(audioTrack) {\n if (!(audioTrack instanceof InputAudioTrack)) {\n throw new TypeError('audioTrack must be an InputAudioTrack.');\n }\n this._audioSampleSink = new AudioSampleSink(audioTrack);\n }\n /** @internal */\n _audioSampleToWrappedArrayBuffer(sample) {\n const result = {\n buffer: sample.toAudioBuffer(),\n timestamp: sample.timestamp,\n duration: sample.duration,\n };\n sample.close();\n return result;\n }\n /**\n * Retrieves the audio buffer corresponding to the given timestamp, in seconds. More specifically, returns\n * the last audio buffer (in presentation order) with a start timestamp less than or equal to the given timestamp.\n * Returns null if the timestamp is before the track's first timestamp.\n *\n * @param timestamp - The timestamp used for retrieval, in seconds.\n */\n async getBuffer(timestamp) {\n validateTimestamp(timestamp);\n const data = await this._audioSampleSink.getSample(timestamp);\n return data && this._audioSampleToWrappedArrayBuffer(data);\n }\n /**\n * Creates an async iterator that yields audio buffers of this track in presentation order. This method\n * will intelligently pre-decode a few buffers ahead to enable fast iteration.\n *\n * @param startTimestamp - The timestamp in seconds at which to start yielding buffers (inclusive).\n * @param endTimestamp - The timestamp in seconds at which to stop yielding buffers (exclusive).\n */\n buffers(startTimestamp = 0, endTimestamp = Infinity) {\n return mapAsyncGenerator(this._audioSampleSink.samples(startTimestamp, endTimestamp), data => this._audioSampleToWrappedArrayBuffer(data));\n }\n /**\n * Creates an async iterator that yields an audio buffer for each timestamp in the argument. This method\n * uses an optimized decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most\n * once, and is therefore more efficient than manually getting the buffer for every timestamp. The iterator may\n * yield null if no buffer is available for a given timestamp.\n *\n * @param timestamps - An iterable or async iterable of timestamps in seconds.\n */\n buffersAtTimestamps(timestamps) {\n return mapAsyncGenerator(this._audioSampleSink.samplesAtTimestamps(timestamps), data => data && this._audioSampleToWrappedArrayBuffer(data));\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { determineVideoPacketType } from './codec-data.js';\nimport { customAudioDecoders, customVideoDecoders } from './custom-coder.js';\nimport { EncodedPacketSink } from './media-sink.js';\nimport { assert } from './misc.js';\nimport { EncodedPacket } from './packet.js';\n/**\n * Represents a media track in an input file.\n * @group Input files & tracks\n * @public\n */\nexport class InputTrack {\n /** @internal */\n constructor(input, backing) {\n this.input = input;\n this._backing = backing;\n }\n /** Returns true if and only if this track is a video track. */\n isVideoTrack() {\n return this instanceof InputVideoTrack;\n }\n /** Returns true if and only if this track is an audio track. */\n isAudioTrack() {\n return this instanceof InputAudioTrack;\n }\n /** The unique ID of this track in the input file. */\n get id() {\n return this._backing.getId();\n }\n /**\n * The identifier of the codec used internally by the container. It is not homogenized by Mediabunny\n * and depends entirely on the container format.\n *\n * This field can be used to determine the codec of a track in case Mediabunny doesn't know that codec.\n *\n * - For ISOBMFF files, this field returns the name of the Sample Description Box (e.g. `'avc1'`).\n * - For Matroska files, this field returns the value of the `CodecID` element.\n * - For WAVE files, this field returns the value of the format tag in the `'fmt '` chunk.\n * - For ADTS files, this field contains the `MPEG-4 Audio Object Type`.\n * - In all other cases, this field is `null`.\n */\n get internalCodecId() {\n return this._backing.getInternalCodecId();\n }\n /**\n * The ISO 639-2/T language code for this track. If the language is unknown, this field is `'und'` (undetermined).\n */\n get languageCode() {\n return this._backing.getLanguageCode();\n }\n /** A user-defined name for this track. */\n get name() {\n return this._backing.getName();\n }\n /**\n * A positive number x such that all timestamps and durations of all packets of this track are\n * integer multiples of 1/x.\n */\n get timeResolution() {\n return this._backing.getTimeResolution();\n }\n /** The track's disposition, i.e. information about its intended usage. */\n get disposition() {\n return this._backing.getDisposition();\n }\n /**\n * Returns the start timestamp of the first packet of this track, in seconds. While often near zero, this value\n * may be positive or even negative. A negative starting timestamp means the track's timing has been offset. Samples\n * with a negative timestamp should not be presented.\n */\n getFirstTimestamp() {\n return this._backing.getFirstTimestamp();\n }\n /** Returns the end timestamp of the last packet of this track, in seconds. */\n computeDuration() {\n return this._backing.computeDuration();\n }\n /**\n * Computes aggregate packet statistics for this track, such as average packet rate or bitrate.\n *\n * @param targetPacketCount - This optional parameter sets a target for how many packets this method must have\n * looked at before it can return early; this means, you can use it to aggregate only a subset (prefix) of all\n * packets. This is very useful for getting a great estimate of video frame rate without having to scan through the\n * entire file.\n */\n async computePacketStats(targetPacketCount = Infinity) {\n const sink = new EncodedPacketSink(this);\n let startTimestamp = Infinity;\n let endTimestamp = -Infinity;\n let packetCount = 0;\n let totalPacketBytes = 0;\n for await (const packet of sink.packets(undefined, undefined, { metadataOnly: true })) {\n if (packetCount >= targetPacketCount\n // This additional condition is needed to produce correct results with out-of-presentation-order packets\n && packet.timestamp >= endTimestamp) {\n break;\n }\n startTimestamp = Math.min(startTimestamp, packet.timestamp);\n endTimestamp = Math.max(endTimestamp, packet.timestamp + packet.duration);\n packetCount++;\n totalPacketBytes += packet.byteLength;\n }\n return {\n packetCount,\n averagePacketRate: packetCount\n ? Number((packetCount / (endTimestamp - startTimestamp)).toPrecision(16))\n : 0,\n averageBitrate: packetCount\n ? Number((8 * totalPacketBytes / (endTimestamp - startTimestamp)).toPrecision(16))\n : 0,\n };\n }\n}\n/**\n * Represents a video track in an input file.\n * @group Input files & tracks\n * @public\n */\nexport class InputVideoTrack extends InputTrack {\n /** @internal */\n constructor(input, backing) {\n super(input, backing);\n this._backing = backing;\n }\n get type() {\n return 'video';\n }\n get codec() {\n return this._backing.getCodec();\n }\n /** The width in pixels of the track's coded samples, before any transformations or rotations. */\n get codedWidth() {\n return this._backing.getCodedWidth();\n }\n /** The height in pixels of the track's coded samples, before any transformations or rotations. */\n get codedHeight() {\n return this._backing.getCodedHeight();\n }\n /** The angle in degrees by which the track's frames should be rotated (clockwise). */\n get rotation() {\n return this._backing.getRotation();\n }\n /** The width in pixels of the track's frames after rotation. */\n get displayWidth() {\n const rotation = this._backing.getRotation();\n return rotation % 180 === 0 ? this._backing.getCodedWidth() : this._backing.getCodedHeight();\n }\n /** The height in pixels of the track's frames after rotation. */\n get displayHeight() {\n const rotation = this._backing.getRotation();\n return rotation % 180 === 0 ? this._backing.getCodedHeight() : this._backing.getCodedWidth();\n }\n /** Returns the color space of the track's samples. */\n getColorSpace() {\n return this._backing.getColorSpace();\n }\n /** If this method returns true, the track's samples use a high dynamic range (HDR). */\n async hasHighDynamicRange() {\n const colorSpace = await this._backing.getColorSpace();\n return colorSpace.primaries === 'bt2020' || colorSpace.primaries === 'smpte432'\n || colorSpace.transfer === 'pg' || colorSpace.transfer === 'hlg'\n || colorSpace.matrix === 'bt2020-ncl';\n }\n /** Checks if this track may contain transparent samples with alpha data. */\n canBeTransparent() {\n return this._backing.canBeTransparent();\n }\n /**\n * Returns the [decoder configuration](https://www.w3.org/TR/webcodecs/#video-decoder-config) for decoding the\n * track's packets using a [`VideoDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/VideoDecoder). Returns\n * null if the track's codec is unknown.\n */\n getDecoderConfig() {\n return this._backing.getDecoderConfig();\n }\n async getCodecParameterString() {\n const decoderConfig = await this._backing.getDecoderConfig();\n return decoderConfig?.codec ?? null;\n }\n async canDecode() {\n try {\n const decoderConfig = await this._backing.getDecoderConfig();\n if (!decoderConfig) {\n return false;\n }\n const codec = this._backing.getCodec();\n assert(codec !== null);\n if (customVideoDecoders.some(x => x.supports(codec, decoderConfig))) {\n return true;\n }\n if (typeof VideoDecoder === 'undefined') {\n return false;\n }\n const support = await VideoDecoder.isConfigSupported(decoderConfig);\n return support.supported === true;\n }\n catch (error) {\n console.error('Error during decodability check:', error);\n return false;\n }\n }\n async determinePacketType(packet) {\n if (!(packet instanceof EncodedPacket)) {\n throw new TypeError('packet must be an EncodedPacket.');\n }\n if (packet.isMetadataOnly) {\n throw new TypeError('packet must not be metadata-only to determine its type.');\n }\n if (this.codec === null) {\n return null;\n }\n const decoderConfig = await this.getDecoderConfig();\n assert(decoderConfig);\n return determineVideoPacketType(this.codec, decoderConfig, packet.data);\n }\n}\n/**\n * Represents an audio track in an input file.\n * @group Input files & tracks\n * @public\n */\nexport class InputAudioTrack extends InputTrack {\n /** @internal */\n constructor(input, backing) {\n super(input, backing);\n this._backing = backing;\n }\n get type() {\n return 'audio';\n }\n get codec() {\n return this._backing.getCodec();\n }\n /** The number of audio channels in the track. */\n get numberOfChannels() {\n return this._backing.getNumberOfChannels();\n }\n /** The track's audio sample rate in hertz. */\n get sampleRate() {\n return this._backing.getSampleRate();\n }\n /**\n * Returns the [decoder configuration](https://www.w3.org/TR/webcodecs/#audio-decoder-config) for decoding the\n * track's packets using an [`AudioDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/AudioDecoder). Returns\n * null if the track's codec is unknown.\n */\n getDecoderConfig() {\n return this._backing.getDecoderConfig();\n }\n async getCodecParameterString() {\n const decoderConfig = await this._backing.getDecoderConfig();\n return decoderConfig?.codec ?? null;\n }\n async canDecode() {\n try {\n const decoderConfig = await this._backing.getDecoderConfig();\n if (!decoderConfig) {\n return false;\n }\n const codec = this._backing.getCodec();\n assert(codec !== null);\n if (customAudioDecoders.some(x => x.supports(codec, decoderConfig))) {\n return true;\n }\n if (decoderConfig.codec.startsWith('pcm-')) {\n return true; // Since we decode it ourselves\n }\n else {\n if (typeof AudioDecoder === 'undefined') {\n return false;\n }\n const support = await AudioDecoder.isConfigSupported(decoderConfig);\n return support.supported === true;\n }\n }\n catch (error) {\n console.error('Error during decodability check:', error);\n return false;\n }\n }\n async determinePacketType(packet) {\n if (!(packet instanceof EncodedPacket)) {\n throw new TypeError('packet must be an EncodedPacket.');\n }\n if (this.codec === null) {\n return null;\n }\n return 'key'; // No audio codec with delta packets\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nexport const buildIsobmffMimeType = (info) => {\n const base = info.hasVideo\n ? 'video/'\n : info.hasAudio\n ? 'audio/'\n : 'application/';\n let string = base + (info.isQuickTime ? 'quicktime' : 'mp4');\n if (info.codecStrings.length > 0) {\n const uniqueCodecMimeTypes = [...new Set(info.codecStrings)];\n string += `; codecs=\"${uniqueCodecMimeTypes.join(', ')}\"`;\n }\n return string;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { RichImageData } from '../metadata.js';\nimport { textDecoder } from '../misc.js';\nimport { readAscii, readBytes, readI32Be, readU16Be, readU32Be, readU64Be, readU8 } from '../reader.js';\nexport const MIN_BOX_HEADER_SIZE = 8;\nexport const MAX_BOX_HEADER_SIZE = 16;\nexport const readBoxHeader = (slice) => {\n let totalSize = readU32Be(slice);\n const name = readAscii(slice, 4);\n let headerSize = 8;\n const hasLargeSize = totalSize === 1;\n if (hasLargeSize) {\n totalSize = readU64Be(slice);\n headerSize = 16;\n }\n const contentSize = totalSize - headerSize;\n if (contentSize < 0) {\n return null; // Hardly a box is it\n }\n return { name, totalSize, headerSize, contentSize };\n};\nexport const readFixed_16_16 = (slice) => {\n return readI32Be(slice) / 0x10000;\n};\nexport const readFixed_2_30 = (slice) => {\n return readI32Be(slice) / 0x40000000;\n};\nexport const readIsomVariableInteger = (slice) => {\n let result = 0;\n for (let i = 0; i < 4; i++) {\n result <<= 7;\n const nextByte = readU8(slice);\n result |= nextByte & 0x7f;\n if ((nextByte & 0x80) === 0) {\n break;\n }\n }\n return result;\n};\nexport const readMetadataStringShort = (slice) => {\n let stringLength = readU16Be(slice);\n slice.skip(2); // Language\n stringLength = Math.min(stringLength, slice.remainingLength);\n return textDecoder.decode(readBytes(slice, stringLength));\n};\nexport const readDataBox = (slice) => {\n const header = readBoxHeader(slice);\n if (!header || header.name !== 'data') {\n return null;\n }\n if (slice.remainingLength < 8) {\n // Box is too small\n return null;\n }\n const typeIndicator = readU32Be(slice);\n slice.skip(4); // Locale indicator\n const data = readBytes(slice, header.contentSize - 8);\n switch (typeIndicator) {\n case 1: return textDecoder.decode(data); // UTF-8\n case 2: return new TextDecoder('utf-16be').decode(data); // UTF-16-BE\n case 13: return new RichImageData(data, 'image/jpeg');\n case 14: return new RichImageData(data, 'image/png');\n case 27: return new RichImageData(data, 'image/bmp');\n default: return data;\n }\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { extractAudioCodecString, extractVideoCodecString, OPUS_SAMPLE_RATE, parseAacAudioSpecificConfig, parsePcmCodec, PCM_AUDIO_CODECS, } from '../codec.js';\nimport { extractAv1CodecInfoFromPacket, extractVp9CodecInfoFromPacket, FlacBlockType, } from '../codec-data.js';\nimport { Demuxer } from '../demuxer.js';\nimport { InputAudioTrack, InputVideoTrack, } from '../input-track.js';\nimport { assert, binarySearchExact, binarySearchLessOrEqual, Bitstream, COLOR_PRIMARIES_MAP_INVERSE, findLastIndex, isIso639Dash2LanguageCode, last, MATRIX_COEFFICIENTS_MAP_INVERSE, normalizeRotation, roundToMultiple, textDecoder, TRANSFER_CHARACTERISTICS_MAP_INVERSE, UNDETERMINED_LANGUAGE, toDataView, roundIfAlmostInteger, } from '../misc.js';\nimport { EncodedPacket, PLACEHOLDER_DATA } from '../packet.js';\nimport { buildIsobmffMimeType } from './isobmff-misc.js';\nimport { MAX_BOX_HEADER_SIZE, MIN_BOX_HEADER_SIZE, readBoxHeader, readDataBox, readFixed_16_16, readFixed_2_30, readIsomVariableInteger, readMetadataStringShort, } from './isobmff-reader.js';\nimport { readBytes, readF64Be, readI16Be, readI32Be, readI64Be, readU16Be, readU24Be, readU32Be, readU64Be, readU8, readAscii, } from '../reader.js';\nimport { DEFAULT_TRACK_DISPOSITION, RichImageData } from '../metadata.js';\nexport class IsobmffDemuxer extends Demuxer {\n constructor(input) {\n super(input);\n this.moovSlice = null;\n this.currentTrack = null;\n this.tracks = [];\n this.metadataPromise = null;\n this.movieTimescale = -1;\n this.movieDurationInTimescale = -1;\n this.isQuickTime = false;\n this.metadataTags = {};\n this.currentMetadataKeys = null;\n this.isFragmented = false;\n this.fragmentTrackDefaults = [];\n this.currentFragment = null;\n /**\n * Caches the last fragment that was read. Based on the assumption that there will be multiple reads to the\n * same fragment in quick succession.\n */\n this.lastReadFragment = null;\n this.reader = input._reader;\n }\n async computeDuration() {\n const tracks = await this.getTracks();\n const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));\n return Math.max(0, ...trackDurations);\n }\n async getTracks() {\n await this.readMetadata();\n return this.tracks.map(track => track.inputTrack);\n }\n async getMimeType() {\n await this.readMetadata();\n const codecStrings = await Promise.all(this.tracks.map(x => x.inputTrack.getCodecParameterString()));\n return buildIsobmffMimeType({\n isQuickTime: this.isQuickTime,\n hasVideo: this.tracks.some(x => x.info?.type === 'video'),\n hasAudio: this.tracks.some(x => x.info?.type === 'audio'),\n codecStrings: codecStrings.filter(Boolean),\n });\n }\n async getMetadataTags() {\n await this.readMetadata();\n return this.metadataTags;\n }\n readMetadata() {\n return this.metadataPromise ??= (async () => {\n let currentPos = 0;\n while (true) {\n let slice = this.reader.requestSliceRange(currentPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const startPos = currentPos;\n const boxInfo = readBoxHeader(slice);\n if (!boxInfo) {\n break;\n }\n if (boxInfo.name === 'ftyp') {\n const majorBrand = readAscii(slice, 4);\n this.isQuickTime = majorBrand === 'qt ';\n }\n else if (boxInfo.name === 'moov') {\n // Found moov, load it\n let moovSlice = this.reader.requestSlice(slice.filePos, boxInfo.contentSize);\n if (moovSlice instanceof Promise)\n moovSlice = await moovSlice;\n if (!moovSlice)\n break;\n this.moovSlice = moovSlice;\n this.readContiguousBoxes(this.moovSlice);\n // Put default tracks first\n this.tracks.sort((a, b) => Number(b.disposition.default) - Number(a.disposition.default));\n for (const track of this.tracks) {\n // Modify the edit list offset based on the previous segment durations. They are in different\n // timescales, so we first convert to seconds and then into the track timescale.\n const previousSegmentDurationsInSeconds = track.editListPreviousSegmentDurations / this.movieTimescale;\n track.editListOffset -= Math.round(previousSegmentDurationsInSeconds * track.timescale);\n }\n break;\n }\n currentPos = startPos + boxInfo.totalSize;\n }\n if (this.isFragmented && this.reader.fileSize !== null) {\n // The last 4 bytes may contain the size of the mfra box at the end of the file\n let lastWordSlice = this.reader.requestSlice(this.reader.fileSize - 4, 4);\n if (lastWordSlice instanceof Promise)\n lastWordSlice = await lastWordSlice;\n assert(lastWordSlice);\n const lastWord = readU32Be(lastWordSlice);\n const potentialMfraPos = this.reader.fileSize - lastWord;\n if (potentialMfraPos >= 0 && potentialMfraPos <= this.reader.fileSize - MAX_BOX_HEADER_SIZE) {\n let mfraHeaderSlice = this.reader.requestSliceRange(potentialMfraPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);\n if (mfraHeaderSlice instanceof Promise)\n mfraHeaderSlice = await mfraHeaderSlice;\n if (mfraHeaderSlice) {\n const boxInfo = readBoxHeader(mfraHeaderSlice);\n if (boxInfo && boxInfo.name === 'mfra') {\n // We found the mfra box, allowing for much better random access. Let's parse it.\n let mfraSlice = this.reader.requestSlice(mfraHeaderSlice.filePos, boxInfo.contentSize);\n if (mfraSlice instanceof Promise)\n mfraSlice = await mfraSlice;\n if (mfraSlice) {\n this.readContiguousBoxes(mfraSlice);\n }\n }\n }\n }\n }\n })();\n }\n getSampleTableForTrack(internalTrack) {\n if (internalTrack.sampleTable) {\n return internalTrack.sampleTable;\n }\n const sampleTable = {\n sampleTimingEntries: [],\n sampleCompositionTimeOffsets: [],\n sampleSizes: [],\n keySampleIndices: null,\n chunkOffsets: [],\n sampleToChunk: [],\n presentationTimestamps: null,\n presentationTimestampIndexMap: null,\n };\n internalTrack.sampleTable = sampleTable;\n assert(this.moovSlice);\n const stblContainerSlice = this.moovSlice.slice(internalTrack.sampleTableByteOffset);\n this.currentTrack = internalTrack;\n this.traverseBox(stblContainerSlice);\n this.currentTrack = null;\n const isPcmCodec = internalTrack.info?.type === 'audio'\n && internalTrack.info.codec\n && PCM_AUDIO_CODECS.includes(internalTrack.info.codec);\n if (isPcmCodec && sampleTable.sampleCompositionTimeOffsets.length === 0) {\n // If the audio has PCM samples, the way the samples are defined in the sample table is somewhat\n // suboptimal: Each individual audio sample is its own sample, meaning we can have 48000 samples per second.\n // Because we treat each sample as its own atomic unit that can be decoded, this would lead to a huge\n // amount of very short samples for PCM audio. So instead, we make a transformation: If the audio is in PCM,\n // we say that each chunk (that normally holds many samples) now is one big sample. We can this because\n // the samples in the chunk are contiguous and the format is PCM, so the entire chunk as one thing still\n // encodes valid audio information.\n assert(internalTrack.info?.type === 'audio');\n const pcmInfo = parsePcmCodec(internalTrack.info.codec);\n const newSampleTimingEntries = [];\n const newSampleSizes = [];\n for (let i = 0; i < sampleTable.sampleToChunk.length; i++) {\n const chunkEntry = sampleTable.sampleToChunk[i];\n const nextEntry = sampleTable.sampleToChunk[i + 1];\n const chunkCount = (nextEntry ? nextEntry.startChunkIndex : sampleTable.chunkOffsets.length)\n - chunkEntry.startChunkIndex;\n for (let j = 0; j < chunkCount; j++) {\n const startSampleIndex = chunkEntry.startSampleIndex + j * chunkEntry.samplesPerChunk;\n const endSampleIndex = startSampleIndex + chunkEntry.samplesPerChunk; // Exclusive, outside of chunk\n const startTimingEntryIndex = binarySearchLessOrEqual(sampleTable.sampleTimingEntries, startSampleIndex, x => x.startIndex);\n const startTimingEntry = sampleTable.sampleTimingEntries[startTimingEntryIndex];\n const endTimingEntryIndex = binarySearchLessOrEqual(sampleTable.sampleTimingEntries, endSampleIndex, x => x.startIndex);\n const endTimingEntry = sampleTable.sampleTimingEntries[endTimingEntryIndex];\n const firstSampleTimestamp = startTimingEntry.startDecodeTimestamp\n + (startSampleIndex - startTimingEntry.startIndex) * startTimingEntry.delta;\n const lastSampleTimestamp = endTimingEntry.startDecodeTimestamp\n + (endSampleIndex - endTimingEntry.startIndex) * endTimingEntry.delta;\n const delta = lastSampleTimestamp - firstSampleTimestamp;\n const lastSampleTimingEntry = last(newSampleTimingEntries);\n if (lastSampleTimingEntry && lastSampleTimingEntry.delta === delta) {\n lastSampleTimingEntry.count++;\n }\n else {\n // One sample for the entire chunk\n newSampleTimingEntries.push({\n startIndex: chunkEntry.startChunkIndex + j,\n startDecodeTimestamp: firstSampleTimestamp,\n count: 1,\n delta,\n });\n }\n // Instead of determining the chunk's size by looping over the samples sizes in the sample table, we\n // can directly compute it as we know how many PCM frames are in this chunk, and the size of each\n // PCM frame. This also improves compatibility with some files which fail to write proper sample\n // size values into their sample tables in the PCM case.\n const chunkSize = chunkEntry.samplesPerChunk\n * pcmInfo.sampleSize\n * internalTrack.info.numberOfChannels;\n newSampleSizes.push(chunkSize);\n }\n chunkEntry.startSampleIndex = chunkEntry.startChunkIndex;\n chunkEntry.samplesPerChunk = 1;\n }\n sampleTable.sampleTimingEntries = newSampleTimingEntries;\n sampleTable.sampleSizes = newSampleSizes;\n }\n if (sampleTable.sampleCompositionTimeOffsets.length > 0) {\n // If composition time offsets are defined, we must build a list of all presentation timestamps and then\n // sort them\n sampleTable.presentationTimestamps = [];\n for (const entry of sampleTable.sampleTimingEntries) {\n for (let i = 0; i < entry.count; i++) {\n sampleTable.presentationTimestamps.push({\n presentationTimestamp: entry.startDecodeTimestamp + i * entry.delta,\n sampleIndex: entry.startIndex + i,\n });\n }\n }\n for (const entry of sampleTable.sampleCompositionTimeOffsets) {\n for (let i = 0; i < entry.count; i++) {\n const sampleIndex = entry.startIndex + i;\n const sample = sampleTable.presentationTimestamps[sampleIndex];\n if (!sample) {\n continue;\n }\n sample.presentationTimestamp += entry.offset;\n }\n }\n sampleTable.presentationTimestamps.sort((a, b) => a.presentationTimestamp - b.presentationTimestamp);\n sampleTable.presentationTimestampIndexMap = Array(sampleTable.presentationTimestamps.length).fill(-1);\n for (let i = 0; i < sampleTable.presentationTimestamps.length; i++) {\n sampleTable.presentationTimestampIndexMap[sampleTable.presentationTimestamps[i].sampleIndex] = i;\n }\n }\n else {\n // If they're not defined, we can simply use the decode timestamps as presentation timestamps\n }\n return sampleTable;\n }\n async readFragment(startPos) {\n if (this.lastReadFragment?.moofOffset === startPos) {\n return this.lastReadFragment;\n }\n let headerSlice = this.reader.requestSliceRange(startPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);\n if (headerSlice instanceof Promise)\n headerSlice = await headerSlice;\n assert(headerSlice);\n const moofBoxInfo = readBoxHeader(headerSlice);\n assert(moofBoxInfo?.name === 'moof');\n let entireSlice = this.reader.requestSlice(startPos, moofBoxInfo.totalSize);\n if (entireSlice instanceof Promise)\n entireSlice = await entireSlice;\n assert(entireSlice);\n this.traverseBox(entireSlice);\n const fragment = this.lastReadFragment;\n assert(fragment && fragment.moofOffset === startPos);\n for (const [, trackData] of fragment.trackData) {\n const track = trackData.track;\n const { fragmentPositionCache } = track;\n if (!trackData.startTimestampIsFinal) {\n // It may be that some tracks don't define the base decode time, i.e. when the fragment begins. This\n // we'll need to figure out the start timestamp another way. We'll compute the timestamp by accessing\n // the lookup entries and fragment cache, which works out nicely with the lookup algorithm: If these\n // exist, then the lookup will automatically start at the furthest possible point. If they don't, the\n // lookup starts sequentially from the start, incrementally summing up all fragment durations. It's sort\n // of implicit, but it ends up working nicely.\n const lookupEntry = track.fragmentLookupTable.find(x => x.moofOffset === fragment.moofOffset);\n if (lookupEntry) {\n // There's a lookup entry, let's use its timestamp\n offsetFragmentTrackDataByTimestamp(trackData, lookupEntry.timestamp);\n }\n else {\n const lastCacheIndex = binarySearchLessOrEqual(fragmentPositionCache, fragment.moofOffset - 1, x => x.moofOffset);\n if (lastCacheIndex !== -1) {\n // Let's use the timestamp of the previous fragment in the cache\n const lastCache = fragmentPositionCache[lastCacheIndex];\n offsetFragmentTrackDataByTimestamp(trackData, lastCache.endTimestamp);\n }\n else {\n // We're the first fragment I guess, \"offset by 0\"\n }\n }\n trackData.startTimestampIsFinal = true;\n }\n // Let's remember that a fragment with a given timestamp is here, speeding up future lookups if no\n // lookup table exists\n const insertionIndex = binarySearchLessOrEqual(fragmentPositionCache, trackData.startTimestamp, x => x.startTimestamp);\n if (insertionIndex === -1\n || fragmentPositionCache[insertionIndex].moofOffset !== fragment.moofOffset) {\n fragmentPositionCache.splice(insertionIndex + 1, 0, {\n moofOffset: fragment.moofOffset,\n startTimestamp: trackData.startTimestamp,\n endTimestamp: trackData.endTimestamp,\n });\n }\n }\n return fragment;\n }\n readContiguousBoxes(slice) {\n const startIndex = slice.filePos;\n while (slice.filePos - startIndex <= slice.length - MIN_BOX_HEADER_SIZE) {\n const foundBox = this.traverseBox(slice);\n if (!foundBox) {\n break;\n }\n }\n }\n // eslint-disable-next-line @stylistic/generator-star-spacing\n *iterateContiguousBoxes(slice) {\n const startIndex = slice.filePos;\n while (slice.filePos - startIndex <= slice.length - MIN_BOX_HEADER_SIZE) {\n const startPos = slice.filePos;\n const boxInfo = readBoxHeader(slice);\n if (!boxInfo) {\n break;\n }\n yield { boxInfo, slice };\n slice.filePos = startPos + boxInfo.totalSize;\n }\n }\n traverseBox(slice) {\n const startPos = slice.filePos;\n const boxInfo = readBoxHeader(slice);\n if (!boxInfo) {\n return false;\n }\n const contentStartPos = slice.filePos;\n const boxEndPos = startPos + boxInfo.totalSize;\n switch (boxInfo.name) {\n case 'mdia':\n case 'minf':\n case 'dinf':\n case 'mfra':\n case 'edts':\n {\n this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n }\n ;\n break;\n case 'mvhd':\n {\n const version = readU8(slice);\n slice.skip(3); // Flags\n if (version === 1) {\n slice.skip(8 + 8);\n this.movieTimescale = readU32Be(slice);\n this.movieDurationInTimescale = readU64Be(slice);\n }\n else {\n slice.skip(4 + 4);\n this.movieTimescale = readU32Be(slice);\n this.movieDurationInTimescale = readU32Be(slice);\n }\n }\n ;\n break;\n case 'trak':\n {\n const track = {\n id: -1,\n demuxer: this,\n inputTrack: null,\n disposition: {\n ...DEFAULT_TRACK_DISPOSITION,\n },\n info: null,\n timescale: -1,\n durationInMovieTimescale: -1,\n durationInMediaTimescale: -1,\n rotation: 0,\n internalCodecId: null,\n name: null,\n languageCode: UNDETERMINED_LANGUAGE,\n sampleTableByteOffset: -1,\n sampleTable: null,\n fragmentLookupTable: [],\n currentFragmentState: null,\n fragmentPositionCache: [],\n editListPreviousSegmentDurations: 0,\n editListOffset: 0,\n };\n this.currentTrack = track;\n this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n if (track.id !== -1 && track.timescale !== -1 && track.info !== null) {\n if (track.info.type === 'video' && track.info.width !== -1) {\n const videoTrack = track;\n track.inputTrack = new InputVideoTrack(this.input, new IsobmffVideoTrackBacking(videoTrack));\n this.tracks.push(track);\n }\n else if (track.info.type === 'audio' && track.info.numberOfChannels !== -1) {\n const audioTrack = track;\n track.inputTrack = new InputAudioTrack(this.input, new IsobmffAudioTrackBacking(audioTrack));\n this.tracks.push(track);\n }\n }\n this.currentTrack = null;\n }\n ;\n break;\n case 'tkhd':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n const version = readU8(slice);\n const flags = readU24Be(slice);\n // Spec says disabled tracks are to be treated like they don't exist, but in practice, they are treated\n // more like non-default tracks.\n const trackEnabled = !!(flags & 0x1);\n track.disposition.default = trackEnabled;\n // Skip over creation & modification time to reach the track ID\n if (version === 0) {\n slice.skip(8);\n track.id = readU32Be(slice);\n slice.skip(4);\n track.durationInMovieTimescale = readU32Be(slice);\n }\n else if (version === 1) {\n slice.skip(16);\n track.id = readU32Be(slice);\n slice.skip(4);\n track.durationInMovieTimescale = readU64Be(slice);\n }\n else {\n throw new Error(`Incorrect track header version ${version}.`);\n }\n slice.skip(2 * 4 + 2 + 2 + 2 + 2);\n const matrix = [\n readFixed_16_16(slice),\n readFixed_16_16(slice),\n readFixed_2_30(slice),\n readFixed_16_16(slice),\n readFixed_16_16(slice),\n readFixed_2_30(slice),\n readFixed_16_16(slice),\n readFixed_16_16(slice),\n readFixed_2_30(slice),\n ];\n const rotation = normalizeRotation(roundToMultiple(extractRotationFromMatrix(matrix), 90));\n assert(rotation === 0 || rotation === 90 || rotation === 180 || rotation === 270);\n track.rotation = rotation;\n }\n ;\n break;\n case 'elst':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n const version = readU8(slice);\n slice.skip(3); // Flags\n let relevantEntryFound = false;\n let previousSegmentDurations = 0;\n const entryCount = readU32Be(slice);\n for (let i = 0; i < entryCount; i++) {\n const segmentDuration = version === 1\n ? readU64Be(slice)\n : readU32Be(slice);\n const mediaTime = version === 1\n ? readI64Be(slice)\n : readI32Be(slice);\n const mediaRate = readFixed_16_16(slice);\n if (segmentDuration === 0) {\n // Don't care\n continue;\n }\n if (relevantEntryFound) {\n console.warn('Unsupported edit list: multiple edits are not currently supported. Only using first edit.');\n break;\n }\n if (mediaTime === -1) {\n previousSegmentDurations += segmentDuration;\n continue;\n }\n if (mediaRate !== 1) {\n console.warn('Unsupported edit list entry: media rate must be 1.');\n break;\n }\n track.editListPreviousSegmentDurations = previousSegmentDurations;\n track.editListOffset = mediaTime;\n relevantEntryFound = true;\n }\n }\n ;\n break;\n case 'mdhd':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n const version = readU8(slice);\n slice.skip(3); // Flags\n if (version === 0) {\n slice.skip(8);\n track.timescale = readU32Be(slice);\n track.durationInMediaTimescale = readU32Be(slice);\n }\n else if (version === 1) {\n slice.skip(16);\n track.timescale = readU32Be(slice);\n track.durationInMediaTimescale = readU64Be(slice);\n }\n let language = readU16Be(slice);\n if (language > 0) {\n track.languageCode = '';\n for (let i = 0; i < 3; i++) {\n track.languageCode = String.fromCharCode(0x60 + (language & 0b11111)) + track.languageCode;\n language >>= 5;\n }\n if (!isIso639Dash2LanguageCode(track.languageCode)) {\n // Sometimes the bytes are garbage\n track.languageCode = UNDETERMINED_LANGUAGE;\n }\n }\n }\n ;\n break;\n case 'hdlr':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n slice.skip(8); // Version + flags + pre-defined\n const handlerType = readAscii(slice, 4);\n if (handlerType === 'vide') {\n track.info = {\n type: 'video',\n width: -1,\n height: -1,\n codec: null,\n codecDescription: null,\n colorSpace: null,\n avcType: null,\n avcCodecInfo: null,\n hevcCodecInfo: null,\n vp9CodecInfo: null,\n av1CodecInfo: null,\n };\n }\n else if (handlerType === 'soun') {\n track.info = {\n type: 'audio',\n numberOfChannels: -1,\n sampleRate: -1,\n codec: null,\n codecDescription: null,\n aacCodecInfo: null,\n };\n }\n }\n ;\n break;\n case 'stbl':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n track.sampleTableByteOffset = startPos;\n this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n }\n ;\n break;\n case 'stsd':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n if (track.info === null || track.sampleTable) {\n break;\n }\n const stsdVersion = readU8(slice);\n slice.skip(3); // Flags\n const entries = readU32Be(slice);\n for (let i = 0; i < entries; i++) {\n const sampleBoxStartPos = slice.filePos;\n const sampleBoxInfo = readBoxHeader(slice);\n if (!sampleBoxInfo) {\n break;\n }\n track.internalCodecId = sampleBoxInfo.name;\n const lowercaseBoxName = sampleBoxInfo.name.toLowerCase();\n if (track.info.type === 'video') {\n if (lowercaseBoxName === 'avc1' || lowercaseBoxName === 'avc3') {\n track.info.codec = 'avc';\n track.info.avcType = lowercaseBoxName === 'avc1' ? 1 : 3;\n }\n else if (lowercaseBoxName === 'hvc1' || lowercaseBoxName === 'hev1') {\n track.info.codec = 'hevc';\n }\n else if (lowercaseBoxName === 'vp08') {\n track.info.codec = 'vp8';\n }\n else if (lowercaseBoxName === 'vp09') {\n track.info.codec = 'vp9';\n }\n else if (lowercaseBoxName === 'av01') {\n track.info.codec = 'av1';\n }\n else {\n console.warn(`Unsupported video codec (sample entry type '${sampleBoxInfo.name}').`);\n }\n slice.skip(6 * 1 + 2 + 2 + 2 + 3 * 4);\n track.info.width = readU16Be(slice);\n track.info.height = readU16Be(slice);\n slice.skip(4 + 4 + 4 + 2 + 32 + 2 + 2);\n this.readContiguousBoxes(slice.slice(slice.filePos, (sampleBoxStartPos + sampleBoxInfo.totalSize) - slice.filePos));\n }\n else {\n if (lowercaseBoxName === 'mp4a') {\n // We don't know the codec yet (might be AAC, might be MP3), need to read the esds box\n }\n else if (lowercaseBoxName === 'opus') {\n track.info.codec = 'opus';\n }\n else if (lowercaseBoxName === 'flac') {\n track.info.codec = 'flac';\n }\n else if (lowercaseBoxName === 'twos'\n || lowercaseBoxName === 'sowt'\n || lowercaseBoxName === 'raw '\n || lowercaseBoxName === 'in24'\n || lowercaseBoxName === 'in32'\n || lowercaseBoxName === 'fl32'\n || lowercaseBoxName === 'fl64'\n || lowercaseBoxName === 'lpcm'\n || lowercaseBoxName === 'ipcm' // ISO/IEC 23003-5\n || lowercaseBoxName === 'fpcm' // \"\n ) {\n // It's PCM\n // developer.apple.com/documentation/quicktime-file-format/sound_sample_descriptions/\n }\n else if (lowercaseBoxName === 'ulaw') {\n track.info.codec = 'ulaw';\n }\n else if (lowercaseBoxName === 'alaw') {\n track.info.codec = 'alaw';\n }\n else {\n console.warn(`Unsupported audio codec (sample entry type '${sampleBoxInfo.name}').`);\n }\n slice.skip(6 * 1 + 2);\n const version = readU16Be(slice);\n slice.skip(3 * 2);\n let channelCount = readU16Be(slice);\n let sampleSize = readU16Be(slice);\n slice.skip(2 * 2);\n // Can't use fixed16_16 as that's signed\n let sampleRate = readU32Be(slice) / 0x10000;\n if (stsdVersion === 0 && version > 0) {\n // Additional QuickTime fields\n if (version === 1) {\n slice.skip(4);\n sampleSize = 8 * readU32Be(slice);\n slice.skip(2 * 4);\n }\n else if (version === 2) {\n slice.skip(4);\n sampleRate = readF64Be(slice);\n channelCount = readU32Be(slice);\n slice.skip(4); // Always 0x7f000000\n sampleSize = readU32Be(slice);\n const flags = readU32Be(slice);\n slice.skip(2 * 4);\n if (lowercaseBoxName === 'lpcm') {\n const bytesPerSample = (sampleSize + 7) >> 3;\n const isFloat = Boolean(flags & 1);\n const isBigEndian = Boolean(flags & 2);\n const sFlags = flags & 4 ? -1 : 0; // I guess it means \"signed flags\" or something?\n if (sampleSize > 0 && sampleSize <= 64) {\n if (isFloat) {\n if (sampleSize === 32) {\n track.info.codec = isBigEndian ? 'pcm-f32be' : 'pcm-f32';\n }\n }\n else {\n if (sFlags & (1 << (bytesPerSample - 1))) {\n if (bytesPerSample === 1) {\n track.info.codec = 'pcm-s8';\n }\n else if (bytesPerSample === 2) {\n track.info.codec = isBigEndian ? 'pcm-s16be' : 'pcm-s16';\n }\n else if (bytesPerSample === 3) {\n track.info.codec = isBigEndian ? 'pcm-s24be' : 'pcm-s24';\n }\n else if (bytesPerSample === 4) {\n track.info.codec = isBigEndian ? 'pcm-s32be' : 'pcm-s32';\n }\n }\n else {\n if (bytesPerSample === 1) {\n track.info.codec = 'pcm-u8';\n }\n }\n }\n }\n if (track.info.codec === null) {\n console.warn('Unsupported PCM format.');\n }\n }\n }\n }\n if (track.info.codec === 'opus') {\n sampleRate = OPUS_SAMPLE_RATE; // Always the same\n }\n track.info.numberOfChannels = channelCount;\n track.info.sampleRate = sampleRate;\n // PCM codec assignments\n if (lowercaseBoxName === 'twos') {\n if (sampleSize === 8) {\n track.info.codec = 'pcm-s8';\n }\n else if (sampleSize === 16) {\n track.info.codec = 'pcm-s16be';\n }\n else {\n console.warn(`Unsupported sample size ${sampleSize} for codec 'twos'.`);\n track.info.codec = null;\n }\n }\n else if (lowercaseBoxName === 'sowt') {\n if (sampleSize === 8) {\n track.info.codec = 'pcm-s8';\n }\n else if (sampleSize === 16) {\n track.info.codec = 'pcm-s16';\n }\n else {\n console.warn(`Unsupported sample size ${sampleSize} for codec 'sowt'.`);\n track.info.codec = null;\n }\n }\n else if (lowercaseBoxName === 'raw ') {\n track.info.codec = 'pcm-u8';\n }\n else if (lowercaseBoxName === 'in24') {\n track.info.codec = 'pcm-s24be';\n }\n else if (lowercaseBoxName === 'in32') {\n track.info.codec = 'pcm-s32be';\n }\n else if (lowercaseBoxName === 'fl32') {\n track.info.codec = 'pcm-f32be';\n }\n else if (lowercaseBoxName === 'fl64') {\n track.info.codec = 'pcm-f64be';\n }\n else if (lowercaseBoxName === 'ipcm') {\n track.info.codec = 'pcm-s16be'; // Placeholder, will be adjusted by the pcmC box\n }\n else if (lowercaseBoxName === 'fpcm') {\n track.info.codec = 'pcm-f32be'; // Placeholder, will be adjusted by the pcmC box\n }\n this.readContiguousBoxes(slice.slice(slice.filePos, (sampleBoxStartPos + sampleBoxInfo.totalSize) - slice.filePos));\n }\n }\n }\n ;\n break;\n case 'avcC':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info);\n track.info.codecDescription = readBytes(slice, boxInfo.contentSize);\n }\n ;\n break;\n case 'hvcC':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info);\n track.info.codecDescription = readBytes(slice, boxInfo.contentSize);\n }\n ;\n break;\n case 'vpcC':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info?.type === 'video');\n slice.skip(4); // Version + flags\n const profile = readU8(slice);\n const level = readU8(slice);\n const thirdByte = readU8(slice);\n const bitDepth = thirdByte >> 4;\n const chromaSubsampling = (thirdByte >> 1) & 0b111;\n const videoFullRangeFlag = thirdByte & 1;\n const colourPrimaries = readU8(slice);\n const transferCharacteristics = readU8(slice);\n const matrixCoefficients = readU8(slice);\n track.info.vp9CodecInfo = {\n profile,\n level,\n bitDepth,\n chromaSubsampling,\n videoFullRangeFlag,\n colourPrimaries,\n transferCharacteristics,\n matrixCoefficients,\n };\n }\n ;\n break;\n case 'av1C':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info?.type === 'video');\n slice.skip(1); // Marker + version\n const secondByte = readU8(slice);\n const profile = secondByte >> 5;\n const level = secondByte & 0b11111;\n const thirdByte = readU8(slice);\n const tier = thirdByte >> 7;\n const highBitDepth = (thirdByte >> 6) & 1;\n const twelveBit = (thirdByte >> 5) & 1;\n const monochrome = (thirdByte >> 4) & 1;\n const chromaSubsamplingX = (thirdByte >> 3) & 1;\n const chromaSubsamplingY = (thirdByte >> 2) & 1;\n const chromaSamplePosition = thirdByte & 0b11;\n // Logic from https://aomediacodec.github.io/av1-spec/av1-spec.pdf\n const bitDepth = profile === 2 && highBitDepth ? (twelveBit ? 12 : 10) : (highBitDepth ? 10 : 8);\n track.info.av1CodecInfo = {\n profile,\n level,\n tier,\n bitDepth,\n monochrome,\n chromaSubsamplingX,\n chromaSubsamplingY,\n chromaSamplePosition,\n };\n }\n ;\n break;\n case 'colr':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info?.type === 'video');\n const colourType = readAscii(slice, 4);\n if (colourType !== 'nclx') {\n break;\n }\n const colourPrimaries = readU16Be(slice);\n const transferCharacteristics = readU16Be(slice);\n const matrixCoefficients = readU16Be(slice);\n const fullRangeFlag = Boolean(readU8(slice) & 0x80);\n track.info.colorSpace = {\n primaries: COLOR_PRIMARIES_MAP_INVERSE[colourPrimaries],\n transfer: TRANSFER_CHARACTERISTICS_MAP_INVERSE[transferCharacteristics],\n matrix: MATRIX_COEFFICIENTS_MAP_INVERSE[matrixCoefficients],\n fullRange: fullRangeFlag,\n };\n }\n ;\n break;\n case 'wave':\n {\n this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n }\n ;\n break;\n case 'esds':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info?.type === 'audio');\n slice.skip(4); // Version + flags\n const tag = readU8(slice);\n assert(tag === 0x03); // ES Descriptor\n readIsomVariableInteger(slice); // Length\n slice.skip(2); // ES ID\n const mixed = readU8(slice);\n const streamDependenceFlag = (mixed & 0x80) !== 0;\n const urlFlag = (mixed & 0x40) !== 0;\n const ocrStreamFlag = (mixed & 0x20) !== 0;\n if (streamDependenceFlag) {\n slice.skip(2);\n }\n if (urlFlag) {\n const urlLength = readU8(slice);\n slice.skip(urlLength);\n }\n if (ocrStreamFlag) {\n slice.skip(2);\n }\n const decoderConfigTag = readU8(slice);\n assert(decoderConfigTag === 0x04); // DecoderConfigDescriptor\n const decoderConfigDescriptorLength = readIsomVariableInteger(slice); // Length\n const payloadStart = slice.filePos;\n const objectTypeIndication = readU8(slice);\n if (objectTypeIndication === 0x40 || objectTypeIndication === 0x67) {\n track.info.codec = 'aac';\n track.info.aacCodecInfo = { isMpeg2: objectTypeIndication === 0x67 };\n }\n else if (objectTypeIndication === 0x69 || objectTypeIndication === 0x6b) {\n track.info.codec = 'mp3';\n }\n else if (objectTypeIndication === 0xdd) {\n track.info.codec = 'vorbis'; // \"nonstandard, gpac uses it\" - FFmpeg\n }\n else {\n console.warn(`Unsupported audio codec (objectTypeIndication ${objectTypeIndication}) - discarding track.`);\n }\n slice.skip(1 + 3 + 4 + 4);\n if (decoderConfigDescriptorLength > slice.filePos - payloadStart) {\n // There's a DecoderSpecificInfo at the end, let's read it\n const decoderSpecificInfoTag = readU8(slice);\n assert(decoderSpecificInfoTag === 0x05); // DecoderSpecificInfo\n const decoderSpecificInfoLength = readIsomVariableInteger(slice);\n track.info.codecDescription = readBytes(slice, decoderSpecificInfoLength);\n if (track.info.codec === 'aac') {\n // Let's try to deduce more accurate values directly from the AudioSpecificConfig:\n const audioSpecificConfig = parseAacAudioSpecificConfig(track.info.codecDescription);\n if (audioSpecificConfig.numberOfChannels !== null) {\n track.info.numberOfChannels = audioSpecificConfig.numberOfChannels;\n }\n if (audioSpecificConfig.sampleRate !== null) {\n track.info.sampleRate = audioSpecificConfig.sampleRate;\n }\n }\n }\n }\n ;\n break;\n case 'enda':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info?.type === 'audio');\n const littleEndian = readU16Be(slice) & 0xff; // 0xff is from FFmpeg\n if (littleEndian) {\n if (track.info.codec === 'pcm-s16be') {\n track.info.codec = 'pcm-s16';\n }\n else if (track.info.codec === 'pcm-s24be') {\n track.info.codec = 'pcm-s24';\n }\n else if (track.info.codec === 'pcm-s32be') {\n track.info.codec = 'pcm-s32';\n }\n else if (track.info.codec === 'pcm-f32be') {\n track.info.codec = 'pcm-f32';\n }\n else if (track.info.codec === 'pcm-f64be') {\n track.info.codec = 'pcm-f64';\n }\n }\n }\n ;\n break;\n case 'pcmC':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info?.type === 'audio');\n slice.skip(1 + 3); // Version + flags\n // ISO/IEC 23003-5\n const formatFlags = readU8(slice);\n const isLittleEndian = Boolean(formatFlags & 0x01);\n const pcmSampleSize = readU8(slice);\n if (track.info.codec === 'pcm-s16be') {\n // ipcm\n if (isLittleEndian) {\n if (pcmSampleSize === 16) {\n track.info.codec = 'pcm-s16';\n }\n else if (pcmSampleSize === 24) {\n track.info.codec = 'pcm-s24';\n }\n else if (pcmSampleSize === 32) {\n track.info.codec = 'pcm-s32';\n }\n else {\n console.warn(`Invalid ipcm sample size ${pcmSampleSize}.`);\n track.info.codec = null;\n }\n }\n else {\n if (pcmSampleSize === 16) {\n track.info.codec = 'pcm-s16be';\n }\n else if (pcmSampleSize === 24) {\n track.info.codec = 'pcm-s24be';\n }\n else if (pcmSampleSize === 32) {\n track.info.codec = 'pcm-s32be';\n }\n else {\n console.warn(`Invalid ipcm sample size ${pcmSampleSize}.`);\n track.info.codec = null;\n }\n }\n }\n else if (track.info.codec === 'pcm-f32be') {\n // fpcm\n if (isLittleEndian) {\n if (pcmSampleSize === 32) {\n track.info.codec = 'pcm-f32';\n }\n else if (pcmSampleSize === 64) {\n track.info.codec = 'pcm-f64';\n }\n else {\n console.warn(`Invalid fpcm sample size ${pcmSampleSize}.`);\n track.info.codec = null;\n }\n }\n else {\n if (pcmSampleSize === 32) {\n track.info.codec = 'pcm-f32be';\n }\n else if (pcmSampleSize === 64) {\n track.info.codec = 'pcm-f64be';\n }\n else {\n console.warn(`Invalid fpcm sample size ${pcmSampleSize}.`);\n track.info.codec = null;\n }\n }\n }\n break;\n }\n ;\n case 'dOps':\n { // Used for Opus audio\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info?.type === 'audio');\n slice.skip(1); // Version\n // https://www.opus-codec.org/docs/opus_in_isobmff.html\n const outputChannelCount = readU8(slice);\n const preSkip = readU16Be(slice);\n const inputSampleRate = readU32Be(slice);\n const outputGain = readI16Be(slice);\n const channelMappingFamily = readU8(slice);\n let channelMappingTable;\n if (channelMappingFamily !== 0) {\n channelMappingTable = readBytes(slice, 2 + outputChannelCount);\n }\n else {\n channelMappingTable = new Uint8Array(0);\n }\n // https://datatracker.ietf.org/doc/html/draft-ietf-codec-oggopus-06\n const description = new Uint8Array(8 + 1 + 1 + 2 + 4 + 2 + 1 + channelMappingTable.byteLength);\n const view = new DataView(description.buffer);\n view.setUint32(0, 0x4f707573, false); // 'Opus'\n view.setUint32(4, 0x48656164, false); // 'Head'\n view.setUint8(8, 1); // Version\n view.setUint8(9, outputChannelCount);\n view.setUint16(10, preSkip, true);\n view.setUint32(12, inputSampleRate, true);\n view.setInt16(16, outputGain, true);\n view.setUint8(18, channelMappingFamily);\n description.set(channelMappingTable, 19);\n track.info.codecDescription = description;\n track.info.numberOfChannels = outputChannelCount;\n // Don't copy the input sample rate, irrelevant, and output sample rate is fixed\n }\n ;\n break;\n case 'dfLa':\n { // Used for FLAC audio\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.info?.type === 'audio');\n slice.skip(4); // Version + flags\n // https://datatracker.ietf.org/doc/rfc9639/\n const BLOCK_TYPE_MASK = 0x7f;\n const LAST_METADATA_BLOCK_FLAG_MASK = 0x80;\n const startPos = slice.filePos;\n while (slice.filePos < boxEndPos) {\n const flagAndType = readU8(slice);\n const metadataBlockLength = readU24Be(slice);\n const type = flagAndType & BLOCK_TYPE_MASK;\n // It's a STREAMINFO block; let's extract the actual sample rate and channel count\n if (type === FlacBlockType.STREAMINFO) {\n slice.skip(10);\n // Extract sample rate and channel count\n const word = readU32Be(slice);\n const sampleRate = word >>> 12;\n const numberOfChannels = ((word >> 9) & 0b111) + 1;\n track.info.sampleRate = sampleRate;\n track.info.numberOfChannels = numberOfChannels;\n slice.skip(20);\n }\n else {\n // Simply skip ahead to the next block\n slice.skip(metadataBlockLength);\n }\n if (flagAndType & LAST_METADATA_BLOCK_FLAG_MASK) {\n break;\n }\n }\n const endPos = slice.filePos;\n slice.filePos = startPos;\n const bytes = readBytes(slice, endPos - startPos);\n const description = new Uint8Array(4 + bytes.byteLength);\n const view = new DataView(description.buffer);\n view.setUint32(0, 0x664c6143, false); // 'fLaC'\n description.set(bytes, 4);\n // Set the codec description to be 'fLaC' + all metadata blocks\n track.info.codecDescription = description;\n }\n ;\n break;\n case 'stts':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n if (!track.sampleTable) {\n break;\n }\n slice.skip(4); // Version + flags\n const entryCount = readU32Be(slice);\n let currentIndex = 0;\n let currentTimestamp = 0;\n for (let i = 0; i < entryCount; i++) {\n const sampleCount = readU32Be(slice);\n const sampleDelta = readU32Be(slice);\n track.sampleTable.sampleTimingEntries.push({\n startIndex: currentIndex,\n startDecodeTimestamp: currentTimestamp,\n count: sampleCount,\n delta: sampleDelta,\n });\n currentIndex += sampleCount;\n currentTimestamp += sampleCount * sampleDelta;\n }\n }\n ;\n break;\n case 'ctts':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n if (!track.sampleTable) {\n break;\n }\n slice.skip(1 + 3); // Version + flags\n const entryCount = readU32Be(slice);\n let sampleIndex = 0;\n for (let i = 0; i < entryCount; i++) {\n const sampleCount = readU32Be(slice);\n const sampleOffset = readI32Be(slice);\n track.sampleTable.sampleCompositionTimeOffsets.push({\n startIndex: sampleIndex,\n count: sampleCount,\n offset: sampleOffset,\n });\n sampleIndex += sampleCount;\n }\n }\n ;\n break;\n case 'stsz':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n if (!track.sampleTable) {\n break;\n }\n slice.skip(4); // Version + flags\n const sampleSize = readU32Be(slice);\n const sampleCount = readU32Be(slice);\n if (sampleSize === 0) {\n for (let i = 0; i < sampleCount; i++) {\n const sampleSize = readU32Be(slice);\n track.sampleTable.sampleSizes.push(sampleSize);\n }\n }\n else {\n track.sampleTable.sampleSizes.push(sampleSize);\n }\n }\n ;\n break;\n case 'stz2':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n if (!track.sampleTable) {\n break;\n }\n slice.skip(4); // Version + flags\n slice.skip(3); // Reserved\n const fieldSize = readU8(slice); // in bits\n const sampleCount = readU32Be(slice);\n const bytes = readBytes(slice, Math.ceil(sampleCount * fieldSize / 8));\n const bitstream = new Bitstream(bytes);\n for (let i = 0; i < sampleCount; i++) {\n const sampleSize = bitstream.readBits(fieldSize);\n track.sampleTable.sampleSizes.push(sampleSize);\n }\n }\n ;\n break;\n case 'stss':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n if (!track.sampleTable) {\n break;\n }\n slice.skip(4); // Version + flags\n track.sampleTable.keySampleIndices = [];\n const entryCount = readU32Be(slice);\n for (let i = 0; i < entryCount; i++) {\n const sampleIndex = readU32Be(slice) - 1; // Convert to 0-indexed\n track.sampleTable.keySampleIndices.push(sampleIndex);\n }\n if (track.sampleTable.keySampleIndices[0] !== 0) {\n // Some files don't mark the first sample a key sample, which is basically almost always incorrect.\n // Here, we correct for that mistake:\n track.sampleTable.keySampleIndices.unshift(0);\n }\n }\n ;\n break;\n case 'stsc':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n if (!track.sampleTable) {\n break;\n }\n slice.skip(4);\n const entryCount = readU32Be(slice);\n for (let i = 0; i < entryCount; i++) {\n const startChunkIndex = readU32Be(slice) - 1; // Convert to 0-indexed\n const samplesPerChunk = readU32Be(slice);\n const sampleDescriptionIndex = readU32Be(slice);\n track.sampleTable.sampleToChunk.push({\n startSampleIndex: -1,\n startChunkIndex,\n samplesPerChunk,\n sampleDescriptionIndex,\n });\n }\n let startSampleIndex = 0;\n for (let i = 0; i < track.sampleTable.sampleToChunk.length; i++) {\n track.sampleTable.sampleToChunk[i].startSampleIndex = startSampleIndex;\n if (i < track.sampleTable.sampleToChunk.length - 1) {\n const nextChunk = track.sampleTable.sampleToChunk[i + 1];\n const chunkCount = nextChunk.startChunkIndex\n - track.sampleTable.sampleToChunk[i].startChunkIndex;\n startSampleIndex += chunkCount * track.sampleTable.sampleToChunk[i].samplesPerChunk;\n }\n }\n }\n ;\n break;\n case 'stco':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n if (!track.sampleTable) {\n break;\n }\n slice.skip(4); // Version + flags\n const entryCount = readU32Be(slice);\n for (let i = 0; i < entryCount; i++) {\n const chunkOffset = readU32Be(slice);\n track.sampleTable.chunkOffsets.push(chunkOffset);\n }\n }\n ;\n break;\n case 'co64':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n if (!track.sampleTable) {\n break;\n }\n slice.skip(4); // Version + flags\n const entryCount = readU32Be(slice);\n for (let i = 0; i < entryCount; i++) {\n const chunkOffset = readU64Be(slice);\n track.sampleTable.chunkOffsets.push(chunkOffset);\n }\n }\n ;\n break;\n case 'mvex':\n {\n this.isFragmented = true;\n this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n }\n ;\n break;\n case 'mehd':\n {\n const version = readU8(slice);\n slice.skip(3); // Flags\n const fragmentDuration = version === 1 ? readU64Be(slice) : readU32Be(slice);\n this.movieDurationInTimescale = fragmentDuration;\n }\n ;\n break;\n case 'trex':\n {\n slice.skip(4); // Version + flags\n const trackId = readU32Be(slice);\n const defaultSampleDescriptionIndex = readU32Be(slice);\n const defaultSampleDuration = readU32Be(slice);\n const defaultSampleSize = readU32Be(slice);\n const defaultSampleFlags = readU32Be(slice);\n // We store these separately rather than in the tracks since the tracks may not exist yet\n this.fragmentTrackDefaults.push({\n trackId,\n defaultSampleDescriptionIndex,\n defaultSampleDuration,\n defaultSampleSize,\n defaultSampleFlags,\n });\n }\n ;\n break;\n case 'tfra':\n {\n const version = readU8(slice);\n slice.skip(3); // Flags\n const trackId = readU32Be(slice);\n const track = this.tracks.find(x => x.id === trackId);\n if (!track) {\n break;\n }\n const word = readU32Be(slice);\n const lengthSizeOfTrafNum = (word & 0b110000) >> 4;\n const lengthSizeOfTrunNum = (word & 0b001100) >> 2;\n const lengthSizeOfSampleNum = word & 0b000011;\n const functions = [readU8, readU16Be, readU24Be, readU32Be];\n const readTrafNum = functions[lengthSizeOfTrafNum];\n const readTrunNum = functions[lengthSizeOfTrunNum];\n const readSampleNum = functions[lengthSizeOfSampleNum];\n const numberOfEntries = readU32Be(slice);\n for (let i = 0; i < numberOfEntries; i++) {\n const time = version === 1 ? readU64Be(slice) : readU32Be(slice);\n const moofOffset = version === 1 ? readU64Be(slice) : readU32Be(slice);\n readTrafNum(slice);\n readTrunNum(slice);\n readSampleNum(slice);\n track.fragmentLookupTable.push({\n timestamp: time,\n moofOffset,\n });\n }\n // Sort by timestamp in case it's not naturally sorted\n track.fragmentLookupTable.sort((a, b) => a.timestamp - b.timestamp);\n // Remove multiple entries for the same time\n for (let i = 0; i < track.fragmentLookupTable.length - 1; i++) {\n const entry1 = track.fragmentLookupTable[i];\n const entry2 = track.fragmentLookupTable[i + 1];\n if (entry1.timestamp === entry2.timestamp) {\n track.fragmentLookupTable.splice(i + 1, 1);\n i--;\n }\n }\n }\n ;\n break;\n case 'moof':\n {\n this.currentFragment = {\n moofOffset: startPos,\n moofSize: boxInfo.totalSize,\n implicitBaseDataOffset: startPos,\n trackData: new Map(),\n };\n this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n this.lastReadFragment = this.currentFragment;\n this.currentFragment = null;\n }\n ;\n break;\n case 'traf':\n {\n assert(this.currentFragment);\n this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n // It is possible that there is no current track, for example when we don't care about the track\n // referenced in the track fragment header.\n if (this.currentTrack) {\n const trackData = this.currentFragment.trackData.get(this.currentTrack.id);\n if (trackData) {\n const { currentFragmentState } = this.currentTrack;\n assert(currentFragmentState);\n if (currentFragmentState.startTimestamp !== null) {\n offsetFragmentTrackDataByTimestamp(trackData, currentFragmentState.startTimestamp);\n trackData.startTimestampIsFinal = true;\n }\n }\n this.currentTrack.currentFragmentState = null;\n this.currentTrack = null;\n }\n }\n ;\n break;\n case 'tfhd':\n {\n assert(this.currentFragment);\n slice.skip(1); // Version\n const flags = readU24Be(slice);\n const baseDataOffsetPresent = Boolean(flags & 0x000001);\n const sampleDescriptionIndexPresent = Boolean(flags & 0x000002);\n const defaultSampleDurationPresent = Boolean(flags & 0x000008);\n const defaultSampleSizePresent = Boolean(flags & 0x000010);\n const defaultSampleFlagsPresent = Boolean(flags & 0x000020);\n const durationIsEmpty = Boolean(flags & 0x010000);\n const defaultBaseIsMoof = Boolean(flags & 0x020000);\n const trackId = readU32Be(slice);\n const track = this.tracks.find(x => x.id === trackId);\n if (!track) {\n // We don't care about this track\n break;\n }\n const defaults = this.fragmentTrackDefaults.find(x => x.trackId === trackId);\n this.currentTrack = track;\n track.currentFragmentState = {\n baseDataOffset: this.currentFragment.implicitBaseDataOffset,\n sampleDescriptionIndex: defaults?.defaultSampleDescriptionIndex ?? null,\n defaultSampleDuration: defaults?.defaultSampleDuration ?? null,\n defaultSampleSize: defaults?.defaultSampleSize ?? null,\n defaultSampleFlags: defaults?.defaultSampleFlags ?? null,\n startTimestamp: null,\n };\n if (baseDataOffsetPresent) {\n track.currentFragmentState.baseDataOffset = readU64Be(slice);\n }\n else if (defaultBaseIsMoof) {\n track.currentFragmentState.baseDataOffset = this.currentFragment.moofOffset;\n }\n if (sampleDescriptionIndexPresent) {\n track.currentFragmentState.sampleDescriptionIndex = readU32Be(slice);\n }\n if (defaultSampleDurationPresent) {\n track.currentFragmentState.defaultSampleDuration = readU32Be(slice);\n }\n if (defaultSampleSizePresent) {\n track.currentFragmentState.defaultSampleSize = readU32Be(slice);\n }\n if (defaultSampleFlagsPresent) {\n track.currentFragmentState.defaultSampleFlags = readU32Be(slice);\n }\n if (durationIsEmpty) {\n track.currentFragmentState.defaultSampleDuration = 0;\n }\n }\n ;\n break;\n case 'tfdt':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(track.currentFragmentState);\n const version = readU8(slice);\n slice.skip(3); // Flags\n const baseMediaDecodeTime = version === 0 ? readU32Be(slice) : readU64Be(slice);\n track.currentFragmentState.startTimestamp = baseMediaDecodeTime;\n }\n ;\n break;\n case 'trun':\n {\n const track = this.currentTrack;\n if (!track) {\n break;\n }\n assert(this.currentFragment);\n assert(track.currentFragmentState);\n if (this.currentFragment.trackData.has(track.id)) {\n console.warn('Can\\'t have two trun boxes for the same track in one fragment. Ignoring...');\n break;\n }\n const version = readU8(slice);\n const flags = readU24Be(slice);\n const dataOffsetPresent = Boolean(flags & 0x000001);\n const firstSampleFlagsPresent = Boolean(flags & 0x000004);\n const sampleDurationPresent = Boolean(flags & 0x000100);\n const sampleSizePresent = Boolean(flags & 0x000200);\n const sampleFlagsPresent = Boolean(flags & 0x000400);\n const sampleCompositionTimeOffsetsPresent = Boolean(flags & 0x000800);\n const sampleCount = readU32Be(slice);\n let dataOffset = track.currentFragmentState.baseDataOffset;\n if (dataOffsetPresent) {\n dataOffset += readI32Be(slice);\n }\n let firstSampleFlags = null;\n if (firstSampleFlagsPresent) {\n firstSampleFlags = readU32Be(slice);\n }\n let currentOffset = dataOffset;\n if (sampleCount === 0) {\n // Don't associate the fragment with the track if it has no samples, this simplifies other code\n this.currentFragment.implicitBaseDataOffset = currentOffset;\n break;\n }\n let currentTimestamp = 0;\n const trackData = {\n track,\n startTimestamp: 0,\n endTimestamp: 0,\n firstKeyFrameTimestamp: null,\n samples: [],\n presentationTimestamps: [],\n startTimestampIsFinal: false,\n };\n this.currentFragment.trackData.set(track.id, trackData);\n for (let i = 0; i < sampleCount; i++) {\n let sampleDuration;\n if (sampleDurationPresent) {\n sampleDuration = readU32Be(slice);\n }\n else {\n assert(track.currentFragmentState.defaultSampleDuration !== null);\n sampleDuration = track.currentFragmentState.defaultSampleDuration;\n }\n let sampleSize;\n if (sampleSizePresent) {\n sampleSize = readU32Be(slice);\n }\n else {\n assert(track.currentFragmentState.defaultSampleSize !== null);\n sampleSize = track.currentFragmentState.defaultSampleSize;\n }\n let sampleFlags;\n if (sampleFlagsPresent) {\n sampleFlags = readU32Be(slice);\n }\n else {\n assert(track.currentFragmentState.defaultSampleFlags !== null);\n sampleFlags = track.currentFragmentState.defaultSampleFlags;\n }\n if (i === 0 && firstSampleFlags !== null) {\n sampleFlags = firstSampleFlags;\n }\n let sampleCompositionTimeOffset = 0;\n if (sampleCompositionTimeOffsetsPresent) {\n if (version === 0) {\n sampleCompositionTimeOffset = readU32Be(slice);\n }\n else {\n sampleCompositionTimeOffset = readI32Be(slice);\n }\n }\n const isKeyFrame = !(sampleFlags & 0x00010000);\n trackData.samples.push({\n presentationTimestamp: currentTimestamp + sampleCompositionTimeOffset,\n duration: sampleDuration,\n byteOffset: currentOffset,\n byteSize: sampleSize,\n isKeyFrame,\n });\n currentOffset += sampleSize;\n currentTimestamp += sampleDuration;\n }\n trackData.presentationTimestamps = trackData.samples\n .map((x, i) => ({ presentationTimestamp: x.presentationTimestamp, sampleIndex: i }))\n .sort((a, b) => a.presentationTimestamp - b.presentationTimestamp);\n for (let i = 0; i < trackData.presentationTimestamps.length; i++) {\n const currentEntry = trackData.presentationTimestamps[i];\n const currentSample = trackData.samples[currentEntry.sampleIndex];\n if (trackData.firstKeyFrameTimestamp === null && currentSample.isKeyFrame) {\n trackData.firstKeyFrameTimestamp = currentSample.presentationTimestamp;\n }\n if (i < trackData.presentationTimestamps.length - 1) {\n // Update sample durations based on presentation order\n const nextEntry = trackData.presentationTimestamps[i + 1];\n currentSample.duration = nextEntry.presentationTimestamp - currentEntry.presentationTimestamp;\n }\n }\n const firstSample = trackData.samples[trackData.presentationTimestamps[0].sampleIndex];\n const lastSample = trackData.samples[last(trackData.presentationTimestamps).sampleIndex];\n trackData.startTimestamp = firstSample.presentationTimestamp;\n trackData.endTimestamp = lastSample.presentationTimestamp + lastSample.duration;\n this.currentFragment.implicitBaseDataOffset = currentOffset;\n }\n ;\n break;\n // Metadata section\n // https://exiftool.org/TagNames/QuickTime.html\n // https://mp4workshop.com/about\n case 'udta':\n { // Contains either movie metadata or track metadata\n const iterator = this.iterateContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n for (const { boxInfo, slice } of iterator) {\n if (boxInfo.name !== 'meta' && !this.currentTrack) {\n const startPos = slice.filePos;\n this.metadataTags.raw ??= {};\n if (boxInfo.name[0] === '\u00A9') {\n // https://mp4workshop.com/about\n // Box name starting with \u00A9 indicates \"international text\"\n this.metadataTags.raw[boxInfo.name] ??= readMetadataStringShort(slice);\n }\n else {\n this.metadataTags.raw[boxInfo.name] ??= readBytes(slice, boxInfo.contentSize);\n }\n slice.filePos = startPos;\n }\n switch (boxInfo.name) {\n case 'meta':\n {\n slice.skip(-boxInfo.headerSize);\n this.traverseBox(slice);\n }\n ;\n break;\n case '\u00A9nam':\n case 'name':\n {\n if (this.currentTrack) {\n this.currentTrack.name = textDecoder.decode(readBytes(slice, boxInfo.contentSize));\n }\n else {\n this.metadataTags.title ??= readMetadataStringShort(slice);\n }\n }\n ;\n break;\n case '\u00A9des':\n {\n if (!this.currentTrack) {\n this.metadataTags.description ??= readMetadataStringShort(slice);\n }\n }\n ;\n break;\n case '\u00A9ART':\n {\n if (!this.currentTrack) {\n this.metadataTags.artist ??= readMetadataStringShort(slice);\n }\n }\n ;\n break;\n case '\u00A9alb':\n {\n if (!this.currentTrack) {\n this.metadataTags.album ??= readMetadataStringShort(slice);\n }\n }\n ;\n break;\n case 'albr':\n {\n if (!this.currentTrack) {\n this.metadataTags.albumArtist ??= readMetadataStringShort(slice);\n }\n }\n ;\n break;\n case '\u00A9gen':\n {\n if (!this.currentTrack) {\n this.metadataTags.genre ??= readMetadataStringShort(slice);\n }\n }\n ;\n break;\n case '\u00A9day':\n {\n if (!this.currentTrack) {\n const date = new Date(readMetadataStringShort(slice));\n if (!Number.isNaN(date.getTime())) {\n this.metadataTags.date ??= date;\n }\n }\n }\n ;\n break;\n case '\u00A9cmt':\n {\n if (!this.currentTrack) {\n this.metadataTags.comment ??= readMetadataStringShort(slice);\n }\n }\n ;\n break;\n case '\u00A9lyr':\n {\n if (!this.currentTrack) {\n this.metadataTags.lyrics ??= readMetadataStringShort(slice);\n }\n }\n ;\n break;\n }\n }\n }\n ;\n break;\n case 'meta':\n {\n if (this.currentTrack) {\n break; // Only care about movie-level metadata for now\n }\n // The 'meta' box comes in two flavors, one with flags/version and one without. To know which is which,\n // let's read the next 4 bytes, which are either the version or the size of the first subbox.\n const word = readU32Be(slice);\n const isQuickTime = word !== 0;\n this.currentMetadataKeys = new Map();\n if (isQuickTime) {\n this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n }\n else {\n this.readContiguousBoxes(slice.slice(contentStartPos + 4, boxInfo.contentSize - 4));\n }\n this.currentMetadataKeys = null;\n }\n ;\n break;\n case 'keys':\n {\n if (!this.currentMetadataKeys) {\n break;\n }\n slice.skip(4); // Version + flags\n const entryCount = readU32Be(slice);\n for (let i = 0; i < entryCount; i++) {\n const keySize = readU32Be(slice);\n slice.skip(4); // Key namespace\n const keyName = textDecoder.decode(readBytes(slice, keySize - 8));\n this.currentMetadataKeys.set(i + 1, keyName);\n }\n }\n ;\n break;\n case 'ilst':\n {\n if (!this.currentMetadataKeys) {\n break;\n }\n const iterator = this.iterateContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));\n for (const { boxInfo, slice } of iterator) {\n let metadataKey = boxInfo.name;\n // Interpret the box name as a u32be\n const nameAsNumber = (metadataKey.charCodeAt(0) << 24)\n + (metadataKey.charCodeAt(1) << 16)\n + (metadataKey.charCodeAt(2) << 8)\n + metadataKey.charCodeAt(3);\n if (this.currentMetadataKeys.has(nameAsNumber)) {\n // An entry exists for this number\n metadataKey = this.currentMetadataKeys.get(nameAsNumber);\n }\n const data = readDataBox(slice);\n this.metadataTags.raw ??= {};\n this.metadataTags.raw[metadataKey] ??= data;\n switch (metadataKey) {\n case '\u00A9nam':\n case 'titl':\n case 'com.apple.quicktime.title':\n case 'title':\n {\n if (typeof data === 'string') {\n this.metadataTags.title ??= data;\n }\n }\n ;\n break;\n case '\u00A9des':\n case 'desc':\n case 'dscp':\n case 'com.apple.quicktime.description':\n case 'description':\n {\n if (typeof data === 'string') {\n this.metadataTags.description ??= data;\n }\n }\n ;\n break;\n case '\u00A9ART':\n case 'com.apple.quicktime.artist':\n case 'artist':\n {\n if (typeof data === 'string') {\n this.metadataTags.artist ??= data;\n }\n }\n ;\n break;\n case '\u00A9alb':\n case 'albm':\n case 'com.apple.quicktime.album':\n case 'album':\n {\n if (typeof data === 'string') {\n this.metadataTags.album ??= data;\n }\n }\n ;\n break;\n case 'aART':\n case 'album_artist':\n {\n if (typeof data === 'string') {\n this.metadataTags.albumArtist ??= data;\n }\n }\n ;\n break;\n case '\u00A9cmt':\n case 'com.apple.quicktime.comment':\n case 'comment':\n {\n if (typeof data === 'string') {\n this.metadataTags.comment ??= data;\n }\n }\n ;\n break;\n case '\u00A9gen':\n case 'gnre':\n case 'com.apple.quicktime.genre':\n case 'genre':\n {\n if (typeof data === 'string') {\n this.metadataTags.genre ??= data;\n }\n }\n ;\n break;\n case '\u00A9lyr':\n case 'lyrics':\n {\n if (typeof data === 'string') {\n this.metadataTags.lyrics ??= data;\n }\n }\n ;\n break;\n case '\u00A9day':\n case 'rldt':\n case 'com.apple.quicktime.creationdate':\n case 'date':\n {\n if (typeof data === 'string') {\n const date = new Date(data);\n if (!Number.isNaN(date.getTime())) {\n this.metadataTags.date ??= date;\n }\n }\n }\n ;\n break;\n case 'covr':\n case 'com.apple.quicktime.artwork':\n {\n if (data instanceof RichImageData) {\n this.metadataTags.images ??= [];\n this.metadataTags.images.push({\n data: data.data,\n kind: 'coverFront',\n mimeType: data.mimeType,\n });\n }\n else if (data instanceof Uint8Array) {\n this.metadataTags.images ??= [];\n this.metadataTags.images.push({\n data,\n kind: 'coverFront',\n mimeType: 'image/*',\n });\n }\n }\n ;\n break;\n case 'track':\n {\n if (typeof data === 'string') {\n const parts = data.split('/');\n const trackNum = Number.parseInt(parts[0], 10);\n const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);\n if (Number.isInteger(trackNum) && trackNum > 0) {\n this.metadataTags.trackNumber ??= trackNum;\n }\n if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {\n this.metadataTags.tracksTotal ??= tracksTotal;\n }\n }\n }\n ;\n break;\n case 'trkn':\n {\n if (data instanceof Uint8Array && data.length >= 6) {\n const view = toDataView(data);\n const trackNumber = view.getUint16(2, false);\n const tracksTotal = view.getUint16(4, false);\n if (trackNumber > 0) {\n this.metadataTags.trackNumber ??= trackNumber;\n }\n if (tracksTotal > 0) {\n this.metadataTags.tracksTotal ??= tracksTotal;\n }\n }\n }\n ;\n break;\n case 'disc':\n case 'disk':\n {\n if (data instanceof Uint8Array && data.length >= 6) {\n const view = toDataView(data);\n const discNumber = view.getUint16(2, false);\n const discNumberMax = view.getUint16(4, false);\n if (discNumber > 0) {\n this.metadataTags.discNumber ??= discNumber;\n }\n if (discNumberMax > 0) {\n this.metadataTags.discsTotal ??= discNumberMax;\n }\n }\n }\n ;\n break;\n }\n }\n }\n ;\n break;\n }\n slice.filePos = boxEndPos;\n return true;\n }\n}\nclass IsobmffTrackBacking {\n constructor(internalTrack) {\n this.internalTrack = internalTrack;\n this.packetToSampleIndex = new WeakMap();\n this.packetToFragmentLocation = new WeakMap();\n }\n getId() {\n return this.internalTrack.id;\n }\n getCodec() {\n throw new Error('Not implemented on base class.');\n }\n getInternalCodecId() {\n return this.internalTrack.internalCodecId;\n }\n getName() {\n return this.internalTrack.name;\n }\n getLanguageCode() {\n return this.internalTrack.languageCode;\n }\n getTimeResolution() {\n return this.internalTrack.timescale;\n }\n getDisposition() {\n return this.internalTrack.disposition;\n }\n async computeDuration() {\n const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });\n return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);\n }\n async getFirstTimestamp() {\n const firstPacket = await this.getFirstPacket({ metadataOnly: true });\n return firstPacket?.timestamp ?? 0;\n }\n async getFirstPacket(options) {\n const regularPacket = await this.fetchPacketForSampleIndex(0, options);\n if (regularPacket || !this.internalTrack.demuxer.isFragmented) {\n // If there's a non-fragmented packet, always prefer that\n return regularPacket;\n }\n return this.performFragmentedLookup(null, (fragment) => {\n const trackData = fragment.trackData.get(this.internalTrack.id);\n if (trackData) {\n return {\n sampleIndex: 0,\n correctSampleFound: true,\n };\n }\n return {\n sampleIndex: -1,\n correctSampleFound: false,\n };\n }, -Infinity, // Use -Infinity as a search timestamp to avoid using the lookup entries\n Infinity, options);\n }\n mapTimestampIntoTimescale(timestamp) {\n // Do a little rounding to catch cases where the result is very close to an integer. If it is, it's likely\n // that the number was originally an integer divided by the timescale. For stability, it's best\n // to return the integer in this case.\n return roundIfAlmostInteger(timestamp * this.internalTrack.timescale) + this.internalTrack.editListOffset;\n }\n async getPacket(timestamp, options) {\n const timestampInTimescale = this.mapTimestampIntoTimescale(timestamp);\n const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);\n const sampleIndex = getSampleIndexForTimestamp(sampleTable, timestampInTimescale);\n const regularPacket = await this.fetchPacketForSampleIndex(sampleIndex, options);\n if (!sampleTableIsEmpty(sampleTable) || !this.internalTrack.demuxer.isFragmented) {\n // Prefer the non-fragmented packet\n return regularPacket;\n }\n return this.performFragmentedLookup(null, (fragment) => {\n const trackData = fragment.trackData.get(this.internalTrack.id);\n if (!trackData) {\n return { sampleIndex: -1, correctSampleFound: false };\n }\n const index = binarySearchLessOrEqual(trackData.presentationTimestamps, timestampInTimescale, x => x.presentationTimestamp);\n const sampleIndex = index !== -1 ? trackData.presentationTimestamps[index].sampleIndex : -1;\n const correctSampleFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;\n return { sampleIndex, correctSampleFound };\n }, timestampInTimescale, timestampInTimescale, options);\n }\n async getNextPacket(packet, options) {\n const regularSampleIndex = this.packetToSampleIndex.get(packet);\n if (regularSampleIndex !== undefined) {\n // Prefer the non-fragmented packet\n return this.fetchPacketForSampleIndex(regularSampleIndex + 1, options);\n }\n const locationInFragment = this.packetToFragmentLocation.get(packet);\n if (locationInFragment === undefined) {\n throw new Error('Packet was not created from this track.');\n }\n return this.performFragmentedLookup(locationInFragment.fragment, (fragment) => {\n if (fragment === locationInFragment.fragment) {\n const trackData = fragment.trackData.get(this.internalTrack.id);\n if (locationInFragment.sampleIndex + 1 < trackData.samples.length) {\n // We can simply take the next sample in the fragment\n return {\n sampleIndex: locationInFragment.sampleIndex + 1,\n correctSampleFound: true,\n };\n }\n }\n else {\n const trackData = fragment.trackData.get(this.internalTrack.id);\n if (trackData) {\n return {\n sampleIndex: 0,\n correctSampleFound: true,\n };\n }\n }\n return {\n sampleIndex: -1,\n correctSampleFound: false,\n };\n }, -Infinity, // Use -Infinity as a search timestamp to avoid using the lookup entries\n Infinity, options);\n }\n async getKeyPacket(timestamp, options) {\n const timestampInTimescale = this.mapTimestampIntoTimescale(timestamp);\n const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);\n const sampleIndex = getKeyframeSampleIndexForTimestamp(sampleTable, timestampInTimescale);\n const regularPacket = await this.fetchPacketForSampleIndex(sampleIndex, options);\n if (!sampleTableIsEmpty(sampleTable) || !this.internalTrack.demuxer.isFragmented) {\n // Prefer the non-fragmented packet\n return regularPacket;\n }\n return this.performFragmentedLookup(null, (fragment) => {\n const trackData = fragment.trackData.get(this.internalTrack.id);\n if (!trackData) {\n return { sampleIndex: -1, correctSampleFound: false };\n }\n const index = findLastIndex(trackData.presentationTimestamps, (x) => {\n const sample = trackData.samples[x.sampleIndex];\n return sample.isKeyFrame && x.presentationTimestamp <= timestampInTimescale;\n });\n const sampleIndex = index !== -1 ? trackData.presentationTimestamps[index].sampleIndex : -1;\n const correctSampleFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;\n return { sampleIndex, correctSampleFound };\n }, timestampInTimescale, timestampInTimescale, options);\n }\n async getNextKeyPacket(packet, options) {\n const regularSampleIndex = this.packetToSampleIndex.get(packet);\n if (regularSampleIndex !== undefined) {\n // Prefer the non-fragmented packet\n const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);\n const nextKeyFrameSampleIndex = getNextKeyframeIndexForSample(sampleTable, regularSampleIndex);\n return this.fetchPacketForSampleIndex(nextKeyFrameSampleIndex, options);\n }\n const locationInFragment = this.packetToFragmentLocation.get(packet);\n if (locationInFragment === undefined) {\n throw new Error('Packet was not created from this track.');\n }\n return this.performFragmentedLookup(locationInFragment.fragment, (fragment) => {\n if (fragment === locationInFragment.fragment) {\n const trackData = fragment.trackData.get(this.internalTrack.id);\n const nextKeyFrameIndex = trackData.samples.findIndex((x, i) => x.isKeyFrame && i > locationInFragment.sampleIndex);\n if (nextKeyFrameIndex !== -1) {\n // We can simply take the next key frame in the fragment\n return {\n sampleIndex: nextKeyFrameIndex,\n correctSampleFound: true,\n };\n }\n }\n else {\n const trackData = fragment.trackData.get(this.internalTrack.id);\n if (trackData && trackData.firstKeyFrameTimestamp !== null) {\n const keyFrameIndex = trackData.samples.findIndex(x => x.isKeyFrame);\n assert(keyFrameIndex !== -1); // There must be one\n return {\n sampleIndex: keyFrameIndex,\n correctSampleFound: true,\n };\n }\n }\n return {\n sampleIndex: -1,\n correctSampleFound: false,\n };\n }, -Infinity, // Use -Infinity as a search timestamp to avoid using the lookup entries\n Infinity, options);\n }\n async fetchPacketForSampleIndex(sampleIndex, options) {\n if (sampleIndex === -1) {\n return null;\n }\n const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);\n const sampleInfo = getSampleInfo(sampleTable, sampleIndex);\n if (!sampleInfo) {\n return null;\n }\n let data;\n if (options.metadataOnly) {\n data = PLACEHOLDER_DATA;\n }\n else {\n let slice = this.internalTrack.demuxer.reader.requestSlice(sampleInfo.sampleOffset, sampleInfo.sampleSize);\n if (slice instanceof Promise)\n slice = await slice;\n assert(slice);\n data = readBytes(slice, sampleInfo.sampleSize);\n }\n const timestamp = (sampleInfo.presentationTimestamp - this.internalTrack.editListOffset)\n / this.internalTrack.timescale;\n const duration = sampleInfo.duration / this.internalTrack.timescale;\n const packet = new EncodedPacket(data, sampleInfo.isKeyFrame ? 'key' : 'delta', timestamp, duration, sampleIndex, sampleInfo.sampleSize);\n this.packetToSampleIndex.set(packet, sampleIndex);\n return packet;\n }\n async fetchPacketInFragment(fragment, sampleIndex, options) {\n if (sampleIndex === -1) {\n return null;\n }\n const trackData = fragment.trackData.get(this.internalTrack.id);\n const fragmentSample = trackData.samples[sampleIndex];\n assert(fragmentSample);\n let data;\n if (options.metadataOnly) {\n data = PLACEHOLDER_DATA;\n }\n else {\n let slice = this.internalTrack.demuxer.reader.requestSlice(fragmentSample.byteOffset, fragmentSample.byteSize);\n if (slice instanceof Promise)\n slice = await slice;\n assert(slice);\n data = readBytes(slice, fragmentSample.byteSize);\n }\n const timestamp = (fragmentSample.presentationTimestamp - this.internalTrack.editListOffset)\n / this.internalTrack.timescale;\n const duration = fragmentSample.duration / this.internalTrack.timescale;\n const packet = new EncodedPacket(data, fragmentSample.isKeyFrame ? 'key' : 'delta', timestamp, duration, fragment.moofOffset + sampleIndex, fragmentSample.byteSize);\n this.packetToFragmentLocation.set(packet, { fragment, sampleIndex });\n return packet;\n }\n /** Looks for a packet in the fragments while trying to load as few fragments as possible to retrieve it. */\n async performFragmentedLookup(\n // The fragment where we start looking\n startFragment, \n // This function returns the best-matching sample in a given fragment\n getMatchInFragment, \n // The timestamp with which we can search the lookup table\n searchTimestamp, \n // The timestamp for which we know the correct sample will not come after it\n latestTimestamp, options) {\n const demuxer = this.internalTrack.demuxer;\n let currentFragment = null;\n let bestFragment = null;\n let bestSampleIndex = -1;\n if (startFragment) {\n const { sampleIndex, correctSampleFound } = getMatchInFragment(startFragment);\n if (correctSampleFound) {\n return this.fetchPacketInFragment(startFragment, sampleIndex, options);\n }\n if (sampleIndex !== -1) {\n bestFragment = startFragment;\n bestSampleIndex = sampleIndex;\n }\n }\n // Search for a lookup entry; this way, we won't need to start searching from the start of the file\n // but can jump right into the correct fragment (or at least nearby).\n const lookupEntryIndex = binarySearchLessOrEqual(this.internalTrack.fragmentLookupTable, searchTimestamp, x => x.timestamp);\n const lookupEntry = lookupEntryIndex !== -1\n ? this.internalTrack.fragmentLookupTable[lookupEntryIndex]\n : null;\n const positionCacheIndex = binarySearchLessOrEqual(this.internalTrack.fragmentPositionCache, searchTimestamp, x => x.startTimestamp);\n const positionCacheEntry = positionCacheIndex !== -1\n ? this.internalTrack.fragmentPositionCache[positionCacheIndex]\n : null;\n const lookupEntryPosition = Math.max(lookupEntry?.moofOffset ?? 0, positionCacheEntry?.moofOffset ?? 0) || null;\n let currentPos;\n if (!startFragment) {\n currentPos = lookupEntryPosition ?? 0;\n }\n else {\n if (lookupEntryPosition === null || startFragment.moofOffset >= lookupEntryPosition) {\n currentPos = startFragment.moofOffset + startFragment.moofSize;\n currentFragment = startFragment;\n }\n else {\n // Use the lookup entry\n currentPos = lookupEntryPosition;\n }\n }\n while (true) {\n if (currentFragment) {\n const trackData = currentFragment.trackData.get(this.internalTrack.id);\n if (trackData && trackData.startTimestamp > latestTimestamp) {\n // We're already past the upper bound, no need to keep searching\n break;\n }\n }\n // Load the header\n let slice = demuxer.reader.requestSliceRange(currentPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const boxStartPos = currentPos;\n const boxInfo = readBoxHeader(slice);\n if (!boxInfo) {\n break;\n }\n if (boxInfo.name === 'moof') {\n currentFragment = await demuxer.readFragment(boxStartPos);\n const { sampleIndex, correctSampleFound } = getMatchInFragment(currentFragment);\n if (correctSampleFound) {\n return this.fetchPacketInFragment(currentFragment, sampleIndex, options);\n }\n if (sampleIndex !== -1) {\n bestFragment = currentFragment;\n bestSampleIndex = sampleIndex;\n }\n }\n currentPos = boxStartPos + boxInfo.totalSize;\n }\n // Catch faulty lookup table entries\n if (lookupEntry && (!bestFragment || bestFragment.moofOffset < lookupEntry.moofOffset)) {\n // The lookup table entry lied to us! We found a lookup entry but no fragment there that satisfied\n // the match. In this case, let's search again but using the lookup entry before that.\n const previousLookupEntry = this.internalTrack.fragmentLookupTable[lookupEntryIndex - 1];\n assert(!previousLookupEntry || previousLookupEntry.timestamp < lookupEntry.timestamp);\n const newSearchTimestamp = previousLookupEntry?.timestamp ?? -Infinity;\n return this.performFragmentedLookup(null, getMatchInFragment, newSearchTimestamp, latestTimestamp, options);\n }\n if (bestFragment) {\n // If we finished looping but didn't find a perfect match, still return the best match we found\n return this.fetchPacketInFragment(bestFragment, bestSampleIndex, options);\n }\n return null;\n }\n}\nclass IsobmffVideoTrackBacking extends IsobmffTrackBacking {\n constructor(internalTrack) {\n super(internalTrack);\n this.decoderConfigPromise = null;\n this.internalTrack = internalTrack;\n }\n getCodec() {\n return this.internalTrack.info.codec;\n }\n getCodedWidth() {\n return this.internalTrack.info.width;\n }\n getCodedHeight() {\n return this.internalTrack.info.height;\n }\n getRotation() {\n return this.internalTrack.rotation;\n }\n async getColorSpace() {\n return {\n primaries: this.internalTrack.info.colorSpace?.primaries,\n transfer: this.internalTrack.info.colorSpace?.transfer,\n matrix: this.internalTrack.info.colorSpace?.matrix,\n fullRange: this.internalTrack.info.colorSpace?.fullRange,\n };\n }\n async canBeTransparent() {\n return false;\n }\n async getDecoderConfig() {\n if (!this.internalTrack.info.codec) {\n return null;\n }\n return this.decoderConfigPromise ??= (async () => {\n if (this.internalTrack.info.codec === 'vp9' && !this.internalTrack.info.vp9CodecInfo) {\n const firstPacket = await this.getFirstPacket({});\n this.internalTrack.info.vp9CodecInfo = firstPacket && extractVp9CodecInfoFromPacket(firstPacket.data);\n }\n else if (this.internalTrack.info.codec === 'av1' && !this.internalTrack.info.av1CodecInfo) {\n const firstPacket = await this.getFirstPacket({});\n this.internalTrack.info.av1CodecInfo = firstPacket && extractAv1CodecInfoFromPacket(firstPacket.data);\n }\n return {\n codec: extractVideoCodecString(this.internalTrack.info),\n codedWidth: this.internalTrack.info.width,\n codedHeight: this.internalTrack.info.height,\n description: this.internalTrack.info.codecDescription ?? undefined,\n colorSpace: this.internalTrack.info.colorSpace ?? undefined,\n };\n })();\n }\n}\nclass IsobmffAudioTrackBacking extends IsobmffTrackBacking {\n constructor(internalTrack) {\n super(internalTrack);\n this.decoderConfig = null;\n this.internalTrack = internalTrack;\n }\n getCodec() {\n return this.internalTrack.info.codec;\n }\n getNumberOfChannels() {\n return this.internalTrack.info.numberOfChannels;\n }\n getSampleRate() {\n return this.internalTrack.info.sampleRate;\n }\n async getDecoderConfig() {\n if (!this.internalTrack.info.codec) {\n return null;\n }\n return this.decoderConfig ??= {\n codec: extractAudioCodecString(this.internalTrack.info),\n numberOfChannels: this.internalTrack.info.numberOfChannels,\n sampleRate: this.internalTrack.info.sampleRate,\n description: this.internalTrack.info.codecDescription ?? undefined,\n };\n }\n}\nconst getSampleIndexForTimestamp = (sampleTable, timescaleUnits) => {\n if (sampleTable.presentationTimestamps) {\n const index = binarySearchLessOrEqual(sampleTable.presentationTimestamps, timescaleUnits, x => x.presentationTimestamp);\n if (index === -1) {\n return -1;\n }\n return sampleTable.presentationTimestamps[index].sampleIndex;\n }\n else {\n const index = binarySearchLessOrEqual(sampleTable.sampleTimingEntries, timescaleUnits, x => x.startDecodeTimestamp);\n if (index === -1) {\n return -1;\n }\n const entry = sampleTable.sampleTimingEntries[index];\n return entry.startIndex\n + Math.min(Math.floor((timescaleUnits - entry.startDecodeTimestamp) / entry.delta), entry.count - 1);\n }\n};\nconst getKeyframeSampleIndexForTimestamp = (sampleTable, timescaleUnits) => {\n if (!sampleTable.keySampleIndices) {\n // Every sample is a keyframe\n return getSampleIndexForTimestamp(sampleTable, timescaleUnits);\n }\n if (sampleTable.presentationTimestamps) {\n const index = binarySearchLessOrEqual(sampleTable.presentationTimestamps, timescaleUnits, x => x.presentationTimestamp);\n if (index === -1) {\n return -1;\n }\n // Walk the samples in presentation order until we find one that's a keyframe\n for (let i = index; i >= 0; i--) {\n const sampleIndex = sampleTable.presentationTimestamps[i].sampleIndex;\n const isKeyFrame = binarySearchExact(sampleTable.keySampleIndices, sampleIndex, x => x) !== -1;\n if (isKeyFrame) {\n return sampleIndex;\n }\n }\n return -1;\n }\n else {\n const sampleIndex = getSampleIndexForTimestamp(sampleTable, timescaleUnits);\n const index = binarySearchLessOrEqual(sampleTable.keySampleIndices, sampleIndex, x => x);\n return sampleTable.keySampleIndices[index] ?? -1;\n }\n};\nconst getSampleInfo = (sampleTable, sampleIndex) => {\n const timingEntryIndex = binarySearchLessOrEqual(sampleTable.sampleTimingEntries, sampleIndex, x => x.startIndex);\n const timingEntry = sampleTable.sampleTimingEntries[timingEntryIndex];\n if (!timingEntry || timingEntry.startIndex + timingEntry.count <= sampleIndex) {\n return null;\n }\n const decodeTimestamp = timingEntry.startDecodeTimestamp\n + (sampleIndex - timingEntry.startIndex) * timingEntry.delta;\n let presentationTimestamp = decodeTimestamp;\n const offsetEntryIndex = binarySearchLessOrEqual(sampleTable.sampleCompositionTimeOffsets, sampleIndex, x => x.startIndex);\n const offsetEntry = sampleTable.sampleCompositionTimeOffsets[offsetEntryIndex];\n if (offsetEntry && sampleIndex - offsetEntry.startIndex < offsetEntry.count) {\n presentationTimestamp += offsetEntry.offset;\n }\n const sampleSize = sampleTable.sampleSizes[Math.min(sampleIndex, sampleTable.sampleSizes.length - 1)];\n const chunkEntryIndex = binarySearchLessOrEqual(sampleTable.sampleToChunk, sampleIndex, x => x.startSampleIndex);\n const chunkEntry = sampleTable.sampleToChunk[chunkEntryIndex];\n assert(chunkEntry);\n const chunkIndex = chunkEntry.startChunkIndex\n + Math.floor((sampleIndex - chunkEntry.startSampleIndex) / chunkEntry.samplesPerChunk);\n const chunkOffset = sampleTable.chunkOffsets[chunkIndex];\n const startSampleIndexOfChunk = chunkEntry.startSampleIndex\n + (chunkIndex - chunkEntry.startChunkIndex) * chunkEntry.samplesPerChunk;\n let chunkSize = 0;\n let sampleOffset = chunkOffset;\n if (sampleTable.sampleSizes.length === 1) {\n sampleOffset += sampleSize * (sampleIndex - startSampleIndexOfChunk);\n chunkSize += sampleSize * chunkEntry.samplesPerChunk;\n }\n else {\n for (let i = startSampleIndexOfChunk; i < startSampleIndexOfChunk + chunkEntry.samplesPerChunk; i++) {\n const sampleSize = sampleTable.sampleSizes[i];\n if (i < sampleIndex) {\n sampleOffset += sampleSize;\n }\n chunkSize += sampleSize;\n }\n }\n let duration = timingEntry.delta;\n if (sampleTable.presentationTimestamps) {\n // In order to accurately compute the duration, we need to take the duration to the next sample in presentation\n // order, not in decode order\n const presentationIndex = sampleTable.presentationTimestampIndexMap[sampleIndex];\n assert(presentationIndex !== undefined);\n if (presentationIndex < sampleTable.presentationTimestamps.length - 1) {\n const nextEntry = sampleTable.presentationTimestamps[presentationIndex + 1];\n const nextPresentationTimestamp = nextEntry.presentationTimestamp;\n duration = nextPresentationTimestamp - presentationTimestamp;\n }\n }\n return {\n presentationTimestamp,\n duration,\n sampleOffset,\n sampleSize,\n chunkOffset,\n chunkSize,\n isKeyFrame: sampleTable.keySampleIndices\n ? binarySearchExact(sampleTable.keySampleIndices, sampleIndex, x => x) !== -1\n : true,\n };\n};\nconst getNextKeyframeIndexForSample = (sampleTable, sampleIndex) => {\n if (!sampleTable.keySampleIndices) {\n return sampleIndex + 1;\n }\n const index = binarySearchLessOrEqual(sampleTable.keySampleIndices, sampleIndex, x => x);\n return sampleTable.keySampleIndices[index + 1] ?? -1;\n};\nconst offsetFragmentTrackDataByTimestamp = (trackData, timestamp) => {\n trackData.startTimestamp += timestamp;\n trackData.endTimestamp += timestamp;\n for (const sample of trackData.samples) {\n sample.presentationTimestamp += timestamp;\n }\n for (const entry of trackData.presentationTimestamps) {\n entry.presentationTimestamp += timestamp;\n }\n};\n/** Extracts the rotation component from a transformation matrix, in degrees. */\nconst extractRotationFromMatrix = (matrix) => {\n const [m11, , , m21] = matrix;\n const scaleX = Math.hypot(m11, m21);\n const cosTheta = m11 / scaleX;\n const sinTheta = m21 / scaleX;\n // Invert the rotation because matrices are post-multiplied in ISOBMFF\n const result = -Math.atan2(sinTheta, cosTheta) * (180 / Math.PI);\n if (!Number.isFinite(result)) {\n // Can happen if the entire matrix is 0, for example\n return 0;\n }\n return result;\n};\nconst sampleTableIsEmpty = (sampleTable) => {\n return sampleTable.sampleSizes.length === 0;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { assertNever, textDecoder, textEncoder } from '../misc.js';\nimport { readBytes, readF32Be, readF64Be, readU8 } from '../reader.js';\n/** Wrapper around a number to be able to differentiate it in the writer. */\nexport class EBMLFloat32 {\n constructor(value) {\n this.value = value;\n }\n}\n/** Wrapper around a number to be able to differentiate it in the writer. */\nexport class EBMLFloat64 {\n constructor(value) {\n this.value = value;\n }\n}\n/** Wrapper around a number to be able to differentiate it in the writer. */\nexport class EBMLSignedInt {\n constructor(value) {\n this.value = value;\n }\n}\nexport class EBMLUnicodeString {\n constructor(value) {\n this.value = value;\n }\n}\n/** Defines some of the EBML IDs used by Matroska files. */\nexport var EBMLId;\n(function (EBMLId) {\n EBMLId[EBMLId[\"EBML\"] = 440786851] = \"EBML\";\n EBMLId[EBMLId[\"EBMLVersion\"] = 17030] = \"EBMLVersion\";\n EBMLId[EBMLId[\"EBMLReadVersion\"] = 17143] = \"EBMLReadVersion\";\n EBMLId[EBMLId[\"EBMLMaxIDLength\"] = 17138] = \"EBMLMaxIDLength\";\n EBMLId[EBMLId[\"EBMLMaxSizeLength\"] = 17139] = \"EBMLMaxSizeLength\";\n EBMLId[EBMLId[\"DocType\"] = 17026] = \"DocType\";\n EBMLId[EBMLId[\"DocTypeVersion\"] = 17031] = \"DocTypeVersion\";\n EBMLId[EBMLId[\"DocTypeReadVersion\"] = 17029] = \"DocTypeReadVersion\";\n EBMLId[EBMLId[\"Void\"] = 236] = \"Void\";\n EBMLId[EBMLId[\"Segment\"] = 408125543] = \"Segment\";\n EBMLId[EBMLId[\"SeekHead\"] = 290298740] = \"SeekHead\";\n EBMLId[EBMLId[\"Seek\"] = 19899] = \"Seek\";\n EBMLId[EBMLId[\"SeekID\"] = 21419] = \"SeekID\";\n EBMLId[EBMLId[\"SeekPosition\"] = 21420] = \"SeekPosition\";\n EBMLId[EBMLId[\"Duration\"] = 17545] = \"Duration\";\n EBMLId[EBMLId[\"Info\"] = 357149030] = \"Info\";\n EBMLId[EBMLId[\"TimestampScale\"] = 2807729] = \"TimestampScale\";\n EBMLId[EBMLId[\"MuxingApp\"] = 19840] = \"MuxingApp\";\n EBMLId[EBMLId[\"WritingApp\"] = 22337] = \"WritingApp\";\n EBMLId[EBMLId[\"Tracks\"] = 374648427] = \"Tracks\";\n EBMLId[EBMLId[\"TrackEntry\"] = 174] = \"TrackEntry\";\n EBMLId[EBMLId[\"TrackNumber\"] = 215] = \"TrackNumber\";\n EBMLId[EBMLId[\"TrackUID\"] = 29637] = \"TrackUID\";\n EBMLId[EBMLId[\"TrackType\"] = 131] = \"TrackType\";\n EBMLId[EBMLId[\"FlagEnabled\"] = 185] = \"FlagEnabled\";\n EBMLId[EBMLId[\"FlagDefault\"] = 136] = \"FlagDefault\";\n EBMLId[EBMLId[\"FlagForced\"] = 21930] = \"FlagForced\";\n EBMLId[EBMLId[\"FlagOriginal\"] = 21934] = \"FlagOriginal\";\n EBMLId[EBMLId[\"FlagHearingImpaired\"] = 21931] = \"FlagHearingImpaired\";\n EBMLId[EBMLId[\"FlagVisualImpaired\"] = 21932] = \"FlagVisualImpaired\";\n EBMLId[EBMLId[\"FlagCommentary\"] = 21935] = \"FlagCommentary\";\n EBMLId[EBMLId[\"FlagLacing\"] = 156] = \"FlagLacing\";\n EBMLId[EBMLId[\"Name\"] = 21358] = \"Name\";\n EBMLId[EBMLId[\"Language\"] = 2274716] = \"Language\";\n EBMLId[EBMLId[\"LanguageBCP47\"] = 2274717] = \"LanguageBCP47\";\n EBMLId[EBMLId[\"CodecID\"] = 134] = \"CodecID\";\n EBMLId[EBMLId[\"CodecPrivate\"] = 25506] = \"CodecPrivate\";\n EBMLId[EBMLId[\"CodecDelay\"] = 22186] = \"CodecDelay\";\n EBMLId[EBMLId[\"SeekPreRoll\"] = 22203] = \"SeekPreRoll\";\n EBMLId[EBMLId[\"DefaultDuration\"] = 2352003] = \"DefaultDuration\";\n EBMLId[EBMLId[\"Video\"] = 224] = \"Video\";\n EBMLId[EBMLId[\"PixelWidth\"] = 176] = \"PixelWidth\";\n EBMLId[EBMLId[\"PixelHeight\"] = 186] = \"PixelHeight\";\n EBMLId[EBMLId[\"AlphaMode\"] = 21440] = \"AlphaMode\";\n EBMLId[EBMLId[\"Audio\"] = 225] = \"Audio\";\n EBMLId[EBMLId[\"SamplingFrequency\"] = 181] = \"SamplingFrequency\";\n EBMLId[EBMLId[\"Channels\"] = 159] = \"Channels\";\n EBMLId[EBMLId[\"BitDepth\"] = 25188] = \"BitDepth\";\n EBMLId[EBMLId[\"SimpleBlock\"] = 163] = \"SimpleBlock\";\n EBMLId[EBMLId[\"BlockGroup\"] = 160] = \"BlockGroup\";\n EBMLId[EBMLId[\"Block\"] = 161] = \"Block\";\n EBMLId[EBMLId[\"BlockAdditions\"] = 30113] = \"BlockAdditions\";\n EBMLId[EBMLId[\"BlockMore\"] = 166] = \"BlockMore\";\n EBMLId[EBMLId[\"BlockAdditional\"] = 165] = \"BlockAdditional\";\n EBMLId[EBMLId[\"BlockAddID\"] = 238] = \"BlockAddID\";\n EBMLId[EBMLId[\"BlockDuration\"] = 155] = \"BlockDuration\";\n EBMLId[EBMLId[\"ReferenceBlock\"] = 251] = \"ReferenceBlock\";\n EBMLId[EBMLId[\"Cluster\"] = 524531317] = \"Cluster\";\n EBMLId[EBMLId[\"Timestamp\"] = 231] = \"Timestamp\";\n EBMLId[EBMLId[\"Cues\"] = 475249515] = \"Cues\";\n EBMLId[EBMLId[\"CuePoint\"] = 187] = \"CuePoint\";\n EBMLId[EBMLId[\"CueTime\"] = 179] = \"CueTime\";\n EBMLId[EBMLId[\"CueTrackPositions\"] = 183] = \"CueTrackPositions\";\n EBMLId[EBMLId[\"CueTrack\"] = 247] = \"CueTrack\";\n EBMLId[EBMLId[\"CueClusterPosition\"] = 241] = \"CueClusterPosition\";\n EBMLId[EBMLId[\"Colour\"] = 21936] = \"Colour\";\n EBMLId[EBMLId[\"MatrixCoefficients\"] = 21937] = \"MatrixCoefficients\";\n EBMLId[EBMLId[\"TransferCharacteristics\"] = 21946] = \"TransferCharacteristics\";\n EBMLId[EBMLId[\"Primaries\"] = 21947] = \"Primaries\";\n EBMLId[EBMLId[\"Range\"] = 21945] = \"Range\";\n EBMLId[EBMLId[\"Projection\"] = 30320] = \"Projection\";\n EBMLId[EBMLId[\"ProjectionType\"] = 30321] = \"ProjectionType\";\n EBMLId[EBMLId[\"ProjectionPoseRoll\"] = 30325] = \"ProjectionPoseRoll\";\n EBMLId[EBMLId[\"Attachments\"] = 423732329] = \"Attachments\";\n EBMLId[EBMLId[\"AttachedFile\"] = 24999] = \"AttachedFile\";\n EBMLId[EBMLId[\"FileDescription\"] = 18046] = \"FileDescription\";\n EBMLId[EBMLId[\"FileName\"] = 18030] = \"FileName\";\n EBMLId[EBMLId[\"FileMediaType\"] = 18016] = \"FileMediaType\";\n EBMLId[EBMLId[\"FileData\"] = 18012] = \"FileData\";\n EBMLId[EBMLId[\"FileUID\"] = 18094] = \"FileUID\";\n EBMLId[EBMLId[\"Chapters\"] = 272869232] = \"Chapters\";\n EBMLId[EBMLId[\"Tags\"] = 307544935] = \"Tags\";\n EBMLId[EBMLId[\"Tag\"] = 29555] = \"Tag\";\n EBMLId[EBMLId[\"Targets\"] = 25536] = \"Targets\";\n EBMLId[EBMLId[\"TargetTypeValue\"] = 26826] = \"TargetTypeValue\";\n EBMLId[EBMLId[\"TargetType\"] = 25546] = \"TargetType\";\n EBMLId[EBMLId[\"TagTrackUID\"] = 25541] = \"TagTrackUID\";\n EBMLId[EBMLId[\"TagEditionUID\"] = 25545] = \"TagEditionUID\";\n EBMLId[EBMLId[\"TagChapterUID\"] = 25540] = \"TagChapterUID\";\n EBMLId[EBMLId[\"TagAttachmentUID\"] = 25542] = \"TagAttachmentUID\";\n EBMLId[EBMLId[\"SimpleTag\"] = 26568] = \"SimpleTag\";\n EBMLId[EBMLId[\"TagName\"] = 17827] = \"TagName\";\n EBMLId[EBMLId[\"TagLanguage\"] = 17530] = \"TagLanguage\";\n EBMLId[EBMLId[\"TagString\"] = 17543] = \"TagString\";\n EBMLId[EBMLId[\"TagBinary\"] = 17541] = \"TagBinary\";\n EBMLId[EBMLId[\"ContentEncodings\"] = 28032] = \"ContentEncodings\";\n EBMLId[EBMLId[\"ContentEncoding\"] = 25152] = \"ContentEncoding\";\n EBMLId[EBMLId[\"ContentEncodingOrder\"] = 20529] = \"ContentEncodingOrder\";\n EBMLId[EBMLId[\"ContentEncodingScope\"] = 20530] = \"ContentEncodingScope\";\n EBMLId[EBMLId[\"ContentCompression\"] = 20532] = \"ContentCompression\";\n EBMLId[EBMLId[\"ContentCompAlgo\"] = 16980] = \"ContentCompAlgo\";\n EBMLId[EBMLId[\"ContentCompSettings\"] = 16981] = \"ContentCompSettings\";\n EBMLId[EBMLId[\"ContentEncryption\"] = 20533] = \"ContentEncryption\";\n})(EBMLId || (EBMLId = {}));\nexport const LEVEL_0_EBML_IDS = [\n EBMLId.EBML,\n EBMLId.Segment,\n];\n// All the stuff that can appear in a segment, basically\nexport const LEVEL_1_EBML_IDS = [\n EBMLId.SeekHead,\n EBMLId.Info,\n EBMLId.Cluster,\n EBMLId.Tracks,\n EBMLId.Cues,\n EBMLId.Attachments,\n EBMLId.Chapters,\n EBMLId.Tags,\n];\nexport const LEVEL_0_AND_1_EBML_IDS = [\n ...LEVEL_0_EBML_IDS,\n ...LEVEL_1_EBML_IDS,\n];\nexport const measureUnsignedInt = (value) => {\n if (value < (1 << 8)) {\n return 1;\n }\n else if (value < (1 << 16)) {\n return 2;\n }\n else if (value < (1 << 24)) {\n return 3;\n }\n else if (value < 2 ** 32) {\n return 4;\n }\n else if (value < 2 ** 40) {\n return 5;\n }\n else {\n return 6;\n }\n};\nexport const measureUnsignedBigInt = (value) => {\n if (value < (1n << 8n)) {\n return 1;\n }\n else if (value < (1n << 16n)) {\n return 2;\n }\n else if (value < (1n << 24n)) {\n return 3;\n }\n else if (value < (1n << 32n)) {\n return 4;\n }\n else if (value < (1n << 40n)) {\n return 5;\n }\n else if (value < (1n << 48n)) {\n return 6;\n }\n else if (value < (1n << 56n)) {\n return 7;\n }\n else {\n return 8;\n }\n};\nexport const measureSignedInt = (value) => {\n if (value >= -(1 << 6) && value < (1 << 6)) {\n return 1;\n }\n else if (value >= -(1 << 13) && value < (1 << 13)) {\n return 2;\n }\n else if (value >= -(1 << 20) && value < (1 << 20)) {\n return 3;\n }\n else if (value >= -(1 << 27) && value < (1 << 27)) {\n return 4;\n }\n else if (value >= -(2 ** 34) && value < 2 ** 34) {\n return 5;\n }\n else {\n return 6;\n }\n};\nexport const measureVarInt = (value) => {\n if (value < (1 << 7) - 1) {\n /** Top bit is set, leaving 7 bits to hold the integer, but we can't store\n * 127 because \"all bits set to one\" is a reserved value. Same thing for the\n * other cases below:\n */\n return 1;\n }\n else if (value < (1 << 14) - 1) {\n return 2;\n }\n else if (value < (1 << 21) - 1) {\n return 3;\n }\n else if (value < (1 << 28) - 1) {\n return 4;\n }\n else if (value < 2 ** 35 - 1) {\n return 5;\n }\n else if (value < 2 ** 42 - 1) {\n return 6;\n }\n else {\n throw new Error('EBML varint size not supported ' + value);\n }\n};\nexport class EBMLWriter {\n constructor(writer) {\n this.writer = writer;\n this.helper = new Uint8Array(8);\n this.helperView = new DataView(this.helper.buffer);\n /**\n * Stores the position from the start of the file to where EBML elements have been written. This is used to\n * rewrite/edit elements that were already added before, and to measure sizes of things.\n */\n this.offsets = new WeakMap();\n /** Same as offsets, but stores position where the element's data starts (after ID and size fields). */\n this.dataOffsets = new WeakMap();\n }\n writeByte(value) {\n this.helperView.setUint8(0, value);\n this.writer.write(this.helper.subarray(0, 1));\n }\n writeFloat32(value) {\n this.helperView.setFloat32(0, value, false);\n this.writer.write(this.helper.subarray(0, 4));\n }\n writeFloat64(value) {\n this.helperView.setFloat64(0, value, false);\n this.writer.write(this.helper);\n }\n writeUnsignedInt(value, width = measureUnsignedInt(value)) {\n let pos = 0;\n // Each case falls through:\n switch (width) {\n case 6:\n // Need to use division to access >32 bits of floating point var\n this.helperView.setUint8(pos++, (value / 2 ** 40) | 0);\n // eslint-disable-next-line no-fallthrough\n case 5:\n this.helperView.setUint8(pos++, (value / 2 ** 32) | 0);\n // eslint-disable-next-line no-fallthrough\n case 4:\n this.helperView.setUint8(pos++, value >> 24);\n // eslint-disable-next-line no-fallthrough\n case 3:\n this.helperView.setUint8(pos++, value >> 16);\n // eslint-disable-next-line no-fallthrough\n case 2:\n this.helperView.setUint8(pos++, value >> 8);\n // eslint-disable-next-line no-fallthrough\n case 1:\n this.helperView.setUint8(pos++, value);\n break;\n default:\n throw new Error('Bad unsigned int size ' + width);\n }\n this.writer.write(this.helper.subarray(0, pos));\n }\n writeUnsignedBigInt(value, width = measureUnsignedBigInt(value)) {\n let pos = 0;\n for (let i = width - 1; i >= 0; i--) {\n this.helperView.setUint8(pos++, Number((value >> BigInt(i * 8)) & 0xffn));\n }\n this.writer.write(this.helper.subarray(0, pos));\n }\n writeSignedInt(value, width = measureSignedInt(value)) {\n if (value < 0) {\n // Two's complement stuff\n value += 2 ** (width * 8);\n }\n this.writeUnsignedInt(value, width);\n }\n writeVarInt(value, width = measureVarInt(value)) {\n let pos = 0;\n switch (width) {\n case 1:\n this.helperView.setUint8(pos++, (1 << 7) | value);\n break;\n case 2:\n this.helperView.setUint8(pos++, (1 << 6) | (value >> 8));\n this.helperView.setUint8(pos++, value);\n break;\n case 3:\n this.helperView.setUint8(pos++, (1 << 5) | (value >> 16));\n this.helperView.setUint8(pos++, value >> 8);\n this.helperView.setUint8(pos++, value);\n break;\n case 4:\n this.helperView.setUint8(pos++, (1 << 4) | (value >> 24));\n this.helperView.setUint8(pos++, value >> 16);\n this.helperView.setUint8(pos++, value >> 8);\n this.helperView.setUint8(pos++, value);\n break;\n case 5:\n /**\n * JavaScript converts its doubles to 32-bit integers for bitwise\n * operations, so we need to do a division by 2^32 instead of a\n * right-shift of 32 to retain those top 3 bits\n */\n this.helperView.setUint8(pos++, (1 << 3) | ((value / 2 ** 32) & 0x7));\n this.helperView.setUint8(pos++, value >> 24);\n this.helperView.setUint8(pos++, value >> 16);\n this.helperView.setUint8(pos++, value >> 8);\n this.helperView.setUint8(pos++, value);\n break;\n case 6:\n this.helperView.setUint8(pos++, (1 << 2) | ((value / 2 ** 40) & 0x3));\n this.helperView.setUint8(pos++, (value / 2 ** 32) | 0);\n this.helperView.setUint8(pos++, value >> 24);\n this.helperView.setUint8(pos++, value >> 16);\n this.helperView.setUint8(pos++, value >> 8);\n this.helperView.setUint8(pos++, value);\n break;\n default:\n throw new Error('Bad EBML varint size ' + width);\n }\n this.writer.write(this.helper.subarray(0, pos));\n }\n writeAsciiString(str) {\n this.writer.write(new Uint8Array(str.split('').map(x => x.charCodeAt(0))));\n }\n writeEBML(data) {\n if (data === null)\n return;\n if (data instanceof Uint8Array) {\n this.writer.write(data);\n }\n else if (Array.isArray(data)) {\n for (const elem of data) {\n this.writeEBML(elem);\n }\n }\n else {\n this.offsets.set(data, this.writer.getPos());\n this.writeUnsignedInt(data.id); // ID field\n if (Array.isArray(data.data)) {\n const sizePos = this.writer.getPos();\n const sizeSize = data.size === -1 ? 1 : (data.size ?? 4);\n if (data.size === -1) {\n // Write the reserved all-one-bits marker for unknown/unbounded size.\n this.writeByte(0xff);\n }\n else {\n this.writer.seek(this.writer.getPos() + sizeSize);\n }\n const startPos = this.writer.getPos();\n this.dataOffsets.set(data, startPos);\n this.writeEBML(data.data);\n if (data.size !== -1) {\n const size = this.writer.getPos() - startPos;\n const endPos = this.writer.getPos();\n this.writer.seek(sizePos);\n this.writeVarInt(size, sizeSize);\n this.writer.seek(endPos);\n }\n }\n else if (typeof data.data === 'number') {\n const size = data.size ?? measureUnsignedInt(data.data);\n this.writeVarInt(size);\n this.writeUnsignedInt(data.data, size);\n }\n else if (typeof data.data === 'bigint') {\n const size = data.size ?? measureUnsignedBigInt(data.data);\n this.writeVarInt(size);\n this.writeUnsignedBigInt(data.data, size);\n }\n else if (typeof data.data === 'string') {\n this.writeVarInt(data.data.length);\n this.writeAsciiString(data.data);\n }\n else if (data.data instanceof Uint8Array) {\n this.writeVarInt(data.data.byteLength, data.size);\n this.writer.write(data.data);\n }\n else if (data.data instanceof EBMLFloat32) {\n this.writeVarInt(4);\n this.writeFloat32(data.data.value);\n }\n else if (data.data instanceof EBMLFloat64) {\n this.writeVarInt(8);\n this.writeFloat64(data.data.value);\n }\n else if (data.data instanceof EBMLSignedInt) {\n const size = data.size ?? measureSignedInt(data.data.value);\n this.writeVarInt(size);\n this.writeSignedInt(data.data.value, size);\n }\n else if (data.data instanceof EBMLUnicodeString) {\n const bytes = textEncoder.encode(data.data.value);\n this.writeVarInt(bytes.length);\n this.writer.write(bytes);\n }\n else {\n assertNever(data.data);\n }\n }\n }\n}\nexport const MAX_VAR_INT_SIZE = 8;\nexport const MIN_HEADER_SIZE = 2; // 1-byte ID and 1-byte size\nexport const MAX_HEADER_SIZE = 2 * MAX_VAR_INT_SIZE; // 8-byte ID and 8-byte size\nexport const readVarIntSize = (slice) => {\n const firstByte = readU8(slice);\n slice.skip(-1);\n if (firstByte === 0) {\n return null; // Invalid VINT\n }\n let width = 1;\n let mask = 0x80;\n while ((firstByte & mask) === 0) {\n width++;\n mask >>= 1;\n }\n return width;\n};\nexport const readVarInt = (slice) => {\n // Read the first byte to determine the width of the variable-length integer\n const firstByte = readU8(slice);\n if (firstByte === 0) {\n return null; // Invalid VINT\n }\n // Find the position of VINT_MARKER, which determines the width\n let width = 1;\n let mask = 1 << 7;\n while ((firstByte & mask) === 0) {\n width++;\n mask >>= 1;\n }\n // First byte's value needs the marker bit cleared\n let value = firstByte & (mask - 1);\n // Read remaining bytes\n for (let i = 1; i < width; i++) {\n value *= 1 << 8;\n value += readU8(slice);\n }\n return value;\n};\nexport const readUnsignedInt = (slice, width) => {\n if (width < 1 || width > 8) {\n throw new Error('Bad unsigned int size ' + width);\n }\n let value = 0;\n // Read bytes from most significant to least significant\n for (let i = 0; i < width; i++) {\n value *= 1 << 8;\n value += readU8(slice);\n }\n return value;\n};\nexport const readUnsignedBigInt = (slice, width) => {\n if (width < 1) {\n throw new Error('Bad unsigned int size ' + width);\n }\n let value = 0n;\n for (let i = 0; i < width; i++) {\n value <<= 8n;\n value += BigInt(readU8(slice));\n }\n return value;\n};\nexport const readSignedInt = (slice, width) => {\n let value = readUnsignedInt(slice, width);\n // If the highest bit is set, convert from two's complement\n if (value & (1 << (width * 8 - 1))) {\n value -= 2 ** (width * 8);\n }\n return value;\n};\nexport const readElementId = (slice) => {\n const size = readVarIntSize(slice);\n if (size === null) {\n return null;\n }\n const id = readUnsignedInt(slice, size);\n return id;\n};\nexport const readElementSize = (slice) => {\n let size = readU8(slice);\n if (size === 0xff) {\n size = null;\n }\n else {\n slice.skip(-1);\n size = readVarInt(slice);\n // In some (livestreamed) files, this is the value of the size field. While this technically is just a very\n // large number, it is intended to behave like the reserved size 0xFF, meaning the size is undefined. We\n // catch the number here. Note that it cannot be perfectly represented as a double, but the comparison works\n // nonetheless.\n // eslint-disable-next-line no-loss-of-precision\n if (size === 0x00ffffffffffffff) {\n size = null;\n }\n }\n return size;\n};\nexport const readElementHeader = (slice) => {\n const id = readElementId(slice);\n if (id === null) {\n return null;\n }\n const size = readElementSize(slice);\n return { id, size };\n};\nexport const readAsciiString = (slice, length) => {\n const bytes = readBytes(slice, length);\n // Actual string length might be shorter due to null terminators\n let strLength = 0;\n while (strLength < length && bytes[strLength] !== 0) {\n strLength += 1;\n }\n return String.fromCharCode(...bytes.subarray(0, strLength));\n};\nexport const readUnicodeString = (slice, length) => {\n const bytes = readBytes(slice, length);\n // Actual string length might be shorter due to null terminators\n let strLength = 0;\n while (strLength < length && bytes[strLength] !== 0) {\n strLength += 1;\n }\n return textDecoder.decode(bytes.subarray(0, strLength));\n};\nexport const readFloat = (slice, width) => {\n if (width === 0) {\n return 0;\n }\n if (width !== 4 && width !== 8) {\n throw new Error('Bad float size ' + width);\n }\n return width === 4 ? readF32Be(slice) : readF64Be(slice);\n};\n/** Returns the byte offset in the file of the next element with a matching ID. */\nexport const searchForNextElementId = async (reader, startPos, ids, until) => {\n const idsSet = new Set(ids);\n let currentPos = startPos;\n while (until === null || currentPos < until) {\n let slice = reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const elementHeader = readElementHeader(slice);\n if (!elementHeader) {\n break;\n }\n if (idsSet.has(elementHeader.id)) {\n return { pos: currentPos, found: true };\n }\n assertDefinedSize(elementHeader.size);\n currentPos = slice.filePos + elementHeader.size;\n }\n return { pos: (until !== null && until > currentPos) ? until : currentPos, found: false };\n};\n/** Searches for the next occurrence of an element ID using a naive byte-wise search. */\nexport const resync = async (reader, startPos, ids, until) => {\n const CHUNK_SIZE = 2 ** 16; // So we don't need to grab thousands of slices\n const idsSet = new Set(ids);\n let currentPos = startPos;\n while (currentPos < until) {\n let slice = reader.requestSliceRange(currentPos, 0, Math.min(CHUNK_SIZE, until - currentPos));\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n if (slice.length < MAX_VAR_INT_SIZE)\n break;\n for (let i = 0; i < slice.length - MAX_VAR_INT_SIZE; i++) {\n slice.filePos = currentPos;\n const elementId = readElementId(slice);\n if (elementId !== null && idsSet.has(elementId)) {\n return currentPos;\n }\n currentPos++;\n }\n }\n return null;\n};\nexport const CODEC_STRING_MAP = {\n 'avc': 'V_MPEG4/ISO/AVC',\n 'hevc': 'V_MPEGH/ISO/HEVC',\n 'vp8': 'V_VP8',\n 'vp9': 'V_VP9',\n 'av1': 'V_AV1',\n 'aac': 'A_AAC',\n 'mp3': 'A_MPEG/L3',\n 'opus': 'A_OPUS',\n 'vorbis': 'A_VORBIS',\n 'flac': 'A_FLAC',\n 'pcm-u8': 'A_PCM/INT/LIT',\n 'pcm-s16': 'A_PCM/INT/LIT',\n 'pcm-s16be': 'A_PCM/INT/BIG',\n 'pcm-s24': 'A_PCM/INT/LIT',\n 'pcm-s24be': 'A_PCM/INT/BIG',\n 'pcm-s32': 'A_PCM/INT/LIT',\n 'pcm-s32be': 'A_PCM/INT/BIG',\n 'pcm-f32': 'A_PCM/FLOAT/IEEE',\n 'pcm-f64': 'A_PCM/FLOAT/IEEE',\n 'webvtt': 'S_TEXT/WEBVTT',\n};\nexport function assertDefinedSize(size) {\n if (size === null) {\n throw new Error('Undefined element size is used in a place where it is not supported.');\n }\n}\n;\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nexport const buildMatroskaMimeType = (info) => {\n const base = info.hasVideo\n ? 'video/'\n : info.hasAudio\n ? 'audio/'\n : 'application/';\n let string = base + (info.isWebM ? 'webm' : 'x-matroska');\n if (info.codecStrings.length > 0) {\n const uniqueCodecMimeTypes = [...new Set(info.codecStrings.filter(Boolean))];\n string += `; codecs=\"${uniqueCodecMimeTypes.join(', ')}\"`;\n }\n return string;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { extractAv1CodecInfoFromPacket, extractAvcDecoderConfigurationRecord, extractHevcDecoderConfigurationRecord, extractVp9CodecInfoFromPacket, } from '../codec-data.js';\nimport { extractAudioCodecString, extractVideoCodecString, OPUS_SAMPLE_RATE, } from '../codec.js';\nimport { Demuxer } from '../demuxer.js';\nimport { InputAudioTrack, InputVideoTrack, } from '../input-track.js';\nimport { AttachedFile, DEFAULT_TRACK_DISPOSITION } from '../metadata.js';\nimport { assert, binarySearchLessOrEqual, COLOR_PRIMARIES_MAP_INVERSE, findLastIndex, isIso639Dash2LanguageCode, last, MATRIX_COEFFICIENTS_MAP_INVERSE, normalizeRotation, roundIfAlmostInteger, TRANSFER_CHARACTERISTICS_MAP_INVERSE, UNDETERMINED_LANGUAGE, } from '../misc.js';\nimport { EncodedPacket, PLACEHOLDER_DATA } from '../packet.js';\nimport { assertDefinedSize, CODEC_STRING_MAP, EBMLId, LEVEL_0_AND_1_EBML_IDS, LEVEL_1_EBML_IDS, MAX_HEADER_SIZE, MIN_HEADER_SIZE, readAsciiString, readUnicodeString, readElementHeader, readElementId, readFloat, readUnsignedInt, readVarInt, resync, searchForNextElementId, readUnsignedBigInt, } from './ebml.js';\nimport { buildMatroskaMimeType } from './matroska-misc.js';\nimport { FileSlice, readBytes, readI16Be, readU8 } from '../reader.js';\nvar BlockLacing;\n(function (BlockLacing) {\n BlockLacing[BlockLacing[\"None\"] = 0] = \"None\";\n BlockLacing[BlockLacing[\"Xiph\"] = 1] = \"Xiph\";\n BlockLacing[BlockLacing[\"FixedSize\"] = 2] = \"FixedSize\";\n BlockLacing[BlockLacing[\"Ebml\"] = 3] = \"Ebml\";\n})(BlockLacing || (BlockLacing = {}));\nvar ContentEncodingScope;\n(function (ContentEncodingScope) {\n ContentEncodingScope[ContentEncodingScope[\"Block\"] = 1] = \"Block\";\n ContentEncodingScope[ContentEncodingScope[\"Private\"] = 2] = \"Private\";\n ContentEncodingScope[ContentEncodingScope[\"Next\"] = 4] = \"Next\";\n})(ContentEncodingScope || (ContentEncodingScope = {}));\nvar ContentCompAlgo;\n(function (ContentCompAlgo) {\n ContentCompAlgo[ContentCompAlgo[\"Zlib\"] = 0] = \"Zlib\";\n ContentCompAlgo[ContentCompAlgo[\"Bzlib\"] = 1] = \"Bzlib\";\n ContentCompAlgo[ContentCompAlgo[\"lzo1x\"] = 2] = \"lzo1x\";\n ContentCompAlgo[ContentCompAlgo[\"HeaderStripping\"] = 3] = \"HeaderStripping\";\n})(ContentCompAlgo || (ContentCompAlgo = {}));\nconst METADATA_ELEMENTS = [\n { id: EBMLId.SeekHead, flag: 'seekHeadSeen' },\n { id: EBMLId.Info, flag: 'infoSeen' },\n { id: EBMLId.Tracks, flag: 'tracksSeen' },\n { id: EBMLId.Cues, flag: 'cuesSeen' },\n];\nconst MAX_RESYNC_LENGTH = 10 * 2 ** 20; // 10 MiB\nexport class MatroskaDemuxer extends Demuxer {\n constructor(input) {\n super(input);\n this.readMetadataPromise = null;\n this.segments = [];\n this.currentSegment = null;\n this.currentTrack = null;\n this.currentCluster = null;\n this.currentBlock = null;\n this.currentBlockAdditional = null;\n this.currentCueTime = null;\n this.currentDecodingInstruction = null;\n this.currentTagTargetIsMovie = true;\n this.currentSimpleTagName = null;\n this.currentAttachedFile = null;\n this.isWebM = false;\n this.reader = input._reader;\n }\n async computeDuration() {\n const tracks = await this.getTracks();\n const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));\n return Math.max(0, ...trackDurations);\n }\n async getTracks() {\n await this.readMetadata();\n return this.segments.flatMap(segment => segment.tracks.map(track => track.inputTrack));\n }\n async getMimeType() {\n await this.readMetadata();\n const tracks = await this.getTracks();\n const codecStrings = await Promise.all(tracks.map(x => x.getCodecParameterString()));\n return buildMatroskaMimeType({\n isWebM: this.isWebM,\n hasVideo: this.segments.some(segment => segment.tracks.some(x => x.info?.type === 'video')),\n hasAudio: this.segments.some(segment => segment.tracks.some(x => x.info?.type === 'audio')),\n codecStrings: codecStrings.filter(Boolean),\n });\n }\n async getMetadataTags() {\n await this.readMetadata();\n // Load metadata tags from each segment lazily (only once)\n for (const segment of this.segments) {\n if (!segment.metadataTagsCollected) {\n if (this.reader.fileSize !== null) {\n await this.loadSegmentMetadata(segment);\n }\n else {\n // The seeking would be too crazy, let's not\n }\n segment.metadataTagsCollected = true;\n }\n }\n // This is kinda handwavy, and how we handle multiple segments isn't suuuuper well-defined anyway; so we just\n // shallow-merge metadata tags from all (usually just one) segments.\n let metadataTags = {};\n for (const segment of this.segments) {\n metadataTags = { ...metadataTags, ...segment.metadataTags };\n }\n return metadataTags;\n }\n readMetadata() {\n return this.readMetadataPromise ??= (async () => {\n let currentPos = 0;\n // Loop over all top-level elements in the file\n while (true) {\n let slice = this.reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const header = readElementHeader(slice);\n if (!header) {\n break; // Zero padding at the end of the file triggers this, for example\n }\n const id = header.id;\n let size = header.size;\n const dataStartPos = slice.filePos;\n if (id === EBMLId.EBML) {\n assertDefinedSize(size);\n let slice = this.reader.requestSlice(dataStartPos, size);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n this.readContiguousElements(slice);\n }\n else if (id === EBMLId.Segment) { // Segment found!\n await this.readSegment(dataStartPos, size);\n if (size === null) {\n // Segment sizes can be undefined (common in livestreamed files), so assume this is the last\n // and only segment\n break;\n }\n if (this.reader.fileSize === null) {\n break; // Stop at the first segment\n }\n }\n else if (id === EBMLId.Cluster) {\n if (this.reader.fileSize === null) {\n break; // Shouldn't be reached anyway, since we stop at the first segment\n }\n // Clusters are not a top-level element in Matroska, but some files contain a Segment whose size\n // doesn't contain any of the clusters that follow it. In the case, we apply the following logic: if\n // we find a top-level cluster, attribute it to the previous segment.\n if (size === null) {\n // Just in case this is one of those weird sizeless clusters, let's do our best and still try to\n // determine its size.\n const nextElementPos = await searchForNextElementId(this.reader, dataStartPos, LEVEL_0_AND_1_EBML_IDS, this.reader.fileSize);\n size = nextElementPos.pos - dataStartPos;\n }\n const lastSegment = last(this.segments);\n if (lastSegment) {\n // Extend the previous segment's size\n lastSegment.elementEndPos = dataStartPos + size;\n }\n }\n assertDefinedSize(size);\n currentPos = dataStartPos + size;\n }\n })();\n }\n async readSegment(segmentDataStart, dataSize) {\n this.currentSegment = {\n seekHeadSeen: false,\n infoSeen: false,\n tracksSeen: false,\n cuesSeen: false,\n tagsSeen: false,\n attachmentsSeen: false,\n timestampScale: -1,\n timestampFactor: -1,\n duration: -1,\n seekEntries: [],\n tracks: [],\n cuePoints: [],\n dataStartPos: segmentDataStart,\n elementEndPos: dataSize === null\n ? null // Assume it goes until the end of the file\n : segmentDataStart + dataSize,\n clusterSeekStartPos: segmentDataStart,\n lastReadCluster: null,\n metadataTags: {},\n metadataTagsCollected: false,\n };\n this.segments.push(this.currentSegment);\n let currentPos = segmentDataStart;\n while (this.currentSegment.elementEndPos === null || currentPos < this.currentSegment.elementEndPos) {\n let slice = this.reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const elementStartPos = currentPos;\n const header = readElementHeader(slice);\n if (!header || (!LEVEL_1_EBML_IDS.includes(header.id) && header.id !== EBMLId.Void)) {\n // Potential junk. Let's try to resync\n const nextPos = await resync(this.reader, elementStartPos, LEVEL_1_EBML_IDS, Math.min(this.currentSegment.elementEndPos ?? Infinity, elementStartPos + MAX_RESYNC_LENGTH));\n if (nextPos) {\n currentPos = nextPos;\n continue;\n }\n else {\n break; // Resync failed\n }\n }\n const { id, size } = header;\n const dataStartPos = slice.filePos;\n const metadataElementIndex = METADATA_ELEMENTS.findIndex(x => x.id === id);\n if (metadataElementIndex !== -1) {\n const field = METADATA_ELEMENTS[metadataElementIndex].flag;\n this.currentSegment[field] = true;\n assertDefinedSize(size);\n let slice = this.reader.requestSlice(dataStartPos, size);\n if (slice instanceof Promise)\n slice = await slice;\n if (slice) {\n this.readContiguousElements(slice);\n }\n }\n else if (id === EBMLId.Tags || id === EBMLId.Attachments) {\n // Metadata found at the beginning of the segment, great, let's parse it\n if (id === EBMLId.Tags) {\n this.currentSegment.tagsSeen = true;\n }\n else {\n this.currentSegment.attachmentsSeen = true;\n }\n assertDefinedSize(size);\n let slice = this.reader.requestSlice(dataStartPos, size);\n if (slice instanceof Promise)\n slice = await slice;\n if (slice) {\n this.readContiguousElements(slice);\n }\n }\n else if (id === EBMLId.Cluster) {\n this.currentSegment.clusterSeekStartPos = elementStartPos;\n break; // Stop at the first cluster\n }\n if (size === null) {\n break;\n }\n else {\n currentPos = dataStartPos + size;\n }\n }\n // Sort the seek entries by file position so reading them exhibits a sequential pattern\n this.currentSegment.seekEntries.sort((a, b) => a.segmentPosition - b.segmentPosition);\n if (this.reader.fileSize !== null) {\n // Use the seek head to read missing metadata elements\n for (const seekEntry of this.currentSegment.seekEntries) {\n const target = METADATA_ELEMENTS.find(x => x.id === seekEntry.id);\n if (!target) {\n continue;\n }\n if (this.currentSegment[target.flag])\n continue;\n let slice = this.reader.requestSliceRange(segmentDataStart + seekEntry.segmentPosition, MIN_HEADER_SIZE, MAX_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n continue;\n const header = readElementHeader(slice);\n if (!header)\n continue;\n const { id, size } = header;\n if (id !== target.id)\n continue;\n assertDefinedSize(size);\n this.currentSegment[target.flag] = true;\n let dataSlice = this.reader.requestSlice(slice.filePos, size);\n if (dataSlice instanceof Promise)\n dataSlice = await dataSlice;\n if (!dataSlice)\n continue;\n this.readContiguousElements(dataSlice);\n }\n }\n if (this.currentSegment.timestampScale === -1) {\n // TimestampScale element is missing. Technically an invalid file, but let's default to the typical value,\n // which is 1e6.\n this.currentSegment.timestampScale = 1e6;\n this.currentSegment.timestampFactor = 1e9 / 1e6;\n }\n // Put default tracks first\n this.currentSegment.tracks.sort((a, b) => Number(b.disposition.default) - Number(a.disposition.default));\n // Now, let's distribute the cue points to the tracks\n const idToTrack = new Map(this.currentSegment.tracks.map(x => [x.id, x]));\n // Assign cue points to their respective tracks\n for (const cuePoint of this.currentSegment.cuePoints) {\n const track = idToTrack.get(cuePoint.trackId);\n if (track) {\n track.cuePoints.push(cuePoint);\n }\n }\n for (const track of this.currentSegment.tracks) {\n // Sort cue points by time\n track.cuePoints.sort((a, b) => a.time - b.time);\n // Remove multiple cue points for the same time\n for (let i = 0; i < track.cuePoints.length - 1; i++) {\n const cuePoint1 = track.cuePoints[i];\n const cuePoint2 = track.cuePoints[i + 1];\n if (cuePoint1.time === cuePoint2.time) {\n track.cuePoints.splice(i + 1, 1);\n i--;\n }\n }\n }\n let trackWithMostCuePoints = null;\n let maxCuePointCount = -Infinity;\n for (const track of this.currentSegment.tracks) {\n if (track.cuePoints.length > maxCuePointCount) {\n maxCuePointCount = track.cuePoints.length;\n trackWithMostCuePoints = track;\n }\n }\n // For every track that has received 0 cue points (can happen, often only the video track receives cue points),\n // we still want to have better seeking. Therefore, let's give it the cue points of the track with the most cue\n // points, which should provide us with the most fine-grained seeking.\n for (const track of this.currentSegment.tracks) {\n if (track.cuePoints.length === 0) {\n track.cuePoints = trackWithMostCuePoints.cuePoints;\n }\n }\n this.currentSegment = null;\n }\n async readCluster(startPos, segment) {\n if (segment.lastReadCluster?.elementStartPos === startPos) {\n return segment.lastReadCluster;\n }\n let headerSlice = this.reader.requestSliceRange(startPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);\n if (headerSlice instanceof Promise)\n headerSlice = await headerSlice;\n assert(headerSlice);\n const elementStartPos = startPos;\n const elementHeader = readElementHeader(headerSlice);\n assert(elementHeader);\n const id = elementHeader.id;\n assert(id === EBMLId.Cluster);\n let size = elementHeader.size;\n const dataStartPos = headerSlice.filePos;\n if (size === null) {\n // The cluster's size is undefined (can happen in livestreamed files). We'd still like to know the size of\n // it, so we have no other choice but to iterate over the EBML structure until we find an element at level\n // 0 or 1, indicating the end of the cluster (all elements inside the cluster are at level 2).\n const nextElementPos = await searchForNextElementId(this.reader, dataStartPos, LEVEL_0_AND_1_EBML_IDS, segment.elementEndPos);\n size = nextElementPos.pos - dataStartPos;\n }\n // Load the entire cluster\n let dataSlice = this.reader.requestSlice(dataStartPos, size);\n if (dataSlice instanceof Promise)\n dataSlice = await dataSlice;\n const cluster = {\n segment,\n elementStartPos,\n elementEndPos: dataStartPos + size,\n dataStartPos,\n timestamp: -1,\n trackData: new Map(),\n };\n this.currentCluster = cluster;\n if (dataSlice) {\n // Read the children of the cluster, stopping early at level 0 or 1 EBML elements. We do this because some\n // clusters have incorrect sizes that are too large\n const endPos = this.readContiguousElements(dataSlice, LEVEL_0_AND_1_EBML_IDS);\n cluster.elementEndPos = endPos;\n }\n for (const [, trackData] of cluster.trackData) {\n const track = trackData.track;\n // This must hold, as track datas only get created if a block for that track is encountered\n assert(trackData.blocks.length > 0);\n let hasLacedBlocks = false;\n for (let i = 0; i < trackData.blocks.length; i++) {\n const block = trackData.blocks[i];\n block.timestamp += cluster.timestamp;\n hasLacedBlocks ||= block.lacing !== BlockLacing.None;\n }\n trackData.presentationTimestamps = trackData.blocks\n .map((block, i) => ({ timestamp: block.timestamp, blockIndex: i }))\n .sort((a, b) => a.timestamp - b.timestamp);\n for (let i = 0; i < trackData.presentationTimestamps.length; i++) {\n const currentEntry = trackData.presentationTimestamps[i];\n const currentBlock = trackData.blocks[currentEntry.blockIndex];\n if (trackData.firstKeyFrameTimestamp === null && currentBlock.isKeyFrame) {\n trackData.firstKeyFrameTimestamp = currentBlock.timestamp;\n }\n if (i < trackData.presentationTimestamps.length - 1) {\n // Update block durations based on presentation order\n const nextEntry = trackData.presentationTimestamps[i + 1];\n currentBlock.duration = nextEntry.timestamp - currentBlock.timestamp;\n }\n else if (currentBlock.duration === 0) {\n if (track.defaultDuration != null) {\n if (currentBlock.lacing === BlockLacing.None) {\n currentBlock.duration = track.defaultDuration;\n }\n else {\n // Handled by the lace resolution code\n }\n }\n }\n }\n if (hasLacedBlocks) {\n // Perform lace resolution. Here, we expand each laced block into multiple blocks where each contains\n // one frame of the lace. We do this after determining block timestamps so we can properly distribute\n // the block's duration across the laced frames.\n this.expandLacedBlocks(trackData.blocks, track);\n // Recompute since blocks have changed\n trackData.presentationTimestamps = trackData.blocks\n .map((block, i) => ({ timestamp: block.timestamp, blockIndex: i }))\n .sort((a, b) => a.timestamp - b.timestamp);\n }\n const firstBlock = trackData.blocks[trackData.presentationTimestamps[0].blockIndex];\n const lastBlock = trackData.blocks[last(trackData.presentationTimestamps).blockIndex];\n trackData.startTimestamp = firstBlock.timestamp;\n trackData.endTimestamp = lastBlock.timestamp + lastBlock.duration;\n // Let's remember that a cluster with a given timestamp is here, speeding up future lookups if no cues exist\n const insertionIndex = binarySearchLessOrEqual(track.clusterPositionCache, trackData.startTimestamp, x => x.startTimestamp);\n if (insertionIndex === -1\n || track.clusterPositionCache[insertionIndex].elementStartPos !== elementStartPos) {\n track.clusterPositionCache.splice(insertionIndex + 1, 0, {\n elementStartPos: cluster.elementStartPos,\n startTimestamp: trackData.startTimestamp,\n });\n }\n }\n segment.lastReadCluster = cluster;\n return cluster;\n }\n getTrackDataInCluster(cluster, trackNumber) {\n let trackData = cluster.trackData.get(trackNumber);\n if (!trackData) {\n const track = cluster.segment.tracks.find(x => x.id === trackNumber);\n if (!track) {\n return null;\n }\n trackData = {\n track,\n startTimestamp: 0,\n endTimestamp: 0,\n firstKeyFrameTimestamp: null,\n blocks: [],\n presentationTimestamps: [],\n };\n cluster.trackData.set(trackNumber, trackData);\n }\n return trackData;\n }\n expandLacedBlocks(blocks, track) {\n // https://www.matroska.org/technical/notes.html#block-lacing\n for (let blockIndex = 0; blockIndex < blocks.length; blockIndex++) {\n const originalBlock = blocks[blockIndex];\n if (originalBlock.lacing === BlockLacing.None) {\n continue;\n }\n // Decode the block data if it hasn't been decoded yet (needed for lacing expansion)\n if (!originalBlock.decoded) {\n originalBlock.data = this.decodeBlockData(track, originalBlock.data);\n originalBlock.decoded = true;\n }\n const slice = FileSlice.tempFromBytes(originalBlock.data);\n const frameSizes = [];\n const frameCount = readU8(slice) + 1;\n switch (originalBlock.lacing) {\n case BlockLacing.Xiph:\n {\n let totalUsedSize = 0;\n // Xiph lacing, just like in Ogg\n for (let i = 0; i < frameCount - 1; i++) {\n let frameSize = 0;\n while (slice.bufferPos < slice.length) {\n const value = readU8(slice);\n frameSize += value;\n if (value < 255) {\n frameSizes.push(frameSize);\n totalUsedSize += frameSize;\n break;\n }\n }\n }\n // Compute the last frame's size from whatever's left\n frameSizes.push(slice.length - (slice.bufferPos + totalUsedSize));\n }\n ;\n break;\n case BlockLacing.FixedSize:\n {\n // Fixed size lacing: all frames have same size\n const totalDataSize = slice.length - 1; // Minus the frame count byte\n const frameSize = Math.floor(totalDataSize / frameCount);\n for (let i = 0; i < frameCount; i++) {\n frameSizes.push(frameSize);\n }\n }\n ;\n break;\n case BlockLacing.Ebml:\n {\n // EBML lacing: first size absolute, subsequent ones are coded as signed differences from the last\n const firstResult = readVarInt(slice);\n assert(firstResult !== null); // Assume it's not an invalid VINT\n let currentSize = firstResult;\n frameSizes.push(currentSize);\n let totalUsedSize = currentSize;\n for (let i = 1; i < frameCount - 1; i++) {\n const startPos = slice.bufferPos;\n const diffResult = readVarInt(slice);\n assert(diffResult !== null);\n const unsignedDiff = diffResult;\n const width = slice.bufferPos - startPos;\n const bias = (1 << (width * 7 - 1)) - 1; // Typo-corrected version of 2^((7*n)-1)^-1\n const diff = unsignedDiff - bias;\n currentSize += diff;\n frameSizes.push(currentSize);\n totalUsedSize += currentSize;\n }\n // Compute the last frame's size from whatever's left\n frameSizes.push(slice.length - (slice.bufferPos + totalUsedSize));\n }\n ;\n break;\n default: assert(false);\n }\n assert(frameSizes.length === frameCount);\n blocks.splice(blockIndex, 1); // Remove the original block\n const blockDuration = originalBlock.duration || frameCount * (track.defaultDuration ?? 0);\n // Now, let's insert each frame as its own block\n for (let i = 0; i < frameCount; i++) {\n const frameSize = frameSizes[i];\n const frameData = readBytes(slice, frameSize);\n // Distribute timestamps evenly across the block duration\n const frameTimestamp = originalBlock.timestamp + (blockDuration * i / frameCount);\n const frameDuration = blockDuration / frameCount;\n blocks.splice(blockIndex + i, 0, {\n timestamp: frameTimestamp,\n duration: frameDuration,\n isKeyFrame: originalBlock.isKeyFrame,\n data: frameData,\n lacing: BlockLacing.None,\n decoded: true,\n mainAdditional: originalBlock.mainAdditional,\n });\n }\n blockIndex += frameCount; // Skip the blocks we just added\n blockIndex--;\n }\n }\n async loadSegmentMetadata(segment) {\n for (const seekEntry of segment.seekEntries) {\n if (seekEntry.id === EBMLId.Tags && !segment.tagsSeen) {\n // We need to load the tags\n }\n else if (seekEntry.id === EBMLId.Attachments && !segment.attachmentsSeen) {\n // We need to load the attachments\n }\n else {\n continue;\n }\n let slice = this.reader.requestSliceRange(segment.dataStartPos + seekEntry.segmentPosition, MIN_HEADER_SIZE, MAX_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n continue;\n const header = readElementHeader(slice);\n if (!header || header.id !== seekEntry.id)\n continue;\n const { size } = header;\n assertDefinedSize(size);\n assert(!this.currentSegment);\n this.currentSegment = segment;\n let dataSlice = this.reader.requestSlice(slice.filePos, size);\n if (dataSlice instanceof Promise)\n dataSlice = await dataSlice;\n if (dataSlice) {\n this.readContiguousElements(dataSlice);\n }\n this.currentSegment = null;\n // Mark as seen\n if (seekEntry.id === EBMLId.Tags) {\n segment.tagsSeen = true;\n }\n else if (seekEntry.id === EBMLId.Attachments) {\n segment.attachmentsSeen = true;\n }\n }\n }\n readContiguousElements(slice, stopIds) {\n const startIndex = slice.filePos;\n while (slice.filePos - startIndex <= slice.length - MIN_HEADER_SIZE) {\n const startPos = slice.filePos;\n const foundElement = this.traverseElement(slice, stopIds);\n if (!foundElement) {\n return startPos;\n }\n }\n return slice.filePos;\n }\n traverseElement(slice, stopIds) {\n const header = readElementHeader(slice);\n if (!header) {\n return false;\n }\n if (stopIds && stopIds.includes(header.id)) {\n return false;\n }\n const { id, size } = header;\n const dataStartPos = slice.filePos;\n assertDefinedSize(size);\n switch (id) {\n case EBMLId.DocType:\n {\n this.isWebM = readAsciiString(slice, size) === 'webm';\n }\n ;\n break;\n case EBMLId.Seek:\n {\n if (!this.currentSegment)\n break;\n const seekEntry = { id: -1, segmentPosition: -1 };\n this.currentSegment.seekEntries.push(seekEntry);\n this.readContiguousElements(slice.slice(dataStartPos, size));\n if (seekEntry.id === -1 || seekEntry.segmentPosition === -1) {\n this.currentSegment.seekEntries.pop();\n }\n }\n ;\n break;\n case EBMLId.SeekID:\n {\n const lastSeekEntry = this.currentSegment?.seekEntries[this.currentSegment.seekEntries.length - 1];\n if (!lastSeekEntry)\n break;\n lastSeekEntry.id = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.SeekPosition:\n {\n const lastSeekEntry = this.currentSegment?.seekEntries[this.currentSegment.seekEntries.length - 1];\n if (!lastSeekEntry)\n break;\n lastSeekEntry.segmentPosition = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.TimestampScale:\n {\n if (!this.currentSegment)\n break;\n this.currentSegment.timestampScale = readUnsignedInt(slice, size);\n this.currentSegment.timestampFactor = 1e9 / this.currentSegment.timestampScale;\n }\n ;\n break;\n case EBMLId.Duration:\n {\n if (!this.currentSegment)\n break;\n this.currentSegment.duration = readFloat(slice, size);\n }\n ;\n break;\n case EBMLId.TrackEntry:\n {\n if (!this.currentSegment)\n break;\n this.currentTrack = {\n id: -1,\n segment: this.currentSegment,\n demuxer: this,\n clusterPositionCache: [],\n cuePoints: [],\n disposition: {\n ...DEFAULT_TRACK_DISPOSITION,\n },\n inputTrack: null,\n codecId: null,\n codecPrivate: null,\n defaultDuration: null,\n name: null,\n languageCode: UNDETERMINED_LANGUAGE,\n decodingInstructions: [],\n info: null,\n };\n this.readContiguousElements(slice.slice(dataStartPos, size));\n if (this.currentTrack.decodingInstructions.some((instruction) => {\n return instruction.data?.type !== 'decompress'\n || instruction.scope !== ContentEncodingScope.Block\n || instruction.data.algorithm !== ContentCompAlgo.HeaderStripping;\n })) {\n console.warn(`Track #${this.currentTrack.id} has an unsupported content encoding; dropping.`);\n this.currentTrack = null;\n }\n if (this.currentTrack\n && this.currentTrack.id !== -1\n && this.currentTrack.codecId\n && this.currentTrack.info) {\n const slashIndex = this.currentTrack.codecId.indexOf('/');\n const codecIdWithoutSuffix = slashIndex === -1\n ? this.currentTrack.codecId\n : this.currentTrack.codecId.slice(0, slashIndex);\n if (this.currentTrack.info.type === 'video'\n && this.currentTrack.info.width !== -1\n && this.currentTrack.info.height !== -1) {\n if (this.currentTrack.codecId === CODEC_STRING_MAP.avc) {\n this.currentTrack.info.codec = 'avc';\n this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;\n }\n else if (this.currentTrack.codecId === CODEC_STRING_MAP.hevc) {\n this.currentTrack.info.codec = 'hevc';\n this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;\n }\n else if (codecIdWithoutSuffix === CODEC_STRING_MAP.vp8) {\n this.currentTrack.info.codec = 'vp8';\n }\n else if (codecIdWithoutSuffix === CODEC_STRING_MAP.vp9) {\n this.currentTrack.info.codec = 'vp9';\n }\n else if (codecIdWithoutSuffix === CODEC_STRING_MAP.av1) {\n this.currentTrack.info.codec = 'av1';\n }\n const videoTrack = this.currentTrack;\n const inputTrack = new InputVideoTrack(this.input, new MatroskaVideoTrackBacking(videoTrack));\n this.currentTrack.inputTrack = inputTrack;\n this.currentSegment.tracks.push(this.currentTrack);\n }\n else if (this.currentTrack.info.type === 'audio'\n && this.currentTrack.info.numberOfChannels !== -1\n && this.currentTrack.info.sampleRate !== -1) {\n if (codecIdWithoutSuffix === CODEC_STRING_MAP.aac) {\n this.currentTrack.info.codec = 'aac';\n this.currentTrack.info.aacCodecInfo = {\n isMpeg2: this.currentTrack.codecId.includes('MPEG2'),\n };\n this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;\n }\n else if (this.currentTrack.codecId === CODEC_STRING_MAP.mp3) {\n this.currentTrack.info.codec = 'mp3';\n }\n else if (codecIdWithoutSuffix === CODEC_STRING_MAP.opus) {\n this.currentTrack.info.codec = 'opus';\n this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;\n this.currentTrack.info.sampleRate = OPUS_SAMPLE_RATE; // Always the same\n }\n else if (codecIdWithoutSuffix === CODEC_STRING_MAP.vorbis) {\n this.currentTrack.info.codec = 'vorbis';\n this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;\n }\n else if (codecIdWithoutSuffix === CODEC_STRING_MAP.flac) {\n this.currentTrack.info.codec = 'flac';\n this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;\n }\n else if (this.currentTrack.codecId === 'A_PCM/INT/LIT') {\n if (this.currentTrack.info.bitDepth === 8) {\n this.currentTrack.info.codec = 'pcm-u8';\n }\n else if (this.currentTrack.info.bitDepth === 16) {\n this.currentTrack.info.codec = 'pcm-s16';\n }\n else if (this.currentTrack.info.bitDepth === 24) {\n this.currentTrack.info.codec = 'pcm-s24';\n }\n else if (this.currentTrack.info.bitDepth === 32) {\n this.currentTrack.info.codec = 'pcm-s32';\n }\n }\n else if (this.currentTrack.codecId === 'A_PCM/INT/BIG') {\n if (this.currentTrack.info.bitDepth === 8) {\n this.currentTrack.info.codec = 'pcm-u8';\n }\n else if (this.currentTrack.info.bitDepth === 16) {\n this.currentTrack.info.codec = 'pcm-s16be';\n }\n else if (this.currentTrack.info.bitDepth === 24) {\n this.currentTrack.info.codec = 'pcm-s24be';\n }\n else if (this.currentTrack.info.bitDepth === 32) {\n this.currentTrack.info.codec = 'pcm-s32be';\n }\n }\n else if (this.currentTrack.codecId === 'A_PCM/FLOAT/IEEE') {\n if (this.currentTrack.info.bitDepth === 32) {\n this.currentTrack.info.codec = 'pcm-f32';\n }\n else if (this.currentTrack.info.bitDepth === 64) {\n this.currentTrack.info.codec = 'pcm-f64';\n }\n }\n const audioTrack = this.currentTrack;\n const inputTrack = new InputAudioTrack(this.input, new MatroskaAudioTrackBacking(audioTrack));\n this.currentTrack.inputTrack = inputTrack;\n this.currentSegment.tracks.push(this.currentTrack);\n }\n }\n this.currentTrack = null;\n }\n ;\n break;\n case EBMLId.TrackNumber:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.id = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.TrackType:\n {\n if (!this.currentTrack)\n break;\n const type = readUnsignedInt(slice, size);\n if (type === 1) {\n this.currentTrack.info = {\n type: 'video',\n width: -1,\n height: -1,\n rotation: 0,\n codec: null,\n codecDescription: null,\n colorSpace: null,\n alphaMode: false,\n };\n }\n else if (type === 2) {\n this.currentTrack.info = {\n type: 'audio',\n numberOfChannels: -1,\n sampleRate: -1,\n bitDepth: -1,\n codec: null,\n codecDescription: null,\n aacCodecInfo: null,\n };\n }\n }\n ;\n break;\n case EBMLId.FlagEnabled:\n {\n if (!this.currentTrack)\n break;\n const enabled = readUnsignedInt(slice, size);\n if (!enabled) {\n this.currentSegment.tracks.pop();\n this.currentTrack = null;\n }\n }\n ;\n break;\n case EBMLId.FlagDefault:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.disposition.default = !!readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.FlagForced:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.disposition.forced = !!readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.FlagOriginal:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.disposition.original = !!readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.FlagHearingImpaired:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.disposition.hearingImpaired = !!readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.FlagVisualImpaired:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.disposition.visuallyImpaired = !!readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.FlagCommentary:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.disposition.commentary = !!readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.CodecID:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.codecId = readAsciiString(slice, size);\n }\n ;\n break;\n case EBMLId.CodecPrivate:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.codecPrivate = readBytes(slice, size);\n }\n ;\n break;\n case EBMLId.DefaultDuration:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.defaultDuration\n = this.currentTrack.segment.timestampFactor * readUnsignedInt(slice, size) / 1e9;\n }\n ;\n break;\n case EBMLId.Name:\n {\n if (!this.currentTrack)\n break;\n this.currentTrack.name = readUnicodeString(slice, size);\n }\n ;\n break;\n case EBMLId.Language:\n {\n if (!this.currentTrack)\n break;\n if (this.currentTrack.languageCode !== UNDETERMINED_LANGUAGE) {\n // LanguageBCP47 was present, which takes precedence\n break;\n }\n this.currentTrack.languageCode = readAsciiString(slice, size);\n if (!isIso639Dash2LanguageCode(this.currentTrack.languageCode)) {\n this.currentTrack.languageCode = UNDETERMINED_LANGUAGE;\n }\n }\n ;\n break;\n case EBMLId.LanguageBCP47:\n {\n if (!this.currentTrack)\n break;\n const bcp47 = readAsciiString(slice, size);\n const languageSubtag = bcp47.split('-')[0];\n if (languageSubtag) {\n // Technically invalid, for now: The language subtag might be a language code from ISO 639-1,\n // ISO 639-2, ISO 639-3, ISO 639-5 or some other thing (source: Wikipedia). But, `languageCode` is\n // documented as ISO 639-2. Changing the definition would be a breaking change. This will get\n // cleaned up in the future by defining languageCode to be BCP 47 instead.\n this.currentTrack.languageCode = languageSubtag;\n }\n else {\n this.currentTrack.languageCode = UNDETERMINED_LANGUAGE;\n }\n }\n ;\n break;\n case EBMLId.Video:\n {\n if (this.currentTrack?.info?.type !== 'video')\n break;\n this.readContiguousElements(slice.slice(dataStartPos, size));\n }\n ;\n break;\n case EBMLId.PixelWidth:\n {\n if (this.currentTrack?.info?.type !== 'video')\n break;\n this.currentTrack.info.width = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.PixelHeight:\n {\n if (this.currentTrack?.info?.type !== 'video')\n break;\n this.currentTrack.info.height = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.AlphaMode:\n {\n if (this.currentTrack?.info?.type !== 'video')\n break;\n this.currentTrack.info.alphaMode = readUnsignedInt(slice, size) === 1;\n }\n ;\n break;\n case EBMLId.Colour:\n {\n if (this.currentTrack?.info?.type !== 'video')\n break;\n this.currentTrack.info.colorSpace = {};\n this.readContiguousElements(slice.slice(dataStartPos, size));\n }\n ;\n break;\n case EBMLId.MatrixCoefficients:\n {\n if (this.currentTrack?.info?.type !== 'video' || !this.currentTrack.info.colorSpace)\n break;\n const matrixCoefficients = readUnsignedInt(slice, size);\n const mapped = MATRIX_COEFFICIENTS_MAP_INVERSE[matrixCoefficients] ?? null;\n this.currentTrack.info.colorSpace.matrix = mapped;\n }\n ;\n break;\n case EBMLId.Range:\n {\n if (this.currentTrack?.info?.type !== 'video' || !this.currentTrack.info.colorSpace)\n break;\n this.currentTrack.info.colorSpace.fullRange = readUnsignedInt(slice, size) === 2;\n }\n ;\n break;\n case EBMLId.TransferCharacteristics:\n {\n if (this.currentTrack?.info?.type !== 'video' || !this.currentTrack.info.colorSpace)\n break;\n const transferCharacteristics = readUnsignedInt(slice, size);\n const mapped = TRANSFER_CHARACTERISTICS_MAP_INVERSE[transferCharacteristics] ?? null;\n this.currentTrack.info.colorSpace.transfer = mapped;\n }\n ;\n break;\n case EBMLId.Primaries:\n {\n if (this.currentTrack?.info?.type !== 'video' || !this.currentTrack.info.colorSpace)\n break;\n const primaries = readUnsignedInt(slice, size);\n const mapped = COLOR_PRIMARIES_MAP_INVERSE[primaries] ?? null;\n this.currentTrack.info.colorSpace.primaries = mapped;\n }\n ;\n break;\n case EBMLId.Projection:\n {\n if (this.currentTrack?.info?.type !== 'video')\n break;\n this.readContiguousElements(slice.slice(dataStartPos, size));\n }\n ;\n break;\n case EBMLId.ProjectionPoseRoll:\n {\n if (this.currentTrack?.info?.type !== 'video')\n break;\n const rotation = readFloat(slice, size);\n const flippedRotation = -rotation; // Convert counter-clockwise to clockwise\n try {\n this.currentTrack.info.rotation = normalizeRotation(flippedRotation);\n }\n catch {\n // It wasn't a valid rotation\n }\n }\n ;\n break;\n case EBMLId.Audio:\n {\n if (this.currentTrack?.info?.type !== 'audio')\n break;\n this.readContiguousElements(slice.slice(dataStartPos, size));\n }\n ;\n break;\n case EBMLId.SamplingFrequency:\n {\n if (this.currentTrack?.info?.type !== 'audio')\n break;\n this.currentTrack.info.sampleRate = readFloat(slice, size);\n }\n ;\n break;\n case EBMLId.Channels:\n {\n if (this.currentTrack?.info?.type !== 'audio')\n break;\n this.currentTrack.info.numberOfChannels = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.BitDepth:\n {\n if (this.currentTrack?.info?.type !== 'audio')\n break;\n this.currentTrack.info.bitDepth = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.CuePoint:\n {\n if (!this.currentSegment)\n break;\n this.readContiguousElements(slice.slice(dataStartPos, size));\n this.currentCueTime = null;\n }\n ;\n break;\n case EBMLId.CueTime:\n {\n this.currentCueTime = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.CueTrackPositions:\n {\n if (this.currentCueTime === null)\n break;\n assert(this.currentSegment);\n const cuePoint = { time: this.currentCueTime, trackId: -1, clusterPosition: -1 };\n this.currentSegment.cuePoints.push(cuePoint);\n this.readContiguousElements(slice.slice(dataStartPos, size));\n if (cuePoint.trackId === -1 || cuePoint.clusterPosition === -1) {\n this.currentSegment.cuePoints.pop();\n }\n }\n ;\n break;\n case EBMLId.CueTrack:\n {\n const lastCuePoint = this.currentSegment?.cuePoints[this.currentSegment.cuePoints.length - 1];\n if (!lastCuePoint)\n break;\n lastCuePoint.trackId = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.CueClusterPosition:\n {\n const lastCuePoint = this.currentSegment?.cuePoints[this.currentSegment.cuePoints.length - 1];\n if (!lastCuePoint)\n break;\n assert(this.currentSegment);\n lastCuePoint.clusterPosition = this.currentSegment.dataStartPos + readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.Timestamp:\n {\n if (!this.currentCluster)\n break;\n this.currentCluster.timestamp = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.SimpleBlock:\n {\n if (!this.currentCluster)\n break;\n const trackNumber = readVarInt(slice);\n if (trackNumber === null)\n break;\n const trackData = this.getTrackDataInCluster(this.currentCluster, trackNumber);\n if (!trackData)\n break; // Not a track we care about\n const relativeTimestamp = readI16Be(slice);\n const flags = readU8(slice);\n const lacing = (flags >> 1) & 0x3; // If the block is laced, we'll expand it later\n let isKeyFrame = !!(flags & 0x80);\n if (trackData.track.info?.type === 'audio' && trackData.track.info.codec) {\n // Some files don't mark their audio packets as key packets (I'm looking at you, Firefox). But, we\n // can fix this in most cases: if we recognize the codec of the track, then we know every packet is\n // necessarily a key packet, no matter what the container says.\n // https://github.com/Vanilagy/mediabunny/issues/192\n isKeyFrame = true;\n }\n const blockData = readBytes(slice, size - (slice.filePos - dataStartPos));\n const hasDecodingInstructions = trackData.track.decodingInstructions.length > 0;\n trackData.blocks.push({\n timestamp: relativeTimestamp, // We'll add the cluster's timestamp to this later\n duration: 0, // Will set later\n isKeyFrame,\n data: blockData,\n lacing,\n decoded: !hasDecodingInstructions,\n mainAdditional: null,\n });\n }\n ;\n break;\n case EBMLId.BlockGroup:\n {\n if (!this.currentCluster)\n break;\n this.readContiguousElements(slice.slice(dataStartPos, size));\n this.currentBlock = null;\n }\n ;\n break;\n case EBMLId.Block:\n {\n if (!this.currentCluster)\n break;\n const trackNumber = readVarInt(slice);\n if (trackNumber === null)\n break;\n const trackData = this.getTrackDataInCluster(this.currentCluster, trackNumber);\n if (!trackData)\n break;\n const relativeTimestamp = readI16Be(slice);\n const flags = readU8(slice);\n const lacing = (flags >> 1) & 0x3; // If the block is laced, we'll expand it later\n const blockData = readBytes(slice, size - (slice.filePos - dataStartPos));\n const hasDecodingInstructions = trackData.track.decodingInstructions.length > 0;\n this.currentBlock = {\n timestamp: relativeTimestamp, // We'll add the cluster's timestamp to this later\n duration: 0, // Will set later\n isKeyFrame: true,\n data: blockData,\n lacing,\n decoded: !hasDecodingInstructions,\n mainAdditional: null,\n };\n trackData.blocks.push(this.currentBlock);\n }\n ;\n break;\n case EBMLId.BlockAdditions:\n {\n this.readContiguousElements(slice.slice(dataStartPos, size));\n }\n ;\n break;\n case EBMLId.BlockMore:\n {\n if (!this.currentBlock)\n break;\n this.currentBlockAdditional = {\n addId: 1,\n data: null,\n };\n this.readContiguousElements(slice.slice(dataStartPos, size));\n if (this.currentBlockAdditional.data && this.currentBlockAdditional.addId === 1) {\n this.currentBlock.mainAdditional = this.currentBlockAdditional.data;\n }\n this.currentBlockAdditional = null;\n }\n ;\n break;\n case EBMLId.BlockAdditional:\n {\n if (!this.currentBlockAdditional)\n break;\n this.currentBlockAdditional.data = readBytes(slice, size);\n }\n ;\n break;\n case EBMLId.BlockAddID:\n {\n if (!this.currentBlockAdditional)\n break;\n this.currentBlockAdditional.addId = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.BlockDuration:\n {\n if (!this.currentBlock)\n break;\n this.currentBlock.duration = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.ReferenceBlock:\n {\n if (!this.currentBlock)\n break;\n this.currentBlock.isKeyFrame = false;\n // We ignore the actual value here, we just use the reference as an indicator for \"not a key frame\".\n // This is in line with FFmpeg's behavior.\n }\n ;\n break;\n case EBMLId.Tag:\n {\n this.currentTagTargetIsMovie = true;\n this.readContiguousElements(slice.slice(dataStartPos, size));\n }\n ;\n break;\n case EBMLId.Targets:\n {\n this.readContiguousElements(slice.slice(dataStartPos, size));\n }\n ;\n break;\n case EBMLId.TargetTypeValue:\n {\n const targetTypeValue = readUnsignedInt(slice, size);\n if (targetTypeValue !== 50) {\n this.currentTagTargetIsMovie = false;\n }\n }\n ;\n break;\n case EBMLId.TagTrackUID:\n case EBMLId.TagEditionUID:\n case EBMLId.TagChapterUID:\n case EBMLId.TagAttachmentUID:\n {\n this.currentTagTargetIsMovie = false;\n }\n ;\n break;\n case EBMLId.SimpleTag:\n {\n if (!this.currentTagTargetIsMovie)\n break;\n this.currentSimpleTagName = null;\n this.readContiguousElements(slice.slice(dataStartPos, size));\n }\n ;\n break;\n case EBMLId.TagName:\n {\n this.currentSimpleTagName = readUnicodeString(slice, size);\n }\n ;\n break;\n case EBMLId.TagString:\n {\n if (!this.currentSimpleTagName)\n break;\n const value = readUnicodeString(slice, size);\n this.processTagValue(this.currentSimpleTagName, value);\n }\n ;\n break;\n case EBMLId.TagBinary:\n {\n if (!this.currentSimpleTagName)\n break;\n const value = readBytes(slice, size);\n this.processTagValue(this.currentSimpleTagName, value);\n }\n ;\n break;\n case EBMLId.AttachedFile:\n {\n if (!this.currentSegment)\n break;\n this.currentAttachedFile = {\n fileUid: null,\n fileName: null,\n fileMediaType: null,\n fileData: null,\n fileDescription: null,\n };\n this.readContiguousElements(slice.slice(dataStartPos, size));\n const tags = this.currentSegment.metadataTags;\n if (this.currentAttachedFile.fileUid && this.currentAttachedFile.fileData) {\n // All attached files get surfaced in the `raw` metadata tags\n tags.raw ??= {};\n tags.raw[this.currentAttachedFile.fileUid.toString()] = new AttachedFile(this.currentAttachedFile.fileData, this.currentAttachedFile.fileMediaType ?? undefined, this.currentAttachedFile.fileName ?? undefined, this.currentAttachedFile.fileDescription ?? undefined);\n }\n // Only process image attachments\n if (this.currentAttachedFile.fileMediaType?.startsWith('image/') && this.currentAttachedFile.fileData) {\n const fileName = this.currentAttachedFile.fileName;\n let kind = 'unknown';\n if (fileName) {\n const lowerName = fileName.toLowerCase();\n if (lowerName.startsWith('cover.')) {\n kind = 'coverFront';\n }\n else if (lowerName.startsWith('back.')) {\n kind = 'coverBack';\n }\n }\n tags.images ??= [];\n tags.images.push({\n data: this.currentAttachedFile.fileData,\n mimeType: this.currentAttachedFile.fileMediaType,\n kind,\n name: this.currentAttachedFile.fileName ?? undefined,\n description: this.currentAttachedFile.fileDescription ?? undefined,\n });\n }\n this.currentAttachedFile = null;\n }\n ;\n break;\n case EBMLId.FileUID:\n {\n if (!this.currentAttachedFile)\n break;\n this.currentAttachedFile.fileUid = readUnsignedBigInt(slice, size);\n }\n ;\n break;\n case EBMLId.FileName:\n {\n if (!this.currentAttachedFile)\n break;\n this.currentAttachedFile.fileName = readUnicodeString(slice, size);\n }\n ;\n break;\n case EBMLId.FileMediaType:\n {\n if (!this.currentAttachedFile)\n break;\n this.currentAttachedFile.fileMediaType = readAsciiString(slice, size);\n }\n ;\n break;\n case EBMLId.FileData:\n {\n if (!this.currentAttachedFile)\n break;\n this.currentAttachedFile.fileData = readBytes(slice, size);\n }\n ;\n break;\n case EBMLId.FileDescription:\n {\n if (!this.currentAttachedFile)\n break;\n this.currentAttachedFile.fileDescription = readUnicodeString(slice, size);\n }\n ;\n break;\n case EBMLId.ContentEncodings:\n {\n if (!this.currentTrack)\n break;\n this.readContiguousElements(slice.slice(dataStartPos, size));\n // \"**MUST** start with the `ContentEncoding` with the highest `ContentEncodingOrder`\"\n this.currentTrack.decodingInstructions.sort((a, b) => b.order - a.order);\n }\n ;\n break;\n case EBMLId.ContentEncoding:\n {\n this.currentDecodingInstruction = {\n order: 0,\n scope: ContentEncodingScope.Block,\n data: null,\n };\n this.readContiguousElements(slice.slice(dataStartPos, size));\n if (this.currentDecodingInstruction.data) {\n this.currentTrack.decodingInstructions.push(this.currentDecodingInstruction);\n }\n this.currentDecodingInstruction = null;\n }\n ;\n break;\n case EBMLId.ContentEncodingOrder:\n {\n if (!this.currentDecodingInstruction)\n break;\n this.currentDecodingInstruction.order = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.ContentEncodingScope:\n {\n if (!this.currentDecodingInstruction)\n break;\n this.currentDecodingInstruction.scope = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.ContentCompression:\n {\n if (!this.currentDecodingInstruction)\n break;\n this.currentDecodingInstruction.data = {\n type: 'decompress',\n algorithm: ContentCompAlgo.Zlib,\n settings: null,\n };\n this.readContiguousElements(slice.slice(dataStartPos, size));\n }\n ;\n break;\n case EBMLId.ContentCompAlgo:\n {\n if (this.currentDecodingInstruction?.data?.type !== 'decompress')\n break;\n this.currentDecodingInstruction.data.algorithm = readUnsignedInt(slice, size);\n }\n ;\n break;\n case EBMLId.ContentCompSettings:\n {\n if (this.currentDecodingInstruction?.data?.type !== 'decompress')\n break;\n this.currentDecodingInstruction.data.settings = readBytes(slice, size);\n }\n ;\n break;\n case EBMLId.ContentEncryption:\n {\n if (!this.currentDecodingInstruction)\n break;\n this.currentDecodingInstruction.data = {\n type: 'decrypt',\n };\n }\n ;\n break;\n }\n slice.filePos = dataStartPos + size;\n return true;\n }\n decodeBlockData(track, rawData) {\n assert(track.decodingInstructions.length > 0); // This method shouldn't be called otherwise\n let currentData = rawData;\n for (const instruction of track.decodingInstructions) {\n assert(instruction.data);\n switch (instruction.data.type) {\n case 'decompress':\n {\n switch (instruction.data.algorithm) {\n case ContentCompAlgo.HeaderStripping:\n {\n if (instruction.data.settings && instruction.data.settings.length > 0) {\n const prefix = instruction.data.settings;\n const newData = new Uint8Array(prefix.length + currentData.length);\n newData.set(prefix, 0);\n newData.set(currentData, prefix.length);\n currentData = newData;\n }\n }\n ;\n break;\n default:\n {\n // Unhandled\n }\n ;\n }\n }\n ;\n break;\n default:\n {\n // Unhandled\n }\n ;\n }\n }\n return currentData;\n }\n processTagValue(name, value) {\n if (!this.currentSegment?.metadataTags)\n return;\n const metadataTags = this.currentSegment.metadataTags;\n metadataTags.raw ??= {};\n metadataTags.raw[name] ??= value;\n if (typeof value === 'string') {\n switch (name.toLowerCase()) {\n case 'title':\n {\n metadataTags.title ??= value;\n }\n ;\n break;\n case 'description':\n {\n metadataTags.description ??= value;\n }\n ;\n break;\n case 'artist':\n {\n metadataTags.artist ??= value;\n }\n ;\n break;\n case 'album':\n {\n metadataTags.album ??= value;\n }\n ;\n break;\n case 'album_artist':\n {\n metadataTags.albumArtist ??= value;\n }\n ;\n break;\n case 'genre':\n {\n metadataTags.genre ??= value;\n }\n ;\n break;\n case 'comment':\n {\n metadataTags.comment ??= value;\n }\n ;\n break;\n case 'lyrics':\n {\n metadataTags.lyrics ??= value;\n }\n ;\n break;\n case 'date':\n {\n const date = new Date(value);\n if (!Number.isNaN(date.getTime())) {\n metadataTags.date ??= date;\n }\n }\n ;\n break;\n case 'track_number':\n case 'part_number':\n {\n const parts = value.split('/');\n const trackNum = Number.parseInt(parts[0], 10);\n const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);\n if (Number.isInteger(trackNum) && trackNum > 0) {\n metadataTags.trackNumber ??= trackNum;\n }\n if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {\n metadataTags.tracksTotal ??= tracksTotal;\n }\n }\n ;\n break;\n case 'disc_number':\n case 'disc':\n {\n const discParts = value.split('/');\n const discNum = Number.parseInt(discParts[0], 10);\n const discsTotal = discParts[1] && Number.parseInt(discParts[1], 10);\n if (Number.isInteger(discNum) && discNum > 0) {\n metadataTags.discNumber ??= discNum;\n }\n if (discsTotal && Number.isInteger(discsTotal) && discsTotal > 0) {\n metadataTags.discsTotal ??= discsTotal;\n }\n }\n ;\n break;\n }\n }\n }\n}\nclass MatroskaTrackBacking {\n constructor(internalTrack) {\n this.internalTrack = internalTrack;\n this.packetToClusterLocation = new WeakMap();\n }\n getId() {\n return this.internalTrack.id;\n }\n getCodec() {\n throw new Error('Not implemented on base class.');\n }\n getInternalCodecId() {\n return this.internalTrack.codecId;\n }\n async computeDuration() {\n const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });\n return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);\n }\n getName() {\n return this.internalTrack.name;\n }\n getLanguageCode() {\n return this.internalTrack.languageCode;\n }\n async getFirstTimestamp() {\n const firstPacket = await this.getFirstPacket({ metadataOnly: true });\n return firstPacket?.timestamp ?? 0;\n }\n getTimeResolution() {\n return this.internalTrack.segment.timestampFactor;\n }\n getDisposition() {\n return this.internalTrack.disposition;\n }\n async getFirstPacket(options) {\n return this.performClusterLookup(null, (cluster) => {\n const trackData = cluster.trackData.get(this.internalTrack.id);\n if (trackData) {\n return {\n blockIndex: 0,\n correctBlockFound: true,\n };\n }\n return {\n blockIndex: -1,\n correctBlockFound: false,\n };\n }, -Infinity, // Use -Infinity as a search timestamp to avoid using the cues\n Infinity, options);\n }\n intoTimescale(timestamp) {\n // Do a little rounding to catch cases where the result is very close to an integer. If it is, it's likely\n // that the number was originally an integer divided by the timescale. For stability, it's best\n // to return the integer in this case.\n return roundIfAlmostInteger(timestamp * this.internalTrack.segment.timestampFactor);\n }\n async getPacket(timestamp, options) {\n const timestampInTimescale = this.intoTimescale(timestamp);\n return this.performClusterLookup(null, (cluster) => {\n const trackData = cluster.trackData.get(this.internalTrack.id);\n if (!trackData) {\n return { blockIndex: -1, correctBlockFound: false };\n }\n const index = binarySearchLessOrEqual(trackData.presentationTimestamps, timestampInTimescale, x => x.timestamp);\n const blockIndex = index !== -1 ? trackData.presentationTimestamps[index].blockIndex : -1;\n const correctBlockFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;\n return { blockIndex, correctBlockFound };\n }, timestampInTimescale, timestampInTimescale, options);\n }\n async getNextPacket(packet, options) {\n const locationInCluster = this.packetToClusterLocation.get(packet);\n if (locationInCluster === undefined) {\n throw new Error('Packet was not created from this track.');\n }\n return this.performClusterLookup(locationInCluster.cluster, (cluster) => {\n if (cluster === locationInCluster.cluster) {\n const trackData = cluster.trackData.get(this.internalTrack.id);\n if (locationInCluster.blockIndex + 1 < trackData.blocks.length) {\n // We can simply take the next block in the cluster\n return {\n blockIndex: locationInCluster.blockIndex + 1,\n correctBlockFound: true,\n };\n }\n }\n else {\n const trackData = cluster.trackData.get(this.internalTrack.id);\n if (trackData) {\n return {\n blockIndex: 0,\n correctBlockFound: true,\n };\n }\n }\n return {\n blockIndex: -1,\n correctBlockFound: false,\n };\n }, -Infinity, // Use -Infinity as a search timestamp to avoid using the cues\n Infinity, options);\n }\n async getKeyPacket(timestamp, options) {\n const timestampInTimescale = this.intoTimescale(timestamp);\n return this.performClusterLookup(null, (cluster) => {\n const trackData = cluster.trackData.get(this.internalTrack.id);\n if (!trackData) {\n return { blockIndex: -1, correctBlockFound: false };\n }\n const index = findLastIndex(trackData.presentationTimestamps, (x) => {\n const block = trackData.blocks[x.blockIndex];\n return block.isKeyFrame && x.timestamp <= timestampInTimescale;\n });\n const blockIndex = index !== -1 ? trackData.presentationTimestamps[index].blockIndex : -1;\n const correctBlockFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;\n return { blockIndex, correctBlockFound };\n }, timestampInTimescale, timestampInTimescale, options);\n }\n async getNextKeyPacket(packet, options) {\n const locationInCluster = this.packetToClusterLocation.get(packet);\n if (locationInCluster === undefined) {\n throw new Error('Packet was not created from this track.');\n }\n return this.performClusterLookup(locationInCluster.cluster, (cluster) => {\n if (cluster === locationInCluster.cluster) {\n const trackData = cluster.trackData.get(this.internalTrack.id);\n const nextKeyFrameIndex = trackData.blocks.findIndex((x, i) => x.isKeyFrame && i > locationInCluster.blockIndex);\n if (nextKeyFrameIndex !== -1) {\n // We can simply take the next key frame in the cluster\n return {\n blockIndex: nextKeyFrameIndex,\n correctBlockFound: true,\n };\n }\n }\n else {\n const trackData = cluster.trackData.get(this.internalTrack.id);\n if (trackData && trackData.firstKeyFrameTimestamp !== null) {\n const keyFrameIndex = trackData.blocks.findIndex(x => x.isKeyFrame);\n assert(keyFrameIndex !== -1); // There must be one\n return {\n blockIndex: keyFrameIndex,\n correctBlockFound: true,\n };\n }\n }\n return {\n blockIndex: -1,\n correctBlockFound: false,\n };\n }, -Infinity, // Use -Infinity as a search timestamp to avoid using the cues\n Infinity, options);\n }\n async fetchPacketInCluster(cluster, blockIndex, options) {\n if (blockIndex === -1) {\n return null;\n }\n const trackData = cluster.trackData.get(this.internalTrack.id);\n const block = trackData.blocks[blockIndex];\n assert(block);\n // Perform lazy decoding if needed\n if (!block.decoded) {\n block.data = this.internalTrack.demuxer.decodeBlockData(this.internalTrack, block.data);\n block.decoded = true;\n }\n const data = options.metadataOnly ? PLACEHOLDER_DATA : block.data;\n const timestamp = block.timestamp / this.internalTrack.segment.timestampFactor;\n const duration = block.duration / this.internalTrack.segment.timestampFactor;\n const sideData = {};\n if (block.mainAdditional && this.internalTrack.info?.type === 'video' && this.internalTrack.info.alphaMode) {\n sideData.alpha = options.metadataOnly ? PLACEHOLDER_DATA : block.mainAdditional;\n sideData.alphaByteLength = block.mainAdditional.byteLength;\n }\n const packet = new EncodedPacket(data, block.isKeyFrame ? 'key' : 'delta', timestamp, duration, cluster.dataStartPos + blockIndex, block.data.byteLength, sideData);\n this.packetToClusterLocation.set(packet, { cluster, blockIndex });\n return packet;\n }\n /** Looks for a packet in the clusters while trying to load as few clusters as possible to retrieve it. */\n async performClusterLookup(\n // The cluster where we start looking\n startCluster, \n // This function returns the best-matching block in a given cluster\n getMatchInCluster, \n // The timestamp with which we can search the lookup table\n searchTimestamp, \n // The timestamp for which we know the correct block will not come after it\n latestTimestamp, options) {\n const { demuxer, segment } = this.internalTrack;\n let currentCluster = null;\n let bestCluster = null;\n let bestBlockIndex = -1;\n if (startCluster) {\n const { blockIndex, correctBlockFound } = getMatchInCluster(startCluster);\n if (correctBlockFound) {\n return this.fetchPacketInCluster(startCluster, blockIndex, options);\n }\n if (blockIndex !== -1) {\n bestCluster = startCluster;\n bestBlockIndex = blockIndex;\n }\n }\n // Search for a cue point; this way, we won't need to start searching from the start of the file\n // but can jump right into the correct cluster (or at least nearby).\n const cuePointIndex = binarySearchLessOrEqual(this.internalTrack.cuePoints, searchTimestamp, x => x.time);\n const cuePoint = cuePointIndex !== -1\n ? this.internalTrack.cuePoints[cuePointIndex]\n : null;\n // Also check the position cache\n const positionCacheIndex = binarySearchLessOrEqual(this.internalTrack.clusterPositionCache, searchTimestamp, x => x.startTimestamp);\n const positionCacheEntry = positionCacheIndex !== -1\n ? this.internalTrack.clusterPositionCache[positionCacheIndex]\n : null;\n const lookupEntryPosition = Math.max(cuePoint?.clusterPosition ?? 0, positionCacheEntry?.elementStartPos ?? 0) || null;\n let currentPos;\n if (!startCluster) {\n currentPos = lookupEntryPosition ?? segment.clusterSeekStartPos;\n }\n else {\n if (lookupEntryPosition === null || startCluster.elementStartPos >= lookupEntryPosition) {\n currentPos = startCluster.elementEndPos;\n currentCluster = startCluster;\n }\n else {\n // Use the lookup entry\n currentPos = lookupEntryPosition;\n }\n }\n while (segment.elementEndPos === null || currentPos <= segment.elementEndPos - MIN_HEADER_SIZE) {\n if (currentCluster) {\n const trackData = currentCluster.trackData.get(this.internalTrack.id);\n if (trackData && trackData.startTimestamp > latestTimestamp) {\n // We're already past the upper bound, no need to keep searching\n break;\n }\n }\n // Load the header\n let slice = demuxer.reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const elementStartPos = currentPos;\n const elementHeader = readElementHeader(slice);\n if (!elementHeader\n || (!LEVEL_1_EBML_IDS.includes(elementHeader.id) && elementHeader.id !== EBMLId.Void)) {\n // There's an element here that shouldn't be here. Might be garbage. In this case, let's\n // try and resync to the next valid element.\n const nextPos = await resync(demuxer.reader, elementStartPos, LEVEL_1_EBML_IDS, Math.min(segment.elementEndPos ?? Infinity, elementStartPos + MAX_RESYNC_LENGTH));\n if (nextPos) {\n currentPos = nextPos;\n continue;\n }\n else {\n break; // Resync failed\n }\n }\n const id = elementHeader.id;\n let size = elementHeader.size;\n const dataStartPos = slice.filePos;\n if (id === EBMLId.Cluster) {\n currentCluster = await demuxer.readCluster(elementStartPos, segment);\n // readCluster computes the proper size even if it's undefined in the header, so let's use that instead\n size = currentCluster.elementEndPos - dataStartPos;\n const { blockIndex, correctBlockFound } = getMatchInCluster(currentCluster);\n if (correctBlockFound) {\n return this.fetchPacketInCluster(currentCluster, blockIndex, options);\n }\n if (blockIndex !== -1) {\n bestCluster = currentCluster;\n bestBlockIndex = blockIndex;\n }\n }\n if (size === null) {\n // Undefined element size (can happen in livestreamed files). In this case, we need to do some\n // searching to determine the actual size of the element.\n assert(id !== EBMLId.Cluster); // Undefined cluster sizes are fixed further up\n // Search for the next element at level 0 or 1\n const nextElementPos = await searchForNextElementId(demuxer.reader, dataStartPos, LEVEL_0_AND_1_EBML_IDS, segment.elementEndPos);\n size = nextElementPos.pos - dataStartPos;\n }\n const endPos = dataStartPos + size;\n if (segment.elementEndPos === null) {\n // Check the next element. If it's a new segment, we know this segment ends here. The new\n // segment is just ignored, since we're likely in a livestreamed file and thus only care about\n // the first segment.\n let slice = demuxer.reader.requestSliceRange(endPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const elementId = readElementId(slice);\n if (elementId === EBMLId.Segment) {\n segment.elementEndPos = endPos; // We now know the segment's size\n break;\n }\n }\n currentPos = endPos;\n }\n // Catch faulty cue points\n if (cuePoint && (!bestCluster || bestCluster.elementStartPos < cuePoint.clusterPosition)) {\n // The cue point lied to us! We found a cue point but no cluster there that satisfied the match. In this\n // case, let's search again but using the cue point before that.\n const previousCuePoint = this.internalTrack.cuePoints[cuePointIndex - 1];\n assert(!previousCuePoint || previousCuePoint.time < cuePoint.time);\n const newSearchTimestamp = previousCuePoint?.time ?? -Infinity;\n return this.performClusterLookup(null, getMatchInCluster, newSearchTimestamp, latestTimestamp, options);\n }\n if (bestCluster) {\n // If we finished looping but didn't find a perfect match, still return the best match we found\n return this.fetchPacketInCluster(bestCluster, bestBlockIndex, options);\n }\n return null;\n }\n}\nclass MatroskaVideoTrackBacking extends MatroskaTrackBacking {\n constructor(internalTrack) {\n super(internalTrack);\n this.decoderConfigPromise = null;\n this.internalTrack = internalTrack;\n }\n getCodec() {\n return this.internalTrack.info.codec;\n }\n getCodedWidth() {\n return this.internalTrack.info.width;\n }\n getCodedHeight() {\n return this.internalTrack.info.height;\n }\n getRotation() {\n return this.internalTrack.info.rotation;\n }\n async getColorSpace() {\n return {\n primaries: this.internalTrack.info.colorSpace?.primaries,\n transfer: this.internalTrack.info.colorSpace?.transfer,\n matrix: this.internalTrack.info.colorSpace?.matrix,\n fullRange: this.internalTrack.info.colorSpace?.fullRange,\n };\n }\n async canBeTransparent() {\n return this.internalTrack.info.alphaMode;\n }\n async getDecoderConfig() {\n if (!this.internalTrack.info.codec) {\n return null;\n }\n return this.decoderConfigPromise ??= (async () => {\n let firstPacket = null;\n const needsPacketForAdditionalInfo = this.internalTrack.info.codec === 'vp9'\n || this.internalTrack.info.codec === 'av1'\n // Packets are in Annex B format:\n || (this.internalTrack.info.codec === 'avc' && !this.internalTrack.info.codecDescription)\n // Packets are in Annex B format:\n || (this.internalTrack.info.codec === 'hevc' && !this.internalTrack.info.codecDescription);\n if (needsPacketForAdditionalInfo) {\n firstPacket = await this.getFirstPacket({});\n }\n return {\n codec: extractVideoCodecString({\n width: this.internalTrack.info.width,\n height: this.internalTrack.info.height,\n codec: this.internalTrack.info.codec,\n codecDescription: this.internalTrack.info.codecDescription,\n colorSpace: this.internalTrack.info.colorSpace,\n avcType: 1, // We don't know better (or do we?) so just assume 'avc1'\n avcCodecInfo: this.internalTrack.info.codec === 'avc' && firstPacket\n ? extractAvcDecoderConfigurationRecord(firstPacket.data)\n : null,\n hevcCodecInfo: this.internalTrack.info.codec === 'hevc' && firstPacket\n ? extractHevcDecoderConfigurationRecord(firstPacket.data)\n : null,\n vp9CodecInfo: this.internalTrack.info.codec === 'vp9' && firstPacket\n ? extractVp9CodecInfoFromPacket(firstPacket.data)\n : null,\n av1CodecInfo: this.internalTrack.info.codec === 'av1' && firstPacket\n ? extractAv1CodecInfoFromPacket(firstPacket.data)\n : null,\n }),\n codedWidth: this.internalTrack.info.width,\n codedHeight: this.internalTrack.info.height,\n description: this.internalTrack.info.codecDescription ?? undefined,\n colorSpace: this.internalTrack.info.colorSpace ?? undefined,\n };\n })();\n }\n}\nclass MatroskaAudioTrackBacking extends MatroskaTrackBacking {\n constructor(internalTrack) {\n super(internalTrack);\n this.decoderConfig = null;\n this.internalTrack = internalTrack;\n }\n getCodec() {\n return this.internalTrack.info.codec;\n }\n getNumberOfChannels() {\n return this.internalTrack.info.numberOfChannels;\n }\n getSampleRate() {\n return this.internalTrack.info.sampleRate;\n }\n async getDecoderConfig() {\n if (!this.internalTrack.info.codec) {\n return null;\n }\n return this.decoderConfig ??= {\n codec: extractAudioCodecString({\n codec: this.internalTrack.info.codec,\n codecDescription: this.internalTrack.info.codecDescription,\n aacCodecInfo: this.internalTrack.info.aacCodecInfo,\n }),\n numberOfChannels: this.internalTrack.info.numberOfChannels,\n sampleRate: this.internalTrack.info.sampleRate,\n description: this.internalTrack.info.codecDescription ?? undefined,\n };\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nexport const FRAME_HEADER_SIZE = 4;\nexport const SAMPLING_RATES = [44100, 48000, 32000];\nexport const KILOBIT_RATES = [\n // lowSamplingFrequency === 0\n -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // layer = 0\n -1, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1, // layer 1\n -1, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1, // layer = 2\n -1, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1, // layer = 3\n // lowSamplingFrequency === 1\n -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // layer = 0\n -1, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1, // layer = 1\n -1, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1, // layer = 2\n -1, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1, // layer = 3\n];\n/** 'Xing' */\nexport const XING = 0x58696e67;\n/** 'Info' */\nexport const INFO = 0x496e666f;\nexport const computeMp3FrameSize = (lowSamplingFrequency, layer, bitrate, sampleRate, padding) => {\n if (layer === 0) {\n return 0; // Not expected that this is hit\n }\n else if (layer === 1) {\n return Math.floor(144 * bitrate / (sampleRate << lowSamplingFrequency)) + padding;\n }\n else if (layer === 2) {\n return Math.floor(144 * bitrate / sampleRate) + padding;\n }\n else { // layer === 3\n return (Math.floor(12 * bitrate / sampleRate) + padding) * 4;\n }\n};\nexport const getXingOffset = (mpegVersionId, channel) => {\n return mpegVersionId === 3\n ? (channel === 3 ? 21 : 36)\n : (channel === 3 ? 13 : 21);\n};\nexport const readFrameHeader = (word, remainingBytes) => {\n const firstByte = word >>> 24;\n const secondByte = (word >>> 16) & 0xff;\n const thirdByte = (word >>> 8) & 0xff;\n const fourthByte = word & 0xff;\n if (firstByte !== 0xff && secondByte !== 0xff && thirdByte !== 0xff && fourthByte !== 0xff) {\n return {\n header: null,\n bytesAdvanced: 4,\n };\n }\n if (firstByte !== 0xff) {\n return { header: null, bytesAdvanced: 1 };\n }\n if ((secondByte & 0xe0) !== 0xe0) {\n return { header: null, bytesAdvanced: 1 };\n }\n let lowSamplingFrequency = 0;\n let mpeg25 = 0;\n if (secondByte & (1 << 4)) {\n lowSamplingFrequency = (secondByte & (1 << 3)) ? 0 : 1;\n }\n else {\n lowSamplingFrequency = 1;\n mpeg25 = 1;\n }\n const mpegVersionId = (secondByte >> 3) & 0x3;\n const layer = (secondByte >> 1) & 0x3;\n const bitrateIndex = (thirdByte >> 4) & 0xf;\n const frequencyIndex = ((thirdByte >> 2) & 0x3) % 3;\n const padding = (thirdByte >> 1) & 0x1;\n const channel = (fourthByte >> 6) & 0x3;\n const modeExtension = (fourthByte >> 4) & 0x3;\n const copyright = (fourthByte >> 3) & 0x1;\n const original = (fourthByte >> 2) & 0x1;\n const emphasis = fourthByte & 0x3;\n const kilobitRate = KILOBIT_RATES[lowSamplingFrequency * 16 * 4 + layer * 16 + bitrateIndex];\n if (kilobitRate === -1) {\n return { header: null, bytesAdvanced: 1 };\n }\n const bitrate = kilobitRate * 1000;\n const sampleRate = SAMPLING_RATES[frequencyIndex] >> (lowSamplingFrequency + mpeg25);\n const frameLength = computeMp3FrameSize(lowSamplingFrequency, layer, bitrate, sampleRate, padding);\n if (remainingBytes !== null && remainingBytes < frameLength) {\n // The frame doesn't fit into the rest of the file\n return { header: null, bytesAdvanced: 1 };\n }\n let audioSamplesInFrame;\n if (mpegVersionId === 3) {\n audioSamplesInFrame = layer === 3 ? 384 : 1152;\n }\n else {\n if (layer === 3) {\n audioSamplesInFrame = 384;\n }\n else if (layer === 2) {\n audioSamplesInFrame = 1152;\n }\n else {\n audioSamplesInFrame = 576;\n }\n }\n return {\n header: {\n totalSize: frameLength,\n mpegVersionId,\n layer,\n bitrate,\n frequencyIndex,\n sampleRate,\n channel,\n modeExtension,\n copyright,\n original,\n emphasis,\n audioSamplesInFrame,\n },\n bytesAdvanced: 1,\n };\n};\nexport const encodeSynchsafe = (unsynchsafed) => {\n let mask = 0x7f;\n let synchsafed = 0;\n let unsynchsafedRest = unsynchsafed;\n while ((mask ^ 0x7fffffff) !== 0) {\n synchsafed = unsynchsafedRest & ~mask;\n synchsafed <<= 1;\n synchsafed |= unsynchsafedRest & mask;\n mask = ((mask + 1) << 8) - 1;\n unsynchsafedRest = synchsafed;\n }\n return synchsafed;\n};\nexport const decodeSynchsafe = (synchsafed) => {\n let mask = 0x7f000000;\n let unsynchsafed = 0;\n while (mask !== 0) {\n unsynchsafed >>= 1;\n unsynchsafed |= synchsafed & mask;\n mask >>= 8;\n }\n return unsynchsafed;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { decodeSynchsafe, encodeSynchsafe } from '../shared/mp3-misc.js';\nimport { coalesceIndex, textDecoder, textEncoder, isIso88591Compatible, assertNever, keyValueIterator, toDataView, } from './misc.js';\nimport { readAscii, readBytes, readU32Be, readU8 } from './reader.js';\nexport var Id3V2HeaderFlags;\n(function (Id3V2HeaderFlags) {\n Id3V2HeaderFlags[Id3V2HeaderFlags[\"Unsynchronisation\"] = 128] = \"Unsynchronisation\";\n Id3V2HeaderFlags[Id3V2HeaderFlags[\"ExtendedHeader\"] = 64] = \"ExtendedHeader\";\n Id3V2HeaderFlags[Id3V2HeaderFlags[\"ExperimentalIndicator\"] = 32] = \"ExperimentalIndicator\";\n Id3V2HeaderFlags[Id3V2HeaderFlags[\"Footer\"] = 16] = \"Footer\";\n})(Id3V2HeaderFlags || (Id3V2HeaderFlags = {}));\nexport var Id3V2TextEncoding;\n(function (Id3V2TextEncoding) {\n Id3V2TextEncoding[Id3V2TextEncoding[\"ISO_8859_1\"] = 0] = \"ISO_8859_1\";\n Id3V2TextEncoding[Id3V2TextEncoding[\"UTF_16_WITH_BOM\"] = 1] = \"UTF_16_WITH_BOM\";\n Id3V2TextEncoding[Id3V2TextEncoding[\"UTF_16_BE_NO_BOM\"] = 2] = \"UTF_16_BE_NO_BOM\";\n Id3V2TextEncoding[Id3V2TextEncoding[\"UTF_8\"] = 3] = \"UTF_8\";\n})(Id3V2TextEncoding || (Id3V2TextEncoding = {}));\nexport const ID3_V1_TAG_SIZE = 128;\nexport const ID3_V2_HEADER_SIZE = 10;\nexport const ID3_V1_GENRES = [\n 'Blues', 'Classic rock', 'Country', 'Dance', 'Disco', 'Funk', 'Grunge', 'Hip-hop', 'Jazz',\n 'Metal', 'New age', 'Oldies', 'Other', 'Pop', 'Rhythm and blues', 'Rap', 'Reggae', 'Rock',\n 'Techno', 'Industrial', 'Alternative', 'Ska', 'Death metal', 'Pranks', 'Soundtrack',\n 'Euro-techno', 'Ambient', 'Trip-hop', 'Vocal', 'Jazz & funk', 'Fusion', 'Trance', 'Classical',\n 'Instrumental', 'Acid', 'House', 'Game', 'Sound clip', 'Gospel', 'Noise', 'Alternative rock',\n 'Bass', 'Soul', 'Punk', 'Space', 'Meditative', 'Instrumental pop', 'Instrumental rock',\n 'Ethnic', 'Gothic', 'Darkwave', 'Techno-industrial', 'Electronic', 'Pop-folk', 'Eurodance',\n 'Dream', 'Southern rock', 'Comedy', 'Cult', 'Gangsta', 'Top 40', 'Christian rap', 'Pop/funk',\n 'Jungle music', 'Native US', 'Cabaret', 'New wave', 'Psychedelic', 'Rave', 'Showtunes',\n 'Trailer', 'Lo-fi', 'Tribal', 'Acid punk', 'Acid jazz', 'Polka', 'Retro', 'Musical',\n 'Rock \\'n\\' roll', 'Hard rock', 'Folk', 'Folk rock', 'National folk', 'Swing', 'Fast fusion',\n 'Bebop', 'Latin', 'Revival', 'Celtic', 'Bluegrass', 'Avantgarde', 'Gothic rock',\n 'Progressive rock', 'Psychedelic rock', 'Symphonic rock', 'Slow rock', 'Big band', 'Chorus',\n 'Easy listening', 'Acoustic', 'Humour', 'Speech', 'Chanson', 'Opera', 'Chamber music',\n 'Sonata', 'Symphony', 'Booty bass', 'Primus', 'Porn groove', 'Satire', 'Slow jam', 'Club',\n 'Tango', 'Samba', 'Folklore', 'Ballad', 'Power ballad', 'Rhythmic Soul', 'Freestyle', 'Duet',\n 'Punk rock', 'Drum solo', 'A cappella', 'Euro-house', 'Dance hall', 'Goa music', 'Drum & bass',\n 'Club-house', 'Hardcore techno', 'Terror', 'Indie', 'Britpop', 'Negerpunk', 'Polsk punk',\n 'Beat', 'Christian gangsta rap', 'Heavy metal', 'Black metal', 'Crossover',\n 'Contemporary Christian', 'Christian rock', 'Merengue', 'Salsa', 'Thrash metal', 'Anime',\n 'Jpop', 'Synthpop', 'Christmas', 'Art rock', 'Baroque', 'Bhangra', 'Big beat', 'Breakbeat',\n 'Chillout', 'Downtempo', 'Dub', 'EBM', 'Eclectic', 'Electro', 'Electroclash', 'Emo',\n 'Experimental', 'Garage', 'Global', 'IDM', 'Illbient', 'Industro-Goth', 'Jam Band',\n 'Krautrock', 'Leftfield', 'Lounge', 'Math rock', 'New romantic', 'Nu-breakz', 'Post-punk',\n 'Post-rock', 'Psytrance', 'Shoegaze', 'Space rock', 'Trop rock', 'World music', 'Neoclassical',\n 'Audiobook', 'Audio theatre', 'Neue Deutsche Welle', 'Podcast', 'Indie rock', 'G-Funk',\n 'Dubstep', 'Garage rock', 'Psybient',\n];\nexport const parseId3V1Tag = (slice, tags) => {\n const startPos = slice.filePos;\n tags.raw ??= {};\n tags.raw['TAG'] ??= readBytes(slice, ID3_V1_TAG_SIZE - 3); // Dump the whole tag into the raw metadata\n slice.filePos = startPos;\n const title = readId3V1String(slice, 30);\n if (title)\n tags.title ??= title;\n const artist = readId3V1String(slice, 30);\n if (artist)\n tags.artist ??= artist;\n const album = readId3V1String(slice, 30);\n if (album)\n tags.album ??= album;\n const yearText = readId3V1String(slice, 4);\n const year = Number.parseInt(yearText, 10);\n if (Number.isInteger(year) && year > 0) {\n tags.date ??= new Date(year, 0, 1);\n }\n const commentBytes = readBytes(slice, 30);\n let comment;\n // Check for the ID3v1.1 track number format:\n // The 29th byte (index 28) is a null terminator, and the 30th byte is the track number.\n if (commentBytes[28] === 0 && commentBytes[29] !== 0) {\n const trackNum = commentBytes[29];\n if (trackNum > 0) {\n tags.trackNumber ??= trackNum;\n }\n slice.skip(-30);\n comment = readId3V1String(slice, 28);\n slice.skip(2);\n }\n else {\n slice.skip(-30);\n comment = readId3V1String(slice, 30);\n }\n if (comment)\n tags.comment ??= comment;\n const genreIndex = readU8(slice);\n if (genreIndex < ID3_V1_GENRES.length) {\n tags.genre ??= ID3_V1_GENRES[genreIndex];\n }\n};\nexport const readId3V1String = (slice, length) => {\n const bytes = readBytes(slice, length);\n const endIndex = coalesceIndex(bytes.indexOf(0), bytes.length);\n const relevantBytes = bytes.subarray(0, endIndex);\n // Decode as ISO-8859-1\n let str = '';\n for (let i = 0; i < relevantBytes.length; i++) {\n str += String.fromCharCode(relevantBytes[i]);\n }\n return str.trimEnd(); // String also may be padded with spaces\n};\nexport const readId3V2Header = (slice) => {\n const startPos = slice.filePos;\n const tag = readAscii(slice, 3);\n const majorVersion = readU8(slice);\n const revision = readU8(slice);\n const flags = readU8(slice);\n const sizeRaw = readU32Be(slice);\n if (tag !== 'ID3' || majorVersion === 0xff || revision === 0xff || (sizeRaw & 0x80808080) !== 0) {\n slice.filePos = startPos;\n return null;\n }\n const size = decodeSynchsafe(sizeRaw);\n return { majorVersion, revision, flags, size };\n};\nexport const parseId3V2Tag = (slice, header, tags) => {\n // https://id3.org/id3v2.3.0\n if (![2, 3, 4].includes(header.majorVersion)) {\n console.warn(`Unsupported ID3v2 major version: ${header.majorVersion}`);\n return;\n }\n const bytes = readBytes(slice, header.size);\n const reader = new Id3V2Reader(header, bytes);\n if (header.flags & Id3V2HeaderFlags.Footer) {\n reader.removeFooter();\n }\n if ((header.flags & Id3V2HeaderFlags.Unsynchronisation) && header.majorVersion === 3) {\n reader.ununsynchronizeAll();\n }\n if (header.flags & Id3V2HeaderFlags.ExtendedHeader) {\n const extendedHeaderSize = reader.readU32();\n if (header.majorVersion === 3) {\n reader.pos += extendedHeaderSize; // The extended header size excludes itself\n }\n else {\n reader.pos += extendedHeaderSize - 4; // The extended header size includes itself\n }\n }\n while (reader.pos <= reader.bytes.length - reader.frameHeaderSize()) {\n const frame = reader.readId3V2Frame();\n if (!frame) {\n break;\n }\n const frameStartPos = reader.pos;\n const frameEndPos = reader.pos + frame.size;\n let frameEncrypted = false;\n let frameCompressed = false;\n let frameUnsynchronized = false;\n if (header.majorVersion === 3) {\n frameEncrypted = !!(frame.flags & (1 << 6));\n frameCompressed = !!(frame.flags & (1 << 7));\n }\n else if (header.majorVersion === 4) {\n frameEncrypted = !!(frame.flags & (1 << 2));\n frameCompressed = !!(frame.flags & (1 << 3));\n frameUnsynchronized = !!(frame.flags & (1 << 1))\n || !!(header.flags & Id3V2HeaderFlags.Unsynchronisation);\n }\n if (frameEncrypted) {\n console.warn(`Skipping encrypted ID3v2 frame ${frame.id}`);\n reader.pos = frameEndPos;\n continue;\n }\n if (frameCompressed) {\n console.warn(`Skipping compressed ID3v2 frame ${frame.id}`); // Maybe someday? Idk\n reader.pos = frameEndPos;\n continue;\n }\n if (frameUnsynchronized) {\n reader.ununsynchronizeRegion(reader.pos, frameEndPos);\n }\n tags.raw ??= {};\n if (frame.id[0] === 'T') {\n // It's a text frame, let's decode as text\n tags.raw[frame.id] ??= reader.readId3V2EncodingAndText(frameEndPos);\n }\n else {\n // For the others, let's just get the bytes\n tags.raw[frame.id] ??= reader.readBytes(frame.size);\n }\n reader.pos = frameStartPos;\n switch (frame.id) {\n case 'TIT2':\n case 'TT2':\n {\n tags.title ??= reader.readId3V2EncodingAndText(frameEndPos);\n }\n ;\n break;\n case 'TIT3':\n case 'TT3':\n {\n tags.description ??= reader.readId3V2EncodingAndText(frameEndPos);\n }\n ;\n break;\n case 'TPE1':\n case 'TP1':\n {\n tags.artist ??= reader.readId3V2EncodingAndText(frameEndPos);\n }\n ;\n break;\n case 'TALB':\n case 'TAL':\n {\n tags.album ??= reader.readId3V2EncodingAndText(frameEndPos);\n }\n ;\n break;\n case 'TPE2':\n case 'TP2':\n {\n tags.albumArtist ??= reader.readId3V2EncodingAndText(frameEndPos);\n }\n ;\n break;\n case 'TRCK':\n case 'TRK':\n {\n const trackText = reader.readId3V2EncodingAndText(frameEndPos);\n const parts = trackText.split('/');\n const trackNum = Number.parseInt(parts[0], 10);\n const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);\n if (Number.isInteger(trackNum) && trackNum > 0) {\n tags.trackNumber ??= trackNum;\n }\n if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {\n tags.tracksTotal ??= tracksTotal;\n }\n }\n ;\n break;\n case 'TPOS':\n case 'TPA':\n {\n const discText = reader.readId3V2EncodingAndText(frameEndPos);\n const parts = discText.split('/');\n const discNum = Number.parseInt(parts[0], 10);\n const discsTotal = parts[1] && Number.parseInt(parts[1], 10);\n if (Number.isInteger(discNum) && discNum > 0) {\n tags.discNumber ??= discNum;\n }\n if (discsTotal && Number.isInteger(discsTotal) && discsTotal > 0) {\n tags.discsTotal ??= discsTotal;\n }\n }\n ;\n break;\n case 'TCON':\n case 'TCO':\n {\n const genreText = reader.readId3V2EncodingAndText(frameEndPos);\n let match = /^\\((\\d+)\\)/.exec(genreText);\n if (match) {\n const genreNumber = Number.parseInt(match[1]);\n if (ID3_V1_GENRES[genreNumber] !== undefined) {\n tags.genre ??= ID3_V1_GENRES[genreNumber];\n break;\n }\n }\n match = /^\\d+$/.exec(genreText);\n if (match) {\n const genreNumber = Number.parseInt(match[0]);\n if (ID3_V1_GENRES[genreNumber] !== undefined) {\n tags.genre ??= ID3_V1_GENRES[genreNumber];\n break;\n }\n }\n tags.genre ??= genreText;\n }\n ;\n break;\n case 'TDRC':\n case 'TDAT':\n {\n const dateText = reader.readId3V2EncodingAndText(frameEndPos);\n const date = new Date(dateText);\n if (!Number.isNaN(date.getTime())) {\n tags.date ??= date;\n }\n }\n ;\n break;\n case 'TYER':\n case 'TYE':\n {\n const yearText = reader.readId3V2EncodingAndText(frameEndPos);\n const year = Number.parseInt(yearText, 10);\n if (Number.isInteger(year)) {\n tags.date ??= new Date(year, 0, 1);\n }\n }\n ;\n break;\n case 'USLT':\n case 'ULT':\n {\n const encoding = reader.readU8();\n reader.pos += 3; // Skip language\n reader.readId3V2Text(encoding, frameEndPos); // Short content description\n tags.lyrics ??= reader.readId3V2Text(encoding, frameEndPos);\n }\n ;\n break;\n case 'COMM':\n case 'COM':\n {\n const encoding = reader.readU8();\n reader.pos += 3; // Skip language\n reader.readId3V2Text(encoding, frameEndPos); // Short content description\n tags.comment ??= reader.readId3V2Text(encoding, frameEndPos);\n }\n ;\n break;\n case 'APIC':\n case 'PIC':\n {\n const encoding = reader.readId3V2TextEncoding();\n let mimeType;\n if (header.majorVersion === 2) {\n const imageFormat = reader.readAscii(3);\n mimeType = imageFormat === 'PNG'\n ? 'image/png'\n : imageFormat === 'JPG'\n ? 'image/jpeg'\n : 'image/*';\n }\n else {\n mimeType = reader.readId3V2Text(encoding, frameEndPos);\n }\n const pictureType = reader.readU8();\n const description = reader.readId3V2Text(encoding, frameEndPos).trimEnd(); // Trim ending spaces\n const imageDataSize = frameEndPos - reader.pos;\n if (imageDataSize >= 0) {\n const imageData = reader.readBytes(imageDataSize);\n if (!tags.images)\n tags.images = [];\n tags.images.push({\n data: imageData,\n mimeType,\n kind: pictureType === 3\n ? 'coverFront'\n : pictureType === 4\n ? 'coverBack'\n : 'unknown',\n description,\n });\n }\n }\n ;\n break;\n default:\n {\n reader.pos += frame.size;\n }\n ;\n break;\n }\n reader.pos = frameEndPos;\n }\n};\n// https://id3.org/id3v2.3.0\nexport class Id3V2Reader {\n constructor(header, bytes) {\n this.header = header;\n this.bytes = bytes;\n this.pos = 0;\n this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n }\n frameHeaderSize() {\n return this.header.majorVersion === 2 ? 6 : 10;\n }\n ununsynchronizeAll() {\n const newBytes = [];\n for (let i = 0; i < this.bytes.length; i++) {\n const value1 = this.bytes[i];\n newBytes.push(value1);\n if (value1 === 0xff && i !== this.bytes.length - 1) {\n const value2 = this.bytes[i];\n if (value2 === 0x00) {\n i++;\n }\n }\n }\n this.bytes = new Uint8Array(newBytes);\n this.view = new DataView(this.bytes.buffer);\n }\n ununsynchronizeRegion(start, end) {\n const newBytes = [];\n for (let i = start; i < end; i++) {\n const value1 = this.bytes[i];\n newBytes.push(value1);\n if (value1 === 0xff && i !== end - 1) {\n const value2 = this.bytes[i + 1];\n if (value2 === 0x00) {\n i++;\n }\n }\n }\n const before = this.bytes.subarray(0, start);\n const after = this.bytes.subarray(end);\n this.bytes = new Uint8Array(before.length + newBytes.length + after.length);\n this.bytes.set(before, 0);\n this.bytes.set(newBytes, before.length);\n this.bytes.set(after, before.length + newBytes.length);\n this.view = new DataView(this.bytes.buffer);\n }\n removeFooter() {\n this.bytes = this.bytes.subarray(0, this.bytes.length - ID3_V2_HEADER_SIZE);\n this.view = new DataView(this.bytes.buffer);\n }\n readBytes(length) {\n const slice = this.bytes.subarray(this.pos, this.pos + length);\n this.pos += length;\n return slice;\n }\n readU8() {\n const value = this.view.getUint8(this.pos);\n this.pos += 1;\n return value;\n }\n readU16() {\n const value = this.view.getUint16(this.pos, false);\n this.pos += 2;\n return value;\n }\n readU24() {\n const high = this.view.getUint16(this.pos, false);\n const low = this.view.getUint8(this.pos + 1);\n this.pos += 3;\n return high * 0x100 + low;\n }\n readU32() {\n const value = this.view.getUint32(this.pos, false);\n this.pos += 4;\n return value;\n }\n readAscii(length) {\n let str = '';\n for (let i = 0; i < length; i++) {\n str += String.fromCharCode(this.view.getUint8(this.pos + i));\n }\n this.pos += length;\n return str;\n }\n readId3V2Frame() {\n if (this.header.majorVersion === 2) {\n const id = this.readAscii(3);\n if (id === '\\x00\\x00\\x00') {\n return null;\n }\n const size = this.readU24();\n return { id, size, flags: 0 };\n }\n else {\n const id = this.readAscii(4);\n if (id === '\\x00\\x00\\x00\\x00') {\n // We've landed in the padding section\n return null;\n }\n const sizeRaw = this.readU32();\n let size = this.header.majorVersion === 4\n ? decodeSynchsafe(sizeRaw)\n : sizeRaw;\n const flags = this.readU16();\n const headerEndPos = this.pos;\n // Some files may have incorrectly synchsafed/unsynchsafed sizes. To validate which interpretation is valid,\n // we validate a size by skipping ahead and seeing if we land at a valid frame header (or at the end of the\n // tag.\n const isSizeValid = (size) => {\n const nextPos = this.pos + size;\n if (nextPos > this.bytes.length) {\n return false;\n }\n if (nextPos <= this.bytes.length - this.frameHeaderSize()) {\n this.pos += size;\n const nextId = this.readAscii(4);\n if (nextId !== '\\x00\\x00\\x00\\x00' && !/[0-9A-Z]{4}/.test(nextId)) {\n return false;\n }\n }\n return true;\n };\n if (!isSizeValid(size)) {\n // Flip the synchsafing, and try if this one makes more sense\n const otherSize = this.header.majorVersion === 4\n ? sizeRaw\n : decodeSynchsafe(sizeRaw);\n if (isSizeValid(otherSize)) {\n size = otherSize;\n }\n }\n this.pos = headerEndPos;\n return { id, size, flags };\n }\n }\n readId3V2TextEncoding() {\n const number = this.readU8();\n if (number > 3) {\n throw new Error(`Unsupported text encoding: ${number}`);\n }\n return number;\n }\n readId3V2Text(encoding, until) {\n const startPos = this.pos;\n const data = this.readBytes(until - this.pos);\n switch (encoding) {\n case Id3V2TextEncoding.ISO_8859_1: {\n let str = '';\n for (let i = 0; i < data.length; i++) {\n const value = data[i];\n if (value === 0) {\n this.pos = startPos + i + 1;\n break;\n }\n str += String.fromCharCode(value);\n }\n return str;\n }\n case Id3V2TextEncoding.UTF_16_WITH_BOM: {\n if (data[0] === 0xff && data[1] === 0xfe) {\n const decoder = new TextDecoder('utf-16le');\n const endIndex = coalesceIndex(data.findIndex((x, i) => x === 0 && data[i + 1] === 0 && i % 2 === 0), data.length);\n this.pos = startPos + Math.min(endIndex + 2, data.length);\n return decoder.decode(data.subarray(2, endIndex));\n }\n else if (data[0] === 0xfe && data[1] === 0xff) {\n const decoder = new TextDecoder('utf-16be');\n const endIndex = coalesceIndex(data.findIndex((x, i) => x === 0 && data[i + 1] === 0 && i % 2 === 0), data.length);\n this.pos = startPos + Math.min(endIndex + 2, data.length);\n return decoder.decode(data.subarray(2, endIndex));\n }\n else {\n // Treat it like UTF-8, some files do this\n const endIndex = coalesceIndex(data.findIndex(x => x === 0), data.length);\n this.pos = startPos + Math.min(endIndex + 1, data.length);\n return textDecoder.decode(data.subarray(0, endIndex));\n }\n }\n case Id3V2TextEncoding.UTF_16_BE_NO_BOM: {\n const decoder = new TextDecoder('utf-16be');\n const endIndex = coalesceIndex(data.findIndex((x, i) => x === 0 && data[i + 1] === 0 && i % 2 === 0), data.length);\n this.pos = startPos + Math.min(endIndex + 2, data.length);\n return decoder.decode(data.subarray(0, endIndex));\n }\n case Id3V2TextEncoding.UTF_8: {\n const endIndex = coalesceIndex(data.findIndex(x => x === 0), data.length);\n this.pos = startPos + Math.min(endIndex + 1, data.length);\n return textDecoder.decode(data.subarray(0, endIndex));\n }\n }\n }\n readId3V2EncodingAndText(until) {\n if (this.pos >= until) {\n return '';\n }\n const encoding = this.readId3V2TextEncoding();\n return this.readId3V2Text(encoding, until);\n }\n}\nexport class Id3V2Writer {\n constructor(writer) {\n this.helper = new Uint8Array(8);\n this.helperView = toDataView(this.helper);\n this.writer = writer;\n }\n writeId3V2Tag(metadata) {\n const tagStartPos = this.writer.getPos();\n // Write ID3v2.4 header\n this.writeAscii('ID3');\n this.writeU8(0x04); // Version 2.4\n this.writeU8(0x00); // Revision 0\n this.writeU8(0x00); // Flags\n this.writeSynchsafeU32(0); // Size placeholder\n const framesStartPos = this.writer.getPos();\n const writtenTags = new Set();\n // Write all metadata frames\n for (const { key, value } of keyValueIterator(metadata)) {\n switch (key) {\n case 'title':\n {\n this.writeId3V2TextFrame('TIT2', value);\n writtenTags.add('TIT2');\n }\n ;\n break;\n case 'description':\n {\n this.writeId3V2TextFrame('TIT3', value);\n writtenTags.add('TIT3');\n }\n ;\n break;\n case 'artist':\n {\n this.writeId3V2TextFrame('TPE1', value);\n writtenTags.add('TPE1');\n }\n ;\n break;\n case 'album':\n {\n this.writeId3V2TextFrame('TALB', value);\n writtenTags.add('TALB');\n }\n ;\n break;\n case 'albumArtist':\n {\n this.writeId3V2TextFrame('TPE2', value);\n writtenTags.add('TPE2');\n }\n ;\n break;\n case 'trackNumber':\n {\n const string = metadata.tracksTotal !== undefined\n ? `${value}/${metadata.tracksTotal}`\n : value.toString();\n this.writeId3V2TextFrame('TRCK', string);\n writtenTags.add('TRCK');\n }\n ;\n break;\n case 'discNumber':\n {\n const string = metadata.discsTotal !== undefined\n ? `${value}/${metadata.discsTotal}`\n : value.toString();\n this.writeId3V2TextFrame('TPOS', string);\n writtenTags.add('TPOS');\n }\n ;\n break;\n case 'genre':\n {\n this.writeId3V2TextFrame('TCON', value);\n writtenTags.add('TCON');\n }\n ;\n break;\n case 'date':\n {\n this.writeId3V2TextFrame('TDRC', value.toISOString().slice(0, 10));\n writtenTags.add('TDRC');\n }\n ;\n break;\n case 'lyrics':\n {\n this.writeId3V2LyricsFrame(value);\n writtenTags.add('USLT');\n }\n ;\n break;\n case 'comment':\n {\n this.writeId3V2CommentFrame(value);\n writtenTags.add('COMM');\n }\n ;\n break;\n case 'images':\n {\n const pictureTypeMap = { coverFront: 0x03, coverBack: 0x04, unknown: 0x00 };\n for (const image of value) {\n const pictureType = pictureTypeMap[image.kind] ?? 0x00;\n const description = image.description ?? '';\n this.writeId3V2ApicFrame(image.mimeType, pictureType, description, image.data);\n }\n }\n ;\n break;\n case 'tracksTotal':\n case 'discsTotal':\n {\n // Handled with trackNumber and discNumber respectively\n }\n ;\n break;\n case 'raw':\n {\n // Handled later\n }\n ;\n break;\n default: {\n assertNever(key);\n }\n }\n }\n if (metadata.raw) {\n for (const key in metadata.raw) {\n const value = metadata.raw[key];\n if (value == null || key.length !== 4 || writtenTags.has(key)) {\n continue;\n }\n let bytes;\n if (typeof value === 'string') {\n const encoded = textEncoder.encode(value);\n bytes = new Uint8Array(encoded.byteLength + 2);\n bytes[0] = Id3V2TextEncoding.UTF_8;\n bytes.set(encoded, 1);\n // Last byte is the null terminator\n }\n else if (value instanceof Uint8Array) {\n bytes = value;\n }\n else {\n continue;\n }\n this.writeAscii(key);\n this.writeSynchsafeU32(bytes.byteLength);\n this.writeU16(0x0000);\n this.writer.write(bytes);\n }\n }\n const framesEndPos = this.writer.getPos();\n const framesSize = framesEndPos - framesStartPos;\n // Update the size field in the header (synchsafe)\n this.writer.seek(tagStartPos + 6); // Skip 'ID3' + version + revision + flags\n this.writeSynchsafeU32(framesSize);\n this.writer.seek(framesEndPos);\n return framesSize + 10; // +10 for the header size\n }\n writeU8(value) {\n this.helper[0] = value;\n this.writer.write(this.helper.subarray(0, 1));\n }\n writeU16(value) {\n this.helperView.setUint16(0, value, false);\n this.writer.write(this.helper.subarray(0, 2));\n }\n writeU32(value) {\n this.helperView.setUint32(0, value, false);\n this.writer.write(this.helper.subarray(0, 4));\n }\n writeAscii(text) {\n for (let i = 0; i < text.length; i++) {\n this.helper[i] = text.charCodeAt(i);\n }\n this.writer.write(this.helper.subarray(0, text.length));\n }\n writeSynchsafeU32(value) {\n this.writeU32(encodeSynchsafe(value));\n }\n writeIsoString(text) {\n const bytes = new Uint8Array(text.length + 1);\n for (let i = 0; i < text.length; i++) {\n bytes[i] = text.charCodeAt(i);\n }\n bytes[text.length] = 0x00;\n this.writer.write(bytes);\n }\n writeUtf8String(text) {\n const utf8Data = textEncoder.encode(text);\n this.writer.write(utf8Data);\n this.writeU8(0x00);\n }\n writeId3V2TextFrame(frameId, text) {\n const useIso88591 = isIso88591Compatible(text);\n const textDataLength = useIso88591 ? text.length : textEncoder.encode(text).byteLength;\n const frameSize = 1 + textDataLength + 1;\n this.writeAscii(frameId);\n this.writeSynchsafeU32(frameSize);\n this.writeU16(0x0000);\n this.writeU8(useIso88591 ? Id3V2TextEncoding.ISO_8859_1 : Id3V2TextEncoding.UTF_8);\n if (useIso88591) {\n this.writeIsoString(text);\n }\n else {\n this.writeUtf8String(text);\n }\n }\n writeId3V2LyricsFrame(lyrics) {\n const useIso88591 = isIso88591Compatible(lyrics);\n const shortDescription = '';\n const frameSize = 1 + 3 + shortDescription.length + 1 + lyrics.length + 1;\n this.writeAscii('USLT');\n this.writeSynchsafeU32(frameSize);\n this.writeU16(0x0000);\n this.writeU8(useIso88591 ? Id3V2TextEncoding.ISO_8859_1 : Id3V2TextEncoding.UTF_8);\n this.writeAscii('und');\n if (useIso88591) {\n this.writeIsoString(shortDescription);\n this.writeIsoString(lyrics);\n }\n else {\n this.writeUtf8String(shortDescription);\n this.writeUtf8String(lyrics);\n }\n }\n writeId3V2CommentFrame(comment) {\n const useIso88591 = isIso88591Compatible(comment);\n const textDataLength = useIso88591 ? comment.length : textEncoder.encode(comment).byteLength;\n const shortDescription = '';\n const frameSize = 1 + 3 + shortDescription.length + 1 + textDataLength + 1;\n this.writeAscii('COMM');\n this.writeSynchsafeU32(frameSize);\n this.writeU16(0x0000);\n this.writeU8(useIso88591 ? Id3V2TextEncoding.ISO_8859_1 : Id3V2TextEncoding.UTF_8);\n this.writeU8(0x75); // 'u'\n this.writeU8(0x6E); // 'n'\n this.writeU8(0x64); // 'd'\n if (useIso88591) {\n this.writeIsoString(shortDescription);\n this.writeIsoString(comment);\n }\n else {\n this.writeUtf8String(shortDescription);\n this.writeUtf8String(comment);\n }\n }\n writeId3V2ApicFrame(mimeType, pictureType, description, imageData) {\n const useIso88591 = isIso88591Compatible(mimeType) && isIso88591Compatible(description);\n const descriptionDataLength = useIso88591\n ? description.length\n : textEncoder.encode(description).byteLength;\n const frameSize = 1 + mimeType.length + 1 + 1 + descriptionDataLength + 1 + imageData.byteLength;\n this.writeAscii('APIC');\n this.writeSynchsafeU32(frameSize);\n this.writeU16(0x0000);\n this.writeU8(useIso88591 ? Id3V2TextEncoding.ISO_8859_1 : Id3V2TextEncoding.UTF_8);\n if (useIso88591) {\n this.writeIsoString(mimeType);\n }\n else {\n this.writeUtf8String(mimeType);\n }\n this.writeU8(pictureType);\n if (useIso88591) {\n this.writeIsoString(description);\n }\n else {\n this.writeUtf8String(description);\n }\n this.writer.write(imageData);\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { FRAME_HEADER_SIZE, readFrameHeader } from '../../shared/mp3-misc.js';\nimport { readU32Be } from '../reader.js';\nexport const readNextFrameHeader = async (reader, startPos, until) => {\n let currentPos = startPos;\n while (until === null || currentPos < until) {\n let slice = reader.requestSlice(currentPos, FRAME_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const word = readU32Be(slice);\n const result = readFrameHeader(word, reader.fileSize !== null ? reader.fileSize - currentPos : null);\n if (result.header) {\n return { header: result.header, startPos: currentPos };\n }\n currentPos += result.bytesAdvanced;\n }\n return null;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { Demuxer } from '../demuxer.js';\nimport { InputAudioTrack } from '../input-track.js';\nimport { DEFAULT_TRACK_DISPOSITION } from '../metadata.js';\nimport { assert, AsyncMutex, binarySearchExact, binarySearchLessOrEqual, UNDETERMINED_LANGUAGE } from '../misc.js';\nimport { EncodedPacket, PLACEHOLDER_DATA } from '../packet.js';\nimport { getXingOffset, INFO, XING } from '../../shared/mp3-misc.js';\nimport { ID3_V1_TAG_SIZE, ID3_V2_HEADER_SIZE, parseId3V1Tag, parseId3V2Tag, readId3V2Header, } from '../id3.js';\nimport { readNextFrameHeader } from './mp3-reader.js';\nimport { readAscii, readBytes, readU32Be } from '../reader.js';\nexport class Mp3Demuxer extends Demuxer {\n constructor(input) {\n super(input);\n this.metadataPromise = null;\n this.firstFrameHeader = null;\n this.loadedSamples = []; // All samples from the start of the file to lastLoadedPos\n this.metadataTags = null;\n this.tracks = [];\n this.readingMutex = new AsyncMutex();\n this.lastSampleLoaded = false;\n this.lastLoadedPos = 0;\n this.nextTimestampInSamples = 0;\n this.reader = input._reader;\n }\n async readMetadata() {\n return this.metadataPromise ??= (async () => {\n // Keep loading until we find the first frame header\n while (!this.firstFrameHeader && !this.lastSampleLoaded) {\n await this.advanceReader();\n }\n if (!this.firstFrameHeader) {\n throw new Error('No valid MP3 frame found.');\n }\n this.tracks = [new InputAudioTrack(this.input, new Mp3AudioTrackBacking(this))];\n })();\n }\n async advanceReader() {\n if (this.lastLoadedPos === 0) {\n // Let's skip all ID3v2 tags at the start of the file\n while (true) {\n let slice = this.reader.requestSlice(this.lastLoadedPos, ID3_V2_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice) {\n this.lastSampleLoaded = true;\n return;\n }\n const id3V2Header = readId3V2Header(slice);\n if (!id3V2Header) {\n break;\n }\n this.lastLoadedPos = slice.filePos + id3V2Header.size;\n }\n }\n const result = await readNextFrameHeader(this.reader, this.lastLoadedPos, this.reader.fileSize);\n if (!result) {\n this.lastSampleLoaded = true;\n return;\n }\n const header = result.header;\n this.lastLoadedPos = result.startPos + header.totalSize - 1; // -1 in case the frame is 1 byte too short\n const xingOffset = getXingOffset(header.mpegVersionId, header.channel);\n let slice = this.reader.requestSlice(result.startPos + xingOffset, 4);\n if (slice instanceof Promise)\n slice = await slice;\n if (slice) {\n const word = readU32Be(slice);\n const isXing = word === XING || word === INFO;\n if (isXing) {\n // There's no actual audio data in this frame, so let's skip it\n return;\n }\n }\n if (!this.firstFrameHeader) {\n this.firstFrameHeader = header;\n }\n if (header.sampleRate !== this.firstFrameHeader.sampleRate) {\n console.warn(`MP3 changed sample rate mid-file: ${this.firstFrameHeader.sampleRate} Hz to ${header.sampleRate} Hz.`\n + ` Might be a bug, so please report this file.`);\n }\n const sampleDuration = header.audioSamplesInFrame / this.firstFrameHeader.sampleRate;\n const sample = {\n timestamp: this.nextTimestampInSamples / this.firstFrameHeader.sampleRate,\n duration: sampleDuration,\n dataStart: result.startPos,\n dataSize: header.totalSize,\n };\n this.loadedSamples.push(sample);\n this.nextTimestampInSamples += header.audioSamplesInFrame;\n return;\n }\n async getMimeType() {\n return 'audio/mpeg';\n }\n async getTracks() {\n await this.readMetadata();\n return this.tracks;\n }\n async computeDuration() {\n await this.readMetadata();\n const track = this.tracks[0];\n assert(track);\n return track.computeDuration();\n }\n async getMetadataTags() {\n const release = await this.readingMutex.acquire();\n try {\n await this.readMetadata();\n if (this.metadataTags) {\n return this.metadataTags;\n }\n this.metadataTags = {};\n let currentPos = 0;\n let id3V2HeaderFound = false;\n while (true) {\n let headerSlice = this.reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);\n if (headerSlice instanceof Promise)\n headerSlice = await headerSlice;\n if (!headerSlice)\n break;\n const id3V2Header = readId3V2Header(headerSlice);\n if (!id3V2Header) {\n break;\n }\n id3V2HeaderFound = true;\n let contentSlice = this.reader.requestSlice(headerSlice.filePos, id3V2Header.size);\n if (contentSlice instanceof Promise)\n contentSlice = await contentSlice;\n if (!contentSlice)\n break;\n parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);\n currentPos = headerSlice.filePos + id3V2Header.size;\n }\n if (!id3V2HeaderFound && this.reader.fileSize !== null && this.reader.fileSize >= ID3_V1_TAG_SIZE) {\n // Try reading an ID3v1 tag at the end of the file\n let slice = this.reader.requestSlice(this.reader.fileSize - ID3_V1_TAG_SIZE, ID3_V1_TAG_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n assert(slice);\n const tag = readAscii(slice, 3);\n if (tag === 'TAG') {\n parseId3V1Tag(slice, this.metadataTags);\n }\n }\n return this.metadataTags;\n }\n finally {\n release();\n }\n }\n}\nclass Mp3AudioTrackBacking {\n constructor(demuxer) {\n this.demuxer = demuxer;\n }\n getId() {\n return 1;\n }\n async getFirstTimestamp() {\n return 0;\n }\n getTimeResolution() {\n assert(this.demuxer.firstFrameHeader);\n return this.demuxer.firstFrameHeader.sampleRate / this.demuxer.firstFrameHeader.audioSamplesInFrame;\n }\n async computeDuration() {\n const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });\n return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);\n }\n getName() {\n return null;\n }\n getLanguageCode() {\n return UNDETERMINED_LANGUAGE;\n }\n getCodec() {\n return 'mp3';\n }\n getInternalCodecId() {\n return null;\n }\n getNumberOfChannels() {\n assert(this.demuxer.firstFrameHeader);\n return this.demuxer.firstFrameHeader.channel === 3 ? 1 : 2;\n }\n getSampleRate() {\n assert(this.demuxer.firstFrameHeader);\n return this.demuxer.firstFrameHeader.sampleRate;\n }\n getDisposition() {\n return {\n ...DEFAULT_TRACK_DISPOSITION,\n };\n }\n async getDecoderConfig() {\n assert(this.demuxer.firstFrameHeader);\n return {\n codec: 'mp3',\n numberOfChannels: this.demuxer.firstFrameHeader.channel === 3 ? 1 : 2,\n sampleRate: this.demuxer.firstFrameHeader.sampleRate,\n };\n }\n async getPacketAtIndex(sampleIndex, options) {\n if (sampleIndex === -1) {\n return null;\n }\n const rawSample = this.demuxer.loadedSamples[sampleIndex];\n if (!rawSample) {\n return null;\n }\n let data;\n if (options.metadataOnly) {\n data = PLACEHOLDER_DATA;\n }\n else {\n let slice = this.demuxer.reader.requestSlice(rawSample.dataStart, rawSample.dataSize);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice) {\n return null; // Data didn't fit into the rest of the file\n }\n data = readBytes(slice, rawSample.dataSize);\n }\n return new EncodedPacket(data, 'key', rawSample.timestamp, rawSample.duration, sampleIndex, rawSample.dataSize);\n }\n getFirstPacket(options) {\n return this.getPacketAtIndex(0, options);\n }\n async getNextPacket(packet, options) {\n const release = await this.demuxer.readingMutex.acquire();\n try {\n const sampleIndex = binarySearchExact(this.demuxer.loadedSamples, packet.timestamp, x => x.timestamp);\n if (sampleIndex === -1) {\n throw new Error('Packet was not created from this track.');\n }\n const nextIndex = sampleIndex + 1;\n // Ensure the next sample exists\n while (nextIndex >= this.demuxer.loadedSamples.length\n && !this.demuxer.lastSampleLoaded) {\n await this.demuxer.advanceReader();\n }\n return this.getPacketAtIndex(nextIndex, options);\n }\n finally {\n release();\n }\n }\n async getPacket(timestamp, options) {\n const release = await this.demuxer.readingMutex.acquire();\n try {\n while (true) {\n const index = binarySearchLessOrEqual(this.demuxer.loadedSamples, timestamp, x => x.timestamp);\n if (index === -1 && this.demuxer.loadedSamples.length > 0) {\n // We're before the first sample\n return null;\n }\n if (this.demuxer.lastSampleLoaded) {\n // All data is loaded, return what we found\n return this.getPacketAtIndex(index, options);\n }\n if (index >= 0 && index + 1 < this.demuxer.loadedSamples.length) {\n // The next packet also exists, we're done\n return this.getPacketAtIndex(index, options);\n }\n // Otherwise, keep loading data\n await this.demuxer.advanceReader();\n }\n }\n finally {\n release();\n }\n }\n getKeyPacket(timestamp, options) {\n return this.getPacket(timestamp, options);\n }\n getNextKeyPacket(packet, options) {\n return this.getNextPacket(packet, options);\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { parseOpusTocByte } from '../codec-data.js';\nimport { assert, ilog, toDataView } from '../misc.js';\nexport const OGGS = 0x5367674f; // 'OggS'\nconst OGG_CRC_POLYNOMIAL = 0x04c11db7;\nconst OGG_CRC_TABLE = new Uint32Array(256);\nfor (let n = 0; n < 256; n++) {\n let crc = n << 24;\n for (let k = 0; k < 8; k++) {\n crc = (crc & 0x80000000)\n ? ((crc << 1) ^ OGG_CRC_POLYNOMIAL)\n : (crc << 1);\n }\n OGG_CRC_TABLE[n] = (crc >>> 0) & 0xffffffff;\n}\nexport const computeOggPageCrc = (bytes) => {\n const view = toDataView(bytes);\n const originalChecksum = view.getUint32(22, true);\n view.setUint32(22, 0, true); // Zero out checksum field\n let crc = 0;\n for (let i = 0; i < bytes.length; i++) {\n const byte = bytes[i];\n crc = ((crc << 8) ^ OGG_CRC_TABLE[(crc >>> 24) ^ byte]) >>> 0;\n }\n view.setUint32(22, originalChecksum, true); // Restore checksum field\n return crc;\n};\nexport const extractSampleMetadata = (data, codecInfo, vorbisLastBlocksize) => {\n let durationInSamples = 0;\n let currentBlocksize = null;\n if (data.length > 0) {\n // To know sample duration, we'll need to peak inside the packet\n if (codecInfo.codec === 'vorbis') {\n assert(codecInfo.vorbisInfo);\n const vorbisModeCount = codecInfo.vorbisInfo.modeBlockflags.length;\n const bitCount = ilog(vorbisModeCount - 1);\n const modeMask = ((1 << bitCount) - 1) << 1;\n const modeNumber = (data[0] & modeMask) >> 1;\n if (modeNumber >= codecInfo.vorbisInfo.modeBlockflags.length) {\n throw new Error('Invalid mode number.');\n }\n // In Vorbis, packet duration also depends on the blocksize of the previous packet\n let prevBlocksize = vorbisLastBlocksize;\n const blockflag = codecInfo.vorbisInfo.modeBlockflags[modeNumber];\n currentBlocksize = codecInfo.vorbisInfo.blocksizes[blockflag];\n if (blockflag === 1) {\n const prevMask = (modeMask | 0x1) + 1;\n const flag = data[0] & prevMask ? 1 : 0;\n prevBlocksize = codecInfo.vorbisInfo.blocksizes[flag];\n }\n durationInSamples = prevBlocksize !== null\n ? (prevBlocksize + currentBlocksize) >> 2\n : 0; // The first sample outputs no audio data and therefore has a duration of 0\n }\n else if (codecInfo.codec === 'opus') {\n const toc = parseOpusTocByte(data);\n durationInSamples = toc.durationInSamples;\n }\n }\n return {\n durationInSamples,\n vorbisBlockSize: currentBlocksize,\n };\n};\nexport const buildOggMimeType = (info) => {\n let string = 'audio/ogg';\n if (info.codecStrings) {\n const uniqueCodecMimeTypes = [...new Set(info.codecStrings)];\n string += `; codecs=\"${uniqueCodecMimeTypes.join(', ')}\"`;\n }\n return string;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { readI64Le, readU32Le, readU8 } from '../reader.js';\nimport { OGGS } from './ogg-misc.js';\nexport const MIN_PAGE_HEADER_SIZE = 27;\nexport const MAX_PAGE_HEADER_SIZE = 27 + 255;\nexport const MAX_PAGE_SIZE = MAX_PAGE_HEADER_SIZE + 255 * 255;\nexport const readPageHeader = (slice) => {\n const startPos = slice.filePos;\n const capturePattern = readU32Le(slice);\n if (capturePattern !== OGGS) {\n return null;\n }\n slice.skip(1); // Version\n const headerType = readU8(slice);\n const granulePosition = readI64Le(slice);\n const serialNumber = readU32Le(slice);\n const sequenceNumber = readU32Le(slice);\n const checksum = readU32Le(slice);\n const numberPageSegments = readU8(slice);\n const lacingValues = new Uint8Array(numberPageSegments);\n for (let i = 0; i < numberPageSegments; i++) {\n lacingValues[i] = readU8(slice);\n }\n const headerSize = 27 + numberPageSegments;\n const dataSize = lacingValues.reduce((a, b) => a + b, 0);\n const totalSize = headerSize + dataSize;\n return {\n headerStartPos: startPos,\n totalSize,\n dataStartPos: startPos + headerSize,\n dataSize,\n headerType,\n granulePosition,\n serialNumber,\n sequenceNumber,\n checksum,\n lacingValues,\n };\n};\nexport const findNextPageHeader = (slice, until) => {\n while (slice.filePos < until - (4 - 1)) { // Size of word minus 1\n const word = readU32Le(slice);\n const firstByte = word & 0xff;\n const secondByte = (word >>> 8) & 0xff;\n const thirdByte = (word >>> 16) & 0xff;\n const fourthByte = (word >>> 24) & 0xff;\n const O = 0x4f; // 'O'\n if (firstByte !== O && secondByte !== O && thirdByte !== O && fourthByte !== O) {\n continue;\n }\n slice.skip(-4);\n if (word === OGGS) {\n // We have found the capture pattern\n return true;\n }\n slice.skip(1);\n }\n return false;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { OPUS_SAMPLE_RATE } from '../codec.js';\nimport { parseModesFromVorbisSetupPacket, parseOpusIdentificationHeader, readVorbisComments } from '../codec-data.js';\nimport { Demuxer } from '../demuxer.js';\nimport { InputAudioTrack } from '../input-track.js';\nimport { DEFAULT_TRACK_DISPOSITION } from '../metadata.js';\nimport { assert, AsyncMutex, binarySearchLessOrEqual, findLast, last, roundIfAlmostInteger, toDataView, UNDETERMINED_LANGUAGE, } from '../misc.js';\nimport { EncodedPacket, PLACEHOLDER_DATA } from '../packet.js';\nimport { readBytes } from '../reader.js';\nimport { buildOggMimeType, computeOggPageCrc, extractSampleMetadata } from './ogg-misc.js';\nimport { findNextPageHeader, MAX_PAGE_HEADER_SIZE, MAX_PAGE_SIZE, MIN_PAGE_HEADER_SIZE, readPageHeader, } from './ogg-reader.js';\nexport class OggDemuxer extends Demuxer {\n constructor(input) {\n super(input);\n this.metadataPromise = null;\n this.bitstreams = [];\n this.tracks = [];\n this.metadataTags = {};\n this.reader = input._reader;\n }\n async readMetadata() {\n return this.metadataPromise ??= (async () => {\n let currentPos = 0;\n while (true) {\n let slice = this.reader.requestSliceRange(currentPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const page = readPageHeader(slice);\n if (!page) {\n break;\n }\n const isBos = !!(page.headerType & 0x02);\n if (!isBos) {\n // All bos pages for all bitstreams are required to be at the start, so if the page is not bos then\n // we know we've seen all bitstreams (minus chaining)\n break;\n }\n this.bitstreams.push({\n serialNumber: page.serialNumber,\n bosPage: page,\n description: null,\n numberOfChannels: -1,\n sampleRate: -1,\n codecInfo: {\n codec: null,\n vorbisInfo: null,\n opusInfo: null,\n },\n lastMetadataPacket: null,\n });\n currentPos = page.headerStartPos + page.totalSize;\n }\n for (const bitstream of this.bitstreams) {\n const firstPacket = await this.readPacket(bitstream.bosPage, 0);\n if (!firstPacket) {\n continue;\n }\n if (\n // Check for Vorbis\n firstPacket.data.byteLength >= 7\n && firstPacket.data[0] === 0x01 // Packet type 1 = identification header\n && firstPacket.data[1] === 0x76 // 'v'\n && firstPacket.data[2] === 0x6f // 'o'\n && firstPacket.data[3] === 0x72 // 'r'\n && firstPacket.data[4] === 0x62 // 'b'\n && firstPacket.data[5] === 0x69 // 'i'\n && firstPacket.data[6] === 0x73 // 's'\n ) {\n await this.readVorbisMetadata(firstPacket, bitstream);\n }\n else if (\n // Check for Opus\n firstPacket.data.byteLength >= 8\n && firstPacket.data[0] === 0x4f // 'O'\n && firstPacket.data[1] === 0x70 // 'p'\n && firstPacket.data[2] === 0x75 // 'u'\n && firstPacket.data[3] === 0x73 // 's'\n && firstPacket.data[4] === 0x48 // 'H'\n && firstPacket.data[5] === 0x65 // 'e'\n && firstPacket.data[6] === 0x61 // 'a'\n && firstPacket.data[7] === 0x64 // 'd'\n ) {\n await this.readOpusMetadata(firstPacket, bitstream);\n }\n if (bitstream.codecInfo.codec !== null) {\n this.tracks.push(new InputAudioTrack(this.input, new OggAudioTrackBacking(bitstream, this)));\n }\n }\n })();\n }\n async readVorbisMetadata(firstPacket, bitstream) {\n let nextPacketPosition = await this.findNextPacketStart(firstPacket);\n if (!nextPacketPosition) {\n return;\n }\n const secondPacket = await this.readPacket(nextPacketPosition.startPage, nextPacketPosition.startSegmentIndex);\n if (!secondPacket) {\n return;\n }\n nextPacketPosition = await this.findNextPacketStart(secondPacket);\n if (!nextPacketPosition) {\n return;\n }\n const thirdPacket = await this.readPacket(nextPacketPosition.startPage, nextPacketPosition.startSegmentIndex);\n if (!thirdPacket) {\n return;\n }\n if (secondPacket.data[0] !== 0x03 || thirdPacket.data[0] !== 0x05) {\n return;\n }\n const lacingValues = [];\n const addBytesToSegmentTable = (bytes) => {\n while (true) {\n lacingValues.push(Math.min(255, bytes));\n if (bytes < 255) {\n break;\n }\n bytes -= 255;\n }\n };\n addBytesToSegmentTable(firstPacket.data.length);\n addBytesToSegmentTable(secondPacket.data.length);\n // We don't add the last packet to the segment table, as it is assumed to be whatever bytes remain\n const description = new Uint8Array(1 + lacingValues.length\n + firstPacket.data.length + secondPacket.data.length + thirdPacket.data.length);\n description[0] = 2; // Num entries in the segment table\n description.set(lacingValues, 1);\n description.set(firstPacket.data, 1 + lacingValues.length);\n description.set(secondPacket.data, 1 + lacingValues.length + firstPacket.data.length);\n description.set(thirdPacket.data, 1 + lacingValues.length + firstPacket.data.length + secondPacket.data.length);\n bitstream.codecInfo.codec = 'vorbis';\n bitstream.description = description;\n bitstream.lastMetadataPacket = thirdPacket;\n const view = toDataView(firstPacket.data);\n bitstream.numberOfChannels = view.getUint8(11);\n bitstream.sampleRate = view.getUint32(12, true);\n const blockSizeByte = view.getUint8(28);\n bitstream.codecInfo.vorbisInfo = {\n blocksizes: [\n 1 << (blockSizeByte & 0xf),\n 1 << (blockSizeByte >> 4),\n ],\n modeBlockflags: parseModesFromVorbisSetupPacket(thirdPacket.data).modeBlockflags,\n };\n readVorbisComments(secondPacket.data.subarray(7), this.metadataTags); // Skip header type and 'vorbis'\n }\n async readOpusMetadata(firstPacket, bitstream) {\n // From https://datatracker.ietf.org/doc/html/rfc7845#section-5:\n // \"An Ogg Opus logical stream contains exactly two mandatory header packets: an identification header and a\n // comment header.\"\n const nextPacketPosition = await this.findNextPacketStart(firstPacket);\n if (!nextPacketPosition) {\n return;\n }\n const secondPacket = await this.readPacket(nextPacketPosition.startPage, nextPacketPosition.startSegmentIndex);\n if (!secondPacket) {\n return;\n }\n bitstream.codecInfo.codec = 'opus';\n bitstream.description = firstPacket.data;\n bitstream.lastMetadataPacket = secondPacket;\n const header = parseOpusIdentificationHeader(firstPacket.data);\n bitstream.numberOfChannels = header.outputChannelCount;\n bitstream.sampleRate = OPUS_SAMPLE_RATE; // Always the same\n bitstream.codecInfo.opusInfo = {\n preSkip: header.preSkip,\n };\n readVorbisComments(secondPacket.data.subarray(8), this.metadataTags); // Skip 'OpusTags'\n }\n async readPacket(startPage, startSegmentIndex) {\n assert(startSegmentIndex < startPage.lacingValues.length);\n let startDataOffset = 0;\n for (let i = 0; i < startSegmentIndex; i++) {\n startDataOffset += startPage.lacingValues[i];\n }\n let currentPage = startPage;\n let currentDataOffset = startDataOffset;\n let currentSegmentIndex = startSegmentIndex;\n const chunks = [];\n outer: while (true) {\n // Load the entire page data\n let pageSlice = this.reader.requestSlice(currentPage.dataStartPos, currentPage.dataSize);\n if (pageSlice instanceof Promise)\n pageSlice = await pageSlice;\n assert(pageSlice);\n const pageData = readBytes(pageSlice, currentPage.dataSize);\n while (true) {\n if (currentSegmentIndex === currentPage.lacingValues.length) {\n chunks.push(pageData.subarray(startDataOffset, currentDataOffset));\n break;\n }\n const lacingValue = currentPage.lacingValues[currentSegmentIndex];\n currentDataOffset += lacingValue;\n if (lacingValue < 255) {\n chunks.push(pageData.subarray(startDataOffset, currentDataOffset));\n break outer;\n }\n currentSegmentIndex++;\n }\n // The packet extends to the next page; let's find it\n let currentPos = currentPage.headerStartPos + currentPage.totalSize;\n while (true) {\n let headerSlice = this.reader.requestSliceRange(currentPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);\n if (headerSlice instanceof Promise)\n headerSlice = await headerSlice;\n if (!headerSlice) {\n return null;\n }\n const nextPage = readPageHeader(headerSlice);\n if (!nextPage) {\n return null;\n }\n currentPage = nextPage;\n if (currentPage.serialNumber === startPage.serialNumber) {\n break;\n }\n currentPos = currentPage.headerStartPos + currentPage.totalSize;\n }\n startDataOffset = 0;\n currentDataOffset = 0;\n currentSegmentIndex = 0;\n }\n const totalPacketSize = chunks.reduce((sum, chunk) => sum + chunk.length, 0);\n const packetData = new Uint8Array(totalPacketSize);\n let offset = 0;\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n packetData.set(chunk, offset);\n offset += chunk.length;\n }\n return {\n data: packetData,\n endPage: currentPage,\n endSegmentIndex: currentSegmentIndex,\n };\n }\n async findNextPacketStart(lastPacket) {\n // If there's another segment in the same page, return it\n if (lastPacket.endSegmentIndex < lastPacket.endPage.lacingValues.length - 1) {\n return { startPage: lastPacket.endPage, startSegmentIndex: lastPacket.endSegmentIndex + 1 };\n }\n const isEos = !!(lastPacket.endPage.headerType & 0x04);\n if (isEos) {\n // The page is marked as the last page of the logical bitstream, so we won't find anything beyond it\n return null;\n }\n // Otherwise, search for the next page belonging to the same bitstream\n let currentPos = lastPacket.endPage.headerStartPos + lastPacket.endPage.totalSize;\n while (true) {\n let slice = this.reader.requestSliceRange(currentPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice) {\n return null;\n }\n const nextPage = readPageHeader(slice);\n if (!nextPage) {\n return null;\n }\n if (nextPage.serialNumber === lastPacket.endPage.serialNumber) {\n return { startPage: nextPage, startSegmentIndex: 0 };\n }\n currentPos = nextPage.headerStartPos + nextPage.totalSize;\n }\n }\n async getMimeType() {\n await this.readMetadata();\n const codecStrings = await Promise.all(this.tracks.map(x => x.getCodecParameterString()));\n return buildOggMimeType({\n codecStrings: codecStrings.filter(Boolean),\n });\n }\n async getTracks() {\n await this.readMetadata();\n return this.tracks;\n }\n async computeDuration() {\n const tracks = await this.getTracks();\n const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));\n return Math.max(0, ...trackDurations);\n }\n async getMetadataTags() {\n await this.readMetadata();\n return this.metadataTags;\n }\n}\nclass OggAudioTrackBacking {\n constructor(bitstream, demuxer) {\n this.bitstream = bitstream;\n this.demuxer = demuxer;\n this.encodedPacketToMetadata = new WeakMap();\n this.sequentialScanCache = [];\n this.sequentialScanMutex = new AsyncMutex();\n // Opus always uses a fixed sample rate for its internal calculations, even if the actual rate is different\n this.internalSampleRate = bitstream.codecInfo.codec === 'opus'\n ? OPUS_SAMPLE_RATE\n : bitstream.sampleRate;\n }\n getId() {\n return this.bitstream.serialNumber;\n }\n getNumberOfChannels() {\n return this.bitstream.numberOfChannels;\n }\n getSampleRate() {\n return this.bitstream.sampleRate;\n }\n getTimeResolution() {\n return this.bitstream.sampleRate;\n }\n getCodec() {\n return this.bitstream.codecInfo.codec;\n }\n getInternalCodecId() {\n return null;\n }\n async getDecoderConfig() {\n assert(this.bitstream.codecInfo.codec);\n return {\n codec: this.bitstream.codecInfo.codec,\n numberOfChannels: this.bitstream.numberOfChannels,\n sampleRate: this.bitstream.sampleRate,\n description: this.bitstream.description ?? undefined,\n };\n }\n getName() {\n return null;\n }\n getLanguageCode() {\n return UNDETERMINED_LANGUAGE;\n }\n getDisposition() {\n return {\n ...DEFAULT_TRACK_DISPOSITION,\n };\n }\n async getFirstTimestamp() {\n return 0;\n }\n async computeDuration() {\n const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });\n return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);\n }\n granulePositionToTimestampInSamples(granulePosition) {\n if (this.bitstream.codecInfo.codec === 'opus') {\n assert(this.bitstream.codecInfo.opusInfo);\n return granulePosition - this.bitstream.codecInfo.opusInfo.preSkip;\n }\n return granulePosition;\n }\n createEncodedPacketFromOggPacket(packet, additional, options) {\n if (!packet) {\n return null;\n }\n const { durationInSamples, vorbisBlockSize } = extractSampleMetadata(packet.data, this.bitstream.codecInfo, additional.vorbisLastBlocksize);\n const encodedPacket = new EncodedPacket(options.metadataOnly ? PLACEHOLDER_DATA : packet.data, 'key', Math.max(0, additional.timestampInSamples) / this.internalSampleRate, durationInSamples / this.internalSampleRate, packet.endPage.headerStartPos + packet.endSegmentIndex, packet.data.byteLength);\n this.encodedPacketToMetadata.set(encodedPacket, {\n packet,\n timestampInSamples: additional.timestampInSamples,\n durationInSamples,\n vorbisLastBlockSize: additional.vorbisLastBlocksize,\n vorbisBlockSize,\n });\n return encodedPacket;\n }\n async getFirstPacket(options) {\n assert(this.bitstream.lastMetadataPacket);\n const packetPosition = await this.demuxer.findNextPacketStart(this.bitstream.lastMetadataPacket);\n if (!packetPosition) {\n return null;\n }\n let timestampInSamples = 0;\n if (this.bitstream.codecInfo.codec === 'opus') {\n assert(this.bitstream.codecInfo.opusInfo);\n timestampInSamples -= this.bitstream.codecInfo.opusInfo.preSkip;\n }\n const packet = await this.demuxer.readPacket(packetPosition.startPage, packetPosition.startSegmentIndex);\n return this.createEncodedPacketFromOggPacket(packet, {\n timestampInSamples,\n vorbisLastBlocksize: null,\n }, options);\n }\n async getNextPacket(prevPacket, options) {\n const prevMetadata = this.encodedPacketToMetadata.get(prevPacket);\n if (!prevMetadata) {\n throw new Error('Packet was not created from this track.');\n }\n const packetPosition = await this.demuxer.findNextPacketStart(prevMetadata.packet);\n if (!packetPosition) {\n return null;\n }\n const timestampInSamples = prevMetadata.timestampInSamples + prevMetadata.durationInSamples;\n const packet = await this.demuxer.readPacket(packetPosition.startPage, packetPosition.startSegmentIndex);\n return this.createEncodedPacketFromOggPacket(packet, {\n timestampInSamples,\n vorbisLastBlocksize: prevMetadata.vorbisBlockSize,\n }, options);\n }\n async getPacket(timestamp, options) {\n if (this.demuxer.reader.fileSize === null) {\n // No file size known, can't do binary search, but fall back to sequential algo instead\n return this.getPacketSequential(timestamp, options);\n }\n const timestampInSamples = roundIfAlmostInteger(timestamp * this.internalSampleRate);\n if (timestampInSamples === 0) {\n // Fast path for timestamp 0 - avoids binary search when playing back from the start\n return this.getFirstPacket(options);\n }\n if (timestampInSamples < 0) {\n // There's nothing here\n return null;\n }\n assert(this.bitstream.lastMetadataPacket);\n const startPosition = await this.demuxer.findNextPacketStart(this.bitstream.lastMetadataPacket);\n if (!startPosition) {\n return null;\n }\n let lowPage = startPosition.startPage;\n let high = this.demuxer.reader.fileSize;\n const lowPages = [lowPage];\n // First, let's perform a binary serach (bisection search) on the file to find the approximate page where\n // we'll find the packet. We want to find a page whose end packet position is less than or equal to the\n // packet position we're searching for.\n // Outer loop: Does the binary serach\n outer: while (lowPage.headerStartPos + lowPage.totalSize < high) {\n const low = lowPage.headerStartPos;\n const mid = Math.floor((low + high) / 2);\n let searchStartPos = mid;\n // Inner loop: Does a linear forward scan if the page cannot be found immediately\n while (true) {\n const until = Math.min(searchStartPos + MAX_PAGE_SIZE, high - MIN_PAGE_HEADER_SIZE);\n let searchSlice = this.demuxer.reader.requestSlice(searchStartPos, until - searchStartPos);\n if (searchSlice instanceof Promise)\n searchSlice = await searchSlice;\n assert(searchSlice);\n const found = findNextPageHeader(searchSlice, until);\n if (!found) {\n high = mid + MIN_PAGE_HEADER_SIZE;\n continue outer;\n }\n let headerSlice = this.demuxer.reader.requestSliceRange(searchSlice.filePos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);\n if (headerSlice instanceof Promise)\n headerSlice = await headerSlice;\n assert(headerSlice);\n const page = readPageHeader(headerSlice);\n assert(page);\n let pageValid = false;\n if (page.serialNumber === this.bitstream.serialNumber) {\n // Serial numbers are basically random numbers, and the chance of finding a fake page with\n // matching serial number is astronomically low, so we can be pretty sure this page is legit.\n pageValid = true;\n }\n else {\n let pageSlice = this.demuxer.reader.requestSlice(page.headerStartPos, page.totalSize);\n if (pageSlice instanceof Promise)\n pageSlice = await pageSlice;\n assert(pageSlice);\n // Validate the page by checking checksum\n const bytes = readBytes(pageSlice, page.totalSize);\n const crc = computeOggPageCrc(bytes);\n pageValid = crc === page.checksum;\n }\n if (!pageValid) {\n // Keep searching for a valid page\n searchStartPos = page.headerStartPos + 4; // 'OggS' is 4 bytes\n continue;\n }\n if (pageValid && page.serialNumber !== this.bitstream.serialNumber) {\n // Page is valid but from a different bitstream, so keep searching forward until we find one\n // belonging to the our bitstream\n searchStartPos = page.headerStartPos + page.totalSize;\n continue;\n }\n const isContinuationPage = page.granulePosition === -1;\n if (isContinuationPage) {\n // No packet ends on this page - keep looking\n searchStartPos = page.headerStartPos + page.totalSize;\n continue;\n }\n // The page is valid and belongs to our bitstream; let's check its granule position to see where we\n // need to take the bisection search.\n if (this.granulePositionToTimestampInSamples(page.granulePosition) > timestampInSamples) {\n high = page.headerStartPos;\n }\n else {\n lowPage = page;\n lowPages.push(page);\n }\n continue outer;\n }\n }\n // Now we have the last page with a packet position <= the packet position we're looking for, but there\n // might be multiple pages with the packet position, in which case we actually need to find the first of\n // such pages. We'll do this in two steps: First, let's find the latest page we know with an earlier packet\n // position, and then linear scan ourselves forward until we find the correct page.\n let lowerPage = startPosition.startPage;\n for (const otherLowPage of lowPages) {\n if (otherLowPage.granulePosition === lowPage.granulePosition) {\n break;\n }\n if (!lowerPage || otherLowPage.headerStartPos > lowerPage.headerStartPos) {\n lowerPage = otherLowPage;\n }\n }\n let currentPage = lowerPage;\n // Keep track of the pages we traversed, we need these later for backwards seeking\n const previousPages = [currentPage];\n while (true) {\n // This loop must terminate as we'll eventually reach lowPage\n if (currentPage.serialNumber === this.bitstream.serialNumber\n && currentPage.granulePosition === lowPage.granulePosition) {\n break;\n }\n const nextPos = currentPage.headerStartPos + currentPage.totalSize;\n let slice = this.demuxer.reader.requestSliceRange(nextPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n assert(slice);\n const nextPage = readPageHeader(slice);\n assert(nextPage);\n currentPage = nextPage;\n if (currentPage.serialNumber === this.bitstream.serialNumber) {\n previousPages.push(currentPage);\n }\n }\n assert(currentPage.granulePosition !== -1);\n let currentSegmentIndex = null;\n let currentTimestampInSamples;\n let currentTimestampIsCorrect;\n // These indicate the end position of the packet that the granule position belongs to\n let endPage = currentPage;\n let endSegmentIndex = 0;\n if (currentPage.headerStartPos === startPosition.startPage.headerStartPos) {\n currentTimestampInSamples = this.granulePositionToTimestampInSamples(0);\n currentTimestampIsCorrect = true;\n currentSegmentIndex = 0;\n }\n else {\n currentTimestampInSamples = 0; // Placeholder value! We'll refine it once we can\n currentTimestampIsCorrect = false;\n // Find the segment index of the next packet\n for (let i = currentPage.lacingValues.length - 1; i >= 0; i--) {\n const value = currentPage.lacingValues[i];\n if (value < 255) {\n // We know the last packet ended at i, so the next one starts at i + 1\n currentSegmentIndex = i + 1;\n break;\n }\n }\n // This must hold: Since this page has a granule position set, that means there must be a packet that\n // ends in this page.\n if (currentSegmentIndex === null) {\n throw new Error('Invalid page with granule position: no packets end on this page.');\n }\n endSegmentIndex = currentSegmentIndex - 1;\n const pseudopacket = {\n data: PLACEHOLDER_DATA,\n endPage,\n endSegmentIndex,\n };\n const nextPosition = await this.demuxer.findNextPacketStart(pseudopacket);\n if (nextPosition) {\n // Let's rewind a single step (packet) - this previous packet ensures that we'll correctly compute\n // the duration for the packet we're looking for.\n const endPosition = findPreviousPacketEndPosition(previousPages, currentPage, currentSegmentIndex);\n assert(endPosition);\n const startPosition = findPacketStartPosition(previousPages, endPosition.page, endPosition.segmentIndex);\n if (startPosition) {\n currentPage = startPosition.page;\n currentSegmentIndex = startPosition.segmentIndex;\n }\n }\n else {\n // There is no next position, which means we're looking for the last packet in the bitstream. The\n // granule position on the last page tends to be fucky, so let's instead start the search on the\n // page before that. So let's loop until we find a packet that ends in a previous page.\n while (true) {\n const endPosition = findPreviousPacketEndPosition(previousPages, currentPage, currentSegmentIndex);\n if (!endPosition) {\n break;\n }\n const startPosition = findPacketStartPosition(previousPages, endPosition.page, endPosition.segmentIndex);\n if (!startPosition) {\n break;\n }\n currentPage = startPosition.page;\n currentSegmentIndex = startPosition.segmentIndex;\n if (endPosition.page.headerStartPos !== endPage.headerStartPos) {\n endPage = endPosition.page;\n endSegmentIndex = endPosition.segmentIndex;\n break;\n }\n }\n }\n }\n let lastEncodedPacket = null;\n let lastEncodedPacketMetadata = null;\n // Alright, now it's time for the final, granular seek: We keep iterating over packets until we've found the\n // one with the correct timestamp - i.e., the last one with a timestamp <= the timestamp we're looking for.\n while (currentPage !== null) {\n assert(currentSegmentIndex !== null);\n const packet = await this.demuxer.readPacket(currentPage, currentSegmentIndex);\n if (!packet) {\n break;\n }\n // We might need to skip the packet if it's a metadata one\n const skipPacket = currentPage.headerStartPos === startPosition.startPage.headerStartPos\n && currentSegmentIndex < startPosition.startSegmentIndex;\n if (!skipPacket) {\n let encodedPacket = this.createEncodedPacketFromOggPacket(packet, {\n timestampInSamples: currentTimestampInSamples,\n vorbisLastBlocksize: lastEncodedPacketMetadata?.vorbisBlockSize ?? null,\n }, options);\n assert(encodedPacket);\n let encodedPacketMetadata = this.encodedPacketToMetadata.get(encodedPacket);\n assert(encodedPacketMetadata);\n if (!currentTimestampIsCorrect\n && packet.endPage.headerStartPos === endPage.headerStartPos\n && packet.endSegmentIndex === endSegmentIndex) {\n // We know this packet end timestamp can be derived from the page's granule position\n currentTimestampInSamples = this.granulePositionToTimestampInSamples(currentPage.granulePosition);\n currentTimestampIsCorrect = true;\n // Let's backpatch the packet we just created with the correct timestamp\n encodedPacket = this.createEncodedPacketFromOggPacket(packet, {\n timestampInSamples: currentTimestampInSamples - encodedPacketMetadata.durationInSamples,\n vorbisLastBlocksize: lastEncodedPacketMetadata?.vorbisBlockSize ?? null,\n }, options);\n assert(encodedPacket);\n encodedPacketMetadata = this.encodedPacketToMetadata.get(encodedPacket);\n assert(encodedPacketMetadata);\n }\n else {\n currentTimestampInSamples += encodedPacketMetadata.durationInSamples;\n }\n lastEncodedPacket = encodedPacket;\n lastEncodedPacketMetadata = encodedPacketMetadata;\n if (currentTimestampIsCorrect\n && (\n // Next timestamp will be too late\n Math.max(currentTimestampInSamples, 0) > timestampInSamples\n // This timestamp already matches\n || Math.max(encodedPacketMetadata.timestampInSamples, 0) === timestampInSamples)) {\n break;\n }\n }\n const nextPosition = await this.demuxer.findNextPacketStart(packet);\n if (!nextPosition) {\n break;\n }\n currentPage = nextPosition.startPage;\n currentSegmentIndex = nextPosition.startSegmentIndex;\n }\n return lastEncodedPacket;\n }\n // A slower but simpler and sequential algorithm for finding a packet in a file\n async getPacketSequential(timestamp, options) {\n const release = await this.sequentialScanMutex.acquire(); // Requires exclusivity because we write to a cache\n try {\n const timestampInSamples = roundIfAlmostInteger(timestamp * this.internalSampleRate);\n timestamp = timestampInSamples / this.internalSampleRate;\n const index = binarySearchLessOrEqual(this.sequentialScanCache, timestampInSamples, x => x.timestampInSamples);\n let currentPacket;\n if (index !== -1) {\n // We don't need to start from the beginning, we can start at a previous scan point\n const cacheEntry = this.sequentialScanCache[index];\n currentPacket = this.createEncodedPacketFromOggPacket(cacheEntry.packet, {\n timestampInSamples: cacheEntry.timestampInSamples,\n vorbisLastBlocksize: cacheEntry.vorbisLastBlockSize,\n }, options);\n }\n else {\n currentPacket = await this.getFirstPacket(options);\n }\n let i = 0;\n while (currentPacket && currentPacket.timestamp < timestamp) {\n const nextPacket = await this.getNextPacket(currentPacket, options);\n if (!nextPacket || nextPacket.timestamp > timestamp) {\n break;\n }\n currentPacket = nextPacket;\n i++;\n if (i === 100) {\n // Add \"checkpoints\" every once in a while to speed up subsequent random accesses\n i = 0;\n const metadata = this.encodedPacketToMetadata.get(currentPacket);\n assert(metadata);\n if (this.sequentialScanCache.length > 0) {\n // If we reach this case, we must be at the end of the cache\n assert(last(this.sequentialScanCache).timestampInSamples <= metadata.timestampInSamples);\n }\n this.sequentialScanCache.push(metadata);\n }\n }\n return currentPacket;\n }\n finally {\n release();\n }\n }\n getKeyPacket(timestamp, options) {\n return this.getPacket(timestamp, options);\n }\n getNextKeyPacket(packet, options) {\n return this.getNextPacket(packet, options);\n }\n}\n/** Finds the start position of a packet given its end position. */\nconst findPacketStartPosition = (pageList, endPage, endSegmentIndex) => {\n let page = endPage;\n let segmentIndex = endSegmentIndex;\n outer: while (true) {\n segmentIndex--;\n for (segmentIndex; segmentIndex >= 0; segmentIndex--) {\n const lacingValue = page.lacingValues[segmentIndex];\n if (lacingValue < 255) {\n segmentIndex++; // We know the last packet starts here\n break outer;\n }\n }\n assert(segmentIndex === -1);\n const pageStartsWithFreshPacket = !(page.headerType & 0x01);\n if (pageStartsWithFreshPacket) {\n // Fast exit: We know we don't need to look in the previous page\n segmentIndex = 0;\n break;\n }\n const previousPage = findLast(pageList, x => x.headerStartPos < page.headerStartPos);\n if (!previousPage) {\n return null;\n }\n page = previousPage;\n segmentIndex = page.lacingValues.length;\n }\n assert(segmentIndex !== -1);\n if (segmentIndex === page.lacingValues.length) {\n // Wrap back around to the first segment of the next page\n const nextPage = pageList[pageList.indexOf(page) + 1];\n assert(nextPage);\n page = nextPage;\n segmentIndex = 0;\n }\n return { page, segmentIndex };\n};\n/** Finds the end position of a packet given the start position of the following packet. */\nconst findPreviousPacketEndPosition = (pageList, startPage, startSegmentIndex) => {\n if (startSegmentIndex > 0) {\n // Easy\n return { page: startPage, segmentIndex: startSegmentIndex - 1 };\n }\n const previousPage = findLast(pageList, x => x.headerStartPos < startPage.headerStartPos);\n if (!previousPage) {\n return null;\n }\n return { page: previousPage, segmentIndex: previousPage.lacingValues.length - 1 };\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { Demuxer } from '../demuxer.js';\nimport { InputAudioTrack } from '../input-track.js';\nimport { DEFAULT_TRACK_DISPOSITION } from '../metadata.js';\nimport { assert, UNDETERMINED_LANGUAGE } from '../misc.js';\nimport { EncodedPacket, PLACEHOLDER_DATA } from '../packet.js';\nimport { readAscii, readBytes, readU16, readU32, readU64 } from '../reader.js';\nimport { parseId3V2Tag, readId3V2Header } from '../id3.js';\nexport var WaveFormat;\n(function (WaveFormat) {\n WaveFormat[WaveFormat[\"PCM\"] = 1] = \"PCM\";\n WaveFormat[WaveFormat[\"IEEE_FLOAT\"] = 3] = \"IEEE_FLOAT\";\n WaveFormat[WaveFormat[\"ALAW\"] = 6] = \"ALAW\";\n WaveFormat[WaveFormat[\"MULAW\"] = 7] = \"MULAW\";\n WaveFormat[WaveFormat[\"EXTENSIBLE\"] = 65534] = \"EXTENSIBLE\";\n})(WaveFormat || (WaveFormat = {}));\nexport class WaveDemuxer extends Demuxer {\n constructor(input) {\n super(input);\n this.metadataPromise = null;\n this.dataStart = -1;\n this.dataSize = -1;\n this.audioInfo = null;\n this.tracks = [];\n this.lastKnownPacketIndex = 0;\n this.metadataTags = {};\n this.reader = input._reader;\n }\n async readMetadata() {\n return this.metadataPromise ??= (async () => {\n let slice = this.reader.requestSlice(0, 12);\n if (slice instanceof Promise)\n slice = await slice;\n assert(slice);\n const riffType = readAscii(slice, 4);\n const littleEndian = riffType !== 'RIFX';\n const isRf64 = riffType === 'RF64';\n const outerChunkSize = readU32(slice, littleEndian);\n let totalFileSize = isRf64\n ? this.reader.fileSize\n : Math.min(outerChunkSize + 8, this.reader.fileSize ?? Infinity);\n const format = readAscii(slice, 4);\n if (format !== 'WAVE') {\n throw new Error('Invalid WAVE file - wrong format');\n }\n let chunksRead = 0;\n let dataChunkSize = null;\n let currentPos = slice.filePos;\n while (totalFileSize === null || currentPos < totalFileSize) {\n let slice = this.reader.requestSlice(currentPos, 8);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const chunkId = readAscii(slice, 4);\n const chunkSize = readU32(slice, littleEndian);\n const startPos = slice.filePos;\n if (isRf64 && chunksRead === 0 && chunkId !== 'ds64') {\n throw new Error('Invalid RF64 file: First chunk must be \"ds64\".');\n }\n if (chunkId === 'fmt ') {\n await this.parseFmtChunk(startPos, chunkSize, littleEndian);\n }\n else if (chunkId === 'data') {\n dataChunkSize ??= chunkSize;\n this.dataStart = slice.filePos;\n this.dataSize = Math.min(dataChunkSize, (totalFileSize ?? Infinity) - this.dataStart);\n if (this.reader.fileSize === null) {\n break; // Stop once we hit the data chunk\n }\n }\n else if (chunkId === 'ds64') {\n // File and data chunk sizes are defined in here instead\n let ds64Slice = this.reader.requestSlice(startPos, chunkSize);\n if (ds64Slice instanceof Promise)\n ds64Slice = await ds64Slice;\n if (!ds64Slice)\n break;\n const riffChunkSize = readU64(ds64Slice, littleEndian);\n dataChunkSize = readU64(ds64Slice, littleEndian);\n totalFileSize = Math.min(riffChunkSize + 8, this.reader.fileSize ?? Infinity);\n }\n else if (chunkId === 'LIST') {\n await this.parseListChunk(startPos, chunkSize, littleEndian);\n }\n else if (chunkId === 'ID3 ' || chunkId === 'id3 ') {\n await this.parseId3Chunk(startPos, chunkSize);\n }\n currentPos = startPos + chunkSize + (chunkSize & 1); // Handle padding\n chunksRead++;\n }\n if (!this.audioInfo) {\n throw new Error('Invalid WAVE file - missing \"fmt \" chunk');\n }\n if (this.dataStart === -1) {\n throw new Error('Invalid WAVE file - missing \"data\" chunk');\n }\n const blockSize = this.audioInfo.blockSizeInBytes;\n this.dataSize = Math.floor(this.dataSize / blockSize) * blockSize;\n this.tracks.push(new InputAudioTrack(this.input, new WaveAudioTrackBacking(this)));\n })();\n }\n async parseFmtChunk(startPos, size, littleEndian) {\n let slice = this.reader.requestSlice(startPos, size);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return; // File too short\n let formatTag = readU16(slice, littleEndian);\n const numChannels = readU16(slice, littleEndian);\n const sampleRate = readU32(slice, littleEndian);\n slice.skip(4); // Bytes per second\n const blockAlign = readU16(slice, littleEndian);\n let bitsPerSample;\n if (size === 14) { // Plain WAVEFORMAT\n bitsPerSample = 8;\n }\n else {\n bitsPerSample = readU16(slice, littleEndian);\n }\n // Handle WAVEFORMATEXTENSIBLE\n if (size >= 18 && formatTag !== 0x0165) {\n const cbSize = readU16(slice, littleEndian);\n const remainingSize = size - 18;\n const extensionSize = Math.min(remainingSize, cbSize);\n if (extensionSize >= 22 && formatTag === WaveFormat.EXTENSIBLE) {\n // Parse WAVEFORMATEXTENSIBLE\n slice.skip(2 + 4);\n const subFormat = readBytes(slice, 16);\n // Get actual format from subFormat GUID\n formatTag = subFormat[0] | (subFormat[1] << 8);\n }\n }\n if (formatTag === WaveFormat.MULAW || formatTag === WaveFormat.ALAW) {\n bitsPerSample = 8;\n }\n this.audioInfo = {\n format: formatTag,\n numberOfChannels: numChannels,\n sampleRate,\n sampleSizeInBytes: Math.ceil(bitsPerSample / 8),\n blockSizeInBytes: blockAlign,\n };\n }\n async parseListChunk(startPos, size, littleEndian) {\n let slice = this.reader.requestSlice(startPos, size);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return; // File too short\n const infoType = readAscii(slice, 4);\n if (infoType !== 'INFO' && infoType !== 'INF0') { // exiftool.org claims INF0 can happen\n return; // Not an INFO chunk\n }\n let currentPos = slice.filePos;\n while (currentPos <= startPos + size - 8) {\n slice.filePos = currentPos;\n const chunkName = readAscii(slice, 4);\n const chunkSize = readU32(slice, littleEndian);\n const bytes = readBytes(slice, chunkSize);\n let stringLength = 0;\n for (let i = 0; i < bytes.length; i++) {\n if (bytes[i] === 0) {\n break;\n }\n stringLength++;\n }\n const value = String.fromCharCode(...bytes.subarray(0, stringLength));\n this.metadataTags.raw ??= {};\n this.metadataTags.raw[chunkName] = value;\n switch (chunkName) {\n case 'INAM':\n case 'TITL':\n {\n this.metadataTags.title ??= value;\n }\n ;\n break;\n case 'TIT3':\n {\n this.metadataTags.description ??= value;\n }\n ;\n break;\n case 'IART':\n {\n this.metadataTags.artist ??= value;\n }\n ;\n break;\n case 'IPRD':\n {\n this.metadataTags.album ??= value;\n }\n ;\n break;\n case 'IPRT':\n case 'ITRK':\n case 'TRCK':\n {\n const parts = value.split('/');\n const trackNum = Number.parseInt(parts[0], 10);\n const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);\n if (Number.isInteger(trackNum) && trackNum > 0) {\n this.metadataTags.trackNumber ??= trackNum;\n }\n if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {\n this.metadataTags.tracksTotal ??= tracksTotal;\n }\n }\n ;\n break;\n case 'ICRD':\n case 'IDIT':\n {\n const date = new Date(value);\n if (!Number.isNaN(date.getTime())) {\n this.metadataTags.date ??= date;\n }\n }\n ;\n break;\n case 'YEAR':\n {\n const year = Number.parseInt(value, 10);\n if (Number.isInteger(year) && year > 0) {\n this.metadataTags.date ??= new Date(year, 0, 1);\n }\n }\n ;\n break;\n case 'IGNR':\n case 'GENR':\n {\n this.metadataTags.genre ??= value;\n }\n ;\n break;\n case 'ICMT':\n case 'CMNT':\n case 'COMM':\n {\n this.metadataTags.comment ??= value;\n }\n ;\n break;\n }\n currentPos += 8 + chunkSize + (chunkSize & 1); // Handle padding\n }\n }\n async parseId3Chunk(startPos, size) {\n // Parse ID3 tag embedded in WAV file (non-default, but used a lot in practice anyway)\n let slice = this.reader.requestSlice(startPos, size);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return; // File too short\n const id3V2Header = readId3V2Header(slice);\n if (id3V2Header) {\n // Extract the content portion (skip the 10-byte header)\n const contentSlice = slice.slice(startPos + 10, id3V2Header.size);\n parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);\n }\n }\n getCodec() {\n assert(this.audioInfo);\n if (this.audioInfo.format === WaveFormat.MULAW) {\n return 'ulaw';\n }\n if (this.audioInfo.format === WaveFormat.ALAW) {\n return 'alaw';\n }\n if (this.audioInfo.format === WaveFormat.PCM) {\n // All formats are little-endian\n if (this.audioInfo.sampleSizeInBytes === 1) {\n return 'pcm-u8';\n }\n else if (this.audioInfo.sampleSizeInBytes === 2) {\n return 'pcm-s16';\n }\n else if (this.audioInfo.sampleSizeInBytes === 3) {\n return 'pcm-s24';\n }\n else if (this.audioInfo.sampleSizeInBytes === 4) {\n return 'pcm-s32';\n }\n }\n if (this.audioInfo.format === WaveFormat.IEEE_FLOAT) {\n if (this.audioInfo.sampleSizeInBytes === 4) {\n return 'pcm-f32';\n }\n }\n return null;\n }\n async getMimeType() {\n return 'audio/wav';\n }\n async computeDuration() {\n await this.readMetadata();\n const track = this.tracks[0];\n assert(track);\n return track.computeDuration();\n }\n async getTracks() {\n await this.readMetadata();\n return this.tracks;\n }\n async getMetadataTags() {\n await this.readMetadata();\n return this.metadataTags;\n }\n}\nconst PACKET_SIZE_IN_FRAMES = 2048;\nclass WaveAudioTrackBacking {\n constructor(demuxer) {\n this.demuxer = demuxer;\n }\n getId() {\n return 1;\n }\n getCodec() {\n return this.demuxer.getCodec();\n }\n getInternalCodecId() {\n assert(this.demuxer.audioInfo);\n return this.demuxer.audioInfo.format;\n }\n async getDecoderConfig() {\n const codec = this.demuxer.getCodec();\n if (!codec) {\n return null;\n }\n assert(this.demuxer.audioInfo);\n return {\n codec,\n numberOfChannels: this.demuxer.audioInfo.numberOfChannels,\n sampleRate: this.demuxer.audioInfo.sampleRate,\n };\n }\n async computeDuration() {\n const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });\n return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);\n }\n getNumberOfChannels() {\n assert(this.demuxer.audioInfo);\n return this.demuxer.audioInfo.numberOfChannels;\n }\n getSampleRate() {\n assert(this.demuxer.audioInfo);\n return this.demuxer.audioInfo.sampleRate;\n }\n getTimeResolution() {\n assert(this.demuxer.audioInfo);\n return this.demuxer.audioInfo.sampleRate;\n }\n getName() {\n return null;\n }\n getLanguageCode() {\n return UNDETERMINED_LANGUAGE;\n }\n getDisposition() {\n return {\n ...DEFAULT_TRACK_DISPOSITION,\n };\n }\n async getFirstTimestamp() {\n return 0;\n }\n async getPacketAtIndex(packetIndex, options) {\n assert(this.demuxer.audioInfo);\n const startOffset = packetIndex * PACKET_SIZE_IN_FRAMES * this.demuxer.audioInfo.blockSizeInBytes;\n if (startOffset >= this.demuxer.dataSize) {\n return null;\n }\n const sizeInBytes = Math.min(PACKET_SIZE_IN_FRAMES * this.demuxer.audioInfo.blockSizeInBytes, this.demuxer.dataSize - startOffset);\n if (this.demuxer.reader.fileSize === null) {\n // If the file size is unknown, we weren't able to cap the dataSize in the init logic and we instead have to\n // rely on the headers telling us how large the file is. But, these might be wrong, so let's check if the\n // requested slice actually exists.\n let slice = this.demuxer.reader.requestSlice(this.demuxer.dataStart + startOffset, sizeInBytes);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice) {\n return null;\n }\n }\n let data;\n if (options.metadataOnly) {\n data = PLACEHOLDER_DATA;\n }\n else {\n let slice = this.demuxer.reader.requestSlice(this.demuxer.dataStart + startOffset, sizeInBytes);\n if (slice instanceof Promise)\n slice = await slice;\n assert(slice);\n data = readBytes(slice, sizeInBytes);\n }\n const timestamp = packetIndex * PACKET_SIZE_IN_FRAMES / this.demuxer.audioInfo.sampleRate;\n const duration = sizeInBytes / this.demuxer.audioInfo.blockSizeInBytes / this.demuxer.audioInfo.sampleRate;\n this.demuxer.lastKnownPacketIndex = Math.max(packetIndex, timestamp);\n return new EncodedPacket(data, 'key', timestamp, duration, packetIndex, sizeInBytes);\n }\n getFirstPacket(options) {\n return this.getPacketAtIndex(0, options);\n }\n async getPacket(timestamp, options) {\n assert(this.demuxer.audioInfo);\n const packetIndex = Math.floor(Math.min(timestamp * this.demuxer.audioInfo.sampleRate / PACKET_SIZE_IN_FRAMES, (this.demuxer.dataSize - 1) / (PACKET_SIZE_IN_FRAMES * this.demuxer.audioInfo.blockSizeInBytes)));\n const packet = await this.getPacketAtIndex(packetIndex, options);\n if (packet) {\n return packet;\n }\n if (packetIndex === 0) {\n return null; // Empty data chunk\n }\n assert(this.demuxer.reader.fileSize === null);\n // The file is shorter than we thought, meaning the packet we were looking for doesn't exist. So, let's find\n // the last packet by doing a sequential scan, instead.\n let currentPacket = await this.getPacketAtIndex(this.demuxer.lastKnownPacketIndex, options);\n while (currentPacket) {\n const nextPacket = await this.getNextPacket(currentPacket, options);\n if (!nextPacket) {\n break;\n }\n currentPacket = nextPacket;\n }\n return currentPacket;\n }\n getNextPacket(packet, options) {\n assert(this.demuxer.audioInfo);\n const packetIndex = Math.round(packet.timestamp * this.demuxer.audioInfo.sampleRate / PACKET_SIZE_IN_FRAMES);\n return this.getPacketAtIndex(packetIndex + 1, options);\n }\n getKeyPacket(timestamp, options) {\n return this.getPacket(timestamp, options);\n }\n getNextKeyPacket(packet, options) {\n return this.getNextPacket(packet, options);\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { Bitstream } from '../misc.js';\nimport { readBytes } from '../reader.js';\nexport const MIN_FRAME_HEADER_SIZE = 7;\nexport const MAX_FRAME_HEADER_SIZE = 9;\nexport const readFrameHeader = (slice) => {\n // https://wiki.multimedia.cx/index.php/ADTS (last visited: 2025/08/17)\n const startPos = slice.filePos;\n const bytes = readBytes(slice, 9); // 9 with CRC, 7 without CRC\n const bitstream = new Bitstream(bytes);\n const syncword = bitstream.readBits(12);\n if (syncword !== 0b1111_11111111) {\n return null;\n }\n bitstream.skipBits(1); // MPEG version\n const layer = bitstream.readBits(2);\n if (layer !== 0) {\n return null;\n }\n const protectionAbsence = bitstream.readBits(1);\n const objectType = bitstream.readBits(2) + 1;\n const samplingFrequencyIndex = bitstream.readBits(4);\n if (samplingFrequencyIndex === 15) {\n return null;\n }\n bitstream.skipBits(1); // Private bit\n const channelConfiguration = bitstream.readBits(3);\n if (channelConfiguration === 0) {\n throw new Error('ADTS frames with channel configuration 0 are not supported.');\n }\n bitstream.skipBits(1); // Originality\n bitstream.skipBits(1); // Home\n bitstream.skipBits(1); // Copyright ID bit\n bitstream.skipBits(1); // Copyright ID start\n const frameLength = bitstream.readBits(13);\n bitstream.skipBits(11); // Buffer fullness\n const numberOfAacFrames = bitstream.readBits(2) + 1;\n if (numberOfAacFrames !== 1) {\n throw new Error('ADTS frames with more than one AAC frame are not supported.');\n }\n let crcCheck = null;\n if (protectionAbsence === 1) { // No CRC\n slice.filePos -= 2;\n }\n else { // CRC\n crcCheck = bitstream.readBits(16);\n }\n return {\n objectType,\n samplingFrequencyIndex,\n channelConfiguration,\n frameLength,\n numberOfAacFrames,\n crcCheck,\n startPos,\n };\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { aacChannelMap, aacFrequencyTable } from '../codec.js';\nimport { Demuxer } from '../demuxer.js';\nimport { InputAudioTrack } from '../input-track.js';\nimport { assert, AsyncMutex, binarySearchExact, binarySearchLessOrEqual, Bitstream, UNDETERMINED_LANGUAGE, } from '../misc.js';\nimport { EncodedPacket, PLACEHOLDER_DATA } from '../packet.js';\nimport { readBytes } from '../reader.js';\nimport { DEFAULT_TRACK_DISPOSITION } from '../metadata.js';\nimport { MAX_FRAME_HEADER_SIZE, MIN_FRAME_HEADER_SIZE, readFrameHeader } from './adts-reader.js';\nconst SAMPLES_PER_AAC_FRAME = 1024;\nexport class AdtsDemuxer extends Demuxer {\n constructor(input) {\n super(input);\n this.metadataPromise = null;\n this.firstFrameHeader = null;\n this.loadedSamples = [];\n this.tracks = [];\n this.readingMutex = new AsyncMutex();\n this.lastSampleLoaded = false;\n this.lastLoadedPos = 0;\n this.nextTimestampInSamples = 0;\n this.reader = input._reader;\n }\n async readMetadata() {\n return this.metadataPromise ??= (async () => {\n // Keep loading until we find the first frame header\n while (!this.firstFrameHeader && !this.lastSampleLoaded) {\n await this.advanceReader();\n }\n // There has to be a frame if this demuxer got selected\n assert(this.firstFrameHeader);\n // Create the single audio track\n this.tracks = [new InputAudioTrack(this.input, new AdtsAudioTrackBacking(this))];\n })();\n }\n async advanceReader() {\n let slice = this.reader.requestSliceRange(this.lastLoadedPos, MIN_FRAME_HEADER_SIZE, MAX_FRAME_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice) {\n this.lastSampleLoaded = true;\n return;\n }\n const header = readFrameHeader(slice);\n if (!header) {\n this.lastSampleLoaded = true;\n return;\n }\n if (this.reader.fileSize !== null && header.startPos + header.frameLength > this.reader.fileSize) {\n // Frame doesn't fit in the rest of the file\n this.lastSampleLoaded = true;\n return;\n }\n if (!this.firstFrameHeader) {\n this.firstFrameHeader = header;\n }\n const sampleRate = aacFrequencyTable[header.samplingFrequencyIndex];\n assert(sampleRate !== undefined);\n const sampleDuration = SAMPLES_PER_AAC_FRAME / sampleRate;\n const headerSize = header.crcCheck ? MAX_FRAME_HEADER_SIZE : MIN_FRAME_HEADER_SIZE;\n const sample = {\n timestamp: this.nextTimestampInSamples / sampleRate,\n duration: sampleDuration,\n dataStart: header.startPos + headerSize,\n dataSize: header.frameLength - headerSize,\n };\n this.loadedSamples.push(sample);\n this.nextTimestampInSamples += SAMPLES_PER_AAC_FRAME;\n this.lastLoadedPos = header.startPos + header.frameLength;\n }\n async getMimeType() {\n return 'audio/aac';\n }\n async getTracks() {\n await this.readMetadata();\n return this.tracks;\n }\n async computeDuration() {\n await this.readMetadata();\n const track = this.tracks[0];\n assert(track);\n return track.computeDuration();\n }\n async getMetadataTags() {\n return {}; // No tags in this one\n }\n}\nclass AdtsAudioTrackBacking {\n constructor(demuxer) {\n this.demuxer = demuxer;\n }\n getId() {\n return 1;\n }\n async getFirstTimestamp() {\n return 0;\n }\n getTimeResolution() {\n const sampleRate = this.getSampleRate();\n return sampleRate / SAMPLES_PER_AAC_FRAME;\n }\n async computeDuration() {\n const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });\n return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);\n }\n getName() {\n return null;\n }\n getLanguageCode() {\n return UNDETERMINED_LANGUAGE;\n }\n getCodec() {\n return 'aac';\n }\n getInternalCodecId() {\n assert(this.demuxer.firstFrameHeader);\n return this.demuxer.firstFrameHeader.objectType;\n }\n getNumberOfChannels() {\n assert(this.demuxer.firstFrameHeader);\n const numberOfChannels = aacChannelMap[this.demuxer.firstFrameHeader.channelConfiguration];\n assert(numberOfChannels !== undefined);\n return numberOfChannels;\n }\n getSampleRate() {\n assert(this.demuxer.firstFrameHeader);\n const sampleRate = aacFrequencyTable[this.demuxer.firstFrameHeader.samplingFrequencyIndex];\n assert(sampleRate !== undefined);\n return sampleRate;\n }\n getDisposition() {\n return {\n ...DEFAULT_TRACK_DISPOSITION,\n };\n }\n async getDecoderConfig() {\n assert(this.demuxer.firstFrameHeader);\n const bytes = new Uint8Array(3); // 19 bits max\n const bitstream = new Bitstream(bytes);\n const { objectType, samplingFrequencyIndex, channelConfiguration } = this.demuxer.firstFrameHeader;\n if (objectType > 31) {\n bitstream.writeBits(5, 31);\n bitstream.writeBits(6, objectType - 32);\n }\n else {\n bitstream.writeBits(5, objectType);\n }\n bitstream.writeBits(4, samplingFrequencyIndex); // samplingFrequencyIndex === 15 is forbidden\n bitstream.writeBits(4, channelConfiguration);\n return {\n codec: `mp4a.40.${this.demuxer.firstFrameHeader.objectType}`,\n numberOfChannels: this.getNumberOfChannels(),\n sampleRate: this.getSampleRate(),\n description: bytes.subarray(0, Math.ceil((bitstream.pos - 1) / 8)),\n };\n }\n async getPacketAtIndex(sampleIndex, options) {\n if (sampleIndex === -1) {\n return null;\n }\n const rawSample = this.demuxer.loadedSamples[sampleIndex];\n if (!rawSample) {\n return null;\n }\n let data;\n if (options.metadataOnly) {\n data = PLACEHOLDER_DATA;\n }\n else {\n let slice = this.demuxer.reader.requestSlice(rawSample.dataStart, rawSample.dataSize);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice) {\n return null; // Data didn't fit into the rest of the file\n }\n data = readBytes(slice, rawSample.dataSize);\n }\n return new EncodedPacket(data, 'key', rawSample.timestamp, rawSample.duration, sampleIndex, rawSample.dataSize);\n }\n getFirstPacket(options) {\n return this.getPacketAtIndex(0, options);\n }\n async getNextPacket(packet, options) {\n const release = await this.demuxer.readingMutex.acquire();\n try {\n const sampleIndex = binarySearchExact(this.demuxer.loadedSamples, packet.timestamp, x => x.timestamp);\n if (sampleIndex === -1) {\n throw new Error('Packet was not created from this track.');\n }\n const nextIndex = sampleIndex + 1;\n // Ensure the next sample exists\n while (nextIndex >= this.demuxer.loadedSamples.length\n && !this.demuxer.lastSampleLoaded) {\n await this.demuxer.advanceReader();\n }\n return this.getPacketAtIndex(nextIndex, options);\n }\n finally {\n release();\n }\n }\n async getPacket(timestamp, options) {\n const release = await this.demuxer.readingMutex.acquire();\n try {\n while (true) {\n const index = binarySearchLessOrEqual(this.demuxer.loadedSamples, timestamp, x => x.timestamp);\n if (index === -1 && this.demuxer.loadedSamples.length > 0) {\n // We're before the first sample\n return null;\n }\n if (this.demuxer.lastSampleLoaded) {\n // All data is loaded, return what we found\n return this.getPacketAtIndex(index, options);\n }\n if (index >= 0 && index + 1 < this.demuxer.loadedSamples.length) {\n // The next packet also exists, we're done\n return this.getPacketAtIndex(index, options);\n }\n // Otherwise, keep loading data\n await this.demuxer.advanceReader();\n }\n }\n finally {\n release();\n }\n }\n getKeyPacket(timestamp, options) {\n return this.getPacket(timestamp, options);\n }\n getNextKeyPacket(packet, options) {\n return this.getNextPacket(packet, options);\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { assert, assertNever, Bitstream } from '../misc.js';\nimport { readBytes, readU16Be, readU8 } from '../reader.js';\n// https://www.rfc-editor.org/rfc/rfc9639.html#name-block-size-bits\nexport const getBlockSizeOrUncommon = (bits) => {\n if (bits === 0b0000) {\n return null;\n }\n else if (bits === 0b0001) {\n return 192;\n }\n else if (bits >= 0b0010 && bits <= 0b0101) {\n return 144 * 2 ** bits;\n }\n else if (bits === 0b0110) {\n return 'uncommon-u8';\n }\n else if (bits === 0b0111) {\n return 'uncommon-u16';\n }\n else if (bits >= 0b1000 && bits <= 0b1111) {\n return 2 ** bits;\n }\n else {\n return null;\n }\n};\n// https://www.rfc-editor.org/rfc/rfc9639.html#name-sample-rate-bits\nexport const getSampleRateOrUncommon = (sampleRateBits, streamInfoSampleRate) => {\n switch (sampleRateBits) {\n case 0b0000: return streamInfoSampleRate;\n case 0b0001: return 88200;\n case 0b0010: return 176400;\n case 0b0011: return 192000;\n case 0b0100: return 8000;\n case 0b0101: return 16000;\n case 0b0110: return 22050;\n case 0b0111: return 24000;\n case 0b1000: return 32000;\n case 0b1001: return 44100;\n case 0b1010: return 48000;\n case 0b1011: return 96000;\n case 0b1100: return 'uncommon-u8';\n case 0b1101: return 'uncommon-u16';\n case 0b1110: return 'uncommon-u16-10';\n default: return null;\n }\n};\n// https://www.rfc-editor.org/rfc/rfc9639.html#name-coded-number\nexport const readCodedNumber = (fileSlice) => {\n let ones = 0;\n const bitstream1 = new Bitstream(readBytes(fileSlice, 1));\n while (bitstream1.readBits(1) === 1) {\n ones++;\n }\n if (ones === 0) {\n return bitstream1.readBits(7);\n }\n const bitArray = [];\n const extraBytes = ones - 1;\n const bitstream2 = new Bitstream(readBytes(fileSlice, extraBytes));\n const firstByteBits = 8 - ones - 1;\n for (let i = 0; i < firstByteBits; i++) {\n bitArray.unshift(bitstream1.readBits(1));\n }\n for (let i = 0; i < extraBytes; i++) {\n for (let j = 0; j < 8; j++) {\n const val = bitstream2.readBits(1);\n if (j < 2) {\n continue;\n }\n bitArray.unshift(val);\n }\n }\n const encoded = bitArray.reduce((acc, bit, index) => {\n return acc | (bit << index);\n }, 0);\n return encoded;\n};\nexport const readBlockSize = (slice, blockSizeBits) => {\n if (blockSizeBits === 'uncommon-u16') {\n return readU16Be(slice) + 1;\n }\n else if (blockSizeBits === 'uncommon-u8') {\n return readU8(slice) + 1;\n }\n else if (typeof blockSizeBits === 'number') {\n return blockSizeBits;\n }\n else {\n assertNever(blockSizeBits);\n assert(false);\n }\n};\nexport const readSampleRate = (slice, sampleRateOrUncommon) => {\n if (sampleRateOrUncommon === 'uncommon-u16') {\n return readU16Be(slice);\n }\n if (sampleRateOrUncommon === 'uncommon-u16-10') {\n return readU16Be(slice) * 10;\n }\n if (sampleRateOrUncommon === 'uncommon-u8') {\n return readU8(slice);\n }\n if (typeof sampleRateOrUncommon === 'number') {\n return sampleRateOrUncommon;\n }\n return null;\n};\n// https://www.rfc-editor.org/rfc/rfc9639.html#section-9.1.1\nexport const calculateCrc8 = (data) => {\n const polynomial = 0x07; // x^8 + x^2 + x^1 + x^0\n let crc = 0x00; // Initialize CRC to 0\n for (const byte of data) {\n crc ^= byte; // XOR byte into least significant byte of crc\n for (let i = 0; i < 8; i++) {\n // For each bit in the byte\n if ((crc & 0x80) !== 0) {\n // If the leftmost bit (MSB) is set\n crc = (crc << 1) ^ polynomial; // Shift left and XOR with polynomial\n }\n else {\n crc <<= 1; // Just shift left\n }\n crc &= 0xff; // Ensure CRC remains 8-bit\n }\n }\n return crc;\n};\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { FlacBlockType, readVorbisComments } from '../codec-data.js';\nimport { Demuxer } from '../demuxer.js';\nimport { InputAudioTrack } from '../input-track.js';\nimport { assert, AsyncMutex, binarySearchLessOrEqual, Bitstream, textDecoder, UNDETERMINED_LANGUAGE, } from '../misc.js';\nimport { EncodedPacket, PLACEHOLDER_DATA } from '../packet.js';\nimport { readBytes, readU24Be, readU32Be, readU8, } from '../reader.js';\nimport { DEFAULT_TRACK_DISPOSITION } from '../metadata.js';\nimport { calculateCrc8, readBlockSize, getBlockSizeOrUncommon, readCodedNumber, readSampleRate, getSampleRateOrUncommon, } from './flac-misc.js';\nexport class FlacDemuxer extends Demuxer {\n constructor(input) {\n super(input);\n this.loadedSamples = []; // All samples from the start of the file to lastLoadedPos\n this.metadataPromise = null;\n this.track = null;\n this.metadataTags = {};\n this.audioInfo = null;\n this.lastLoadedPos = null;\n this.blockingBit = null;\n this.readingMutex = new AsyncMutex();\n this.lastSampleLoaded = false;\n this.reader = input._reader;\n }\n async computeDuration() {\n await this.readMetadata();\n assert(this.track);\n return this.track.computeDuration();\n }\n async getMetadataTags() {\n await this.readMetadata();\n return this.metadataTags;\n }\n async getTracks() {\n await this.readMetadata();\n assert(this.track);\n return [this.track];\n }\n async getMimeType() {\n return 'audio/flac';\n }\n async readMetadata() {\n let currentPos = 4; // Skip 'fLaC'\n return (this.metadataPromise ??= (async () => {\n while (this.reader.fileSize === null\n || currentPos < this.reader.fileSize) {\n let sizeSlice = this.reader.requestSlice(currentPos, 4);\n if (sizeSlice instanceof Promise)\n sizeSlice = await sizeSlice;\n currentPos += 4;\n if (sizeSlice === null) {\n throw new Error(`Metadata block at position ${currentPos} is too small! Corrupted file.`);\n }\n assert(sizeSlice);\n const byte = readU8(sizeSlice); // first bit: isLastMetadata, remaining 7 bits: metaBlockType\n const size = readU24Be(sizeSlice);\n const isLastMetadata = (byte & 0x80) !== 0;\n const metaBlockType = byte & 0x7f;\n switch (metaBlockType) {\n case FlacBlockType.STREAMINFO: {\n // Parse streaminfo block\n // https://www.rfc-editor.org/rfc/rfc9639.html#section-8.2\n let streamInfoBlock = this.reader.requestSlice(currentPos, size);\n if (streamInfoBlock instanceof Promise)\n streamInfoBlock = await streamInfoBlock;\n assert(streamInfoBlock);\n if (streamInfoBlock === null) {\n throw new Error(`StreamInfo block at position ${currentPos} is too small! Corrupted file.`);\n }\n const streamInfoBytes = readBytes(streamInfoBlock, 34);\n const bitstream = new Bitstream(streamInfoBytes);\n const minimumBlockSize = bitstream.readBits(16);\n const maximumBlockSize = bitstream.readBits(16);\n const minimumFrameSize = bitstream.readBits(24);\n const maximumFrameSize = bitstream.readBits(24);\n const sampleRate = bitstream.readBits(20);\n const numberOfChannels = bitstream.readBits(3) + 1;\n bitstream.readBits(5); // bitsPerSample - 1\n const totalSamples = bitstream.readBits(36);\n // https://www.w3.org/TR/webcodecs-flac-codec-registration/#audiodecoderconfig-description\n // description is required, and has to be the following:\n // 1. The bytes 0x66 0x4C 0x61 0x43 (\"fLaC\" in ASCII)\n // 2. A metadata block (called the STREAMINFO block) as described in section 7 of [FLAC]\n // 3. Optionaly (sic) other metadata blocks, that are not used by the specification\n bitstream.skipBits(16 * 8); // md5 hash\n const description = new Uint8Array(42);\n // 1. \"fLaC\"\n description.set(new Uint8Array([0x66, 0x4c, 0x61, 0x43]), 0);\n // 2. STREAMINFO block\n description.set(new Uint8Array([128, 0, 0, 34]), 4);\n // 3. Other metadata blocks\n description.set(streamInfoBytes, 8);\n this.audioInfo = {\n numberOfChannels,\n sampleRate,\n totalSamples,\n minimumBlockSize,\n maximumBlockSize,\n minimumFrameSize,\n maximumFrameSize,\n description,\n };\n this.track = new InputAudioTrack(this.input, new FlacAudioTrackBacking(this));\n break;\n }\n case FlacBlockType.VORBIS_COMMENT: {\n // Parse vorbis comment block\n // https://www.rfc-editor.org/rfc/rfc9639.html#name-vorbis-comment\n let vorbisCommentBlock = this.reader.requestSlice(currentPos, size);\n if (vorbisCommentBlock instanceof Promise)\n vorbisCommentBlock = await vorbisCommentBlock;\n assert(vorbisCommentBlock);\n readVorbisComments(readBytes(vorbisCommentBlock, size), this.metadataTags);\n break;\n }\n case FlacBlockType.PICTURE: {\n // Parse picture block\n // https://www.rfc-editor.org/rfc/rfc9639.html#name-picture\n let pictureBlock = this.reader.requestSlice(currentPos, size);\n if (pictureBlock instanceof Promise)\n pictureBlock = await pictureBlock;\n assert(pictureBlock);\n const pictureType = readU32Be(pictureBlock);\n const mediaTypeLength = readU32Be(pictureBlock);\n const mediaType = textDecoder.decode(readBytes(pictureBlock, mediaTypeLength));\n const descriptionLength = readU32Be(pictureBlock);\n const description = textDecoder.decode(readBytes(pictureBlock, descriptionLength));\n pictureBlock.skip(4 + 4 + 4 + 4); // Skip width, height, color depth, number of indexed colors\n const dataLength = readU32Be(pictureBlock);\n const data = readBytes(pictureBlock, dataLength);\n this.metadataTags.images ??= [];\n this.metadataTags.images.push({\n data,\n mimeType: mediaType,\n // https://www.rfc-editor.org/rfc/rfc9639.html#table13\n kind: pictureType === 3\n ? 'coverFront'\n : pictureType === 4\n ? 'coverBack'\n : 'unknown',\n description,\n });\n break;\n }\n default:\n break;\n }\n currentPos += size;\n if (isLastMetadata) {\n this.lastLoadedPos = currentPos;\n break;\n }\n }\n })());\n }\n async readNextFlacFrame({ startPos, isFirstPacket, }) {\n assert(this.audioInfo);\n // we expect that there are at least `minimumFrameSize` bytes left in the file\n // Ideally we also want to validate the next header is valid\n // to throw out an accidential sync word\n // The shortest valid FLAC header I can think of, based off the code\n // of readFlacFrameHeader:\n // 4 bytes used for bitstream from syncword to bit depth\n // 1 byte coded number\n // (uncommon values, no bytes read)\n // 1 byte crc\n // --> 6 bytes\n const minimumHeaderLength = 6;\n // If we read everything in readFlacFrameHeader, we read 16 bytes\n const maximumHeaderSize = 16;\n const maximumSliceLength = this.audioInfo.maximumFrameSize + maximumHeaderSize;\n const slice = await this.reader.requestSliceRange(startPos, this.audioInfo.minimumFrameSize, maximumSliceLength);\n if (!slice) {\n return null;\n }\n const frameHeader = this.readFlacFrameHeader({\n slice,\n isFirstPacket: isFirstPacket,\n });\n if (!frameHeader) {\n return null;\n }\n // We don't know exactly how long the packet is, we only know the `minimumFrameSize` and `maximumFrameSize`\n // The packet is over if the next 2 bytes are the sync word followed by a valid header\n // or the end of the file is reached\n // The next sync word is expected at earliest when `minimumFrameSize` is reached,\n // we can skip over anything before that\n slice.filePos = startPos + this.audioInfo.minimumFrameSize;\n while (true) {\n // Reached end of the file, packet is over\n if (slice.filePos > slice.end - minimumHeaderLength) {\n return {\n num: frameHeader.num,\n blockSize: frameHeader.blockSize,\n sampleRate: frameHeader.sampleRate,\n size: slice.end - startPos,\n isLastFrame: true,\n };\n }\n const nextByte = readU8(slice);\n if (nextByte === 0xff) {\n const positionBeforeReading = slice.filePos;\n const byteAfterNextByte = readU8(slice);\n const expected = this.blockingBit === 1 ? 0b1111_1001 : 0b1111_1000;\n if (byteAfterNextByte !== expected) {\n slice.filePos = positionBeforeReading;\n continue;\n }\n slice.skip(-2);\n const lengthIfNextFlacFrameHeaderIsLegit = slice.filePos - startPos;\n const nextFrameHeader = this.readFlacFrameHeader({\n slice,\n isFirstPacket: false,\n });\n if (!nextFrameHeader) {\n slice.filePos = positionBeforeReading;\n continue;\n }\n // Ensure the frameOrSampleNum is consecutive.\n // https://github.com/Vanilagy/mediabunny/issues/194\n if (this.blockingBit === 0) {\n // Case A: If the stream is fixed block size, this is the frame number, which increments by 1\n if (nextFrameHeader.num - frameHeader.num !== 1) {\n slice.filePos = positionBeforeReading;\n continue;\n }\n }\n else {\n // Case B: If the stream is variable block size, this is the sample number, which increments by\n // amount of samples in a frame.\n if (nextFrameHeader.num - frameHeader.num !== frameHeader.blockSize) {\n slice.filePos = positionBeforeReading;\n continue;\n }\n }\n return {\n num: frameHeader.num,\n blockSize: frameHeader.blockSize,\n sampleRate: frameHeader.sampleRate,\n size: lengthIfNextFlacFrameHeaderIsLegit,\n isLastFrame: false,\n };\n }\n }\n }\n readFlacFrameHeader({ slice, isFirstPacket, }) {\n // In this function, generally it is not safe to throw errors.\n // We might end up here because we stumbled upon a syncword,\n // but the data might not actually be a FLAC frame, it might be random bitstream\n // data, in that case we should return null and continue.\n const startOffset = slice.filePos;\n // https://www.rfc-editor.org/rfc/rfc9639.html#section-9.1\n // Each frame MUST start on a byte boundary and start with the 15-bit frame\n // sync code 0b111111111111100. Following the sync code is the blocking strategy\n // bit, which MUST NOT change during the audio stream.\n const bytes = readBytes(slice, 4);\n const bitstream = new Bitstream(bytes);\n const bits = bitstream.readBits(15);\n if (bits !== 0b111111111111100) {\n // This cannot be a valid FLAC frame, must start with the syncword\n return null;\n }\n if (this.blockingBit === null) {\n assert(isFirstPacket);\n const newBlockingBit = bitstream.readBits(1);\n this.blockingBit = newBlockingBit;\n }\n else if (this.blockingBit === 1) {\n assert(!isFirstPacket);\n const newBlockingBit = bitstream.readBits(1);\n if (newBlockingBit !== 1) {\n // This cannot be a valid FLAC frame, expected 1 but got 0\n return null;\n }\n }\n else if (this.blockingBit === 0) {\n assert(!isFirstPacket);\n const newBlockingBit = bitstream.readBits(1);\n if (newBlockingBit !== 0) {\n // This cannot be a valid FLAC frame, expected 0 but got 1\n return null;\n }\n }\n else {\n throw new Error('Invalid blocking bit');\n }\n const blockSizeOrUncommon = getBlockSizeOrUncommon(bitstream.readBits(4));\n if (!blockSizeOrUncommon) {\n // This cannot be a valid FLAC frame, the syncword was just coincidental\n return null;\n }\n assert(this.audioInfo);\n const sampleRateOrUncommon = getSampleRateOrUncommon(bitstream.readBits(4), this.audioInfo.sampleRate);\n if (!sampleRateOrUncommon) {\n // This cannot be a valid FLAC frame, the syncword was just coincidental\n return null;\n }\n bitstream.readBits(4); // channel count\n bitstream.readBits(3); // bit depth\n const reservedZero = bitstream.readBits(1); // reserved zero\n if (reservedZero !== 0) {\n // This cannot be a valid FLAC frame, the syncword was just coincidental\n return null;\n }\n const num = readCodedNumber(slice);\n const blockSize = readBlockSize(slice, blockSizeOrUncommon);\n const sampleRate = readSampleRate(slice, sampleRateOrUncommon);\n if (sampleRate === null) {\n // This cannot be a valid FLAC frame, the syncword was just coincidental\n return null;\n }\n if (sampleRate !== this.audioInfo.sampleRate) {\n // This cannot be a valid FLAC frame, the sample rate is not the same as in the stream info\n return null;\n }\n const size = slice.filePos - startOffset;\n const crc = readU8(slice);\n slice.skip(-size);\n slice.skip(-1);\n const crcCalculated = calculateCrc8(readBytes(slice, size));\n if (crc !== crcCalculated) {\n // Maybe this wasn't a FLAC frame at all, the syncword was just coincidentally\n // in the bitstream\n return null;\n }\n return { num, blockSize, sampleRate };\n }\n async advanceReader() {\n await this.readMetadata();\n assert(this.lastLoadedPos !== null);\n assert(this.audioInfo);\n const startPos = this.lastLoadedPos;\n const frame = await this.readNextFlacFrame({\n startPos,\n isFirstPacket: this.loadedSamples.length === 0,\n });\n if (!frame) {\n // Unexpected case, failed to read next FLAC frame\n // handling gracefully\n this.lastSampleLoaded = true;\n return;\n }\n const lastSample = this.loadedSamples[this.loadedSamples.length - 1];\n const blockOffset = lastSample\n ? lastSample.blockOffset + lastSample.blockSize\n : 0;\n const sample = {\n blockOffset,\n blockSize: frame.blockSize,\n byteOffset: startPos,\n byteSize: frame.size,\n };\n this.lastLoadedPos = this.lastLoadedPos + frame.size;\n this.loadedSamples.push(sample);\n if (frame.isLastFrame) {\n this.lastSampleLoaded = true;\n return;\n }\n }\n}\nclass FlacAudioTrackBacking {\n constructor(demuxer) {\n this.demuxer = demuxer;\n }\n getId() {\n return 1;\n }\n getCodec() {\n return 'flac';\n }\n getInternalCodecId() {\n return null;\n }\n getNumberOfChannels() {\n assert(this.demuxer.audioInfo);\n return this.demuxer.audioInfo.numberOfChannels;\n }\n async computeDuration() {\n const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });\n return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);\n }\n getSampleRate() {\n assert(this.demuxer.audioInfo);\n return this.demuxer.audioInfo.sampleRate;\n }\n getName() {\n return null;\n }\n getLanguageCode() {\n return UNDETERMINED_LANGUAGE;\n }\n getTimeResolution() {\n assert(this.demuxer.audioInfo);\n return this.demuxer.audioInfo.sampleRate;\n }\n getDisposition() {\n return {\n ...DEFAULT_TRACK_DISPOSITION,\n };\n }\n async getFirstTimestamp() {\n return 0;\n }\n async getDecoderConfig() {\n assert(this.demuxer.audioInfo);\n return {\n codec: 'flac',\n numberOfChannels: this.demuxer.audioInfo.numberOfChannels,\n sampleRate: this.demuxer.audioInfo.sampleRate,\n description: this.demuxer.audioInfo.description,\n };\n }\n async getPacket(timestamp, options) {\n assert(this.demuxer.audioInfo);\n if (timestamp < 0) {\n throw new Error('Timestamp cannot be negative');\n }\n const release = await this.demuxer.readingMutex.acquire();\n try {\n while (true) {\n const packetIndex = binarySearchLessOrEqual(this.demuxer.loadedSamples, timestamp, x => x.blockOffset / this.demuxer.audioInfo.sampleRate);\n if (packetIndex === -1) {\n await this.demuxer.advanceReader();\n continue;\n }\n const packet = this.demuxer.loadedSamples[packetIndex];\n const sampleTimestamp = packet.blockOffset / this.demuxer.audioInfo.sampleRate;\n const sampleDuration = packet.blockSize / this.demuxer.audioInfo.sampleRate;\n if (sampleTimestamp + sampleDuration <= timestamp) {\n if (this.demuxer.lastSampleLoaded) {\n return this.getPacketAtIndex(this.demuxer.loadedSamples.length - 1, options);\n }\n await this.demuxer.advanceReader();\n continue;\n }\n return this.getPacketAtIndex(packetIndex, options);\n }\n }\n finally {\n release();\n }\n }\n async getNextPacket(packet, options) {\n const release = await this.demuxer.readingMutex.acquire();\n try {\n const nextIndex = packet.sequenceNumber + 1;\n if (this.demuxer.lastSampleLoaded\n && nextIndex >= this.demuxer.loadedSamples.length) {\n return null;\n }\n // Ensure the next sample exists\n while (nextIndex >= this.demuxer.loadedSamples.length\n && !this.demuxer.lastSampleLoaded) {\n await this.demuxer.advanceReader();\n }\n return this.getPacketAtIndex(nextIndex, options);\n }\n finally {\n release();\n }\n }\n getKeyPacket(timestamp, options) {\n return this.getPacket(timestamp, options);\n }\n getNextKeyPacket(packet, options) {\n return this.getNextPacket(packet, options);\n }\n async getPacketAtIndex(sampleIndex, options) {\n const rawSample = this.demuxer.loadedSamples[sampleIndex];\n if (!rawSample) {\n return null;\n }\n let data;\n if (options.metadataOnly) {\n data = PLACEHOLDER_DATA;\n }\n else {\n let slice = this.demuxer.reader.requestSlice(rawSample.byteOffset, rawSample.byteSize);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice) {\n return null; // Data didn't fit into the rest of the file\n }\n data = readBytes(slice, rawSample.byteSize);\n }\n assert(this.demuxer.audioInfo);\n const timestamp = rawSample.blockOffset / this.demuxer.audioInfo.sampleRate;\n const duration = rawSample.blockSize / this.demuxer.audioInfo.sampleRate;\n return new EncodedPacket(data, 'key', timestamp, duration, sampleIndex, rawSample.byteSize);\n }\n async getFirstPacket(options) {\n // Ensure the next sample exists\n while (this.demuxer.loadedSamples.length === 0\n && !this.demuxer.lastSampleLoaded) {\n await this.demuxer.advanceReader();\n }\n return this.getPacketAtIndex(0, options);\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { IsobmffDemuxer } from './isobmff/isobmff-demuxer.js';\nimport { EBMLId, MAX_HEADER_SIZE, MIN_HEADER_SIZE, readAsciiString, readElementHeader, readElementSize, readUnsignedInt, readVarIntSize, } from './matroska/ebml.js';\nimport { MatroskaDemuxer } from './matroska/matroska-demuxer.js';\nimport { Mp3Demuxer } from './mp3/mp3-demuxer.js';\nimport { FRAME_HEADER_SIZE } from '../shared/mp3-misc.js';\nimport { ID3_V2_HEADER_SIZE, readId3V2Header } from './id3.js';\nimport { readNextFrameHeader } from './mp3/mp3-reader.js';\nimport { OggDemuxer } from './ogg/ogg-demuxer.js';\nimport { WaveDemuxer } from './wave/wave-demuxer.js';\nimport { MAX_FRAME_HEADER_SIZE, MIN_FRAME_HEADER_SIZE, readFrameHeader } from './adts/adts-reader.js';\nimport { AdtsDemuxer } from './adts/adts-demuxer.js';\nimport { readAscii } from './reader.js';\nimport { FlacDemuxer } from './flac/flac-demuxer.js';\n/**\n * Base class representing an input media file format.\n * @group Input formats\n * @public\n */\nexport class InputFormat {\n}\n/**\n * Format representing files compatible with the ISO base media file format (ISOBMFF), like MP4 or MOV files.\n * @group Input formats\n * @public\n */\nexport class IsobmffInputFormat extends InputFormat {\n /** @internal */\n async _getMajorBrand(input) {\n let slice = input._reader.requestSlice(0, 12);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return null;\n slice.skip(4);\n const fourCc = readAscii(slice, 4);\n if (fourCc !== 'ftyp') {\n return null;\n }\n return readAscii(slice, 4);\n }\n /** @internal */\n _createDemuxer(input) {\n return new IsobmffDemuxer(input);\n }\n}\n/**\n * MPEG-4 Part 14 (MP4) file format.\n *\n * Do not instantiate this class; use the {@link MP4} singleton instead.\n *\n * @group Input formats\n * @public\n */\nexport class Mp4InputFormat extends IsobmffInputFormat {\n /** @internal */\n async _canReadInput(input) {\n const majorBrand = await this._getMajorBrand(input);\n return !!majorBrand && majorBrand !== 'qt ';\n }\n get name() {\n return 'MP4';\n }\n get mimeType() {\n return 'video/mp4';\n }\n}\n/**\n * QuickTime File Format (QTFF), often called MOV.\n *\n * Do not instantiate this class; use the {@link QTFF} singleton instead.\n *\n * @group Input formats\n * @public\n */\nexport class QuickTimeInputFormat extends IsobmffInputFormat {\n /** @internal */\n async _canReadInput(input) {\n const majorBrand = await this._getMajorBrand(input);\n return majorBrand === 'qt ';\n }\n get name() {\n return 'QuickTime File Format';\n }\n get mimeType() {\n return 'video/quicktime';\n }\n}\n/**\n * Matroska file format.\n *\n * Do not instantiate this class; use the {@link MATROSKA} singleton instead.\n *\n * @group Input formats\n * @public\n */\nexport class MatroskaInputFormat extends InputFormat {\n /** @internal */\n async isSupportedEBMLOfDocType(input, desiredDocType) {\n let headerSlice = input._reader.requestSlice(0, MAX_HEADER_SIZE);\n if (headerSlice instanceof Promise)\n headerSlice = await headerSlice;\n if (!headerSlice)\n return false;\n const varIntSize = readVarIntSize(headerSlice);\n if (varIntSize === null) {\n return false;\n }\n if (varIntSize < 1 || varIntSize > 8) {\n return false;\n }\n const id = readUnsignedInt(headerSlice, varIntSize);\n if (id !== EBMLId.EBML) {\n return false;\n }\n const dataSize = readElementSize(headerSlice);\n if (dataSize === null) {\n return false; // Miss me with that shit\n }\n let dataSlice = input._reader.requestSlice(headerSlice.filePos, dataSize);\n if (dataSlice instanceof Promise)\n dataSlice = await dataSlice;\n if (!dataSlice)\n return false;\n const startPos = headerSlice.filePos;\n while (dataSlice.filePos <= startPos + dataSize - MIN_HEADER_SIZE) {\n const header = readElementHeader(dataSlice);\n if (!header)\n break;\n const { id, size } = header;\n const dataStartPos = dataSlice.filePos;\n if (size === null)\n return false;\n switch (id) {\n case EBMLId.EBMLVersion:\n {\n const ebmlVersion = readUnsignedInt(dataSlice, size);\n if (ebmlVersion !== 1) {\n return false;\n }\n }\n ;\n break;\n case EBMLId.EBMLReadVersion:\n {\n const ebmlReadVersion = readUnsignedInt(dataSlice, size);\n if (ebmlReadVersion !== 1) {\n return false;\n }\n }\n ;\n break;\n case EBMLId.DocType:\n {\n const docType = readAsciiString(dataSlice, size);\n if (docType !== desiredDocType) {\n return false;\n }\n }\n ;\n break;\n case EBMLId.DocTypeVersion:\n {\n const docTypeVersion = readUnsignedInt(dataSlice, size);\n if (docTypeVersion > 4) { // Support up to Matroska v4\n return false;\n }\n }\n ;\n break;\n }\n dataSlice.filePos = dataStartPos + size;\n }\n return true;\n }\n /** @internal */\n _canReadInput(input) {\n return this.isSupportedEBMLOfDocType(input, 'matroska');\n }\n /** @internal */\n _createDemuxer(input) {\n return new MatroskaDemuxer(input);\n }\n get name() {\n return 'Matroska';\n }\n get mimeType() {\n return 'video/x-matroska';\n }\n}\n/**\n * WebM file format, based on Matroska.\n *\n * Do not instantiate this class; use the {@link WEBM} singleton instead.\n *\n * @group Input formats\n * @public\n */\nexport class WebMInputFormat extends MatroskaInputFormat {\n /** @internal */\n _canReadInput(input) {\n return this.isSupportedEBMLOfDocType(input, 'webm');\n }\n get name() {\n return 'WebM';\n }\n get mimeType() {\n return 'video/webm';\n }\n}\n/**\n * MP3 file format.\n *\n * Do not instantiate this class; use the {@link MP3} singleton instead.\n *\n * @group Input formats\n * @public\n */\nexport class Mp3InputFormat extends InputFormat {\n /** @internal */\n async _canReadInput(input) {\n let slice = input._reader.requestSlice(0, 10);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return false;\n let currentPos = 0;\n let id3V2HeaderFound = false;\n while (true) {\n let slice = input._reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n break;\n const id3V2Header = readId3V2Header(slice);\n if (!id3V2Header) {\n break;\n }\n id3V2HeaderFound = true;\n currentPos = slice.filePos + id3V2Header.size;\n }\n const firstResult = await readNextFrameHeader(input._reader, currentPos, currentPos + 4096);\n if (!firstResult) {\n return false;\n }\n if (id3V2HeaderFound) {\n // If there was an ID3v2 tag at the start, we can be pretty sure this is MP3 by now\n return true;\n }\n currentPos = firstResult.startPos + firstResult.header.totalSize;\n // Fine, we found one frame header, but we're still not entirely sure this is MP3. Let's check if we can find\n // another header right after it:\n const secondResult = await readNextFrameHeader(input._reader, currentPos, currentPos + FRAME_HEADER_SIZE);\n if (!secondResult) {\n return false;\n }\n const firstHeader = firstResult.header;\n const secondHeader = secondResult.header;\n // In a well-formed MP3 file, we'd expect these two frames to share some similarities:\n if (firstHeader.channel !== secondHeader.channel || firstHeader.sampleRate !== secondHeader.sampleRate) {\n return false;\n }\n // We have found two matching consecutive MP3 frames, a strong indicator that this is an MP3 file\n return true;\n }\n /** @internal */\n _createDemuxer(input) {\n return new Mp3Demuxer(input);\n }\n get name() {\n return 'MP3';\n }\n get mimeType() {\n return 'audio/mpeg';\n }\n}\n/**\n * WAVE file format, based on RIFF.\n *\n * Do not instantiate this class; use the {@link WAVE} singleton instead.\n *\n * @group Input formats\n * @public\n */\nexport class WaveInputFormat extends InputFormat {\n /** @internal */\n async _canReadInput(input) {\n let slice = input._reader.requestSlice(0, 12);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return false;\n const riffType = readAscii(slice, 4);\n if (riffType !== 'RIFF' && riffType !== 'RIFX' && riffType !== 'RF64') {\n return false;\n }\n slice.skip(4);\n const format = readAscii(slice, 4);\n return format === 'WAVE';\n }\n /** @internal */\n _createDemuxer(input) {\n return new WaveDemuxer(input);\n }\n get name() {\n return 'WAVE';\n }\n get mimeType() {\n return 'audio/wav';\n }\n}\n/**\n * Ogg file format.\n *\n * Do not instantiate this class; use the {@link OGG} singleton instead.\n *\n * @group Input formats\n * @public\n */\nexport class OggInputFormat extends InputFormat {\n /** @internal */\n async _canReadInput(input) {\n let slice = input._reader.requestSlice(0, 4);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return false;\n return readAscii(slice, 4) === 'OggS';\n }\n /** @internal */\n _createDemuxer(input) {\n return new OggDemuxer(input);\n }\n get name() {\n return 'Ogg';\n }\n get mimeType() {\n return 'application/ogg';\n }\n}\n/**\n * FLAC file format.\n *\n * Do not instantiate this class; use the {@link FLAC} singleton instead.\n *\n * @group Input formats\n * @public\n */\nexport class FlacInputFormat extends InputFormat {\n /** @internal */\n async _canReadInput(input) {\n let slice = input._reader.requestSlice(0, 4);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return false;\n return readAscii(slice, 4) === 'fLaC';\n }\n get name() {\n return 'FLAC';\n }\n get mimeType() {\n return 'audio/flac';\n }\n /** @internal */\n _createDemuxer(input) {\n return new FlacDemuxer(input);\n }\n}\n/**\n * ADTS file format.\n *\n * Do not instantiate this class; use the {@link ADTS} singleton instead.\n *\n * @group Input formats\n * @public\n */\nexport class AdtsInputFormat extends InputFormat {\n /** @internal */\n async _canReadInput(input) {\n let slice = input._reader.requestSliceRange(0, MIN_FRAME_HEADER_SIZE, MAX_FRAME_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return false;\n const firstHeader = readFrameHeader(slice);\n if (!firstHeader) {\n return false;\n }\n slice = input._reader.requestSliceRange(firstHeader.frameLength, MIN_FRAME_HEADER_SIZE, MAX_FRAME_HEADER_SIZE);\n if (slice instanceof Promise)\n slice = await slice;\n if (!slice)\n return false;\n const secondHeader = readFrameHeader(slice);\n if (!secondHeader) {\n return false;\n }\n return firstHeader.objectType === secondHeader.objectType\n && firstHeader.samplingFrequencyIndex === secondHeader.samplingFrequencyIndex\n && firstHeader.channelConfiguration === secondHeader.channelConfiguration;\n }\n /** @internal */\n _createDemuxer(input) {\n return new AdtsDemuxer(input);\n }\n get name() {\n return 'ADTS';\n }\n get mimeType() {\n return 'audio/aac';\n }\n}\n/**\n * MP4 input format singleton.\n * @group Input formats\n * @public\n */\nexport const MP4 = /* #__PURE__ */ new Mp4InputFormat();\n/**\n * QuickTime File Format input format singleton.\n * @group Input formats\n * @public\n */\nexport const QTFF = /* #__PURE__ */ new QuickTimeInputFormat();\n/**\n * Matroska input format singleton.\n * @group Input formats\n * @public\n */\nexport const MATROSKA = /* #__PURE__ */ new MatroskaInputFormat();\n/**\n * WebM input format singleton.\n * @group Input formats\n * @public\n */\nexport const WEBM = /* #__PURE__ */ new WebMInputFormat();\n/**\n * MP3 input format singleton.\n * @group Input formats\n * @public\n */\nexport const MP3 = /* #__PURE__ */ new Mp3InputFormat();\n/**\n * WAVE input format singleton.\n * @group Input formats\n * @public\n */\nexport const WAVE = /* #__PURE__ */ new WaveInputFormat();\n/**\n * Ogg input format singleton.\n * @group Input formats\n * @public\n */\nexport const OGG = /* #__PURE__ */ new OggInputFormat();\n/**\n * ADTS input format singleton.\n * @group Input formats\n * @public\n */\nexport const ADTS = /* #__PURE__ */ new AdtsInputFormat();\n/**\n * FLAC input format singleton.\n * @group Input formats\n * @public\n */\nexport const FLAC = /* #__PURE__ */ new FlacInputFormat();\n/**\n * List of all input format singletons. If you don't need to support all input formats, you should specify the\n * formats individually for better tree shaking.\n * @group Input formats\n * @public\n */\nexport const ALL_FORMATS = [MP4, QTFF, MATROSKA, WEBM, WAVE, OGG, FLAC, MP3, ADTS];\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { assert, binarySearchLessOrEqual, closedIntervalsOverlap, isNumber, isWebKit, mergeRequestInit, promiseWithResolvers, retriedFetch, toDataView, toUint8Array, } from './misc.js';\nimport * as nodeAlias from './node.js';\nimport { InputDisposedError } from './input.js';\nconst node = typeof nodeAlias !== 'undefined'\n ? nodeAlias // Aliasing it prevents some bundler warnings\n : undefined;\n/**\n * The source base class, representing a resource from which bytes can be read.\n * @group Input sources\n * @public\n */\nexport class Source {\n constructor() {\n /** @internal */\n this._disposed = false;\n /** @internal */\n this._sizePromise = null;\n /** Called each time data is retrieved from the source. Will be called with the retrieved range (end exclusive). */\n this.onread = null;\n }\n /**\n * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call\n * will retrieve the size.\n *\n * Returns null if the source is unsized.\n */\n async getSizeOrNull() {\n if (this._disposed) {\n throw new InputDisposedError();\n }\n return this._sizePromise ??= Promise.resolve(this._retrieveSize());\n }\n /**\n * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call\n * will retrieve the size.\n *\n * Throws an error if the source is unsized.\n */\n async getSize() {\n if (this._disposed) {\n throw new InputDisposedError();\n }\n const result = await this.getSizeOrNull();\n if (result === null) {\n throw new Error('Cannot determine the size of an unsized source.');\n }\n return result;\n }\n}\n/**\n * A source backed by an ArrayBuffer or ArrayBufferView, with the entire file held in memory.\n * @group Input sources\n * @public\n */\nexport class BufferSource extends Source {\n /**\n * Creates a new {@link BufferSource} backed by the specified `ArrayBuffer`, `SharedArrayBuffer`,\n * or `ArrayBufferView`.\n */\n constructor(buffer) {\n if (!(buffer instanceof ArrayBuffer)\n && !(typeof SharedArrayBuffer !== 'undefined' && buffer instanceof SharedArrayBuffer)\n && !ArrayBuffer.isView(buffer)) {\n throw new TypeError('buffer must be an ArrayBuffer, SharedArrayBuffer, or ArrayBufferView.');\n }\n super();\n /** @internal */\n this._onreadCalled = false;\n this._bytes = toUint8Array(buffer);\n this._view = toDataView(buffer);\n }\n /** @internal */\n _retrieveSize() {\n return this._bytes.byteLength;\n }\n /** @internal */\n _read() {\n if (!this._onreadCalled) {\n // We just say the first read retrives all bytes from the source (which, I mean, it does)\n this.onread?.(0, this._bytes.byteLength);\n this._onreadCalled = true;\n }\n return {\n bytes: this._bytes,\n view: this._view,\n offset: 0,\n };\n }\n /** @internal */\n _dispose() { }\n}\n/**\n * A source backed by a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob). Since a\n * [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) is also a `Blob`, this is the source to use when\n * reading files off the disk.\n * @group Input sources\n * @public\n */\nexport class BlobSource extends Source {\n /**\n * Creates a new {@link BlobSource} backed by the specified\n * [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n */\n constructor(blob, options = {}) {\n if (!(blob instanceof Blob)) {\n throw new TypeError('blob must be a Blob.');\n }\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (options.maxCacheSize !== undefined\n && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {\n throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');\n }\n super();\n /** @internal */\n this._readers = new WeakMap();\n this._blob = blob;\n this._orchestrator = new ReadOrchestrator({\n maxCacheSize: options.maxCacheSize ?? (8 * 2 ** 20 /* 8 MiB */),\n maxWorkerCount: 4,\n runWorker: this._runWorker.bind(this),\n prefetchProfile: PREFETCH_PROFILES.fileSystem,\n });\n }\n /** @internal */\n _retrieveSize() {\n const size = this._blob.size;\n this._orchestrator.fileSize = size;\n return size;\n }\n /** @internal */\n _read(start, end) {\n return this._orchestrator.read(start, end);\n }\n /** @internal */\n async _runWorker(worker) {\n let reader = this._readers.get(worker);\n if (reader === undefined) {\n // https://github.com/Vanilagy/mediabunny/issues/184\n // WebKit has critical bugs with blob.stream():\n // - WebKitBlobResource error 1 when streaming large files\n // - Memory buildup and reload loops on iOS (network process crashes)\n // - ReadableStream stalls under backpressure (especially video)\n // Affects Safari and all iOS browsers (Chrome, Firefox, etc.).\n // Use arrayBuffer() fallback for WebKit browsers.\n if ('stream' in this._blob && !isWebKit()) {\n // Get a reader of the blob starting at the required offset, and then keep it around\n const slice = this._blob.slice(worker.currentPos);\n reader = slice.stream().getReader();\n }\n else {\n // We'll need to use more primitive ways\n reader = null;\n }\n this._readers.set(worker, reader);\n }\n while (worker.currentPos < worker.targetPos && !worker.aborted) {\n if (reader) {\n const { done, value } = await reader.read();\n if (done) {\n this._orchestrator.forgetWorker(worker);\n throw new Error('Blob reader stopped unexpectedly before all requested data was read.');\n }\n if (worker.aborted) {\n break;\n }\n this.onread?.(worker.currentPos, worker.currentPos + value.length);\n this._orchestrator.supplyWorkerData(worker, value);\n }\n else {\n const data = await this._blob.slice(worker.currentPos, worker.targetPos).arrayBuffer();\n if (worker.aborted) {\n break;\n }\n this.onread?.(worker.currentPos, worker.currentPos + data.byteLength);\n this._orchestrator.supplyWorkerData(worker, new Uint8Array(data));\n }\n }\n worker.running = false;\n if (worker.aborted) {\n // MDN: \"Calling this method signals a loss of interest in the stream by a consumer.\"\n await reader?.cancel();\n }\n }\n /** @internal */\n _dispose() {\n this._orchestrator.dispose();\n }\n}\nconst URL_SOURCE_MIN_LOAD_AMOUNT = 0.5 * 2 ** 20; // 0.5 MiB\nconst DEFAULT_RETRY_DELAY = ((previousAttempts, error, src) => {\n // Check if this could be a CORS error. If so, we cannot recover from it and\n // should not attempt to retry.\n // CORS errors are intentionally not opaque, so we need to rely on heuristics.\n const couldBeCorsError = error instanceof Error && (error.message.includes('Failed to fetch') // Chrome\n || error.message.includes('Load failed') // Safari\n || error.message.includes('NetworkError when attempting to fetch resource') // Firefox\n );\n if (couldBeCorsError) {\n let originOfSrc = null;\n // Checking if the origin is different, because only then a CORS error could originate\n try {\n if (typeof window !== 'undefined' && typeof window.location !== 'undefined') {\n originOfSrc = new URL(src instanceof Request ? src.url : src, window.location.href).origin;\n }\n }\n catch {\n // URL parse failed\n }\n // If user is offline, it is probably not a CORS error.\n const isOnline = typeof navigator !== 'undefined' && typeof navigator.onLine === 'boolean' ? navigator.onLine : true;\n if (isOnline && originOfSrc !== null && originOfSrc !== window.location.origin) {\n console.warn(`Request will not be retried because a CORS error was suspected due to different origins. You can`\n + ` modify this behavior by providing your own function for the 'getRetryDelay' option.`);\n return null;\n }\n }\n return Math.min(2 ** (previousAttempts - 2), 16);\n});\n/**\n * A source backed by a URL. This is useful for reading data from the network. Requests will be made using an optimized\n * reading and prefetching pattern to minimize request count and latency.\n * @group Input sources\n * @public\n */\nexport class UrlSource extends Source {\n /** Creates a new {@link UrlSource} backed by the resource at the specified URL. */\n constructor(url, options = {}) {\n if (typeof url !== 'string'\n && !(url instanceof URL)\n && !(typeof Request !== 'undefined' && url instanceof Request)) {\n throw new TypeError('url must be a string, URL or Request.');\n }\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (options.requestInit !== undefined && (!options.requestInit || typeof options.requestInit !== 'object')) {\n throw new TypeError('options.requestInit, when provided, must be an object.');\n }\n if (options.getRetryDelay !== undefined && typeof options.getRetryDelay !== 'function') {\n throw new TypeError('options.getRetryDelay, when provided, must be a function.');\n }\n if (options.maxCacheSize !== undefined\n && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {\n throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');\n }\n if (options.fetchFn !== undefined && typeof options.fetchFn !== 'function') {\n throw new TypeError('options.fetchFn, when provided, must be a function.');\n // Won't bother validating this function beyond this\n }\n super();\n /** @internal */\n this._existingResponses = new WeakMap();\n this._url = url;\n this._options = options;\n this._getRetryDelay = options.getRetryDelay ?? DEFAULT_RETRY_DELAY;\n this._orchestrator = new ReadOrchestrator({\n maxCacheSize: options.maxCacheSize ?? (64 * 2 ** 20 /* 64 MiB */),\n // Most files in the real-world have a single sequential access pattern, but having two in parallel can\n // also happen\n maxWorkerCount: 2,\n runWorker: this._runWorker.bind(this),\n prefetchProfile: PREFETCH_PROFILES.network,\n });\n }\n /** @internal */\n async _retrieveSize() {\n // Retrieving the resource size for UrlSource is optimized: Almost always (= always), the first bytes we have to\n // read are the start of the file. This means it's smart to combine size fetching with fetching the start of the\n // file. We additionally use this step to probe if the server supports range requests, killing three birds with\n // one stone.\n const abortController = new AbortController();\n const response = await retriedFetch(this._options.fetchFn ?? fetch, this._url, mergeRequestInit(this._options.requestInit ?? {}, {\n headers: {\n // We could also send a non-range request to request the same bytes (all of them), but doing it like\n // this is an easy way to check if the server supports range requests in the first place\n Range: 'bytes=0-',\n },\n signal: abortController.signal,\n }), this._getRetryDelay, () => this._disposed);\n if (!response.ok) {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n throw new Error(`Error fetching ${String(this._url)}: ${response.status} ${response.statusText}`);\n }\n let worker;\n let fileSize;\n if (response.status === 206) {\n fileSize = this._getTotalLengthFromRangeResponse(response);\n worker = this._orchestrator.createWorker(0, Math.min(fileSize, URL_SOURCE_MIN_LOAD_AMOUNT));\n }\n else {\n // Server probably returned a 200.\n const contentLength = response.headers.get('Content-Length');\n if (contentLength) {\n fileSize = Number(contentLength);\n worker = this._orchestrator.createWorker(0, fileSize);\n this._orchestrator.options.maxCacheSize = Infinity; // \uD83E\uDD37\n console.warn('HTTP server did not respond with 206 Partial Content, meaning the entire remote resource now has'\n + ' to be downloaded. For efficient media file streaming across a network, please make sure your'\n + ' server supports range requests.');\n }\n else {\n throw new Error(`HTTP response (status ${response.status}) must surface Content-Length header.`);\n }\n }\n this._orchestrator.fileSize = fileSize;\n this._existingResponses.set(worker, { response, abortController });\n this._orchestrator.runWorker(worker);\n return fileSize;\n }\n /** @internal */\n _read(start, end) {\n return this._orchestrator.read(start, end);\n }\n /** @internal */\n async _runWorker(worker) {\n // The outer loop is for resuming a request if it dies mid-response\n while (true) {\n const existing = this._existingResponses.get(worker);\n this._existingResponses.delete(worker);\n let abortController = existing?.abortController;\n let response = existing?.response;\n if (!abortController) {\n abortController = new AbortController();\n response = await retriedFetch(this._options.fetchFn ?? fetch, this._url, mergeRequestInit(this._options.requestInit ?? {}, {\n headers: {\n Range: `bytes=${worker.currentPos}-`,\n },\n signal: abortController.signal,\n }), this._getRetryDelay, () => this._disposed);\n }\n assert(response);\n if (!response.ok) {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n throw new Error(`Error fetching ${String(this._url)}: ${response.status} ${response.statusText}`);\n }\n if (worker.currentPos > 0 && response.status !== 206) {\n throw new Error('HTTP server did not respond with 206 Partial Content to a range request. To enable efficient media'\n + ' file streaming across a network, please make sure your server supports range requests.');\n }\n if (!response.body) {\n throw new Error('Missing HTTP response body stream. The used fetch function must provide the response body as a'\n + ' ReadableStream.');\n }\n const reader = response.body.getReader();\n while (true) {\n if (worker.currentPos >= worker.targetPos || worker.aborted) {\n abortController.abort();\n worker.running = false;\n return;\n }\n let readResult;\n try {\n readResult = await reader.read();\n }\n catch (error) {\n if (this._disposed) {\n // No need to try to retry\n throw error;\n }\n const retryDelayInSeconds = this._getRetryDelay(1, error, this._url);\n if (retryDelayInSeconds !== null) {\n console.error('Error while reading response stream. Attempting to resume.', error);\n await new Promise(resolve => setTimeout(resolve, 1000 * retryDelayInSeconds));\n break;\n }\n else {\n throw error;\n }\n }\n if (worker.aborted) {\n continue; // Cleanup happens in next iteration\n }\n const { done, value } = readResult;\n if (done) {\n if (worker.currentPos >= worker.targetPos) {\n // All data was delivered, we're good\n this._orchestrator.forgetWorker(worker);\n worker.running = false;\n return;\n }\n // The response stopped early, before the target. This can happen if server decides to cap range\n // requests arbitrarily, even if the request had an uncapped end. In this case, let's fetch the rest\n // of the data using a new request.\n break;\n }\n this.onread?.(worker.currentPos, worker.currentPos + value.length);\n this._orchestrator.supplyWorkerData(worker, value);\n }\n }\n // The previous UrlSource had logic for circumventing https://issues.chromium.org/issues/436025873; I haven't\n // been able to observe this bug with the new UrlSource (maybe because we're using response streaming), so the\n // logic for that has vanished for now. Leaving a comment here if this becomes relevant again.\n }\n /** @internal */\n _getTotalLengthFromRangeResponse(response) {\n const contentRange = response.headers.get('Content-Range');\n if (contentRange) {\n const match = /\\/(\\d+)/.exec(contentRange);\n if (match) {\n return Number(match[1]);\n }\n }\n const contentLength = response.headers.get('Content-Length');\n if (contentLength) {\n return Number(contentLength);\n }\n else {\n throw new Error('Partial HTTP response (status 206) must surface either Content-Range or'\n + ' Content-Length header.');\n }\n }\n /** @internal */\n _dispose() {\n this._orchestrator.dispose();\n }\n}\n/**\n * A source backed by a path to a file. Intended for server-side usage in Node, Bun, or Deno.\n *\n * Make sure to call `.dispose()` on the corresponding {@link Input} when done to explicitly free the internal file\n * handle acquired by this source.\n * @group Input sources\n * @public\n */\nexport class FilePathSource extends Source {\n /** Creates a new {@link FilePathSource} backed by the file at the specified file path. */\n constructor(filePath, options = {}) {\n if (typeof filePath !== 'string') {\n throw new TypeError('filePath must be a string.');\n }\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (options.maxCacheSize !== undefined\n && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {\n throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');\n }\n super();\n /** @internal */\n this._fileHandle = null;\n // Let's back this source with a StreamSource, makes the implementation very simple\n this._streamSource = new StreamSource({\n getSize: async () => {\n this._fileHandle = await node.fs.open(filePath, 'r');\n const stats = await this._fileHandle.stat();\n return stats.size;\n },\n read: async (start, end) => {\n assert(this._fileHandle);\n const buffer = new Uint8Array(end - start);\n await this._fileHandle.read(buffer, 0, end - start, start);\n return buffer;\n },\n maxCacheSize: options.maxCacheSize,\n prefetchProfile: 'fileSystem',\n });\n }\n /** @internal */\n _read(start, end) {\n return this._streamSource._read(start, end);\n }\n /** @internal */\n _retrieveSize() {\n return this._streamSource._retrieveSize();\n }\n /** @internal */\n _dispose() {\n this._streamSource._dispose();\n void this._fileHandle?.close();\n this._fileHandle = null;\n }\n}\n/**\n * A general-purpose, callback-driven source that can get its data from anywhere.\n * @group Input sources\n * @public\n */\nexport class StreamSource extends Source {\n /** Creates a new {@link StreamSource} whose behavior is specified by `options`. */\n constructor(options) {\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (typeof options.getSize !== 'function') {\n throw new TypeError('options.getSize must be a function.');\n }\n if (typeof options.read !== 'function') {\n throw new TypeError('options.read must be a function.');\n }\n if (options.dispose !== undefined && typeof options.dispose !== 'function') {\n throw new TypeError('options.dispose, when provided, must be a function.');\n }\n if (options.maxCacheSize !== undefined\n && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {\n throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');\n }\n if (options.prefetchProfile && !['none', 'fileSystem', 'network'].includes(options.prefetchProfile)) {\n throw new TypeError('options.prefetchProfile, when provided, must be one of \\'none\\', \\'fileSystem\\' or \\'network\\'.');\n }\n super();\n this._options = options;\n this._orchestrator = new ReadOrchestrator({\n maxCacheSize: options.maxCacheSize ?? (8 * 2 ** 20 /* 8 MiB */),\n maxWorkerCount: 2, // Fixed for now, *should* be fine\n prefetchProfile: PREFETCH_PROFILES[options.prefetchProfile ?? 'none'],\n runWorker: this._runWorker.bind(this),\n });\n }\n /** @internal */\n _retrieveSize() {\n const result = this._options.getSize();\n if (result instanceof Promise) {\n return result.then((size) => {\n if (!Number.isInteger(size) || size < 0) {\n throw new TypeError('options.getSize must return or resolve to a non-negative integer.');\n }\n this._orchestrator.fileSize = size;\n return size;\n });\n }\n else {\n if (!Number.isInteger(result) || result < 0) {\n throw new TypeError('options.getSize must return or resolve to a non-negative integer.');\n }\n this._orchestrator.fileSize = result;\n return result;\n }\n }\n /** @internal */\n _read(start, end) {\n return this._orchestrator.read(start, end);\n }\n /** @internal */\n async _runWorker(worker) {\n while (worker.currentPos < worker.targetPos && !worker.aborted) {\n const originalCurrentPos = worker.currentPos;\n const originalTargetPos = worker.targetPos;\n let data = this._options.read(worker.currentPos, originalTargetPos);\n if (data instanceof Promise)\n data = await data;\n if (worker.aborted) {\n break;\n }\n if (data instanceof Uint8Array) {\n data = toUint8Array(data); // Normalize things like Node.js Buffer to Uint8Array\n if (data.length !== originalTargetPos - worker.currentPos) {\n // Yes, we're that strict\n throw new Error(`options.read returned a Uint8Array with unexpected length: Requested ${originalTargetPos - worker.currentPos} bytes, but got ${data.length}.`);\n }\n this.onread?.(worker.currentPos, worker.currentPos + data.length);\n this._orchestrator.supplyWorkerData(worker, data);\n }\n else if (data instanceof ReadableStream) {\n const reader = data.getReader();\n while (worker.currentPos < originalTargetPos && !worker.aborted) {\n const { done, value } = await reader.read();\n if (done) {\n if (worker.currentPos < originalTargetPos) {\n // Yes, we're *that* strict\n throw new Error(`ReadableStream returned by options.read ended before supplying enough data.`\n + ` Requested ${originalTargetPos - originalCurrentPos} bytes, but got ${worker.currentPos - originalCurrentPos}`);\n }\n break;\n }\n if (!(value instanceof Uint8Array)) {\n throw new TypeError('ReadableStream returned by options.read must yield Uint8Array chunks.');\n }\n if (worker.aborted) {\n break;\n }\n const data = toUint8Array(value); // Normalize things like Node.js Buffer to Uint8Array\n this.onread?.(worker.currentPos, worker.currentPos + data.length);\n this._orchestrator.supplyWorkerData(worker, data);\n }\n }\n else {\n throw new TypeError('options.read must return or resolve to a Uint8Array or a ReadableStream.');\n }\n }\n worker.running = false;\n }\n /** @internal */\n _dispose() {\n this._orchestrator.dispose();\n this._options.dispose?.();\n }\n}\n/**\n * A source backed by a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) of\n * `Uint8Array`, representing an append-only byte stream of unknown length. This is the source to use for incrementally\n * streaming in input files that are still being constructed and whose size we don't yet know, like for example the\n * output chunks of [MediaRecorder](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder).\n *\n * This source is *unsized*, meaning calls to `.getSize()` will throw and readers are more limited due to the\n * lack of random file access. You should only use this source with sequential access patterns, such as reading all\n * packets from start to end. This source does not work well with random access patterns unless you increase its\n * max cache size.\n *\n * @group Input sources\n * @public\n */\nexport class ReadableStreamSource extends Source {\n /** Creates a new {@link ReadableStreamSource} backed by the specified `ReadableStream<Uint8Array>`. */\n constructor(stream, options = {}) {\n if (!(stream instanceof ReadableStream)) {\n throw new TypeError('stream must be a ReadableStream.');\n }\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (options.maxCacheSize !== undefined\n && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {\n throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');\n }\n super();\n /** @internal */\n this._reader = null;\n /** @internal */\n this._cache = [];\n /** @internal */\n this._pendingSlices = [];\n /** @internal */\n this._currentIndex = 0;\n /** @internal */\n this._targetIndex = 0;\n /** @internal */\n this._maxRequestedIndex = 0;\n /** @internal */\n this._endIndex = null;\n /** @internal */\n this._pulling = false;\n this._stream = stream;\n this._maxCacheSize = options.maxCacheSize ?? (16 * 2 ** 20 /* 16 MiB */);\n }\n /** @internal */\n _retrieveSize() {\n return this._endIndex; // Starts out as null, meaning this source is unsized\n }\n /** @internal */\n _read(start, end) {\n if (this._endIndex !== null && end > this._endIndex) {\n return null;\n }\n this._maxRequestedIndex = Math.max(this._maxRequestedIndex, end);\n const cacheStartIndex = binarySearchLessOrEqual(this._cache, start, x => x.start);\n const cacheStartEntry = cacheStartIndex !== -1 ? this._cache[cacheStartIndex] : null;\n if (cacheStartEntry && cacheStartEntry.start <= start && end <= cacheStartEntry.end) {\n // The request can be satisfied with a single cache entry\n return {\n bytes: cacheStartEntry.bytes,\n view: cacheStartEntry.view,\n offset: cacheStartEntry.start,\n };\n }\n let lastEnd = start;\n const bytes = new Uint8Array(end - start);\n if (cacheStartIndex !== -1) {\n // Walk over the cache to see if we can satisfy the request using multiple cache entries\n for (let i = cacheStartIndex; i < this._cache.length; i++) {\n const cacheEntry = this._cache[i];\n if (cacheEntry.start >= end) {\n break;\n }\n const cappedStart = Math.max(start, cacheEntry.start);\n if (cappedStart > lastEnd) {\n // We're too far behind\n this._throwDueToCacheMiss();\n }\n const cappedEnd = Math.min(end, cacheEntry.end);\n if (cappedStart < cappedEnd) {\n bytes.set(cacheEntry.bytes.subarray(cappedStart - cacheEntry.start, cappedEnd - cacheEntry.start), cappedStart - start);\n lastEnd = cappedEnd;\n }\n }\n }\n if (lastEnd === end) {\n return {\n bytes,\n view: toDataView(bytes),\n offset: start,\n };\n }\n // We need to pull more data\n if (this._currentIndex > lastEnd) {\n // We're too far behind\n this._throwDueToCacheMiss();\n }\n const { promise, resolve, reject } = promiseWithResolvers();\n this._pendingSlices.push({\n start,\n end,\n bytes,\n resolve,\n reject,\n });\n this._targetIndex = Math.max(this._targetIndex, end);\n // Start pulling from the stream if we're not already doing it\n if (!this._pulling) {\n this._pulling = true;\n void this._pull()\n .catch((error) => {\n this._pulling = false;\n if (this._pendingSlices.length > 0) {\n this._pendingSlices.forEach(x => x.reject(error)); // Make sure to propagate any errors\n this._pendingSlices.length = 0;\n }\n else {\n throw error; // So it doesn't get swallowed\n }\n });\n }\n return promise;\n }\n /** @internal */\n _throwDueToCacheMiss() {\n throw new Error('Read is before the cached region. With ReadableStreamSource, you must access the data more'\n + ' sequentially or increase the size of its cache.');\n }\n /** @internal */\n async _pull() {\n this._reader ??= this._stream.getReader();\n // This is the loop that keeps pulling data from the stream until a target index is reached, filling requests\n // in the process\n while (this._currentIndex < this._targetIndex && !this._disposed) {\n const { done, value } = await this._reader.read();\n if (done) {\n for (const pendingSlice of this._pendingSlices) {\n pendingSlice.resolve(null);\n }\n this._pendingSlices.length = 0;\n this._endIndex = this._currentIndex; // We know how long the file is now!\n break;\n }\n const startIndex = this._currentIndex;\n const endIndex = this._currentIndex + value.byteLength;\n // Fill the pending slices with the data\n for (let i = 0; i < this._pendingSlices.length; i++) {\n const pendingSlice = this._pendingSlices[i];\n const cappedStart = Math.max(startIndex, pendingSlice.start);\n const cappedEnd = Math.min(endIndex, pendingSlice.end);\n if (cappedStart < cappedEnd) {\n pendingSlice.bytes.set(value.subarray(cappedStart - startIndex, cappedEnd - startIndex), cappedStart - pendingSlice.start);\n if (cappedEnd === pendingSlice.end) {\n // Pending slice fully filled\n pendingSlice.resolve({\n bytes: pendingSlice.bytes,\n view: toDataView(pendingSlice.bytes),\n offset: pendingSlice.start,\n });\n this._pendingSlices.splice(i, 1);\n i--;\n }\n }\n }\n this._cache.push({\n start: startIndex,\n end: endIndex,\n bytes: value,\n view: toDataView(value),\n age: 0, // Unused\n });\n // Do cache eviction, based on the distance from the last-requested index. It's important that we do it like\n // this and not based on where the reader is at, because if the reader is fast, we'll unnecessarily evict\n // data that we still might need.\n while (this._cache.length > 0) {\n const firstEntry = this._cache[0];\n const distance = this._maxRequestedIndex - firstEntry.end;\n if (distance <= this._maxCacheSize) {\n break;\n }\n this._cache.shift();\n }\n this._currentIndex += value.byteLength;\n }\n this._pulling = false;\n }\n /** @internal */\n _dispose() {\n this._pendingSlices.length = 0;\n this._cache.length = 0;\n }\n}\nconst PREFETCH_PROFILES = {\n none: (start, end) => ({ start, end }),\n fileSystem: (start, end) => {\n const padding = 2 ** 16;\n start = Math.floor((start - padding) / padding) * padding;\n end = Math.ceil((end + padding) / padding) * padding;\n return { start, end };\n },\n network: (start, end, workers) => {\n // Add a slight bit of start padding because backwards reading is painful\n const paddingStart = 2 ** 16;\n start = Math.max(0, Math.floor((start - paddingStart) / paddingStart) * paddingStart);\n // Remote resources have extreme latency (relatively speaking), so the benefit from intelligent\n // prefetching is great. The network prefetch strategy is as follows: When we notice\n // successive reads to a worker's read region, we prefetch more data at the end of that region,\n // growing exponentially (up to a cap). This performs well for real-world use cases: Either we read a\n // small part of the file once and then never need it again, in which case the requested about of data\n // is small. Or, we're repeatedly doing a sequential access pattern (common in media files), in which\n // case we can become more and more confident to prefetch more and more data.\n for (const worker of workers) {\n const maxExtensionAmount = 8 * 2 ** 20; // 8 MiB\n // When the read region cross the threshold point, we trigger a prefetch. This point is typically\n // in the middle of the worker's read region, or a fixed offset from the end if the region has grown\n // really large.\n const thresholdPoint = Math.max((worker.startPos + worker.targetPos) / 2, worker.targetPos - maxExtensionAmount);\n if (closedIntervalsOverlap(start, end, thresholdPoint, worker.targetPos)) {\n const size = worker.targetPos - worker.startPos;\n // If we extend by maxExtensionAmount\n const a = Math.ceil((size + 1) / maxExtensionAmount) * maxExtensionAmount;\n // If we extend to the next power of 2\n const b = 2 ** Math.ceil(Math.log2(size + 1));\n const extent = Math.min(b, a);\n end = Math.max(end, worker.startPos + extent);\n }\n }\n end = Math.max(end, start + URL_SOURCE_MIN_LOAD_AMOUNT);\n return {\n start,\n end,\n };\n },\n};\n/**\n * Godclass for orchestrating complex, cached read operations. The reading model is as follows: Any reading task is\n * delegated to a *worker*, which is a sequential reader positioned somewhere along the file. All workers run in\n * parallel and can be stopped and resumed in their forward movement. When read requests come in, this orchestrator will\n * first try to satisfy the request with only the cached data. If this isn't possible, workers are spun up for all\n * missing parts (or existing workers are repurposed), and these workers will then fill the holes in the data as they\n * march along the file.\n */\nclass ReadOrchestrator {\n constructor(options) {\n this.options = options;\n this.fileSize = null;\n this.nextAge = 0; // Used for LRU eviction of both cache entries and workers\n this.workers = [];\n this.cache = [];\n this.currentCacheSize = 0;\n this.disposed = false;\n }\n read(innerStart, innerEnd) {\n assert(this.fileSize !== null);\n const prefetchRange = this.options.prefetchProfile(innerStart, innerEnd, this.workers);\n const outerStart = Math.max(prefetchRange.start, 0);\n const outerEnd = Math.min(prefetchRange.end, this.fileSize);\n assert(outerStart <= innerStart && innerEnd <= outerEnd);\n let result = null;\n const innerCacheStartIndex = binarySearchLessOrEqual(this.cache, innerStart, x => x.start);\n const innerStartEntry = innerCacheStartIndex !== -1 ? this.cache[innerCacheStartIndex] : null;\n // See if the read request can be satisfied by a single cache entry\n if (innerStartEntry && innerStartEntry.start <= innerStart && innerEnd <= innerStartEntry.end) {\n innerStartEntry.age = this.nextAge++;\n result = {\n bytes: innerStartEntry.bytes,\n view: innerStartEntry.view,\n offset: innerStartEntry.start,\n };\n // Can't return yet though, still need to check if the prefetch range might lie outside the cached area\n }\n const outerCacheStartIndex = binarySearchLessOrEqual(this.cache, outerStart, x => x.start);\n const bytes = result ? null : new Uint8Array(innerEnd - innerStart);\n let contiguousBytesWriteEnd = 0; // Used to track if the cache is able to completely cover the bytes\n let lastEnd = outerStart;\n // The \"holes\" in the cache (the parts we need to load)\n const outerHoles = [];\n // Loop over the cache and build up the list of holes\n if (outerCacheStartIndex !== -1) {\n for (let i = outerCacheStartIndex; i < this.cache.length; i++) {\n const entry = this.cache[i];\n if (entry.start >= outerEnd) {\n break;\n }\n if (entry.end <= outerStart) {\n continue;\n }\n const cappedOuterStart = Math.max(outerStart, entry.start);\n const cappedOuterEnd = Math.min(outerEnd, entry.end);\n assert(cappedOuterStart <= cappedOuterEnd);\n if (lastEnd < cappedOuterStart) {\n outerHoles.push({ start: lastEnd, end: cappedOuterStart });\n }\n lastEnd = cappedOuterEnd;\n if (bytes) {\n const cappedInnerStart = Math.max(innerStart, entry.start);\n const cappedInnerEnd = Math.min(innerEnd, entry.end);\n if (cappedInnerStart < cappedInnerEnd) {\n const relativeOffset = cappedInnerStart - innerStart;\n // Fill the relevant section of the bytes with the cached data\n bytes.set(entry.bytes.subarray(cappedInnerStart - entry.start, cappedInnerEnd - entry.start), relativeOffset);\n if (relativeOffset === contiguousBytesWriteEnd) {\n contiguousBytesWriteEnd = cappedInnerEnd - innerStart;\n }\n }\n }\n entry.age = this.nextAge++;\n }\n if (lastEnd < outerEnd) {\n outerHoles.push({ start: lastEnd, end: outerEnd });\n }\n }\n else {\n outerHoles.push({ start: outerStart, end: outerEnd });\n }\n if (bytes && contiguousBytesWriteEnd >= bytes.length) {\n // Multiple cache entries were able to completely cover the requested bytes!\n result = {\n bytes,\n view: toDataView(bytes),\n offset: innerStart,\n };\n }\n if (outerHoles.length === 0) {\n assert(result);\n return result;\n }\n // We need to read more data, so now we're in async land\n const { promise, resolve, reject } = promiseWithResolvers();\n const innerHoles = [];\n for (const outerHole of outerHoles) {\n const cappedStart = Math.max(innerStart, outerHole.start);\n const cappedEnd = Math.min(innerEnd, outerHole.end);\n if (cappedStart === outerHole.start && cappedEnd === outerHole.end) {\n innerHoles.push(outerHole); // Can reuse without allocating a new object\n }\n else if (cappedStart < cappedEnd) {\n innerHoles.push({ start: cappedStart, end: cappedEnd });\n }\n }\n // Fire off workers to take care of patching the holes\n for (const outerHole of outerHoles) {\n const pendingSlice = bytes && {\n start: innerStart,\n bytes,\n holes: innerHoles,\n resolve,\n reject,\n };\n let workerFound = false;\n for (const worker of this.workers) {\n // A small tolerance in the case that the requested region is *just* after the target position of an\n // existing worker. In that case, it's probably more efficient to repurpose that worker than to spawn\n // another one so close to it\n const gapTolerance = 2 ** 17;\n // This check also implies worker.currentPos <= outerHole.start, a critical condition\n if (closedIntervalsOverlap(outerHole.start - gapTolerance, outerHole.start, worker.currentPos, worker.targetPos)) {\n worker.targetPos = Math.max(worker.targetPos, outerHole.end); // Update the worker's target position\n workerFound = true;\n if (pendingSlice && !worker.pendingSlices.includes(pendingSlice)) {\n worker.pendingSlices.push(pendingSlice);\n }\n if (!worker.running) {\n // Kick it off if it's idle\n this.runWorker(worker);\n }\n break;\n }\n }\n if (!workerFound) {\n // We need to spawn a new worker\n const newWorker = this.createWorker(outerHole.start, outerHole.end);\n if (pendingSlice) {\n newWorker.pendingSlices = [pendingSlice];\n }\n this.runWorker(newWorker);\n }\n }\n if (!result) {\n assert(bytes);\n result = promise.then(bytes => ({\n bytes,\n view: toDataView(bytes),\n offset: innerStart,\n }));\n }\n else {\n // The requested region was satisfied by the cache, but the entire prefetch region was not\n }\n return result;\n }\n createWorker(startPos, targetPos) {\n const worker = {\n startPos,\n currentPos: startPos,\n targetPos,\n running: false,\n // Due to async shenanigans, it can happen that workers are started after disposal. In this case, instead of\n // simply not creating the worker, we allow it to run but immediately label it as aborted, so it can then\n // shut itself down.\n aborted: this.disposed,\n pendingSlices: [],\n age: this.nextAge++,\n };\n this.workers.push(worker);\n // LRU eviction of the other workers\n while (this.workers.length > this.options.maxWorkerCount) {\n let oldestIndex = 0;\n let oldestWorker = this.workers[0];\n for (let i = 1; i < this.workers.length; i++) {\n const worker = this.workers[i];\n if (worker.age < oldestWorker.age) {\n oldestIndex = i;\n oldestWorker = worker;\n }\n }\n if (oldestWorker.running && oldestWorker.pendingSlices.length > 0) {\n break;\n }\n oldestWorker.aborted = true;\n this.workers.splice(oldestIndex, 1);\n }\n return worker;\n }\n runWorker(worker) {\n assert(!worker.running);\n assert(worker.currentPos < worker.targetPos);\n worker.running = true;\n worker.age = this.nextAge++;\n void this.options.runWorker(worker)\n .catch((error) => {\n worker.running = false;\n if (worker.pendingSlices.length > 0) {\n worker.pendingSlices.forEach(x => x.reject(error)); // Make sure to propagate any errors\n worker.pendingSlices.length = 0;\n }\n else {\n throw error; // So it doesn't get swallowed\n }\n });\n }\n /** Called by a worker when it has read some data. */\n supplyWorkerData(worker, bytes) {\n assert(!worker.aborted);\n const start = worker.currentPos;\n const end = start + bytes.length;\n this.insertIntoCache({\n start,\n end,\n bytes,\n view: toDataView(bytes),\n age: this.nextAge++,\n });\n worker.currentPos += bytes.length;\n worker.targetPos = Math.max(worker.targetPos, worker.currentPos); // In case it overshoots\n // Now, let's see if we can use the read bytes to fill any pending slice\n for (let i = 0; i < worker.pendingSlices.length; i++) {\n const pendingSlice = worker.pendingSlices[i];\n const clampedStart = Math.max(start, pendingSlice.start);\n const clampedEnd = Math.min(end, pendingSlice.start + pendingSlice.bytes.length);\n if (clampedStart < clampedEnd) {\n pendingSlice.bytes.set(bytes.subarray(clampedStart - start, clampedEnd - start), clampedStart - pendingSlice.start);\n }\n for (let j = 0; j < pendingSlice.holes.length; j++) {\n // The hole is intentionally not modified here if the read section starts somewhere in the middle of\n // the hole. We don't need to do \"hole splitting\", since the workers are spawned *by* the holes,\n // meaning there's always a worker which will consume the hole left to right.\n const hole = pendingSlice.holes[j];\n if (start <= hole.start && end > hole.start) {\n hole.start = end;\n }\n if (hole.end <= hole.start) {\n pendingSlice.holes.splice(j, 1);\n j--;\n }\n }\n if (pendingSlice.holes.length === 0) {\n // The slice has been fulfilled, everything has been read. Let's resolve the promise\n pendingSlice.resolve(pendingSlice.bytes);\n worker.pendingSlices.splice(i, 1);\n i--;\n }\n }\n // Remove other idle workers if we \"ate\" into their territory\n for (let i = 0; i < this.workers.length; i++) {\n const otherWorker = this.workers[i];\n if (worker === otherWorker || otherWorker.running) {\n continue;\n }\n if (closedIntervalsOverlap(start, end, otherWorker.currentPos, otherWorker.targetPos)) {\n this.workers.splice(i, 1);\n i--;\n }\n }\n }\n forgetWorker(worker) {\n const index = this.workers.indexOf(worker);\n assert(index !== -1);\n this.workers.splice(index, 1);\n }\n insertIntoCache(entry) {\n if (this.options.maxCacheSize === 0) {\n return; // No caching\n }\n let insertionIndex = binarySearchLessOrEqual(this.cache, entry.start, x => x.start) + 1;\n if (insertionIndex > 0) {\n const previous = this.cache[insertionIndex - 1];\n if (previous.end >= entry.end) {\n // Previous entry swallows the one to be inserted; we don't need to do anything\n return;\n }\n if (previous.end > entry.start) {\n // Partial overlap with the previous entry, let's join\n const joined = new Uint8Array(entry.end - previous.start);\n joined.set(previous.bytes, 0);\n joined.set(entry.bytes, entry.start - previous.start);\n this.currentCacheSize += entry.end - previous.end;\n previous.bytes = joined;\n previous.view = toDataView(joined);\n previous.end = entry.end;\n // Do the rest of the logic with the previous entry instead\n insertionIndex--;\n entry = previous;\n }\n else {\n this.cache.splice(insertionIndex, 0, entry);\n this.currentCacheSize += entry.bytes.length;\n }\n }\n else {\n this.cache.splice(insertionIndex, 0, entry);\n this.currentCacheSize += entry.bytes.length;\n }\n for (let i = insertionIndex + 1; i < this.cache.length; i++) {\n const next = this.cache[i];\n if (entry.end <= next.start) {\n // Even if they touch, we don't wanna merge them, no need\n break;\n }\n if (entry.end >= next.end) {\n // The inserted entry completely swallows the next entry\n this.cache.splice(i, 1);\n this.currentCacheSize -= next.bytes.length;\n i--;\n continue;\n }\n // Partial overlap, let's join\n const joined = new Uint8Array(next.end - entry.start);\n joined.set(entry.bytes, 0);\n joined.set(next.bytes, next.start - entry.start);\n this.currentCacheSize -= entry.end - next.start; // Subtract the overlap\n entry.bytes = joined;\n entry.view = toDataView(joined);\n entry.end = next.end;\n this.cache.splice(i, 1);\n break; // After the join case, we're done: the next entry cannot possibly overlap with the inserted one.\n }\n // LRU eviction of cache entries\n while (this.currentCacheSize > this.options.maxCacheSize) {\n let oldestIndex = 0;\n let oldestEntry = this.cache[0];\n for (let i = 1; i < this.cache.length; i++) {\n const entry = this.cache[i];\n if (entry.age < oldestEntry.age) {\n oldestIndex = i;\n oldestEntry = entry;\n }\n }\n if (this.currentCacheSize - oldestEntry.bytes.length <= this.options.maxCacheSize) {\n // Don't evict if it would shrink the cache below the max size\n break;\n }\n this.cache.splice(oldestIndex, 1);\n this.currentCacheSize -= oldestEntry.bytes.length;\n }\n }\n dispose() {\n for (const worker of this.workers) {\n worker.aborted = true;\n }\n this.workers.length = 0;\n this.cache.length = 0;\n this.disposed = true;\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { InputFormat } from './input-format.js';\nimport { assert, polyfillSymbolDispose } from './misc.js';\nimport { Reader } from './reader.js';\nimport { Source } from './source.js';\npolyfillSymbolDispose();\n/**\n * Represents an input media file. This is the root object from which all media read operations start.\n * @group Input files & tracks\n * @public\n */\nexport class Input {\n /** True if the input has been disposed. */\n get disposed() {\n return this._disposed;\n }\n /**\n * Creates a new input file from the specified options. No reading operations will be performed until methods are\n * called on this instance.\n */\n constructor(options) {\n /** @internal */\n this._demuxerPromise = null;\n /** @internal */\n this._format = null;\n /** @internal */\n this._disposed = false;\n if (!options || typeof options !== 'object') {\n throw new TypeError('options must be an object.');\n }\n if (!Array.isArray(options.formats) || options.formats.some(x => !(x instanceof InputFormat))) {\n throw new TypeError('options.formats must be an array of InputFormat.');\n }\n if (!(options.source instanceof Source)) {\n throw new TypeError('options.source must be a Source.');\n }\n if (options.source._disposed) {\n throw new Error('options.source must not be disposed.');\n }\n this._formats = options.formats;\n this._source = options.source;\n this._reader = new Reader(options.source);\n }\n /** @internal */\n _getDemuxer() {\n return this._demuxerPromise ??= (async () => {\n this._reader.fileSize = await this._source.getSizeOrNull();\n for (const format of this._formats) {\n const canRead = await format._canReadInput(this);\n if (canRead) {\n this._format = format;\n return format._createDemuxer(this);\n }\n }\n throw new Error('Input has an unsupported or unrecognizable format.');\n })();\n }\n /**\n * Returns the source from which this input file reads its data. This is the same source that was passed to the\n * constructor.\n */\n get source() {\n return this._source;\n }\n /**\n * Returns the format of the input file. You can compare this result directly to the {@link InputFormat} singletons\n * or use `instanceof` checks for subset-aware logic (for example, `format instanceof MatroskaInputFormat` is true\n * for both MKV and WebM).\n */\n async getFormat() {\n await this._getDemuxer();\n assert(this._format);\n return this._format;\n }\n /**\n * Computes the duration of the input file, in seconds. More precisely, returns the largest end timestamp among\n * all tracks.\n */\n async computeDuration() {\n const demuxer = await this._getDemuxer();\n return demuxer.computeDuration();\n }\n /** Returns the list of all tracks of this input file. */\n async getTracks() {\n const demuxer = await this._getDemuxer();\n return demuxer.getTracks();\n }\n /** Returns the list of all video tracks of this input file. */\n async getVideoTracks() {\n const tracks = await this.getTracks();\n return tracks.filter(x => x.isVideoTrack());\n }\n /** Returns the list of all audio tracks of this input file. */\n async getAudioTracks() {\n const tracks = await this.getTracks();\n return tracks.filter(x => x.isAudioTrack());\n }\n /** Returns the primary video track of this input file, or null if there are no video tracks. */\n async getPrimaryVideoTrack() {\n const tracks = await this.getTracks();\n return tracks.find(x => x.isVideoTrack()) ?? null;\n }\n /** Returns the primary audio track of this input file, or null if there are no audio tracks. */\n async getPrimaryAudioTrack() {\n const tracks = await this.getTracks();\n return tracks.find(x => x.isAudioTrack()) ?? null;\n }\n /** Returns the full MIME type of this input file, including track codecs. */\n async getMimeType() {\n const demuxer = await this._getDemuxer();\n return demuxer.getMimeType();\n }\n /**\n * Returns descriptive metadata tags about the media file, such as title, author, date, cover art, or other\n * attached files.\n */\n async getMetadataTags() {\n const demuxer = await this._getDemuxer();\n return demuxer.getMetadataTags();\n }\n /**\n * Disposes this input and frees connected resources. When an input is disposed, ongoing read operations will be\n * canceled, all future read operations will fail, any open decoders will be closed, and all ongoing media sink\n * operations will be canceled. Disallowed and canceled operations will throw an {@link InputDisposedError}.\n *\n * You are expected not to use an input after disposing it. While some operations may still work, it is not\n * specified and may change in any future update.\n */\n dispose() {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._source._disposed = true;\n this._source._dispose();\n }\n /**\n * Calls `.dispose()` on the input, implementing the `Disposable` interface for use with\n * JavaScript Explicit Resource Management features.\n */\n [Symbol.dispose]() {\n this.dispose();\n }\n}\n/**\n * Thrown when an operation was prevented because the corresponding {@link Input} has been disposed.\n * @group Input files & tracks\n * @public\n */\nexport class InputDisposedError extends Error {\n /** Creates a new {@link InputDisposedError}. */\n constructor(message = 'Input has been disposed.') {\n super(message);\n this.name = 'InputDisposedError';\n }\n}\n", "/*!\n * Copyright (c) 2025-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n */\nimport { InputDisposedError } from './input.js';\nimport { assert, clamp, getUint24, toDataView } from './misc.js';\nexport class Reader {\n constructor(source) {\n this.source = source;\n }\n requestSlice(start, length) {\n if (this.source._disposed) {\n throw new InputDisposedError();\n }\n if (this.fileSize !== null && start + length > this.fileSize) {\n return null;\n }\n const end = start + length;\n const result = this.source._read(start, end);\n if (result instanceof Promise) {\n return result.then((x) => {\n if (!x) {\n return null;\n }\n return new FileSlice(x.bytes, x.view, x.offset, start, end);\n });\n }\n else {\n if (!result) {\n return null;\n }\n return new FileSlice(result.bytes, result.view, result.offset, start, end);\n }\n }\n requestSliceRange(start, minLength, maxLength) {\n if (this.source._disposed) {\n throw new InputDisposedError();\n }\n if (this.fileSize !== null) {\n return this.requestSlice(start, clamp(this.fileSize - start, minLength, maxLength));\n }\n else {\n const promisedAttempt = this.requestSlice(start, maxLength);\n const handleAttempt = (attempt) => {\n if (attempt) {\n return attempt;\n }\n const handleFileSize = (fileSize) => {\n assert(fileSize !== null); // The slice couldn't fit, meaning we must know the file size now\n return this.requestSlice(start, clamp(fileSize - start, minLength, maxLength));\n };\n const promisedFileSize = this.source._retrieveSize();\n if (promisedFileSize instanceof Promise) {\n return promisedFileSize.then(handleFileSize);\n }\n else {\n return handleFileSize(promisedFileSize);\n }\n };\n if (promisedAttempt instanceof Promise) {\n return promisedAttempt.then(handleAttempt);\n }\n else {\n return handleAttempt(promisedAttempt);\n }\n }\n }\n}\nexport class FileSlice {\n constructor(\n /** The underlying bytes backing this slice. Avoid using this directly and prefer reader functions instead. */\n bytes, \n /** A view into the bytes backing this slice. Avoid using this directly and prefer reader functions instead. */\n view, \n /** The offset in \"file bytes\" at which `bytes` begins in the file. */\n offset, \n /** The offset in \"file bytes\" where this slice begins. */\n start, \n /** The offset in \"file bytes\" where this slice ends (exclusive). */\n end) {\n this.bytes = bytes;\n this.view = view;\n this.offset = offset;\n this.start = start;\n this.end = end;\n this.bufferPos = start - offset;\n }\n static tempFromBytes(bytes) {\n return new FileSlice(bytes, toDataView(bytes), 0, 0, bytes.length);\n }\n get length() {\n return this.end - this.start;\n }\n get filePos() {\n return this.offset + this.bufferPos;\n }\n set filePos(value) {\n this.bufferPos = value - this.offset;\n }\n /** The number of bytes left from the current pos to the end of the slice. */\n get remainingLength() {\n return Math.max(this.end - this.filePos, 0);\n }\n skip(byteCount) {\n this.bufferPos += byteCount;\n }\n /** Creates a new subslice of this slice whose byte range must be contained within this slice. */\n slice(filePos, length = this.end - filePos) {\n if (filePos < this.start || filePos + length > this.end) {\n throw new RangeError('Slicing outside of original slice.');\n }\n return new FileSlice(this.bytes, this.view, this.offset, filePos, filePos + length);\n }\n}\nconst checkIsInRange = (slice, bytesToRead) => {\n if (slice.filePos < slice.start || slice.filePos + bytesToRead > slice.end) {\n throw new RangeError(`Tried reading [${slice.filePos}, ${slice.filePos + bytesToRead}), but slice is`\n + ` [${slice.start}, ${slice.end}). This is likely an internal error, please report it alongside the file`\n + ` that caused it.`);\n }\n};\nexport const readBytes = (slice, length) => {\n checkIsInRange(slice, length);\n const bytes = slice.bytes.subarray(slice.bufferPos, slice.bufferPos + length);\n slice.bufferPos += length;\n return bytes;\n};\nexport const readU8 = (slice) => {\n checkIsInRange(slice, 1);\n return slice.view.getUint8(slice.bufferPos++);\n};\nexport const readU16 = (slice, littleEndian) => {\n checkIsInRange(slice, 2);\n const value = slice.view.getUint16(slice.bufferPos, littleEndian);\n slice.bufferPos += 2;\n return value;\n};\nexport const readU16Be = (slice) => {\n checkIsInRange(slice, 2);\n const value = slice.view.getUint16(slice.bufferPos, false);\n slice.bufferPos += 2;\n return value;\n};\nexport const readU24Be = (slice) => {\n checkIsInRange(slice, 3);\n const value = getUint24(slice.view, slice.bufferPos, false);\n slice.bufferPos += 3;\n return value;\n};\nexport const readI16Be = (slice) => {\n checkIsInRange(slice, 2);\n const value = slice.view.getInt16(slice.bufferPos, false);\n slice.bufferPos += 2;\n return value;\n};\nexport const readU32 = (slice, littleEndian) => {\n checkIsInRange(slice, 4);\n const value = slice.view.getUint32(slice.bufferPos, littleEndian);\n slice.bufferPos += 4;\n return value;\n};\nexport const readU32Be = (slice) => {\n checkIsInRange(slice, 4);\n const value = slice.view.getUint32(slice.bufferPos, false);\n slice.bufferPos += 4;\n return value;\n};\nexport const readU32Le = (slice) => {\n checkIsInRange(slice, 4);\n const value = slice.view.getUint32(slice.bufferPos, true);\n slice.bufferPos += 4;\n return value;\n};\nexport const readI32Be = (slice) => {\n checkIsInRange(slice, 4);\n const value = slice.view.getInt32(slice.bufferPos, false);\n slice.bufferPos += 4;\n return value;\n};\nexport const readI32Le = (slice) => {\n checkIsInRange(slice, 4);\n const value = slice.view.getInt32(slice.bufferPos, true);\n slice.bufferPos += 4;\n return value;\n};\nexport const readU64 = (slice, littleEndian) => {\n let low;\n let high;\n if (littleEndian) {\n low = readU32(slice, true);\n high = readU32(slice, true);\n }\n else {\n high = readU32(slice, false);\n low = readU32(slice, false);\n }\n return high * 0x100000000 + low;\n};\nexport const readU64Be = (slice) => {\n const high = readU32Be(slice);\n const low = readU32Be(slice);\n return high * 0x100000000 + low;\n};\nexport const readI64Be = (slice) => {\n const high = readI32Be(slice);\n const low = readU32Be(slice);\n return high * 0x100000000 + low;\n};\nexport const readI64Le = (slice) => {\n const low = readU32Le(slice);\n const high = readI32Le(slice);\n return high * 0x100000000 + low;\n};\nexport const readF32Be = (slice) => {\n checkIsInRange(slice, 4);\n const value = slice.view.getFloat32(slice.bufferPos, false);\n slice.bufferPos += 4;\n return value;\n};\nexport const readF64Be = (slice) => {\n checkIsInRange(slice, 8);\n const value = slice.view.getFloat64(slice.bufferPos, false);\n slice.bufferPos += 8;\n return value;\n};\nexport const readAscii = (slice, length) => {\n checkIsInRange(slice, length);\n let str = '';\n for (let i = 0; i < length; i++) {\n str += String.fromCharCode(slice.bytes[slice.bufferPos++]);\n }\n return str;\n};\n", "import {BlobSource, UrlSource} from \"mediabunny\"\nimport {DecoderSource} from \"../fns/schematic.js\"\n\n// only streamable sources\nexport async function loadDecoderSource(source: DecoderSource): Promise<UrlSource | BlobSource> {\n\tif(source instanceof Blob) {\n\t\treturn new BlobSource(source)\n\t} else {\n\t\treturn new UrlSource(source)\n\t}\n}\n\n", "\nimport {ALL_FORMATS, Input} from \"mediabunny\"\n\nimport {Datafile} from \"../utils/datafile.js\"\nimport {DecoderSource} from \"../../driver/fns/schematic.js\"\nimport {loadDecoderSource} from \"../../driver/utils/load-decoder-source.js\"\n\nexport class Media {\n\tduration = 0\n\thasVideo = false\n\thasAudio = false\n\n\tconstructor(public datafile: Datafile) {}\n\n\tstatic async analyze(datafile: Datafile) {\n\t\tconst media = new this(datafile)\n\t\tconst duration = (await this.duration(datafile.url)) * 1000\n\t\tmedia.duration = duration\n\t\tconst {video, audio} = await this.#has(datafile.url)\n\t\tmedia.hasAudio = audio\n\t\tmedia.hasVideo = video\n\t\treturn media\n\t}\n\n\tstatic async duration(source: DecoderSource) {\n\t\tconst input = new Input({\n\t\t\tformats: ALL_FORMATS,\n\t\t\tsource: await loadDecoderSource(source)\n\t\t})\n\t\tconst duration = await input.computeDuration()\n\t\treturn Number(duration.toFixed(5)) // fix weird floating points\n\t}\n\n\tstatic async #has(source: DecoderSource) {\n\t\tconst input = new Input({\n\t\t\tformats: ALL_FORMATS,\n\t\t\tsource: await loadDecoderSource(source)\n\t\t})\n\t\treturn {\n\t\t\taudio: !!(await input.getPrimaryAudioTrack()),\n\t\t\tvideo: !!(await input.getPrimaryVideoTrack())\n\t\t}\n\t}\n}\n\n", "\nimport {GMap} from \"@e280/stz\"\nimport {Hash} from \"./basics.js\"\nimport {Media} from \"./media.js\"\nimport {Resource} from \"./resource.js\"\nimport {Datafile} from \"../utils/datafile.js\"\n\nexport class ResourcePool {\n\t#map = new GMap<Hash, Resource.Any>\n\n\t/** store a media file (avoids duplicates via hash) */\n\tasync store(datafile: Datafile) {\n\t\tconst media = await Media.analyze(datafile)\n\t\tconst {hash} = media.datafile.checksum\n\t\tconst {filename, bytes, url, blob} = media.datafile\n\n\t\tif (this.#map.has(hash)) {\n\t\t\tconst alreadyExists = this.#map.require(hash)\n\t\t\talreadyExists.filename = filename\n\t\t}\n\t\telse\n\t\t\tthis.#map.set(hash, {kind: \"media\", filename, bytes, url, blob, duration: media.duration})\n\n\t\treturn media\n\t}\n\n\trequire(hash: Hash) {\n\t\treturn this.#map.require(hash)\n\t}\n}\n", "declare const MsBrand: unique symbol\n\nexport type Ms = number & {\n\treadonly [MsBrand]: \"ms\"\n}\n\nexport const ms = (value: number): Ms =>\n\tvalue as Ms\n", "\nimport {Pub, pub} from \"@e280/stz\"\n\nimport {ms, Ms} from \"../../../units/ms.js\"\nimport {fps, Fps} from \"../../../units/fps.js\"\n\nexport type RealtimeGenerator = {\n\tplay(): void\n\tpause(): void\n\tsetFPS(v: Fps): void\n\tisPlaying(): boolean\n\tticks(): AsyncGenerator<void>\n\tonTick: Pub<[]>\n}\n\nexport const realtime = (): RealtimeGenerator => {\n\n\tlet playing = false\n\tlet frameRate = fps(60)\n\tlet frameDuration = 1000 / frameRate\n\n\tlet lastNow = 0\n\tlet lastComposite = 0\n\n\tconst onTick = pub()\n\tlet resolveTick: (() => void) | null = null\n\n\tconst loop = (now: number) => {\n\t\trequestAnimationFrame(loop)\n\n\t\tif (!playing) return\n\n\t\tlastNow = now\n\n\t\twhile (now - lastComposite >= frameDuration) {\n\t\t\tlastComposite += frameDuration\n\n\t\t\tresolveTick?.()\n\t\t\tresolveTick = null\n\t\t\tonTick()\n\t\t}\n\t}\n\n\tasync function* ticks(): AsyncGenerator<void> {\n\t\tlastNow = performance.now()\n\t\tlastComposite = lastNow\n\t\trequestAnimationFrame(loop)\n\n\t\twhile (true) {\n\t\t\tawait new Promise<void>(r => resolveTick = r)\n\t\t\tyield\n\t\t}\n\n\t}\n\n\treturn {\n\t\tplay() {\n\t\t\tif (playing) return\n\t\t\tplaying = true\n\t\t\tlastNow = performance.now()\n\t\t\tlastComposite = lastNow\n\t\t},\n\t\tpause() {\n\t\t\tplaying = false\n\t\t},\n\t\tsetFPS(v: Fps) {\n\t\t\tframeRate = v\n\t\t\tframeDuration = 1000 / frameRate\n\t\t},\n\t\tisPlaying() {\n\t\t\treturn playing\n\t\t},\n\t\tticks,\n\t\tonTick\n\t}\n}\n\nexport type FixedStepOptions = {\n\tfps: Fps\n\tduration: Ms\n}\n\nexport const fixedStep = async (\n\topts: FixedStepOptions,\n\tonFrame: (t: Ms, index: number) => Promise<void> | void\n) => {\n\tconst dt = ms(1000 / opts.fps)\n\tconst durationInSeconds = opts.duration / 1000\n\tconst total = Math.ceil(durationInSeconds * opts.fps)\n\n\tfor (let i = 0; i < total; i++) {\n\t\tconst t = ms(i * dt)\n\t\tawait onFrame(t, i)\n\t}\n}\n\n", "import { ExtensionType } from '../extensions/Extensions';\n\n/**\n * Extension for the browser environment.\n * @category environment\n * @internal\n */\nexport const browserExt = {\n extension: {\n type: ExtensionType.Environment,\n name: 'browser',\n priority: -1,\n },\n test: () => true,\n load: async () =>\n {\n await import('./browserAll');\n },\n};\n", "import { ExtensionType } from '../extensions/Extensions';\n\n/**\n * Extension for the webworker environment.\n * @category environment\n * @internal\n */\nexport const webworkerExt = {\n extension: {\n type: ExtensionType.Environment,\n name: 'webworker',\n priority: 0,\n },\n test: () => typeof self !== 'undefined' && self.WorkerGlobalScope !== undefined,\n load: async () =>\n {\n await import('./webworkerAll');\n },\n};\n", "import { DOMAdapter } from '../../environment/adapter';\nimport { AbstractRenderer } from '../../rendering/renderers/shared/system/AbstractRenderer';\n\nlet _isWebGLSupported: boolean | undefined;\n\n/**\n * Helper for checking for WebGL support in the current environment.\n *\n * Results are cached after first call for better performance.\n * @example\n * ```ts\n * // Basic WebGL support check\n * if (isWebGLSupported()) {\n * console.log('WebGL is available');\n * }\n * ```\n * @param failIfMajorPerformanceCaveat - Whether to fail if there is a major performance caveat\n * @returns True if WebGL is supported\n * @category utils\n * @standard\n */\nexport function isWebGLSupported(\n failIfMajorPerformanceCaveat?: boolean\n): boolean\n{\n if (_isWebGLSupported !== undefined) return _isWebGLSupported;\n\n _isWebGLSupported = ((): boolean =>\n {\n const contextOptions = {\n stencil: true,\n failIfMajorPerformanceCaveat:\n failIfMajorPerformanceCaveat\n ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat,\n };\n\n try\n {\n if (!DOMAdapter.get().getWebGLRenderingContext())\n {\n return false;\n }\n\n const canvas = DOMAdapter.get().createCanvas();\n let gl = canvas.getContext('webgl', contextOptions);\n\n const success = !!gl?.getContextAttributes()?.stencil;\n\n if (gl)\n {\n const loseContext = gl.getExtension('WEBGL_lose_context');\n\n if (loseContext)\n {\n loseContext.loseContext();\n }\n }\n\n gl = null;\n\n return success;\n }\n catch (_e)\n {\n return false;\n }\n })();\n\n return _isWebGLSupported;\n}\n", "import { DOMAdapter } from '../../environment/adapter';\n\nlet _isWebGPUSupported: boolean | undefined;\n\n/**\n * Helper for checking for WebGPU support in the current environment.\n * Results are cached after first call for better performance.\n * @example\n * ```ts\n * // Basic WebGPU support check\n * const hasWebGPU = await isWebGPUSupported();\n * console.log('WebGPU available:', hasWebGPU);\n * ```\n * @param options - The options for requesting a GPU adapter\n * @returns Promise that resolves to true if WebGPU is supported\n * @category utils\n * @standard\n */\nexport async function isWebGPUSupported(options: GPURequestAdapterOptions = {}): Promise<boolean>\n{\n if (_isWebGPUSupported !== undefined) return _isWebGPUSupported;\n\n _isWebGPUSupported = await (async (): Promise<boolean> =>\n {\n const gpu = DOMAdapter.get().getNavigator().gpu;\n\n if (!gpu)\n {\n return false;\n }\n\n try\n {\n const adapter = await gpu.requestAdapter(options) as GPUAdapter;\n\n // TODO and one of these!\n await adapter.requestDevice();\n\n return true;\n }\n catch (_e)\n {\n return false;\n }\n })();\n\n return _isWebGPUSupported;\n}\n", "import { isWebGLSupported } from '../../utils/browser/isWebGLSupported';\nimport { isWebGPUSupported } from '../../utils/browser/isWebGPUSupported';\nimport { AbstractRenderer } from './shared/system/AbstractRenderer';\n\nimport type { WebGLOptions } from './gl/WebGLRenderer';\nimport type { WebGPUOptions } from './gpu/WebGPURenderer';\nimport type { Renderer, RendererOptions } from './types';\n\n/**\n * Options for {@link autoDetectRenderer}.\n * @category rendering\n * @advanced\n */\nexport interface AutoDetectOptions extends RendererOptions\n{\n /** The preferred renderer type. WebGPU is recommended as its generally faster than WebGL. */\n preference?: 'webgl' | 'webgpu'// | 'canvas';\n /** Optional WebGPUOptions to pass only to WebGPU renderer. */\n webgpu?: Partial<WebGPUOptions>;\n /** Optional WebGLOptions to pass only to the WebGL renderer */\n webgl?: Partial<WebGLOptions>;\n}\n\nconst renderPriority = ['webgl', 'webgpu', 'canvas'];\n\n/**\n * Automatically determines the most appropriate renderer for the current environment.\n *\n * The function will prioritize the WebGL renderer as it is the most tested safe API to use.\n * In the near future as WebGPU becomes more stable and ubiquitous, it will be prioritized over WebGL.\n *\n * The selected renderer's code is then dynamically imported to optimize\n * performance and minimize the initial bundle size.\n *\n * To maximize the benefits of dynamic imports, it's recommended to use a modern bundler\n * that supports code splitting. This will place the renderer code in a separate chunk,\n * which is loaded only when needed.\n * @example\n *\n * // create a renderer\n * const renderer = await autoDetectRenderer({\n * width: 800,\n * height: 600,\n * antialias: true,\n * });\n *\n * // custom for each renderer\n * const renderer = await autoDetectRenderer({\n * width: 800,\n * height: 600,\n * webgpu:{\n * antialias: true,\n * backgroundColor: 'red'\n * },\n * webgl:{\n * antialias: true,\n * backgroundColor: 'green'\n * }\n * });\n * @param options - A partial configuration object based on the `AutoDetectOptions` type.\n * @returns A Promise that resolves to an instance of the selected renderer.\n * @category rendering\n * @standard\n */\nexport async function autoDetectRenderer(options: Partial<AutoDetectOptions>): Promise<Renderer>\n{\n let preferredOrder: string[] = [];\n\n if (options.preference)\n {\n preferredOrder.push(options.preference);\n\n renderPriority.forEach((item) =>\n {\n if (item !== options.preference)\n {\n preferredOrder.push(item);\n }\n });\n }\n else\n {\n preferredOrder = renderPriority.slice();\n }\n\n let RendererClass: new () => Renderer;\n let finalOptions: Partial<AutoDetectOptions> = {};\n\n for (let i = 0; i < preferredOrder.length; i++)\n {\n const rendererType = preferredOrder[i];\n\n if (rendererType === 'webgpu' && (await isWebGPUSupported()))\n {\n const { WebGPURenderer } = await import('./gpu/WebGPURenderer');\n\n RendererClass = WebGPURenderer;\n\n finalOptions = { ...options, ...options.webgpu };\n\n break;\n }\n else if (\n rendererType === 'webgl'\n && isWebGLSupported(\n options.failIfMajorPerformanceCaveat\n ?? AbstractRenderer.defaultOptions.failIfMajorPerformanceCaveat\n )\n )\n {\n const { WebGLRenderer } = await import('./gl/WebGLRenderer');\n\n RendererClass = WebGLRenderer;\n\n finalOptions = { ...options, ...options.webgl };\n\n break;\n }\n else if (rendererType === 'canvas')\n {\n finalOptions = { ...options };\n\n throw new Error('CanvasRenderer is not yet implemented');\n }\n }\n\n delete finalOptions.webgpu;\n delete finalOptions.webgl;\n\n if (!RendererClass)\n {\n throw new Error('No available renderer for the current environment');\n }\n\n const renderer = new RendererClass();\n\n await renderer.init(finalOptions);\n\n return renderer;\n}\n", "import { ObservablePoint } from '../../maths/point/ObservablePoint';\nimport { deprecation, v8_0_0 } from '../../utils/logging/deprecation';\nimport { ViewContainer, type ViewContainerOptions } from '../view/ViewContainer';\n\nimport type { Size } from '../../maths/misc/Size';\nimport type { PointData } from '../../maths/point/PointData';\nimport type { View } from '../../rendering/renderers/shared/view/View';\nimport type { Optional } from '../container/container-mixins/measureMixin';\nimport type { DestroyOptions } from '../container/destroyTypes';\nimport type { HTMLTextStyle, HTMLTextStyleOptions } from '../text-html/HTMLTextStyle';\nimport type { TextStyle, TextStyleOptions } from './TextStyle';\n\n/**\n * A string or number that can be used as text.\n * @example\n * ```ts\n * const text: TextString = 'Hello Pixi!';\n * const text2: TextString = 12345;\n * const text3: TextString = { toString: () => 'Hello Pixi!' };\n * ```\n * @category text\n * @standard\n */\nexport type TextString = string | number | { toString: () => string };\n/**\n * A union of all text styles, including HTML, Bitmap and Canvas text styles.\n * This is used to allow for any text style to be passed to a text object.\n * @example\n * ```ts\n * import { TextStyle, HTMLTextStyle } from 'pixi.js';\n * const style: AnyTextStyle = new TextStyle({ fontSize: 24 });\n * const htmlStyle: AnyTextStyle = new HTMLTextStyle({ fontSize: '24px' });\n * ```\n * @category text\n * @standard\n * @see TextStyle\n * @see HTMLTextStyle\n */\nexport type AnyTextStyle = TextStyle | HTMLTextStyle;\n/**\n * A union of all text style options, including HTML, Bitmap and Canvas text style options.\n * This is used to allow for any text style options to be passed to a text object.\n * @example\n * ```ts\n * import { TextStyleOptions, HTMLTextStyleOptions } from 'pixi.js';\n * const styleOptions: AnyTextStyleOptions = { fontSize: 24 } as TextStyleOptions;\n * const htmlStyleOptions: AnyTextStyleOptions = { fontSize: '24px' } as HTMLTextStyleOptions;\n * ```\n * @category text\n * @standard\n * @see TextStyleOptions\n * @see HTMLTextStyleOptions\n */\nexport type AnyTextStyleOptions = TextStyleOptions | HTMLTextStyleOptions;\n\n/**\n * Options for creating text objects in PixiJS. This interface defines the common properties\n * used across different text rendering implementations (Canvas, HTML, and Bitmap).\n * @example\n * ```ts\n * // Create basic text with minimal options\n * const basicText = new Text({\n * text: 'Hello Pixi!',\n * style: {\n * fontSize: 24,\n * fill: 0xff1010\n * }\n * });\n *\n * // Create text with advanced styling\n * const styledText = new Text({\n * text: 'Styled Text',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 32,\n * fill: new FillGradient({\n * end: { x: 1, y: 1 },\n * stops: [\n * { color: 0xff0000, offset: 0 }, // Red at start\n * { color: 0x0000ff, offset: 1 }, // Blue at end\n * ]\n * }),\n * stroke: { color: '#4a1850', width: 5 },\n * dropShadow: {\n * color: '#000000',\n * blur: 4,\n * distance: 6\n * },\n * align: 'center'\n * },\n * anchor: 0.5,\n * resolution: window.devicePixelRatio\n * });\n *\n * // Create multiline text with word wrap\n * const wrappedText = new Text({\n * text: 'This is a long piece of text that will wrap onto multiple lines',\n * style: {\n * fontSize: 20,\n * wordWrap: true,\n * wordWrapWidth: 200,\n * lineHeight: 30\n * },\n * resolution: 2,\n * roundPixels: true\n * });\n * ```\n * @category text\n * @standard\n * @noInheritDoc\n */\nexport interface TextOptions<\n TEXT_STYLE extends TextStyle = TextStyle,\n TEXT_STYLE_OPTIONS extends TextStyleOptions = TextStyleOptions,\n> extends PixiMixins.TextOptions, ViewContainerOptions\n{\n /**\n * The anchor point of the text that controls the origin point for positioning and rotation.\n * Can be a number (same value for x/y) or a PointData object.\n * - (0,0) is top-left\n * - (0.5,0.5) is center\n * - (1,1) is bottom-right\n * ```ts\n * // Set anchor to center\n * const text = new Text({\n * text: 'Hello Pixi!',\n * anchor: 0.5 // Same as { x: 0.5, y: 0.5 }\n * });\n * // Set anchor to top-left\n * const text2 = new Text({\n * text: 'Hello Pixi!',\n * anchor: { x: 0, y: 0 } // Top-left corner\n * });\n * // Set anchor to bottom-right\n * const text3 = new Text({\n * text: 'Hello Pixi!',\n * anchor: { x: 1, y: 1 } // Bottom-right corner\n * });\n * ```\n * @default { x: 0, y: 0 }\n */\n anchor?: PointData | number;\n /**\n * The text content to display. Use '\\n' for line breaks.\n * Accepts strings, numbers, or objects with toString() method.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Hello Pixi!',\n * });\n * const multilineText = new Text({\n * text: 'Line 1\\nLine 2\\nLine 3',\n * });\n * const numberText = new Text({\n * text: 12345, // Will be converted to '12345'\n * });\n * const objectText = new Text({\n * text: { toString: () => 'Object Text' }, // Custom toString\n * });\n * ```\n * @default ''\n */\n text?: TextString;\n /**\n * The resolution/device pixel ratio for rendering.\n * Higher values result in sharper text at the cost of performance.\n * Set to null for auto-resolution based on device.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Hello Pixi!',\n * resolution: 2 // High DPI for sharper text\n * });\n * const autoResText = new Text({\n * text: 'Auto Resolution',\n * resolution: null // Use device's pixel ratio\n * });\n * ```\n * @default null\n */\n resolution?: number;\n /**\n * The style configuration for the text.\n * Can be a TextStyle instance or a configuration object.\n * Supports canvas text styles, HTML text styles, and bitmap text styles.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Styled Text',\n * style: {\n * fontSize: 24,\n * fill: 0xff1010, // Red color\n * fontFamily: 'Arial',\n * align: 'center', // Center alignment\n * stroke: { color: '#4a1850', width: 5 }, // Purple stroke\n * dropShadow: {\n * color: '#000000', // Black shadow\n * blur: 4, // Shadow blur\n * distance: 6 // Shadow distance\n * }\n * }\n * });\n * const htmlText = new HTMLText({\n * text: 'HTML Styled Text',\n * style: {\n * fontSize: '20px',\n * fill: 'blue',\n * fontFamily: 'Verdana',\n * }\n * });\n * const bitmapText = new BitmapText({\n * text: 'Bitmap Styled Text',\n * style: {\n * fontName: 'Arial',\n * fontSize: 32,\n * }\n * })\n */\n style?: TEXT_STYLE | TEXT_STYLE_OPTIONS;\n /**\n * Whether to round the x/y position to whole pixels.\n * Enabling can prevent anti-aliasing of text edges but may cause slight position shifting.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Rounded Text',\n * roundPixels: true // Rounds position to whole pixels\n * });\n * @default false\n */\n roundPixels?: boolean;\n}\n\n/**\n * An abstract Text class, used by all text type in Pixi. This includes Canvas, HTML, and Bitmap Text.\n * @see Text\n * @see BitmapText\n * @see HTMLText\n * @category text\n * @advanced\n */\nexport abstract class AbstractText<\n TEXT_STYLE extends TextStyle = TextStyle,\n TEXT_STYLE_OPTIONS extends TextStyleOptions = TextStyleOptions,\n TEXT_OPTIONS extends TextOptions<TEXT_STYLE, TEXT_STYLE_OPTIONS> = TextOptions<TEXT_STYLE, TEXT_STYLE_OPTIONS>,\n GPU_DATA extends { destroy: () => void } = any\n> extends ViewContainer<GPU_DATA> implements View\n{\n /** @internal */\n public batched = true;\n /** @internal */\n public _anchor: ObservablePoint;\n\n /** @internal */\n public _resolution: number = null;\n /** @internal */\n public _autoResolution: boolean = true;\n\n /** @internal */\n public _style: TEXT_STYLE;\n /** @internal */\n public _didTextUpdate = true;\n\n protected _text: string;\n private readonly _styleClass: new (options: TEXT_STYLE_OPTIONS) => TEXT_STYLE;\n\n constructor(\n options: TEXT_OPTIONS,\n styleClass: new (options: TEXT_STYLE_OPTIONS) => TEXT_STYLE\n )\n {\n const { text, resolution, style, anchor, width, height, roundPixels, ...rest } = options;\n\n super({\n ...rest\n });\n\n this._styleClass = styleClass;\n\n this.text = text ?? '';\n\n this.style = style;\n\n this.resolution = resolution ?? null;\n\n this.allowChildren = false;\n\n this._anchor = new ObservablePoint(\n {\n _onUpdate: () =>\n {\n this.onViewUpdate();\n },\n },\n );\n\n if (anchor) this.anchor = anchor;\n this.roundPixels = roundPixels ?? false;\n\n // needs to be set after the container has initiated\n if (width !== undefined) this.width = width;\n if (height !== undefined) this.height = height;\n }\n\n /**\n * The anchor point of the text that controls the origin point for positioning and rotation.\n * Can be a number (same value for x/y) or a PointData object.\n * - (0,0) is top-left\n * - (0.5,0.5) is center\n * - (1,1) is bottom-right\n * ```ts\n * // Set anchor to center\n * const text = new Text({\n * text: 'Hello Pixi!',\n * anchor: 0.5 // Same as { x: 0.5, y: 0.5 }\n * });\n * // Set anchor to top-left\n * const text2 = new Text({\n * text: 'Hello Pixi!',\n * anchor: { x: 0, y: 0 } // Top-left corner\n * });\n * // Set anchor to bottom-right\n * const text3 = new Text({\n * text: 'Hello Pixi!',\n * anchor: { x: 1, y: 1 } // Bottom-right corner\n * });\n * ```\n * @default { x: 0, y: 0 }\n */\n get anchor(): ObservablePoint\n {\n return this._anchor;\n }\n\n set anchor(value: PointData | number)\n {\n typeof value === 'number' ? this._anchor.set(value) : this._anchor.copyFrom(value);\n }\n\n /**\n * The text content to display. Use '\\n' for line breaks.\n * Accepts strings, numbers, or objects with toString() method.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Hello Pixi!',\n * });\n * const multilineText = new Text({\n * text: 'Line 1\\nLine 2\\nLine 3',\n * });\n * const numberText = new Text({\n * text: 12345, // Will be converted to '12345'\n * });\n * const objectText = new Text({\n * text: { toString: () => 'Object Text' }, // Custom toString\n * });\n *\n * // Update text dynamically\n * text.text = 'Updated Text'; // Re-renders with new text\n * text.text = 67890; // Updates to '67890'\n * text.text = { toString: () => 'Dynamic Text' }; // Uses custom toString method\n * // Clear text\n * text.text = ''; // Clears the text\n * ```\n * @default ''\n */\n set text(value: TextString)\n {\n // check its a string\n value = value.toString();\n\n if (this._text === value) return;\n\n this._text = value as string;\n this.onViewUpdate();\n }\n\n get text(): string\n {\n return this._text;\n }\n\n /**\n * The resolution/device pixel ratio for rendering.\n * Higher values result in sharper text at the cost of performance.\n * Set to null for auto-resolution based on device.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Hello Pixi!',\n * resolution: 2 // High DPI for sharper text\n * });\n * const autoResText = new Text({\n * text: 'Auto Resolution',\n * resolution: null // Use device's pixel ratio\n * });\n * ```\n * @default null\n */\n set resolution(value: number)\n {\n this._autoResolution = value === null;\n this._resolution = value;\n this.onViewUpdate();\n }\n\n get resolution(): number\n {\n return this._resolution;\n }\n\n get style(): TEXT_STYLE\n {\n return this._style;\n }\n\n /**\n * The style configuration for the text.\n * Can be a TextStyle instance or a configuration object.\n * Supports canvas text styles, HTML text styles, and bitmap text styles.\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Styled Text',\n * style: {\n * fontSize: 24,\n * fill: 0xff1010, // Red color\n * fontFamily: 'Arial',\n * align: 'center', // Center alignment\n * stroke: { color: '#4a1850', width: 5 }, // Purple stroke\n * dropShadow: {\n * color: '#000000', // Black shadow\n * blur: 4, // Shadow blur\n * distance: 6 // Shadow distance\n * }\n * }\n * });\n * const htmlText = new HTMLText({\n * text: 'HTML Styled Text',\n * style: {\n * fontSize: '20px',\n * fill: 'blue',\n * fontFamily: 'Verdana',\n * }\n * });\n * const bitmapText = new BitmapText({\n * text: 'Bitmap Styled Text',\n * style: {\n * fontName: 'Arial',\n * fontSize: 32,\n * }\n * })\n *\n * // Update style dynamically\n * text.style = {\n * fontSize: 30, // Change font size\n * fill: 0x00ff00, // Change color to green\n * align: 'right', // Change alignment to right\n * stroke: { color: '#000000', width: 2 }, // Add black stroke\n * }\n */\n set style(style: TEXT_STYLE | Partial<TEXT_STYLE> | TEXT_STYLE_OPTIONS)\n {\n style ||= {};\n\n this._style?.off('update', this.onViewUpdate, this);\n\n if (style instanceof this._styleClass)\n {\n this._style = style as TEXT_STYLE;\n }\n else\n {\n this._style = new this._styleClass(style as TEXT_STYLE_OPTIONS);\n }\n\n this._style.on('update', this.onViewUpdate, this);\n this.onViewUpdate();\n }\n\n /**\n * The width of the sprite, setting this will actually modify the scale to achieve the value set.\n * @example\n * ```ts\n * // Set width directly\n * texture.width = 200;\n * console.log(texture.scale.x); // Scale adjusted to match width\n *\n * // For better performance when setting both width and height\n * texture.setSize(300, 400); // Avoids recalculating bounds twice\n * ```\n */\n override get width(): number\n {\n return Math.abs(this.scale.x) * this.bounds.width;\n }\n\n override set width(value: number)\n {\n this._setWidth(value, this.bounds.width);\n }\n\n /**\n * The height of the sprite, setting this will actually modify the scale to achieve the value set.\n * @example\n * ```ts\n * // Set height directly\n * texture.height = 200;\n * console.log(texture.scale.y); // Scale adjusted to match height\n *\n * // For better performance when setting both width and height\n * texture.setSize(300, 400); // Avoids recalculating bounds twice\n * ```\n */\n override get height(): number\n {\n return Math.abs(this.scale.y) * this.bounds.height;\n }\n\n override set height(value: number)\n {\n this._setHeight(value, this.bounds.height);\n }\n\n /**\n * Retrieves the size of the Text as a [Size]{@link Size} object based on the texture dimensions and scale.\n * This is faster than getting width and height separately as it only calculates the bounds once.\n * @example\n * ```ts\n * // Basic size retrieval\n * const text = new Text({\n * text: 'Hello Pixi!',\n * style: { fontSize: 24 }\n * });\n * const size = text.getSize();\n * console.log(`Size: ${size.width}x${size.height}`);\n *\n * // Reuse existing size object\n * const reuseSize = { width: 0, height: 0 };\n * text.getSize(reuseSize);\n * ```\n * @param out - Optional object to store the size in, to avoid allocating a new object\n * @returns The size of the Sprite\n * @see {@link Text#width} For getting just the width\n * @see {@link Text#height} For getting just the height\n * @see {@link Text#setSize} For setting both width and height\n */\n public override getSize(out?: Size): Size\n {\n out ||= {} as Size;\n out.width = Math.abs(this.scale.x) * this.bounds.width;\n out.height = Math.abs(this.scale.y) * this.bounds.height;\n\n return out;\n }\n\n /**\n * Sets the size of the Text to the specified width and height.\n * This is faster than setting width and height separately as it only recalculates bounds once.\n * @example\n * ```ts\n * // Basic size setting\n * const text = new Text({\n * text: 'Hello Pixi!',\n * style: { fontSize: 24 }\n * });\n * text.setSize(100, 200); // Width: 100, Height: 200\n *\n * // Set uniform size\n * text.setSize(100); // Sets both width and height to 100\n *\n * // Set size with object\n * text.setSize({\n * width: 200,\n * height: 300\n * });\n * ```\n * @param value - This can be either a number or a {@link Size} object\n * @param height - The height to set. Defaults to the value of `width` if not provided\n * @see {@link Text#width} For setting width only\n * @see {@link Text#height} For setting height only\n */\n public override setSize(value: number | Optional<Size, 'height'>, height?: number)\n {\n if (typeof value === 'object')\n {\n height = value.height ?? value.width;\n value = value.width;\n }\n else\n {\n height ??= value;\n }\n\n value !== undefined && this._setWidth(value, this.bounds.width);\n height !== undefined && this._setHeight(height, this.bounds.height);\n }\n\n /**\n * Checks if the object contains the given point in local coordinates.\n * Uses the text's bounds for hit testing.\n * @example\n * ```ts\n * // Basic point check\n * const localPoint = { x: 50, y: 25 };\n * const contains = text.containsPoint(localPoint);\n * console.log('Point is inside:', contains);\n * ```\n * @param point - The point to check in local coordinates\n * @returns True if the point is within the text's bounds\n * @see {@link Container#toLocal} For converting global coordinates to local\n */\n public override containsPoint(point: PointData)\n {\n const width = this.bounds.width;\n const height = this.bounds.height;\n\n const x1 = -width * this.anchor.x;\n let y1 = 0;\n\n if (point.x >= x1 && point.x <= x1 + width)\n {\n y1 = -height * this.anchor.y;\n\n if (point.y >= y1 && point.y <= y1 + height) return true;\n }\n\n return false;\n }\n\n /** @internal */\n public override onViewUpdate()\n {\n if (!this.didViewUpdate) this._didTextUpdate = true;\n super.onViewUpdate();\n }\n\n /**\n * Destroys this text renderable and optionally its style texture.\n * @param options - Options parameter. A boolean will act as if all options\n * have been set to that value\n * @example\n * // Destroys the text and its style\n * text.destroy({ style: true, texture: true, textureSource: true });\n * text.destroy(true);\n * text.destroy() // Destroys the text, but not its style\n */\n public override destroy(options: DestroyOptions = false): void\n {\n super.destroy(options);\n\n (this as any).owner = null;\n this._bounds = null;\n this._anchor = null;\n\n if (typeof options === 'boolean' ? options : options?.style)\n {\n this._style.destroy(options);\n }\n\n this._style = null;\n this._text = null;\n }\n\n /**\n * Returns a unique key for this instance.\n * This key is used for caching.\n * @returns {string} Unique key for the instance\n */\n public get styleKey(): string\n {\n return `${this._text}:${this._style.styleKey}:${this._resolution}`;\n }\n}\n\n/**\n * Helper function to ensure consistent handling of text options across different text classes.\n * This function handles both the new options object format and the deprecated parameter format.\n * @example\n * // New recommended way:\n * const options = ensureTextOptions([{\n * text: \"Hello\",\n * style: { fontSize: 20 }\n * }], \"Text\");\n *\n * // Deprecated way (will show warning in debug):\n * const options = ensureTextOptions([\"Hello\", { fontSize: 20 }], \"Text\");\n * @param args - Arguments passed to text constructor\n * @param name - Name of the text class (used in deprecation warning)\n * @returns Normalized text options object\n * @template TEXT_OPTIONS - The type of the text options\n * @internal\n */\nexport function ensureTextOptions<\n TEXT_OPTIONS extends TextOptions\n>(\n args: any[],\n name: string\n): TEXT_OPTIONS\n{\n let options = (args[0] ?? {}) as TEXT_OPTIONS;\n\n // @deprecated\n if (typeof options === 'string' || args[1])\n {\n // #if _DEBUG\n deprecation(v8_0_0, `use new ${name}({ text: \"hi!\", style }) instead`);\n // #endif\n\n options = {\n text: options,\n style: args[1],\n } as unknown as TEXT_OPTIONS;\n }\n\n return options;\n}\n", "import { TextureStyle, type TextureStyleOptions } from '../../rendering/renderers/shared/texture/TextureStyle';\nimport { AbstractText, ensureTextOptions } from './AbstractText';\nimport { type BatchableText } from './canvas/BatchableText';\nimport { CanvasTextGenerator } from './canvas/CanvasTextGenerator';\nimport { CanvasTextMetrics } from './canvas/CanvasTextMetrics';\nimport { TextStyle } from './TextStyle';\n\nimport type { View } from '../../rendering/renderers/shared/view/View';\nimport type { TextOptions, TextString } from './AbstractText';\nimport type { TextStyleOptions } from './TextStyle';\n\n// eslint-disable-next-line requireExport/require-export-jsdoc, requireMemberAPI/require-member-api-doc\nexport interface Text extends PixiMixins.Text, AbstractText<\n TextStyle,\n TextStyleOptions,\n CanvasTextOptions,\n BatchableText\n> {}\n\n/**\n * Constructor options used for `Text` instances. These options extend TextOptions with\n * canvas-specific features like texture styling.\n * @example\n * ```ts\n * // Create basic canvas text\n * const text = new Text({\n * text: 'Hello Pixi!',\n * style: {\n * fontSize: 24,\n * fill: 0xff1010,\n * }\n * });\n *\n * // Create text with custom texture style\n * const customText = new Text({\n * text: 'Custom Text',\n * style: {\n * fontSize: 32,\n * fill: 0x4a4a4a\n * },\n * textureStyle: {\n * scaleMode: 'nearest',\n * }\n * });\n * ```\n * @extends TextOptions\n * @category text\n * @standard\n */\nexport interface CanvasTextOptions extends TextOptions\n{\n /**\n * Optional texture style to use for the text texture. This allows fine control over\n * how the text is rendered to a texture before being displayed.\n *\n * The texture style can affect:\n * - Scale mode (nearest/linear)\n * - Resolution\n * - Format (rgb/rgba)\n * - Alpha handling\n * @example\n * ```ts\n * const text = new Text({\n * text: 'Crisp Text',\n * textureStyle: {\n * scaleMode: 'nearest', // Pixel-perfect scaling\n * }\n * });\n * ```\n * @advanced\n */\n textureStyle?: TextureStyle | TextureStyleOptions;\n}\n\n/**\n * A powerful text rendering class that creates one or multiple lines of text using the Canvas API.\n * Provides rich text styling capabilities with runtime modifications.\n *\n * Key features:\n * - Dynamic text content and styling\n * - Multi-line text support\n * - Word wrapping\n * - Custom texture styling\n * - High-quality text rendering\n * @example\n * ```ts\n * import { Text } from 'pixi.js';\n *\n * // Basic text creation\n * const basicText = new Text({\n * text: 'Hello Pixi!',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xff1010,\n * align: 'center',\n * }\n * });\n *\n * // Rich text with multiple styles\n * const richText = new Text({\n * text: 'Styled\\nMultiline\\nText',\n * style: {\n * fontFamily: 'Arial',\n * fontSize: 36,\n * fill: 'red',\n * stroke: { color: '#4a1850', width: 5 },\n * align: 'center',\n * lineHeight: 45,\n * dropShadow: {\n * color: '#000000',\n * blur: 4,\n * distance: 6,\n * }\n * },\n * anchor: 0.5,\n * });\n *\n * // Text with custom texture settings\n * const crispText = new Text({\n * text: 'High Quality Text',\n * style: {\n * fontSize: 24,\n * fill: 0x4a4a4a,\n * },\n * textureStyle: {\n * scaleMode: 'nearest',\n * }\n * });\n *\n * // Word-wrapped text\n * const wrappedText = new Text({\n * text: 'This is a long piece of text that will automatically wrap to multiple lines',\n * style: {\n * fontSize: 20,\n * wordWrap: true,\n * wordWrapWidth: 200,\n * lineHeight: 30,\n * }\n * });\n * ```\n *\n * Performance Considerations:\n * - Each text instance creates its own texture\n * - Texture is regenerated when text or style changes\n * - Use BitmapText for better performance with static text\n * - Consider texture style options for quality vs performance tradeoffs\n * @category text\n * @standard\n * @see {@link TextStyle} For detailed style options\n * @see {@link BitmapText} For better performance with static text\n * @see {@link HTMLText} For HTML/CSS-based text rendering\n */\nexport class Text\n extends AbstractText<TextStyle, TextStyleOptions, CanvasTextOptions, BatchableText>\n implements View\n{\n /** @internal */\n public override readonly renderPipeId: string = 'text';\n\n /**\n * Optional texture style to use for the text.\n * > [!NOTE] Text is not updated when this property is updated,\n * > you must update the text manually by calling `text.onViewUpdate()`\n * @advanced\n */\n public textureStyle?: TextureStyle;\n\n /**\n * @param {CanvasTextOptions} options - The options of the text.\n */\n constructor(options?: CanvasTextOptions);\n /** @deprecated since 8.0.0 */\n constructor(text?: TextString, options?: Partial<TextStyle>);\n constructor(...args: [CanvasTextOptions?] | [TextString, Partial<TextStyle>])\n {\n const options = ensureTextOptions<CanvasTextOptions>(args, 'Text');\n\n super(options, TextStyle);\n\n if (options.textureStyle)\n {\n this.textureStyle = options.textureStyle instanceof TextureStyle\n ? options.textureStyle\n : new TextureStyle(options.textureStyle);\n }\n }\n\n /** @private */\n protected updateBounds()\n {\n const bounds = this._bounds;\n const anchor = this._anchor;\n\n let width = 0;\n let height = 0;\n\n if (this._style.trim)\n {\n const { frame, canvasAndContext } = CanvasTextGenerator.getCanvasAndContext({\n text: this.text,\n style: this._style,\n resolution: 1,\n });\n\n CanvasTextGenerator.returnCanvasAndContext(canvasAndContext);\n\n width = frame.width;\n height = frame.height;\n }\n else\n {\n const canvasMeasurement = CanvasTextMetrics.measureText(\n this._text,\n this._style\n );\n\n width = canvasMeasurement.width;\n height = canvasMeasurement.height;\n }\n\n bounds.minX = (-anchor._x * width);\n bounds.maxX = bounds.minX + width;\n bounds.minY = (-anchor._y * height);\n bounds.maxY = bounds.minY + height;\n }\n}\n", "import { browserExt } from './environment-browser/browserExt';\nimport { webworkerExt } from './environment-webworker/webworkerExt';\nimport { extensions } from './extensions/Extensions';\nimport './rendering/init';\nimport './spritesheet/init';\n\nexport * from './accessibility';\nexport * from './advanced-blend-modes';\nexport * from './app';\nexport * from './assets';\nexport * from './color';\nexport * from './compressed-textures';\nexport * from './culling';\nexport * from './dom';\nexport * from './environment';\nexport * from './environment-browser';\nexport * from './environment-webworker';\nexport * from './events';\nexport * from './extensions';\nexport * from './filters';\nexport * from './maths';\nexport * from './prepare';\nexport * from './rendering';\nexport * from './scene';\nexport * from './spritesheet';\nexport * from './ticker';\nexport * from './utils';\n\nextensions.add(browserExt, webworkerExt);\n", "import {Matrix} from \"pixi.js\"\nimport {Transform} from \"../types.js\"\n\nexport const transformToMat6 = (t: Transform): Mat6 => {\n\tconst [pos, scl, rotDeg] = t\n\tconst [x, y] = pos\n\tconst [sx, sy] = scl\n\tconst r = rotDeg * Math.PI / 180\n\tconst cos = Math.cos(r)\n\tconst sin = Math.sin(r)\n\treturn [cos * sx, sin * sx, -sin * sy, cos * sy, x, y]\n}\n\nexport const mat6ToMatrix = ([a, b, c, d, tx, ty]: Mat6): Matrix =>\n\tnew Matrix(a, b, c, d, tx, ty)\n\nexport const transformToMatrix = (t: Transform) => mat6ToMatrix(transformToMat6(t))\n\nexport const mul6 = (local: Mat6, parent: Mat6): Mat6 => {\n\tconst [a1, b1, c1, d1, tx1, ty1] = local\n\tconst [a2, b2, c2, d2, tx2, ty2] = parent\n\treturn [\n\t\ta1 * a2 + c1 * b2,\n\t\tb1 * a2 + d1 * b2,\n\t\ta1 * c2 + c1 * d2,\n\t\tb1 * c2 + d1 * d2,\n\t\ta1 * tx2 + c1 * ty2 + tx1,\n\t\tb1 * tx2 + d1 * ty2 + ty1\n\t]\n}\n\nexport const I6: Mat6 = [1, 0, 0, 1, 0, 0]\nexport type Mat6 = [a: number, b: number, c: number, d: number, tx: number, ty: number]\n", "\nimport {ms, Ms} from '../../../units/ms.js'\nimport {Id, TimelineFile} from '../../parts/basics.js'\nimport {I6, Mat6, mul6, transformToMat6} from '../../utils/matrix.js'\nimport {ContainerItem, Item, Kind, PlayableItem} from '../../parts/item.js'\n\nfunction isPlayableItem(item: Item.Any): item is PlayableItem {\n\treturn 'duration' in item\n}\n\ntype WalkAtCallbacks = {\n\tsequence: (x: Item.Sequence, localTime: Ms, ancestors: ContainerItem[]) => void\n\tstack: (x: Item.Stack, localTime: Ms, ancestors: ContainerItem[]) => void\n\tvideo: (x: Item.Video, localTime: Ms, ancestors: ContainerItem[]) => void\n\ttext: (x: Item.Text, localTime: Ms, ancestors: ContainerItem[]) => void\n\taudio: (x: Item.Audio, localTime: Ms, ancestors: ContainerItem[]) => void\n}\n\ntype WalkCallbacks = {\n\tsequence?: (x: Item.Sequence, matrix: Mat6, ancestors: ContainerItem[]) => void\n\tstack?: (x: Item.Stack, matrix: Mat6, ancestors: ContainerItem[]) => void\n\tvideo?: (x: Item.Video, matrix: Mat6, ancestors: ContainerItem[]) => void\n\ttext?: (x: Item.Text, matrix: Mat6, ancestors: ContainerItem[]) => void\n\taudio?: (x: Item.Audio) => void\n}\n\ninterface Props {\n\ttimeline: TimelineFile\n\ttimecode: Ms\n}\n\ninterface At {\n\titem: Item.Any\n\tlocalTime: Ms\n\tancestors: ContainerItem[]\n}\n\nexport function itemsAt(p: Props): At[] {\n\tconst results: At[] = []\n\tconst itemMap = new Map(p.timeline.items.map(item => [item.id, item]))\n\n\twalkAt(p.timeline.rootId, itemMap, p.timecode, {\n\t\tsequence: () => { },\n\t\tstack: () => { },\n\t\tvideo: (item, localTime, ancestors) => results.push({ item, localTime, ancestors }),\n\t\ttext: (item, localTime, ancestors) => results.push({ item, localTime, ancestors }),\n\t\taudio: (item, localTime, ancestors) => results.push({ item, localTime, ancestors })\n\t})\n\n\treturn results\n}\n\ninterface FromProps {\n\ttimeline: TimelineFile\n\tfrom: Ms\n}\n\nexport function itemsFrom(p: FromProps): At[] {\n\tconst results: At[] = []\n\tconst itemMap = new Map(p.timeline.items.map(item => [item.id, item]))\n\n\twalkFrom(p.timeline.rootId, itemMap, p.from, {\n\t\tsequence: () => { },\n\t\tstack: () => { },\n\t\tvideo: (item, localTime, ancestors) => results.push({ item, localTime, ancestors }),\n\t\ttext: (item, localTime, ancestors) => results.push({ item, localTime, ancestors }),\n\t\taudio: (item, localTime, ancestors) => results.push({ item, localTime, ancestors })\n\t})\n\n\treturn results\n}\n\nexport function computeWorldMatrix(\n\titems: Map<Id, Item.Any>,\n\tancestors: ContainerItem[],\n\titem: Item.Any\n): Mat6 {\n\tlet world = I6\n\n\tfor (const ancestor of ancestors) {\n\t\tworld = applySpatialIfAny(items, ancestor, world)\n\t}\n\n\treturn applySpatialIfAny(items, item, world)\n}\n\nfunction applySpatialIfAny(\n\titems: Map<Id, Item.Any>,\n\titem: Item.Any,\n\tparentMatrix: Mat6\n) {\n\tif (\"spatialId\" in item && item.spatialId) {\n\t\tconst spatial = items.get(item.spatialId) as Item.Spatial | undefined\n\t\tif (spatial?.enabled) {\n\t\t\tconst local = transformToMat6(spatial.transform)\n\t\t\treturn mul6(local, parentMatrix)\n\t\t}\n\t}\n\treturn parentMatrix\n}\n\nexport function walk(\n\tid: Id,\n\titems: Map<Id, Item.Any>,\n\tparentMatrix: Mat6,\n\tcallbacks: WalkCallbacks,\n\tancestors: ContainerItem[] = []\n) {\n\tconst item = items.get(id)\n\tif (!item) return\n\n\tlet currentMatrix = parentMatrix\n\n\tif (\"spatialId\" in item && item.spatialId) {\n\t\tconst spatial = items.get(item.spatialId) as Item.Spatial\n\t\tif (spatial.enabled) {\n\t\t\tconst local = transformToMat6(spatial.transform)\n\t\t\tcurrentMatrix = mul6(local, currentMatrix)\n\t\t}\n\t}\n\n\tswitch (item.kind) {\n\t\tcase Kind.Stack:\n\t\t\tcallbacks.stack?.(item, currentMatrix, ancestors)\n\t\t\tfor (const childId of item.childrenIds) {\n\t\t\t\twalk(childId, items, currentMatrix, callbacks, [...ancestors, item])\n\t\t\t}\n\t\t\tbreak\n\n\t\tcase Kind.Sequence: {\n\t\t\tcallbacks.sequence?.(item, currentMatrix, ancestors)\n\n\t\t\tfor (const childId of item.childrenIds) {\n\t\t\t\tconst child = items.get(childId)\n\n\t\t\t\tif (!child)\n\t\t\t\t\tcontinue\n\t\t\t\tif (!isPlayableItem(child)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\twalk(\n\t\t\t\t\tchildId,\n\t\t\t\t\titems,\n\t\t\t\t\tcurrentMatrix,\n\t\t\t\t\tcallbacks,\n\t\t\t\t\t[...ancestors, item]\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tbreak\n\t\t}\n\n\t\tcase Kind.Video:\n\t\t\tcallbacks.video?.(item, currentMatrix, ancestors)\n\t\t\tbreak\n\n\t\tcase Kind.Text:\n\t\t\tcallbacks.text?.(item, currentMatrix, ancestors)\n\t\t\tbreak\n\n\t\tcase Kind.Audio:\n\t\t\tcallbacks.audio?.(item)\n\t\t\tbreak\n\t}\n}\n\n\nfunction walkAt(\n\tid: Id,\n\titems: Map<Id, Item.Any>,\n\ttime: Ms,\n\tcallbacks: WalkAtCallbacks,\n\tancestors: ContainerItem[] = []\n) {\n\tconst item = items.get(id)\n\tif (!item) return\n\n\tswitch (item.kind) {\n\t\tcase Kind.Stack:\n\t\t\tcallbacks.stack(item, time, ancestors)\n\t\t\tfor (const childId of item.childrenIds) {\n\t\t\t\twalkAt(childId, items, time, callbacks, [...ancestors, item])\n\t\t\t}\n\t\t\tbreak\n\n\t\tcase Kind.Sequence: {\n\t\t\tcallbacks.sequence(item, time, ancestors)\n\n\t\t\tlet offset = ms(0)\n\n\t\t\tfor (const childId of item.childrenIds) {\n\t\t\t\tconst child = items.get(childId)\n\n\t\t\t\tif (!child)\n\t\t\t\t\tcontinue\n\t\t\t\tif (!isPlayableItem(child)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif (time >= offset && time < offset + child.duration) {\n\t\t\t\t\tconst localTime = ms(time - offset)\n\t\t\t\t\twalkAt(\n\t\t\t\t\t\tchildId,\n\t\t\t\t\t\titems,\n\t\t\t\t\t\tlocalTime,\n\t\t\t\t\t\tcallbacks,\n\t\t\t\t\t\t[...ancestors, item]\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\toffset = ms(offset + child.duration)\n\t\t\t}\n\n\t\t\tbreak\n\t\t}\n\n\t\tcase Kind.Video:\n\t\t\tcallbacks.video(item, time, ancestors)\n\t\t\tbreak\n\n\t\tcase Kind.Text:\n\t\t\tcallbacks.text(item, time, ancestors)\n\t\t\tbreak\n\n\t\tcase Kind.Audio:\n\t\t\tcallbacks.audio(item, time, ancestors)\n\t\t\tbreak\n\t}\n}\n\nfunction walkFrom(\n\tid: Id,\n\titems: Map<Id, Item.Any>,\n\tfrom: Ms,\n\tcallbacks: WalkAtCallbacks,\n\tancestors: ContainerItem[] = []\n) {\n\tconst item = items.get(id)\n\tif (!item) return\n\n\tswitch (item.kind) {\n\t\tcase Kind.Stack:\n\t\t\tcallbacks.stack(item, from, ancestors)\n\t\t\tfor (const childId of item.childrenIds) {\n\t\t\t\twalkFrom(childId, items, from, callbacks, [...ancestors, item])\n\t\t\t}\n\t\t\tbreak\n\n\t\tcase Kind.Sequence: {\n\t\t\tcallbacks.sequence(item, from, ancestors)\n\n\t\t\tlet offset = ms(0)\n\n\t\t\tfor (const childId of item.childrenIds) {\n\t\t\t\tconst child = items.get(childId)\n\n\t\t\t\tif (!child)\n\t\t\t\t\tcontinue\n\t\t\t\tif (!isPlayableItem(child)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tconst end = ms(offset + child.duration)\n\t\t\t\tif (from >= end) {\n\t\t\t\t\toffset = end\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tconst localTime = ms(Math.max(0, from - offset))\n\t\t\t\twalkFrom(\n\t\t\t\t\tchildId,\n\t\t\t\t\titems,\n\t\t\t\t\tlocalTime,\n\t\t\t\t\tcallbacks,\n\t\t\t\t\t[...ancestors, item]\n\t\t\t\t)\n\n\t\t\t\toffset = end\n\t\t\t}\n\n\t\t\tbreak\n\t\t}\n\n\t\tcase Kind.Video:\n\t\t\tcallbacks.video(item, from, ancestors)\n\t\t\tbreak\n\n\t\tcase Kind.Text:\n\t\t\tcallbacks.text(item, from, ancestors)\n\t\t\tbreak\n\n\t\tcase Kind.Audio:\n\t\t\tcallbacks.audio(item, from, ancestors)\n\t\t\tbreak\n\t}\n}\n\nexport function computeItemDuration(\n\tid: number,\n\ttimeline: TimelineFile\n): Ms {\n\tconst item = timeline.items.find(item => item.id === id)\n\n\tif (!item) return ms(0)\n\n\tswitch (item.kind) {\n\t\tcase Kind.Sequence: {\n\t\t\tconst children = item.childrenIds\n\t\t\t\t.map(childId => timeline.items.find(x => x.id === childId))\n\t\t\t\t.filter(Boolean) as Item.Any[]\n\n\t\t\tlet total = ms(0)\n\n\t\t\tfor (let i = 0; i < children.length; i++) {\n\t\t\t\tconst child = children[i]\n\n\t\t\t\tif (child.kind === Kind.Transition) {\n\t\t\t\t\tconst prev = children[i - 1]\n\t\t\t\t\tconst next = children[i + 1]\n\n\t\t\t\t\tif (prev && next && prev.kind !== Kind.Transition && next.kind !== Kind.Transition) {\n\t\t\t\t\t\tconst prevDur = computeItemDuration(prev.id, timeline)\n\t\t\t\t\t\tconst nextDur = computeItemDuration(next.id, timeline)\n\t\t\t\t\t\tconst overlap = Math.max(0, Math.min(child.duration, prevDur, nextDur))\n\n\t\t\t\t\t\ttotal = ms(total - overlap)\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\ttotal = ms(total + computeItemDuration(child.id, timeline))\n\t\t\t}\n\n\t\t\treturn total\n\t\t}\n\n\t\tcase Kind.Stack: {\n\t\t\tlet longest = ms(0)\n\n\t\t\tfor (const childId of item.childrenIds) {\n\t\t\t\tconst duration = computeItemDuration(childId, timeline)\n\t\t\t\tif (duration > longest) {\n\t\t\t\t\tlongest = duration\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn longest\n\t\t}\n\n\t\tdefault: {\n\t\t\tif (!isPlayableItem(item))\n\t\t\t\treturn ms(0)\n\n\t\t\treturn item.duration\n\t\t}\n\t}\n}\n\n", "declare const SecondsBrand: unique symbol\n\nexport type Seconds = number & {\n\treadonly [SecondsBrand]: \"s\"\n}\n\nexport const seconds = (value: number): Seconds =>\n\tvalue as Seconds\n", "\nimport {ALL_FORMATS, Input, VideoSampleSink} from \"mediabunny\"\n\nimport {DecoderSource} from \"../../../../../../driver/fns/schematic.js\"\nimport {loadDecoderSource} from \"../../../../../../driver/utils/load-decoder-source.js\"\n\ntype SinkState = {\n\tinput: Input\n\tsink: VideoSampleSink | null\n}\n\nexport class VideoSink {\n\treadonly #sinks = new Map<string, SinkState>()\n\n\tconstructor(\n\t\tprivate resolveMedia: (hash: string) => DecoderSource\n\t) {}\n\n\tasync getSink(hash: string) {\n\t\tconst existing = this.#sinks.get(hash)\n\n\t\tif (existing)\n\t\t\treturn existing.sink\n\n\t\tconst input = new Input({\n\t\t\tformats: ALL_FORMATS,\n\t\t\tsource: await loadDecoderSource(this.resolveMedia(hash)),\n\t\t})\n\n\t\tconst videoTrack = await input.getPrimaryVideoTrack()\n\t\tconst canDecodeVideo = !!videoTrack && await videoTrack.canDecode()\n\t\tconst sink = canDecodeVideo && videoTrack ? new VideoSampleSink(videoTrack) : null\n\n\t\tthis.#sinks.set(hash, {input, sink})\n\n\t\treturn sink\n\t}\n}\n", "\nimport {Item} from \"../../../../../parts/item.js\"\nimport {Layer} from \"../../../../../../driver/fns/schematic.js\"\n\nexport async function sampleTransition(\n\titem: Item.Transition,\n\tprogress: number,\n\tp1: Promise<Layer[]>,\n\tp2: Promise<Layer[]>\n): Promise<Layer[]> {\n\tconst [l1, l2] = await Promise.all([p1, p2])\n\tconst f1 = l1.find(l => l.kind === \"image\")?.frame\n\tconst f2 = l2.find(l => l.kind === \"image\")?.frame\n\n\tconst rest = [\n\t\t...l1.filter(l => l.kind !== \"image\"),\n\t\t...l2.filter(l => l.kind !== \"image\")\n\t]\n\n\treturn f1 && f2 ? [{\n\t\tid: item.id,\n\t\tkind: \"transition\",\n\t\tname: \"circle\",\n\t\tprogress,\n\t\tfrom: f1,\n\t\tto: f2\n\t}, ...rest] : rest\n}\n", "\nimport {sampleVisual} from \"./sample.js\"\nimport {SampleContext} from \"./types.js\"\nimport {sampleTransition} from \"./transition.js\"\nimport {ms, Ms} from \"../../../../../../units/ms.js\"\nimport {computeItemDuration} from \"../../../handy.js\"\nimport {Layer} from \"../../../../../../driver/fns/schematic.js\"\nimport {ContainerItem, Item, Kind} from \"../../../../../parts/item.js\"\n\nexport async function sampleSequence(\n\tctx: SampleContext,\n\tseq: Item.Sequence,\n\ttime: Ms,\n\tancestors: ContainerItem[]\n): Promise<Layer[]> {\n\tconst state = sampleSequenceAt(ctx, seq, time)\n\n\tif (!state) return []\n\n\tconst nextAnc = [...ancestors, seq]\n\n\tif (!state.isTransitioning) {\n\t\treturn sampleVisual(ctx, state.item, state.localTime, nextAnc)\n\t}\n\n\treturn sampleTransition(\n\t\tstate.transition,\n\t\tstate.progress,\n\t\tsampleVisual(ctx, state.outgoing, state.outgoingTime, nextAnc),\n\t\tsampleVisual(ctx, state.incoming, state.incomingTime, nextAnc)\n\t)\n}\n\nfunction sampleSequenceAt(\n\tctx: SampleContext,\n\tseq: Item.Sequence,\n\ttime: Ms\n) {\n\tconst children = seq.childrenIds\n\t\t.map(id => ctx.items.get(id))\n\t\t.filter((i): i is Item.Any => !!i)\n\n\tlet cursor = ms(0)\n\n\tfor (let i = 0; i < children.length; i++) {\n\t\tconst currentItem = children[i]\n\t\tif (currentItem.kind === Kind.Transition)\n\t\t\tcontinue\n\n\t\tconst currentItemStart = cursor\n\t\tconst currentItemDuration = computeItemDuration(currentItem.id, ctx.timeline)\n\t\tconst currentItemEnd = ms(currentItemStart + currentItemDuration)\n\n\t\tconst next = children[i + 1]\n\t\tconst hasTransition = next?.kind === Kind.Transition\n\n\t\tif (!hasTransition) {\n\t\t\tif (time < currentItemEnd) {\n\t\t\t\treturn {\n\t\t\t\t\tisTransitioning: false,\n\t\t\t\t\titem: currentItem,\n\t\t\t\t\tlocalTime: ms(time - currentItemStart)\n\t\t\t\t} as const\n\t\t\t}\n\n\t\t\tcursor = currentItemEnd\n\t\t\tcontinue\n\t\t}\n\n\t\tconst transition = next as Item.Transition\n\t\tconst incoming = children[i + 2]\n\n\t\tif (!incoming || incoming.kind === Kind.Transition) {\n\t\t\tcursor = currentItemEnd\n\t\t\tcontinue\n\t\t}\n\n\t\tconst incomingItemDuration = computeItemDuration(incoming.id, ctx.timeline)\n\t\tconst overlap = Math.max(0, Math.min(transition.duration, currentItemDuration, incomingItemDuration))\n\t\tconst currentItemSoloEnd = ms(currentItemEnd - overlap)\n\n\t\tif (time < currentItemSoloEnd) {\n\t\t\treturn {\n\t\t\t\tisTransitioning: false,\n\t\t\t\titem: currentItem,\n\t\t\t\tlocalTime: ms(time - currentItemStart)\n\t\t\t} as const\n\t\t}\n\n\t\tif (time < currentItemEnd) {\n\t\t\tconst inLocal = ms(time - currentItemSoloEnd)\n\t\t\tconst outLocal = ms(time - currentItemStart)\n\n\t\t\treturn {\n\t\t\t\tisTransitioning: true,\n\t\t\t\tincoming,\n\t\t\t\toutgoing: currentItem,\n\t\t\t\toutgoingTime: outLocal,\n\t\t\t\tincomingTime: inLocal,\n\t\t\t\tprogress: overlap > 0 ? inLocal / overlap : 1,\n\t\t\t\ttransition\n\t\t\t} as const\n\t\t}\n\n\t\tcursor = currentItemSoloEnd\n\t\ti++\n\t}\n\n\treturn null\n}\n\n", "\nimport {SampleContext} from \"./types.js\"\nimport {sampleSequence} from \"./sequence.js\"\nimport {Ms} from \"../../../../../../units/ms.js\"\nimport {computeWorldMatrix} from \"../../../handy.js\"\nimport {Layer} from \"../../../../../../driver/fns/schematic.js\"\nimport {ContainerItem, Item, Kind} from \"../../../../../parts/item.js\"\n\nexport async function sampleVisual(\n\tctx: SampleContext,\n\titem: Item.Any,\n\ttime: Ms,\n\tancestors: ContainerItem[]\n): Promise<Layer[]> {\n\tconst matrix = computeWorldMatrix(ctx.items, ancestors, item)\n\n\tswitch (item.kind) {\n\t\tcase Kind.Stack: {\n\t\t\tconst nextAnc = [...ancestors, item]\n\n\t\t\tconst layers = await Promise.all(\n\t\t\t\titem.childrenIds\n\t\t\t\t\t.map(id => ctx.items.get(id))\n\t\t\t\t\t.filter((child): child is Item.Any => !!child)\n\t\t\t\t\t.map(child => sampleVisual(ctx, child, time, nextAnc))\n\t\t\t)\n\n\t\t\treturn layers.flat()\n\t\t}\n\n\t\tcase Kind.Sequence:\n\t\t\treturn sampleSequence(ctx, item, time, ancestors)\n\n\t\tcase Kind.Video: {\n\t\t\tif (time < 0 || time >= item.duration) return []\n\n\t\t\tconst frame = await ctx.videoSampler(item, time)\n\t\t\treturn frame ? [{kind: \"image\", frame, matrix, id: item.id}] : []\n\t\t}\n\n\t\tcase Kind.Text: {\n\t\t\tif (time < 0 || time >= item.duration) return []\n\n\t\t\tconst style = item.styleId\n\t\t\t\t? (ctx.items.get(item.styleId) as Item.TextStyle)?.style\n\t\t\t\t: undefined\n\n\t\t\treturn [{id: item.id, kind: \"text\", content: item.content, style, matrix}]\n\t\t}\n\n\t\tcase Kind.Gap: {\n\t\t\treturn [{id: item.id, kind: \"gap\"}]\n\t\t}\n\n\t\tdefault:\n\t\t\treturn []\n\t}\n}\n\n", "\nimport {VideoSink} from \"./sink.js\"\nimport {Ms} from \"../../../../../../units/ms.js\"\nimport {Item} from \"../../../../../parts/item.js\"\n\nexport type VideoSampler = (item: Item.Video, time: Ms) => Promise<VideoFrame | undefined>\n\nexport function createDefaultVideoSampler(sink: VideoSink): VideoSampler {\n\treturn async (item, time) => {\n\t\tconst s = await sink.getSink(item.mediaHash)\n\t\tconst sample = await s?.getSample(time / 1000)\n\t\tconst frame = sample?.toVideoFrame()\n\t\tsample?.close()\n\t\treturn frame ?? undefined\n\t}\n}\n", "\nimport {VideoSink} from \"./parts/sink.js\"\nimport {sampleVisual} from \"./parts/sample.js\"\nimport {Ms} from \"../../../../../units/ms.js\"\nimport {TimelineFile} from \"../../../../parts/basics.js\"\nimport {DecoderSource} from \"../../../../../driver/fns/schematic.js\"\nimport {createDefaultVideoSampler, VideoSampler} from \"./parts/defaults.js\"\n\nexport function createVisualSampler(\n\tresolveMedia: (hash: string) => DecoderSource,\n\tsampleVideo?: VideoSampler\n) {\n\tconst sink = new VideoSink(resolveMedia)\n\tconst videoSampler = sampleVideo ?? createDefaultVideoSampler(sink)\n\n\treturn {\n\t\tasync sample(timeline: TimelineFile, timecode: Ms) {\n\t\t\tconst items = new Map(timeline.items.map(item => [item.id, item]))\n\t\t\tconst root = items.get(timeline.rootId)\n\n\t\t\tif (!root)\n\t\t\t\treturn []\n\n\t\t\treturn sampleVisual({videoSampler, timeline, items}, root, timecode, [])\n\t\t}\n\t}\n}\n\n", "\nimport {ms, Ms} from \"../../../../units/ms.js\"\nimport {Driver} from \"../../../../driver/driver.js\"\nimport {TimelineFile} from \"../../../parts/basics.js\"\nimport {DecoderSource} from \"../../../../driver/fns/schematic.js\"\nimport {createVisualSampler} from \"../../parts/samplers/visual/sampler.js\"\n\n/**\n * forward-only frame cursor optimized for export purposes.\n * it uses mediabunny internally so the support for non-clients\n * should be done from mediabunny custom decoder/encoder\n */\n\nexport class CursorVisualSampler {\n\t#lastTimecode = -Infinity\n\t#videoCursors = new Map<number, VideoFrameCursor>()\n\t#sampler\n\n\tconstructor(\n\t\tprivate driver: Driver,\n\t\tprivate resolveMedia: (hash: string) => DecoderSource,\n\t\tprivate timeline: TimelineFile\n\t) {\n\t\tthis.#sampler = createVisualSampler(this.resolveMedia, (item, time) => {\n\t\t\tconst targetUs = toUs(time)\n\t\t\tlet cursor = this.#videoCursors.get(item.id)\n\n\t\t\tif (!cursor) {\n\t\t\t\tconst source = this.resolveMedia(item.mediaHash)\n\t\t\t\tconst endUs = toUs(ms(item.start + item.duration))\n\t\t\t\tcursor = this.#createVideoCursor(source, targetUs, endUs)\n\t\t\t\tthis.#videoCursors.set(item.id, cursor)\n\t\t\t}\n\n\t\t\treturn cursor.next(targetUs)\n\t\t})\n\t}\n\n\tnext(timecode: Ms) {\n\t\tif (timecode < this.#lastTimecode)\n\t\t\tthrow new Error(`Forward-only cursor regression: ${timecode}ms < ${this.#lastTimecode}ms`)\n\n\t\tthis.#lastTimecode = timecode\n\t\treturn this.#sampler.sample(this.timeline, timecode)\n\t}\n\n\tasync cancel() {\n\t\tawait Promise.all([...this.#videoCursors.values()].map(c => c.cancel()))\n\t\tthis.#videoCursors.clear()\n\t}\n\n\t#createVideoCursor(source: DecoderSource, startUs: number, endUs: number): VideoFrameCursor {\n\t\tconst video = this.driver.decodeVideo({source, start: startUs / 1_000_000, end: endUs / 1_000_000})\n\t\tconst reader = video.readable.getReader()\n\n\t\tlet current: VideoFrame | null = null\n\t\tlet nextPromise: Promise<VideoFrame | null> | null = null\n\t\tlet ended = false\n\n\t\tconst readNext = async () => {\n\t\t\tif (ended) return null\n\t\t\tconst {done, value} = await reader.read()\n\t\t\tif (done) return (ended = true, null)\n\n\t\t\tconst frame = new VideoFrame(value)\n\t\t\tvalue.close()\n\t\t\treturn frame\n\t\t}\n\n\t\treturn {\n\t\t\tasync next(targetUs: number): Promise<VideoFrame | undefined> {\n\t\t\t\tcurrent ??= await readNext()\n\t\t\t\tif (!current) return undefined\n\n\t\t\t\twhile (true) {\n\t\t\t\t\tnextPromise ??= readNext()\n\t\t\t\t\tconst nextFrame = await nextPromise\n\n\t\t\t\t\tif (!nextFrame) return new VideoFrame(current)\n\n\t\t\t\t\tconst currentUs = current.timestamp ?? -Infinity\n\t\t\t\t\tconst nextUs = nextFrame.timestamp ?? currentUs\n\n\t\t\t\t\tif (nextUs < targetUs) {\n\t\t\t\t\t\tcurrent.close()\n\t\t\t\t\t\tcurrent = nextFrame\n\t\t\t\t\t\tnextPromise = null\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tconst useNext = Math.abs(nextUs - targetUs) < Math.abs(currentUs - targetUs)\n\n\t\t\t\t\tif (useNext) {\n\t\t\t\t\t\tcurrent.close()\n\t\t\t\t\t\tcurrent = nextFrame\n\t\t\t\t\t\tnextPromise = null\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\treturn new VideoFrame(current)\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tasync cancel() {\n\t\t\t\tconst pending = nextPromise\n\t\t\t\tnextPromise = null\n\t\t\t\tended = true\n\n\t\t\t\tconst buffered = await pending?.catch(() => null)\n\t\t\t\tbuffered?.close()\n\n\t\t\t\tcurrent?.close()\n\t\t\t\tcurrent = null\n\n\t\t\t\tvideo.cancel()\n\t\t\t}\n\t\t}\n\t}\n}\n\nconst toUs = (ms: Ms) => Math.round(ms * 1_000)\n\ntype StreamCursor<T> = {\n\tnext(target: number): Promise<T | undefined>\n\tcancel(): Promise<void>\n}\n\ntype VideoFrameCursor = StreamCursor<VideoFrame>\n\n", "\nimport {AudioSinkPool} from \"./sink.js\"\nimport {ActiveStream} from \"./types.js\"\nimport {itemsFrom} from \"../../../handy.js\"\nimport {Ms} from \"../../../../../../units/ms.js\"\nimport {Kind} from \"../../../../../parts/item.js\"\nimport {seconds} from \"../../../../../../units/seconds.js\"\n\nexport async function initStreams(\n\tpool: AudioSinkPool,\n\titems: ReturnType<typeof itemsFrom>,\n\tfrom: Ms\n): Promise<ActiveStream[]> {\n\tconst streams = await Promise.all(\n\t\titems.map(async ({item, localTime}) => {\n\t\t\tif (item.kind !== Kind.Audio)\n\t\t\t\treturn\n\n\t\t\tconst sink = await pool.getSink(item.mediaHash)\n\t\t\tif (!sink)\n\t\t\t\treturn\n\n\t\t\tconst mediaTime = item.start + localTime\n\t\t\tconst offset = seconds((from - mediaTime) / 1000)\n\t\t\tconst iter = sink.samples(mediaTime / 1000)\n\n\t\t\tconst first = await iter.next()\n\t\t\tif (first.done)\n\t\t\t\treturn\n\n\t\t\tlet currentSample = first.value\n\t\t\tlet nextPromise = iter.next()\n\n\t\t\treturn {\n\t\t\t\toffset,\n\t\t\t\tgain: item.gain ?? 1,\n\t\t\t\tget currentSample() {return currentSample},\n\t\t\t\ttimelineTime: () => seconds(offset + currentSample.timestamp),\n\t\t\t\toutput: () => ({\n\t\t\t\t\tsample: currentSample,\n\t\t\t\t\ttimestamp: offset + currentSample.timestamp,\n\t\t\t\t\tgain: item.gain ?? 1\n\t\t\t\t}),\n\t\t\t\tadvance: async () => {\n\t\t\t\t\tconst result = await nextPromise\n\t\t\t\t\tif (result.done)\n\t\t\t\t\t\treturn false\n\n\t\t\t\t\tcurrentSample = result.value\n\t\t\t\t\tnextPromise = iter.next()\n\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t)\n\n\treturn streams.filter((stream): stream is ActiveStream => !!stream)\n}\n\n", "\nimport {ALL_FORMATS, Input, AudioSampleSink} from \"mediabunny\"\n\nimport {DecoderSource} from \"../../../../../../driver/fns/schematic.js\"\nimport {loadDecoderSource} from \"../../../../../../driver/utils/load-decoder-source.js\"\n\ntype SinkState = {\n\tinput: Input\n\tsink: AudioSampleSink | null\n}\n\nexport class AudioSinkPool {\n\treadonly #sinks = new Map<string, SinkState>()\n\n\tconstructor(\n\t\tprivate resolveMedia: (hash: string) => DecoderSource\n\t) {}\n\n\tasync getSink(hash: string) {\n\t\tconst existing = this.#sinks.get(hash)\n\n\t\tif (existing)\n\t\t\treturn existing.sink\n\n\t\tconst input = new Input({\n\t\t\tformats: ALL_FORMATS,\n\t\t\tsource: await loadDecoderSource(this.resolveMedia(hash)),\n\t\t})\n\n\t\tconst audioTrack = await input.getPrimaryAudioTrack()\n\t\tconst canDecodeAudio = !!audioTrack && await audioTrack.canDecode()\n\t\tconst sink = canDecodeAudio && audioTrack ? new AudioSampleSink(audioTrack) : null\n\n\t\tthis.#sinks.set(hash, {input, sink})\n\n\t\treturn sink\n\t}\n}\n", "\nimport {ActiveStream} from \"./types.js\"\n\nexport function findEarliestStream(streams: ActiveStream[]) {\n\tlet earliest = {\n\t\tindex: 0,\n\t\tstream: streams[0],\n\t\ttime: streams[0].timelineTime()\n\t}\n\n\tfor (const [index, stream] of streams.entries()) {\n\t\tconst time = stream.timelineTime()\n\t\tif (time < earliest.time) {\n\t\t\tearliest = {time, stream, index}\n\t\t}\n\t}\n\n\treturn earliest\n}\n", "\nimport {AudioSample} from \"mediabunny\"\n\nimport {itemsFrom} from \"../../handy.js\"\nimport {initStreams} from \"./parts/init.js\"\nimport {AudioSinkPool} from \"./parts/sink.js\"\nimport {Ms} from \"../../../../../units/ms.js\"\nimport {findEarliestStream} from \"./parts/find.js\"\nimport {TimelineFile} from \"../../../../parts/basics.js\"\nimport {DecoderSource} from \"../../../../../driver/fns/schematic.js\"\n\nexport function createAudioSampler(resolveMedia: (hash: string) => DecoderSource) {\n\tconst sinkPool = new AudioSinkPool(resolveMedia)\n\n\treturn {\n\t\tasync *sampleAudio(timeline: TimelineFile, from: Ms) {\n\t\t\tconst items = itemsFrom({timeline, from})\n\t\t\tconst streams = await initStreams(sinkPool, items, from)\n\n\t\t\twhile (streams.length > 0) {\n\t\t\t\tconst {stream, index} = findEarliestStream(streams)\n\n\t\t\t\tyield stream.output()\n\n\t\t\t\tconst advancing = await stream.advance()\n\n\t\t\t\tif (!advancing) {\n\t\t\t\t\tstreams.splice(index, 1)\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n}\n\n", "\nimport {Fps} from '../../../../units/fps.js'\nimport {ms, Ms} from '../../../../units/ms.js'\nimport {Driver} from '../../../../driver/driver.js'\nimport {realtime} from '../../parts/schedulers.js'\nimport {TimelineFile} from '../../../parts/basics.js'\nimport {computeItemDuration} from '../../parts/handy.js'\nimport {seconds, Seconds} from '../../../../units/seconds.js'\nimport {CursorVisualSampler} from '../../export/parts/cursor.js'\nimport {DecoderSource} from '../../../../driver/fns/schematic.js'\nimport {createAudioSampler} from '../../parts/samplers/audio/sampler.js'\nimport {createVisualSampler} from '../../parts/samplers/visual/sampler.js'\n\nexport class Playback {\n\taudioSampler\n\tseekVisualSampler\n\tplayVisualSampler: CursorVisualSampler | null = null\n\n\t#playbackStart = ms(0)\n\t#audioStartSec: number | null = null\n\n\t#controller = realtime()\n\tonTick = this.#controller.onTick\n\n\taudioContext = new AudioContext({sampleRate: 48000})\n\taudioGain = this.audioContext.createGain()\n\taudioNodes = new Set<AudioBufferSourceNode>()\n\t#audioAbort: AbortController | null = null\n\n\tconstructor(\n\t\tprivate driver: Driver,\n\t\tprivate timeline: TimelineFile,\n\t\tprivate resolveMedia: (hash: string) => DecoderSource\n\t) {\n\t\tthis.audioGain.connect(this.audioContext.destination)\n\t\tthis.audioGain.gain.value = 0.7 ** 2\n\t\tthis.seekVisualSampler = createVisualSampler(this.resolveMedia)\n\t\tthis.audioSampler = createAudioSampler(this.resolveMedia)\n\t\tthis.#samples()\n\t}\n\n\tupdate(timeline: TimelineFile) {\n\t\tthis.timeline = timeline\n\t}\n\n\tget isPlaying() {\n\t\treturn this.#controller.isPlaying()\n\t}\n\n\tasync #samples() {\n\t\tfor await (const _ of this.#controller.ticks()) {\n\t\t\tconst layers = await this.playVisualSampler?.next(this.currentTime) ?? []\n\n\t\t\tconst frame = await this.driver.composite(layers)\n\t\t\tframe.close()\n\n\t\t\tif (this.currentTime >= this.duration)\n\t\t\t\tthis.pause()\n\t\t}\n\t}\n\n\tasync seek(time: Ms) {\n\t\tthis.pause()\n\t\tthis.#playbackStart = time\n\t\treturn await this.seekVisualSampler.sample(this.timeline, time)\n\t}\n\n\tasync start() {\n\t\tif(this.#controller.isPlaying())\n\t\t\treturn\n\n\t\tawait this.audioContext.resume()\n\n\t\tthis.#playbackStart = this.currentTime\n\t\tthis.#audioStartSec = this.audioContext.currentTime\n\n\t\tthis.#audioAbort?.abort()\n\t\tthis.#audioAbort = new AbortController()\n\n\t\tfor (const node of this.audioNodes)\n\t\t\tnode.stop()\n\n\t\tthis.audioNodes.clear()\n\n\t\tthis.playVisualSampler = new CursorVisualSampler(this.driver, this.resolveMedia, this.timeline)\n\n\t\tthis.#controller.play()\n\t\tthis.#startAudio(this.#audioAbort.signal, seconds(this.#playbackStart / 1000))\n\t}\n\n\tpause() {\n\t\tthis.#playbackStart = this.currentTime\n\t\tthis.#controller.pause()\n\t\tthis.#audioAbort?.abort()\n\n\t\tfor (const node of this.audioNodes)\n\t\t\tnode.stop()\n\n\t\tthis.audioNodes.clear()\n\n\t\tif (this.playVisualSampler) {\n\t\t\tthis.playVisualSampler.cancel()\n\t\t\tthis.playVisualSampler = null\n\t\t}\n\n\t}\n\n\tget duration() {\n\t\treturn computeItemDuration(\n\t\t\tthis.timeline.rootId,\n\t\t\tthis.timeline\n\t\t)\n\t}\n\n\tget currentTime() {\n\t\tif (!this.#controller.isPlaying() || this.#audioStartSec === null)\n\t\t\treturn this.#playbackStart\n\n\t\tconst elapsedMs = (this.audioContext.currentTime - this.#audioStartSec) * 1000\n\t\treturn ms(this.#playbackStart + elapsedMs)\n\t}\n\n\tsetFps(fps: Fps) {\n\t\tthis.#controller.setFPS(fps)\n\t}\n\n\tasync #startAudio(signal: AbortSignal, from: Seconds) {\n\t\tconst ctx = this.audioContext\n\n\t\tif (this.#audioStartSec === null)\n\t\t\treturn\n\n\t\tfor await (const {sample, timestamp} of this.audioSampler.sampleAudio(\n\t\t\tthis.timeline,\n\t\t\tms(from * 1000)\n\t\t)) {\n\n\t\t\tif (signal.aborted || !this.#controller.isPlaying())\n\t\t\t\treturn\n\n\t\t\twhile (timestamp - (ctx.currentTime - this.#audioStartSec + from) > 0.75)\n\t\t\t\tawait new Promise(r => setTimeout(r, 25))\n\n\t\t\tconst node = ctx.createBufferSource()\n\t\t\tnode.buffer = sample.toAudioBuffer()\n\t\t\tnode.connect(this.audioGain)\n\t\t\tnode.onended = () => this.audioNodes.delete(node)\n\t\t\tthis.audioNodes.add(node)\n\n\t\t\tconst startAt = this.#audioStartSec + timestamp - from\n\n\t\t\tstartAt >= ctx.currentTime\n\t\t\t\t? node.start(startAt)\n\t\t\t\t: node.start(ctx.currentTime, ctx.currentTime - startAt)\n\n\t\t}\n\t}\n}\n\n", "\nimport {ms} from \"../../../units/ms.js\"\nimport {fps} from \"../../../units/fps.js\"\nimport {Playback} from \"./parts/playback.js\"\nimport {Driver} from \"../../../driver/driver.js\"\nimport {TimelineFile} from \"../../parts/basics.js\"\nimport {DecoderSource} from \"../../../driver/fns/schematic.js\"\n\ntype ResolveMedia = (hash: string) => DecoderSource\n\nexport class VideoPlayer {\n\tcanvas: HTMLCanvasElement\n\tplayback: Playback\n\n\t#pendingSeek: number | null = null\n\t#flushTask: Promise<void> | null = null\n\n\tconstructor(\n\t\tprivate driver: Driver,\n\t\tresolveMedia: ResolveMedia,\n\t\ttimeline: TimelineFile\n\t) {\n\t\tthis.playback = new Playback(driver, timeline, resolveMedia)\n\t\tthis.canvas = driver.compositor.pixi.renderer.canvas\n\t}\n\n\tasync play() {\n\t\tawait this.playback.start()\n\t}\n\n\tpause() {\n\t\tthis.playback.pause()\n\t}\n\n\tseek(timeMs: number) {\n\t\tthis.#pendingSeek = timeMs\n\t\treturn this.#flushTask ??= this.#flushSeeks().finally(() => this.#flushTask = null)\n\t}\n\n\tsetFPS(value: number) {\n\t\tthis.playback.setFps(fps(value))\n\t}\n\n\tget isSeeking() {\n\t\treturn this.#flushTask !== null\n\t}\n\n\tget isPlaying() {\n\t\treturn this.playback.isPlaying\n\t}\n\n\tget duration() {\n\t\treturn this.playback.duration\n\t}\n\n\tget currentTime() {\n\t\treturn this.playback.currentTime\n\t}\n\n\t/**\n\t call this whenever your timeline state changes\n\t*/\n\tupdate(timeline: TimelineFile) {\n\t\tthis.playback.update(timeline)\n\t}\n\n\tasync #flushSeeks() {\n\t\twhile (this.#pendingSeek !== null) {\n\t\t\tconst next = this.#pendingSeek\n\t\t\tthis.#pendingSeek = null\n\t\t\tconst layers = await this.playback.seek(ms(next))\n\t\t\tconst frame = await this.driver.composite(layers)\n\t\t\tframe.close()\n\t\t}\n\t}\n}\n\n", "\nexport type AudioPlanesInput = {\n\tplanes: Float32Array[]\n\tsampleRate: number\n\ttimestamp: number\n}\n\nexport type MixedChunk = {\n\tplanar: Float32Array\n\tsampleRate: number\n\tchannels: number\n\tframes: number\n\tstartFrame: number\n}\n\ntype ActiveSample = {\n\tstartFrame: number\n\tendFrame: number\n\tdata: Float32Array[]\n}\n\nexport type AudioMixOptions = {\n\tchunkFrames?: number\n\tclamp?: boolean\n}\n\nexport class AudioMix {\n\treadonly #chunkFrames: number\n\treadonly #clamp: boolean\n\n\tconstructor(options: AudioMixOptions = {}) {\n\t\tthis.#chunkFrames = options.chunkFrames ?? 1024\n\t\tthis.#clamp = options.clamp ?? true\n\t}\n\n\tasync *mix(samples: AsyncIterable<AudioPlanesInput>): AsyncGenerator<MixedChunk> {\n\t\tconst chunkFrames = this.#chunkFrames\n\t\tlet sampleRate: number | null = null\n\t\tlet channels: number | null = null\n\t\tconst active: ActiveSample[] = []\n\t\tlet nextFrame = 0\n\t\tlet maxEnd = 0\n\n\t\tfor await (const input of samples) {\n\t\t\tif (channels === null) {\n\t\t\t\tchannels = input.planes.length\n\t\t\t\tsampleRate = input.sampleRate\n\t\t\t} else {\n\t\t\t\tif (input.planes.length !== channels) throw new Error(`Channel count changed`)\n\t\t\t\tif (input.sampleRate !== sampleRate) throw new Error(`Sample rate changed`)\n\t\t\t}\n\n\t\t\tconst inputStart = Math.round(input.timestamp * sampleRate)\n\t\t\tconst frames = input.planes[0]?.length ?? 0\n\n\t\t\twhile (nextFrame + chunkFrames <= inputStart) {\n\t\t\t\tyield this.#processChunk(active, nextFrame, channels, sampleRate)\n\t\t\t\tnextFrame += chunkFrames\n\t\t\t}\n\n\t\t\tactive.push({\n\t\t\t\tstartFrame: inputStart,\n\t\t\t\tendFrame: inputStart + frames,\n\t\t\t\tdata: input.planes\n\t\t\t})\n\n\t\t\tmaxEnd = Math.max(maxEnd, inputStart + frames)\n\t\t}\n\n\t\tif (channels !== null && sampleRate !== null) {\n\t\t\twhile (nextFrame < maxEnd) {\n\t\t\t\tyield this.#processChunk(active, nextFrame, channels, sampleRate)\n\t\t\t\tnextFrame += chunkFrames\n\t\t\t}\n\t\t}\n\t}\n\n\t#processChunk(\n\t\tactive: ActiveSample[],\n\t\tcurrentStartFrame: number,\n\t\tchannels: number,\n\t\tsampleRate: number\n\t): MixedChunk {\n\t\tconst chunkFrames = this.#chunkFrames\n\t\tconst outputBuffer = new Float32Array(channels * chunkFrames)\n\t\tconst chunkEnd = currentStartFrame + chunkFrames\n\n\t\tfor (let ch = 0; ch < channels; ch++) {\n\t\t\tconst channelOffset = ch * chunkFrames\n\t\t\tconst outChannelView = outputBuffer.subarray(channelOffset, channelOffset + chunkFrames)\n\n\t\t\tfor (const sample of active) {\n\t\t\t\tconst data = sample.data[ch]\n\t\t\t\tif (!data) continue\n\n\t\t\t\tconst start = Math.max(currentStartFrame, sample.startFrame)\n\t\t\t\tconst end = Math.min(chunkEnd, sample.endFrame)\n\n\t\t\t\tif (start >= end) continue\n\n\t\t\t\tconst dstIdx = start - currentStartFrame\n\t\t\t\tconst srcIdx = start - sample.startFrame\n\t\t\t\tconst len = end - start\n\n\t\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\t\toutChannelView[dstIdx + i] += data[srcIdx + i]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.#clamp) {\n\t\t\t\tfor (let i = 0; i < chunkFrames; i++) {\n\t\t\t\t\tconst v = outChannelView[i]\n\t\t\t\t\toutChannelView[i] = v < -1.0 ? -1.0 : (v > 1.0 ? 1.0 : v)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let i = active.length - 1; i >= 0; i--) {\n\t\t\tif (active[i].endFrame <= chunkEnd) {\n\t\t\t\tactive.splice(i, 1)\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tplanar: outputBuffer,\n\t\t\tsampleRate,\n\t\t\tchannels,\n\t\t\tframes: chunkFrames,\n\t\t\tstartFrame: currentStartFrame\n\t\t}\n\t}\n}\n\n", "\nconst resampleLinear = (\n\tsrc: Float32Array,\n\tfromRate: number,\n\ttargetRate: number\n) => {\n\tif (fromRate === targetRate)\n\t\treturn src\n\n\tconst ratio = targetRate / fromRate\n\tconst outFrames = Math.max(1, Math.round(src.length * ratio))\n\tconst out = new Float32Array(outFrames)\n\n\tfor (let i = 0; i < outFrames; i++) {\n\t\tconst t = i / ratio\n\t\tconst i0 = Math.floor(t)\n\t\tconst i1 = Math.min(i0 + 1, src.length - 1)\n\t\tconst frac = t - i0\n\t\tout[i] = src[i0] * (1 - frac) + src[i1] * frac\n\t}\n\n\treturn out\n}\n\nexport const resampleToPlanar = (\n\tsample: {\n\t\tnumberOfFrames: number\n\t\tnumberOfChannels: number\n\t\tsampleRate: number\n\t\tcopyTo: (dest: Float32Array, options: {planeIndex: number; format: 'f32-planar'}) => void\n\t},\n\ttargetRate: number\n): {data: Float32Array[]; frames: number} => {\n\tconst channels = sample.numberOfChannels\n\tconst data = new Array<Float32Array>(channels)\n\tlet frames = 0\n\n\tfor (let ch = 0; ch < channels; ch++) {\n\t\tconst plane = new Float32Array(sample.numberOfFrames)\n\t\tsample.copyTo(plane, {planeIndex: ch, format: 'f32-planar'})\n\t\tconst resampled = resampleLinear(plane, sample.sampleRate, targetRate)\n\t\tdata[ch] = resampled\n\t\tframes = resampled.length\n\t}\n\n\treturn {data, frames}\n}\n\n", "// this is mutating fn\nexport const applyGainToPlanar = (\n\tplanes: Float32Array[],\n\tgain: number\n) => {\n\tif (gain === 1)\n\t\treturn\n\t// planes\n\n\tfor (const plane of planes) {\n\t\tfor (let i = 0; i < plane.length; i++) {\n\t\t\tplane[i] *= gain\n\t\t}\n\t}\n\n\t// return planes\n}\n", "\nimport {AudioMix} from \"./audio-mix.js\"\nimport {ms} from \"../../../../units/ms.js\"\nimport {resampleToPlanar} from \"./resamplers.js\"\nimport {applyGainToPlanar} from \"./audio-gain.js\"\nimport {TimelineFile} from \"../../../parts/basics.js\"\nimport {DecoderSource} from \"../../../../driver/fns/schematic.js\"\nimport {createAudioSampler} from \"../../parts/samplers/audio/sampler.js\"\n\nexport function produceAudio({\n\ttimeline,\n\tresolveMedia\n}: {\n\ttimeline: TimelineFile,\n\tresolveMedia: (hash: string) => DecoderSource\n}) {\n\tconst mixer = new AudioMix()\n\tconst audio = streamAudio(timeline, resolveMedia)\n\tconst stream = new TransformStream<AudioData, AudioData>()\n\tconst writer = stream.writable.getWriter()\n\n\tasync function produce() {\n\t\tfor await (const chunk of mixer.mix(audio)) {\n\t\t\tconst data = new AudioData({\n\t\t\t\tformat: 'f32-planar',\n\t\t\t\tsampleRate: chunk.sampleRate,\n\t\t\t\tnumberOfFrames: chunk.frames,\n\t\t\t\tnumberOfChannels: chunk.channels,\n\t\t\t\ttimestamp: Math.round(\n\t\t\t\t\t(chunk.startFrame / chunk.sampleRate) * 1_000_000\n\t\t\t\t),\n\t\t\t\tdata: new Float32Array(chunk.planar)\n\t\t\t})\n\n\t\t\tawait writer.write(data)\n\t\t}\n\n\t\tawait writer.close()\n\t}\n\n\tproduce()\n\n\treturn stream.readable\n}\n\nasync function *streamAudio(timeline: TimelineFile, resolveMedia: (hash: string) => DecoderSource) {\n\tconst audioSampler = createAudioSampler(resolveMedia)\n\n\tfor await (const {sample, timestamp, gain}\n\t\tof audioSampler.sampleAudio(timeline, ms(0))) {\n\n\t\tconst {data} = resampleToPlanar(sample, 48000)\n\t\tapplyGainToPlanar(data, gain)\n\n\t\tyield {\n\t\t\tplanes: data,\n\t\t\tsampleRate: 48000,\n\t\t\ttimestamp\n\t\t}\n\n\t\tsample.close()\n\t}\n}\n\n", "\nimport {Fps} from \"../../../../units/fps.js\"\nimport {CursorVisualSampler} from \"./cursor.js\"\nimport {Driver} from \"../../../../driver/driver.js\"\nimport {fixedStep} from \"../../parts/schedulers.js\"\nimport {TimelineFile} from \"../../../parts/basics.js\"\nimport {computeItemDuration} from \"../../parts/handy.js\"\nimport {DecoderSource} from \"../../../../driver/fns/schematic.js\"\n\nexport function produceVideo({\n\ttimeline,\n\tfps,\n\tdriver,\n\tresolveMedia,\n}: {\n\tdriver: Driver\n\tresolveMedia: (hash: string) => DecoderSource\n\ttimeline: TimelineFile\n\tfps: Fps\n}) {\n\n\tconst stream = new TransformStream<VideoFrame, VideoFrame>()\n\tconst writer = stream.writable.getWriter()\n\tconst sampler = new CursorVisualSampler(driver, resolveMedia, timeline)\n\tconst dt = 1 / fps\n\tconst duration = computeItemDuration(timeline.rootId, timeline)\n\n\tasync function produce() {\n\t\tawait fixedStep({fps, duration}, async (timecode, i) => {\n\t\t\tconst layers = await sampler.next(timecode)\n\t\t\tconst composed = await driver.composite(layers)\n\n\t\t\tconst frame = new VideoFrame(composed, {\n\t\t\t\ttimestamp: Math.round(i * dt * 1_000_000),\n\t\t\t\tduration: Math.round(dt * 1_000_000)\n\t\t\t})\n\n\t\t\tawait writer.write(frame)\n\t\t\tcomposed.close()\n\t\t})\n\n\t\tawait writer.close()\n\t}\n\n\tproduce()\n\n\treturn stream.readable\n}\n\n", "\nimport {Fps} from \"../../../units/fps.js\"\nimport {Driver} from \"../../../driver/driver.js\"\nimport {TimelineFile} from \"../../parts/basics.js\"\nimport {produceAudio} from \"./parts/produce-audio.js\"\nimport {produceVideo} from \"./parts/produce-video.js\"\nimport {DecoderSource} from \"../../../driver/fns/schematic.js\"\n\nexport function produce(opts: {\n\ttimeline: TimelineFile\n\tfps: Fps\n\tdriver: Driver\n\tresolveMedia: (hash: string) => DecoderSource\n}) {\n\n\tconst audio = produceAudio({...opts})\n\tconst video = produceVideo({...opts})\n\n\treturn opts.driver.encode({\n\t\tvideo,\n\t\taudio,\n\t\tconfig: {\n\t\t\taudio: {codec: 'opus', bitrate: 128000},\n\t\t\tvideo: {codec: 'vp9', bitrate: 1000000}\n\t\t}\n\t})\n}\n\n", "\nimport {O} from \"./o.js\"\nimport {Item} from \"../parts/item.js\"\nimport {fps} from \"../../units/fps.js\"\nimport {Media} from \"../parts/media.js\"\nimport {Driver} from \"../../driver/driver.js\"\nimport {Datafile} from \"../utils/datafile.js\"\nimport {TimelineFile} from \"../parts/basics.js\"\nimport {ResourcePool} from \"../parts/resource-pool.js\"\nimport {VideoPlayer} from \"../renderers/player/player.js\"\nimport {produce} from \"../renderers/export/produce.js\"\n\nexport class Omni {\n\tresources = new ResourcePool()\n\n\tconstructor(private driver: Driver) {}\n\n\tload = async<S extends Record<string, Promise<Datafile>>>(spec: S) => {\n\t\treturn Object.fromEntries(await Promise.all(Object.entries(spec).map(\n\t\t\tasync ([key, value]) => [key, await this.resources.store(await value)]\n\t\t))) as {[K in keyof S]: Media}\n\t}\n\n\ttimeline = (fn: (o: O) => Item.Any): TimelineFile => {\n\t\tconst o = new O({\n\t\t\ttimeline: {\n\t\t\t\tformat: \"timeline\",\n\t\t\t\tinfo: \"https://omniclip.app/\",\n\t\t\t\tversion: 0,\n\t\t\t\titems: [],\n\t\t\t\trootId: 0\n\t\t\t}\n\t\t})\n\t\tconst root = fn(o)\n\t\to.timeline.rootId = root.id\n\t\treturn o.timeline\n\t}\n\n\tplayback = async (timeline: TimelineFile) => {\n\t\treturn new VideoPlayer(\n\t\t\tthis.driver,\n\t\t\t(hash) => this.resources.require(hash).url,\n\t\t\ttimeline\n\t\t)\n\t}\n\n\trender = async (timeline: TimelineFile, framerate: number = 30) => {\n\t\treturn produce({\n\t\t\ttimeline,\n\t\t\tfps: fps(framerate),\n\t\t\tdriver: this.driver,\n\t\t\tresolveMedia: (hash) => this.resources.require(hash).url\n\t\t})\n\t}\n}\n\n", "\nimport {Tap, TapContext} from \"../types.js\"\n\nexport function bindTap(tap: Tap, ctx: TapContext): Tap {\n\treturn {\n\t\terror: o => tap.error({...ctx, ...o}),\n\t\trpcRequest: o => tap.rpcRequest({...ctx, ...o}),\n\t\trpcError: o => tap.rpcError({...ctx, ...o}),\n\t}\n}\n\n", "\nimport {asTheme} from \"./theme.js\"\n\nexport const basicTheme = () => asTheme(colors => ({\n\tplain: colors.none,\n\terrMessage: colors.mix(colors.brightRed, colors.bold),\n\terrName: colors.red,\n\terrStack: colors.mix(colors.red, colors.dim),\n\ttimestamp: colors.blue,\n\ttimestampErr: colors.red,\n}))\n\n", "\nimport {basicTheme} from \"./basic.js\"\n\nexport function autoTheme() {\n\treturn basicTheme()\n}\n\n", "\nexport const codes = Object.freeze({\n\n\t// regular colors\n\tblack: \"\\u001b[30m\",\n\tred: \"\\u001b[31m\",\n\tgreen: \"\\u001b[32m\",\n\tyellow: \"\\u001b[33m\",\n\tblue: \"\\u001b[34m\",\n\tmagenta: \"\\u001b[35m\",\n\tcyan: \"\\u001b[36m\",\n\twhite: \"\\u001b[37m\",\n\n\t// bright colors\n\tbrightBlack: \"\\u001b[90m\",\n\tbrightRed: \"\\u001b[91m\",\n\tbrightGreen: \"\\u001b[92m\",\n\tbrightYellow: \"\\u001b[93m\",\n\tbrightBlue: \"\\u001b[94m\",\n\tbrightMagenta: \"\\u001b[95m\",\n\tbrightCyan: \"\\u001b[96m\",\n\tbrightWhite: \"\\u001b[97m\",\n\n\t// background colors\n\tbgBlack: \"\\u001b[40m\",\n\tbgRed: \"\\u001b[41m\",\n\tbgGreen: \"\\u001b[42m\",\n\tbgYellow: \"\\u001b[43m\",\n\tbgBlue: \"\\u001b[44m\",\n\tbgMagenta: \"\\u001b[45m\",\n\tbgCyan: \"\\u001b[46m\",\n\tbgWhite: \"\\u001b[47m\",\n\n\t// bright background colors\n\tbgBrightBlack: \"\\u001b[100m\",\n\tbgBrightRed: \"\\u001b[101m\",\n\tbgBrightGreen: \"\\u001b[102m\",\n\tbgBrightYellow: \"\\u001b[103m\",\n\tbgBrightBlue: \"\\u001b[104m\",\n\tbgBrightMagenta: \"\\u001b[105m\",\n\tbgBrightCyan: \"\\u001b[106m\",\n\tbgBrightWhite: \"\\u001b[107m\",\n\n\t// styles\n\tbold: \"\\u001b[1m\",\n\tdim: \"\\u001b[2m\",\n\titalic: \"\\u001b[3m\",\n\tunderline: \"\\u001b[4m\",\n\tinverse: \"\\u001b[7m\",\n\thidden: \"\\u001b[8m\",\n\tstrikethrough: \"\\u001b[9m\",\n\n\t// reset\n\treset: \"\\u001b[0m\",\n})\n\n", "\nimport {codes} from \"./codes.js\"\n\nexport type ColorFn = (s: string) => string\n\nexport const colorFns = () => ({\n\tnone: (s: string) => s,\n\tuncolor,\n\tmix,\n\thex,\n\trgb,\n\tbgRgb,\n})\n\nexport function uncolor(s: string) {\n\treturn s.replace(\n\t\t/[\\u001b\\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,\n\t\t\"\",\n\t)\n}\n\nexport function mix(...colorFns: ColorFn[]) {\n\treturn (s: string) => {\n\t\tfor (const fn of colorFns)\n\t\t\ts = fn(s)\n\t\treturn s\n\t}\n}\n\nexport function hex(hex: string) {\n\thex = hex.replace(/^#/, \"\")\n\tlet bigint: number\n\tlet r: number\n\tlet g: number\n\tlet b: number\n\n\tif (hex.length === 3)\n\t\tbigint = parseInt(hex.split('').map(c => c + c).join(''), 16)\n\telse if (hex.length === 6)\n\t\tbigint = parseInt(hex, 16)\n\telse\n\t\tthrow new Error('Invalid hex color')\n\n\tr = (bigint >> 16) & 255\n\tg = (bigint >> 8) & 255\n\tb = bigint & 255\n\treturn rgb(r, g, b)\n}\n\nexport function rgb(r: number, g: number, b: number) {\n\tconst code = `\\u001b[38;2;${r};${g};${b}m`\n\treturn (s: string) => `${code}${s}${codes.reset}`\n}\n\nexport function bgRgb(r: number, g: number, b: number) {\n\tconst code = `\\u001b[48;2;${r};${g};${b}m`\n\treturn (s: string) => `${code}${s}${codes.reset}`\n}\n\n", "\nimport {Colors} from \"./colorful.js\"\nimport {codes} from \"./parts/codes.js\"\nimport {colorFns} from \"./parts/color-fns.js\"\n\nexport const colorless = {\n\t...<{[key in keyof typeof codes]: (s: string) => string}>(\n\t\tObject.fromEntries(\n\t\t\tObject.entries(codes)\n\t\t\t\t.map(([key]) => [\n\t\t\t\t\tkey,\n\t\t\t\t\t(s: string) => s,\n\t\t\t\t])\n\t\t)\n\t),\n\t...colorFns(),\n} as Colors\n\n", "\nimport {codes} from \"./parts/codes.js\"\nimport {colorFns} from \"./parts/color-fns.js\"\n\nexport type Colors = typeof colorful\n\nexport const colorful = {\n\t...<{[key in keyof typeof codes]: (s: string) => string}>(\n\t\tObject.fromEntries(\n\t\t\tObject.entries(codes)\n\t\t\t\t.map(([key, code]) => [\n\t\t\t\t\tkey,\n\t\t\t\t\t(s: string) => `${code}${s}${codes.reset}`,\n\t\t\t\t])\n\t\t)\n\t),\n\t...colorFns(),\n}\n\n", "\ndeclare const Deno: any\n\nexport function isDeno() {\n\treturn typeof Deno !== \"undefined\" && typeof Deno.version !== \"undefined\"\n}\n\nexport function isNode() {\n\treturn (\n\t\ttypeof process !== \"undefined\" &&\n\t\tprocess.versions &&\n\t\tprocess.versions.node\n\t)\n}\n\nexport function isColorSupported() {\n\tif (isNode())\n\t\treturn (process.env.FORCE_COLOR) || (\n\t\t\tprocess.stdout.isTTY &&\n\t\t\tprocess.env.TERM !== \"dumb\"\n\t\t)\n\n\telse if (isDeno())\n\t\treturn (Deno.env.get(\"FORCE_COLOR\")) || (\n\t\t\tDeno.isatty(Deno.stdout.rid) &&\n\t\t\tDeno.env.get(\"TERM\") !== \"dumb\"\n\t\t)\n\n\telse\n\t\treturn false\n}\n\nexport function exit(code: number) {\n\tif (isNode())\n\t\tprocess.exit(code)\n\telse if (isDeno())\n\t\tDeno.exit(code)\n}\n\nexport function hasEnv(name: string): boolean {\n\tif (isNode())\n\t\treturn name in process.env\n\telse if (isDeno())\n\t\treturn Deno.env.get(name) !== undefined\n\treturn false\n}\n\nexport function hasArg(arg: string): boolean {\n\tif (isNode())\n\t\treturn process.argv.slice(1).includes(arg)\n\telse if (isDeno())\n\t\treturn Deno.args.includes(arg)\n\telse\n\t\treturn false\n}\n\nfunction findArgValue(name: string, args: string[]) {\n\tfor (const arg of args) {\n\t\tif (arg.includes(\"=\")) {\n\t\t\tconst [first, ...rest] = arg.split(\"=\")\n\t\t\tif (first === name)\n\t\t\t\treturn rest.join(\"=\")\n\t\t}\n\t}\n}\n\nexport function getArg(name: string) {\n\tif (isNode())\n\t\treturn findArgValue(name, process.argv.slice(1))\n\telse if (isDeno())\n\t\treturn findArgValue(name, Deno.args)\n}\n\nexport function getEnv(name: string): string | undefined {\n\tif (isNode())\n\t\treturn process.env[name]\n\telse if (isDeno())\n\t\treturn Deno.env.get(name)\n}\n\nexport async function writeStdout(line: string) {\n\tif (isNode())\n\t\tprocess.stdout.write(line + \"\\n\")\n\telse if (isDeno())\n\t\tawait Deno.stdout.write(new TextEncoder().encode(line + \"\\n\"))\n\telse\n\t\tconsole.log(line)\n}\n\nexport async function writeStderr(line: string) {\n\tif (isNode())\n\t\tprocess.stderr.write(line + \"\\n\")\n\telse if (isDeno())\n\t\tawait Deno.stderr.write(new TextEncoder().encode(line + \"\\n\"))\n\telse\n\t\tconsole.error(line)\n}\n\n", "\nimport {colorless} from \"./colorless.js\"\nimport {colorful, Colors} from \"./colorful.js\"\nimport {isColorSupported} from \"../utils/supports.js\"\n\nexport const autoColors = (): Colors => {\n\treturn isColorSupported()\n\t\t? colorful\n\t\t: colorless\n}\n\n", "\nimport {Shaper} from \"./shaper.js\"\n\nexport const errorsShaper = (): Shaper => ({colors, theme}) => {\n\tconst palette = theme(colors)\n\n\tfunction errstring(error: Error) {\n\t\tconst stack = error.stack\n\t\t\t? \"\\n\" + error.stack + \"\\n\"\n\t\t\t: \"\"\n\t\treturn [\n\t\t\tpalette.errName(error.name + \":\"),\n\t\t\tpalette.errMessage(error.message),\n\t\t].join(\" \") + palette.errStack(stack)\n\t}\n\n\tfunction processErrors(item: any) {\n\t\treturn (item && item instanceof Error)\n\t\t\t? errstring(item)\n\t\t\t: item\n\t}\n\n\tfunction processAll(item: any) {\n\t\treturn (item && item instanceof Error)\n\t\t\t? errstring(item)\n\t\t\t: palette.errMessage(item)\n\t}\n\n\treturn {\n\t\tstdout: items => items.map(processErrors),\n\t\tstderr: items => items.map(processAll),\n\t}\n}\n\n", "\nimport {Theme} from \"../themes/theme.js\"\nimport {Colors} from \"../colors/colorful.js\"\n\nexport type ShaperContext = {\n\tcolors: Colors\n\ttheme: Theme\n}\n\nexport type Shaper = (context: ShaperContext) => ShaperFns\n\nexport type ShaperFns = {\n\tstdout: (items: any[]) => any[]\n\tstderr: (items: any[]) => any[]\n}\n\nexport function asShaper(shaper: Shaper) {\n\treturn shaper\n}\n\nexport function combineShapers(...shapers: Shaper[]): Shaper {\n\treturn context => ({\n\t\tstdout: items => {\n\t\t\tfor (const shaper of shapers)\n\t\t\t\titems = shaper(context).stdout(items)\n\t\t\treturn items\n\t\t},\n\t\tstderr: items => {\n\t\t\tfor (const shaper of shapers)\n\t\t\t\titems = shaper(context).stderr(items)\n\t\t\treturn items\n\t\t},\n\t})\n}\n\n", "\nimport {Shaper} from \"./shaper.js\"\n\nexport type TimestampOptions = {\n\ticon: string | undefined\n\tnow: () => number\n}\n\nfunction defaultTimestampOptions(): TimestampOptions {\n\treturn {\n\t\ticon: \"\uD83D\uDEA8\",\n\t\tnow: () => Date.now(),\n\t}\n}\n\nexport const timestampShaper = (options?: Partial<TimestampOptions>): Shaper => ({colors, theme}) => {\n\tconst opts = {...defaultTimestampOptions(), ...options}\n\tconst palette = theme(colors)\n\n\tconst date = new Date(opts.now())\n\n\tconst year = date.getUTCFullYear().toString().padStart(4, \"0\")\n\tconst month = (date.getUTCMonth() + 1).toString().padStart(2, \"0\")\n\tconst day = date.getUTCDate().toString().padStart(2, \"0\")\n\tconst calendar = `${year}-${month}-${day}`\n\n\tconst hour = date.getUTCHours().toString().padStart(2, \"0\")\n\tconst minute = date.getUTCMinutes().toString().padStart(2, \"0\")\n\tconst second = date.getUTCSeconds().toString().padStart(2, \"0\")\n\tconst milliseconds = date.getUTCMilliseconds().toString().padStart(3, \"0\")\n\tconst clock = `${hour}:${minute}:${second}.${milliseconds}`\n\n\tconst stamp = `${calendar}::${clock}`\n\n\treturn {\n\t\tstdout: items => [\n\t\t\tpalette.timestamp(stamp),\n\t\t\t...items,\n\t\t],\n\t\tstderr: items => [\n\t\t\tpalette.timestampErr(stamp),\n\t\t\t...[opts.icon].filter(Boolean),\n\t\t\t...items,\n\t\t],\n\t}\n}\n\n", "\nimport {errorsShaper} from \"./errors.js\"\nimport {combineShapers} from \"./shaper.js\"\nimport {timestampShaper} from \"./timestamp.js\"\n\nexport function autoShaper() {\n\treturn combineShapers(\n\t\terrorsShaper(),\n\t\ttimestampShaper(),\n\t)\n}\n\n", "\nimport {Writer} from \"./writer.js\"\n\ndeclare const Deno: any\n\nexport const denoWriter = (): Writer => ({\n\tstdout: async line => {\n\t\tawait Deno.stdout.write(new TextEncoder().encode(line + \"\\n\"))\n\t},\n\tstderr: async line => {\n\t\tawait Deno.stderr.write(new TextEncoder().encode(line + \"\\n\"))\n\t},\n})\n\n", "\nimport {Writer} from \"./writer.js\"\n\nexport const nodeWriter = (): Writer => ({\n\tstdout: async(line: string) => void process.stdout.write(line + \"\\n\"),\n\tstderr: async(line: string) => void process.stderr.write(line + \"\\n\"),\n})\n\n", "\nimport {Writer} from \"./writer.js\"\n\nexport const consoleWriter = (): Writer => ({\n\tstdout: async line => console.log(line),\n\tstderr: async line => console.error(line),\n})\n\n", "\nimport {Writer} from \"./writer.js\"\nimport {denoWriter} from \"./deno.js\"\nimport {nodeWriter} from \"./node.js\"\nimport {consoleWriter} from \"./console.js\"\nimport {isDeno, isNode} from \"../utils/supports.js\"\n\nexport const autoWriter = (): Writer => {\n\tif (isDeno()) return denoWriter()\n\telse if (isNode()) return nodeWriter()\n\telse return consoleWriter()\n}\n\n", "\nimport {Writer} from \"./writer.js\"\n\nexport const voidWriter = (): Writer => ({\n\tstdout: async() => undefined,\n\tstderr: async() => undefined,\n})\n\n", "\nimport {Shaper} from \"./shaper.js\"\n\nexport function noneShaper(): Shaper {\n\treturn () => ({\n\t\tstdout: items => items,\n\t\tstderr: items => items,\n\t})\n}\n\n", "\nimport {Theme} from \"./themes/theme.js\"\nimport {Writer} from \"./writers/writer.js\"\nimport {autoTheme} from \"./themes/auto.js\"\nimport {autoColors} from \"./colors/auto.js\"\nimport {autoShaper} from \"./shapers/auto.js\"\nimport {autoWriter} from \"./writers/auto.js\"\nimport {basicTheme} from \"./themes/basic.js\"\nimport {denoWriter} from \"./writers/deno.js\"\nimport {nodeWriter} from \"./writers/node.js\"\nimport {voidWriter} from \"./writers/void.js\"\nimport {noneShaper} from \"./shapers/none.js\"\nimport {colorless} from \"./colors/colorless.js\"\nimport {errorsShaper} from \"./shapers/errors.js\"\nimport {consoleWriter} from \"./writers/console.js\"\nimport {colorful, Colors} from \"./colors/colorful.js\"\nimport {timestampShaper} from \"./shapers/timestamp.js\"\nimport {combineShapers, Shaper} from \"./shapers/shaper.js\"\n\nexport class Logger {\n\tstatic writers = {\n\t\tauto: autoWriter,\n\t\tvoid: voidWriter,\n\t\tdeno: denoWriter,\n\t\tnode: nodeWriter,\n\t\tconsole: consoleWriter,\n\t}\n\n\tstatic colors = {\n\t\tauto: autoColors,\n\t\tcolorful: () => colorful,\n\t\tcolorless: () => colorless,\n\t}\n\n\tstatic themes = {\n\t\tauto: autoTheme,\n\t\tbasic: basicTheme,\n\t}\n\n\tstatic shapers = {\n\t\tauto: autoShaper,\n\t\tnone: noneShaper,\n\t\terrors: errorsShaper,\n\t\ttimestamp: timestampShaper,\n\t}\n\n\twriter: Writer = Logger.writers.auto()\n\tcolors: Colors = Logger.colors.auto()\n\ttheme: Theme = Logger.themes.auto()\n\tshaper: Shaper = Logger.shapers.auto()\n\n\tasync log(...items: any[]) {\n\t\tawait this.writer.stdout(\n\t\t\tthis.shaper(this).stdout(items).join(\" \")\n\t\t)\n\t}\n\n\tasync error(...items: any[]) {\n\t\tawait this.writer.stderr(\n\t\t\tthis.shaper(this).stderr(items).join(\" \")\n\t\t)\n\t}\n\n\tsetWriter(writer: Writer) {\n\t\tthis.writer = writer\n\t\treturn this\n\t}\n\n\tsetColors(colors: Colors) {\n\t\tthis.colors = colors\n\t\treturn this\n\t}\n\n\tsetTheme(theme: Theme) {\n\t\tthis.theme = theme\n\t\treturn this\n\t}\n\n\tsetShaper(...shapers: Shaper[]) {\n\t\tthis.shaper = combineShapers(...shapers)\n\t\treturn this\n\t}\n}\n\n", "\nimport {Logger} from \"@e280/sten\"\nimport {Tap, HttpMeta, TapContext} from \"../types.js\"\n\nexport class LoggerTap extends Logger implements Tap {\n\tstatic dummy() {\n\t\treturn new this().setWriter(Logger.writers.void())\n\t}\n\n\trpcRequest: Tap[\"rpcRequest\"] = async({request, ...context}) => {\n\t\tconst g = this.colors.none\n\t\tthis.log(\n\t\t\t...this.#context(context),\n\t\t\tg(`${request.method}()`),\n\t\t)\n\t}\n\n\trpcError: Tap[\"rpcError\"] = async({request, error, ...context}) => {\n\t\tthis.error(\n\t\t\t...this.#context(context),\n\t\t\t`${request.method}()`,\n\t\t\terror,\n\t\t)\n\t}\n\n\t#context({meta, label, remote}: TapContext) {\n\t\tconst cRemote = this.colors.mix(this.colors.blue, this.colors.dim)\n\t\tconst cLocal = this.colors.mix(this.colors.cyan, this.colors.dim)\n\t\treturn [\n\t\t\tmeta\n\t\t\t\t? this.#meta(meta)\n\t\t\t\t: undefined,\n\t\t\tlabel\n\t\t\t\t? label\n\t\t\t\t: undefined,\n\t\t\tremote === undefined\n\t\t\t\t? undefined\n\t\t\t\t: remote\n\t\t\t\t\t? cRemote(\"<-\")\n\t\t\t\t\t: cLocal(\"->\"),\n\t\t].filter(Boolean)\n\t}\n\n\t#meta(meta: HttpMeta) {\n\t\tconst {headers} = meta.request\n\t\treturn [\n\t\t\tthis.colors.yellow(`[${meta.ip}]`),\n\t\t\tthis.colors.green(headers.origin ?headers.origin :\"(no-origin)\"),\n\t\t].join(\" \")\n\t}\n}\n\n", "\nimport {Tap} from \"../types.js\"\nimport {LoggerTap} from \"./logger.js\"\n\nexport class ErrorTap extends LoggerTap implements Tap {\n\trpcRequest: Tap[\"rpcRequest\"] = async() => {}\n}\n\n", "\nexport namespace JsonRpc {\n\texport type Requestish = Request | Request[]\n\texport type Respondish = Response | Response[]\n\texport type Bidirectional = Requestish | Respondish\n\n\t/////////////////////////////////////////////////////////////\n\n\texport const version = \"2.0\"\n\n\texport type Request<P extends Params = any> = (\n\t\t| Query<P>\n\t\t| Notification<P>\n\t)\n\n\texport type Response<Result = any> = (\n\t\t| Success<Result>\n\t\t| Failure\n\t)\n\n\texport type Serializable = (\n\t\t| void\n\t\t| null\n\t\t| undefined\n\t\t| boolean\n\t\t| number\n\t\t| string\n\t\t| Serializable[]\n\t\t| {[key: string]: Serializable}\n\t)\n\n\t/////////////////////////////////////////////////////////////\n\n\texport type Id = number | string\n\texport type Params = Serializable[] | Record<string, Serializable>\n\n\texport type Notification<P extends Params> = {\n\t\tjsonrpc: string\n\t\tmethod: string\n\t\tparams: P\n\t}\n\n\texport type Query<P extends Params> = {\n\t\tid: Id\n\t\tjsonrpc: string\n\t\tmethod: string\n\t\tparams: P\n\t}\n\n\texport type Error = {\n\t\tcode: number\n\t\tmessage: string\n\t\tdata?: any\n\t}\n\n\texport type Success<Result> = {\n\t\tjsonrpc: \"2.0\"\n\t\tid: Id\n\t\tresult: Result\n\t}\n\n\texport type Failure = {\n\t\tjsonrpc: \"2.0\"\n\t\tid: Id\n\t\terror: Error\n\t}\n\n\t/////////////////////////////////////////////////////////////\n\n\texport function getId(request: Request): Id | null {\n\t\treturn \"id\" in request\n\t\t\t? request.id\n\t\t\t: null\n\t}\n\n\texport const errorCodes = {\n\t\tserverError: -32000,\n\t\tunexposedError: -32001,\n\t}\n}\n\n", "\n/**\n * An error that has a publicly viewable name and message.\n * - this error class, and its subclasses, are the only kinds of errors that renraku will send back to clients\n * - so if you want a client to be able to read an error message you throw, it must be a subclass of ExposedError\n */\nexport class ExposedError extends Error {\n\treadonly name = this.constructor.name\n}\n\n////////////////////////////////////////////////////\n\nexport class RemoteError extends Error {\n\treadonly name = this.constructor.name\n}\n\nexport class RemoteTimeoutError extends RemoteError {\n\treadonly name = this.constructor.name\n}\n\n////////////////////////////////////////////////////\n\nexport class HttpError extends Error {\n\treadonly name = this.constructor.name\n\treadonly code: number\n\n\tconstructor(code: number, message: string) {\n\t\tsuper(message)\n\t\tthis.code = code\n\t}\n}\n\n", "\nimport {Tap} from \"./types.js\"\nimport {JsonRpc} from \"./json-rpc.js\"\nimport {ExposedError} from \"./errors.js\"\n\nexport async function execute<R>({\n\t\ttap,\n\t\trequest,\n\t\taction,\n\t}: {\n\t\ttap: Tap\n\t\trequest: JsonRpc.Request\n\t\taction: () => Promise<R>\n\t}): Promise<JsonRpc.Response<R> | null> {\n\n\tconst id = JsonRpc.getId(request)\n\n\ttry {\n\t\tconst result = await action()\n\n\t\tif (id === null)\n\t\t\treturn null\n\n\t\treturn {\n\t\t\tid,\n\t\t\tresult,\n\t\t\tjsonrpc: JsonRpc.version,\n\t\t}\n\t}\n\n\tcatch (error) {\n\t\ttap.rpcError({request, error})\n\n\t\tif (id === null)\n\t\t\treturn null\n\n\t\treturn {\n\t\t\tid,\n\t\t\tjsonrpc: JsonRpc.version,\n\t\t\terror: (error instanceof ExposedError)\n\t\t\t\t? {\n\t\t\t\t\tcode: JsonRpc.errorCodes.serverError,\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t}\n\t\t\t\t: {\n\t\t\t\t\tcode: JsonRpc.errorCodes.unexposedError,\n\t\t\t\t\tmessage: `unexposed error`,\n\t\t\t\t},\n\t\t}\n\t}\n}\n\n", "\nimport {drill} from \"@e280/stz\"\nimport {execute} from \"./execute.js\"\nimport {ErrorTap} from \"./taps/error.js\"\nimport {Endpoint, Fn, Fns, Tap} from \"./types.js\"\n\nexport type EndpointOptions<F extends Fns> = {\n\tfns: F\n\ttap?: Tap\n}\n\n/**\n * Create a renraku endpoint for your fns.\n * - an endpoint is a function that accepts json rpc requests\n * - for each request, it calls the appropriate fn\n * - it then returns the fn's in json rpc response format\n */\nexport function makeEndpoint<F extends Fns>(options: EndpointOptions<F>): Endpoint {\n\tconst tap = options.tap ?? new ErrorTap()\n\n\treturn async request => {\n\t\tconst path = request.method.split(\".\")\n\t\tconst fn = drill(options.fns, path) as Fn\n\t\tconst action = async() => await fn(...request.params)\n\n\t\ttap.rpcRequest({request})\n\n\t\tconst response = await execute({\n\t\t\ttap,\n\t\t\trequest,\n\t\t\taction,\n\t\t})\n\n\t\treturn response\n\t}\n}\n\n", "\nimport {Fn, Fns} from \"./types.js\"\n\nexport const tune = Symbol(\"tune\")\nexport const query = Symbol(\"query\")\nexport const notify = Symbol(\"notify\")\nexport const settings = Symbol(\"settings\")\n\nexport type TuneSymbol = typeof tune\nexport type QuerySymbol = typeof query\nexport type NotifySymbol = typeof notify\nexport type SettingsSymbol = typeof settings\n\nexport type Executor = (\n\tpath: string[],\n\targs: any[],\n\tsettings: Settings,\n) => Promise<any>\n\nexport type Settings = {\n\tnotify?: boolean\n\ttransfer?: Transferable[]\n}\n\nexport type Remote<F extends Fn | Fns> = (\n\tF extends Fn\n\t\t? F & {\n\t\t\t[tune]: (settings: Settings) => F\n\t\t\t[query]: F\n\t\t\t[notify]: F\n\t\t\t[settings]: Settings\n\t\t}\n\t\t: F extends Fns\n\t\t\t? {[K in keyof F]: Remote<F[K]>}\n\t\t\t: never\n)\n\nexport function remoteProxy<F extends Fns>(executor: Executor) {\n\n\tfunction recurse(path: string[]) {\n\t\tconst currentSettings: Settings = {notify: undefined}\n\n\t\treturn new Proxy((() => {}) as any, {\n\t\t\tapply: (_, _this, args) => {\n\t\t\t\treturn executor(path, args, currentSettings)\n\t\t\t},\n\t\t\tget: (target, key: string | QuerySymbol | NotifySymbol | TuneSymbol | SettingsSymbol) => {\n\n\t\t\t\tif (key === \"then\")\n\t\t\t\t\treturn undefined\n\n\t\t\t\tif (key === tune)\n\t\t\t\t\treturn (settings: Settings) => (...args: any[]) => executor(path, args, {\n\t\t\t\t\t\t...currentSettings,\n\t\t\t\t\t\t...settings,\n\t\t\t\t\t})\n\n\t\t\t\tif (key === notify)\n\t\t\t\t\treturn (...args: any[]) => executor(path, args, {\n\t\t\t\t\t\t...currentSettings,\n\t\t\t\t\t\tnotify: true,\n\t\t\t\t\t})\n\n\t\t\t\tif (key === query)\n\t\t\t\t\treturn (...args: any[]) => executor(path, args, {\n\t\t\t\t\t\t...currentSettings,\n\t\t\t\t\t\tnotify: false,\n\t\t\t\t\t})\n\n\t\t\t\tif (key === settings)\n\t\t\t\t\treturn currentSettings\n\n\t\t\t\tif (!target[key])\n\t\t\t\t\ttarget[key] = recurse([...path, key])\n\n\t\t\t\treturn target[key]\n\t\t\t},\n\t\t\tset: (target, key: string, value: any) => {\n\t\t\t\ttarget[key] = value\n\t\t\t\treturn true\n\t\t\t},\n\t\t})\n\t}\n\n\treturn recurse([]) as Remote<F>\n}\n\n", "\nimport {JsonRpc} from \"./json-rpc.js\"\nimport {RemoteError} from \"./errors.js\"\nimport {ErrorTap} from \"./taps/error.js\"\nimport {remoteProxy} from \"./remote-proxy.js\"\nimport {Endpoint, Fns, Tap} from \"./types.js\"\n\nexport type RemoteOptions = {\n\tendpoint: Endpoint\n\tlabel?: string\n\tnotify?: boolean\n\ttap?: Tap\n}\n\n/**\n * Create a renraku remote for the given endpoint.\n * - the remote uses js proxies to mirror the shape of your fns object\n * - so when you make async calls on the remote, it will convert those into json rpc requests that are actuated on the given endpoint\n * - the endpoint you provide could be making network calls, or doing something else, the remote doesn't care how the endpoint is implemented\n */\nexport function makeRemote<F extends Fns>(options: RemoteOptions) {\n\tconst {endpoint, tap = new ErrorTap()} = options\n\tlet id = 1\n\n\treturn remoteProxy<F>(async(\n\t\t\tpath,\n\t\t\tparams,\n\t\t\tsettings,\n\t\t) => {\n\n\t\tconst notify = settings.notify ?? options.notify ?? false\n\t\tconst transfer = settings.transfer\n\n\t\tconst base: JsonRpc.Notification<any[]> = {\n\t\t\tjsonrpc: \"2.0\" as const,\n\t\t\tmethod: path.join(\".\"),\n\t\t\tparams,\n\t\t}\n\n\t\tconst request: JsonRpc.Request = (\n\t\t\tnotify\n\t\t\t\t? base\n\t\t\t\t: {...base, id: id++}\n\t\t)\n\n\t\ttap.rpcRequest({request})\n\n\t\tconst response = await endpoint(request, {transfer})\n\n\t\tif (notify && !response)\n\t\t\treturn null\n\n\t\tif (!response)\n\t\t\tthrow new RemoteError(\"response was null, but shouldn't be, because the request was not a notification\")\n\n\t\tif (\"error\" in response)\n\t\t\tthrow new RemoteError(\n\t\t\t\toptions.label\n\t\t\t\t\t? `${options.label}: ${response.error.message}`\n\t\t\t\t\t: response.error.message\n\t\t\t)\n\n\t\treturn response.result\n\t})\n}\n\n", "\nimport {Fns} from \"./types.js\"\nimport {makeRemote} from \"./remote.js\"\nimport {Remote} from \"./remote-proxy.js\"\nimport {makeEndpoint, EndpointOptions} from \"./endpoint.js\"\n\n/**\n * Wrap your fns in an endpoint and remote.\n * - this gives you a real renraku remote where you can use the `tune` symbol and such\n * - this is useful for when you have special logic that relies on that special renraku functionality\n */\nexport function makeMock<F extends Fns>(options: EndpointOptions<F>): Remote<F> {\n\treturn makeRemote<F>({endpoint: makeEndpoint(options), tap: options.tap})\n}\n\n", "\nimport {pub} from \"@e280/stz\"\nimport {JsonRpc} from \"../../../core/json-rpc.js\"\n\nexport class Conduit {\n\trecv = pub<[incoming: JsonRpc.Bidirectional, {origin: string}]>()\n\tsendRequest = pub<[request: JsonRpc.Requestish, transfer: Transferable[] | undefined]>()\n\tsendResponse = pub<[response: JsonRpc.Respondish, transfer: Transferable[] | undefined]>()\n\n\tstatic makeEntangledPair({origin = \"example.e280.org\"}: {origin?: string} = {}) {\n\t\tconst a = new this()\n\t\tconst b = new this()\n\n\t\tconst disposers = [\n\t\t\ta.sendRequest.sub(data => b.recv(data, {origin})),\n\t\t\ta.sendResponse.sub(data => b.recv(data, {origin})),\n\t\t\tb.sendRequest.sub(data => a.recv(data, {origin})),\n\t\t\tb.sendResponse.sub(data => a.recv(data, {origin})),\n\t\t]\n\n\t\tconst dispose = () => disposers.forEach(fn => fn())\n\t\treturn [a, b, dispose] as [Conduit, Conduit, () => void]\n\t}\n}\n\n", "\nimport {defer} from \"@e280/stz\"\nimport {Endpoint} from \"../../../core/types.js\"\nimport {JsonRpc} from \"../../../core/json-rpc.js\"\nimport {Channel, ChannelMessage} from \"../types.js\"\nimport {ResponseWaiter} from \"./response-waiter.js\"\n\nexport function onMessage(channel: Channel, fn: (e: ChannelMessage) => void) {\n\tchannel.addEventListener(\"message\", fn)\n\treturn () => channel.removeEventListener(\"message\", fn)\n}\n\nexport function is_valid_json_rpc_message(data: any): data is JsonRpc.Bidirectional {\n\treturn (\n\t\tdata !== undefined &&\n\t\tdata !== null &&\n\t\ttypeof data === \"object\" &&\n\t\t\"jsonrpc\" in data &&\n\t\tdata.jsonrpc === JsonRpc.version\n\t)\n}\n\n////////////////\n\nexport type SendRequestFn = (\n\trequest: JsonRpc.Request,\n\ttransfer: Transferable[] | undefined,\n\tdone: Promise<JsonRpc.Response | null>,\n) => void\n\nexport function makeRemoteEndpoint(waiter: ResponseWaiter, sendRequest: SendRequestFn): Endpoint {\n\treturn async(request, {transfer} = {}) => {\n\t\tif (\"id\" in request) {\n\t\t\tconst done = defer<JsonRpc.Response | null>()\n\t\t\tsendRequest(request, transfer, done.promise)\n\t\t\treturn waiter.wait(request.id, request.method).then(response => {\n\t\t\t\tdone.resolve(response)\n\t\t\t\treturn response\n\t\t\t})\n\t\t}\n\t\telse {\n\t\t\tconst done = Promise.resolve(null)\n\t\t\tsendRequest(request, transfer, done)\n\t\t\treturn done\n\t\t}\n\t}\n}\n\nexport function interpretIncoming(json: JsonRpc.Bidirectional) {\n\tconst requests: JsonRpc.Request[] = []\n\tconst responses: JsonRpc.Response[] = []\n\n\tfor (const item of (Array.isArray(json) ? json : [json])) {\n\t\tif (\"method\" in item) requests.push(item)\n\t\telse responses.push(item)\n\t}\n\n\treturn {requests, responses}\n}\n\nexport async function handleIncomingRequests(\n\t\tlocalEndpoint: Endpoint,\n\t\trequests: JsonRpc.Request[],\n\t): Promise<JsonRpc.Respondish | null> {\n\n\tconst responses = (\n\t\tawait Promise.all(\n\t\t\trequests.map(async request => localEndpoint(request))\n\t\t)\n\t).filter(r => r !== null)\n\n\tif (responses.length === 0)\n\t\treturn null\n\n\treturn (responses.length === 1)\n\t\t? responses[0]\n\t\t: responses\n}\n\nexport function handleIncomingResponses(\n\t\twaiter: ResponseWaiter,\n\t\tresponses: JsonRpc.Response[],\n\t) {\n\n\tfor (const response of responses)\n\t\twaiter.deliverResponse(response)\n}\n\n", "\nimport {disposer} from \"@e280/stz\"\nimport {Conduit} from \"./conduit.js\"\nimport {PostableChannel} from \"../types.js\"\nimport {onMessage} from \"../parts/helpers.js\"\n\nexport class PostableConduit extends Conduit {\n\tdispose = disposer()\n\n\tconstructor(channel: PostableChannel) {\n\t\tsuper()\n\t\tthis.dispose.schedule(\n\t\t\tthis.sendRequest.sub((m, transfer) => channel.postMessage(m, transfer)),\n\t\t\tthis.sendResponse.sub((m, transfer) => channel.postMessage(m, transfer)),\n\t\t\tonMessage(channel, e => this.recv(e.data, e)),\n\t\t)\n\t}\n}\n\n", "\nimport {Fns} from \"../../../core/types.js\"\nimport {Remote} from \"../../../core/remote-proxy.js\"\n\nexport class MessengerMeta<RemoteFns extends Fns> {\n\ttransfer: Transferable[] | undefined\n\n\tconstructor(public remote: Remote<RemoteFns>) {}\n}\n\n", "\nexport const defaults = Object.freeze({\n\ttimeout: 60_000,\n\tmaxRequestBytes: 10_000_000,\n})\n\n", "\nimport {deadline, DeadlineError, defer, Deferred} from \"@e280/stz\"\n\nimport {JsonRpc} from \"../../../core/json-rpc.js\"\nimport {RemoteError} from \"../../../core/errors.js\"\n\ntype Pend = {\n\tmethod: string\n\tdeferred: Deferred<JsonRpc.Response>\n}\n\nexport class ResponseWaiter {\n\tpending = new Map<JsonRpc.Id, Pend>()\n\n\tconstructor(public timeout: number) {}\n\n\tasync wait(id: JsonRpc.Id, method: string) {\n\t\tconst deferred = defer<JsonRpc.Response>()\n\t\tthis.pending.set(id, {method, deferred})\n\t\treturn await deadline(this.timeout, () => deferred.promise)\n\t\t\t.catch(error => {\n\t\t\t\tif (error instanceof DeadlineError)\n\t\t\t\t\terror.message = `request #${id} ${method}(), ${error.message}`\n\t\t\t\tthrow error\n\t\t\t})\n\t}\n\n\tdeliverResponse(response: JsonRpc.Response) {\n\t\tconst pend = this.pending.get(response.id)\n\t\tif (pend) {\n\t\t\tif (\"error\" in response)\n\t\t\t\tpend.deferred.reject(new RemoteError(response.error.message))\n\t\t\telse\n\t\t\t\tpend.deferred.resolve(response)\n\t\t}\n\t}\n}\n\n", "\nimport {disposer} from \"@e280/stz\"\n\nimport {defaults} from \"../../defaults.js\"\nimport {MessengerOptions} from \"./types.js\"\nimport {MessengerMeta} from \"./parts/meta.js\"\nimport {JsonRpc} from \"../../core/json-rpc.js\"\nimport {bindTap} from \"../../core/taps/bind.js\"\nimport {makeRemote} from \"../../core/remote.js\"\nimport {Remote} from \"../../core/remote-proxy.js\"\nimport {Endpoint, Fns} from \"../../core/types.js\"\nimport {makeEndpoint} from \"../../core/endpoint.js\"\nimport {ResponseWaiter} from \"./parts/response-waiter.js\"\nimport {handleIncomingRequests, interpretIncoming, makeRemoteEndpoint} from \"./parts/helpers.js\"\n\n/**\n * Establish a renraku remote that communicates over the given conduit.\n * - supports two-way or one-way communication\n * - you can use a messenger to call a remote messenger\n * - you can use a messenger to respond to incoming requests\n */\nexport class Messenger<LocalFns extends Fns = any, RemoteFns extends Fns = any> {\n\tremote: Remote<RemoteFns>\n\tremoteEndpoint: Endpoint\n\tdispose = disposer()\n\n\t#waiter: ResponseWaiter\n\n\tconstructor(private options: MessengerOptions<LocalFns, RemoteFns>) {\n\t\tconst {conduit, tap} = options\n\n\t\tthis.#waiter = new ResponseWaiter(options.timeout ?? defaults.timeout)\n\n\t\tthis.remoteEndpoint = makeRemoteEndpoint(\n\t\t\tthis.#waiter,\n\t\t\tconduit.sendRequest.pub.bind(conduit.sendRequest),\n\t\t)\n\n\t\tthis.remote = makeRemote<RemoteFns>({\n\t\t\tendpoint: this.remoteEndpoint,\n\t\t\ttap: tap && bindTap(tap, {remote: true}),\n\t\t})\n\n\t\tthis.dispose.schedule(conduit.recv.sub(m => this.recv(m)))\n\t}\n\n\tasync recv(incoming: JsonRpc.Bidirectional) {\n\t\tconst meta = new MessengerMeta<RemoteFns>(this.remote)\n\t\tconst {conduit, rpc, tap} = this.options\n\n\t\tconst {requests, responses} = interpretIncoming(incoming)\n\n\t\tfor (const response of responses)\n\t\t\tthis.#waiter.deliverResponse(response)\n\n\t\tif (!rpc)\n\t\t\treturn\n\n\t\tconst fns = await rpc(meta)\n\t\tconst endpoint = makeEndpoint({\n\t\t\tfns,\n\t\t\ttap: tap && bindTap(tap, {remote: false}),\n\t\t})\n\n\t\tconst outgoing = await handleIncomingRequests(endpoint, requests)\n\t\tif (outgoing)\n\t\t\tawait conduit.sendResponse(outgoing, meta.transfer)\n\t}\n}\n\n", "\nimport {MessengerMeta, Remote} from \"@e280/renraku\"\nimport {MinistryFns, Schematic} from \"./types.js\"\n\nexport type HostShell<S extends Schematic> = {\n\thost: Remote<S[\"host\"]>\n\ttransfer: Transferable[] | undefined\n}\n\nexport type WorkShell<S extends Schematic> = {\n\twork: Remote<S[\"work\"]>\n\ttransfer: Transferable[] | undefined\n}\n\nexport const shells = {\n\tderive: {\n\t\thost: <S extends Schematic>(meta: MessengerMeta<MinistryFns<S>>): HostShell<S> => ({\n\t\t\thost: meta.remote.host,\n\t\t\tget transfer() { return meta.transfer },\n\t\t\tset transfer(t) { meta.transfer = t },\n\t\t}),\n\t\twork: <S extends Schematic>(meta: MessengerMeta<S[\"work\"]>): WorkShell<S> => ({\n\t\t\twork: meta.remote,\n\t\t\tget transfer() { return meta.transfer },\n\t\t\tset transfer(t) { meta.transfer = t },\n\t\t}),\n\t},\n\tmock: {\n\t\thost: <S extends Schematic>(): HostShell<S> => ({\n\t\t\thost: undefined as any,\n\t\t\ttransfer: undefined,\n\t\t}),\n\t\twork: <S extends Schematic>(): WorkShell<S> => ({\n\t\t\twork: undefined as any,\n\t\t\ttransfer: undefined,\n\t\t})\n\t},\n}\n\n", "\nimport {ErrorTap} from \"@e280/renraku\"\n\nexport const defaultTap = new ErrorTap()\n\n", "\nimport {Messenger, PostableConduit} from \"@e280/renraku\"\n\nimport {shells} from \"./shells.js\"\nimport {Compat} from \"../compat/types.js\"\nimport {defaultTap} from \"./default-tap.js\"\nimport {MinistryFns, Schematic, SetupWork, WorkerOpts} from \"./types.js\"\n\n/**\n * create a web worker\n */\nexport async function worker<S extends Schematic>(\n\t\tcompat: Compat,\n\t\tsetupWork: SetupWork<S>,\n\t\toptions: WorkerOpts = {},\n\t) {\n\n\tconst tap = options.tap ?? defaultTap\n\n\tconst messenger = new Messenger<S[\"work\"], MinistryFns<S>>({\n\t\ttap,\n\t\ttimeout: options.timeout ?? Infinity,\n\t\tconduit: new PostableConduit(compat.getSelf()),\n\t\trpc: async m => setupWork(\n\t\t\tshells.derive.host<S>(m),\n\t\t),\n\t})\n\n\tawait messenger.remote.infra.ready()\n\treturn messenger.remote.host\n}\n\n", "\nimport {defer} from \"@e280/stz\"\nimport {Messenger, PostableConduit} from \"@e280/renraku\"\n\nimport {shells} from \"./shells.js\"\nimport {defaultTap} from \"./default-tap.js\"\nimport {Compat, CompatWorker} from \"../compat/types.js\"\nimport {Infra, MinistryFns, Schematic, ThreadOptions} from \"./types.js\"\n\nexport class Thread<S extends Schematic> {\n\tconstructor(\n\t\tpublic worker: CompatWorker,\n\t\tpublic messenger: Messenger<MinistryFns<S>, S[\"work\"]>,\n\t) {}\n\n\tstatic async make<S extends Schematic>(compat: Compat, options: ThreadOptions<S>) {\n\t\tconst tap = options.tap ?? defaultTap\n\t\tconst label = options.label ?? \"comrade\"\n\t\tconst worker = compat.loadWorker(options.workerUrl, label)\n\t\tconst readyprom = defer<void>()\n\n\t\tconst infra: Infra = {\n\t\t\tasync ready() {\n\t\t\t\treadyprom.resolve()\n\t\t\t},\n\t\t}\n\n\t\tconst messenger = new Messenger<MinistryFns<S>, S[\"work\"]>({\n\t\t\ttap,\n\t\t\ttimeout: options.timeout ?? Infinity,\n\t\t\tconduit: new PostableConduit(worker),\n\t\t\trpc: async m => ({\n\t\t\t\tinfra,\n\t\t\t\thost: options.setupHost(\n\t\t\t\t\tshells.derive.work<S>(m)\n\t\t\t\t),\n\t\t\t}),\n\t\t})\n\n\t\tawait readyprom.promise\n\t\treturn new this<S>(worker, messenger)\n\t}\n\n\tget work() {\n\t\treturn this.messenger.remote\n\t}\n\n\tterminate() {\n\t\tthis.worker.terminate()\n\t}\n}\n\n", "\nimport {defer} from \"@e280/stz\"\nimport {Endpoint, makeRemote, Remote, Tap} from \"@e280/renraku\"\n\nimport {Thread} from \"./thread.js\"\nimport {Compat} from \"../compat/types.js\"\nimport {defaultTap} from \"./default-tap.js\"\nimport {ClusterOptions, Schematic, Task} from \"./types.js\"\n\n/**\n * a pool of web workers\n * - please use `await Cluster.make(options)` to create your worker pool\n * - call your worker functions like `await cluster.remote.hello()`\n */\nexport class Cluster<S extends Schematic> {\n\n\tstatic async make<S extends Schematic>(compat: Compat, options: ClusterOptions<S>) {\n\t\tconst workerCount = options.workerCount ?? compat.guessOptimalThreadCount()\n\t\tconst threads = await Promise.all([...Array(workerCount)].map(\n\t\t\tasync(_, index) => Thread.make(compat, {\n\t\t\t\t...options,\n\t\t\t\tlabel: options.label ?? `${options.label ?? \"comrade\"}_${index + 1}`,\n\t\t\t})\n\t\t))\n\t\treturn new this<S>(threads, {tap: options.tap})\n\t}\n\n\twork: Remote<S[\"work\"]>\n\t#available = new Set<Thread<S>>()\n\t#tasks: Task[] = []\n\n\tconstructor(private threads: Thread<S>[], options: {tap?: Tap} = {}) {\n\t\tconst tap = options.tap ?? defaultTap\n\n\t\t// delegation\n\t\tconst remoteEndpoint: Endpoint = async(request, special) => this.#scheduleTask({\n\t\t\trequest,\n\t\t\tprom: defer(),\n\t\t\ttransfer: special?.transfer,\n\t\t})\n\n\t\t// remote proxy to call comrade fns\n\t\tthis.work = makeRemote({\n\t\t\ttap,\n\t\t\tendpoint: remoteEndpoint,\n\t\t})\n\n\t\t// in the beginning, all threads are available\n\t\tthreads.forEach(t => this.#available.add(t))\n\t}\n\n\tget threadCount() {\n\t\treturn this.threads.length\n\t}\n\n\tterminate() {\n\t\tfor (const thread of this.threads)\n\t\t\tthread.terminate()\n\t}\n\n\t#scheduleTask(task: Task) {\n\t\tthis.#tasks.push(task)\n\t\tthis.#distributeTasks()\n\t\treturn task.prom.promise\n\t}\n\n\t#distributeTasks() {\n\t\twhile (this.#available.size > 0 && this.#tasks.length > 0) {\n\t\t\tconst thread = [...this.#available].pop()!\n\t\t\tthis.#available.delete(thread)\n\n\t\t\tconst task = this.#tasks.shift()!\n\n\t\t\t// this thread is no longer available\n\t\t\tthis.#available.delete(thread)\n\n\t\t\t// call the thread endpoint\n\t\t\tconst callprom = thread.messenger.remoteEndpoint(task.request, {transfer: task.transfer})\n\n\t\t\t// resolve/reject the task prom when callprom is done\n\t\t\ttask.prom.entangle(callprom).finally(() => {\n\n\t\t\t\t// thread is ready again\n\t\t\t\tthis.#available.add(thread)\n\n\t\t\t\t// distribute more tasks\n\t\t\t\tthis.#distributeTasks()\n\t\t\t})\n\t\t}\n\t}\n}\n\n", "\nimport {makeMock, Tap} from \"@e280/renraku\"\n\nimport {worker} from \"./parts/worker.js\"\nimport {Compat} from \"./compat/types.js\"\nimport {Thread} from \"./parts/thread.js\"\nimport {shells} from \"./parts/shells.js\"\nimport {Cluster} from \"./parts/cluster.js\"\nimport {defaultTap} from \"./parts/default-tap.js\"\nimport {ClusterOptions, Mocks, Schematic, SetupHost, SetupWork, ThreadOptions, WorkerOpts} from \"./parts/types.js\"\n\nexport const setupComrade = (compat: Compat) => ({\n\tthread: <S extends Schematic>(options: ThreadOptions<S>) => Thread.make(compat, options),\n\tcluster: <S extends Schematic>(options: ClusterOptions<S>) => Cluster.make(compat, options),\n\n\tworker: <S extends Schematic>(\n\t\tsetupWork: SetupWork<S>,\n\t\toptions: WorkerOpts = {},\n\t) => worker(compat, setupWork, options),\n\n\twork: <S extends Schematic>(fn: SetupWork<S>) => fn,\n\thost: <S extends Schematic>(fn: SetupHost<S>) => fn,\n\n\tmocks<S extends Schematic>(options: {\n\t\t\ttap?: Tap\n\t\t\tsetupWork: SetupWork<S>\n\t\t\tsetupHost: SetupHost<S>\n\t\t}): Mocks<S> {\n\n\t\tconst {setupWork, setupHost, tap = defaultTap} = options\n\n\t\tconst hostShell = shells.mock.host<S>()\n\t\tconst workShell = shells.mock.work<S>()\n\n\t\tworkShell.work = makeMock({tap, fns: setupWork(hostShell)})\n\t\thostShell.host = makeMock({tap, fns: setupHost(workShell)})\n\n\t\treturn {\n\t\t\tworkShell,\n\t\t\thostShell,\n\t\t\twork: workShell.work,\n\t\t\thost: hostShell.host,\n\t\t}\n\t},\n\n\tmockWork<S extends Schematic>(setupWork: SetupWork<S>, tap: Tap = defaultTap) {\n\t\tconst hostShell = shells.mock.host<S>()\n\t\tconst workShell = shells.mock.work<S>()\n\n\t\tworkShell.work = makeMock({tap, fns: setupWork(hostShell)})\n\n\t\treturn {\n\t\t\tworkShell,\n\t\t\thostShell,\n\t\t\twork: workShell.work,\n\t\t\tmockHost: (setupHost: SetupHost<S>): Mocks<S> => {\n\t\t\t\thostShell.host = makeMock({tap, fns: setupHost(workShell)})\n\t\t\t\treturn {\n\t\t\t\t\tworkShell,\n\t\t\t\t\thostShell,\n\t\t\t\t\twork: workShell.work,\n\t\t\t\t\thost: hostShell.host,\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t},\n})\n\n", "\nimport {Compat, CompatWorker} from \"./types.js\"\n\nexport const setupBrowserCompat = (): Compat => ({\n\tgetSelf() {\n\t\treturn self\n\t},\n\n\tguessOptimalThreadCount() {\n\t\tconst count = navigator.hardwareConcurrency ?? 1\n\t\treturn Math.max(1, count - 1)\n\t},\n\n\tloadWorker(url, name) {\n\t\treturn new window.Worker(url, {name, type: \"module\"}) as CompatWorker\n\t},\n\n\tasync loadWasm(url) {\n\t\treturn WebAssembly.instantiateStreaming(fetch(url))\n\t},\n})\n\n", "\nimport {setupComrade} from \"./comrade.js\"\nimport {setupBrowserCompat} from \"./compat/browser.js\"\n\nexport const compat = setupBrowserCompat()\nexport const Comrade = setupComrade(compat)\n\nexport * from \"./exports.js\"\n\n", "\n// type Events =\n// \t| {type: \"config\", config: {audio: AudioDecoderConfig, video: VideoDecoderConfig}}\n// \t| {type: \"info\", data: WebMediaInfo}\n// \t| {type: \"encoderQueueSize\", size: number}\n//\n// type Handler = (event: Events) => void\n\nexport class Machina {\n\tcount = 0\n\n\t// #handlers = new Map<number, Handler>()\n\t//\n\t// register(id: number, handler: Handler) {\n\t// \tthis.#handlers.set(id, handler)\n\t// }\n\t//\n\t// unregister(id: number) {\n\t// \tthis.#handlers.delete(id)\n\t// }\n\t//\n\t// dispatch(id: number, event: Events) {\n\t// \tthis.#handlers.get(id)?.(event)\n\t// }\n}\n\n", "//@ts-ignore\nimport transitions from \"gl-transitions\"\nimport {Filter, GlProgram, Sprite, Texture, ImageSource} from \"pixi.js\"\n\nimport {vertex} from \"./parts/vertex.js\"\nimport {uniforms} from \"./parts/uniforms.js\"\nimport {fragment} from \"./parts/fragment.js\"\nimport {GLTransition, TransitionOptions, TransitionRendererOptions} from \"./parts/types.js\"\n\nexport function makeTransition({name, renderer}: TransitionOptions) {\n\tconst transition = transitions.find((t: GLTransition) => t.name === name) as GLTransition\n\tconst transitionSprite = new Sprite()\n\tconst transitionTexture = new Texture()\n\tconst sourceFrom = new ImageSource({})\n\tconst sourceTo = new ImageSource({})\n\n\tconst filter = new Filter({\n\t\tglProgram: new GlProgram({\n\t\t\tvertex,\n\t\t\tfragment: fragment(transition.glsl),\n\t\t}),\n\t\tresources: {\n\t\t\tfrom: sourceFrom,\n\t\t\tto: sourceTo,\n\t\t\tuniforms: {\n\t\t\t\t...uniforms.basics,\n\t\t\t\t...uniforms.custom(transition)\n\t\t\t}\n\t\t}\n\t})\n\n\ttransitionSprite.filters = [filter]\n\n\treturn {\n\t\trender({width, height, from, to, progress}: TransitionRendererOptions) {\n\t\t\tif(transitionSprite.width !== width || transitionSprite.height !== height) {\n\t\t\t\ttransitionSprite.setSize({width, height})\n\t\t\t\ttransitionTexture.source.resize(width, height)\n\t\t\t}\n\n\t\t\tsourceFrom.resource = from\n\t\t\tsourceTo.resource = to\n\t\t\tsourceFrom.update()\n\t\t\tsourceTo.update()\n\n\t\t\tfilter.resources.uniforms.uniforms.progress = progress\n\n\t\t\trenderer.render({\n\t\t\t\tcontainer: transitionSprite,\n\t\t\t\ttarget: transitionTexture,\n\t\t\t\tclear: false,\n\t\t\t\twidth,\n\t\t\t\theight\n\t\t\t})\n\n\t\t\treturn transitionTexture\n\t\t}\n\t}\n}\n\n", "export const vertex = `\n\tin vec2 aPosition;\n\tvarying vec2 _uv; // gl-transition\n\tuniform mat3 projectionMatrix;\n\tuniform vec4 uInputSize;\n\tuniform vec4 uOutputFrame;\n\tout vec2 vTextureCoord;\n\tuniform vec4 uOutputTexture;\n\n\tvec4 filterVertexPosition( void )\n\t{\n\t\t\tvec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;\n\n\t\t\tposition.x = position.x * (2.0 / uOutputTexture.x) - 1.0;\n\t\t\tposition.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;\n\n\t\t\treturn vec4(position, 0.0, 1.0);\n\t}\n\n\tvec2 filterTextureCoord( void )\n\t{\n\treturn aPosition * (uOutputFrame.zw * uInputSize.zw);\n\t}\n\n\tvoid main(void)\n\t{\n\tgl_Position = filterVertexPosition();\n\tvTextureCoord = filterTextureCoord();\n\t_uv = vec2(0.5, 0.5) * (aPosition +vec2(1.0, 1.0)); // gl-transition\n\t}\n`\n", "import {GLTransition} from \"./types.js\"\n\nexport const uniforms = {\n\tcustom: (transition: GLTransition) => Object.fromEntries(\n\t\tObject.entries(transition.defaultParams).map(([name, value]) => [\n\t\t\tname,\n\t\t\t{\n\t\t\t\tvalue,\n\t\t\t\ttype: getUniformType(transition.paramsTypes[name])\n\t\t\t}\n\t\t])\n\t),\n\tbasics: {\n\t\t_fromR: {value: 1, type: \"f32\"},\n\t\t_toR: {value: 1, type: \"f32\"},\n\t\tratio: {value: 1, type: \"f32\"},\n\t\tprogress: {value: 0, type: \"f32\"},\n\t\tcustomUniform: {value: 0, type: \"f32\"},\n\t}\n}\n\nconst getUniformType = (type: string) => {\n\tif(type === \"f32\" || type === \"i32\") {\n\t\treturn type\n\t} else if(type === \"float\") {\n\t\treturn \"f32\"\n\t}\n\telse return `${type}<f32>`\n}\n", "export const fragment = (glsl: string) => `\n\tprecision highp float;\n\tvarying vec2 vTextureCoord;\n\tvarying vec2 _uv;\n\tuniform sampler2D from, to;\n\tuniform float progress, ratio, _fromR, _toR;\n\tuniform float customUniform;\n\n\tvec4 getFromColor(vec2 uv){\n\t\treturn texture2D(from, .5+(uv-.5)*vec2(max(ratio/_fromR,1.), max(_fromR/ratio,1.)));\n\t}\n\tvec4 getToColor(vec2 uv){\n\t\treturn texture2D(to, .5+(uv-.5)*vec2(max(ratio/_toR,1.), max(_toR/ratio,1.)));\n\t}\n\n\t// gl-transition code here\n\t${glsl}\n\t// gl-transition code end\n\n\tvoid main(){\n\t\tvec2 uv = vTextureCoord.xy;\n\t\tgl_FragColor = transition(vTextureCoord);\n\t}\n`\n", "import {autoDetectRenderer, Container, Renderer, Sprite, Text, Texture} from \"pixi.js\"\n\nimport {Id} from \"../../timeline/index.js\"\nimport {Composition, Layer} from \"../fns/schematic.js\"\nimport {Mat6, mat6ToMatrix} from \"../../timeline/utils/matrix.js\"\nimport {makeTransition} from \"../../features/transition/transition.js\"\n\nexport class Compositor {\n\n\tstatic async setup() {\n\t\tconst renderer = await autoDetectRenderer({\n\t\t\twidth: 1920,\n\t\t\theight: 1080,\n\t\t\tpreference: \"webgl\", // webgl and webgl2 causes memory leaks on chrome\n\t\t\tbackground: \"black\",\n\t\t\tpreferWebGLVersion: 2\n\t\t})\n\t\tconst stage = new Container()\n\t\tstage.interactive = true\n\t\treturn new this({renderer, stage})\n\t}\n\n\tconstructor(public pixi: {renderer: Renderer, stage: Container}) {}\n\n\t#transitions: Map<string, ReturnType<typeof makeTransition>> = new Map()\n\t// objects rendered for current Composition\n\t#activeObjects = new Map<number, Container>()\n\n\tasync composite(\n\t\tcomposition: Composition,\n\t) {\n\t\tconst {stage, renderer} = this.pixi\n\n\t\tthis.#cleanup(this.#collectIds(composition))\n\t\tconst {dispose} = await this.#renderLayer(composition, stage)\n\t\trenderer.render(stage)\n\n\t\t// make sure browser support webgl/webgpu otherwise it might take much longer to construct frame\n\t\t// if its very slow on eg edge try chrome\n\t\tconst frame = new VideoFrame(renderer.canvas, {\n\t\t\ttimestamp: 0,\n\t\t\tduration: 0,\n\t\t})\n\n\t\tdispose()\n\n\t\treturn frame\n\t}\n\n\t/**\n\t * get object for current Composition\n\t * */\n\tgetActiveObject(id: Id) {\n\t\treturn this.#activeObjects.get(id)\n\t}\n\n\tasync #renderLayer(\n\t\tlayer: Layer | Composition,\n\t\tparent: Container,\n\t) {\n\t\tif (Array.isArray(layer)) {\n\t\t\tlayer.reverse()\n\t\t\tconst disposers: (() => void)[] = []\n\t\t\tfor (const child of layer) {\n\t\t\t\tconst result = await this.#renderLayer(child, parent)\n\t\t\t\tdisposers.push(result.dispose)\n\t\t\t}\n\t\t\treturn {dispose: () => disposers.forEach(d => d())}\n\t\t}\n\n\t\tswitch (layer.kind) {\n\t\t\tcase 'text':\n\t\t\t\treturn this.#renderTextLayer(layer, parent)\n\t\t\tcase 'image':\n\t\t\t\treturn this.#renderImageLayer(layer, parent)\n\t\t\tcase 'transition':\n\t\t\t\treturn this.#renderTransitionLayer(layer, parent)\n\t\t\tcase 'gap': {\n\t\t\t\tthis.pixi?.renderer.clear()\n\t\t\t\treturn {dispose: () => {}}\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tconsole.warn('Unknown layer kind', (layer as any).kind)\n\t\t\t\treturn {dispose: () => {}}\n\t\t}\n\t}\n\n\t#renderTextLayer(\n\t\tlayer: Extract<Layer, {kind: 'text'}>,\n\t\tparent: Container,\n\t) {\n\t\tconst text = this.#findOrCreate<Text>(layer)!\n\t\tthis.#applyTransform(text, layer.matrix)\n\t\tparent.addChild(text)\n\t\treturn {\n\t\t\tdispose: () => {}\n\t\t}\n\t}\n\n\t#renderImageLayer(\n\t\tlayer: Extract<Layer, {kind: 'image'}>,\n\t\tparent: Container,\n\t) {\n\t\tconst texture = Texture.from(layer.frame)\n\t\tconst sprite = this.#findOrCreate<Sprite>(layer)!\n\t\tsprite.texture = texture\n\t\tthis.#applyTransform(sprite, layer.matrix)\n\t\tparent.addChild(sprite)\n\t\treturn {\n\t\t\tdispose: () => {\n\t\t\t\ttexture.destroy(true)\n\t\t\t\tlayer.frame.close()\n\t\t\t}\n\t\t}\n\t}\n\n\t#renderTransitionLayer(\n\t\t{from, to, progress, name}: Extract<Layer, {kind: 'transition'}>,\n\t\tparent: Container,\n\t) {\n\t\tconst transition = this.#transitions.get(name) ??\n\t\t\t(this.#transitions.set(name, makeTransition({\n\t\t\t\tname: \"circle\",\n\t\t\t\trenderer: this.pixi.renderer\n\t\t\t})),\n\t \tthis.#transitions.get(name)!\n\t\t)\n\t\tconst texture = transition.render({from, to, progress, width: from.displayWidth, height: from.displayHeight})\n\t\tconst sprite = new Sprite(texture)\n\t\tparent.addChild(sprite)\n\t\treturn {dispose: () => sprite.destroy(false)}\n\t}\n\n\t#applyTransform(target: Sprite | Text, worldMatrix?: Mat6) {\n \tif (!worldMatrix) return\n\t\tconst mx = mat6ToMatrix(worldMatrix)\n \ttarget.setFromMatrix(mx)\n\t}\n\n\t#findOrCreate<T = Container>(layer: Layer) {\n\t\tconst object = this.#activeObjects.get(layer.id)\n\t\tif(!object) {\n\t\t\tswitch (layer.kind) {\n\t\t\t\tcase 'text': {\n\t\t\t\t\tconst text = new Text({\n\t\t\t\t\t\ttext: layer.content,\n\t\t\t\t\t\tstyle: layer.style\n\t\t\t\t\t})\n\t\t\t\t\ttext.onmouseenter = () => console.log(\"enter text\")\n\t\t\t\t\treturn this.#activeObjects\n\t\t\t\t\t\t.set(layer.id, text)\n\t\t\t\t\t\t.get(layer.id) as T\n\t\t\t\t}\n\t\t\t\tcase 'image': {\n\t\t\t\t\tconst sprite = new Sprite()\n\t\t\t\t\tsprite.onmouseenter = () => console.log(\"enter\")\n\t\t\t\t\treturn this.#activeObjects\n\t\t\t\t\t\t.set(layer.id, sprite)\n\t\t\t\t\t\t.get(layer.id) as T\n\t\t\t\t}\n\t\t\t}\n\t\t} else return object as T\n\t}\n\n\t#collectIds(layers: Layer | Composition): Set<number> {\n\t\tconst result = new Set<number>()\n\t\tconst traverse = (node: Layer | Composition) => {\n\t\t\tif (Array.isArray(node)) {\n\t\t\t\tfor (const child of node) traverse(child)\n\t\t\t} else {\n\t\t\t\tresult.add(node.id)\n\t\t\t}\n\t\t}\n\t\ttraverse(layers)\n\t\treturn result\n\t}\n\n\t#cleanup(activeIds: Set<number>) {\n\t\tfor (const id of this.#activeObjects.keys()) {\n\t\t\tif (!activeIds.has(id)) {\n\t\t\t\tconst obj = this.#activeObjects.get(id)!\n\t\t\t\tobj.destroy(true)\n\t\t\t\tthis.#activeObjects.delete(id)\n\t\t\t}\n\t\t}\n\t}\n}\n", "\nimport {Comrade} from \"@e280/comrade\"\nimport {Machina} from \"../parts/machina.js\"\nimport {DriverSchematic} from \"./schematic.js\"\n\nexport const setupDriverHost = (machina: Machina) => (\n\tComrade.host<DriverSchematic>(_shell => ({\n\t\tasync world() {\n\t\t\tmachina.count++\n\t\t},\n\t}))\n)\n\n", "\nimport {is} from \"@e280/stz\"\nimport {Comrade, tune, Thread} from \"@e280/comrade\"\nimport {ALL_FORMATS, Input, type StreamTargetChunk} from \"mediabunny\"\n\nimport {Machina} from \"./parts/machina.js\"\nimport {Compositor} from \"./parts/compositor.js\"\nimport {setupDriverHost} from \"./fns/host.js\"\nimport {loadDecoderSource} from \"./utils/load-decoder-source.js\"\nimport {DecoderInput, DriverSchematic, Composition, EncoderInput, DecoderSource} from \"./fns/schematic.js\"\n\nexport type DriverOptions = {\n\tworkerUrl: URL | string\n}\n\nexport class Driver {\n\tstatic async setup(options?: DriverOptions) {\n\t\tconst machina = new Machina()\n\t\tconst thread = await Comrade.thread<DriverSchematic>({\n\t\t\tlabel: \"OmnitoolDriver\",\n\t\t\tworkerUrl: options?.workerUrl ?? \"/node_modules/@omnimedia/omnitool/x/driver/driver.worker.bundle.min.js\",\n\t\t\tsetupHost: setupDriverHost(machina),\n\t\t})\n\t\tconst compositor = await Compositor.setup()\n\t\treturn new this(machina, thread, compositor)\n\t}\n\n\tconstructor(\n\t\tpublic machina: Machina,\n\t\tpublic thread: Thread<DriverSchematic>,\n\t\tpublic compositor: Compositor\n\t) {}\n\n\tasync hello() {\n\t\treturn this.thread.work.hello()\n\t}\n\n\tasync getAudioDuration(source: DecoderSource) {\n\t\tconst input = new Input({\n\t\t\tsource: await loadDecoderSource(source),\n\t\t\tformats: ALL_FORMATS\n\t\t})\n\n\t\tconst audioTrack = await input.getPrimaryAudioTrack()\n\t\tif (!audioTrack) throw new Error(\"primary audio track not found\")\n\t\treturn await audioTrack.computeDuration()\n\t}\n\n\tasync getVideoDuration(source: DecoderSource) {\n\t\tconst input = new Input({\n\t\t\tsource: await loadDecoderSource(source),\n\t\t\tformats: ALL_FORMATS\n\t\t})\n\n\t\tconst videoTrack = await input.getPrimaryVideoTrack()\n\t\treturn await videoTrack?.computeDuration()\n\t}\n\n\tdecodeVideo(input: DecoderInput) {\n\t\tlet lastFrame: VideoFrame | null = null\n\t\tconst {port1, port2} = new MessageChannel()\n\t\tconst videoTransform = new TransformStream<VideoFrame, VideoFrame>({\n\t\t\tasync transform(chunk, controller) {\n\t\t\t\tconst frame = await input.onFrame?.(chunk) ?? chunk\n\t\t\t\tlastFrame?.close()\n\t\t\t\tcontroller.enqueue(frame)\n\t\t\t\tlastFrame = frame\n\t\t\t}\n\t\t})\n\t\tthis.thread.work.decodeVideo[tune]({transfer: [videoTransform.writable, port2]})({\n\t\t\tsource: input.source,\n\t\t\tcancel: port2,\n\t\t\tvideo: videoTransform.writable,\n\t\t\tstart: input.start,\n\t\t\tend: input.end\n\t\t})\n\t\treturn {\n\t\t\treadable: videoTransform.readable,\n\t\t\t/**\n\t\t\t * use this to stop decoding (premature interruption)\n\t\t\t * */\n\t\t\tcancel() {\n\t\t\t\tport1.postMessage(\"close\")\n\t\t\t\tport1.close()\n\t\t\t}\n\t\t}\n\t}\n\n\tdecodeAudio(input: DecoderInput) {\n\t\tconst audioTransform = new TransformStream<AudioData, AudioData>()\n\t\tconst {port1, port2} = new MessageChannel()\n\t\tthis.thread.work.decodeAudio[tune]({transfer: [audioTransform.writable, port2]})({\n\t\t\tsource: input.source,\n\t\t\tcancel: port2,\n\t\t\taudio: audioTransform.writable,\n\t\t\tstart: input.start,\n\t\t\tend: input.end\n\t\t})\n\t\treturn {\n\t\t\treadable: audioTransform.readable,\n\t\t\t/**\n\t\t\t * use this to stop decoding (premature interruption)\n\t\t\t * */\n\t\t\tcancel() {\n\t\t\t\tport1.postMessage(\"close\")\n\t\t\t\tport1.close()\n\t\t\t}\n\t\t}\n\t}\n\n\tencode({audio, video, config}: EncoderInput) {\n\t\tconst {readable, writable} = new TransformStream<StreamTargetChunk, StreamTargetChunk>()\n\t\tconst transfer = [audio, video, writable].filter(is.happy)\n\t\tconst done = this.thread.work.encode[tune]({transfer})({audio, video, config, writable})\n\t\treturn {readable, done}\n\t}\n\n\tasync composite(\n\t\tcomposition: Composition,\n\t) {\n\t\treturn await this.compositor.composite(composition)\n\t}\n\n}\n\n", "\nimport {Hex, Thumbprint} from \"@e280/stz\"\n\nimport {Hash} from \"../parts/basics.js\"\n\nexport class Checksum {\n\tconstructor(\n\t\tpublic data: Uint8Array,\n\t\tpublic bytes: Uint8Array,\n\t\tpublic hash: Hash,\n\t\tpublic nickname: string,\n\t) {}\n\n\tstatic async make(data: Uint8Array) {\n\t\tconst data2 = new Uint8Array(data)\n\t\tconst bytes = new Uint8Array(await crypto.subtle.digest(\"SHA-256\", data2))\n\t\tconst hash = Hex.fromBytes(bytes)\n\t\tconst nickname = Thumbprint.sigil.fromBytes(bytes)\n\t\treturn new this(data, bytes, hash, nickname)\n\t}\n}\n\n", "\nimport {Checksum} from \"./checksum.js\"\n\nexport class Datafile {\n\tconstructor(\n\t\tpublic url: string,\n\t\tpublic bytes: Uint8Array,\n\t\tpublic blob: Blob,\n\t\tpublic filename: string,\n\t\tpublic checksum: Checksum,\n\t) {}\n\n\tstatic async make(file: Blob, name?: string) {\n\t\tconst buffer = await file.arrayBuffer()\n\t\tconst bytes = new Uint8Array(buffer)\n\t\tconst checksum = await Checksum.make(bytes)\n\t\tconst filename = name ?? checksum.nickname\n\t\tconst url = URL.createObjectURL(file)\n\t\treturn new this(url, bytes, file, filename, checksum)\n\t}\n\n\tstatic async load(path: string) {\n\t\t// const file = await fetch(path)\n\t\t// const buffer = await file.arrayBuffer()\n\t\t// const bytes = new Uint8Array(buffer)\n\t\t// const filename = file?.headers.get('Content-Disposition')?.split('filename=')[1] ?? \"file\"\n\t\t// console.log(filename)\n\t\t// const checksum = await Checksum.make(bytes)\n\t\t// return new this(path, bytes, filename, checksum)\n\t}\n}\n\n", "\nexport async function loadVideo(url: string) {\n\treturn fetch(url)\n\t\t.then(response => response.blob())\n}\n\n", "\nimport {expect, Science, test} from \"@e280/science\"\n\nimport {O} from \"./o.js\"\nimport {Omni} from \"./omni.js\"\nimport {Item} from \"../parts/item.js\"\nimport {Driver} from \"../../driver/driver.js\"\nimport {Datafile} from \"../utils/datafile.js\"\nimport {loadVideo} from \"../../demo/routines/load-video.js\"\nimport {computeItemDuration} from \"../renderers/parts/handy.js\"\n\nconst workerUrl = new URL(\"../driver/driver.worker.bundle.min.js\", import.meta.url)\nexport async function setupTest() {\n\tconst driver = await Driver.setup({workerUrl})\n\tconst omni = new Omni(driver)\n\n\tconst testVideo = await loadVideo(\"/assets/temp/test.mp4\")\n\tconst {videoA} = await omni.load({videoA: Datafile.make(testVideo, \"test.mp4\")})\n\n\treturn {driver, omni, testVideo, videoA}\n}\n\nexport default Science.suite({\n\t\"basic demo\": test(async () => {\n\t\tconst driver = await Driver.setup({workerUrl: new URL(\"../driver/driver.worker.bundle.min.js\", import.meta.url)})\n\t\tconst omni = new Omni(driver)\n\n\t\tconst testVideo = await loadVideo(\"/assets/temp/test.mp4\")\n\t\tconst {videoA} = await omni.load({videoA: Datafile.make(testVideo, \"test.mp4\")})\n\n\t\tconst o = new O({timeline: omni.timeline(o => o.sequence())})\n\t\tconst rootItem = o.require<Item.Sequence>(o.timeline.rootId)!\n\n\t\tconst video = o.video(videoA)\n\t\to.addChildren(rootItem, video)\n\n\t\tconst videoDuration = computeItemDuration(video.id, o.timeline)\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\n\t\texpect(videoDuration).is(timelineDuration)\n\t}),\n\n\t\"sequence duration is 3x\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst o = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA),\n\t\t\to.video(videoA),\n\t\t\to.video(videoA),\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\texpect(timelineDuration).is(videoA.duration * 3)\n\t}),\n\n\t\"stack duration is 1x\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst o = new O({timeline: omni.timeline(o => o.stack(\n\t\t\to.video(videoA),\n\t\t\to.video(videoA),\n\t\t\to.video(videoA),\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\texpect(timelineDuration).is(videoA.duration)\n\t}),\n\n\t\"nested stack inside sequence\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst o = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA),\n\t\t\to.stack(\n\t\t\t\to.video(videoA),\n\t\t\t\to.video(videoA)\n\t\t\t),\n\t\t\to.video(videoA),\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\texpect(timelineDuration).is(videoA.duration * 3)\n\t}),\n\n\t\"nested sequence inside stack\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst o = new O({timeline: omni.timeline(o => o.stack(\n\t\t\to.video(videoA),\n\t\t\to.sequence(\n\t\t\t\to.video(videoA),\n\t\t\t\to.video(videoA)\n\t\t\t)\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\texpect(timelineDuration).is(videoA.duration * 2)\n\t}),\n\n\t\"empty timeline duration is 0\": test(async () => {\n\t\tconst {omni} = await setupTest()\n\t\tconst o1 = new O({timeline: omni.timeline(o => o.sequence())})\n\t\tconst o2 = new O({timeline: omni.timeline(o => o.stack())})\n\t\tconst duration1 = computeItemDuration(o1.timeline.rootId, o1.timeline)\n\t\tconst duration2 = computeItemDuration(o2.timeline.rootId, o2.timeline)\n\t\texpect(duration1).is(0)\n\t\texpect(duration2).is(0)\n\t}),\n\n\t\"transition in a sequence\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst transitionDuration = 1000\n\t\tconst o = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA),\n\t\t\to.transition.crossfade(transitionDuration),\n\t\t\to.video(videoA)\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\tconst expectedDuration = (videoA.duration * 2) - transitionDuration\n\t\texpect(timelineDuration).is(expectedDuration)\n\t}),\n\n\t\"transition in a stack\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst transitionDuration = 1000\n\t\tconst o = new O({timeline: omni.timeline(o => o.stack(\n\t\t\to.video(videoA),\n\t\t\to.transition.crossfade(transitionDuration),\n\t\t\to.video(videoA)\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\texpect(timelineDuration).is(videoA.duration)\n\t}),\n\n\t\"ignore invalid transition\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst o = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.transition.crossfade(1000),\n\t\t\to.video(videoA),\n\t\t\to.video(videoA),\n\t\t\to.transition.crossfade(1000),\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\texpect(timelineDuration).is(videoA.duration * 2)\n\t}),\n\n\t\"clamp transition duration on overflow\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst duration = 3000\n\t\tconst o = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA, {duration}),\n\t\t\to.transition.crossfade(duration * 2),\n\t\t\to.video(videoA, {duration})\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\texpect(timelineDuration).is(duration)\n\t}),\n\n\t\"multiple transitions\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst transitionDuration = 1000\n\t\tconst o = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA),\n\t\t\to.transition.crossfade(transitionDuration),\n\t\t\to.video(videoA),\n\t\t\to.transition.crossfade(transitionDuration),\n\t\t\to.video(videoA)\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\tconst expected = (videoA.duration * 3) - (transitionDuration * 2)\n\t\texpect(timelineDuration).is(expected)\n\t}),\n\n\t\"gap item in a sequence\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst gapDuration = 1000\n\t\tconst o = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA),\n\t\t\to.gap(gapDuration),\n\t\t\to.video(videoA)\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\tconst expected = videoA.duration * 2 + gapDuration\n\t\texpect(timelineDuration).is(expected)\n\t}),\n\n\t\"gap item in a stack\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst o = new O({timeline: omni.timeline(o => o.stack(\n\t\t\to.video(videoA),\n\t\t\to.gap(1000),\n\t\t\to.video(videoA)\n\t\t))})\n\t\tconst timelineDuration = computeItemDuration(o.timeline.rootId, o.timeline)\n\t\texpect(timelineDuration).is(videoA.duration)\n\t}),\n\n\t\"load media into Omni\": test(async () => {\n\t\tconst driver = await Driver.setup({workerUrl})\n\t\tconst omni = new Omni(driver)\n\t\tconst testVideo = await loadVideo(\"/assets/temp/test.mp4\")\n\t\tconst {videoA} = await omni.load({videoA: Datafile.make(testVideo, \"test.mp4\")})\n\t\texpect(omni.resources.require(videoA.datafile.checksum.hash)).happy()\n\t}),\n\n\t\"playback seeks to correct time\": test(async () => {\n\t\tconst {omni, videoA} = await setupTest()\n\t\tconst o = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA, {duration: 2000}),\n\t\t\to.gap(500),\n\t\t\to.video(videoA, {duration: 2500})\n\t\t))})\n\t\tconst playback = await omni.playback(o.timeline)\n\t\tawait playback.seek(1000)\n\t\texpect(playback.currentTime).is(1000)\n\t})\n})\n\n", "\nimport {Science, test, expect} from \"@e280/science\"\n\nimport {O} from \"../sugar/o.js\"\nimport {ms} from \"../../units/ms.js\"\nimport {Omni} from \"../sugar/omni.js\"\nimport {fps} from \"../../units/fps.js\"\nimport {Datafile} from \"../utils/datafile.js\"\nimport {Driver} from \"../../driver/driver.js\"\nimport {AudioMix} from \"./export/parts/audio-mix.js\"\nimport {produceAudio} from \"./export/parts/produce-audio.js\"\nimport {resampleToPlanar} from \"./export/parts/resamplers.js\"\nimport {loadVideo} from \"../../demo/routines/load-video.js\"\nimport {produceVideo} from \"./export/parts/produce-video.js\"\nimport {CursorVisualSampler} from \"./export/parts/cursor.js\"\nimport {applyGainToPlanar} from \"./export/parts/audio-gain.js\"\nimport {createVisualSampler} from \"./parts/samplers/visual/sampler.js\"\n\nconst workerUrl = new URL(\"../driver/driver.worker.bundle.min.js\", import.meta.url)\nexport async function setupTest() {\n\tconst driver = await Driver.setup({workerUrl})\n\tconst omni = new Omni(driver)\n\n\tconst testVideo = await loadVideo(\"/assets/temp/test.mp4\")\n\tconst {videoA} = await omni.load({videoA: Datafile.make(testVideo, \"test.mp4\")})\n\n\tconst resolveMedia = (hash: string) => omni.resources.require(hash).blob\n\n\treturn {driver, omni, testVideo, videoA, resolveMedia}\n}\n\nasync function collect<T>(iterable: AsyncIterable<T>) {\n\tconst out: T[] = []\n\tfor await (const item of iterable)\n\t\tout.push(item)\n\treturn out\n}\n\nconst near = (actual: number, expected: number, eps = 1e-6) =>\n\tMath.abs(actual - expected) < eps\n\nexport default Science.suite({\n\n\t\"cursor visual sampler cannot get previous samples\": test(async () => {\n\t\tconst {omni, videoA, resolveMedia, driver} = await setupTest()\n\t\tconst {timeline} = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA, {duration: 2000}),\n\t\t\to.gap(500),\n\t\t\to.video(videoA, {duration: 2000}),\n\t\t\to.audio(videoA, {duration: 500}),\n\t\t))})\n\t\tconst cursor = new CursorVisualSampler(driver, resolveMedia, timeline)\n\t\tawait cursor.next(ms(1000))\n\t\tawait expect(async () => await cursor.next(ms(100))).throwsAsync()\n\t}),\n\n\t\"visual sampler gives correct layer at x time\": test(async () => {\n\t\tconst {omni, videoA, resolveMedia} = await setupTest()\n\t\tconst {timeline} = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA, {duration: 2000}),\n\t\t\to.gap(500),\n\t\t\to.video(videoA, {duration: 2000}),\n\t\t\to.audio(videoA, {duration: 500}),\n\t\t\to.text(\"123\", {duration: 1000})\n\t\t))})\n\t\tconst sampler = createVisualSampler(resolveMedia)\n\t\tconst imgLayer = await sampler.sample(timeline, ms(1000))\n\t\texpect(imgLayer[0].kind).is(\"image\")\n\t\tconst gapLayer = await sampler.sample(timeline, ms(2300))\n\t\texpect(gapLayer[0].kind).is(\"gap\")\n\t\tconst imgLayer1 = await sampler.sample(timeline, ms(2700))\n\t\texpect(imgLayer1[0].kind).is(\"image\")\n\t\tconst textLayer = await sampler.sample(timeline, ms(5500))\n\t\texpect(textLayer[0].kind).is(\"text\")\n\t}),\n\n\t\"audio mix sums overlapping chunks\": test(async () => {\n\t\tconst mixer = new AudioMix({chunkFrames: 4, clamp: false})\n\t\tasync function *samples() {\n\t\t\tyield {\n\t\t\t\tplanes: [new Float32Array([0.25, 0.25, 0.25, 0.25])],\n\t\t\t\tsampleRate: 4,\n\t\t\t\ttimestamp: 0\n\t\t\t}\n\t\t\tyield {\n\t\t\t\tplanes: [new Float32Array([0.5, 0.5, 0.5, 0.5])],\n\t\t\t\tsampleRate: 4,\n\t\t\t\ttimestamp: 0.5\n\t\t\t}\n\t\t}\n\n\t\tconst mixed = await collect(mixer.mix(samples()))\n\t\texpect(mixed.length).is(2)\n\t\texpect(mixed[0].startFrame).is(0)\n\t\texpect(mixed[0].frames).is(4)\n\t\texpect(mixed[0].channels).is(1)\n\t\texpect(mixed[0].planar[0]).is(0.25)\n\t\texpect(mixed[0].planar[1]).is(0.25)\n\t\texpect(mixed[0].planar[2]).is(0.75)\n\t\texpect(mixed[0].planar[3]).is(0.75)\n\t\texpect(mixed[1].startFrame).is(4)\n\t\texpect(mixed[1].planar[0]).is(0.5)\n\t\texpect(mixed[1].planar[1]).is(0.5)\n\t\texpect(mixed[1].planar[2]).is(0)\n\t\texpect(mixed[1].planar[3]).is(0)\n\t}),\n\n\t\"audio mix clamps output to [-1, 1]\": test(async () => {\n\t\tconst mixer = new AudioMix({chunkFrames: 4, clamp: true})\n\t\tasync function *samples() {\n\t\t\tyield {\n\t\t\t\tplanes: [new Float32Array([0.9, 0.9, 0.9, 0.9])],\n\t\t\t\tsampleRate: 4,\n\t\t\t\ttimestamp: 0\n\t\t\t}\n\t\t\tyield {\n\t\t\t\tplanes: [new Float32Array([0.8, 0.8, 0.8, 0.8])],\n\t\t\t\tsampleRate: 4,\n\t\t\t\ttimestamp: 0\n\t\t\t}\n\t\t}\n\n\t\tconst mixed = await collect(mixer.mix(samples()))\n\t\texpect(mixed.length).is(1)\n\t\texpect(mixed[0].planar[0]).is(1)\n\t\texpect(mixed[0].planar[1]).is(1)\n\t\texpect(mixed[0].planar[2]).is(1)\n\t\texpect(mixed[0].planar[3]).is(1)\n\t}),\n\n\t\"audio mix fills gaps with silence\": test(async () => {\n\t\tconst mixer = new AudioMix({chunkFrames: 4, clamp: false})\n\t\tasync function *samples() {\n\t\t\tyield {\n\t\t\t\tplanes: [new Float32Array([1, 1, 1, 1])],\n\t\t\t\tsampleRate: 4,\n\t\t\t\ttimestamp: 0\n\t\t\t}\n\t\t\tyield {\n\t\t\t\tplanes: [new Float32Array([2, 2, 2, 2])],\n\t\t\t\tsampleRate: 4,\n\t\t\t\ttimestamp: 2\n\t\t\t}\n\t\t}\n\n\t\tconst mixed = await collect(mixer.mix(samples()))\n\t\texpect(mixed.length).is(3)\n\t\texpect(mixed[0].startFrame).is(0)\n\t\texpect(mixed[0].planar[0]).is(1)\n\n\t\texpect(mixed[1].startFrame).is(4)\n\t\texpect(mixed[1].planar[0]).is(0)\n\t\texpect(mixed[1].planar[3]).is(0)\n\n\t\texpect(mixed[2].startFrame).is(8)\n\t\texpect(mixed[2].planar[0]).is(2)\n\t}),\n\n\t\"audio mix truncates negative timestamps\": test(async () => {\n\t\tconst mixer = new AudioMix({chunkFrames: 4, clamp: false})\n\t\tasync function *samples() {\n\t\t\tyield {\n\t\t\t\tplanes: [new Float32Array([1, 2, 3, 4])],\n\t\t\t\tsampleRate: 4,\n\t\t\t\ttimestamp: -0.5\n\t\t\t}\n\t\t}\n\n\t\tconst mixed = await collect(mixer.mix(samples()))\n\t\texpect(mixed.length).is(1)\n\t\texpect(mixed[0].startFrame).is(0)\n\t\texpect(mixed[0].planar[0]).is(3)\n\t\texpect(mixed[0].planar[1]).is(4)\n\t\texpect(mixed[0].planar[2]).is(0)\n\t\texpect(mixed[0].planar[3]).is(0)\n\t}),\n\n\t\"audio mix handles stereo planar layout\": test(async () => {\n\t\tconst mixer = new AudioMix({chunkFrames: 4, clamp: false})\n\t\tasync function *samples() {\n\t\t\tyield {\n\t\t\t\tplanes: [\n\t\t\t\t\tnew Float32Array([1, 1, 1, 1]),\n\t\t\t\t\tnew Float32Array([2, 2, 2, 2])\n\t\t\t\t],\n\t\t\t\tsampleRate: 4,\n\t\t\t\ttimestamp: 0\n\t\t\t}\n\t\t}\n\n\t\tconst mixed = await collect(mixer.mix(samples()))\n\t\texpect(mixed.length).is(1)\n\t\texpect(mixed[0].channels).is(2)\n\t\texpect(mixed[0].planar.length).is(8)\n\t\texpect(mixed[0].planar[0]).is(1)\n\t\texpect(mixed[0].planar[4]).is(2)\n\t}),\n\n\t\"applyGainToPlanar scales values across multiple channels\": test(async () => {\n\t\tconst planes = [\n\t\t\tnew Float32Array([0.2, -0.4]),\n\t\t\tnew Float32Array([0.6, -0.8])\n\t\t]\n\n\t\tapplyGainToPlanar(planes, 0.5)\n\n\t\texpect(near(planes[0][0], 0.1)).ok()\n\t\texpect(near(planes[0][1], -0.2)).ok()\n\t\texpect(near(planes[1][0], 0.3)).ok()\n\t\texpect(near(planes[1][1], -0.4)).ok()\n\t}),\n\n\t\"applyGainToPlanar does not mutate when gain is 1\": test(async () => {\n\t\tconst planes = [new Float32Array([0.5, -0.5])]\n\n\t\tapplyGainToPlanar(planes, 1)\n\n\t\texpect(near(planes[0][0], 0.5)).ok()\n\t\texpect(near(planes[0][1], -0.5)).ok()\n\t}),\n\n\t\"applyGainToPlanar mutes entirely when gain is 0\": test(async () => {\n\t\tconst planes = [new Float32Array([0.9, -0.9])]\n\n\t\tapplyGainToPlanar(planes, 0)\n\n\t\texpect(planes[0][0]).is(0)\n\t\texpect(planes[0][1]).is(0)\n\t}),\n\n\t\"resampleToPlanar returns original data when sample rates match\": test(async () => {\n\t\tconst sample = {\n\t\t\tnumberOfFrames: 3,\n\t\t\tnumberOfChannels: 1,\n\t\t\tsampleRate: 48000,\n\t\t\tcopyTo: (dest: Float32Array) => dest.set([0.1, 0.2, 0.3])\n\t\t}\n\n\t\tconst result = resampleToPlanar(sample, 48000)\n\n\t\texpect(result.frames).is(3)\n\t\texpect(result.data.length).is(1)\n\t\texpect(near(result.data[0][0], 0.1)).ok()\n\t\texpect(near(result.data[0][1], 0.2)).ok()\n\t\texpect(near(result.data[0][2], 0.3)).ok()\n\t}),\n\n\t\"resampleToPlanar upsamples using linear interpolation\": test(async () => {\n\t\tconst sample = {\n\t\t\tnumberOfFrames: 2,\n\t\t\tnumberOfChannels: 1,\n\t\t\tsampleRate: 1,\n\t\t\tcopyTo: (dest: Float32Array) => dest.set([10, 20])\n\t\t}\n\n\t\tconst result = resampleToPlanar(sample as any, 2)\n\n\t\texpect(result.frames).is(4)\n\t\texpect(near(result.data[0][0], 10)).ok()\n\t\texpect(near(result.data[0][1], 15)).ok()\n\t\texpect(near(result.data[0][2], 20)).ok()\n\t\texpect(near(result.data[0][3], 20)).ok()\n\t}),\n\n\t\"resampleToPlanar downsamples correctly\": test(async () => {\n\t\tconst sample = {\n\t\t\tnumberOfFrames: 4,\n\t\t\tnumberOfChannels: 1,\n\t\t\tsampleRate: 4,\n\t\t\tcopyTo: (dest: Float32Array) => dest.set([1, 2, 3, 4])\n\t\t}\n\n\t\tconst result = resampleToPlanar(sample, 2)\n\n\t\texpect(result.frames).is(2)\n\t\texpect(near(result.data[0][0], 1)).ok()\n\t\texpect(near(result.data[0][1], 3)).ok()\n\t}),\n\n\t\"resampleToPlanar processes multi-channel planar data\": test(async () => {\n\t\tconst planes = [\n\t\t\tnew Float32Array([1, 2]),\n\t\t\tnew Float32Array([3, 4])\n\t\t]\n\n\t\tconst sample = {\n\t\t\tnumberOfFrames: 2,\n\t\t\tnumberOfChannels: 2,\n\t\t\tsampleRate: 1,\n\t\t\tcopyTo: (dest: Float32Array, options: { planeIndex: number }) => {\n\t\t\t\tdest.set(planes[options.planeIndex])\n\t\t\t}\n\t\t}\n\n\t\tconst result = resampleToPlanar(sample, 2)\n\n\t\texpect(result.data.length).is(2)\n\t\texpect(near(result.data[0][1], 1.5)).ok()\n\t\texpect(near(result.data[1][1], 3.5)).ok()\n\t}),\n\n\t\"resampleToPlanar handles zero channels gracefully\": test(async () => {\n\t\tconst sample = {\n\t\t\tnumberOfFrames: 10,\n\t\t\tnumberOfChannels: 0,\n\t\t\tsampleRate: 48000,\n\t\t\tcopyTo: () => { throw new Error(\"Should not be called\") }\n\t\t}\n\n\t\tconst result = resampleToPlanar(sample, 44100)\n\n\t\texpect(result.data.length).is(0)\n\t\texpect(result.frames).is(0)\n\t}),\n\n\t\"resampleToPlanar enforces minimum of 1 frame on aggressive downsample\": test(async () => {\n\t\tconst sample = {\n\t\t\tnumberOfFrames: 1,\n\t\t\tnumberOfChannels: 1,\n\t\t\tsampleRate: 48000,\n\t\t\tcopyTo: (dest: Float32Array) => dest.set([0.8])\n\t\t}\n\n\t\tconst result = resampleToPlanar(sample, 8000)\n\n\t\texpect(result.frames).is(1)\n\t\texpect(result.data[0].length).is(1)\n\t\texpect(near(result.data[0][0], 0.8)).ok()\n\t}),\n\n\t\"resampleToPlanar calls copyTo with strict contract shape\": test(async () => {\n\t\tlet passedOptions: any = null\n\t\tconst sample = {\n\t\t\tnumberOfFrames: 2,\n\t\t\tnumberOfChannels: 1,\n\t\t\tsampleRate: 48000,\n\t\t\tcopyTo: (dest: Float32Array, options: any) => {\n\t\t\t\tpassedOptions = options\n\t\t\t}\n\t\t}\n\n\t\tresampleToPlanar(sample, 44100)\n\n\t\texpect(passedOptions).not.is(null)\n\t\texpect(passedOptions.planeIndex).is(0)\n\t\texpect(passedOptions.format).is(\"f32-planar\")\n\t}),\n\n\t\"5s long export at 30fps renders exacly 150 frames\": test(async () => {\n\t\tconst {omni, videoA, driver, resolveMedia} = await setupTest()\n\t\tconst {timeline} = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA, {duration: 2000}),\n\t\t\to.gap(500),\n\t\t\to.video(videoA, {duration: 2000}),\n\t\t\to.audio(videoA, {duration: 500})\n\t\t))})\n\t\tconst readable = produceVideo({timeline, fps: fps(30), driver, resolveMedia})\n\t\tlet frames = 0\n\t\tfor await (const frame of readable) {\n\t\t\tframe.close()\n\t\t\tframes++\n\t\t}\n\t\texpect(frames).is(150)\n\t}),\n\n\t\"5s long audio export at 48000Hz renders exactly 240000 frames\": test(async () => {\n\t\tconst {omni, videoA, resolveMedia} = await setupTest()\n\t\tconst {timeline} = new O({timeline: omni.timeline(o => o.sequence(\n\t\t\to.video(videoA, {duration: 2000}),\n\t\t\to.gap(500),\n\t\t\to.video(videoA, {duration: 2000}),\n\t\t\to.audio(videoA, {duration: 500})\n\t\t))})\n\n\t\tconst readable = produceAudio({timeline, resolveMedia})\n\t\tlet totalFrames = 0\n\n\t\tfor await (const chunk of readable) {\n\t\t\ttotalFrames += chunk.numberOfFrames\n\t\t\tchunk.close()\n\t\t}\n\n\t\texpect(totalFrames).is(240000)\n\t})\n})\n", "\nimport {Science} from \"@e280/science\"\nimport omniTest from \"./timeline/sugar/omni.test.js\"\nimport renderersTest from \"./timeline/renderers/renderers.test.js\"\n\nawait Science.run\n({\n\tomniTest,\n\trenderersTest\n})\n\n"],
5
+ "mappings": "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,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,OChBpF,IAAMC,GAAW,CACvB,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAC1F,MAAM,MAAM,MAAM,MAAM,MAAM,M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",
6
+ "names": ["require_gl_transitions", "__commonJSMin", "exports", "module", "parts_exports", "__export", "Experiment", "Fail", "Stderr", "Stdout", "Tube", "asTheme", "color", "colorBgRgb", "colorHex", "colorRgb", "deliver", "execute", "exit", "expect", "getArg", "getEnv", "hasArg", "hasEnv", "isColorSupported", "isDeno", "isNode", "meta", "options", "run", "setExitCode", "spy", "suite", "summarize", "test", "themes", "uncolor", "writeStderr", "writeStdout", "plural", "x", "one", "many", "ms", "chunkify", "array", "size", "chunks", "currentChunk", "commit", "item", "Fail", "makeExpectations", "a", "b", "ErrorClass", "Fail", "error", "promise", "expectancy", "not", "a", "expectations", "message", "key", "fn", "fn1", "b", "result", "r", "Fail", "expectmessage", "inverseExpectations", "originals", "makeExpectations", "p", "trunc", "s", "max", "display", "x", "displays", "meta", "options", "o", "Experiment", "time", "fail", "Tube", "label", "fn", "path", "flattenTests", "tree", "tubes", "recurse", "s", "path", "label", "value", "fn", "meta", "Tube", "childSuite", "execute", "tree", "tubes", "flattenTests", "nonSkipped", "tube", "only", "selectedTubes", "executeTube", "start", "result", "time", "reason", "Fail", "display", "totalStart", "experiments", "workload", "chunkify", "group", "experiment", "expect", "a", "note", "expectancy", "makeExpectations", "inverseExpectations", "note2", "codes", "colorHex", "hex", "bigint", "g", "b", "c", "colorRgb", "r", "code", "s", "colorBgRgb", "color", "key", "uncolor", "Stdout", "line", "Stderr", "isDeno", "isNode", "isColorSupported", "exit", "code", "setExitCode", "hasEnv", "name", "hasArg", "arg", "findArgValue", "args", "first", "rest", "getArg", "getEnv", "writeStdout", "line", "writeStderr", "deliver", "summary", "output", "Stderr", "writeStderr", "writeStdout", "setExitCode", "summarize", "ex", "options", "verbose", "icons", "colors", "failures", "r", "successes", "allCount", "happyCount", "angryCount", "skipCount", "t", "onlyCount", "outputs", "log", "line", "Stdout", "err", "Stderr", "loggedCaseCount", "pickIntro", "tube", "experiment", "suffix", "errFailedTest", "path", "label", "breadcrumb", "message", "timely", "ms", "intro", "logHappyTest", "logLameTest", "ignored", "plural", "x", "happy", "time", "didnt", "asTheme", "theme", "themes", "color", "s", "spy", "fn", "calls", "spyFn", "args", "ret", "r", "c", "getArgs", "options", "hasArg", "getArg", "getEnv", "themeName", "theme", "themes", "considerColorSupport", "theme", "isColorSupported", "themes", "run", "tests", "options", "verbose", "theme", "getArgs", "theme2", "considerColorSupport", "report", "execute", "summary", "summarize", "deliver", "test", "fn", "meta", "suite", "meta", "bytes", "a", "b", "i", "count", "BaseX", "lexicon", "char", "i", "s", "bitsPerChar", "bitBuffer", "bitCount", "output", "val", "num", "base", "negative", "out", "bytes", "byte", "index", "n", "value", "count", "hex", "BaseX", "base2", "base36", "base58", "base62", "base64", "base64url", "prefixes", "suffixes", "bytename", "byteCount", "options", "b", "bytes", "groupSize", "wordSeparator", "groupSeparator", "words", "currentWord", "byte", "index", "source", "prefixes", "suffixes", "grouped", "i", "bname", "letters", "triplets", "triplet", "number", "t", "hex", "h", "thumbprint", "tstring", "beans", "s", "bytename", "bulk", "preview", "base58", "options", "bytes", "raw", "delimiter", "previewBytes", "sigilBytes", "yoink", "len", "sigil", "full", "hstring", "hex", "b", "h", "Thumbprint", "Hex", "bytes", "byte", "string", "i", "byteCount", "defer", "resolve", "reject", "promise", "res", "rej", "entangle", "outside", "is", "x", "GMap", "_GMap", "map", "key", "make", "value", "DeadlineError", "milliseconds", "deadline", "fn", "resolve", "reject", "id", "disposer", "fns", "d", "fn", "newFns", "drill", "object", "path", "current", "key", "is", "xub", "set", "publish", "a", "fn", "subscribe", "pub", "sub", "next", "promise", "resolve", "defer", "unsubscribe", "clear", "x", "pub", "listener", "x", "xub", "Kind", "Effect", "O", "state", "id", "item", "hex", "#mutate", "fn", "style", "Kind", "transform", "items", "media", "options", "content", "duration", "Effect", "position", "scale", "rotation", "parent", "partial", "project", "fps", "value", "assert", "x", "normalizeRotation", "rotation", "mappedRotation", "last", "arr", "Bitstream", "_Bitstream", "bytes", "byteOffset", "byteIndex", "byte", "bitIndex", "bit", "n", "result", "i", "value", "end", "clone", "readExpGolomb", "bitstream", "leadingZeroBits", "readSignedExpGolomb", "codeNum", "toUint8Array", "source", "toDataView", "textDecoder", "invertObject", "object", "key", "value", "COLOR_PRIMARIES_MAP", "COLOR_PRIMARIES_MAP_INVERSE", "TRANSFER_CHARACTERISTICS_MAP", "TRANSFER_CHARACTERISTICS_MAP_INVERSE", "MATRIX_COEFFICIENTS_MAP", "MATRIX_COEFFICIENTS_MAP_INVERSE", "isAllowSharedBufferSource", "x", "AsyncMutex", "resolver", "nextPromise", "resolve", "currentPromiseAlias", "bytesToHexString", "bytes", "reverseBitsU32", "binarySearchExact", "arr", "key", "valueGetter", "low", "high", "ans", "mid", "midVal", "binarySearchLessOrEqual", "insertSorted", "item", "insertionIndex", "promiseWithResolvers", "reject", "res", "rej", "findLast", "arr", "predicate", "i", "findLastIndex", "toAsyncIterator", "source", "validateAnyIterable", "iterable", "assertNever", "x", "getUint24", "view", "byteOffset", "littleEndian", "byte1", "byte2", "byte3", "getInt24", "setUint24", "value", "clamp", "value", "min", "max", "UNDETERMINED_LANGUAGE", "roundIfAlmostInteger", "rounded", "roundToMultiple", "multiple", "ilog", "x", "ret", "ISO_639_2_REGEX", "isIso639Dash2LanguageCode", "SECOND_TO_MICROSECOND_FACTOR", "mergeRequestInit", "init1", "init2", "merged", "headers1", "normalizeHeaders", "headers2", "mergedHeaders", "key2", "value2", "existingKey", "key1", "headers", "result", "key", "retriedFetch", "fetchFn", "url", "requestInit", "getRetryDelay", "shouldStop", "attempts", "error", "retryDelayInSeconds", "resolve", "CallSerializer", "fn", "isWebKitCache", "isWebKit", "isFirefoxCache", "isFirefox", "isChromiumCache", "isChromium", "chromiumVersionCache", "getChromiumVersion", "match", "coalesceIndex", "a", "b", "closedIntervalsOverlap", "startA", "endA", "startB", "endB", "base64ToBytes", "base64", "decoded", "bytes", "i", "polyfillSymbolDispose", "isNumber", "x", "RichImageData", "data", "mimeType", "AttachedFile", "name", "description", "DEFAULT_TRACK_DISPOSITION", "PCM_AUDIO_CODECS", "NON_PCM_AUDIO_CODECS", "AUDIO_CODECS", "VP9_LEVEL_TABLE", "VP9_DEFAULT_SUFFIX", "AV1_DEFAULT_SUFFIX", "extractVideoCodecString", "trackInfo", "codec", "codecDescription", "colorSpace", "avcCodecInfo", "hevcCodecInfo", "vp9CodecInfo", "av1CodecInfo", "assert", "bytes", "bytesToHexString", "generalProfileSpace", "generalProfileIdc", "compatibilityFlags", "generalTierFlag", "generalLevelIdc", "constraintFlags", "reverseBitsU32", "view", "toDataView", "profileByte", "i", "codecString", "x", "pictureSize", "level", "last", "VP9_LEVEL_TABLE", "entry", "profile", "bitDepth", "chromaSubsampling", "colourPrimaries", "transferCharacteristics", "matrixCoefficients", "videoFullRangeFlag", "string", "VP9_DEFAULT_SUFFIX", "tier", "monochrome", "colorPrimaries", "COLOR_PRIMARIES_MAP", "TRANSFER_CHARACTERISTICS_MAP", "MATRIX_COEFFICIENTS_MAP", "AV1_DEFAULT_SUFFIX", "extractAudioCodecString", "trackInfo", "codec", "codecDescription", "aacCodecInfo", "parseAacAudioSpecificConfig", "PCM_AUDIO_CODECS", "aacFrequencyTable", "aacChannelMap", "bytes", "bitstream", "Bitstream", "objectType", "frequencyIndex", "sampleRate", "channelConfiguration", "numberOfChannels", "OPUS_SAMPLE_RATE", "PCM_CODEC_REGEX", "parsePcmCodec", "codec", "assert", "PCM_AUDIO_CODECS", "match", "dataType", "sampleSize", "littleEndian", "silentValue", "AvcNalUnitType", "HevcNalUnitType", "findNalUnitsInAnnexB", "packetData", "nalUnits", "i", "startCodePos", "startCodeLength", "j", "nalData", "findNalUnitsInLengthPrefixed", "lengthSize", "offset", "dataView", "nalUnitLength", "getUint24", "assertNever", "assert", "nalUnit", "removeEmulationPreventionBytes", "data", "result", "len", "ANNEX_B_START_CODE", "concatNalUnitsInAnnexB", "totalLength", "a", "b", "concatNalUnitsInLengthPrefixed", "setUint24", "extractAvcNalUnits", "decoderConfig", "toUint8Array", "concatAvcNalUnits", "extractNalUnitTypeForAvc", "extractAvcDecoderConfigurationRecord", "spsUnits", "unit", "ppsUnits", "spsExtUnits", "spsData", "spsInfo", "parseAvcSps", "hasExtendedData", "error", "deserializeAvcDecoderConfigurationRecord", "data", "view", "toDataView", "offset", "configurationVersion", "avcProfileIndication", "profileCompatibility", "avcLevelIndication", "lengthSizeMinusOne", "numOfSequenceParameterSets", "sequenceParameterSets", "i", "length", "numOfPictureParameterSets", "pictureParameterSets", "record", "chromaFormat", "bitDepthLumaMinus8", "bitDepthChromaMinus8", "numOfSequenceParameterSetExt", "sequenceParameterSetExt", "error", "parseAvcSps", "sps", "bitstream", "Bitstream", "removeEmulationPreventionBytes", "profileIdc", "constraintFlags", "levelIdc", "readExpGolomb", "chromaFormatIdc", "sizeOfScalingList", "lastScale", "nextScale", "j", "deltaScale", "readSignedExpGolomb", "picOrderCntType", "numRefFramesInPicOrderCntCycle", "frameMbsOnlyFlag", "extractHevcNalUnits", "packetData", "decoderConfig", "lengthSize", "toUint8Array", "findNalUnitsInLengthPrefixed", "findNalUnitsInAnnexB", "extractNalUnitTypeForHevc", "extractHevcDecoderConfigurationRecord", "nalUnits", "vpsUnits", "unit", "HevcNalUnitType", "spsUnits", "ppsUnits", "seiUnits", "sps_max_sub_layers_minus1", "sps_temporal_id_nesting_flag", "general_profile_space", "general_tier_flag", "general_profile_idc", "general_profile_compatibility_flags", "general_constraint_indicator_flags", "general_level_idc", "parseProfileTierLevel", "chroma_format_idc", "bit_depth_luma_minus8", "bit_depth_chroma_minus8", "maxNum", "skipScalingListData", "num_short_term_ref_pic_sets", "skipAllStRefPicSets", "num_long_term_ref_pics_sps", "min_spatial_segmentation_idc", "parseVuiForMinSpatialSegmentationIdc", "parallelismType", "pps", "ppsBitstream", "tiles_enabled_flag", "entropy_coding_sync_enabled_flag", "arrays", "maxNumSubLayersMinus1", "sub_layer_profile_present_flag", "sub_layer_level_present_flag", "sizeId", "matrixId", "coefNum", "NumDeltaPocs", "stRpsIdx", "skipStRefPicSet", "NumDeltaPocsThis", "inter_ref_pic_set_prediction_flag", "RefRpsIdx", "delta_idx_minus1", "numDelta", "num_negative_pics", "num_positive_pics", "skipHrdParameters", "commonInfPresentFlag", "nal_hrd_parameters_present_flag", "vcl_hrd_parameters_present_flag", "sub_pic_hrd_params_present_flag", "fixed_pic_rate_general_flag", "fixed_pic_rate_within_cvs_flag", "low_delay_hrd_flag", "CpbCnt", "skipSubLayerHrdParameters", "extractVp9CodecInfoFromPacket", "packet", "bitstream", "Bitstream", "profileLowBit", "profile", "bitDepth", "colorSpace", "chromaSubsampling", "videoFullRangeFlag", "subsamplingX", "subsamplingY", "widthMinusOne", "heightMinusOne", "width", "height", "pictureSize", "level", "last", "VP9_LEVEL_TABLE", "entry", "iterateAv1PacketObus", "readLeb128", "value", "i", "byte", "obuType", "obuExtension", "obuHasSizeField", "obuSize", "obuSizeValue", "assert", "extractAv1CodecInfoFromPacket", "type", "data", "seqProfile", "stillPicture", "reducedStillPictureHeader", "seqLevel", "seqTier", "bufferDelayLengthMinus1", "decoderModelInfoPresentFlag", "operatingPointsCntMinus1", "seqLevelIdx", "seqTierTemp", "n", "frameWidthBitsMinus1", "frameHeightBitsMinus1", "n1", "n2", "frameIdNumbersPresentFlag", "enableOrderHint", "seqChooseScreenContentTools", "seqForceScreenContentTools", "highBitdepth", "monochrome", "chromaSubsamplingX", "chromaSubsamplingY", "chromaSamplePosition", "parseOpusIdentificationHeader", "bytes", "view", "toDataView", "outputChannelCount", "preSkip", "inputSampleRate", "outputGain", "channelMappingFamily", "channelMappingTable", "OPUS_FRAME_DURATION_TABLE", "parseOpusTocByte", "config", "parseModesFromVorbisSetupPacket", "setupHeader", "bufSize", "revBuffer", "gotFramingBit", "modeCount", "gotModeHeader", "lastModeCount", "tempPos", "a", "b", "c", "finalModeCount", "modeBlockflags", "determineVideoPacketType", "codec", "decoderConfig", "packetData", "nalUnits", "extractAvcNalUnits", "isKeyframe", "x", "extractNalUnitTypeForAvc", "AvcNalUnitType", "isChromium", "getChromiumVersion", "nalUnit", "removeEmulationPreventionBytes", "pos", "payloadType", "nextByte", "payloadSize", "recoveryFrameCount", "readExpGolomb", "exactMatchFlag", "extractHevcNalUnits", "extractNalUnitTypeForHevc", "HevcNalUnitType", "assertNever", "FlacBlockType", "readVorbisComments", "metadataTags", "commentView", "commentPos", "vendorStringLength", "vendorString", "textDecoder", "listLength", "stringLength", "string", "separatorIndex", "key", "parts", "trackNum", "tracksTotal", "discNum", "discsTotal", "date", "decoded", "base64ToBytes", "pictureType", "mediaTypeLength", "mediaType", "descriptionLength", "description", "dataLength", "Demuxer", "input", "customVideoDecoders", "customAudioDecoders", "PLACEHOLDER_DATA", "EncodedPacket", "_EncodedPacket", "data", "type", "timestamp", "duration", "sequenceNumber", "byteLength", "sideData", "SECOND_TO_MICROSECOND_FACTOR", "chunk", "options", "fromUlaw", "u8", "sign", "position", "number", "decoded", "fromAlaw", "u8", "sign", "position", "number", "decoded", "polyfillSymbolDispose", "lastVideoGcErrorLog", "lastAudioGcErrorLog", "finalizationRegistry", "value", "now", "VIDEO_SAMPLE_PIXEL_FORMATS", "VIDEO_SAMPLE_PIXEL_FORMATS_SET", "VideoSample", "_VideoSample", "SECOND_TO_MICROSECOND_FACTOR", "data", "init", "toUint8Array", "createDefaultPlaneLayout", "VideoSampleColorSpace", "width", "height", "canvas", "context", "isFirefox", "assert", "isVideoFrame", "options", "validateVideoFrameCopyToOptions", "videoFrame", "size", "destination", "isAllowSharedBufferSource", "layout", "imageData", "arg1", "arg2", "arg3", "arg4", "arg5", "arg6", "arg7", "arg8", "sx", "sy", "sWidth", "sHeight", "dx", "dy", "dWidth", "dHeight", "source", "centerX", "centerY", "aspectRatioChange", "validateCropRectangle", "canvasWidth", "canvasHeight", "rotation", "rotatedWidth", "rotatedHeight", "clampCropRectangle", "newWidth", "newHeight", "sampleWidth", "sampleHeight", "scale", "newRotation", "newTimestamp", "newDuration", "x", "crop", "outerWidth", "outerHeight", "prefix", "plane", "format", "codedWidth", "codedHeight", "planes", "getPlaneConfigs", "layouts", "currentOffset", "planeWidth", "planeHeight", "stride", "planeSize", "yuv", "yBytes", "uvBytes", "subX", "subY", "hasAlpha", "configs", "assertNever", "AUDIO_SAMPLE_FORMATS", "AudioSample", "_AudioSample", "isAudioData", "numberOfFrames", "getBytesPerSample", "dataBuffer", "expectedSize", "destFormat", "frameOffset", "copyFrameCount", "bytesPerSample", "isPlanar", "formatIsPlanar", "planeIndex", "optFrameCount", "optFrameOffset", "srcFormat", "numFrames", "numChannels", "destBytesPerSample", "destIsPlanar", "requiredSize", "destView", "toDataView", "writeFn", "getWriteFunction", "isWebKit", "doAudioDataCopyToWebKitWorkaround", "uint8Data", "srcView", "readFn", "getReadFunction", "srcBytesPerSample", "srcIsPlanar", "i", "destOffset", "srcOffset", "normalized", "ch", "sample", "audioBuffer", "dataBytes", "timestamp", "MAX_FLOAT_COUNT", "numberOfChannels", "sampleRate", "totalFrames", "maxFramesPerChunk", "currentRelativeFrame", "remainingFrames", "framesToCopy", "chunkData", "channel", "result", "audioSample", "view", "offset", "clamp", "audioData", "dataView", "idx", "validatePacketRetrievalOptions", "options", "validateTimestamp", "timestamp", "isNumber", "maybeFixPacketType", "track", "promise", "packet", "determinedType", "EncodedPacketSink", "InputTrack", "InputDisposedError", "EncodedPacket", "assert", "nextPacket", "startPacket", "endPacket", "packetQueue", "queueNotEmpty", "onQueueNotEmpty", "promiseWithResolvers", "queueDequeue", "onQueueDequeue", "ended", "terminated", "outOfBandError", "timestamps", "maxQueueSize", "error", "value", "now", "DecoderWrapper", "onSample", "onError", "BaseMediaSampleSink", "startTimestamp", "endTimestamp", "sampleQueue", "firstSampleQueued", "lastSample", "decoderIsFlushed", "decoder", "sample", "packetSink", "keyPacket", "currentPacket", "packets", "computeMaxQueueSize", "packetResult", "closeSamples", "validateAnyIterable", "timestampIterator", "toAsyncIterator", "timestampsOfInterest", "pushToQueue", "sampleUses", "i", "lastPacket", "lastKeyPacket", "maxSequenceNumber", "decodePackets", "flushDecoder", "targetPacket", "decodedSampleQueueSize", "VideoDecoderWrapper", "codec", "decoderConfig", "rotation", "timeResolution", "CallSerializer", "MatchingCustomDecoder", "customVideoDecoders", "x", "VideoSample", "colorHandler", "frame", "alphaFrame", "isChromium", "record", "deserializeAvcDecoderConfigurationRecord", "toUint8Array", "sps", "parseAvcSps", "stack", "isWebKit", "insertSorted", "filteredNalUnits", "extractAvcNalUnits", "type", "extractNalUnitTypeForAvc", "newData", "concatAvcNalUnits", "ColorAlphaMerger", "alphaHandler", "colorFrame", "determineVideoPacketType", "packetData", "extractHevcNalUnits", "extractNalUnitTypeForHevc", "HevcNalUnitType", "last", "color", "alpha", "finalSample", "finalFrame", "gl", "vertexShader", "fragmentShader", "program", "source", "shader", "vao", "vertices", "buffer", "positionLocation", "texCoordLocation", "texture", "VideoSampleSink", "videoTrack", "InputVideoTrack", "AudioDecoderWrapper", "DecoderWrapper", "onSample", "onError", "codec", "decoderConfig", "CallSerializer", "sampleHandler", "sample", "preciseTimestamp", "sampleRate", "MatchingCustomDecoder", "customAudioDecoders", "x", "AudioSample", "stack", "data", "error", "assert", "packet", "PcmAudioDecoderWrapper", "PCM_AUDIO_CODECS", "dataType", "sampleSize", "littleEndian", "parsePcmCodec", "view", "byteOffset", "fromUlaw", "fromAlaw", "getUint24", "getInt24", "assertNever", "value", "inputView", "toDataView", "numberOfFrames", "outputBufferSize", "outputBuffer", "outputView", "i", "inputIndex", "outputIndex", "preciseDuration", "audioSample", "AudioSampleSink", "BaseMediaSampleSink", "audioTrack", "InputAudioTrack", "EncodedPacketSink", "timestamp", "validateTimestamp", "startTimestamp", "endTimestamp", "timestamps", "InputTrack", "input", "backing", "InputVideoTrack", "InputAudioTrack", "targetPacketCount", "sink", "EncodedPacketSink", "startTimestamp", "endTimestamp", "packetCount", "totalPacketBytes", "packet", "colorSpace", "decoderConfig", "codec", "assert", "customVideoDecoders", "x", "error", "EncodedPacket", "determineVideoPacketType", "customAudioDecoders", "buildIsobmffMimeType", "info", "string", "uniqueCodecMimeTypes", "MIN_BOX_HEADER_SIZE", "MAX_BOX_HEADER_SIZE", "readBoxHeader", "slice", "totalSize", "readU32Be", "name", "readAscii", "headerSize", "readU64Be", "contentSize", "readFixed_16_16", "readI32Be", "readFixed_2_30", "readIsomVariableInteger", "result", "i", "nextByte", "readU8", "readMetadataStringShort", "stringLength", "readU16Be", "textDecoder", "readBytes", "readDataBox", "header", "typeIndicator", "data", "RichImageData", "IsobmffDemuxer", "Demuxer", "input", "tracks", "trackDurations", "x", "track", "codecStrings", "buildIsobmffMimeType", "currentPos", "slice", "MIN_BOX_HEADER_SIZE", "MAX_BOX_HEADER_SIZE", "startPos", "boxInfo", "readBoxHeader", "majorBrand", "readAscii", "moovSlice", "a", "b", "previousSegmentDurationsInSeconds", "lastWordSlice", "assert", "lastWord", "readU32Be", "potentialMfraPos", "mfraHeaderSlice", "mfraSlice", "internalTrack", "sampleTable", "stblContainerSlice", "PCM_AUDIO_CODECS", "pcmInfo", "parsePcmCodec", "newSampleTimingEntries", "newSampleSizes", "i", "chunkEntry", "nextEntry", "chunkCount", "j", "startSampleIndex", "endSampleIndex", "startTimingEntryIndex", "binarySearchLessOrEqual", "startTimingEntry", "endTimingEntryIndex", "endTimingEntry", "firstSampleTimestamp", "delta", "lastSampleTimingEntry", "last", "chunkSize", "entry", "sampleIndex", "sample", "headerSlice", "moofBoxInfo", "entireSlice", "fragment", "trackData", "fragmentPositionCache", "lookupEntry", "offsetFragmentTrackDataByTimestamp", "lastCacheIndex", "lastCache", "insertionIndex", "startIndex", "contentStartPos", "boxEndPos", "version", "readU8", "readU64Be", "DEFAULT_TRACK_DISPOSITION", "UNDETERMINED_LANGUAGE", "videoTrack", "InputVideoTrack", "IsobmffVideoTrackBacking", "audioTrack", "InputAudioTrack", "IsobmffAudioTrackBacking", "trackEnabled", "readU24Be", "matrix", "readFixed_16_16", "readFixed_2_30", "rotation", "normalizeRotation", "roundToMultiple", "extractRotationFromMatrix", "relevantEntryFound", "previousSegmentDurations", "entryCount", "segmentDuration", "mediaTime", "readI64Be", "readI32Be", "mediaRate", "language", "readU16Be", "isIso639Dash2LanguageCode", "handlerType", "stsdVersion", "entries", "sampleBoxStartPos", "sampleBoxInfo", "lowercaseBoxName", "channelCount", "sampleSize", "sampleRate", "readF64Be", "flags", "bytesPerSample", "isFloat", "isBigEndian", "sFlags", "OPUS_SAMPLE_RATE", "readBytes", "profile", "level", "thirdByte", "bitDepth", "chromaSubsampling", "videoFullRangeFlag", "colourPrimaries", "transferCharacteristics", "matrixCoefficients", "secondByte", "tier", "highBitDepth", "twelveBit", "monochrome", "chromaSubsamplingX", "chromaSubsamplingY", "chromaSamplePosition", "fullRangeFlag", "COLOR_PRIMARIES_MAP_INVERSE", "TRANSFER_CHARACTERISTICS_MAP_INVERSE", "MATRIX_COEFFICIENTS_MAP_INVERSE", "tag", "readIsomVariableInteger", "mixed", "streamDependenceFlag", "urlFlag", "ocrStreamFlag", "urlLength", "decoderConfigTag", "decoderConfigDescriptorLength", "payloadStart", "objectTypeIndication", "decoderSpecificInfoTag", "decoderSpecificInfoLength", "audioSpecificConfig", "parseAacAudioSpecificConfig", "isLittleEndian", "pcmSampleSize", "outputChannelCount", "preSkip", "inputSampleRate", "outputGain", "readI16Be", "channelMappingFamily", "channelMappingTable", "description", "view", "BLOCK_TYPE_MASK", "LAST_METADATA_BLOCK_FLAG_MASK", "flagAndType", "metadataBlockLength", "FlacBlockType", "word", "numberOfChannels", "endPos", "bytes", "currentIndex", "currentTimestamp", "sampleCount", "sampleDelta", "sampleOffset", "fieldSize", "bitstream", "Bitstream", "startChunkIndex", "samplesPerChunk", "sampleDescriptionIndex", "chunkOffset", "fragmentDuration", "trackId", "defaultSampleDescriptionIndex", "defaultSampleDuration", "defaultSampleSize", "defaultSampleFlags", "lengthSizeOfTrafNum", "lengthSizeOfTrunNum", "lengthSizeOfSampleNum", "functions", "readTrafNum", "readTrunNum", "readSampleNum", "numberOfEntries", "time", "moofOffset", "entry1", "entry2", "currentFragmentState", "baseDataOffsetPresent", "sampleDescriptionIndexPresent", "defaultSampleDurationPresent", "defaultSampleSizePresent", "defaultSampleFlagsPresent", "durationIsEmpty", "defaultBaseIsMoof", "defaults", "baseMediaDecodeTime", "dataOffsetPresent", "firstSampleFlagsPresent", "sampleDurationPresent", "sampleSizePresent", "sampleFlagsPresent", "sampleCompositionTimeOffsetsPresent", "dataOffset", "firstSampleFlags", "currentOffset", "sampleDuration", "sampleFlags", "sampleCompositionTimeOffset", "isKeyFrame", "currentEntry", "currentSample", "firstSample", "lastSample", "iterator", "readMetadataStringShort", "textDecoder", "date", "isQuickTime", "keySize", "keyName", "metadataKey", "nameAsNumber", "data", "readDataBox", "RichImageData", "parts", "trackNum", "tracksTotal", "toDataView", "trackNumber", "discNumber", "discNumberMax", "IsobmffTrackBacking", "lastPacket", "options", "regularPacket", "timestamp", "roundIfAlmostInteger", "timestampInTimescale", "getSampleIndexForTimestamp", "sampleTableIsEmpty", "index", "correctSampleFound", "packet", "regularSampleIndex", "locationInFragment", "getKeyframeSampleIndexForTimestamp", "findLastIndex", "nextKeyFrameSampleIndex", "getNextKeyframeIndexForSample", "nextKeyFrameIndex", "keyFrameIndex", "sampleInfo", "getSampleInfo", "PLACEHOLDER_DATA", "duration", "EncodedPacket", "fragmentSample", "startFragment", "getMatchInFragment", "searchTimestamp", "latestTimestamp", "demuxer", "currentFragment", "bestFragment", "bestSampleIndex", "lookupEntryIndex", "positionCacheIndex", "positionCacheEntry", "lookupEntryPosition", "boxStartPos", "previousLookupEntry", "newSearchTimestamp", "firstPacket", "extractVp9CodecInfoFromPacket", "extractAv1CodecInfoFromPacket", "extractVideoCodecString", "extractAudioCodecString", "timescaleUnits", "binarySearchExact", "timingEntryIndex", "timingEntry", "presentationTimestamp", "offsetEntryIndex", "offsetEntry", "chunkEntryIndex", "chunkIndex", "startSampleIndexOfChunk", "presentationIndex", "m11", "m21", "scaleX", "cosTheta", "sinTheta", "result", "EBMLId", "LEVEL_0_EBML_IDS", "LEVEL_1_EBML_IDS", "LEVEL_0_AND_1_EBML_IDS", "MAX_VAR_INT_SIZE", "MIN_HEADER_SIZE", "MAX_HEADER_SIZE", "readVarIntSize", "slice", "firstByte", "readU8", "width", "mask", "readVarInt", "value", "i", "readUnsignedInt", "readUnsignedBigInt", "readElementId", "slice", "size", "readVarIntSize", "readUnsignedInt", "readElementSize", "readU8", "readVarInt", "readElementHeader", "id", "readAsciiString", "length", "bytes", "readBytes", "strLength", "readUnicodeString", "textDecoder", "readFloat", "width", "readF32Be", "readF64Be", "searchForNextElementId", "reader", "startPos", "ids", "until", "idsSet", "currentPos", "MIN_HEADER_SIZE", "MAX_HEADER_SIZE", "elementHeader", "assertDefinedSize", "resync", "MAX_VAR_INT_SIZE", "i", "elementId", "CODEC_STRING_MAP", "buildMatroskaMimeType", "info", "string", "uniqueCodecMimeTypes", "BlockLacing", "ContentEncodingScope", "ContentCompAlgo", "METADATA_ELEMENTS", "EBMLId", "MAX_RESYNC_LENGTH", "MatroskaDemuxer", "Demuxer", "input", "tracks", "trackDurations", "x", "segment", "track", "codecStrings", "buildMatroskaMimeType", "metadataTags", "currentPos", "slice", "MIN_HEADER_SIZE", "MAX_HEADER_SIZE", "header", "readElementHeader", "id", "size", "dataStartPos", "assertDefinedSize", "searchForNextElementId", "LEVEL_0_AND_1_EBML_IDS", "lastSegment", "last", "segmentDataStart", "dataSize", "elementStartPos", "LEVEL_1_EBML_IDS", "nextPos", "resync", "metadataElementIndex", "field", "b", "seekEntry", "target", "dataSlice", "idToTrack", "cuePoint", "a", "i", "cuePoint1", "cuePoint2", "trackWithMostCuePoints", "maxCuePointCount", "startPos", "headerSlice", "assert", "elementHeader", "cluster", "endPos", "trackData", "hasLacedBlocks", "block", "currentEntry", "currentBlock", "nextEntry", "firstBlock", "lastBlock", "insertionIndex", "binarySearchLessOrEqual", "trackNumber", "blocks", "blockIndex", "originalBlock", "FileSlice", "frameSizes", "frameCount", "readU8", "totalUsedSize", "frameSize", "value", "totalDataSize", "firstResult", "readVarInt", "currentSize", "diffResult", "unsignedDiff", "bias", "diff", "blockDuration", "frameData", "readBytes", "frameTimestamp", "frameDuration", "stopIds", "startIndex", "readAsciiString", "lastSeekEntry", "readUnsignedInt", "readFloat", "DEFAULT_TRACK_DISPOSITION", "UNDETERMINED_LANGUAGE", "instruction", "slashIndex", "codecIdWithoutSuffix", "CODEC_STRING_MAP", "videoTrack", "inputTrack", "InputVideoTrack", "MatroskaVideoTrackBacking", "OPUS_SAMPLE_RATE", "audioTrack", "InputAudioTrack", "MatroskaAudioTrackBacking", "type", "readUnicodeString", "isIso639Dash2LanguageCode", "languageSubtag", "matrixCoefficients", "mapped", "MATRIX_COEFFICIENTS_MAP_INVERSE", "transferCharacteristics", "TRANSFER_CHARACTERISTICS_MAP_INVERSE", "primaries", "COLOR_PRIMARIES_MAP_INVERSE", "flippedRotation", "normalizeRotation", "lastCuePoint", "relativeTimestamp", "readI16Be", "flags", "lacing", "isKeyFrame", "blockData", "hasDecodingInstructions", "tags", "AttachedFile", "fileName", "kind", "lowerName", "readUnsignedBigInt", "rawData", "currentData", "prefix", "newData", "name", "date", "parts", "trackNum", "tracksTotal", "discParts", "discNum", "discsTotal", "MatroskaTrackBacking", "internalTrack", "lastPacket", "options", "timestamp", "roundIfAlmostInteger", "timestampInTimescale", "index", "correctBlockFound", "packet", "locationInCluster", "findLastIndex", "nextKeyFrameIndex", "keyFrameIndex", "data", "PLACEHOLDER_DATA", "duration", "sideData", "EncodedPacket", "startCluster", "getMatchInCluster", "searchTimestamp", "latestTimestamp", "demuxer", "currentCluster", "bestCluster", "bestBlockIndex", "cuePointIndex", "positionCacheIndex", "positionCacheEntry", "lookupEntryPosition", "readElementId", "previousCuePoint", "newSearchTimestamp", "firstPacket", "extractVideoCodecString", "extractAvcDecoderConfigurationRecord", "extractHevcDecoderConfigurationRecord", "extractVp9CodecInfoFromPacket", "extractAv1CodecInfoFromPacket", "extractAudioCodecString", "SAMPLING_RATES", "KILOBIT_RATES", "XING", "INFO", "computeMp3FrameSize", "lowSamplingFrequency", "layer", "bitrate", "sampleRate", "padding", "getXingOffset", "mpegVersionId", "channel", "readFrameHeader", "word", "remainingBytes", "firstByte", "secondByte", "thirdByte", "fourthByte", "mpeg25", "bitrateIndex", "frequencyIndex", "modeExtension", "copyright", "original", "emphasis", "kilobitRate", "frameLength", "audioSamplesInFrame", "decodeSynchsafe", "synchsafed", "mask", "unsynchsafed", "Id3V2HeaderFlags", "Id3V2TextEncoding", "ID3_V1_TAG_SIZE", "ID3_V2_HEADER_SIZE", "ID3_V1_GENRES", "parseId3V1Tag", "slice", "tags", "startPos", "readBytes", "title", "readId3V1String", "artist", "album", "yearText", "year", "commentBytes", "comment", "trackNum", "genreIndex", "readU8", "length", "bytes", "endIndex", "coalesceIndex", "relevantBytes", "str", "readId3V2Header", "tag", "readAscii", "majorVersion", "revision", "flags", "sizeRaw", "readU32Be", "size", "decodeSynchsafe", "parseId3V2Tag", "header", "reader", "Id3V2Reader", "extendedHeaderSize", "frame", "frameStartPos", "frameEndPos", "frameEncrypted", "frameCompressed", "frameUnsynchronized", "parts", "tracksTotal", "discNum", "discsTotal", "genreText", "match", "genreNumber", "dateText", "date", "encoding", "mimeType", "imageFormat", "pictureType", "description", "imageDataSize", "imageData", "newBytes", "i", "value1", "start", "end", "before", "after", "value", "high", "low", "id", "headerEndPos", "isSizeValid", "nextPos", "nextId", "otherSize", "number", "until", "data", "decoder", "x", "textDecoder", "readNextFrameHeader", "reader", "startPos", "until", "currentPos", "slice", "word", "readU32Be", "result", "readFrameHeader", "Mp3Demuxer", "Demuxer", "input", "AsyncMutex", "InputAudioTrack", "Mp3AudioTrackBacking", "slice", "ID3_V2_HEADER_SIZE", "id3V2Header", "readId3V2Header", "result", "readNextFrameHeader", "header", "xingOffset", "getXingOffset", "word", "readU32Be", "XING", "INFO", "sampleDuration", "sample", "track", "assert", "release", "currentPos", "id3V2HeaderFound", "headerSlice", "contentSlice", "parseId3V2Tag", "ID3_V1_TAG_SIZE", "readAscii", "parseId3V1Tag", "demuxer", "lastPacket", "UNDETERMINED_LANGUAGE", "DEFAULT_TRACK_DISPOSITION", "sampleIndex", "options", "rawSample", "data", "PLACEHOLDER_DATA", "readBytes", "EncodedPacket", "packet", "binarySearchExact", "x", "nextIndex", "timestamp", "index", "binarySearchLessOrEqual", "OGGS", "OGG_CRC_POLYNOMIAL", "OGG_CRC_TABLE", "n", "crc", "k", "computeOggPageCrc", "bytes", "view", "toDataView", "originalChecksum", "i", "byte", "extractSampleMetadata", "data", "codecInfo", "vorbisLastBlocksize", "durationInSamples", "currentBlocksize", "assert", "vorbisModeCount", "modeMask", "ilog", "modeNumber", "prevBlocksize", "blockflag", "prevMask", "flag", "parseOpusTocByte", "buildOggMimeType", "info", "string", "uniqueCodecMimeTypes", "MIN_PAGE_HEADER_SIZE", "MAX_PAGE_HEADER_SIZE", "MAX_PAGE_SIZE", "readPageHeader", "slice", "startPos", "readU32Le", "OGGS", "headerType", "readU8", "granulePosition", "readI64Le", "serialNumber", "sequenceNumber", "checksum", "numberPageSegments", "lacingValues", "i", "headerSize", "dataSize", "a", "b", "totalSize", "findNextPageHeader", "until", "word", "firstByte", "secondByte", "thirdByte", "fourthByte", "O", "OggDemuxer", "Demuxer", "input", "currentPos", "slice", "MIN_PAGE_HEADER_SIZE", "MAX_PAGE_HEADER_SIZE", "page", "readPageHeader", "bitstream", "firstPacket", "InputAudioTrack", "OggAudioTrackBacking", "nextPacketPosition", "secondPacket", "thirdPacket", "lacingValues", "addBytesToSegmentTable", "bytes", "description", "view", "toDataView", "blockSizeByte", "parseModesFromVorbisSetupPacket", "readVorbisComments", "header", "parseOpusIdentificationHeader", "OPUS_SAMPLE_RATE", "startPage", "startSegmentIndex", "assert", "startDataOffset", "i", "currentPage", "currentDataOffset", "currentSegmentIndex", "chunks", "outer", "pageSlice", "pageData", "readBytes", "lacingValue", "headerSlice", "nextPage", "totalPacketSize", "sum", "chunk", "packetData", "offset", "lastPacket", "codecStrings", "x", "buildOggMimeType", "tracks", "trackDurations", "demuxer", "AsyncMutex", "UNDETERMINED_LANGUAGE", "DEFAULT_TRACK_DISPOSITION", "granulePosition", "packet", "additional", "options", "durationInSamples", "vorbisBlockSize", "extractSampleMetadata", "encodedPacket", "EncodedPacket", "PLACEHOLDER_DATA", "packetPosition", "timestampInSamples", "prevPacket", "prevMetadata", "timestamp", "roundIfAlmostInteger", "startPosition", "lowPage", "high", "lowPages", "low", "mid", "searchStartPos", "until", "MAX_PAGE_SIZE", "searchSlice", "findNextPageHeader", "pageValid", "computeOggPageCrc", "lowerPage", "otherLowPage", "previousPages", "nextPos", "currentTimestampInSamples", "currentTimestampIsCorrect", "endPage", "endSegmentIndex", "pseudopacket", "endPosition", "findPreviousPacketEndPosition", "findPacketStartPosition", "lastEncodedPacket", "lastEncodedPacketMetadata", "encodedPacketMetadata", "nextPosition", "release", "index", "binarySearchLessOrEqual", "currentPacket", "cacheEntry", "nextPacket", "metadata", "last", "pageList", "segmentIndex", "previousPage", "findLast", "WaveFormat", "WaveDemuxer", "Demuxer", "input", "slice", "assert", "riffType", "readAscii", "littleEndian", "isRf64", "outerChunkSize", "readU32", "totalFileSize", "chunksRead", "dataChunkSize", "currentPos", "chunkId", "chunkSize", "startPos", "ds64Slice", "riffChunkSize", "readU64", "blockSize", "InputAudioTrack", "WaveAudioTrackBacking", "size", "formatTag", "readU16", "numChannels", "sampleRate", "blockAlign", "bitsPerSample", "cbSize", "remainingSize", "subFormat", "readBytes", "infoType", "chunkName", "bytes", "stringLength", "i", "value", "parts", "trackNum", "tracksTotal", "date", "year", "id3V2Header", "readId3V2Header", "contentSlice", "parseId3V2Tag", "track", "PACKET_SIZE_IN_FRAMES", "demuxer", "codec", "lastPacket", "UNDETERMINED_LANGUAGE", "DEFAULT_TRACK_DISPOSITION", "packetIndex", "options", "startOffset", "sizeInBytes", "data", "PLACEHOLDER_DATA", "timestamp", "duration", "EncodedPacket", "packet", "currentPacket", "nextPacket", "MIN_FRAME_HEADER_SIZE", "MAX_FRAME_HEADER_SIZE", "readFrameHeader", "slice", "startPos", "bytes", "readBytes", "bitstream", "Bitstream", "protectionAbsence", "objectType", "samplingFrequencyIndex", "channelConfiguration", "frameLength", "numberOfAacFrames", "crcCheck", "SAMPLES_PER_AAC_FRAME", "AdtsDemuxer", "Demuxer", "input", "AsyncMutex", "assert", "InputAudioTrack", "AdtsAudioTrackBacking", "slice", "MIN_FRAME_HEADER_SIZE", "MAX_FRAME_HEADER_SIZE", "header", "readFrameHeader", "sampleRate", "aacFrequencyTable", "sampleDuration", "headerSize", "sample", "track", "demuxer", "lastPacket", "UNDETERMINED_LANGUAGE", "numberOfChannels", "aacChannelMap", "DEFAULT_TRACK_DISPOSITION", "bytes", "bitstream", "Bitstream", "objectType", "samplingFrequencyIndex", "channelConfiguration", "sampleIndex", "options", "rawSample", "data", "PLACEHOLDER_DATA", "readBytes", "EncodedPacket", "packet", "release", "binarySearchExact", "x", "nextIndex", "timestamp", "index", "binarySearchLessOrEqual", "getBlockSizeOrUncommon", "bits", "getSampleRateOrUncommon", "sampleRateBits", "streamInfoSampleRate", "readCodedNumber", "fileSlice", "ones", "bitstream1", "Bitstream", "readBytes", "bitArray", "extraBytes", "bitstream2", "firstByteBits", "i", "j", "val", "acc", "bit", "index", "readBlockSize", "slice", "blockSizeBits", "readU16Be", "readU8", "assertNever", "assert", "readSampleRate", "sampleRateOrUncommon", "calculateCrc8", "data", "crc", "byte", "FlacDemuxer", "Demuxer", "input", "AsyncMutex", "assert", "currentPos", "sizeSlice", "byte", "readU8", "size", "readU24Be", "isLastMetadata", "FlacBlockType", "streamInfoBlock", "streamInfoBytes", "readBytes", "bitstream", "Bitstream", "minimumBlockSize", "maximumBlockSize", "minimumFrameSize", "maximumFrameSize", "sampleRate", "numberOfChannels", "totalSamples", "description", "InputAudioTrack", "FlacAudioTrackBacking", "vorbisCommentBlock", "readVorbisComments", "pictureBlock", "pictureType", "readU32Be", "mediaTypeLength", "mediaType", "textDecoder", "descriptionLength", "dataLength", "data", "startPos", "isFirstPacket", "minimumHeaderLength", "maximumSliceLength", "slice", "frameHeader", "positionBeforeReading", "byteAfterNextByte", "expected", "lengthIfNextFlacFrameHeaderIsLegit", "nextFrameHeader", "startOffset", "bytes", "newBlockingBit", "blockSizeOrUncommon", "getBlockSizeOrUncommon", "sampleRateOrUncommon", "getSampleRateOrUncommon", "num", "readCodedNumber", "blockSize", "readBlockSize", "readSampleRate", "crc", "crcCalculated", "calculateCrc8", "frame", "lastSample", "sample", "demuxer", "lastPacket", "UNDETERMINED_LANGUAGE", "DEFAULT_TRACK_DISPOSITION", "timestamp", "options", "release", "packetIndex", "binarySearchLessOrEqual", "x", "packet", "sampleTimestamp", "sampleDuration", "nextIndex", "sampleIndex", "rawSample", "PLACEHOLDER_DATA", "duration", "EncodedPacket", "InputFormat", "IsobmffInputFormat", "input", "slice", "readAscii", "IsobmffDemuxer", "Mp4InputFormat", "majorBrand", "QuickTimeInputFormat", "MatroskaInputFormat", "desiredDocType", "headerSlice", "MAX_HEADER_SIZE", "varIntSize", "readVarIntSize", "readUnsignedInt", "EBMLId", "dataSize", "readElementSize", "dataSlice", "startPos", "MIN_HEADER_SIZE", "header", "readElementHeader", "id", "size", "dataStartPos", "readAsciiString", "MatroskaDemuxer", "WebMInputFormat", "Mp3InputFormat", "currentPos", "id3V2HeaderFound", "ID3_V2_HEADER_SIZE", "id3V2Header", "readId3V2Header", "firstResult", "readNextFrameHeader", "secondResult", "firstHeader", "secondHeader", "Mp3Demuxer", "WaveInputFormat", "riffType", "WaveDemuxer", "OggInputFormat", "OggDemuxer", "FlacInputFormat", "FlacDemuxer", "AdtsInputFormat", "MIN_FRAME_HEADER_SIZE", "MAX_FRAME_HEADER_SIZE", "readFrameHeader", "AdtsDemuxer", "MP4", "QTFF", "MATROSKA", "WEBM", "MP3", "WAVE", "OGG", "ADTS", "FLAC", "ALL_FORMATS", "Source", "InputDisposedError", "result", "BlobSource", "Source", "blob", "options", "isNumber", "ReadOrchestrator", "PREFETCH_PROFILES", "size", "start", "end", "worker", "reader", "isWebKit", "done", "value", "data", "URL_SOURCE_MIN_LOAD_AMOUNT", "DEFAULT_RETRY_DELAY", "previousAttempts", "error", "src", "originOfSrc", "UrlSource", "url", "abortController", "response", "retriedFetch", "mergeRequestInit", "fileSize", "contentLength", "existing", "assert", "readResult", "retryDelayInSeconds", "resolve", "contentRange", "match", "PREFETCH_PROFILES", "start", "end", "workers", "worker", "thresholdPoint", "closedIntervalsOverlap", "size", "a", "b", "extent", "URL_SOURCE_MIN_LOAD_AMOUNT", "ReadOrchestrator", "options", "innerStart", "innerEnd", "assert", "prefetchRange", "outerStart", "outerEnd", "result", "innerCacheStartIndex", "binarySearchLessOrEqual", "x", "innerStartEntry", "outerCacheStartIndex", "bytes", "contiguousBytesWriteEnd", "lastEnd", "outerHoles", "i", "entry", "cappedOuterStart", "cappedOuterEnd", "cappedInnerStart", "cappedInnerEnd", "relativeOffset", "toDataView", "promise", "resolve", "reject", "promiseWithResolvers", "innerHoles", "outerHole", "cappedStart", "cappedEnd", "pendingSlice", "workerFound", "newWorker", "startPos", "targetPos", "oldestIndex", "oldestWorker", "error", "clampedStart", "clampedEnd", "j", "hole", "otherWorker", "index", "insertionIndex", "previous", "joined", "next", "oldestEntry", "polyfillSymbolDispose", "Input", "options", "x", "InputFormat", "Source", "Reader", "format", "assert", "InputDisposedError", "message", "Reader", "source", "start", "length", "InputDisposedError", "end", "result", "x", "FileSlice", "minLength", "maxLength", "clamp", "promisedAttempt", "handleAttempt", "attempt", "handleFileSize", "fileSize", "assert", "promisedFileSize", "_FileSlice", "bytes", "view", "offset", "toDataView", "value", "byteCount", "filePos", "checkIsInRange", "slice", "bytesToRead", "readBytes", "readU8", "readU16", "littleEndian", "readU16Be", "readU24Be", "getUint24", "readI16Be", "readU32", "readU32Be", "readU32Le", "readI32Be", "readI32Le", "readU64", "low", "high", "readU64Be", "readI64Be", "readI64Le", "readF32Be", "readF64Be", "readAscii", "str", "i", "loadDecoderSource", "source", "BlobSource", "UrlSource", "Media", "datafile", "media", "duration", "video", "audio", "#has", "source", "Input", "ALL_FORMATS", "loadDecoderSource", "input", "ResourcePool", "#map", "GMap", "datafile", "media", "Media", "hash", "filename", "bytes", "url", "blob", "alreadyExists", "ms", "value", "realtime", "playing", "frameRate", "fps", "frameDuration", "lastNow", "lastComposite", "onTick", "pub", "resolveTick", "loop", "now", "ticks", "r", "v", "fixedStep", "opts", "onFrame", "dt", "ms", "durationInSeconds", "total", "i", "t", "browserExt", "ExtensionType", "webworkerExt", "ExtensionType", "_isWebGLSupported", "isWebGLSupported", "failIfMajorPerformanceCaveat", "contextOptions", "AbstractRenderer", "DOMAdapter", "gl", "success", "loseContext", "_isWebGPUSupported", "isWebGPUSupported", "options", "gpu", "DOMAdapter", "renderPriority", "autoDetectRenderer", "options", "preferredOrder", "item", "RendererClass", "finalOptions", "i", "rendererType", "isWebGPUSupported", "WebGPURenderer", "isWebGLSupported", "AbstractRenderer", "WebGLRenderer", "renderer", "AbstractText", "ViewContainer", "options", "styleClass", "text", "resolution", "style", "anchor", "width", "height", "roundPixels", "rest", "ObservablePoint", "value", "out", "point", "x1", "y1", "ensureTextOptions", "args", "name", "deprecation", "v8_0_0", "Text", "AbstractText", "args", "options", "ensureTextOptions", "TextStyle", "TextureStyle", "bounds", "anchor", "width", "height", "frame", "canvasAndContext", "CanvasTextGenerator", "canvasMeasurement", "CanvasTextMetrics", "extensions", "browserExt", "webworkerExt", "transformToMat6", "pos", "scl", "rotDeg", "x", "y", "sx", "sy", "r", "cos", "sin", "mat6ToMatrix", "a", "b", "c", "d", "tx", "ty", "Matrix", "mul6", "local", "parent", "a1", "b1", "c1", "d1", "tx1", "ty1", "a2", "b2", "c2", "d2", "tx2", "ty2", "I6", "isPlayableItem", "item", "itemsFrom", "p", "results", "itemMap", "item", "walkFrom", "localTime", "ancestors", "computeWorldMatrix", "items", "world", "I6", "ancestor", "applySpatialIfAny", "parentMatrix", "spatial", "local", "transformToMat6", "mul6", "walkFrom", "id", "items", "from", "callbacks", "ancestors", "item", "Kind", "childId", "offset", "ms", "child", "isPlayableItem", "end", "localTime", "computeItemDuration", "timeline", "children", "x", "total", "i", "prev", "next", "prevDur", "nextDur", "overlap", "longest", "duration", "seconds", "value", "VideoSink", "#sinks", "resolveMedia", "hash", "existing", "input", "Input", "ALL_FORMATS", "loadDecoderSource", "videoTrack", "sink", "VideoSampleSink", "sampleTransition", "item", "progress", "p1", "p2", "l1", "l2", "f1", "f2", "rest", "sampleSequence", "ctx", "seq", "time", "ancestors", "state", "sampleSequenceAt", "nextAnc", "sampleTransition", "sampleVisual", "children", "id", "i", "cursor", "ms", "currentItem", "Kind", "currentItemStart", "currentItemDuration", "computeItemDuration", "currentItemEnd", "next", "transition", "incoming", "incomingItemDuration", "overlap", "currentItemSoloEnd", "inLocal", "outLocal", "sampleVisual", "ctx", "item", "time", "ancestors", "matrix", "computeWorldMatrix", "Kind", "nextAnc", "id", "child", "sampleSequence", "frame", "style", "createDefaultVideoSampler", "sink", "item", "time", "sample", "frame", "createVisualSampler", "resolveMedia", "sampleVideo", "sink", "VideoSink", "videoSampler", "createDefaultVideoSampler", "timeline", "timecode", "items", "item", "root", "sampleVisual", "CursorVisualSampler", "#lastTimecode", "#videoCursors", "#sampler", "driver", "resolveMedia", "timeline", "createVisualSampler", "item", "time", "targetUs", "toUs", "cursor", "source", "endUs", "ms", "#createVideoCursor", "timecode", "c", "startUs", "video", "reader", "current", "nextPromise", "ended", "readNext", "done", "value", "frame", "nextFrame", "currentUs", "nextUs", "pending", "initStreams", "pool", "items", "from", "item", "localTime", "Kind", "sink", "mediaTime", "offset", "seconds", "iter", "first", "currentSample", "nextPromise", "result", "stream", "AudioSinkPool", "#sinks", "resolveMedia", "hash", "existing", "input", "Input", "ALL_FORMATS", "loadDecoderSource", "audioTrack", "sink", "AudioSampleSink", "findEarliestStream", "streams", "earliest", "index", "stream", "time", "createAudioSampler", "resolveMedia", "sinkPool", "AudioSinkPool", "timeline", "from", "items", "itemsFrom", "streams", "initStreams", "stream", "index", "findEarliestStream", "Playback", "#playbackStart", "ms", "#audioStartSec", "#controller", "realtime", "#audioAbort", "driver", "timeline", "resolveMedia", "createVisualSampler", "createAudioSampler", "#samples", "_", "layers", "time", "node", "CursorVisualSampler", "#startAudio", "seconds", "computeItemDuration", "elapsedMs", "fps", "signal", "from", "ctx", "sample", "timestamp", "r", "startAt", "VideoPlayer", "#pendingSeek", "#flushTask", "driver", "resolveMedia", "timeline", "Playback", "timeMs", "#flushSeeks", "value", "fps", "next", "layers", "ms", "AudioMix", "#chunkFrames", "#clamp", "options", "samples", "chunkFrames", "sampleRate", "channels", "active", "nextFrame", "maxEnd", "input", "inputStart", "frames", "#processChunk", "currentStartFrame", "outputBuffer", "chunkEnd", "ch", "channelOffset", "outChannelView", "sample", "data", "start", "end", "dstIdx", "srcIdx", "len", "i", "v", "resampleLinear", "src", "fromRate", "targetRate", "ratio", "outFrames", "out", "t", "i0", "i1", "frac", "resampleToPlanar", "sample", "channels", "data", "frames", "ch", "plane", "resampled", "applyGainToPlanar", "planes", "gain", "plane", "i", "produceAudio", "timeline", "resolveMedia", "mixer", "AudioMix", "audio", "streamAudio", "stream", "writer", "produce", "chunk", "data", "audioSampler", "createAudioSampler", "sample", "timestamp", "gain", "ms", "resampleToPlanar", "applyGainToPlanar", "produceVideo", "timeline", "fps", "driver", "resolveMedia", "stream", "writer", "sampler", "CursorVisualSampler", "dt", "duration", "computeItemDuration", "produce", "fixedStep", "timecode", "i", "layers", "composed", "frame", "produce", "opts", "audio", "produceAudio", "video", "produceVideo", "Omni", "ResourcePool", "driver", "spec", "key", "value", "fn", "o", "O", "root", "timeline", "VideoPlayer", "hash", "framerate", "produce", "fps", "bindTap", "tap", "ctx", "o", "basicTheme", "colors", "autoTheme", "basicTheme", "codes", "colorFns", "s", "uncolor", "mix", "hex", "rgb", "bgRgb", "fn", "bigint", "g", "b", "c", "r", "code", "codes", "colorless", "codes", "key", "s", "colorFns", "colorful", "codes", "key", "code", "s", "colorFns", "isDeno", "isNode", "isColorSupported", "autoColors", "isColorSupported", "colorful", "colorless", "errorsShaper", "colors", "theme", "palette", "errstring", "error", "stack", "processErrors", "item", "processAll", "items", "combineShapers", "shapers", "context", "items", "shaper", "defaultTimestampOptions", "timestampShaper", "options", "colors", "theme", "opts", "palette", "date", "year", "month", "day", "calendar", "hour", "minute", "second", "milliseconds", "clock", "stamp", "items", "autoShaper", "combineShapers", "errorsShaper", "timestampShaper", "denoWriter", "line", "nodeWriter", "line", "consoleWriter", "line", "autoWriter", "isDeno", "denoWriter", "isNode", "nodeWriter", "consoleWriter", "voidWriter", "noneShaper", "items", "Logger", "_Logger", "autoWriter", "voidWriter", "denoWriter", "nodeWriter", "consoleWriter", "autoColors", "colorful", "colorless", "autoTheme", "basicTheme", "autoShaper", "noneShaper", "errorsShaper", "timestampShaper", "items", "writer", "colors", "theme", "shapers", "combineShapers", "LoggerTap", "Logger", "request", "context", "g", "#context", "error", "meta", "label", "remote", "cRemote", "cLocal", "#meta", "headers", "ErrorTap", "LoggerTap", "JsonRpc", "getId", "request", "ExposedError", "RemoteError", "execute", "tap", "request", "action", "id", "JsonRpc", "result", "error", "ExposedError", "makeEndpoint", "options", "tap", "ErrorTap", "request", "path", "fn", "drill", "action", "execute", "tune", "query", "notify", "settings", "remoteProxy", "executor", "recurse", "path", "currentSettings", "_", "_this", "args", "target", "key", "value", "makeRemote", "options", "endpoint", "tap", "ErrorTap", "id", "remoteProxy", "path", "params", "settings", "notify", "transfer", "base", "request", "response", "RemoteError", "makeMock", "options", "makeRemote", "makeEndpoint", "Conduit", "pub", "origin", "a", "b", "disposers", "data", "fn", "onMessage", "channel", "fn", "makeRemoteEndpoint", "waiter", "sendRequest", "request", "transfer", "done", "defer", "response", "interpretIncoming", "json", "requests", "responses", "item", "handleIncomingRequests", "localEndpoint", "r", "PostableConduit", "Conduit", "disposer", "channel", "m", "transfer", "onMessage", "e", "MessengerMeta", "remote", "defaults", "ResponseWaiter", "timeout", "id", "method", "deferred", "defer", "deadline", "error", "DeadlineError", "response", "pend", "RemoteError", "Messenger", "disposer", "#waiter", "options", "conduit", "tap", "ResponseWaiter", "defaults", "makeRemoteEndpoint", "makeRemote", "bindTap", "m", "incoming", "meta", "MessengerMeta", "rpc", "requests", "responses", "interpretIncoming", "response", "fns", "endpoint", "makeEndpoint", "outgoing", "handleIncomingRequests", "shells", "meta", "t", "defaultTap", "ErrorTap", "worker", "compat", "setupWork", "options", "tap", "defaultTap", "messenger", "Messenger", "PostableConduit", "m", "shells", "Thread", "worker", "messenger", "compat", "options", "tap", "defaultTap", "label", "readyprom", "defer", "infra", "Messenger", "PostableConduit", "m", "shells", "Cluster", "compat", "options", "workerCount", "threads", "_", "index", "Thread", "#available", "#tasks", "tap", "defaultTap", "remoteEndpoint", "request", "special", "#scheduleTask", "defer", "makeRemote", "t", "thread", "task", "#distributeTasks", "callprom", "setupComrade", "compat", "options", "Thread", "Cluster", "setupWork", "worker", "fn", "setupHost", "tap", "defaultTap", "hostShell", "shells", "workShell", "makeMock", "setupBrowserCompat", "count", "url", "name", "compat", "setupBrowserCompat", "Comrade", "setupComrade", "Machina", "import_gl_transitions", "vertex", "uniforms", "transition", "name", "value", "getUniformType", "type", "fragment", "glsl", "makeTransition", "name", "renderer", "transition", "transitions", "t", "transitionSprite", "Sprite", "transitionTexture", "Texture", "sourceFrom", "ImageSource", "sourceTo", "filter", "Filter", "GlProgram", "vertex", "fragment", "uniforms", "width", "height", "from", "to", "progress", "Compositor", "renderer", "autoDetectRenderer", "stage", "Container", "pixi", "#transitions", "#activeObjects", "composition", "#cleanup", "#collectIds", "dispose", "#renderLayer", "frame", "id", "layer", "parent", "disposers", "child", "result", "d", "#renderTextLayer", "#renderImageLayer", "#renderTransitionLayer", "text", "#findOrCreate", "#applyTransform", "texture", "Texture", "sprite", "from", "to", "progress", "name", "makeTransition", "Sprite", "target", "worldMatrix", "mx", "mat6ToMatrix", "object", "Text", "layers", "traverse", "node", "activeIds", "setupDriverHost", "machina", "Comrade", "_shell", "Driver", "options", "machina", "Machina", "thread", "Comrade", "setupDriverHost", "compositor", "Compositor", "source", "audioTrack", "Input", "loadDecoderSource", "ALL_FORMATS", "input", "lastFrame", "port1", "port2", "videoTransform", "chunk", "controller", "frame", "tune", "audioTransform", "audio", "video", "config", "readable", "writable", "transfer", "is", "done", "composition", "Checksum", "data", "bytes", "hash", "nickname", "data2", "Hex", "Thumbprint", "Datafile", "url", "bytes", "blob", "filename", "checksum", "file", "name", "buffer", "Checksum", "path", "loadVideo", "url", "response", "workerUrl", "setupTest", "driver", "Driver", "omni", "Omni", "testVideo", "loadVideo", "videoA", "Datafile", "omni_test_default", "parts_exports", "O", "o", "rootItem", "video", "videoDuration", "computeItemDuration", "timelineDuration", "expect", "o1", "o2", "duration1", "duration2", "transitionDuration", "expectedDuration", "duration", "expected", "gapDuration", "playback", "workerUrl", "setupTest", "driver", "Driver", "omni", "Omni", "testVideo", "loadVideo", "videoA", "Datafile", "hash", "collect", "iterable", "out", "item", "near", "actual", "expected", "eps", "renderers_test_default", "parts_exports", "resolveMedia", "timeline", "O", "o", "cursor", "CursorVisualSampler", "ms", "expect", "sampler", "createVisualSampler", "imgLayer", "gapLayer", "imgLayer1", "textLayer", "mixer", "AudioMix", "samples", "mixed", "planes", "applyGainToPlanar", "result", "resampleToPlanar", "dest", "options", "passedOptions", "readable", "produceVideo", "fps", "frames", "frame", "produceAudio", "totalFrames", "chunk", "parts_exports", "omni_test_default", "renderers_test_default"]
7
+ }