@osmo.inc/cli 0.1.15

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 (949) hide show
  1. package/DEPLOY.md +87 -0
  2. package/README.md +243 -0
  3. package/RELEASE.md +164 -0
  4. package/SETUP.md +60 -0
  5. package/THIRD_PARTY_NOTICES.md +18 -0
  6. package/bin/osmo.mjs +12 -0
  7. package/dist/osmo.js +7817 -0
  8. package/node_modules/@esbuild/darwin-arm64/README.md +3 -0
  9. package/node_modules/@esbuild/darwin-arm64/bin/esbuild +0 -0
  10. package/node_modules/@esbuild/darwin-arm64/package.json +20 -0
  11. package/node_modules/esbuild/LICENSE.md +21 -0
  12. package/node_modules/esbuild/README.md +3 -0
  13. package/node_modules/esbuild/bin/esbuild +223 -0
  14. package/node_modules/esbuild/install.js +289 -0
  15. package/node_modules/esbuild/lib/main.d.ts +716 -0
  16. package/node_modules/esbuild/lib/main.js +2532 -0
  17. package/node_modules/esbuild/package.json +49 -0
  18. package/node_modules/fflate/LICENSE +21 -0
  19. package/node_modules/fflate/esm/index.mjs +2710 -0
  20. package/node_modules/fflate/package.json +128 -0
  21. package/node_modules/typescript/LICENSE.txt +55 -0
  22. package/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
  23. package/node_modules/typescript/lib/lib.d.ts +22 -0
  24. package/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
  25. package/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
  26. package/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
  27. package/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
  28. package/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
  29. package/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
  30. package/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
  31. package/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
  32. package/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
  33. package/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
  34. package/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
  35. package/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
  36. package/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
  37. package/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
  38. package/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
  39. package/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
  40. package/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
  41. package/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
  42. package/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
  43. package/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
  44. package/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
  45. package/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
  46. package/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
  47. package/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
  48. package/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
  49. package/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
  50. package/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
  51. package/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
  52. package/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
  53. package/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
  54. package/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
  55. package/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
  56. package/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
  57. package/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
  58. package/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
  59. package/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
  60. package/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
  61. package/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
  62. package/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
  63. package/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
  64. package/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
  65. package/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
  66. package/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
  67. package/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
  68. package/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
  69. package/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
  70. package/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
  71. package/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
  72. package/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
  73. package/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
  74. package/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
  75. package/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
  76. package/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
  77. package/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
  78. package/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
  79. package/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
  80. package/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
  81. package/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
  82. package/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
  83. package/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
  84. package/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
  85. package/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
  86. package/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
  87. package/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
  88. package/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
  89. package/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
  90. package/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
  91. package/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
  92. package/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
  93. package/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
  94. package/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
  95. package/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
  96. package/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
  97. package/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
  98. package/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
  99. package/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
  100. package/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
  101. package/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
  102. package/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
  103. package/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
  104. package/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
  105. package/node_modules/typescript/lib/lib.es6.d.ts +23 -0
  106. package/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
  107. package/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
  108. package/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
  109. package/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
  110. package/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
  111. package/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
  112. package/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
  113. package/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
  114. package/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
  115. package/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
  116. package/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
  117. package/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
  118. package/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
  119. package/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
  120. package/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
  121. package/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
  122. package/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
  123. package/node_modules/typescript/lib/typescript.js +382 -0
  124. package/node_modules/typescript/package.json +57 -0
  125. package/package.json +54 -0
  126. package/release.json +136 -0
  127. package/runtime/apps/native/tools/compile.mjs +217 -0
  128. package/runtime/packages/scene/scripts/validate-strict.mjs +246 -0
  129. package/runtime/packages/scene/src/clip.d.mts +14 -0
  130. package/runtime/packages/scene/src/clip.mjs +15 -0
  131. package/runtime/packages/scene/src/color-value.d.mts +5 -0
  132. package/runtime/packages/scene/src/color-value.mjs +19 -0
  133. package/runtime/packages/scene/src/color.ts +1 -0
  134. package/runtime/packages/scene/src/effects.ts +213 -0
  135. package/runtime/packages/scene/src/elements.ts +491 -0
  136. package/runtime/packages/scene/src/evaluate.ts +919 -0
  137. package/runtime/packages/scene/src/index.ts +69 -0
  138. package/runtime/packages/scene/src/jsx-runtime.ts +73 -0
  139. package/runtime/packages/scene/src/knob-schema.ts +115 -0
  140. package/runtime/packages/scene/src/knobs.ts +118 -0
  141. package/runtime/packages/scene/src/mask.d.mts +6 -0
  142. package/runtime/packages/scene/src/mask.mjs +17 -0
  143. package/runtime/packages/scene/src/metadata.d.mts +23 -0
  144. package/runtime/packages/scene/src/metadata.mjs +44 -0
  145. package/runtime/packages/scene/src/motion-sampling.d.mts +2 -0
  146. package/runtime/packages/scene/src/motion-sampling.mjs +50 -0
  147. package/runtime/packages/scene/src/motion.ts +121 -0
  148. package/runtime/packages/scene/src/shader.ts +57 -0
  149. package/src/resource-examples/example-image/landscape.svg +7 -0
  150. package/src/resource-examples/example-image/resource.json +8 -0
  151. package/src/resource-examples/example-model/gem.glb +0 -0
  152. package/src/resource-examples/example-model/preview.svg +1 -0
  153. package/src/resource-examples/example-model/resource.json +7 -0
  154. package/src/resource-examples/example-scene/resource.json +1 -0
  155. package/src/resource-examples/example-scene/scene.tsx +8 -0
  156. package/src/resource-examples/example-shader/effect.wgsl +7 -0
  157. package/src/resource-examples/example-shader/preview.svg +1 -0
  158. package/src/resource-examples/example-shader/resource.json +27 -0
  159. package/src/resource-examples/example-shader/tint.wgsl +7 -0
  160. package/src/resource-examples/example-video/ambient.mp4 +0 -0
  161. package/src/resource-examples/example-video/resource.json +9 -0
  162. package/src/starter/scene.tsx +20 -0
  163. package/studio/index.html +2 -0
  164. package/studio/public/check-circle-filled.svg +3 -0
  165. package/studio/public/comment-cursor/active-outer.svg +3 -0
  166. package/studio/public/comment-cursor/default.svg +6 -0
  167. package/studio/public/osmo-studio-logo.svg +12 -0
  168. package/studio/public/pencil-simple.svg +5 -0
  169. package/studio/src/active-outer-TVYUEURE.svg +3 -0
  170. package/studio/src/app.css +4 -0
  171. package/studio/src/app.js +705 -0
  172. package/studio/src/default-6CTRH4V5.svg +6 -0
  173. package/studio/src/engine_bg.wasm +0 -0
  174. package/studio/src/inter-cyrillic-ext-wght-normal-IYF56FF6.woff2 +0 -0
  175. package/studio/src/inter-cyrillic-wght-normal-JEOLYBOO.woff2 +0 -0
  176. package/studio/src/inter-greek-ext-wght-normal-EOVOK2B5.woff2 +0 -0
  177. package/studio/src/inter-greek-wght-normal-IRE366VL.woff2 +0 -0
  178. package/studio/src/inter-latin-ext-wght-normal-HA22NDSG.woff2 +0 -0
  179. package/studio/src/inter-latin-wght-normal-NRMW37G5.woff2 +0 -0
  180. package/studio/src/inter-vietnamese-wght-normal-CE5GGD3W.woff2 +0 -0
  181. package/studio/src/osmo-studio-logo-D5R2V77B.svg +12 -0
  182. package/third-party/cargo/adler2@2.0.1/Cargo.toml +91 -0
  183. package/third-party/cargo/adler2@2.0.1/LICENSE-0BSD +12 -0
  184. package/third-party/cargo/adler2@2.0.1/LICENSE-APACHE +201 -0
  185. package/third-party/cargo/adler2@2.0.1/LICENSE-MIT +23 -0
  186. package/third-party/cargo/allocator-api2@0.2.21/Cargo.toml +48 -0
  187. package/third-party/cargo/allocator-api2@0.2.21/LICENSE-APACHE +176 -0
  188. package/third-party/cargo/allocator-api2@0.2.21/LICENSE-MIT +23 -0
  189. package/third-party/cargo/arrayref@0.3.9/Cargo.toml +23 -0
  190. package/third-party/cargo/arrayref@0.3.9/LICENSE +26 -0
  191. package/third-party/cargo/arrayvec@0.7.8/Cargo.toml +112 -0
  192. package/third-party/cargo/arrayvec@0.7.8/LICENSE-APACHE +201 -0
  193. package/third-party/cargo/arrayvec@0.7.8/LICENSE-MIT +25 -0
  194. package/third-party/cargo/ascii@1.1.0/Cargo.toml +41 -0
  195. package/third-party/cargo/ascii@1.1.0/LICENSE-APACHE +201 -0
  196. package/third-party/cargo/ascii@1.1.0/LICENSE-MIT +22 -0
  197. package/third-party/cargo/ash@0.38.0+1.3.281/Cargo.toml +66 -0
  198. package/third-party/cargo/ash@0.38.0+1.3.281/LICENSE-APACHE +67 -0
  199. package/third-party/cargo/ash@0.38.0+1.3.281/LICENSE-MIT +25 -0
  200. package/third-party/cargo/autocfg@1.5.1/Cargo.toml +75 -0
  201. package/third-party/cargo/autocfg@1.5.1/LICENSE-APACHE +201 -0
  202. package/third-party/cargo/autocfg@1.5.1/LICENSE-MIT +25 -0
  203. package/third-party/cargo/base64@0.13.1/Cargo.toml +53 -0
  204. package/third-party/cargo/base64@0.13.1/LICENSE-APACHE +201 -0
  205. package/third-party/cargo/base64@0.13.1/LICENSE-MIT +21 -0
  206. package/third-party/cargo/base64@0.22.1/Cargo.toml +85 -0
  207. package/third-party/cargo/base64@0.22.1/LICENSE-APACHE +201 -0
  208. package/third-party/cargo/base64@0.22.1/LICENSE-MIT +21 -0
  209. package/third-party/cargo/bit-set@0.10.0/Cargo.toml +108 -0
  210. package/third-party/cargo/bit-set@0.10.0/LICENSE-APACHE +201 -0
  211. package/third-party/cargo/bit-set@0.10.0/LICENSE-MIT +25 -0
  212. package/third-party/cargo/bit-vec@0.9.1/Cargo.toml +94 -0
  213. package/third-party/cargo/bit-vec@0.9.1/LICENSE-APACHE +201 -0
  214. package/third-party/cargo/bit-vec@0.9.1/LICENSE-MIT +25 -0
  215. package/third-party/cargo/bitflags@2.13.0/Cargo.toml +120 -0
  216. package/third-party/cargo/bitflags@2.13.0/LICENSE-APACHE +201 -0
  217. package/third-party/cargo/bitflags@2.13.0/LICENSE-MIT +25 -0
  218. package/third-party/cargo/block2@0.6.2/Cargo.toml +115 -0
  219. package/third-party/cargo/block2@0.6.2/MIT-terms.txt +22 -0
  220. package/third-party/cargo/block2@0.6.2/madsmtm-objc2-b4167b582b2f-LICENSE.md +34 -0
  221. package/third-party/cargo/bumpalo@3.20.3/Cargo.toml +99 -0
  222. package/third-party/cargo/bumpalo@3.20.3/LICENSE-APACHE +201 -0
  223. package/third-party/cargo/bumpalo@3.20.3/LICENSE-MIT +25 -0
  224. package/third-party/cargo/bytemuck@1.25.1/Cargo.toml +153 -0
  225. package/third-party/cargo/bytemuck@1.25.1/LICENSE-APACHE +61 -0
  226. package/third-party/cargo/bytemuck@1.25.1/LICENSE-MIT +9 -0
  227. package/third-party/cargo/bytemuck@1.25.1/LICENSE-ZLIB +11 -0
  228. package/third-party/cargo/bytemuck_derive@1.11.0/Cargo.toml +60 -0
  229. package/third-party/cargo/bytemuck_derive@1.11.0/LICENSE-APACHE +61 -0
  230. package/third-party/cargo/bytemuck_derive@1.11.0/LICENSE-MIT +9 -0
  231. package/third-party/cargo/bytemuck_derive@1.11.0/LICENSE-ZLIB +11 -0
  232. package/third-party/cargo/byteorder-lite@0.1.0/Cargo.toml +57 -0
  233. package/third-party/cargo/byteorder-lite@0.1.0/LICENSE-MIT +21 -0
  234. package/third-party/cargo/byteorder-lite@0.1.0/UNLICENSE +24 -0
  235. package/third-party/cargo/byteorder@1.5.0/COPYING +3 -0
  236. package/third-party/cargo/byteorder@1.5.0/Cargo.toml +54 -0
  237. package/third-party/cargo/byteorder@1.5.0/LICENSE-MIT +21 -0
  238. package/third-party/cargo/byteorder@1.5.0/UNLICENSE +24 -0
  239. package/third-party/cargo/cfg-if@1.0.4/Cargo.toml +47 -0
  240. package/third-party/cargo/cfg-if@1.0.4/LICENSE-APACHE +201 -0
  241. package/third-party/cargo/cfg-if@1.0.4/LICENSE-MIT +25 -0
  242. package/third-party/cargo/cfg_aliases@0.2.1/Cargo.toml +43 -0
  243. package/third-party/cargo/cfg_aliases@0.2.1/LICENSE +9 -0
  244. package/third-party/cargo/chunked_transfer@1.5.0/Cargo.toml +27 -0
  245. package/third-party/cargo/chunked_transfer@1.5.0/LICENSE-APACHE +201 -0
  246. package/third-party/cargo/chunked_transfer@1.5.0/LICENSE-MIT +22 -0
  247. package/third-party/cargo/codespan-reporting@0.13.1/Cargo.toml +115 -0
  248. package/third-party/cargo/codespan-reporting@0.13.1/LICENSE +201 -0
  249. package/third-party/cargo/color_quant@1.1.0/Cargo.toml +20 -0
  250. package/third-party/cargo/color_quant@1.1.0/LICENSE +21 -0
  251. package/third-party/cargo/console_error_panic_hook@0.1.7/Cargo.toml +27 -0
  252. package/third-party/cargo/console_error_panic_hook@0.1.7/LICENSE-APACHE +201 -0
  253. package/third-party/cargo/console_error_panic_hook@0.1.7/LICENSE-MIT +25 -0
  254. package/third-party/cargo/core_maths@0.1.1/Cargo.toml +37 -0
  255. package/third-party/cargo/core_maths@0.1.1/LICENSE +21 -0
  256. package/third-party/cargo/cosmic-text@0.19.0/Cargo.toml +214 -0
  257. package/third-party/cargo/cosmic-text@0.19.0/LICENSE-APACHE +201 -0
  258. package/third-party/cargo/cosmic-text@0.19.0/LICENSE-MIT +21 -0
  259. package/third-party/cargo/crc32fast@1.5.0/Cargo.toml +68 -0
  260. package/third-party/cargo/crc32fast@1.5.0/LICENSE-APACHE +202 -0
  261. package/third-party/cargo/crc32fast@1.5.0/LICENSE-MIT +21 -0
  262. package/third-party/cargo/data-url@0.3.2/Cargo.toml +63 -0
  263. package/third-party/cargo/data-url@0.3.2/LICENSE-APACHE +201 -0
  264. package/third-party/cargo/data-url@0.3.2/LICENSE-MIT +25 -0
  265. package/third-party/cargo/dispatch2@0.3.1/Cargo.toml +122 -0
  266. package/third-party/cargo/dispatch2@0.3.1/MIT-terms.txt +22 -0
  267. package/third-party/cargo/dispatch2@0.3.1/madsmtm-objc2-8852b424193c-LICENSE.md +34 -0
  268. package/third-party/cargo/dlib@0.5.3/Cargo.toml +43 -0
  269. package/third-party/cargo/dlib@0.5.3/LICENSE.txt +19 -0
  270. package/third-party/cargo/document-features@0.2.12/Cargo.toml +51 -0
  271. package/third-party/cargo/document-features@0.2.12/LICENSE-APACHE +73 -0
  272. package/third-party/cargo/document-features@0.2.12/LICENSE-MIT +19 -0
  273. package/third-party/cargo/equivalent@1.0.2/Cargo.toml +37 -0
  274. package/third-party/cargo/equivalent@1.0.2/LICENSE-APACHE +201 -0
  275. package/third-party/cargo/equivalent@1.0.2/LICENSE-MIT +25 -0
  276. package/third-party/cargo/errno@0.3.14/Cargo.toml +67 -0
  277. package/third-party/cargo/errno@0.3.14/LICENSE-APACHE +201 -0
  278. package/third-party/cargo/errno@0.3.14/LICENSE-MIT +25 -0
  279. package/third-party/cargo/etagere@0.3.0/Cargo.toml +57 -0
  280. package/third-party/cargo/etagere@0.3.0/LICENSE-APACHE +13 -0
  281. package/third-party/cargo/etagere@0.3.0/LICENSE-MIT +20 -0
  282. package/third-party/cargo/euclid@0.22.14/COPYRIGHT +5 -0
  283. package/third-party/cargo/euclid@0.22.14/Cargo.toml +66 -0
  284. package/third-party/cargo/euclid@0.22.14/LICENSE-APACHE +201 -0
  285. package/third-party/cargo/euclid@0.22.14/LICENSE-MIT +25 -0
  286. package/third-party/cargo/fastrand@2.5.0/Cargo.toml +89 -0
  287. package/third-party/cargo/fastrand@2.5.0/LICENSE-APACHE +201 -0
  288. package/third-party/cargo/fastrand@2.5.0/LICENSE-MIT +23 -0
  289. package/third-party/cargo/fdeflate@0.3.7/Cargo.toml +55 -0
  290. package/third-party/cargo/fdeflate@0.3.7/LICENSE-APACHE +177 -0
  291. package/third-party/cargo/fdeflate@0.3.7/LICENSE-MIT +25 -0
  292. package/third-party/cargo/flate2@1.1.9/Cargo.toml +274 -0
  293. package/third-party/cargo/flate2@1.1.9/LICENSE-APACHE +201 -0
  294. package/third-party/cargo/flate2@1.1.9/LICENSE-MIT +25 -0
  295. package/third-party/cargo/float-cmp@0.9.0/Cargo.toml +39 -0
  296. package/third-party/cargo/float-cmp@0.9.0/LICENSE +19 -0
  297. package/third-party/cargo/float_next_after@1.0.0/Cargo.toml +43 -0
  298. package/third-party/cargo/float_next_after@1.0.0/LICENSE +23 -0
  299. package/third-party/cargo/foldhash@0.2.0/Cargo.toml +80 -0
  300. package/third-party/cargo/foldhash@0.2.0/LICENSE +19 -0
  301. package/third-party/cargo/font-types@0.11.3/Cargo.toml +55 -0
  302. package/third-party/cargo/font-types@0.11.3/LICENSE-APACHE +67 -0
  303. package/third-party/cargo/font-types@0.11.3/LICENSE-MIT +25 -0
  304. package/third-party/cargo/fontdb@0.23.0/Cargo.toml +83 -0
  305. package/third-party/cargo/fontdb@0.23.0/LICENSE +21 -0
  306. package/third-party/cargo/futures-core@0.3.32/Cargo.toml +66 -0
  307. package/third-party/cargo/futures-core@0.3.32/LICENSE-APACHE +202 -0
  308. package/third-party/cargo/futures-core@0.3.32/LICENSE-MIT +26 -0
  309. package/third-party/cargo/futures-task@0.3.32/Cargo.toml +58 -0
  310. package/third-party/cargo/futures-task@0.3.32/LICENSE-APACHE +202 -0
  311. package/third-party/cargo/futures-task@0.3.32/LICENSE-MIT +26 -0
  312. package/third-party/cargo/futures-util@0.3.32/Cargo.toml +181 -0
  313. package/third-party/cargo/futures-util@0.3.32/LICENSE-APACHE +202 -0
  314. package/third-party/cargo/futures-util@0.3.32/LICENSE-MIT +26 -0
  315. package/third-party/cargo/getrandom@0.4.3/Cargo.toml +165 -0
  316. package/third-party/cargo/getrandom@0.4.3/LICENSE-APACHE +201 -0
  317. package/third-party/cargo/getrandom@0.4.3/LICENSE-MIT +26 -0
  318. package/third-party/cargo/gif@0.14.2/Cargo.toml +84 -0
  319. package/third-party/cargo/gif@0.14.2/LICENSE-APACHE +201 -0
  320. package/third-party/cargo/gif@0.14.2/LICENSE-MIT +21 -0
  321. package/third-party/cargo/glam@0.33.2/Cargo.toml +354 -0
  322. package/third-party/cargo/glam@0.33.2/LICENSE-APACHE +201 -0
  323. package/third-party/cargo/glam@0.33.2/LICENSE-MIT +23 -0
  324. package/third-party/cargo/glow@0.17.0/Cargo.toml +122 -0
  325. package/third-party/cargo/glow@0.17.0/LICENSE-APACHE +201 -0
  326. package/third-party/cargo/glow@0.17.0/LICENSE-MIT +23 -0
  327. package/third-party/cargo/glow@0.17.0/LICENSE-ZLIB +15 -0
  328. package/third-party/cargo/gltf-derive@1.4.1/Cargo.toml +34 -0
  329. package/third-party/cargo/gltf-derive@1.4.1/LICENSE-APACHE +202 -0
  330. package/third-party/cargo/gltf-derive@1.4.1/LICENSE-MIT +26 -0
  331. package/third-party/cargo/gltf-json@1.4.1/Cargo.toml +50 -0
  332. package/third-party/cargo/gltf-json@1.4.1/LICENSE-APACHE +202 -0
  333. package/third-party/cargo/gltf-json@1.4.1/LICENSE-MIT +26 -0
  334. package/third-party/cargo/gltf@1.4.1/Cargo.toml +122 -0
  335. package/third-party/cargo/gltf@1.4.1/LICENSE-APACHE +202 -0
  336. package/third-party/cargo/gltf@1.4.1/LICENSE-MIT +26 -0
  337. package/third-party/cargo/glyphon@0.12.0/Cargo.toml +35 -0
  338. package/third-party/cargo/glyphon@0.12.0/LICENSE-APACHE +201 -0
  339. package/third-party/cargo/glyphon@0.12.0/LICENSE-MIT +23 -0
  340. package/third-party/cargo/glyphon@0.12.0/LICENSE-ZLIB +15 -0
  341. package/third-party/cargo/gpu-allocator@0.28.0/Cargo.toml +180 -0
  342. package/third-party/cargo/gpu-allocator@0.28.0/LICENSE-APACHE +201 -0
  343. package/third-party/cargo/gpu-allocator@0.28.0/LICENSE-MIT +7 -0
  344. package/third-party/cargo/grid@1.0.1/Cargo.toml +77 -0
  345. package/third-party/cargo/grid@1.0.1/LICENSE +21 -0
  346. package/third-party/cargo/half@2.7.1/Cargo.toml +137 -0
  347. package/third-party/cargo/half@2.7.1/LICENSE-APACHE +176 -0
  348. package/third-party/cargo/half@2.7.1/LICENSE-MIT +19 -0
  349. package/third-party/cargo/harfrust@0.5.2/Cargo.toml +115 -0
  350. package/third-party/cargo/harfrust@0.5.2/harfbuzz-harfrust-efdae3142ab7-LICENSE +22 -0
  351. package/third-party/cargo/hashbrown@0.16.1/Cargo.toml +180 -0
  352. package/third-party/cargo/hashbrown@0.16.1/LICENSE-APACHE +201 -0
  353. package/third-party/cargo/hashbrown@0.16.1/LICENSE-MIT +25 -0
  354. package/third-party/cargo/hashbrown@0.17.1/Cargo.toml +201 -0
  355. package/third-party/cargo/hashbrown@0.17.1/LICENSE-APACHE +201 -0
  356. package/third-party/cargo/hashbrown@0.17.1/LICENSE-MIT +25 -0
  357. package/third-party/cargo/httpdate@1.0.3/Cargo.toml +35 -0
  358. package/third-party/cargo/httpdate@1.0.3/LICENSE-APACHE +201 -0
  359. package/third-party/cargo/httpdate@1.0.3/LICENSE-MIT +19 -0
  360. package/third-party/cargo/image-webp@0.2.4/Cargo.toml +63 -0
  361. package/third-party/cargo/image-webp@0.2.4/LICENSE-APACHE +177 -0
  362. package/third-party/cargo/image-webp@0.2.4/LICENSE-MIT +25 -0
  363. package/third-party/cargo/image@0.25.10/Cargo.toml +248 -0
  364. package/third-party/cargo/image@0.25.10/LICENSE-APACHE +177 -0
  365. package/third-party/cargo/image@0.25.10/LICENSE-MIT +25 -0
  366. package/third-party/cargo/imagesize@0.14.0/Cargo.toml +104 -0
  367. package/third-party/cargo/imagesize@0.14.0/LICENSE +21 -0
  368. package/third-party/cargo/indexmap@2.14.0/Cargo.toml +167 -0
  369. package/third-party/cargo/indexmap@2.14.0/LICENSE-APACHE +201 -0
  370. package/third-party/cargo/indexmap@2.14.0/LICENSE-MIT +25 -0
  371. package/third-party/cargo/inflections@1.1.1/Cargo.toml +21 -0
  372. package/third-party/cargo/inflections@1.1.1/LICENSE +20 -0
  373. package/third-party/cargo/itoa@1.0.18/Cargo.toml +66 -0
  374. package/third-party/cargo/itoa@1.0.18/LICENSE-APACHE +176 -0
  375. package/third-party/cargo/itoa@1.0.18/LICENSE-MIT +23 -0
  376. package/third-party/cargo/js-sys@0.3.103/Cargo.toml +98 -0
  377. package/third-party/cargo/js-sys@0.3.103/LICENSE-APACHE +201 -0
  378. package/third-party/cargo/js-sys@0.3.103/LICENSE-MIT +25 -0
  379. package/third-party/cargo/khronos-egl@6.0.0/Cargo.toml +82 -0
  380. package/third-party/cargo/khronos-egl@6.0.0/LICENSE-APACHE +201 -0
  381. package/third-party/cargo/khronos-egl@6.0.0/LICENSE-MIT +23 -0
  382. package/third-party/cargo/kurbo@0.13.1/Cargo.toml +230 -0
  383. package/third-party/cargo/kurbo@0.13.1/LICENSE-APACHE +202 -0
  384. package/third-party/cargo/kurbo@0.13.1/LICENSE-MIT +25 -0
  385. package/third-party/cargo/lazy_static@1.5.0/Cargo.toml +46 -0
  386. package/third-party/cargo/lazy_static@1.5.0/LICENSE-APACHE +201 -0
  387. package/third-party/cargo/lazy_static@1.5.0/LICENSE-MIT +25 -0
  388. package/third-party/cargo/libc@0.2.186/Cargo.toml +229 -0
  389. package/third-party/cargo/libc@0.2.186/LICENSE-APACHE +176 -0
  390. package/third-party/cargo/libc@0.2.186/LICENSE-MIT +25 -0
  391. package/third-party/cargo/libloading@0.8.9/Cargo.toml +90 -0
  392. package/third-party/cargo/libloading@0.8.9/LICENSE +12 -0
  393. package/third-party/cargo/libm@0.2.16/Cargo.toml +61 -0
  394. package/third-party/cargo/libm@0.2.16/LICENSE.txt +258 -0
  395. package/third-party/cargo/linebender_resource_handle@0.1.1/Cargo.toml +107 -0
  396. package/third-party/cargo/linebender_resource_handle@0.1.1/LICENSE-APACHE +176 -0
  397. package/third-party/cargo/linebender_resource_handle@0.1.1/LICENSE-MIT +19 -0
  398. package/third-party/cargo/litrs@1.0.0/Cargo.toml +63 -0
  399. package/third-party/cargo/litrs@1.0.0/LICENSE-APACHE +176 -0
  400. package/third-party/cargo/litrs@1.0.0/LICENSE-MIT +25 -0
  401. package/third-party/cargo/lock_api@0.4.14/Cargo.toml +68 -0
  402. package/third-party/cargo/lock_api@0.4.14/LICENSE-APACHE +201 -0
  403. package/third-party/cargo/lock_api@0.4.14/LICENSE-MIT +25 -0
  404. package/third-party/cargo/log@0.4.33/Cargo.toml +152 -0
  405. package/third-party/cargo/log@0.4.33/LICENSE-APACHE +201 -0
  406. package/third-party/cargo/log@0.4.33/LICENSE-MIT +25 -0
  407. package/third-party/cargo/lru@0.16.4/Cargo.toml +47 -0
  408. package/third-party/cargo/lru@0.16.4/LICENSE +21 -0
  409. package/third-party/cargo/lyon_geom@1.0.19/Cargo.toml +69 -0
  410. package/third-party/cargo/lyon_geom@1.0.19/nical-lyon-56219c95c658-LICENSE-APACHE +13 -0
  411. package/third-party/cargo/lyon_geom@1.0.19/nical-lyon-56219c95c658-LICENSE-MIT +20 -0
  412. package/third-party/cargo/lyon_path@1.0.19/Cargo.toml +58 -0
  413. package/third-party/cargo/lyon_path@1.0.19/nical-lyon-56219c95c658-LICENSE-APACHE +13 -0
  414. package/third-party/cargo/lyon_path@1.0.19/nical-lyon-56219c95c658-LICENSE-MIT +20 -0
  415. package/third-party/cargo/lyon_tessellation@1.0.20/Cargo.toml +71 -0
  416. package/third-party/cargo/lyon_tessellation@1.0.20/nical-lyon-7fa75ea8eea3-LICENSE-APACHE +13 -0
  417. package/third-party/cargo/lyon_tessellation@1.0.20/nical-lyon-7fa75ea8eea3-LICENSE-MIT +20 -0
  418. package/third-party/cargo/memchr@2.8.3/COPYING +3 -0
  419. package/third-party/cargo/memchr@2.8.3/Cargo.toml +89 -0
  420. package/third-party/cargo/memchr@2.8.3/LICENSE-MIT +21 -0
  421. package/third-party/cargo/memchr@2.8.3/UNLICENSE +24 -0
  422. package/third-party/cargo/memmap2@0.9.11/Cargo.toml +59 -0
  423. package/third-party/cargo/memmap2@0.9.11/LICENSE-APACHE +201 -0
  424. package/third-party/cargo/memmap2@0.9.11/LICENSE-MIT +26 -0
  425. package/third-party/cargo/miniz_oxide@0.8.9/Cargo.toml +91 -0
  426. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE +25 -0
  427. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE-APACHE.md +177 -0
  428. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE-MIT.md +24 -0
  429. package/third-party/cargo/miniz_oxide@0.8.9/LICENSE-ZLIB.md +14 -0
  430. package/third-party/cargo/moxcms@0.8.1/Cargo.toml +113 -0
  431. package/third-party/cargo/moxcms@0.8.1/LICENSE-APACHE.md +201 -0
  432. package/third-party/cargo/moxcms@0.8.1/LICENSE.md +26 -0
  433. package/third-party/cargo/naga-types@30.0.0/Cargo.toml +94 -0
  434. package/third-party/cargo/naga-types@30.0.0/LICENSE.APACHE +176 -0
  435. package/third-party/cargo/naga-types@30.0.0/LICENSE.MIT +21 -0
  436. package/third-party/cargo/naga@30.0.0/Cargo.toml +246 -0
  437. package/third-party/cargo/naga@30.0.0/LICENSE.APACHE +176 -0
  438. package/third-party/cargo/naga@30.0.0/LICENSE.MIT +21 -0
  439. package/third-party/cargo/num-traits@0.2.19/Cargo.toml +54 -0
  440. package/third-party/cargo/num-traits@0.2.19/LICENSE-APACHE +201 -0
  441. package/third-party/cargo/num-traits@0.2.19/LICENSE-MIT +25 -0
  442. package/third-party/cargo/objc2-core-foundation@0.3.2/Cargo.toml +221 -0
  443. package/third-party/cargo/objc2-core-foundation@0.3.2/MIT-terms.txt +22 -0
  444. package/third-party/cargo/objc2-core-foundation@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  445. package/third-party/cargo/objc2-core-graphics@0.3.2/Cargo.toml +331 -0
  446. package/third-party/cargo/objc2-core-graphics@0.3.2/MIT-terms.txt +22 -0
  447. package/third-party/cargo/objc2-core-graphics@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  448. package/third-party/cargo/objc2-encode@4.1.0/Cargo.toml +81 -0
  449. package/third-party/cargo/objc2-encode@4.1.0/MIT-terms.txt +22 -0
  450. package/third-party/cargo/objc2-encode@4.1.0/madsmtm-objc2-8d214f547736-LICENSE.md +34 -0
  451. package/third-party/cargo/objc2-foundation@0.3.2/Cargo.toml +529 -0
  452. package/third-party/cargo/objc2-foundation@0.3.2/MIT-terms.txt +22 -0
  453. package/third-party/cargo/objc2-foundation@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  454. package/third-party/cargo/objc2-io-surface@0.3.2/Cargo.toml +139 -0
  455. package/third-party/cargo/objc2-io-surface@0.3.2/MIT-terms.txt +22 -0
  456. package/third-party/cargo/objc2-io-surface@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  457. package/third-party/cargo/objc2-metal@0.3.2/Cargo.toml +601 -0
  458. package/third-party/cargo/objc2-metal@0.3.2/MIT-terms.txt +22 -0
  459. package/third-party/cargo/objc2-metal@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  460. package/third-party/cargo/objc2-quartz-core@0.3.2/Cargo.toml +302 -0
  461. package/third-party/cargo/objc2-quartz-core@0.3.2/MIT-terms.txt +22 -0
  462. package/third-party/cargo/objc2-quartz-core@0.3.2/madsmtm-objc2-7b1abfd750a2-LICENSE.md +34 -0
  463. package/third-party/cargo/objc2@0.6.4/Cargo.toml +232 -0
  464. package/third-party/cargo/objc2@0.6.4/MIT-terms.txt +22 -0
  465. package/third-party/cargo/objc2@0.6.4/madsmtm-objc2-8852b424193c-LICENSE.md +34 -0
  466. package/third-party/cargo/once_cell@1.21.4/Cargo.toml +119 -0
  467. package/third-party/cargo/once_cell@1.21.4/LICENSE-APACHE +201 -0
  468. package/third-party/cargo/once_cell@1.21.4/LICENSE-MIT +23 -0
  469. package/third-party/cargo/ordered-float@5.3.0/Cargo.toml +162 -0
  470. package/third-party/cargo/ordered-float@5.3.0/LICENSE-MIT +25 -0
  471. package/third-party/cargo/parking_lot@0.12.5/Cargo.toml +87 -0
  472. package/third-party/cargo/parking_lot@0.12.5/LICENSE-APACHE +201 -0
  473. package/third-party/cargo/parking_lot@0.12.5/LICENSE-MIT +25 -0
  474. package/third-party/cargo/parking_lot_core@0.9.12/Cargo.toml +72 -0
  475. package/third-party/cargo/parking_lot_core@0.9.12/LICENSE-APACHE +201 -0
  476. package/third-party/cargo/parking_lot_core@0.9.12/LICENSE-MIT +25 -0
  477. package/third-party/cargo/pico-args@0.5.0/Cargo.toml +32 -0
  478. package/third-party/cargo/pico-args@0.5.0/LICENSE +20 -0
  479. package/third-party/cargo/pin-project-lite@0.2.17/Cargo.toml +198 -0
  480. package/third-party/cargo/pin-project-lite@0.2.17/LICENSE-APACHE +177 -0
  481. package/third-party/cargo/pin-project-lite@0.2.17/LICENSE-MIT +23 -0
  482. package/third-party/cargo/pkg-config@0.3.33/Cargo.toml +43 -0
  483. package/third-party/cargo/pkg-config@0.3.33/LICENSE-APACHE +201 -0
  484. package/third-party/cargo/pkg-config@0.3.33/LICENSE-MIT +25 -0
  485. package/third-party/cargo/png@0.18.1/Cargo.toml +130 -0
  486. package/third-party/cargo/png@0.18.1/LICENSE-APACHE +201 -0
  487. package/third-party/cargo/png@0.18.1/LICENSE-MIT +25 -0
  488. package/third-party/cargo/pollster@0.4.0/Cargo.toml +53 -0
  489. package/third-party/cargo/pollster@0.4.0/LICENSE-APACHE +201 -0
  490. package/third-party/cargo/pollster@0.4.0/LICENSE-MIT +25 -0
  491. package/third-party/cargo/polycool@0.4.0/Cargo.toml +83 -0
  492. package/third-party/cargo/polycool@0.4.0/LICENSE-APACHE +202 -0
  493. package/third-party/cargo/polycool@0.4.0/LICENSE-MIT +25 -0
  494. package/third-party/cargo/pp-rs@0.2.1/Cargo.toml +23 -0
  495. package/third-party/cargo/pp-rs@0.2.1/LICENSE +29 -0
  496. package/third-party/cargo/presser@0.3.1/Cargo.toml +58 -0
  497. package/third-party/cargo/presser@0.3.1/LICENSE-APACHE +201 -0
  498. package/third-party/cargo/presser@0.3.1/LICENSE-MIT +25 -0
  499. package/third-party/cargo/proc-macro2@1.0.106/Cargo.toml +105 -0
  500. package/third-party/cargo/proc-macro2@1.0.106/LICENSE-APACHE +176 -0
  501. package/third-party/cargo/proc-macro2@1.0.106/LICENSE-MIT +23 -0
  502. package/third-party/cargo/profiling@1.0.18/Cargo.toml +96 -0
  503. package/third-party/cargo/profiling@1.0.18/aclysma-profiling-8271551172eb-LICENSE-APACHE +201 -0
  504. package/third-party/cargo/profiling@1.0.18/aclysma-profiling-8271551172eb-LICENSE-MIT +21 -0
  505. package/third-party/cargo/pxfm@0.1.30/Cargo.toml +53 -0
  506. package/third-party/cargo/pxfm@0.1.30/LICENSE-APACHE.md +201 -0
  507. package/third-party/cargo/pxfm@0.1.30/LICENSE.md +26 -0
  508. package/third-party/cargo/quick-error@2.0.1/Cargo.toml +24 -0
  509. package/third-party/cargo/quick-error@2.0.1/LICENSE-APACHE +202 -0
  510. package/third-party/cargo/quick-error@2.0.1/LICENSE-MIT +19 -0
  511. package/third-party/cargo/quote@1.0.46/Cargo.toml +70 -0
  512. package/third-party/cargo/quote@1.0.46/LICENSE-APACHE +176 -0
  513. package/third-party/cargo/quote@1.0.46/LICENSE-MIT +23 -0
  514. package/third-party/cargo/rangemap@1.7.1/Cargo.toml +91 -0
  515. package/third-party/cargo/rangemap@1.7.1/LICENSE-APACHE +191 -0
  516. package/third-party/cargo/rangemap@1.7.1/LICENSE-MIT +7 -0
  517. package/third-party/cargo/raw-window-handle@0.6.2/Cargo.toml +56 -0
  518. package/third-party/cargo/raw-window-handle@0.6.2/LICENSE-APACHE.md +177 -0
  519. package/third-party/cargo/raw-window-handle@0.6.2/LICENSE-MIT.md +21 -0
  520. package/third-party/cargo/raw-window-handle@0.6.2/LICENSE-ZLIB.md +11 -0
  521. package/third-party/cargo/raw-window-metal@1.1.0/Cargo.toml +111 -0
  522. package/third-party/cargo/raw-window-metal@1.1.0/LICENSE-APACHE +202 -0
  523. package/third-party/cargo/raw-window-metal@1.1.0/LICENSE-MIT +17 -0
  524. package/third-party/cargo/read-fonts@0.37.0/Cargo.toml +95 -0
  525. package/third-party/cargo/read-fonts@0.37.0/LICENSE-APACHE +67 -0
  526. package/third-party/cargo/read-fonts@0.37.0/LICENSE-MIT +25 -0
  527. package/third-party/cargo/read-fonts@0.39.2/Cargo.toml +96 -0
  528. package/third-party/cargo/read-fonts@0.39.2/LICENSE-APACHE +67 -0
  529. package/third-party/cargo/read-fonts@0.39.2/LICENSE-MIT +25 -0
  530. package/third-party/cargo/renderdoc-sys@1.1.0/Cargo.toml +39 -0
  531. package/third-party/cargo/renderdoc-sys@1.1.0/LICENSE-APACHE +201 -0
  532. package/third-party/cargo/renderdoc-sys@1.1.0/LICENSE-MIT +25 -0
  533. package/third-party/cargo/resvg@0.47.0/Cargo.toml +112 -0
  534. package/third-party/cargo/resvg@0.47.0/LICENSE-APACHE +176 -0
  535. package/third-party/cargo/resvg@0.47.0/LICENSE-MIT +25 -0
  536. package/third-party/cargo/rgb@0.8.53/Cargo.toml +110 -0
  537. package/third-party/cargo/rgb@0.8.53/LICENSE +21 -0
  538. package/third-party/cargo/roxmltree@0.21.1/Cargo.toml +75 -0
  539. package/third-party/cargo/roxmltree@0.21.1/LICENSE-APACHE +201 -0
  540. package/third-party/cargo/roxmltree@0.21.1/LICENSE-MIT +21 -0
  541. package/third-party/cargo/rustc-hash@1.1.0/Cargo.toml +25 -0
  542. package/third-party/cargo/rustc-hash@1.1.0/LICENSE-APACHE +201 -0
  543. package/third-party/cargo/rustc-hash@1.1.0/LICENSE-MIT +23 -0
  544. package/third-party/cargo/rustc-hash@2.1.3/Cargo.toml +50 -0
  545. package/third-party/cargo/rustc-hash@2.1.3/LICENSE-APACHE +176 -0
  546. package/third-party/cargo/rustc-hash@2.1.3/LICENSE-MIT +23 -0
  547. package/third-party/cargo/rustix@1.1.4/COPYRIGHT +29 -0
  548. package/third-party/cargo/rustix@1.1.4/Cargo.toml +292 -0
  549. package/third-party/cargo/rustix@1.1.4/LICENSE-APACHE +201 -0
  550. package/third-party/cargo/rustix@1.1.4/LICENSE-Apache-2.0_WITH_LLVM-exception +220 -0
  551. package/third-party/cargo/rustix@1.1.4/LICENSE-MIT +23 -0
  552. package/third-party/cargo/rustversion@1.0.23/Cargo.toml +69 -0
  553. package/third-party/cargo/rustversion@1.0.23/LICENSE-APACHE +176 -0
  554. package/third-party/cargo/rustversion@1.0.23/LICENSE-MIT +23 -0
  555. package/third-party/cargo/rustybuzz@0.20.1/Cargo.toml +110 -0
  556. package/third-party/cargo/rustybuzz@0.20.1/LICENSE +22 -0
  557. package/third-party/cargo/scopeguard@1.2.0/Cargo.toml +43 -0
  558. package/third-party/cargo/scopeguard@1.2.0/LICENSE-APACHE +201 -0
  559. package/third-party/cargo/scopeguard@1.2.0/LICENSE-MIT +25 -0
  560. package/third-party/cargo/self_cell@1.2.2/Cargo.toml +33 -0
  561. package/third-party/cargo/self_cell@1.2.2/LICENSE-APACHE +201 -0
  562. package/third-party/cargo/self_cell@1.2.2/LICENSE-GPLv2 +339 -0
  563. package/third-party/cargo/self_cell@1.3.0/Cargo.toml +33 -0
  564. package/third-party/cargo/self_cell@1.3.0/LICENSE-APACHE +201 -0
  565. package/third-party/cargo/self_cell@1.3.0/LICENSE-GPLv2 +339 -0
  566. package/third-party/cargo/serde@1.0.228/Cargo.toml +84 -0
  567. package/third-party/cargo/serde@1.0.228/LICENSE-APACHE +176 -0
  568. package/third-party/cargo/serde@1.0.228/LICENSE-MIT +23 -0
  569. package/third-party/cargo/serde_core@1.0.228/Cargo.toml +87 -0
  570. package/third-party/cargo/serde_core@1.0.228/LICENSE-APACHE +176 -0
  571. package/third-party/cargo/serde_core@1.0.228/LICENSE-MIT +23 -0
  572. package/third-party/cargo/serde_derive@1.0.228/Cargo.toml +87 -0
  573. package/third-party/cargo/serde_derive@1.0.228/LICENSE-APACHE +176 -0
  574. package/third-party/cargo/serde_derive@1.0.228/LICENSE-MIT +23 -0
  575. package/third-party/cargo/serde_json@1.0.150/Cargo.toml +162 -0
  576. package/third-party/cargo/serde_json@1.0.150/LICENSE-APACHE +176 -0
  577. package/third-party/cargo/serde_json@1.0.150/LICENSE-MIT +23 -0
  578. package/third-party/cargo/simd-adler32@0.3.10/Cargo.toml +68 -0
  579. package/third-party/cargo/simd-adler32@0.3.10/LICENSE.md +21 -0
  580. package/third-party/cargo/simplecss@0.2.2/Cargo.toml +146 -0
  581. package/third-party/cargo/simplecss@0.2.2/LICENSE-APACHE +201 -0
  582. package/third-party/cargo/simplecss@0.2.2/LICENSE-MIT +21 -0
  583. package/third-party/cargo/siphasher@1.0.3/COPYING +7 -0
  584. package/third-party/cargo/siphasher@1.0.3/Cargo.toml +64 -0
  585. package/third-party/cargo/skrifa@0.40.0/Cargo.toml +86 -0
  586. package/third-party/cargo/skrifa@0.40.0/LICENSE-APACHE +67 -0
  587. package/third-party/cargo/skrifa@0.40.0/LICENSE-MIT +25 -0
  588. package/third-party/cargo/skrifa@0.42.1/Cargo.toml +86 -0
  589. package/third-party/cargo/skrifa@0.42.1/LICENSE-APACHE +67 -0
  590. package/third-party/cargo/skrifa@0.42.1/LICENSE-MIT +25 -0
  591. package/third-party/cargo/slab@0.4.12/Cargo.toml +67 -0
  592. package/third-party/cargo/slab@0.4.12/LICENSE +25 -0
  593. package/third-party/cargo/slotmap@1.1.1/Cargo.toml +83 -0
  594. package/third-party/cargo/slotmap@1.1.1/LICENSE +19 -0
  595. package/third-party/cargo/smallvec@1.15.2/Cargo.toml +103 -0
  596. package/third-party/cargo/smallvec@1.15.2/LICENSE-APACHE +201 -0
  597. package/third-party/cargo/smallvec@1.15.2/LICENSE-MIT +25 -0
  598. package/third-party/cargo/smol_str@0.3.6/Cargo.toml +155 -0
  599. package/third-party/cargo/smol_str@0.3.6/LICENSE-APACHE +201 -0
  600. package/third-party/cargo/smol_str@0.3.6/LICENSE-MIT +23 -0
  601. package/third-party/cargo/spirv@0.4.0+sdk-1.4.341.0/Cargo.toml +56 -0
  602. package/third-party/cargo/spirv@0.4.0+sdk-1.4.341.0/gfx-rs-rspirv-8afc3d0ac8e1-LICENSE +202 -0
  603. package/third-party/cargo/static_assertions@1.1.0/Cargo.toml +39 -0
  604. package/third-party/cargo/static_assertions@1.1.0/LICENSE-APACHE +202 -0
  605. package/third-party/cargo/static_assertions@1.1.0/LICENSE-MIT +21 -0
  606. package/third-party/cargo/strict-num@0.1.1/Cargo.toml +35 -0
  607. package/third-party/cargo/strict-num@0.1.1/LICENSE +19 -0
  608. package/third-party/cargo/svgtypes@0.16.1/Cargo.toml +57 -0
  609. package/third-party/cargo/svgtypes@0.16.1/LICENSE-APACHE +201 -0
  610. package/third-party/cargo/svgtypes@0.16.1/LICENSE-MIT +20 -0
  611. package/third-party/cargo/swash@0.2.9/Cargo.toml +93 -0
  612. package/third-party/cargo/swash@0.2.9/LICENSE-APACHE +201 -0
  613. package/third-party/cargo/swash@0.2.9/LICENSE-MIT +25 -0
  614. package/third-party/cargo/syn@2.0.118/Cargo.toml +272 -0
  615. package/third-party/cargo/syn@2.0.118/LICENSE-APACHE +176 -0
  616. package/third-party/cargo/syn@2.0.118/LICENSE-MIT +23 -0
  617. package/third-party/cargo/sys-locale@0.3.2/Cargo.toml +73 -0
  618. package/third-party/cargo/sys-locale@0.3.2/LICENSE-APACHE +201 -0
  619. package/third-party/cargo/sys-locale@0.3.2/LICENSE-MIT +21 -0
  620. package/third-party/cargo/taffy@0.12.1/Cargo.toml +171 -0
  621. package/third-party/cargo/taffy@0.12.1/DioxusLabs-taffy-1c9e37a0a1cf-LICENSE.md +25 -0
  622. package/third-party/cargo/tempfile@3.27.0/Cargo.toml +105 -0
  623. package/third-party/cargo/tempfile@3.27.0/LICENSE-APACHE +201 -0
  624. package/third-party/cargo/tempfile@3.27.0/LICENSE-MIT +25 -0
  625. package/third-party/cargo/termcolor@1.4.1/COPYING +3 -0
  626. package/third-party/cargo/termcolor@1.4.1/Cargo.toml +40 -0
  627. package/third-party/cargo/termcolor@1.4.1/LICENSE-MIT +21 -0
  628. package/third-party/cargo/termcolor@1.4.1/UNLICENSE +24 -0
  629. package/third-party/cargo/thiserror-impl@2.0.18/Cargo.toml +52 -0
  630. package/third-party/cargo/thiserror-impl@2.0.18/LICENSE-APACHE +176 -0
  631. package/third-party/cargo/thiserror-impl@2.0.18/LICENSE-MIT +23 -0
  632. package/third-party/cargo/thiserror@2.0.18/Cargo.toml +119 -0
  633. package/third-party/cargo/thiserror@2.0.18/LICENSE-APACHE +176 -0
  634. package/third-party/cargo/thiserror@2.0.18/LICENSE-MIT +23 -0
  635. package/third-party/cargo/tiny-skia-path@0.12.0/Cargo.toml +58 -0
  636. package/third-party/cargo/tiny-skia-path@0.12.0/LICENSE +30 -0
  637. package/third-party/cargo/tiny-skia@0.12.0/Cargo.toml +116 -0
  638. package/third-party/cargo/tiny-skia@0.12.0/LICENSE +30 -0
  639. package/third-party/cargo/tiny_http@0.12.0/Cargo.toml +82 -0
  640. package/third-party/cargo/tiny_http@0.12.0/LICENSE-APACHE +201 -0
  641. package/third-party/cargo/tiny_http@0.12.0/LICENSE-MIT +25 -0
  642. package/third-party/cargo/tinyvec@1.12.0/Cargo.toml +184 -0
  643. package/third-party/cargo/tinyvec@1.12.0/LICENSE-APACHE.md +202 -0
  644. package/third-party/cargo/tinyvec@1.12.0/LICENSE-MIT.md +5 -0
  645. package/third-party/cargo/tinyvec@1.12.0/LICENSE-ZLIB.md +11 -0
  646. package/third-party/cargo/tinyvec_macros@0.1.1/Cargo.toml +19 -0
  647. package/third-party/cargo/tinyvec_macros@0.1.1/LICENSE-APACHE.md +202 -0
  648. package/third-party/cargo/tinyvec_macros@0.1.1/LICENSE-MIT.md +21 -0
  649. package/third-party/cargo/tinyvec_macros@0.1.1/LICENSE-ZLIB.md +20 -0
  650. package/third-party/cargo/ttf-parser@0.25.1/Cargo.toml +101 -0
  651. package/third-party/cargo/ttf-parser@0.25.1/LICENSE-APACHE +201 -0
  652. package/third-party/cargo/ttf-parser@0.25.1/LICENSE-MIT +20 -0
  653. package/third-party/cargo/unicode-bidi-mirroring@0.4.0/Cargo.toml +22 -0
  654. package/third-party/cargo/unicode-bidi-mirroring@0.4.0/LICENSE-APACHE +201 -0
  655. package/third-party/cargo/unicode-bidi-mirroring@0.4.0/LICENSE-MIT +21 -0
  656. package/third-party/cargo/unicode-bidi@0.3.18/COPYRIGHT +8 -0
  657. package/third-party/cargo/unicode-bidi@0.3.18/Cargo.toml +90 -0
  658. package/third-party/cargo/unicode-bidi@0.3.18/LICENSE-APACHE +201 -0
  659. package/third-party/cargo/unicode-bidi@0.3.18/LICENSE-MIT +25 -0
  660. package/third-party/cargo/unicode-ccc@0.4.0/Cargo.toml +22 -0
  661. package/third-party/cargo/unicode-ccc@0.4.0/LICENSE-APACHE +201 -0
  662. package/third-party/cargo/unicode-ccc@0.4.0/LICENSE-MIT +21 -0
  663. package/third-party/cargo/unicode-ident@1.0.24/Cargo.toml +84 -0
  664. package/third-party/cargo/unicode-ident@1.0.24/LICENSE-APACHE +176 -0
  665. package/third-party/cargo/unicode-ident@1.0.24/LICENSE-MIT +23 -0
  666. package/third-party/cargo/unicode-ident@1.0.24/LICENSE-UNICODE +39 -0
  667. package/third-party/cargo/unicode-linebreak@0.1.5/Cargo.toml +32 -0
  668. package/third-party/cargo/unicode-linebreak@0.1.5/LICENSE +201 -0
  669. package/third-party/cargo/unicode-properties@0.1.4/COPYRIGHT +7 -0
  670. package/third-party/cargo/unicode-properties@0.1.4/Cargo.toml +65 -0
  671. package/third-party/cargo/unicode-properties@0.1.4/LICENSE-APACHE +201 -0
  672. package/third-party/cargo/unicode-properties@0.1.4/LICENSE-MIT +25 -0
  673. package/third-party/cargo/unicode-script@0.5.8/Cargo.toml +63 -0
  674. package/third-party/cargo/unicode-script@0.5.8/LICENSE-APACHE +201 -0
  675. package/third-party/cargo/unicode-script@0.5.8/LICENSE-MIT +27 -0
  676. package/third-party/cargo/unicode-segmentation@1.13.3/COPYRIGHT +7 -0
  677. package/third-party/cargo/unicode-segmentation@1.13.3/Cargo.toml +91 -0
  678. package/third-party/cargo/unicode-segmentation@1.13.3/LICENSE-APACHE +201 -0
  679. package/third-party/cargo/unicode-segmentation@1.13.3/LICENSE-MIT +25 -0
  680. package/third-party/cargo/unicode-vo@0.1.0/Cargo.toml +22 -0
  681. package/third-party/cargo/unicode-vo@0.1.0/LICENSE-APACHE +201 -0
  682. package/third-party/cargo/unicode-vo@0.1.0/LICENSE-MIT +21 -0
  683. package/third-party/cargo/unicode-width@0.2.2/COPYRIGHT +7 -0
  684. package/third-party/cargo/unicode-width@0.2.2/Cargo.toml +77 -0
  685. package/third-party/cargo/unicode-width@0.2.2/LICENSE-APACHE +201 -0
  686. package/third-party/cargo/unicode-width@0.2.2/LICENSE-MIT +25 -0
  687. package/third-party/cargo/unicode-xid@0.2.6/COPYRIGHT +7 -0
  688. package/third-party/cargo/unicode-xid@0.2.6/Cargo.toml +65 -0
  689. package/third-party/cargo/unicode-xid@0.2.6/LICENSE-APACHE +201 -0
  690. package/third-party/cargo/unicode-xid@0.2.6/LICENSE-MIT +25 -0
  691. package/third-party/cargo/urlencoding@2.1.3/Cargo.toml +41 -0
  692. package/third-party/cargo/urlencoding@2.1.3/LICENSE +20 -0
  693. package/third-party/cargo/usvg@0.47.0/Cargo.toml +138 -0
  694. package/third-party/cargo/usvg@0.47.0/LICENSE-APACHE +176 -0
  695. package/third-party/cargo/usvg@0.47.0/LICENSE-MIT +25 -0
  696. package/third-party/cargo/version_check@0.9.5/Cargo.toml +38 -0
  697. package/third-party/cargo/version_check@0.9.5/LICENSE-APACHE +201 -0
  698. package/third-party/cargo/version_check@0.9.5/LICENSE-MIT +19 -0
  699. package/third-party/cargo/wasm-bindgen-futures@0.4.76/Cargo.toml +88 -0
  700. package/third-party/cargo/wasm-bindgen-futures@0.4.76/LICENSE-APACHE +201 -0
  701. package/third-party/cargo/wasm-bindgen-futures@0.4.76/LICENSE-MIT +25 -0
  702. package/third-party/cargo/wasm-bindgen-macro-support@0.2.126/Cargo.toml +83 -0
  703. package/third-party/cargo/wasm-bindgen-macro-support@0.2.126/LICENSE-APACHE +201 -0
  704. package/third-party/cargo/wasm-bindgen-macro-support@0.2.126/LICENSE-MIT +25 -0
  705. package/third-party/cargo/wasm-bindgen-macro@0.2.126/Cargo.toml +73 -0
  706. package/third-party/cargo/wasm-bindgen-macro@0.2.126/LICENSE-APACHE +201 -0
  707. package/third-party/cargo/wasm-bindgen-macro@0.2.126/LICENSE-MIT +25 -0
  708. package/third-party/cargo/wasm-bindgen-shared@0.2.126/Cargo.toml +66 -0
  709. package/third-party/cargo/wasm-bindgen-shared@0.2.126/LICENSE-APACHE +201 -0
  710. package/third-party/cargo/wasm-bindgen-shared@0.2.126/LICENSE-MIT +25 -0
  711. package/third-party/cargo/wasm-bindgen@0.2.126/Cargo.toml +122 -0
  712. package/third-party/cargo/wasm-bindgen@0.2.126/LICENSE-APACHE +201 -0
  713. package/third-party/cargo/wasm-bindgen@0.2.126/LICENSE-MIT +25 -0
  714. package/third-party/cargo/wayland-sys@0.31.11/Cargo.toml +81 -0
  715. package/third-party/cargo/wayland-sys@0.31.11/LICENSE.txt +19 -0
  716. package/third-party/cargo/web-sys@0.3.103/Cargo.toml +2823 -0
  717. package/third-party/cargo/web-sys@0.3.103/LICENSE-APACHE +201 -0
  718. package/third-party/cargo/web-sys@0.3.103/LICENSE-MIT +25 -0
  719. package/third-party/cargo/weezl@0.1.12/Cargo.toml +120 -0
  720. package/third-party/cargo/weezl@0.1.12/LICENSE-APACHE +201 -0
  721. package/third-party/cargo/weezl@0.1.12/LICENSE-MIT +22 -0
  722. package/third-party/cargo/wgpu-core-deps-apple@30.0.0/Cargo.toml +53 -0
  723. package/third-party/cargo/wgpu-core-deps-apple@30.0.0/LICENSE.APACHE +176 -0
  724. package/third-party/cargo/wgpu-core-deps-apple@30.0.0/LICENSE.MIT +21 -0
  725. package/third-party/cargo/wgpu-core@30.0.0/Cargo.toml +237 -0
  726. package/third-party/cargo/wgpu-core@30.0.0/LICENSE.APACHE +176 -0
  727. package/third-party/cargo/wgpu-core@30.0.0/LICENSE.MIT +21 -0
  728. package/third-party/cargo/wgpu-hal@30.0.0/Cargo.toml +541 -0
  729. package/third-party/cargo/wgpu-hal@30.0.0/LICENSE.APACHE +176 -0
  730. package/third-party/cargo/wgpu-hal@30.0.0/LICENSE.MIT +21 -0
  731. package/third-party/cargo/wgpu-naga-bridge@30.0.0/Cargo.toml +46 -0
  732. package/third-party/cargo/wgpu-naga-bridge@30.0.0/LICENSE.APACHE +176 -0
  733. package/third-party/cargo/wgpu-naga-bridge@30.0.0/LICENSE.MIT +21 -0
  734. package/third-party/cargo/wgpu-types@30.0.0/Cargo.toml +161 -0
  735. package/third-party/cargo/wgpu-types@30.0.0/LICENSE.APACHE +176 -0
  736. package/third-party/cargo/wgpu-types@30.0.0/LICENSE.MIT +21 -0
  737. package/third-party/cargo/wgpu@30.0.0/Cargo.toml +278 -0
  738. package/third-party/cargo/wgpu@30.0.0/LICENSE.APACHE +176 -0
  739. package/third-party/cargo/wgpu@30.0.0/LICENSE.MIT +21 -0
  740. package/third-party/cargo/xmlwriter@0.1.0/Cargo.toml +23 -0
  741. package/third-party/cargo/xmlwriter@0.1.0/LICENSE +21 -0
  742. package/third-party/cargo/yazi@0.2.1/Cargo.toml +45 -0
  743. package/third-party/cargo/yazi@0.2.1/LICENSE-APACHE +201 -0
  744. package/third-party/cargo/yazi@0.2.1/LICENSE-MIT +19 -0
  745. package/third-party/cargo/zeno@0.3.3/Cargo.toml +65 -0
  746. package/third-party/cargo/zeno@0.3.3/LICENSE-APACHE +201 -0
  747. package/third-party/cargo/zeno@0.3.3/LICENSE-MIT +25 -0
  748. package/third-party/cargo/zerocopy-derive@0.8.54/Cargo.toml +209 -0
  749. package/third-party/cargo/zerocopy-derive@0.8.54/LICENSE-APACHE +202 -0
  750. package/third-party/cargo/zerocopy-derive@0.8.54/LICENSE-BSD +24 -0
  751. package/third-party/cargo/zerocopy-derive@0.8.54/LICENSE-MIT +26 -0
  752. package/third-party/cargo/zerocopy@0.8.54/Cargo.toml +419 -0
  753. package/third-party/cargo/zerocopy@0.8.54/LICENSE-APACHE +202 -0
  754. package/third-party/cargo/zerocopy@0.8.54/LICENSE-BSD +24 -0
  755. package/third-party/cargo/zerocopy@0.8.54/LICENSE-MIT +26 -0
  756. package/third-party/cargo/zmij@1.0.23/Cargo.toml +90 -0
  757. package/third-party/cargo/zmij@1.0.23/LICENSE-MIT +23 -0
  758. package/third-party/cargo/zune-core@0.5.1/Cargo.toml +47 -0
  759. package/third-party/cargo/zune-core@0.5.1/LICENSE-APACHE +201 -0
  760. package/third-party/cargo/zune-core@0.5.1/LICENSE-MIT +21 -0
  761. package/third-party/cargo/zune-core@0.5.1/LICENSE-ZLIB +19 -0
  762. package/third-party/cargo/zune-jpeg@0.5.15/Cargo.toml +67 -0
  763. package/third-party/cargo/zune-jpeg@0.5.15/LICENSE-APACHE +201 -0
  764. package/third-party/cargo/zune-jpeg@0.5.15/LICENSE-MIT +21 -0
  765. package/third-party/cargo/zune-jpeg@0.5.15/LICENSE-ZLIB +19 -0
  766. package/third-party/inventory.json +3614 -0
  767. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/esbuild-0.27.4-LICENSE.md +21 -0
  768. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/go-LICENSE +27 -0
  769. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/golang-x-sys-c0bba94af5f8-LICENSE +27 -0
  770. package/third-party/npm/@esbuild__darwin-arm64@0.27.4/package.json +20 -0
  771. package/third-party/npm/@floating-ui__core@1.7.5/LICENSE +20 -0
  772. package/third-party/npm/@floating-ui__core@1.7.5/package.json +63 -0
  773. package/third-party/npm/@floating-ui__dom@1.7.6/LICENSE +20 -0
  774. package/third-party/npm/@floating-ui__dom@1.7.6/package.json +71 -0
  775. package/third-party/npm/@floating-ui__react-dom@2.1.8/LICENSE +20 -0
  776. package/third-party/npm/@floating-ui__react-dom@2.1.8/package.json +76 -0
  777. package/third-party/npm/@floating-ui__utils@0.2.11/LICENSE +20 -0
  778. package/third-party/npm/@floating-ui__utils@0.2.11/package.json +70 -0
  779. package/third-party/npm/@radix-ui__primitive@1.1.7/LICENSE +21 -0
  780. package/third-party/npm/@radix-ui__primitive@1.1.7/package.json +79 -0
  781. package/third-party/npm/@radix-ui__react-arrow@1.1.15/LICENSE +21 -0
  782. package/third-party/npm/@radix-ui__react-arrow@1.1.15/package.json +68 -0
  783. package/third-party/npm/@radix-ui__react-collection@1.1.15/LICENSE +21 -0
  784. package/third-party/npm/@radix-ui__react-collection@1.1.15/package.json +71 -0
  785. package/third-party/npm/@radix-ui__react-compose-refs@1.1.5/LICENSE +21 -0
  786. package/third-party/npm/@radix-ui__react-compose-refs@1.1.5/package.json +60 -0
  787. package/third-party/npm/@radix-ui__react-context-menu@2.3.7/LICENSE +21 -0
  788. package/third-party/npm/@radix-ui__react-context-menu@2.3.7/package.json +73 -0
  789. package/third-party/npm/@radix-ui__react-context@1.2.2/LICENSE +21 -0
  790. package/third-party/npm/@radix-ui__react-context@1.2.2/package.json +60 -0
  791. package/third-party/npm/@radix-ui__react-direction@1.1.4/LICENSE +21 -0
  792. package/third-party/npm/@radix-ui__react-direction@1.1.4/package.json +60 -0
  793. package/third-party/npm/@radix-ui__react-dismissable-layer@1.1.19/LICENSE +21 -0
  794. package/third-party/npm/@radix-ui__react-dismissable-layer@1.1.19/package.json +74 -0
  795. package/third-party/npm/@radix-ui__react-focus-guards@1.1.6/LICENSE +21 -0
  796. package/third-party/npm/@radix-ui__react-focus-guards@1.1.6/package.json +60 -0
  797. package/third-party/npm/@radix-ui__react-focus-scope@1.1.16/LICENSE +21 -0
  798. package/third-party/npm/@radix-ui__react-focus-scope@1.1.16/package.json +71 -0
  799. package/third-party/npm/@radix-ui__react-id@1.1.4/LICENSE +21 -0
  800. package/third-party/npm/@radix-ui__react-id@1.1.4/package.json +63 -0
  801. package/third-party/npm/@radix-ui__react-menu@2.1.24/LICENSE +21 -0
  802. package/third-party/npm/@radix-ui__react-menu@2.1.24/package.json +86 -0
  803. package/third-party/npm/@radix-ui__react-popper@1.3.7/LICENSE +21 -0
  804. package/third-party/npm/@radix-ui__react-popper@1.3.7/package.json +78 -0
  805. package/third-party/npm/@radix-ui__react-portal@1.1.17/LICENSE +21 -0
  806. package/third-party/npm/@radix-ui__react-portal@1.1.17/package.json +69 -0
  807. package/third-party/npm/@radix-ui__react-presence@1.1.10/LICENSE +21 -0
  808. package/third-party/npm/@radix-ui__react-presence@1.1.10/package.json +68 -0
  809. package/third-party/npm/@radix-ui__react-primitive@2.1.10/LICENSE +21 -0
  810. package/third-party/npm/@radix-ui__react-primitive@2.1.10/package.json +68 -0
  811. package/third-party/npm/@radix-ui__react-roving-focus@1.1.19/LICENSE +21 -0
  812. package/third-party/npm/@radix-ui__react-roving-focus@1.1.19/package.json +78 -0
  813. package/third-party/npm/@radix-ui__react-slot@1.3.3/LICENSE +21 -0
  814. package/third-party/npm/@radix-ui__react-slot@1.3.3/package.json +63 -0
  815. package/third-party/npm/@radix-ui__react-use-callback-ref@1.1.4/LICENSE +21 -0
  816. package/third-party/npm/@radix-ui__react-use-callback-ref@1.1.4/package.json +60 -0
  817. package/third-party/npm/@radix-ui__react-use-controllable-state@1.2.6/LICENSE +21 -0
  818. package/third-party/npm/@radix-ui__react-use-controllable-state@1.2.6/package.json +65 -0
  819. package/third-party/npm/@radix-ui__react-use-effect-event@0.0.5/LICENSE +21 -0
  820. package/third-party/npm/@radix-ui__react-use-effect-event@0.0.5/package.json +65 -0
  821. package/third-party/npm/@radix-ui__react-use-is-hydrated@0.1.3/LICENSE +21 -0
  822. package/third-party/npm/@radix-ui__react-use-is-hydrated@0.1.3/package.json +61 -0
  823. package/third-party/npm/@radix-ui__react-use-layout-effect@1.1.4/LICENSE +21 -0
  824. package/third-party/npm/@radix-ui__react-use-layout-effect@1.1.4/package.json +60 -0
  825. package/third-party/npm/@radix-ui__react-use-size@1.1.4/LICENSE +21 -0
  826. package/third-party/npm/@radix-ui__react-use-size@1.1.4/package.json +63 -0
  827. package/third-party/npm/aria-hidden@1.2.6/LICENSE +21 -0
  828. package/third-party/npm/aria-hidden@1.2.6/package.json +71 -0
  829. package/third-party/npm/detect-node-es@1.1.0/LICENSE +21 -0
  830. package/third-party/npm/detect-node-es@1.1.0/package.json +29 -0
  831. package/third-party/npm/esbuild@0.27.4/LICENSE.md +21 -0
  832. package/third-party/npm/esbuild@0.27.4/package.json +49 -0
  833. package/third-party/npm/fflate@0.8.3/LICENSE +21 -0
  834. package/third-party/npm/fflate@0.8.3/package.json +128 -0
  835. package/third-party/npm/get-nonce@1.0.1/LICENSE +21 -0
  836. package/third-party/npm/get-nonce@1.0.1/package.json +68 -0
  837. package/third-party/npm/mediabunny@1.52.2/LICENSE +373 -0
  838. package/third-party/npm/mediabunny@1.52.2/package.json +136 -0
  839. package/third-party/npm/mediabunny@1.52.2/source/LICENSE +373 -0
  840. package/third-party/npm/mediabunny@1.52.2/source/package.json +136 -0
  841. package/third-party/npm/mediabunny@1.52.2/source/src/adts/adts-demuxer.ts +400 -0
  842. package/third-party/npm/mediabunny@1.52.2/source/src/adts/adts-muxer.ts +124 -0
  843. package/third-party/npm/mediabunny@1.52.2/source/src/adts/adts-reader.ts +85 -0
  844. package/third-party/npm/mediabunny@1.52.2/source/src/aes.ts +307 -0
  845. package/third-party/npm/mediabunny@1.52.2/source/src/codec-data.ts +3178 -0
  846. package/third-party/npm/mediabunny@1.52.2/source/src/codec.ts +1154 -0
  847. package/third-party/npm/mediabunny@1.52.2/source/src/conversion.ts +2042 -0
  848. package/third-party/npm/mediabunny@1.52.2/source/src/custom-coder.ts +212 -0
  849. package/third-party/npm/mediabunny@1.52.2/source/src/decode.ts +263 -0
  850. package/third-party/npm/mediabunny@1.52.2/source/src/demuxer.ts +43 -0
  851. package/third-party/npm/mediabunny@1.52.2/source/src/encode.ts +1412 -0
  852. package/third-party/npm/mediabunny@1.52.2/source/src/flac/flac-demuxer.ts +813 -0
  853. package/third-party/npm/mediabunny@1.52.2/source/src/flac/flac-misc.ts +165 -0
  854. package/third-party/npm/mediabunny@1.52.2/source/src/flac/flac-muxer.ts +350 -0
  855. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-demuxer.ts +995 -0
  856. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-misc.ts +81 -0
  857. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-muxer.ts +1529 -0
  858. package/third-party/npm/mediabunny@1.52.2/source/src/hls/hls-segmented-input.ts +772 -0
  859. package/third-party/npm/mediabunny@1.52.2/source/src/id3.ts +972 -0
  860. package/third-party/npm/mediabunny@1.52.2/source/src/index.ts +319 -0
  861. package/third-party/npm/mediabunny@1.52.2/source/src/input-format.ts +819 -0
  862. package/third-party/npm/mediabunny@1.52.2/source/src/input-track.ts +1141 -0
  863. package/third-party/npm/mediabunny@1.52.2/source/src/input.ts +571 -0
  864. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-boxes.ts +1911 -0
  865. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-demuxer.ts +3953 -0
  866. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-misc.ts +90 -0
  867. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-muxer.ts +1595 -0
  868. package/third-party/npm/mediabunny@1.52.2/source/src/isobmff/isobmff-reader.ts +91 -0
  869. package/third-party/npm/mediabunny@1.52.2/source/src/logging.ts +120 -0
  870. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/ebml.ts +770 -0
  871. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/matroska-demuxer.ts +2598 -0
  872. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/matroska-misc.ts +29 -0
  873. package/third-party/npm/mediabunny@1.52.2/source/src/matroska/matroska-muxer.ts +1360 -0
  874. package/third-party/npm/mediabunny@1.52.2/source/src/media-sink.ts +2589 -0
  875. package/third-party/npm/mediabunny@1.52.2/source/src/media-source.ts +3041 -0
  876. package/third-party/npm/mediabunny@1.52.2/source/src/metadata.ts +335 -0
  877. package/third-party/npm/mediabunny@1.52.2/source/src/misc.ts +1336 -0
  878. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-demuxer.ts +469 -0
  879. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-muxer.ts +169 -0
  880. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-reader.ts +61 -0
  881. package/third-party/npm/mediabunny@1.52.2/source/src/mp3/mp3-writer.ts +121 -0
  882. package/third-party/npm/mediabunny@1.52.2/source/src/mpeg-ts/mpeg-ts-demuxer.ts +2519 -0
  883. package/third-party/npm/mediabunny@1.52.2/source/src/mpeg-ts/mpeg-ts-misc.ts +32 -0
  884. package/third-party/npm/mediabunny@1.52.2/source/src/mpeg-ts/mpeg-ts-muxer.ts +842 -0
  885. package/third-party/npm/mediabunny@1.52.2/source/src/muxer.ts +80 -0
  886. package/third-party/npm/mediabunny@1.52.2/source/src/node.ts +11 -0
  887. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-demuxer.ts +1087 -0
  888. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-misc.ts +116 -0
  889. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-muxer.ts +527 -0
  890. package/third-party/npm/mediabunny@1.52.2/source/src/ogg/ogg-reader.ts +93 -0
  891. package/third-party/npm/mediabunny@1.52.2/source/src/output-format.ts +1425 -0
  892. package/third-party/npm/mediabunny@1.52.2/source/src/output.ts +940 -0
  893. package/third-party/npm/mediabunny@1.52.2/source/src/packet.ts +287 -0
  894. package/third-party/npm/mediabunny@1.52.2/source/src/pcm.ts +112 -0
  895. package/third-party/npm/mediabunny@1.52.2/source/src/reader.ts +391 -0
  896. package/third-party/npm/mediabunny@1.52.2/source/src/resample.ts +287 -0
  897. package/third-party/npm/mediabunny@1.52.2/source/src/sample.ts +3231 -0
  898. package/third-party/npm/mediabunny@1.52.2/source/src/segmented-input.ts +575 -0
  899. package/third-party/npm/mediabunny@1.52.2/source/src/source.ts +2588 -0
  900. package/third-party/npm/mediabunny@1.52.2/source/src/subtitles.ts +131 -0
  901. package/third-party/npm/mediabunny@1.52.2/source/src/target.ts +871 -0
  902. package/third-party/npm/mediabunny@1.52.2/source/src/tsconfig.json +16 -0
  903. package/third-party/npm/mediabunny@1.52.2/source/src/wave/riff-writer.ts +36 -0
  904. package/third-party/npm/mediabunny@1.52.2/source/src/wave/wave-demuxer.ts +583 -0
  905. package/third-party/npm/mediabunny@1.52.2/source/src/wave/wave-muxer.ts +375 -0
  906. package/third-party/npm/mediabunny@1.52.2/source/src/writer.ts +128 -0
  907. package/third-party/npm/react-dom@19.3.0/LICENSE +21 -0
  908. package/third-party/npm/react-dom@19.3.0/package.json +117 -0
  909. package/third-party/npm/react-remove-scroll-bar@2.3.8/package.json +85 -0
  910. package/third-party/npm/react-remove-scroll-bar@2.3.8/react-remove-scroll-bar-LICENSE +21 -0
  911. package/third-party/npm/react-remove-scroll@2.7.2/LICENSE +21 -0
  912. package/third-party/npm/react-remove-scroll@2.7.2/package.json +98 -0
  913. package/third-party/npm/react-style-singleton@2.2.3/LICENSE +21 -0
  914. package/third-party/npm/react-style-singleton@2.2.3/package.json +90 -0
  915. package/third-party/npm/react@19.3.0/LICENSE +21 -0
  916. package/third-party/npm/react@19.3.0/package.json +51 -0
  917. package/third-party/npm/scheduler@0.28.0/LICENSE +21 -0
  918. package/third-party/npm/scheduler@0.28.0/package.json +27 -0
  919. package/third-party/npm/tslib@2.8.1/LICENSE.txt +12 -0
  920. package/third-party/npm/tslib@2.8.1/package.json +47 -0
  921. package/third-party/npm/typescript@5.9.3/LICENSE.txt +55 -0
  922. package/third-party/npm/typescript@5.9.3/ThirdPartyNoticeText.txt +193 -0
  923. package/third-party/npm/typescript@5.9.3/package.json +120 -0
  924. package/third-party/npm/use-callback-ref@1.3.3/LICENSE +21 -0
  925. package/third-party/npm/use-callback-ref@1.3.3/package.json +85 -0
  926. package/third-party/npm/use-sidecar@1.1.3/LICENSE +21 -0
  927. package/third-party/npm/use-sidecar@1.1.3/package.json +93 -0
  928. package/third-party/packages/render-engine/assets/OFL.txt +93 -0
  929. package/third-party/packages/studio/public/fonts/OFL.txt +93 -0
  930. package/third-party/packages/studio/vendor/osmo-icons/LICENSE +21 -0
  931. package/third-party/packages/studio/vendor/shadcn/LICENSE +21 -0
  932. package/third-party/repository-notices.md +41 -0
  933. package/third-party/rust-standard-library/COPYRIGHT-library.html +5556 -0
  934. package/third-party/rust-standard-library/licenses/Apache-2.0.txt +73 -0
  935. package/third-party/rust-standard-library/licenses/BSD-2-Clause.txt +9 -0
  936. package/third-party/rust-standard-library/licenses/CC-BY-SA-4.0.txt +427 -0
  937. package/third-party/rust-standard-library/licenses/GCC-exception-3.1.txt +30 -0
  938. package/third-party/rust-standard-library/licenses/GPL-2.0-only.txt +133 -0
  939. package/third-party/rust-standard-library/licenses/GPL-3.0-or-later.txt +202 -0
  940. package/third-party/rust-standard-library/licenses/ISC.txt +7 -0
  941. package/third-party/rust-standard-library/licenses/LLVM-exception.txt +15 -0
  942. package/third-party/rust-standard-library/licenses/MIT.txt +9 -0
  943. package/third-party/rust-standard-library/licenses/NCSA.txt +29 -0
  944. package/third-party/rust-standard-library/licenses/OFL-1.1.txt +43 -0
  945. package/third-party/rust-standard-library/licenses/Unicode-3.0.txt +39 -0
  946. package/third-party/rust-standard-library/version.txt +1 -0
  947. package/vendor/osmo-lite +0 -0
  948. package/vendor/osmo-scene-0.1.0.tgz +0 -0
  949. package/vendor/platform.json +1 -0
@@ -0,0 +1,2519 @@
1
+ /*!
2
+ * Copyright (c) 2026-present, Vanilagy and contributors
3
+ *
4
+ * This Source Code Form is subject to the terms of the Mozilla Public
5
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
6
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
+ */
8
+
9
+ import { TrackType } from '../output';
10
+ import { SAMPLES_PER_AAC_FRAME } from '../adts/adts-demuxer';
11
+ import { MAX_ADTS_FRAME_HEADER_SIZE, readAdtsFrameHeader } from '../adts/adts-reader';
12
+ import { aacChannelMap, aacFrequencyTable } from '../../shared/aac-misc';
13
+ import {
14
+ AacCodecInfo,
15
+ AudioCodec,
16
+ extractAudioCodecString,
17
+ extractVideoCodecString,
18
+ MediaCodec,
19
+ VideoCodec,
20
+ } from '../codec';
21
+ import {
22
+ AC3_ACMOD_CHANNEL_COUNTS,
23
+ AC3_SAMPLES_PER_FRAME,
24
+ AvcDecoderConfigurationRecord,
25
+ AvcNalUnitType,
26
+ determineVideoPacketType,
27
+ extractAvcDecoderConfigurationRecord,
28
+ extractHevcDecoderConfigurationRecord,
29
+ EAC3_NUMBLKS_TABLE,
30
+ getEac3ChannelCount,
31
+ getEac3SampleRate,
32
+ HevcDecoderConfigurationRecord,
33
+ HevcNalUnitType,
34
+ parseAc3SyncFrame,
35
+ parseAvcSps,
36
+ parseEac3SyncFrame,
37
+ parseHevcSps,
38
+ AC3_FRAME_SIZES,
39
+ extractNalUnitTypeForAvc,
40
+ extractNalUnitTypeForHevc,
41
+ } from '../codec-data';
42
+ import { Demuxer } from '../demuxer';
43
+ import { Input } from '../input';
44
+ import { Logging } from '../logging';
45
+ import {
46
+ InputAudioTrackBacking,
47
+ InputTrackBacking,
48
+ InputVideoTrackBacking,
49
+ } from '../input-track';
50
+ import { PacketRetrievalOptions } from '../media-sink';
51
+ import { DEFAULT_TRACK_DISPOSITION, MetadataTags, TrackDisposition } from '../metadata';
52
+ import {
53
+ assert,
54
+ binarySearchExact,
55
+ binarySearchLessOrEqual,
56
+ COLOR_PRIMARIES_MAP_INVERSE,
57
+ findLastIndex,
58
+ floorToMultiple,
59
+ last,
60
+ MATRIX_COEFFICIENTS_MAP_INVERSE,
61
+ readExpGolomb,
62
+ Rotation,
63
+ roundIfAlmostInteger,
64
+ toDataView,
65
+ TRANSFER_CHARACTERISTICS_MAP_INVERSE,
66
+ UNDETERMINED_LANGUAGE,
67
+ } from '../misc';
68
+ import {
69
+ MP3_FRAME_HEADER_SIZE,
70
+ getMp3ChannelCount,
71
+ readMp3FrameHeader,
72
+ } from '../../shared/mp3-misc';
73
+ import { EncodedPacket, PacketType, PLACEHOLDER_DATA } from '../packet';
74
+ import { FileSlice, readBytes, Reader, readU16Be, readU32Be, readU8 } from '../reader';
75
+ import { buildMpegTsMimeType, MpegTsStreamType, TIMESCALE, TS_PACKET_SIZE } from './mpeg-ts-misc';
76
+ import { AC3_SAMPLE_RATES } from '../../shared/ac3-misc';
77
+ import { Bitstream } from '../../shared/bitstream';
78
+
79
+ // Resources:
80
+ // ISO/IEC 13818-1
81
+
82
+ const MISSING_PTS_ERROR_MESSAGE = 'PES packet is missing PTS where it was expected. PES packets without PTS are not'
83
+ + ' currently supported. If you think this file should be supported, please report it.';
84
+
85
+ type ElementaryStream = {
86
+ demuxer: MpegTsDemuxer;
87
+ pid: number;
88
+ streamType: number;
89
+ initialized: boolean;
90
+ firstSection: Section | null;
91
+ /**
92
+ * Some muxers suck ass and don't correctly label key frames, meaning we'll need to use our skill to
93
+ * compensate for another programmer's skill issue.
94
+ */
95
+ canBeTrustedWithKeyPackets: boolean;
96
+ info: {
97
+ type: 'video';
98
+ codec: VideoCodec;
99
+ decoderConfig: VideoDecoderConfig | null;
100
+ avcCodecInfo: AvcDecoderConfigurationRecord | null;
101
+ hevcCodecInfo: HevcDecoderConfigurationRecord | null;
102
+ colorSpace: VideoColorSpaceInit;
103
+ width: number;
104
+ height: number;
105
+ squarePixelWidth: number;
106
+ squarePixelHeight: number;
107
+ reorderSize: number;
108
+ } | {
109
+ type: 'audio';
110
+ codec: AudioCodec;
111
+ decoderConfig: AudioDecoderConfig | null;
112
+ aacCodecInfo: AacCodecInfo | null;
113
+ numberOfChannels: number;
114
+ sampleRate: number;
115
+ };
116
+ /**
117
+ * Reference PES packets, spread throughout the file, to be used to speed up repeated random access. Sorted by both
118
+ * byte offset and PTS.
119
+ */
120
+ referencePesPackets: TimestampedPesPacketHeader[];
121
+ };
122
+
123
+ type ElementaryVideoStream = ElementaryStream & { info: { type: 'video' } };
124
+ type ElementaryAudioStream = ElementaryStream & { info: { type: 'audio' } };
125
+
126
+ type TsPacketHeader = {
127
+ payloadUnitStartIndicator: number;
128
+ pid: number;
129
+ adaptationFieldControl: number;
130
+ };
131
+
132
+ type TsPacket = TsPacketHeader & {
133
+ body: Uint8Array<ArrayBufferLike>;
134
+ };
135
+
136
+ type Section = {
137
+ startPos: number;
138
+ endPos: number | null; // null if the section was not read fully
139
+ pid: number;
140
+ payload: Uint8Array<ArrayBufferLike>;
141
+ randomAccessIndicator: number;
142
+ };
143
+
144
+ // Remember them so the warning doesn't get spammed
145
+ const ignoredStreamTypes = new Set<number>();
146
+
147
+ export class MpegTsDemuxer extends Demuxer {
148
+ reader: Reader;
149
+
150
+ metadataPromise: Promise<void> | null = null;
151
+ elementaryStreams: ElementaryStream[] = [];
152
+ trackBackingEntries: InputTrackBacking[] = [];
153
+ packetOffset = 0;
154
+ packetStride = -1;
155
+ sectionEndPositions: number[] = [];
156
+ seekChunkSize = 5 * 1024 * 1024; // 5 MiB, picked because most HLS segments are below this size
157
+ minReferencePointByteDistance = -1;
158
+
159
+ constructor(input: Input) {
160
+ super(input);
161
+
162
+ this.reader = input._reader;
163
+ }
164
+
165
+ async readMetadata() {
166
+ return this.metadataPromise ??= (async () => {
167
+ const lengthToCheck = TS_PACKET_SIZE + 16 + 1;
168
+ let startingSlice = this.reader.requestSlice(0, lengthToCheck);
169
+ if (startingSlice instanceof Promise) startingSlice = await startingSlice;
170
+ assert(startingSlice);
171
+
172
+ const startingBytes = readBytes(startingSlice, lengthToCheck);
173
+
174
+ if (startingBytes[0] === 0x47 && startingBytes[TS_PACKET_SIZE] === 0x47) {
175
+ // Regular MPEG-TS
176
+ this.packetOffset = 0;
177
+ this.packetStride = TS_PACKET_SIZE;
178
+ } else if (startingBytes[0] === 0x47 && startingBytes[TS_PACKET_SIZE + 16] === 0x47) {
179
+ // MPEG-TS with Forward Error Correction
180
+ this.packetOffset = 0;
181
+ this.packetStride = TS_PACKET_SIZE + 16;
182
+ } else if (startingBytes[4] === 0x47 && startingBytes[4 + TS_PACKET_SIZE + 4] === 0x47) {
183
+ // MPEG-2-TS (DVHS)
184
+ this.packetOffset = 4;
185
+ this.packetStride = TS_PACKET_SIZE + 4;
186
+ } else {
187
+ throw new Error('Unreachable.');
188
+ }
189
+
190
+ const MIN_REFERENCE_POINT_PACKET_DISTANCE = 256;
191
+ this.minReferencePointByteDistance = MIN_REFERENCE_POINT_PACKET_DISTANCE * this.packetStride;
192
+
193
+ let currentPos = this.packetOffset;
194
+ let programMapPid: number | null = null;
195
+ // Some files contain these multiple times, but we only care about their first appearance
196
+ let hasProgramAssociationTable = false;
197
+ let hasProgramMap = false;
198
+
199
+ while (true) {
200
+ const packetHeader = await this.readPacketHeader(currentPos);
201
+ if (!packetHeader) {
202
+ break;
203
+ }
204
+
205
+ if (packetHeader.payloadUnitStartIndicator === 0) {
206
+ // Not the start of a section
207
+ currentPos += this.packetStride;
208
+ continue;
209
+ }
210
+
211
+ if (hasProgramMap && !this.elementaryStreams.some(x => x.pid === packetHeader.pid)) {
212
+ // Don't care about this PID
213
+ currentPos += this.packetStride;
214
+ continue;
215
+ }
216
+
217
+ const section = await this.readSection(
218
+ currentPos,
219
+ true,
220
+ !hasProgramMap, // Expect contiguous sections as long as we don't have the PMT
221
+ );
222
+ if (!section) {
223
+ break;
224
+ }
225
+
226
+ const BYTES_BEFORE_SECTION_LENGTH = 3;
227
+ const BITS_IN_CRC_32 = 32; // Duh
228
+
229
+ // Some streams don't contain a PAT for some reason, so we must do some guesswork to figure out where
230
+ // the PMT is.
231
+ let isProbablyProgramMap = false;
232
+ if (!hasProgramMap && section.pid !== 0) {
233
+ const isPesPacket
234
+ = section.payload[0] === 0x00 && section.payload[1] === 0x00 && section.payload[2] === 0x01;
235
+
236
+ if (!isPesPacket) {
237
+ // Assume it's a PSI
238
+
239
+ const bitstream = new Bitstream(section.payload);
240
+ const pointerField = bitstream.readAlignedByte();
241
+
242
+ bitstream.skipBits(8 * pointerField);
243
+
244
+ const tableId = bitstream.readBits(8);
245
+ isProbablyProgramMap = tableId === 0x02; // 0x02 == TS_program_map_section
246
+ }
247
+ }
248
+
249
+ if (section.pid === 0 && !hasProgramAssociationTable) {
250
+ const bitstream = new Bitstream(section.payload);
251
+ const pointerField = bitstream.readAlignedByte();
252
+
253
+ bitstream.skipBits(8 * pointerField);
254
+
255
+ bitstream.skipBits(14);
256
+ const sectionLength = bitstream.readBits(10);
257
+
258
+ bitstream.skipBits(40);
259
+
260
+ while (8 * (sectionLength + BYTES_BEFORE_SECTION_LENGTH) - bitstream.pos > BITS_IN_CRC_32) {
261
+ const programNumber = bitstream.readBits(16);
262
+ bitstream.skipBits(3); // Reserved
263
+ const id = bitstream.readBits(13);
264
+
265
+ if (programNumber !== 0) {
266
+ if (programMapPid !== null) {
267
+ throw new Error('Only files with a single program are supported.');
268
+ } else {
269
+ programMapPid = id;
270
+ }
271
+ }
272
+ }
273
+
274
+ if (programMapPid === null) {
275
+ throw new Error('Program Association Table must link to a Program Map Table.');
276
+ }
277
+
278
+ hasProgramAssociationTable = true;
279
+ } else if ((section.pid === programMapPid || isProbablyProgramMap) && !hasProgramMap) {
280
+ const bitstream = new Bitstream(section.payload);
281
+ const pointerField = bitstream.readAlignedByte();
282
+
283
+ bitstream.skipBits(8 * pointerField);
284
+
285
+ bitstream.skipBits(12);
286
+ const sectionLength = bitstream.readBits(12);
287
+
288
+ bitstream.skipBits(43);
289
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
290
+ const pcrPid = bitstream.readBits(13);
291
+
292
+ bitstream.skipBits(6);
293
+
294
+ // "The remaining 10 bits specify the number of bytes of the descriptors immediately following the
295
+ // program_info_length field"
296
+ const programInfoLength = bitstream.readBits(10);
297
+ bitstream.skipBits(8 * programInfoLength);
298
+
299
+ while (8 * (sectionLength + BYTES_BEFORE_SECTION_LENGTH) - bitstream.pos > BITS_IN_CRC_32) {
300
+ const streamType = bitstream.readBits(8);
301
+ bitstream.skipBits(3);
302
+ const elementaryPid = bitstream.readBits(13);
303
+
304
+ bitstream.skipBits(6);
305
+ const esInfoLength = bitstream.readBits(10);
306
+
307
+ // Check ES descriptors to detect AC-3/E-AC-3 in System B
308
+ const esInfoEndPos = bitstream.pos + 8 * esInfoLength;
309
+ let hasAc3Descriptor = false;
310
+ let hasEac3Descriptor = false;
311
+ while (bitstream.pos < esInfoEndPos) {
312
+ const descriptorTag = bitstream.readBits(8);
313
+ const descriptorLength = bitstream.readBits(8);
314
+ if (descriptorTag === 0x6a) {
315
+ hasAc3Descriptor = true;
316
+ } else if (descriptorTag === 0x7a || descriptorTag === 0xcc) {
317
+ hasEac3Descriptor = true;
318
+ }
319
+ bitstream.skipBits(8 * descriptorLength);
320
+ }
321
+
322
+ let info: ElementaryStream['info'] | null = null;
323
+
324
+ switch (streamType) {
325
+ case MpegTsStreamType.AVC:
326
+ case MpegTsStreamType.HEVC: {
327
+ const codec = streamType === MpegTsStreamType.AVC ? 'avc' : 'hevc';
328
+
329
+ info = {
330
+ type: 'video',
331
+ codec,
332
+ decoderConfig: null,
333
+ avcCodecInfo: null,
334
+ hevcCodecInfo: null,
335
+ colorSpace: {
336
+ primaries: null,
337
+ transfer: null,
338
+ matrix: null,
339
+ fullRange: null,
340
+ },
341
+ width: -1,
342
+ height: -1,
343
+ squarePixelWidth: -1,
344
+ squarePixelHeight: -1,
345
+ reorderSize: -1,
346
+ };
347
+ }; break;
348
+
349
+ case MpegTsStreamType.MP3_MPEG1:
350
+ case MpegTsStreamType.MP3_MPEG2:
351
+ case MpegTsStreamType.AAC:
352
+ case MpegTsStreamType.AC3_SYSTEM_A:
353
+ case MpegTsStreamType.EAC3_SYSTEM_A: {
354
+ let codec: AudioCodec;
355
+ if (
356
+ streamType === MpegTsStreamType.MP3_MPEG1
357
+ || streamType === MpegTsStreamType.MP3_MPEG2
358
+ ) {
359
+ codec = 'mp3';
360
+ } else if (streamType === MpegTsStreamType.AAC) {
361
+ codec = 'aac';
362
+ } else if (streamType === MpegTsStreamType.AC3_SYSTEM_A) {
363
+ codec = 'ac3';
364
+ } else if (streamType === MpegTsStreamType.EAC3_SYSTEM_A) {
365
+ codec = 'eac3';
366
+ } else {
367
+ throw new Error('Unreachable.');
368
+ }
369
+
370
+ info = {
371
+ type: 'audio',
372
+ codec,
373
+ decoderConfig: null,
374
+ aacCodecInfo: null,
375
+ numberOfChannels: -1,
376
+ sampleRate: -1,
377
+ };
378
+ }; break;
379
+
380
+ case MpegTsStreamType.PRIVATE_DATA: {
381
+ if (hasEac3Descriptor) {
382
+ info = {
383
+ type: 'audio',
384
+ codec: 'eac3',
385
+ decoderConfig: null,
386
+ aacCodecInfo: null,
387
+ numberOfChannels: -1,
388
+ sampleRate: -1,
389
+ };
390
+ } else if (hasAc3Descriptor) {
391
+ info = {
392
+ type: 'audio',
393
+ codec: 'ac3',
394
+ decoderConfig: null,
395
+ aacCodecInfo: null,
396
+ numberOfChannels: -1,
397
+ sampleRate: -1,
398
+ };
399
+ }
400
+ }; break;
401
+
402
+ default: {
403
+ // If we don't recognize the codec, we don't surface the track at all. This is because
404
+ // we can't determine its metadata and also have no idea how to packetize its data.
405
+
406
+ if (!ignoredStreamTypes.has(streamType)) {
407
+ Logging._warn(
408
+ `Note: MPEG-TS streams with stream_type 0x${streamType.toString(16)} are not`
409
+ + ` currently supported.`,
410
+ );
411
+ ignoredStreamTypes.add(streamType);
412
+ }
413
+ }
414
+ }
415
+
416
+ if (info) {
417
+ this.elementaryStreams.push({
418
+ demuxer: this,
419
+ pid: elementaryPid,
420
+ streamType,
421
+ initialized: false,
422
+ firstSection: null,
423
+ canBeTrustedWithKeyPackets: false,
424
+ info,
425
+ referencePesPackets: [],
426
+ });
427
+ }
428
+ }
429
+
430
+ hasProgramMap = true;
431
+ } else {
432
+ const elementaryStream = this.elementaryStreams.find(x => x.pid === section.pid);
433
+ outer:
434
+ if (elementaryStream && !elementaryStream.initialized) {
435
+ const pesPacket = readPesPacket(section, true);
436
+ if (!pesPacket) {
437
+ throw new Error(
438
+ `Couldn't read first PES packet for Elementary Stream with PID ${elementaryStream.pid}`,
439
+ );
440
+ }
441
+
442
+ elementaryStream.firstSection = section;
443
+ elementaryStream.canBeTrustedWithKeyPackets = section.randomAccessIndicator === 1;
444
+
445
+ if (this.input._initInput) {
446
+ const initDemuxer = (await this.input._initInput._getDemuxer()) as MpegTsDemuxer;
447
+ const matchingStream = initDemuxer.elementaryStreams.find(x => (
448
+ x.pid === section.pid && x.info.codec === elementaryStream.info.codec
449
+ ));
450
+
451
+ if (matchingStream) {
452
+ elementaryStream.info = matchingStream.info;
453
+ elementaryStream.initialized = true;
454
+
455
+ break outer; // We have the stream info, we're done
456
+ }
457
+ }
458
+
459
+ const context = new PacketReadingContext(elementaryStream, pesPacket);
460
+
461
+ if (elementaryStream.info.type === 'video') {
462
+ // We loop because in some files, the video parameters are not in the first packet
463
+ while (true) {
464
+ const contextAlias = context; // TyyyyypeScript 😩
465
+ contextAlias.suppliedPacket = null;
466
+ await context.markNextPacket();
467
+
468
+ if (elementaryStream.info.codec === 'avc') {
469
+ if (!context.suppliedPacket) {
470
+ throw new Error(
471
+ 'Invalid AVC video stream; could not extract AVCDecoderConfigurationRecord'
472
+ + ' from any packet.',
473
+ );
474
+ }
475
+
476
+ elementaryStream.info.avcCodecInfo
477
+ = extractAvcDecoderConfigurationRecord(context.suppliedPacket.data);
478
+
479
+ if (!elementaryStream.info.avcCodecInfo) {
480
+ continue; // Search the next packet for it
481
+ }
482
+
483
+ const spsUnit = elementaryStream.info.avcCodecInfo.sequenceParameterSets[0];
484
+ assert(spsUnit);
485
+ const spsInfo = parseAvcSps(spsUnit)!;
486
+
487
+ elementaryStream.info.width = spsInfo.displayWidth;
488
+ elementaryStream.info.height = spsInfo.displayHeight;
489
+
490
+ const num = spsInfo.pixelAspectRatio.num;
491
+ const den = spsInfo.pixelAspectRatio.den;
492
+
493
+ if (num > 0 && den > 0) {
494
+ if (num > den) {
495
+ elementaryStream.info.squarePixelWidth = Math.round(
496
+ elementaryStream.info.width * num / den,
497
+ );
498
+ elementaryStream.info.squarePixelHeight = elementaryStream.info.height;
499
+ } else {
500
+ elementaryStream.info.squarePixelWidth = elementaryStream.info.width;
501
+ elementaryStream.info.squarePixelHeight = Math.round(
502
+ elementaryStream.info.height * den / num,
503
+ );
504
+ }
505
+ }
506
+
507
+ elementaryStream.info.colorSpace = {
508
+ primaries:
509
+ COLOR_PRIMARIES_MAP_INVERSE[spsInfo.colourPrimaries] as
510
+ VideoColorPrimaries | undefined,
511
+ transfer:
512
+ TRANSFER_CHARACTERISTICS_MAP_INVERSE[spsInfo.transferCharacteristics] as
513
+ VideoTransferCharacteristics | undefined,
514
+ matrix:
515
+ MATRIX_COEFFICIENTS_MAP_INVERSE[spsInfo.matrixCoefficients] as
516
+ VideoMatrixCoefficients | undefined,
517
+ fullRange: !!spsInfo.fullRangeFlag,
518
+ };
519
+ elementaryStream.info.reorderSize = spsInfo.maxDecFrameBuffering;
520
+
521
+ break;
522
+ } else if (elementaryStream.info.codec === 'hevc') {
523
+ if (!context.suppliedPacket) {
524
+ throw new Error(
525
+ 'Invalid HEVC video stream; could not extract HVCDecoderConfigurationRecord'
526
+ + ' from first packet.',
527
+ );
528
+ }
529
+
530
+ elementaryStream.info.hevcCodecInfo
531
+ = extractHevcDecoderConfigurationRecord(context.suppliedPacket.data);
532
+
533
+ if (!elementaryStream.info.hevcCodecInfo) {
534
+ continue; // Search the next packet for it
535
+ }
536
+
537
+ const spsArray = elementaryStream.info.hevcCodecInfo.arrays.find(
538
+ a => a.nalUnitType === HevcNalUnitType.SPS_NUT,
539
+ )!;
540
+ const spsUnit = spsArray.nalUnits[0];
541
+ assert(spsUnit);
542
+ const spsInfo = parseHevcSps(spsUnit)!;
543
+
544
+ elementaryStream.info.width = spsInfo.displayWidth;
545
+ elementaryStream.info.height = spsInfo.displayHeight;
546
+ if (spsInfo.pixelAspectRatio.num > spsInfo.pixelAspectRatio.den) {
547
+ elementaryStream.info.squarePixelWidth = Math.round(
548
+ elementaryStream.info.width
549
+ * spsInfo.pixelAspectRatio.num / spsInfo.pixelAspectRatio.den,
550
+ );
551
+ elementaryStream.info.squarePixelHeight = elementaryStream.info.height;
552
+ } else {
553
+ elementaryStream.info.squarePixelWidth = elementaryStream.info.width;
554
+ elementaryStream.info.squarePixelHeight = Math.round(
555
+ elementaryStream.info.height
556
+ * spsInfo.pixelAspectRatio.den / spsInfo.pixelAspectRatio.num,
557
+ );
558
+ }
559
+
560
+ elementaryStream.info.colorSpace = {
561
+ primaries:
562
+ COLOR_PRIMARIES_MAP_INVERSE[spsInfo.colourPrimaries] as
563
+ VideoColorPrimaries | undefined,
564
+ transfer:
565
+ TRANSFER_CHARACTERISTICS_MAP_INVERSE[spsInfo.transferCharacteristics] as
566
+ VideoTransferCharacteristics | undefined,
567
+ matrix:
568
+ MATRIX_COEFFICIENTS_MAP_INVERSE[spsInfo.matrixCoefficients] as
569
+ VideoMatrixCoefficients | undefined,
570
+ fullRange: !!spsInfo.fullRangeFlag,
571
+ };
572
+ elementaryStream.info.reorderSize = spsInfo.maxDecFrameBuffering;
573
+
574
+ break;
575
+ } else {
576
+ throw new Error('Unhandled.');
577
+ }
578
+ }
579
+
580
+ elementaryStream.info.decoderConfig = {
581
+ codec: extractVideoCodecString({
582
+ width: elementaryStream.info.width,
583
+ height: elementaryStream.info.height,
584
+ codec: elementaryStream.info.codec,
585
+ codecDescription: null,
586
+ colorSpace: elementaryStream.info.colorSpace,
587
+ avcType: 1,
588
+ avcCodecInfo: elementaryStream.info.avcCodecInfo,
589
+ hevcCodecInfo: elementaryStream.info.hevcCodecInfo,
590
+ vp9CodecInfo: null,
591
+ av1CodecInfo: null,
592
+ proresFormat: null,
593
+ }),
594
+ codedWidth: elementaryStream.info.width,
595
+ codedHeight: elementaryStream.info.height,
596
+ colorSpace: elementaryStream.info.colorSpace,
597
+ };
598
+
599
+ if (
600
+ elementaryStream.info.width !== elementaryStream.info.squarePixelWidth
601
+ || elementaryStream.info.height !== elementaryStream.info.squarePixelHeight
602
+ ) {
603
+ elementaryStream.info.decoderConfig.displayAspectWidth
604
+ = elementaryStream.info.squarePixelWidth;
605
+ elementaryStream.info.decoderConfig.displayAspectHeight
606
+ = elementaryStream.info.squarePixelHeight;
607
+ }
608
+
609
+ elementaryStream.initialized = true;
610
+ } else {
611
+ await context.markNextPacket();
612
+ if (!context.suppliedPacket) {
613
+ throw new Error(
614
+ `Couldn't parse first media packet for Elementary Stream with`
615
+ + ` PID ${elementaryStream.pid}`,
616
+ );
617
+ }
618
+
619
+ if (elementaryStream.info.codec === 'aac') {
620
+ const slice = FileSlice.tempFromBytes(context.suppliedPacket.data);
621
+ const header = readAdtsFrameHeader(slice);
622
+ if (!header) {
623
+ throw new Error(
624
+ 'Invalid AAC audio stream; could not read ADTS frame header from first packet.',
625
+ );
626
+ }
627
+
628
+ elementaryStream.info.aacCodecInfo = {
629
+ isMpeg2: false,
630
+ objectType: header.objectType,
631
+ };
632
+ elementaryStream.info.numberOfChannels
633
+ = aacChannelMap[header.channelConfiguration]!;
634
+ elementaryStream.info.sampleRate
635
+ = aacFrequencyTable[header.samplingFrequencyIndex]!;
636
+ } else if (elementaryStream.info.codec === 'mp3') {
637
+ const word = readU32Be(FileSlice.tempFromBytes(context.suppliedPacket.data));
638
+ const result = readMp3FrameHeader(word, context.suppliedPacket.data.byteLength);
639
+ if (!result.header) {
640
+ throw new Error(
641
+ 'Invalid MP3 audio stream; could not read frame header from first packet.',
642
+ );
643
+ }
644
+
645
+ elementaryStream.info.numberOfChannels = getMp3ChannelCount(result.header.channel);
646
+ elementaryStream.info.sampleRate = result.header.sampleRate;
647
+ } else if (elementaryStream.info.codec === 'ac3') {
648
+ const frameInfo = parseAc3SyncFrame(context.suppliedPacket.data);
649
+ if (!frameInfo) {
650
+ throw new Error(
651
+ 'Invalid AC-3 audio stream; could not read sync frame from first packet.',
652
+ );
653
+ }
654
+
655
+ if (frameInfo.fscod === 3) {
656
+ throw new Error(
657
+ 'Invalid AC-3 audio stream; reserved sample rate code found in first packet.',
658
+ );
659
+ }
660
+
661
+ elementaryStream.info.numberOfChannels
662
+ = AC3_ACMOD_CHANNEL_COUNTS[frameInfo.acmod]! + frameInfo.lfeon;
663
+ elementaryStream.info.sampleRate = AC3_SAMPLE_RATES[frameInfo.fscod]!;
664
+ } else if (elementaryStream.info.codec === 'eac3') {
665
+ const frameInfo = parseEac3SyncFrame(context.suppliedPacket.data);
666
+ if (!frameInfo) {
667
+ throw new Error(
668
+ 'Invalid E-AC-3 audio stream; could not read sync frame from first packet.',
669
+ );
670
+ }
671
+
672
+ const sampleRate = getEac3SampleRate(frameInfo);
673
+ if (sampleRate === null) {
674
+ throw new Error(
675
+ 'Invalid E-AC-3 audio stream; reserved sample rate code found in first packet.',
676
+ );
677
+ }
678
+
679
+ elementaryStream.info.numberOfChannels = getEac3ChannelCount(frameInfo);
680
+ elementaryStream.info.sampleRate = sampleRate;
681
+ } else {
682
+ throw new Error('Unhandled.');
683
+ }
684
+
685
+ elementaryStream.info.decoderConfig = {
686
+ codec: extractAudioCodecString({
687
+ codec: elementaryStream.info.codec,
688
+ codecDescription: null,
689
+ aacCodecInfo: elementaryStream.info.aacCodecInfo,
690
+ }),
691
+ numberOfChannels: elementaryStream.info.numberOfChannels,
692
+ sampleRate: elementaryStream.info.sampleRate,
693
+ };
694
+ elementaryStream.initialized = true;
695
+ }
696
+ }
697
+ }
698
+
699
+ const isDone = hasProgramMap && this.elementaryStreams.every(x => x.initialized);
700
+ if (isDone) {
701
+ break;
702
+ }
703
+
704
+ currentPos += this.packetStride;
705
+ }
706
+
707
+ if (!hasProgramMap) {
708
+ if (!hasProgramAssociationTable) {
709
+ throw new Error('No Program Association Table found in the file.');
710
+ }
711
+
712
+ throw new Error('No Program Map Table found in the file.');
713
+ }
714
+
715
+ for (const stream of this.elementaryStreams) {
716
+ if (stream.info.type === 'video') {
717
+ this.trackBackingEntries.push(
718
+ new MpegTsVideoTrackBacking(stream as ElementaryVideoStream),
719
+ );
720
+ } else {
721
+ this.trackBackingEntries.push(
722
+ new MpegTsAudioTrackBacking(stream as ElementaryAudioStream),
723
+ );
724
+ }
725
+ }
726
+ })();
727
+ }
728
+
729
+ async getTrackBackings() {
730
+ await this.readMetadata();
731
+ return this.trackBackingEntries;
732
+ }
733
+
734
+ async getMetadataTags(): Promise<MetadataTags> {
735
+ return {}; // Nothing for now
736
+ }
737
+
738
+ async getMimeType(): Promise<string> {
739
+ await this.readMetadata();
740
+
741
+ const codecStrings = await Promise.all(this.trackBackingEntries.map(
742
+ x => x.getDecoderConfig().then(c => c?.codec ?? null),
743
+ ));
744
+
745
+ return buildMpegTsMimeType(codecStrings);
746
+ }
747
+
748
+ async readSection(startPos: number, full: boolean, contiguous = false): Promise<Section | null> {
749
+ let endPos = startPos;
750
+ let currentPos = startPos;
751
+ const chunks: Uint8Array[] = [];
752
+ let chunksByteLength = 0;
753
+ let firstPacket: TsPacket | null = null;
754
+ let mustAddSectionEnd = true;
755
+ let randomAccessIndicator = 0;
756
+
757
+ while (true) {
758
+ const packet = await this.readPacket(currentPos);
759
+ currentPos += this.packetStride;
760
+
761
+ if (!packet) {
762
+ break;
763
+ }
764
+
765
+ if (!firstPacket) {
766
+ if (packet.payloadUnitStartIndicator === 0) {
767
+ break;
768
+ }
769
+
770
+ firstPacket = packet;
771
+ } else {
772
+ if (packet.pid !== firstPacket.pid) {
773
+ if (contiguous) {
774
+ break; // End of section
775
+ } else {
776
+ continue; // Ignore this packet
777
+ }
778
+ }
779
+
780
+ if (packet.payloadUnitStartIndicator === 1) {
781
+ break;
782
+ }
783
+ }
784
+
785
+ const hasAdaptationField = !!(packet.adaptationFieldControl & 0b10);
786
+ const hasPayload = !!(packet.adaptationFieldControl & 0b01);
787
+
788
+ let adaptationFieldLength = 0;
789
+ if (hasAdaptationField) {
790
+ adaptationFieldLength = 1 + packet.body[0]!;
791
+
792
+ // Extract random_access_indicator from first packet's adaptation field
793
+ if (packet === firstPacket && adaptationFieldLength > 1) {
794
+ randomAccessIndicator = (packet.body[1]! >> 6) & 1;
795
+ }
796
+ }
797
+
798
+ if (hasPayload) {
799
+ if (adaptationFieldLength === 0) {
800
+ chunks.push(packet.body);
801
+ chunksByteLength += packet.body.byteLength;
802
+ } else {
803
+ chunks.push(packet.body.subarray(adaptationFieldLength));
804
+ chunksByteLength += packet.body.byteLength - adaptationFieldLength;
805
+ }
806
+ }
807
+
808
+ endPos = currentPos;
809
+
810
+ // 64 is just "a bit of data", enough for the PES packet header
811
+ if (!full && chunksByteLength >= 64) {
812
+ mustAddSectionEnd = false; // Not the actual section end
813
+ break;
814
+ }
815
+
816
+ // Check if we already know this is a section end
817
+ const isKnownSectionEnd = binarySearchExact(this.sectionEndPositions, endPos, x => x) !== -1;
818
+ if (isKnownSectionEnd) {
819
+ mustAddSectionEnd = false;
820
+ break;
821
+ }
822
+ }
823
+
824
+ if (mustAddSectionEnd) {
825
+ const index = binarySearchLessOrEqual(this.sectionEndPositions, endPos, x => x);
826
+ this.sectionEndPositions.splice(index + 1, 0, endPos);
827
+ }
828
+
829
+ if (!firstPacket) {
830
+ return null;
831
+ }
832
+
833
+ let merged: Uint8Array;
834
+ if (chunks.length === 1) {
835
+ merged = chunks[0]!;
836
+ } else {
837
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
838
+ merged = new Uint8Array(totalLength);
839
+ let offset = 0;
840
+ for (const chunk of chunks) {
841
+ merged.set(chunk, offset);
842
+ offset += chunk.length;
843
+ }
844
+ }
845
+
846
+ return {
847
+ startPos,
848
+ endPos: full ? endPos : null,
849
+ pid: firstPacket.pid,
850
+ payload: merged,
851
+ randomAccessIndicator,
852
+ };
853
+ }
854
+
855
+ async readPacketHeader(pos: number): Promise<TsPacketHeader | null> {
856
+ let slice = this.reader.requestSlice(pos, 4);
857
+ if (slice instanceof Promise) slice = await slice;
858
+
859
+ if (!slice) {
860
+ return null;
861
+ }
862
+
863
+ const syncByte = readU8(slice);
864
+ if (syncByte !== 0x47) {
865
+ throw new Error('Invalid TS packet sync byte. Likely an internal bug, please report this file.');
866
+ }
867
+
868
+ const nextTwoBytes = readU16Be(slice);
869
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
870
+ const transportErrorIndicator = nextTwoBytes >> 15;
871
+ const payloadUnitStartIndicator = (nextTwoBytes >> 14) & 0x1;
872
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
873
+ const transportPriority = (nextTwoBytes >> 13) & 0x1;
874
+ const pid = nextTwoBytes & 0x1FFF;
875
+
876
+ const nextByte = readU8(slice);
877
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
878
+ const transportScramblingControl = nextByte >> 6;
879
+ const adaptationFieldControl = (nextByte >> 4) & 0x3;
880
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
881
+ const continuityCounter = nextByte & 0xF;
882
+
883
+ return {
884
+ payloadUnitStartIndicator,
885
+ pid,
886
+ adaptationFieldControl,
887
+ };
888
+ }
889
+
890
+ async readPacket(pos: number): Promise<TsPacket | null> {
891
+ // Code in here is duplicated from readPacketHeader for performance reasons
892
+ let slice = this.reader.requestSlice(pos, TS_PACKET_SIZE);
893
+ if (slice instanceof Promise) slice = await slice;
894
+
895
+ if (!slice) {
896
+ return null;
897
+ }
898
+
899
+ const bytes = readBytes(slice, TS_PACKET_SIZE);
900
+
901
+ const syncByte = bytes[0]!;
902
+ if (syncByte !== 0x47) {
903
+ throw new Error('Invalid TS packet sync byte. Likely an internal bug, please report this file.');
904
+ }
905
+
906
+ const nextTwoBytes = (bytes[1]! << 8) + bytes[2]!;
907
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
908
+ const transportErrorIndicator = nextTwoBytes >> 15;
909
+ const payloadUnitStartIndicator = (nextTwoBytes >> 14) & 0x1;
910
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
911
+ const transportPriority = (nextTwoBytes >> 13) & 0x1;
912
+ const pid = nextTwoBytes & 0x1FFF;
913
+
914
+ const nextByte = bytes[3]!;
915
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
916
+ const transportScramblingControl = nextByte >> 6;
917
+ const adaptationFieldControl = (nextByte >> 4) & 0x3;
918
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
919
+ const continuityCounter = nextByte & 0xF;
920
+
921
+ return {
922
+ payloadUnitStartIndicator,
923
+ pid,
924
+ adaptationFieldControl,
925
+ body: bytes.subarray(4),
926
+ };
927
+ }
928
+ }
929
+
930
+ type PesPacketHeader = {
931
+ sectionStartPos: number;
932
+ sectionEndPos: number | null; // null if the section wasn't read fully
933
+ pts: number | null;
934
+ randomAccessIndicator: number;
935
+ };
936
+
937
+ type TimestampedPesPacketHeader = PesPacketHeader & {
938
+ pts: number;
939
+ };
940
+
941
+ type PesPacket = PesPacketHeader & {
942
+ data: Uint8Array<ArrayBufferLike>;
943
+ };
944
+
945
+ type TimestampedPesPacket = PesPacket & {
946
+ pts: number;
947
+ };
948
+
949
+ const readPesPacketHeader = <T extends boolean>(
950
+ section: Section,
951
+ expectPts: T,
952
+ ): (T extends true ? TimestampedPesPacketHeader : PesPacketHeader) | null => {
953
+ if (section.payload.byteLength < 3) {
954
+ return null;
955
+ }
956
+
957
+ const bitstream = new Bitstream(section.payload);
958
+
959
+ const startCodePrefix = bitstream.readBits(24);
960
+ if (startCodePrefix !== 0x000001) {
961
+ return null;
962
+ }
963
+
964
+ const streamId = bitstream.readBits(8);
965
+ bitstream.skipBits(16);
966
+
967
+ if (
968
+ streamId === 0b10111100 // program_stream_map
969
+ || streamId === 0b10111110 // padding_stream
970
+ || streamId === 0b10111111 // private_stream_2
971
+ || streamId === 0b11110000 // ECM
972
+ || streamId === 0b11110001 // EMM
973
+ || streamId === 0b11111111 // program_stream_directory
974
+ || streamId === 0b11110010 // DSMCC_stream
975
+ || streamId === 0b11111000 // ITU-T Rec. H.222.1 type E stream
976
+ ) {
977
+ return null;
978
+ }
979
+
980
+ bitstream.skipBits(8);
981
+
982
+ const ptsDtsFlags = bitstream.readBits(2);
983
+
984
+ bitstream.skipBits(14);
985
+
986
+ let pts: number | null = null;
987
+ if (ptsDtsFlags === 0b10 || ptsDtsFlags === 0b11) {
988
+ pts = 0;
989
+
990
+ bitstream.skipBits(4);
991
+ pts += bitstream.readBits(3) * (1 << 30);
992
+ bitstream.skipBits(1);
993
+ pts += bitstream.readBits(15) * (1 << 15);
994
+ bitstream.skipBits(1);
995
+ pts += bitstream.readBits(15);
996
+ } else {
997
+ if (expectPts) {
998
+ throw new Error(MISSING_PTS_ERROR_MESSAGE);
999
+ }
1000
+ }
1001
+
1002
+ return {
1003
+ sectionStartPos: section.startPos,
1004
+ sectionEndPos: section.endPos,
1005
+ pts,
1006
+ randomAccessIndicator: section.randomAccessIndicator,
1007
+ } as T extends true ? TimestampedPesPacketHeader : PesPacketHeader;
1008
+ };
1009
+
1010
+ const readPesPacket = <T extends boolean>(
1011
+ section: Section,
1012
+ expectPts: T,
1013
+ ): (T extends true ? TimestampedPesPacket : PesPacket) | null => {
1014
+ assert(section.endPos !== null); // Can only read full PES packets from fully read sections
1015
+
1016
+ const header = readPesPacketHeader(section, expectPts);
1017
+ if (!header) {
1018
+ return null;
1019
+ }
1020
+
1021
+ const bitstream = new Bitstream(section.payload);
1022
+ bitstream.skipBits(32);
1023
+ const pesPacketLength = bitstream.readBits(16);
1024
+ const BYTES_UNTIL_END_OF_PES_PACKET_LENGTH = 6;
1025
+
1026
+ bitstream.skipBits(16);
1027
+ const pesHeaderDataLength = bitstream.readBits(8);
1028
+ const pesHeaderEndPos = bitstream.pos + 8 * pesHeaderDataLength;
1029
+
1030
+ bitstream.pos = pesHeaderEndPos;
1031
+
1032
+ const bytePos = pesHeaderEndPos / 8;
1033
+ assert(Number.isInteger(bytePos));
1034
+
1035
+ const data = section.payload.subarray(
1036
+ bytePos,
1037
+ // "A value of 0 indicates that the PES packet length is neither specified nor bounded and is allowed only in
1038
+ // PES packets whose payload consists of bytes from a video elementary stream contained in
1039
+ // transport stream packets."
1040
+ pesPacketLength > 0
1041
+ ? BYTES_UNTIL_END_OF_PES_PACKET_LENGTH + pesPacketLength
1042
+ : section.payload.byteLength,
1043
+ );
1044
+
1045
+ return {
1046
+ ...header,
1047
+ data,
1048
+ } as T extends true ? TimestampedPesPacket : PesPacket;
1049
+ };
1050
+
1051
+ abstract class MpegTsTrackBacking implements InputTrackBacking {
1052
+ packetBuffers = new WeakMap<EncodedPacket, PacketBuffer>();
1053
+ /** Used for recreating PacketBuffers if necessary. */
1054
+ packetSectionStarts = new WeakMap<EncodedPacket, number>();
1055
+
1056
+ constructor(public elementaryStream: ElementaryStream) {}
1057
+
1058
+ abstract getType(): TrackType;
1059
+ abstract getDecoderConfig(): Promise<VideoDecoderConfig | AudioDecoderConfig | null>;
1060
+
1061
+ getId() {
1062
+ return this.elementaryStream.pid;
1063
+ }
1064
+
1065
+ getNumber() {
1066
+ const demuxer = this.elementaryStream.demuxer;
1067
+ const trackType = this.elementaryStream.info.type;
1068
+
1069
+ let number = 0;
1070
+ for (const backing of demuxer.trackBackingEntries) {
1071
+ if (backing.getType() === trackType) {
1072
+ number++;
1073
+ }
1074
+
1075
+ assert(backing instanceof MpegTsTrackBacking);
1076
+ if (backing.elementaryStream === this.elementaryStream) {
1077
+ break;
1078
+ }
1079
+ }
1080
+
1081
+ return number;
1082
+ }
1083
+
1084
+ getCodec(): MediaCodec | null {
1085
+ throw new Error('Not implemented on base class.');
1086
+ }
1087
+
1088
+ getInternalCodecId() {
1089
+ return this.elementaryStream.streamType;
1090
+ }
1091
+
1092
+ getName() {
1093
+ return null;
1094
+ }
1095
+
1096
+ getLanguageCode() {
1097
+ return UNDETERMINED_LANGUAGE;
1098
+ }
1099
+
1100
+ getDisposition(): TrackDisposition {
1101
+ return {
1102
+ ...DEFAULT_TRACK_DISPOSITION,
1103
+ primary: false,
1104
+ };
1105
+ }
1106
+
1107
+ getTimeResolution() {
1108
+ return TIMESCALE;
1109
+ }
1110
+
1111
+ isRelativeToUnixEpoch() {
1112
+ return false;
1113
+ }
1114
+
1115
+ getUnixTimeForTimestamp() {
1116
+ return null;
1117
+ }
1118
+
1119
+ getPairingMask() {
1120
+ return 1n;
1121
+ }
1122
+
1123
+ getBitrate() {
1124
+ return null;
1125
+ }
1126
+
1127
+ getAverageBitrate() {
1128
+ return null;
1129
+ }
1130
+
1131
+ async getDurationFromMetadata() {
1132
+ return null;
1133
+ }
1134
+
1135
+ async getLiveRefreshInterval() {
1136
+ return null;
1137
+ }
1138
+
1139
+ abstract allPacketsAreKeyPackets(): boolean;
1140
+ abstract getReorderSize(): number;
1141
+
1142
+ createEncodedPacket(
1143
+ suppliedPacket: SuppliedPacket,
1144
+ duration: number,
1145
+ options: PacketRetrievalOptions,
1146
+ ) {
1147
+ let packetType: PacketType;
1148
+
1149
+ if (this.allPacketsAreKeyPackets()) {
1150
+ packetType = 'key';
1151
+ } else {
1152
+ packetType = suppliedPacket.randomAccessIndicator === 1
1153
+ ? 'key'
1154
+ : 'delta';
1155
+ }
1156
+
1157
+ return new EncodedPacket(
1158
+ options.metadataOnly ? PLACEHOLDER_DATA : suppliedPacket.data,
1159
+ packetType,
1160
+ suppliedPacket.pts / TIMESCALE,
1161
+ Math.max(duration / TIMESCALE, 0),
1162
+ suppliedPacket.sequenceNumber,
1163
+ suppliedPacket.data.byteLength,
1164
+ );
1165
+ }
1166
+
1167
+ async getFirstPacket(options: PacketRetrievalOptions): Promise<EncodedPacket | null> {
1168
+ const section = this.elementaryStream.firstSection;
1169
+ assert(section);
1170
+
1171
+ const pesPacket = readPesPacket(section, true);
1172
+ assert(pesPacket);
1173
+
1174
+ const context = new PacketReadingContext(this.elementaryStream, pesPacket);
1175
+ const buffer = new PacketBuffer(this, context);
1176
+
1177
+ const result = await buffer.readNext();
1178
+ if (!result) {
1179
+ return null;
1180
+ }
1181
+
1182
+ const packet = this.createEncodedPacket(result.packet, result.duration, options);
1183
+ this.packetBuffers.set(packet, buffer);
1184
+ this.packetSectionStarts.set(packet, result.packet.sectionStartPos);
1185
+
1186
+ return packet;
1187
+ }
1188
+
1189
+ async getNextPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null> {
1190
+ let buffer = this.packetBuffers.get(packet);
1191
+
1192
+ if (buffer) {
1193
+ // Fast path
1194
+ const result = await buffer.readNext();
1195
+ if (!result) {
1196
+ return null;
1197
+ }
1198
+
1199
+ // Remove PacketBuffer access from the old packet, it belongs to the next packet now
1200
+ this.packetBuffers.delete(packet);
1201
+
1202
+ const newPacket = this.createEncodedPacket(result.packet, result.duration, options);
1203
+ this.packetBuffers.set(newPacket, buffer);
1204
+ this.packetSectionStarts.set(newPacket, result.packet.sectionStartPos);
1205
+
1206
+ return newPacket;
1207
+ }
1208
+
1209
+ // No buffer, we gotta do some rereading
1210
+ const sectionStartPos = this.packetSectionStarts.get(packet);
1211
+ if (sectionStartPos === undefined) {
1212
+ throw new Error('Packet was not created from this track.');
1213
+ }
1214
+
1215
+ const demuxer = this.elementaryStream.demuxer;
1216
+ const section = await demuxer.readSection(sectionStartPos, true);
1217
+ assert(section);
1218
+
1219
+ const pesPacket = readPesPacket(section, true);
1220
+ assert(pesPacket);
1221
+
1222
+ const context = new PacketReadingContext(this.elementaryStream, pesPacket);
1223
+ buffer = new PacketBuffer(this, context);
1224
+
1225
+ // Advance until we pass the current packet's sequence number
1226
+ const targetSequenceNumber = packet.sequenceNumber;
1227
+ while (true) {
1228
+ const result = await buffer.readNext();
1229
+ if (!result) {
1230
+ return null;
1231
+ }
1232
+
1233
+ if (result.packet.sequenceNumber > targetSequenceNumber) {
1234
+ // We found the next packet!
1235
+ const newPacket = this.createEncodedPacket(result.packet, result.duration, options);
1236
+ this.packetBuffers.set(newPacket, buffer);
1237
+ this.packetSectionStarts.set(newPacket, result.packet.sectionStartPos);
1238
+ return newPacket;
1239
+ }
1240
+ }
1241
+ }
1242
+
1243
+ async getNextKeyPacket(packet: EncodedPacket, options: PacketRetrievalOptions): Promise<EncodedPacket | null> {
1244
+ let currentPacket: EncodedPacket | null = packet;
1245
+
1246
+ // Just loop until we hit one
1247
+ while (true) {
1248
+ currentPacket = await this.getNextPacket(currentPacket, options);
1249
+
1250
+ if (!currentPacket) {
1251
+ return null;
1252
+ }
1253
+
1254
+ if (currentPacket.type === 'key') {
1255
+ return currentPacket;
1256
+ }
1257
+ }
1258
+ }
1259
+
1260
+ getPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null> {
1261
+ return this.doPacketLookup(timestamp, false, options);
1262
+ }
1263
+
1264
+ getKeyPacket(timestamp: number, options: PacketRetrievalOptions): Promise<EncodedPacket | null> {
1265
+ return this.doPacketLookup(timestamp, true, options);
1266
+ }
1267
+
1268
+ /**
1269
+ * Searches for the packet with the largest timestamp not larger than `timestamp` in the file, using a combination
1270
+ * of chunk-based binary search and linear refinement. The reason the coarse search is done in large chunks is to
1271
+ * make it more performant for small files and over high-latency readers such as the network.
1272
+ */
1273
+ async doPacketLookup(
1274
+ timestamp: number,
1275
+ keyframesOnly: boolean,
1276
+ options: PacketRetrievalOptions,
1277
+ ): Promise<EncodedPacket | null> {
1278
+ const searchPts = roundIfAlmostInteger(timestamp * TIMESCALE);
1279
+
1280
+ const demuxer = this.elementaryStream.demuxer;
1281
+ const { reader, seekChunkSize } = demuxer;
1282
+ const pid = this.elementaryStream.pid;
1283
+
1284
+ const findFirstPesPacketHeaderInChunk = async (
1285
+ startPos: number,
1286
+ endPos: number,
1287
+ readSectionInFull: boolean,
1288
+ ) => {
1289
+ let currentPos = startPos;
1290
+
1291
+ while (currentPos < endPos) {
1292
+ const packetHeader = await demuxer.readPacketHeader(currentPos);
1293
+ if (!packetHeader) {
1294
+ return null;
1295
+ }
1296
+
1297
+ if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
1298
+ const section = await demuxer.readSection(currentPos, readSectionInFull);
1299
+ if (!section) {
1300
+ return null;
1301
+ }
1302
+
1303
+ const pesPacketHeader = readPesPacketHeader(section, false);
1304
+ if (pesPacketHeader && pesPacketHeader.pts !== null) {
1305
+ return {
1306
+ pesPacketHeader: pesPacketHeader as TimestampedPesPacketHeader,
1307
+ section,
1308
+ };
1309
+ }
1310
+ }
1311
+
1312
+ currentPos += demuxer.packetStride;
1313
+ }
1314
+
1315
+ return null;
1316
+ };
1317
+
1318
+ // Get the first PES packet of the track
1319
+ const firstSection = this.elementaryStream.firstSection;
1320
+ assert(firstSection);
1321
+ const firstPesPacketHeader = readPesPacketHeader(firstSection, true);
1322
+ assert(firstPesPacketHeader);
1323
+
1324
+ if (searchPts < firstPesPacketHeader.pts) {
1325
+ // We're before the first packet, definitely nothing here
1326
+ return null;
1327
+ }
1328
+
1329
+ let scanStartPos: number;
1330
+
1331
+ const referencePesPackets = this.elementaryStream.referencePesPackets;
1332
+ const referencePointIndex = binarySearchLessOrEqual(referencePesPackets, searchPts, x => x.pts);
1333
+ const referencePoint = referencePointIndex !== -1 ? referencePesPackets[referencePointIndex]! : null;
1334
+ if (referencePoint && searchPts - referencePoint.pts < TIMESCALE / 2) {
1335
+ // Reference point ain't too far away, prefer it over the chunk search
1336
+ scanStartPos = referencePoint.sectionStartPos;
1337
+ } else {
1338
+ let startChunkIndex = 0;
1339
+
1340
+ if (reader.fileSize !== null) {
1341
+ const numChunks = Math.ceil(reader.fileSize / seekChunkSize);
1342
+
1343
+ if (numChunks > 1) {
1344
+ // Binary search to find the chunk with highest index whose first PES has pts <= searchPts
1345
+ let low = 0;
1346
+ let high = numChunks - 1;
1347
+ startChunkIndex = low;
1348
+
1349
+ while (low <= high) {
1350
+ const mid = Math.floor((low + high) / 2);
1351
+ const chunkStartPos = floorToMultiple(mid * seekChunkSize, demuxer.packetStride)
1352
+ + firstPesPacketHeader.sectionStartPos;
1353
+ const chunkEndPos = chunkStartPos + seekChunkSize;
1354
+
1355
+ const result = await findFirstPesPacketHeaderInChunk(chunkStartPos, chunkEndPos, false);
1356
+
1357
+ if (!result) {
1358
+ // No PES packet found in this chunk, search left
1359
+ high = mid - 1;
1360
+ continue;
1361
+ }
1362
+
1363
+ if (result.pesPacketHeader.pts <= searchPts) {
1364
+ // This chunk's first PES is <= searchPts, it's a candidate
1365
+ startChunkIndex = mid;
1366
+ low = mid + 1; // Search right
1367
+ } else {
1368
+ // Search left
1369
+ high = mid - 1;
1370
+ }
1371
+ }
1372
+ }
1373
+ }
1374
+
1375
+ scanStartPos = floorToMultiple(
1376
+ startChunkIndex * seekChunkSize,
1377
+ demuxer.packetStride,
1378
+ ) + firstPesPacketHeader.sectionStartPos;
1379
+ }
1380
+
1381
+ // Find the first PES packet at or after scanStartPos
1382
+ const result = await findFirstPesPacketHeaderInChunk(
1383
+ scanStartPos,
1384
+ reader.fileSize ?? Infinity,
1385
+ false,
1386
+ );
1387
+
1388
+ let currentPesHeader = result?.pesPacketHeader ?? null;
1389
+ if (!currentPesHeader) {
1390
+ // Fall back to first packet
1391
+ currentPesHeader = firstPesPacketHeader;
1392
+ }
1393
+
1394
+ const reorderSize = this.getReorderSize();
1395
+
1396
+ const retrieveEncodedPacket = async (
1397
+ sectionStartPos: number,
1398
+ predicate: (packet: SuppliedPacket) => boolean,
1399
+ ) => {
1400
+ // Load the relevant section in full
1401
+ const section = await demuxer.readSection(sectionStartPos, true);
1402
+ assert(section);
1403
+
1404
+ const pesPacket = readPesPacket(section, true);
1405
+ assert(pesPacket);
1406
+
1407
+ const context = new PacketReadingContext(this.elementaryStream, pesPacket);
1408
+ const buffer = new PacketBuffer(this, context);
1409
+
1410
+ // Advance until the top-most presentation timestamp crosses or equals searchPts
1411
+ while (true) {
1412
+ const topPts = last(buffer.presentationOrderPackets)?.pts ?? -Infinity;
1413
+ if (topPts >= searchPts) {
1414
+ break;
1415
+ }
1416
+
1417
+ const didRead = await buffer.readNextPacket();
1418
+ if (!didRead) {
1419
+ break;
1420
+ }
1421
+ }
1422
+
1423
+ const targetIndex = findLastIndex(buffer.presentationOrderPackets, predicate);
1424
+ if (targetIndex === -1) {
1425
+ return null;
1426
+ }
1427
+
1428
+ const targetPacket = buffer.presentationOrderPackets[targetIndex]!;
1429
+ const lastDuration = targetIndex === 0
1430
+ ? 0
1431
+ : targetPacket.pts - buffer.presentationOrderPackets[targetIndex - 1]!.pts;
1432
+
1433
+ // Pop packets in decode order until we hit the target packet
1434
+ while (buffer.decodeOrderPackets[0] !== targetPacket) {
1435
+ buffer.decodeOrderPackets.shift();
1436
+ }
1437
+ buffer.lastDuration = lastDuration; // Kinda ugly but necessary fix
1438
+
1439
+ const result = await buffer.readNext();
1440
+ assert(result);
1441
+
1442
+ const packet = this.createEncodedPacket(result.packet, result.duration, options);
1443
+ this.packetBuffers.set(packet, buffer);
1444
+ this.packetSectionStarts.set(packet, result.packet.sectionStartPos);
1445
+
1446
+ return packet;
1447
+ };
1448
+
1449
+ if (!keyframesOnly || this.allPacketsAreKeyPackets()) {
1450
+ // Normat packet lookup case. Slightly easier since we just need to search (mostly) forward to find the
1451
+ // packet.
1452
+
1453
+ // Linear scan to find the PES packet with largest pts <= searchPts. This will be used as the "midpoint"
1454
+ // of the next refinement step (which is needed because of B-frames).
1455
+ outer:
1456
+ while (true) {
1457
+ let currentPos = currentPesHeader.sectionStartPos + demuxer.packetStride;
1458
+
1459
+ while (true) {
1460
+ const packetHeader = await demuxer.readPacketHeader(currentPos);
1461
+ if (!packetHeader) {
1462
+ break outer; // End of file
1463
+ }
1464
+
1465
+ if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
1466
+ const section = await demuxer.readSection(currentPos, false);
1467
+ if (section) {
1468
+ const nextPesHeader = readPesPacketHeader(section, false);
1469
+ if (nextPesHeader && nextPesHeader.pts !== null) {
1470
+ if (nextPesHeader.pts > searchPts) {
1471
+ break outer;
1472
+ }
1473
+
1474
+ currentPesHeader = nextPesHeader as TimestampedPesPacketHeader;
1475
+ maybeInsertReferencePacket(this.elementaryStream, currentPesHeader);
1476
+
1477
+ break;
1478
+ }
1479
+ }
1480
+ }
1481
+
1482
+ currentPos += demuxer.packetStride;
1483
+ }
1484
+ }
1485
+
1486
+ // Rewind by reorderSize + 1 PES packets (even for audio! To ensure proper durations)
1487
+ outer:
1488
+ for (let i = 0; i < reorderSize + 1; i++) {
1489
+ let pos = currentPesHeader.sectionStartPos - demuxer.packetStride;
1490
+
1491
+ while (pos >= demuxer.packetOffset) {
1492
+ const packetHeader = await demuxer.readPacketHeader(pos);
1493
+ if (!packetHeader) {
1494
+ break outer;
1495
+ }
1496
+
1497
+ if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
1498
+ const section = await demuxer.readSection(pos, false);
1499
+ if (section) {
1500
+ const header = readPesPacketHeader(section, false);
1501
+ if (header && header.pts !== null) {
1502
+ currentPesHeader = header as TimestampedPesPacketHeader;
1503
+ break;
1504
+ }
1505
+ }
1506
+ }
1507
+
1508
+ pos -= demuxer.packetStride;
1509
+ }
1510
+ }
1511
+
1512
+ return retrieveEncodedPacket(currentPesHeader.sectionStartPos, p => p.pts <= searchPts);
1513
+ } else {
1514
+ // Key packet lookup case. Slightly harder since the starting chunk may not have a key packet at all, which
1515
+ // means we might need to search the previous chunks until we find something.
1516
+
1517
+ let currentChunkStartPos = scanStartPos;
1518
+ let nextChunkStartPos: number | null = null; // "next" as in later in the file, even tho we scan backwards
1519
+
1520
+ const readSectionsInFull = !this.elementaryStream.canBeTrustedWithKeyPackets;
1521
+
1522
+ while (true) {
1523
+ let bestKeyPesHeader: TimestampedPesPacketHeader | null = null;
1524
+
1525
+ const isFirstChunk = currentChunkStartPos <= firstPesPacketHeader.sectionStartPos;
1526
+
1527
+ let pesHeader: TimestampedPesPacketHeader | null;
1528
+ let pesHeaderSection: Section | null = null;
1529
+
1530
+ if (isFirstChunk) {
1531
+ pesHeader = firstPesPacketHeader;
1532
+ pesHeaderSection = firstSection;
1533
+ } else {
1534
+ const result = await findFirstPesPacketHeaderInChunk(
1535
+ currentChunkStartPos,
1536
+ reader.fileSize ?? Infinity,
1537
+ readSectionsInFull,
1538
+ );
1539
+
1540
+ pesHeader = result?.pesPacketHeader ?? null;
1541
+ pesHeaderSection = result?.section ?? null;
1542
+ }
1543
+
1544
+ let passedSearchPts = false;
1545
+ let lookaheadCount = 0;
1546
+
1547
+ outer:
1548
+ while (pesHeader) {
1549
+ if (nextChunkStartPos !== null && pesHeader.sectionStartPos >= nextChunkStartPos) {
1550
+ // Stop at the next chunk boundary
1551
+ break;
1552
+ }
1553
+
1554
+ if (pesHeader.pts <= searchPts) {
1555
+ let isKeyPacket: boolean;
1556
+ if (this.elementaryStream.canBeTrustedWithKeyPackets) {
1557
+ isKeyPacket = pesHeader.randomAccessIndicator === 1;
1558
+ } else {
1559
+ assert(pesHeaderSection);
1560
+ const pesPacket = readPesPacket(pesHeaderSection, true);
1561
+ assert(pesPacket);
1562
+
1563
+ const context = new PacketReadingContext(this.elementaryStream, pesPacket);
1564
+ await context.markNextPacket();
1565
+
1566
+ isKeyPacket = context.suppliedPacket?.randomAccessIndicator === 1;
1567
+ }
1568
+
1569
+ if (isKeyPacket) {
1570
+ bestKeyPesHeader = pesHeader;
1571
+ }
1572
+ }
1573
+
1574
+ if (pesHeader.pts > searchPts) {
1575
+ passedSearchPts = true;
1576
+ }
1577
+
1578
+ // If we've passed searchPts, do lookahead for reorderSize more packets just to be sure
1579
+ if (passedSearchPts) {
1580
+ lookaheadCount++;
1581
+
1582
+ if (lookaheadCount > reorderSize) {
1583
+ break;
1584
+ }
1585
+ }
1586
+
1587
+ // Find next PES packet
1588
+ let currentPos = pesHeader.sectionStartPos + demuxer.packetStride;
1589
+
1590
+ while (true) {
1591
+ const packetHeader = await demuxer.readPacketHeader(currentPos);
1592
+ if (!packetHeader) {
1593
+ break outer; // End of file
1594
+ }
1595
+
1596
+ if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
1597
+ const section = await demuxer.readSection(currentPos, readSectionsInFull);
1598
+ if (section) {
1599
+ const nextPesHeader = readPesPacketHeader(section, false);
1600
+
1601
+ if (nextPesHeader && nextPesHeader.pts !== null) {
1602
+ pesHeader = nextPesHeader as TimestampedPesPacketHeader;
1603
+ pesHeaderSection = section;
1604
+ maybeInsertReferencePacket(this.elementaryStream, pesHeader);
1605
+
1606
+ break;
1607
+ }
1608
+ }
1609
+ }
1610
+
1611
+ currentPos += demuxer.packetStride;
1612
+ }
1613
+ }
1614
+
1615
+ if (bestKeyPesHeader) {
1616
+ let startPesHeader = bestKeyPesHeader;
1617
+
1618
+ if (lookaheadCount === 0) {
1619
+ // Packet is at the end of stream, let's rewind a little to obtain the correct packet duration
1620
+ outer:
1621
+ for (let i = 0; i < reorderSize; i++) {
1622
+ let pos = startPesHeader.sectionStartPos - demuxer.packetStride;
1623
+
1624
+ while (pos >= demuxer.packetOffset) {
1625
+ const packetHeader = await demuxer.readPacketHeader(pos);
1626
+ if (!packetHeader) {
1627
+ break outer;
1628
+ }
1629
+
1630
+ if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
1631
+ const section = await demuxer.readSection(pos, readSectionsInFull);
1632
+ if (section) {
1633
+ const header = readPesPacketHeader(section, false);
1634
+ if (header && header.pts !== null) {
1635
+ startPesHeader = header as TimestampedPesPacketHeader;
1636
+ break;
1637
+ }
1638
+ }
1639
+ }
1640
+
1641
+ pos -= demuxer.packetStride;
1642
+ }
1643
+ }
1644
+ }
1645
+
1646
+ const encodedPacket = await retrieveEncodedPacket(
1647
+ startPesHeader.sectionStartPos,
1648
+ p => p.pts <= searchPts && p.randomAccessIndicator === 1,
1649
+ );
1650
+ assert(encodedPacket); // There must be one
1651
+
1652
+ return encodedPacket;
1653
+ }
1654
+
1655
+ if (isFirstChunk) {
1656
+ return null;
1657
+ }
1658
+
1659
+ // No key frame found in this chunk, move one chunk to the left
1660
+ nextChunkStartPos = currentChunkStartPos;
1661
+ currentChunkStartPos = Math.max(
1662
+ floorToMultiple(
1663
+ currentChunkStartPos - firstPesPacketHeader.sectionStartPos - seekChunkSize,
1664
+ demuxer.packetStride,
1665
+ ) + firstPesPacketHeader.sectionStartPos,
1666
+ firstPesPacketHeader.sectionStartPos,
1667
+ );
1668
+ }
1669
+ }
1670
+ }
1671
+ }
1672
+
1673
+ class MpegTsVideoTrackBacking extends MpegTsTrackBacking implements InputVideoTrackBacking {
1674
+ override elementaryStream!: ElementaryVideoStream;
1675
+
1676
+ getType() {
1677
+ return 'video' as const;
1678
+ }
1679
+
1680
+ override getCodec(): VideoCodec {
1681
+ return this.elementaryStream.info.codec;
1682
+ }
1683
+
1684
+ getCodedWidth() {
1685
+ return this.elementaryStream.info.width;
1686
+ }
1687
+
1688
+ getCodedHeight() {
1689
+ return this.elementaryStream.info.height;
1690
+ }
1691
+
1692
+ getSquarePixelWidth() {
1693
+ return this.elementaryStream.info.squarePixelWidth;
1694
+ }
1695
+
1696
+ getSquarePixelHeight() {
1697
+ return this.elementaryStream.info.squarePixelHeight;
1698
+ }
1699
+
1700
+ getRotation(): Rotation {
1701
+ return 0;
1702
+ }
1703
+
1704
+ async getColorSpace(): Promise<VideoColorSpaceInit> {
1705
+ return this.elementaryStream.info.colorSpace;
1706
+ }
1707
+
1708
+ async canBeTransparent() {
1709
+ return false;
1710
+ }
1711
+
1712
+ async getDecoderConfig(): Promise<VideoDecoderConfig> {
1713
+ assert(this.elementaryStream.info.decoderConfig);
1714
+ return this.elementaryStream.info.decoderConfig;
1715
+ }
1716
+
1717
+ override allPacketsAreKeyPackets(): boolean {
1718
+ return false;
1719
+ }
1720
+
1721
+ override getReorderSize(): number {
1722
+ return this.elementaryStream.info.reorderSize;
1723
+ }
1724
+ }
1725
+
1726
+ class MpegTsAudioTrackBacking extends MpegTsTrackBacking implements InputAudioTrackBacking {
1727
+ override elementaryStream!: ElementaryAudioStream;
1728
+
1729
+ getType() {
1730
+ return 'audio' as const;
1731
+ }
1732
+
1733
+ override getCodec(): AudioCodec {
1734
+ return this.elementaryStream.info.codec;
1735
+ }
1736
+
1737
+ getNumberOfChannels() {
1738
+ return this.elementaryStream.info.numberOfChannels;
1739
+ }
1740
+
1741
+ getSampleRate() {
1742
+ return this.elementaryStream.info.sampleRate;
1743
+ }
1744
+
1745
+ async getDecoderConfig(): Promise<AudioDecoderConfig> {
1746
+ assert(this.elementaryStream.info.decoderConfig);
1747
+ return this.elementaryStream.info.decoderConfig;
1748
+ }
1749
+
1750
+ override allPacketsAreKeyPackets(): boolean {
1751
+ return true;
1752
+ }
1753
+
1754
+ override getReorderSize(): number {
1755
+ return 0; // No reordering, since no B-frames because goated
1756
+ }
1757
+ }
1758
+
1759
+ const maybeInsertReferencePacket = (
1760
+ elementaryStream: ElementaryStream,
1761
+ pesPacketHeader: TimestampedPesPacketHeader,
1762
+ ) => {
1763
+ const referencePesPackets = elementaryStream.referencePesPackets;
1764
+
1765
+ const index = binarySearchLessOrEqual(
1766
+ referencePesPackets,
1767
+ pesPacketHeader.sectionStartPos,
1768
+ x => x.sectionStartPos,
1769
+ );
1770
+ if (index >= 0) {
1771
+ // Since pts and file position don't necessarily have a monotonic relationship (since pts can go crazy),
1772
+ // let's see if inserting at the given index would violate the pts order. If so, return.
1773
+ const entry = referencePesPackets[index]!;
1774
+ if (pesPacketHeader.pts <= entry.pts) {
1775
+ return false;
1776
+ }
1777
+
1778
+ const minByteDistance = elementaryStream.demuxer.minReferencePointByteDistance;
1779
+
1780
+ if (pesPacketHeader.sectionStartPos - entry.sectionStartPos < minByteDistance) {
1781
+ // Too close
1782
+ return false;
1783
+ }
1784
+
1785
+ if (index < referencePesPackets.length - 1) {
1786
+ const nextEntry = referencePesPackets[index + 1]!;
1787
+ if (nextEntry.pts < pesPacketHeader.pts) {
1788
+ // Out of order
1789
+ return false;
1790
+ }
1791
+
1792
+ if (nextEntry.sectionStartPos - pesPacketHeader.sectionStartPos < minByteDistance) {
1793
+ // Too close
1794
+ return false;
1795
+ }
1796
+ }
1797
+ }
1798
+
1799
+ referencePesPackets.splice(index + 1, 0, pesPacketHeader);
1800
+ return true;
1801
+ };
1802
+
1803
+ type SuppliedPacket = {
1804
+ pts: number;
1805
+ data: Uint8Array;
1806
+ sequenceNumber: number;
1807
+ sectionStartPos: number;
1808
+ randomAccessIndicator: number;
1809
+ };
1810
+
1811
+ /** Stateful context used to extract exact encoded packets from the underlying data stream. */
1812
+ class PacketReadingContext {
1813
+ elementaryStream: ElementaryStream;
1814
+ pid: number;
1815
+ demuxer: MpegTsDemuxer;
1816
+ startingPesPacket: TimestampedPesPacket;
1817
+
1818
+ currentPos = 0; // Relative to the data in startingPesPacket
1819
+ pesPackets: PesPacket[] = [];
1820
+ currentPesPacketIndex = 0;
1821
+ currentPesPacketPos = 0;
1822
+ endPos = 0;
1823
+ lastSuppliedPesPacket: PesPacket | null = null;
1824
+ nextPts: number | null = null;
1825
+
1826
+ suppliedPacket: SuppliedPacket | null = null;
1827
+
1828
+ constructor(elementaryStream: ElementaryStream, startingPesPacket: TimestampedPesPacket) {
1829
+ this.elementaryStream = elementaryStream;
1830
+ this.pid = elementaryStream.pid;
1831
+ this.demuxer = elementaryStream.demuxer;
1832
+ this.startingPesPacket = startingPesPacket;
1833
+ }
1834
+
1835
+ ensureBuffered(length: number) {
1836
+ const remaining = this.endPos - this.currentPos;
1837
+ if (remaining >= length) {
1838
+ return length;
1839
+ }
1840
+
1841
+ return this.bufferData(length - remaining)
1842
+ .then(() => Math.min(this.endPos - this.currentPos, length));
1843
+ }
1844
+
1845
+ getCurrentPesPacket() {
1846
+ const packet = this.pesPackets[this.currentPesPacketIndex];
1847
+ assert(packet);
1848
+
1849
+ return packet;
1850
+ }
1851
+
1852
+ async bufferData(length: number): Promise<void> {
1853
+ const targetEndPos = this.endPos + length;
1854
+
1855
+ while (this.endPos < targetEndPos) {
1856
+ let pesPacket: PesPacket;
1857
+ if (this.pesPackets.length === 0) {
1858
+ pesPacket = this.startingPesPacket;
1859
+ } else {
1860
+ // Find the next PES packet
1861
+ let currentPos = last(this.pesPackets)!.sectionEndPos;
1862
+ assert(currentPos !== null);
1863
+
1864
+ while (true) {
1865
+ const packetHeader = await this.demuxer.readPacketHeader(currentPos);
1866
+ if (!packetHeader) {
1867
+ return;
1868
+ }
1869
+
1870
+ if (packetHeader.pid === this.pid) {
1871
+ const nextSection = await this.demuxer.readSection(currentPos, true);
1872
+ if (!nextSection) {
1873
+ return;
1874
+ }
1875
+
1876
+ const nextPesPacket = readPesPacket(nextSection, false);
1877
+ if (nextPesPacket) {
1878
+ pesPacket = nextPesPacket;
1879
+ break;
1880
+ }
1881
+ }
1882
+
1883
+ currentPos += this.demuxer.packetStride;
1884
+ }
1885
+ }
1886
+
1887
+ this.pesPackets.push(pesPacket);
1888
+ this.endPos += pesPacket.data.byteLength;
1889
+ }
1890
+ }
1891
+
1892
+ readBytes(length: number) {
1893
+ const currentPesPacket = this.getCurrentPesPacket();
1894
+
1895
+ const relativeStartOffset = this.currentPos - this.currentPesPacketPos;
1896
+ const relativeEndOffset = relativeStartOffset + length;
1897
+
1898
+ this.currentPos += length;
1899
+
1900
+ if (relativeEndOffset <= currentPesPacket.data.byteLength) {
1901
+ // Request can be satisfied with one PES packet
1902
+ return currentPesPacket.data.subarray(relativeStartOffset, relativeEndOffset);
1903
+ }
1904
+
1905
+ // Data spans multiple PES packets, we must do some merging
1906
+ const result = new Uint8Array(length);
1907
+ result.set(currentPesPacket.data.subarray(relativeStartOffset));
1908
+ let offset = currentPesPacket.data.byteLength - relativeStartOffset;
1909
+
1910
+ while (true) {
1911
+ this.advanceCurrentPacket();
1912
+ const currentPesPacket = this.getCurrentPesPacket();
1913
+ const relativeEndOffset = length - offset;
1914
+
1915
+ if (relativeEndOffset <= currentPesPacket.data.byteLength) {
1916
+ result.set(currentPesPacket.data.subarray(0, relativeEndOffset), offset);
1917
+ break;
1918
+ }
1919
+
1920
+ result.set(currentPesPacket.data, offset);
1921
+ offset += currentPesPacket.data.byteLength;
1922
+ }
1923
+
1924
+ return result;
1925
+ }
1926
+
1927
+ readU8() {
1928
+ let currentPesPacket = this.getCurrentPesPacket();
1929
+
1930
+ const relativeOffset = this.currentPos - this.currentPesPacketPos;
1931
+ this.currentPos++;
1932
+
1933
+ if (relativeOffset < currentPesPacket.data.byteLength) {
1934
+ return currentPesPacket.data[relativeOffset]!;
1935
+ }
1936
+
1937
+ this.advanceCurrentPacket();
1938
+
1939
+ currentPesPacket = this.getCurrentPesPacket();
1940
+ return currentPesPacket.data[0]!;
1941
+ }
1942
+
1943
+ seekTo(pos: number) {
1944
+ if (pos === this.currentPos) {
1945
+ return;
1946
+ }
1947
+
1948
+ if (pos < this.currentPos) {
1949
+ while (pos < this.currentPesPacketPos) {
1950
+ // Move to the previous PES packet
1951
+ this.currentPesPacketIndex--;
1952
+ const currentPacket = this.getCurrentPesPacket();
1953
+ this.currentPesPacketPos -= currentPacket.data.byteLength;
1954
+ }
1955
+ } else {
1956
+ while (true) {
1957
+ // Move to the next PES packet
1958
+ const currentPesPacket = this.getCurrentPesPacket();
1959
+ const currentEndPos = this.currentPesPacketPos + currentPesPacket.data.byteLength;
1960
+
1961
+ if (pos < currentEndPos) {
1962
+ break;
1963
+ }
1964
+
1965
+ this.currentPesPacketPos += currentPesPacket.data.byteLength;
1966
+ this.currentPesPacketIndex++;
1967
+ }
1968
+ }
1969
+
1970
+ this.currentPos = pos;
1971
+ }
1972
+
1973
+ skip(n: number) {
1974
+ this.seekTo(this.currentPos + n);
1975
+ }
1976
+
1977
+ advanceCurrentPacket() {
1978
+ this.currentPesPacketPos += this.getCurrentPesPacket().data.byteLength;
1979
+ this.currentPesPacketIndex++;
1980
+ }
1981
+
1982
+ async markNextPacket() {
1983
+ assert(!this.suppliedPacket);
1984
+
1985
+ const elementaryStream = this.elementaryStream;
1986
+
1987
+ if (elementaryStream.info.type === 'video') {
1988
+ // Our job here is to separate the video stream into access units. Sometimes this is easy (like when AUDs
1989
+ // are present), sometimes it's a little harder.
1990
+
1991
+ const codec = elementaryStream.info.codec;
1992
+ const CHUNK_SIZE = 1024;
1993
+
1994
+ if (codec !== 'avc' && codec !== 'hevc') {
1995
+ throw new Error('Unhandled.');
1996
+ }
1997
+
1998
+ const nalHeaderSize = codec === 'avc' ? 1 : 2;
1999
+ let packetStartPos: number | null = null;
2000
+ let frameStartFound = false;
2001
+ let lastFirstMacroblockInSlice = 0;
2002
+
2003
+ while (true) {
2004
+ let remaining = this.ensureBuffered(CHUNK_SIZE);
2005
+ if (remaining instanceof Promise) remaining = await remaining;
2006
+
2007
+ if (remaining === 0) {
2008
+ break;
2009
+ }
2010
+
2011
+ const chunkStartPos = this.currentPos;
2012
+ const chunk = this.readBytes(remaining);
2013
+ const length = chunk.byteLength;
2014
+
2015
+ let i = 0;
2016
+ while (i < length) {
2017
+ const zeroIndex = chunk.indexOf(0, i);
2018
+ if (zeroIndex === -1 || zeroIndex >= length) {
2019
+ break;
2020
+ }
2021
+ i = zeroIndex;
2022
+
2023
+ const posBeforeZero = chunkStartPos + i;
2024
+
2025
+ // Need 3 more bytes after the 0x00 to recognize a start code prefix
2026
+ if (i + 3 >= length) {
2027
+ // Not enough data in current chunk, seek back and let the next iteration handle it
2028
+ this.seekTo(posBeforeZero);
2029
+ break;
2030
+ }
2031
+
2032
+ const b1 = chunk[i + 1]!;
2033
+ const b2 = chunk[i + 2]!;
2034
+ const b3 = chunk[i + 3]!;
2035
+
2036
+ let startCodeLength = 0;
2037
+
2038
+ // Check for 4-byte start code (0x00000001)
2039
+ if (b1 === 0x00 && b2 === 0x00 && b3 === 0x01) {
2040
+ startCodeLength = 4;
2041
+ } else if (b1 === 0x00 && b2 === 0x01) {
2042
+ // 3-byte start code (0x000001)
2043
+ startCodeLength = 3;
2044
+ }
2045
+
2046
+ if (startCodeLength === 0) {
2047
+ // Not a start code, continue
2048
+ i++;
2049
+ continue;
2050
+ }
2051
+
2052
+ const startCodePos = posBeforeZero;
2053
+
2054
+ // The packet only really begins at the first NAL unit; anything before it isn't usable
2055
+ packetStartPos ??= startCodePos;
2056
+
2057
+ const nalHeaderStart = i + startCodeLength;
2058
+ const payloadStart = nalHeaderStart + nalHeaderSize;
2059
+
2060
+ // Bytes peeked from the start of a slice header to decode first_mb_in_slice. Six bytes (48 bits)
2061
+ // comfortably covers the exp-Golomb code for any realistic macroblock count
2062
+ const AVC_SLICE_HEADER_PEEK_SIZE = 6;
2063
+
2064
+ // We read the NAL header plus, for slices, the start of the slice header to decode the
2065
+ // first_mb_in_slice / first_slice_segment_in_pic_flag. Make sure all of it is buffered.
2066
+ const bytesNeeded = payloadStart + (codec === 'avc' ? AVC_SLICE_HEADER_PEEK_SIZE : 1);
2067
+ if (bytesNeeded > length) {
2068
+ this.seekTo(posBeforeZero);
2069
+ break;
2070
+ }
2071
+
2072
+ const headerByte0 = chunk[nalHeaderStart]!;
2073
+
2074
+ let nalUnitType: number;
2075
+ let isSlice: boolean;
2076
+ let isAccessUnitStart: boolean;
2077
+
2078
+ if (codec === 'avc') {
2079
+ nalUnitType = extractNalUnitTypeForAvc(headerByte0);
2080
+ isSlice = nalUnitType === AvcNalUnitType.NON_IDR_SLICE
2081
+ || nalUnitType === AvcNalUnitType.SLICE_DPA
2082
+ || nalUnitType === AvcNalUnitType.IDR;
2083
+ isAccessUnitStart = nalUnitType === AvcNalUnitType.SEI
2084
+ || nalUnitType === AvcNalUnitType.SPS
2085
+ || nalUnitType === AvcNalUnitType.PPS
2086
+ || nalUnitType === AvcNalUnitType.AUD;
2087
+ } else {
2088
+ nalUnitType = extractNalUnitTypeForHevc(headerByte0);
2089
+ const layerId = ((headerByte0 & 1) << 5) | (chunk[nalHeaderStart + 1]! >> 3);
2090
+ if (layerId > 0) {
2091
+ // Higher layers don't delimit the base-layer frames we care about
2092
+ i += startCodeLength;
2093
+ continue;
2094
+ }
2095
+
2096
+ // VCL slices: 0..RASL_R, plus the IRAP range BLA_W_LP..CRA_NUT
2097
+ isSlice = nalUnitType <= HevcNalUnitType.RASL_R
2098
+ || (nalUnitType >= HevcNalUnitType.BLA_W_LP && nalUnitType <= 21);
2099
+ // VPS..FD, prefix SEI, and the reserved/unspecified non-VCL ranges
2100
+ isAccessUnitStart = (nalUnitType >= HevcNalUnitType.VPS_NUT && nalUnitType <= 37)
2101
+ || nalUnitType === HevcNalUnitType.PREFIX_SEI_NUT
2102
+ || (nalUnitType >= 41 && nalUnitType <= 44)
2103
+ || (nalUnitType >= 48 && nalUnitType <= 55);
2104
+ }
2105
+
2106
+ let isFrameBoundary = false;
2107
+
2108
+ if (isSlice) {
2109
+ let startsNewPicture: boolean;
2110
+
2111
+ if (codec === 'avc') {
2112
+ const headerBytes = chunk.subarray(payloadStart, payloadStart + AVC_SLICE_HEADER_PEEK_SIZE);
2113
+ const firstMacroblockInSlice = readExpGolomb(new Bitstream(headerBytes));
2114
+ startsNewPicture = !frameStartFound || firstMacroblockInSlice <= lastFirstMacroblockInSlice;
2115
+ lastFirstMacroblockInSlice = firstMacroblockInSlice;
2116
+ } else {
2117
+ startsNewPicture = (chunk[payloadStart]! >> 7) === 1;
2118
+ }
2119
+
2120
+ if (startsNewPicture) {
2121
+ if (frameStartFound) {
2122
+ isFrameBoundary = true;
2123
+ } else {
2124
+ frameStartFound = true;
2125
+ }
2126
+ }
2127
+ } else if (isAccessUnitStart && frameStartFound) {
2128
+ isFrameBoundary = true;
2129
+ }
2130
+
2131
+ if (isFrameBoundary) {
2132
+ // End the packet at this start code (the next frame begins here)
2133
+ const packetLength = startCodePos - packetStartPos;
2134
+ this.seekTo(packetStartPos);
2135
+ return this.supplyPacket(packetLength, 0);
2136
+ }
2137
+
2138
+ i += startCodeLength;
2139
+ }
2140
+
2141
+ if (remaining < CHUNK_SIZE) {
2142
+ // End of stream
2143
+ break;
2144
+ }
2145
+ }
2146
+
2147
+ // End of stream - emit whatever's left as the final packet
2148
+ if (packetStartPos !== null && this.endPos > packetStartPos) {
2149
+ const packetLength = this.endPos - packetStartPos;
2150
+ this.seekTo(packetStartPos);
2151
+ return this.supplyPacket(packetLength, 0);
2152
+ }
2153
+ } else {
2154
+ const codec = elementaryStream.info.codec;
2155
+ const CHUNK_SIZE = 128;
2156
+
2157
+ while (true) {
2158
+ let remaining = this.ensureBuffered(CHUNK_SIZE);
2159
+ if (remaining instanceof Promise) remaining = await remaining;
2160
+
2161
+ const startPos = this.currentPos;
2162
+
2163
+ while (this.currentPos - startPos < remaining) {
2164
+ const byte = this.readU8();
2165
+
2166
+ if (codec === 'aac') {
2167
+ if (byte !== 0xff) {
2168
+ continue;
2169
+ }
2170
+
2171
+ this.skip(-1);
2172
+ const possibleHeaderStartPos = this.currentPos;
2173
+
2174
+ let remaining = this.ensureBuffered(MAX_ADTS_FRAME_HEADER_SIZE);
2175
+ if (remaining instanceof Promise) remaining = await remaining;
2176
+
2177
+ if (remaining < MAX_ADTS_FRAME_HEADER_SIZE) {
2178
+ return;
2179
+ }
2180
+
2181
+ const headerBytes = this.readBytes(MAX_ADTS_FRAME_HEADER_SIZE);
2182
+ const header = readAdtsFrameHeader(FileSlice.tempFromBytes(headerBytes));
2183
+
2184
+ if (header) {
2185
+ this.seekTo(possibleHeaderStartPos);
2186
+
2187
+ let remaining = this.ensureBuffered(header.frameLength);
2188
+ if (remaining instanceof Promise) remaining = await remaining;
2189
+
2190
+ return this.supplyPacket(
2191
+ remaining,
2192
+ Math.round(SAMPLES_PER_AAC_FRAME * TIMESCALE / elementaryStream.info.sampleRate),
2193
+ );
2194
+ } else {
2195
+ this.seekTo(possibleHeaderStartPos + 1);
2196
+ }
2197
+ } else if (codec === 'mp3') {
2198
+ if (byte !== 0xff) {
2199
+ continue;
2200
+ }
2201
+
2202
+ this.skip(-1);
2203
+ const possibleHeaderStartPos = this.currentPos;
2204
+
2205
+ let remaining = this.ensureBuffered(MP3_FRAME_HEADER_SIZE);
2206
+ if (remaining instanceof Promise) remaining = await remaining;
2207
+
2208
+ if (remaining < MP3_FRAME_HEADER_SIZE) {
2209
+ return;
2210
+ }
2211
+
2212
+ const headerBytes = this.readBytes(MP3_FRAME_HEADER_SIZE);
2213
+ const word = toDataView(headerBytes).getUint32(0);
2214
+ const result = readMp3FrameHeader(word, null);
2215
+
2216
+ if (result.header) {
2217
+ this.seekTo(possibleHeaderStartPos);
2218
+
2219
+ let remaining = this.ensureBuffered(result.header.totalSize);
2220
+ if (remaining instanceof Promise) remaining = await remaining;
2221
+
2222
+ const duration = result.header.audioSamplesInFrame * TIMESCALE
2223
+ / elementaryStream.info.sampleRate;
2224
+ return this.supplyPacket(remaining, Math.round(duration));
2225
+ } else {
2226
+ this.seekTo(possibleHeaderStartPos + 1);
2227
+ }
2228
+ } else if (codec === 'ac3') {
2229
+ if (byte !== 0x0b) {
2230
+ continue;
2231
+ }
2232
+
2233
+ this.skip(-1);
2234
+ const possibleSyncPos = this.currentPos;
2235
+
2236
+ // Need at least 5 bytes for sync word + CRC + fscod/frmsizecod
2237
+ let remaining = this.ensureBuffered(5);
2238
+ if (remaining instanceof Promise) remaining = await remaining;
2239
+
2240
+ if (remaining < 5) {
2241
+ return;
2242
+ }
2243
+
2244
+ const headerBytes = this.readBytes(5);
2245
+
2246
+ // Verify sync word (0x0B77)
2247
+ if (headerBytes[0] !== 0x0b || headerBytes[1] !== 0x77) {
2248
+ this.seekTo(possibleSyncPos + 1);
2249
+ continue;
2250
+ }
2251
+
2252
+ const fscod = headerBytes[4]! >> 6;
2253
+ const frmsizecod = headerBytes[4]! & 0x3f;
2254
+
2255
+ if (fscod === 3 || frmsizecod > 37) {
2256
+ // Invalid
2257
+ this.seekTo(possibleSyncPos + 1);
2258
+ continue;
2259
+ }
2260
+
2261
+ const frameSize = AC3_FRAME_SIZES[3 * frmsizecod + fscod];
2262
+ assert(frameSize !== undefined);
2263
+
2264
+ this.seekTo(possibleSyncPos);
2265
+
2266
+ remaining = this.ensureBuffered(frameSize);
2267
+ if (remaining instanceof Promise) remaining = await remaining;
2268
+
2269
+ const duration = Math.round(
2270
+ AC3_SAMPLES_PER_FRAME * TIMESCALE / elementaryStream.info.sampleRate,
2271
+ );
2272
+ return this.supplyPacket(remaining, duration);
2273
+ } else if (codec === 'eac3') {
2274
+ if (byte !== 0x0b) {
2275
+ continue;
2276
+ }
2277
+
2278
+ this.skip(-1);
2279
+ const possibleSyncPos = this.currentPos;
2280
+
2281
+ // Need at least 5 bytes for E-AC-3 header parsing (sync word + frmsiz + fscod/numblkscod)
2282
+ let remaining = this.ensureBuffered(5);
2283
+ if (remaining instanceof Promise) remaining = await remaining;
2284
+
2285
+ if (remaining < 5) {
2286
+ return;
2287
+ }
2288
+
2289
+ const headerBytes = this.readBytes(5);
2290
+
2291
+ if (headerBytes[0] !== 0x0b || headerBytes[1] !== 0x77) {
2292
+ this.seekTo(possibleSyncPos + 1);
2293
+ continue;
2294
+ }
2295
+
2296
+ const frmsiz = ((headerBytes[2]! & 0x07) << 8) | headerBytes[3]!;
2297
+ const frameSize = (frmsiz + 1) * 2;
2298
+ const fscod = headerBytes[4]! >> 6;
2299
+ const numblkscod = fscod === 3 ? 3 : (headerBytes[4]! >> 4) & 0x03;
2300
+ const numblks = EAC3_NUMBLKS_TABLE[numblkscod]!;
2301
+
2302
+ this.seekTo(possibleSyncPos);
2303
+
2304
+ remaining = this.ensureBuffered(frameSize);
2305
+ if (remaining instanceof Promise) remaining = await remaining;
2306
+
2307
+ // Duration = numblks * 256 samples per block
2308
+ const samplesPerFrame = numblks * 256;
2309
+ const duration = Math.round(
2310
+ samplesPerFrame * TIMESCALE / elementaryStream.info.sampleRate,
2311
+ );
2312
+ return this.supplyPacket(remaining, duration);
2313
+ } else {
2314
+ throw new Error('Unhandled.');
2315
+ }
2316
+ }
2317
+
2318
+ if (remaining < CHUNK_SIZE) {
2319
+ break;
2320
+ }
2321
+ }
2322
+ }
2323
+ }
2324
+
2325
+ /** Supplies the context with a new encoded packet, beginning at the current position. */
2326
+ supplyPacket(packetLength: number, intrinsicDuration: number) {
2327
+ const currentPesPacket = this.getCurrentPesPacket();
2328
+
2329
+ let pts: number;
2330
+ if (this.lastSuppliedPesPacket === currentPesPacket) {
2331
+ assert(this.nextPts !== null);
2332
+ pts = this.nextPts;
2333
+ } else {
2334
+ if (currentPesPacket.pts === null) {
2335
+ throw new Error(MISSING_PTS_ERROR_MESSAGE);
2336
+ }
2337
+
2338
+ pts = currentPesPacket.pts;
2339
+
2340
+ maybeInsertReferencePacket(this.elementaryStream, currentPesPacket as TimestampedPesPacket);
2341
+ }
2342
+
2343
+ this.lastSuppliedPesPacket = currentPesPacket;
2344
+ this.nextPts = pts + intrinsicDuration;
2345
+
2346
+ const sectionStartPos = currentPesPacket.sectionStartPos;
2347
+ // The sequence number is the starting position of the section the PES packet is in, PLUS the offset within the
2348
+ // PES packet where the packet starts.
2349
+ const sequenceNumber = sectionStartPos + (this.currentPos - this.currentPesPacketPos);
2350
+ const data = this.readBytes(packetLength);
2351
+
2352
+ let randomAccessIndicator = currentPesPacket.randomAccessIndicator;
2353
+
2354
+ if (randomAccessIndicator === 0 && !this.elementaryStream.canBeTrustedWithKeyPackets) {
2355
+ if (this.elementaryStream.info.type === 'audio') {
2356
+ randomAccessIndicator = 1;
2357
+ } else {
2358
+ if (this.elementaryStream.info.decoderConfig) {
2359
+ const isKey = determineVideoPacketType(
2360
+ this.elementaryStream.info.codec,
2361
+ this.elementaryStream.info.decoderConfig,
2362
+ data,
2363
+ ) === 'key';
2364
+
2365
+ randomAccessIndicator = Number(isKey);
2366
+ } else {
2367
+ // We're reading packets before the decoder config is determined
2368
+ }
2369
+ }
2370
+ }
2371
+
2372
+ this.suppliedPacket = {
2373
+ pts,
2374
+ data,
2375
+ sequenceNumber,
2376
+ sectionStartPos,
2377
+ randomAccessIndicator,
2378
+ };
2379
+
2380
+ this.pesPackets.splice(0, this.currentPesPacketIndex);
2381
+ this.currentPesPacketIndex = 0;
2382
+ }
2383
+ }
2384
+
2385
+ /**
2386
+ * A buffer that simulates decoder frame reordering to compute packet durations. Packets arrive in decode order but
2387
+ * durations are based on presentation order.
2388
+ */
2389
+ class PacketBuffer {
2390
+ backing: MpegTsTrackBacking;
2391
+ context: PacketReadingContext;
2392
+
2393
+ decodeOrderPackets: SuppliedPacket[] = [];
2394
+ reorderSize: number;
2395
+ reorderBuffer: SuppliedPacket[] = [];
2396
+ presentationOrderPackets: SuppliedPacket[] = [];
2397
+ reachedEnd = false;
2398
+ lastDuration = 0;
2399
+
2400
+ constructor(backing: MpegTsTrackBacking, context: PacketReadingContext) {
2401
+ this.backing = backing;
2402
+ this.context = context;
2403
+ this.reorderSize = backing.getReorderSize();
2404
+ assert(this.reorderSize >= 0);
2405
+ }
2406
+
2407
+ async readNext(): Promise<{ packet: SuppliedPacket; duration: number } | null> {
2408
+ if (this.decodeOrderPackets.length === 0) {
2409
+ // We need the next packet
2410
+ const didRead = await this.readNextPacket();
2411
+ if (!didRead) {
2412
+ return null;
2413
+ }
2414
+ }
2415
+
2416
+ // Ensure we know the next packet in presentation order so we can compute the current packet's duration
2417
+ await this.ensureCurrentPacketHasNext();
2418
+
2419
+ const packet = this.decodeOrderPackets[0]!;
2420
+
2421
+ // Let's compute the duration
2422
+ const presentationIndex = this.presentationOrderPackets.indexOf(packet);
2423
+ assert(presentationIndex !== -1);
2424
+
2425
+ let duration: number;
2426
+ if (presentationIndex === this.presentationOrderPackets.length - 1) {
2427
+ duration = this.lastDuration; // Reasonable heuristic
2428
+ } else {
2429
+ const nextPacket = this.presentationOrderPackets[presentationIndex + 1]!;
2430
+ duration = nextPacket.pts - packet.pts;
2431
+ this.lastDuration = duration;
2432
+ }
2433
+
2434
+ this.decodeOrderPackets.shift();
2435
+
2436
+ // Shrink the presentation array as much as possible
2437
+ while (this.presentationOrderPackets.length > 0) {
2438
+ const first = this.presentationOrderPackets[0]!;
2439
+ if (this.decodeOrderPackets.includes(first)) {
2440
+ break;
2441
+ }
2442
+
2443
+ this.presentationOrderPackets.shift();
2444
+ }
2445
+
2446
+ return { packet, duration };
2447
+ }
2448
+
2449
+ async readNextPacket() {
2450
+ if (this.reachedEnd) {
2451
+ return false;
2452
+ }
2453
+
2454
+ let suppliedPacket: SuppliedPacket | null;
2455
+ if (this.context.suppliedPacket) {
2456
+ // Small optimization: there was already a supplied packet in the context, so let's first use that one
2457
+ suppliedPacket = this.context.suppliedPacket;
2458
+ } else {
2459
+ await this.context.markNextPacket();
2460
+ suppliedPacket = this.context.suppliedPacket;
2461
+ }
2462
+ this.context.suppliedPacket = null;
2463
+
2464
+ if (!suppliedPacket) {
2465
+ this.reachedEnd = true;
2466
+ this.flushReorderBuffer();
2467
+
2468
+ return false;
2469
+ }
2470
+
2471
+ this.decodeOrderPackets.push(suppliedPacket);
2472
+ this.processPacketThroughReorderBuffer(suppliedPacket);
2473
+
2474
+ return true;
2475
+ }
2476
+
2477
+ async ensureCurrentPacketHasNext() {
2478
+ const current = this.decodeOrderPackets[0];
2479
+ assert(current);
2480
+
2481
+ while (true) {
2482
+ const presentationIndex = this.presentationOrderPackets.indexOf(current);
2483
+
2484
+ // Check if current packet has a next packet
2485
+ if (presentationIndex !== -1 && presentationIndex <= this.presentationOrderPackets.length - 2) {
2486
+ break;
2487
+ }
2488
+
2489
+ const didRead = await this.readNextPacket();
2490
+ if (!didRead) {
2491
+ break;
2492
+ }
2493
+ }
2494
+ }
2495
+
2496
+ processPacketThroughReorderBuffer(packet: SuppliedPacket) {
2497
+ this.reorderBuffer.push(packet);
2498
+
2499
+ // If buffer is now overfull, output the packet with smallest PTS
2500
+ if (this.reorderBuffer.length > this.reorderSize) {
2501
+ let minIndex = 0;
2502
+ for (let i = 1; i < this.reorderBuffer.length; i++) {
2503
+ if (this.reorderBuffer[i]!.pts < this.reorderBuffer[minIndex]!.pts) {
2504
+ minIndex = i;
2505
+ }
2506
+ }
2507
+
2508
+ const packet = this.reorderBuffer[minIndex]!;
2509
+ this.presentationOrderPackets.push(packet);
2510
+ this.reorderBuffer.splice(minIndex, 1);
2511
+ }
2512
+ }
2513
+
2514
+ flushReorderBuffer() {
2515
+ this.reorderBuffer.sort((a, b) => a.pts - b.pts);
2516
+ this.presentationOrderPackets.push(...this.reorderBuffer);
2517
+ this.reorderBuffer.length = 0;
2518
+ }
2519
+ }