omni-viewer-core 0.1.0

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 (387) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -0
  3. package/THIRD_PARTY_NOTICES.md +49 -0
  4. package/dist/assets/audio-engine/audio_engine.mjs +2 -0
  5. package/dist/assets/audio-engine/audio_engine.wasm +0 -0
  6. package/dist/assets/pdfjs/pdf.worker.min.mjs +21 -0
  7. package/dist/host/index.d.ts +133 -0
  8. package/dist/host/index.js +10 -0
  9. package/dist/i18n/catalog.en.d.ts +1 -0
  10. package/dist/i18n/catalog.en.js +411 -0
  11. package/dist/i18n/catalog.ko.d.ts +1 -0
  12. package/dist/i18n/catalog.ko.js +68 -0
  13. package/dist/i18n/index.d.ts +18 -0
  14. package/dist/i18n/index.js +41 -0
  15. package/dist/licenses/emscripten.txt +101 -0
  16. package/dist/licenses/kissfft.txt +28 -0
  17. package/dist/licenses/pdfjs-dist.txt +177 -0
  18. package/dist/parsers/a2l/index.d.ts +1 -0
  19. package/dist/parsers/a2l/index.js +1 -0
  20. package/dist/parsers/archive/index.d.ts +22 -0
  21. package/dist/parsers/archive/index.js +46 -0
  22. package/dist/parsers/archive/model.d.ts +29 -0
  23. package/dist/parsers/archive/model.js +1 -0
  24. package/dist/parsers/archive/worker.d.ts +21 -0
  25. package/dist/parsers/archive/worker.js +1 -0
  26. package/dist/parsers/arxml/index.d.ts +1 -0
  27. package/dist/parsers/arxml/index.js +1 -0
  28. package/dist/parsers/asc/index.d.ts +1 -0
  29. package/dist/parsers/asc/index.js +1 -0
  30. package/dist/parsers/audio/index.d.ts +9 -0
  31. package/dist/parsers/audio/index.js +46 -0
  32. package/dist/parsers/automotive/index.d.ts +33 -0
  33. package/dist/parsers/automotive/index.js +973 -0
  34. package/dist/parsers/blf/index.d.ts +1 -0
  35. package/dist/parsers/blf/index.js +1 -0
  36. package/dist/parsers/csv/delimiter.d.ts +31 -0
  37. package/dist/parsers/csv/delimiter.js +151 -0
  38. package/dist/parsers/csv/index.d.ts +30 -0
  39. package/dist/parsers/csv/index.js +108 -0
  40. package/dist/parsers/csv/parseText.d.ts +20 -0
  41. package/dist/parsers/csv/parseText.js +108 -0
  42. package/dist/parsers/csv/sort.d.ts +26 -0
  43. package/dist/parsers/csv/sort.js +224 -0
  44. package/dist/parsers/csv/statistics.d.ts +49 -0
  45. package/dist/parsers/csv/statistics.js +150 -0
  46. package/dist/parsers/dbc/index.d.ts +56 -0
  47. package/dist/parsers/dbc/index.js +94 -0
  48. package/dist/parsers/doc-binary/index.d.ts +35 -0
  49. package/dist/parsers/doc-binary/index.js +267 -0
  50. package/dist/parsers/doc-binary/vscode-parser.d.ts +142 -0
  51. package/dist/parsers/doc-binary/vscode-parser.js +3747 -0
  52. package/dist/parsers/excel/index.d.ts +17 -0
  53. package/dist/parsers/excel/index.js +406 -0
  54. package/dist/parsers/excel/model.d.ts +80 -0
  55. package/dist/parsers/excel/model.js +48 -0
  56. package/dist/parsers/excel/serialize.d.ts +3 -0
  57. package/dist/parsers/excel/serialize.js +78 -0
  58. package/dist/parsers/hdf5/index.d.ts +75 -0
  59. package/dist/parsers/hdf5/index.js +658 -0
  60. package/dist/parsers/hdf5/node.d.ts +21 -0
  61. package/dist/parsers/hdf5/node.js +95 -0
  62. package/dist/parsers/json/index.d.ts +15 -0
  63. package/dist/parsers/json/index.js +102 -0
  64. package/dist/parsers/json/model.d.ts +42 -0
  65. package/dist/parsers/json/model.js +140 -0
  66. package/dist/parsers/json/parse.d.ts +22 -0
  67. package/dist/parsers/json/parse.js +279 -0
  68. package/dist/parsers/json/tokenizer.d.ts +17 -0
  69. package/dist/parsers/json/tokenizer.js +175 -0
  70. package/dist/parsers/jsonl/index.d.ts +14 -0
  71. package/dist/parsers/jsonl/index.js +18 -0
  72. package/dist/parsers/jsonl/model.d.ts +23 -0
  73. package/dist/parsers/jsonl/model.js +1 -0
  74. package/dist/parsers/jsonl/parse.d.ts +7 -0
  75. package/dist/parsers/jsonl/parse.js +34 -0
  76. package/dist/parsers/markdown/index.d.ts +37 -0
  77. package/dist/parsers/markdown/index.js +59 -0
  78. package/dist/parsers/mat/index.d.ts +31 -0
  79. package/dist/parsers/mat/index.js +426 -0
  80. package/dist/parsers/mermaid/index.d.ts +5 -0
  81. package/dist/parsers/mermaid/index.js +3 -0
  82. package/dist/parsers/mf4/index.d.ts +1 -0
  83. package/dist/parsers/mf4/index.js +1 -0
  84. package/dist/parsers/parquet/index.d.ts +21 -0
  85. package/dist/parsers/parquet/index.js +68 -0
  86. package/dist/parsers/pcap/index.d.ts +1 -0
  87. package/dist/parsers/pcap/index.js +1 -0
  88. package/dist/parsers/pcapng/index.d.ts +1 -0
  89. package/dist/parsers/pcapng/index.js +1 -0
  90. package/dist/parsers/plantuml/index.d.ts +5 -0
  91. package/dist/parsers/plantuml/index.js +4 -0
  92. package/dist/parsers/ppt-binary/index.d.ts +5 -0
  93. package/dist/parsers/ppt-binary/index.js +62 -0
  94. package/dist/parsers/ppt-binary/pptBinaryBuildContext.d.ts +12 -0
  95. package/dist/parsers/ppt-binary/pptBinaryBuildContext.js +40 -0
  96. package/dist/parsers/ppt-binary/pptBinaryContainer.d.ts +4 -0
  97. package/dist/parsers/ppt-binary/pptBinaryContainer.js +174 -0
  98. package/dist/parsers/ppt-binary/pptBinaryTypes.d.ts +125 -0
  99. package/dist/parsers/ppt-binary/pptBinaryTypes.js +1 -0
  100. package/dist/parsers/ppt-binary/pptSlideLayouts.d.ts +9 -0
  101. package/dist/parsers/ppt-binary/pptSlideLayouts.js +510 -0
  102. package/dist/parsers/ppt-binary/vscode-parser.d.ts +116 -0
  103. package/dist/parsers/ppt-binary/vscode-parser.js +2853 -0
  104. package/dist/parsers/ppt-binary/vscode.d.ts +4 -0
  105. package/dist/parsers/ppt-binary/vscode.js +12 -0
  106. package/dist/parsers/pptx/index.d.ts +15 -0
  107. package/dist/parsers/pptx/index.js +88 -0
  108. package/dist/parsers/pptx/vscode-parser.d.ts +167 -0
  109. package/dist/parsers/pptx/vscode-parser.js +1503 -0
  110. package/dist/parsers/pptx/vscode.d.ts +4 -0
  111. package/dist/parsers/pptx/vscode.js +18 -0
  112. package/dist/parsers/pptx/zip-reader.d.ts +3 -0
  113. package/dist/parsers/pptx/zip-reader.js +20 -0
  114. package/dist/parsers/proto/index.d.ts +90 -0
  115. package/dist/parsers/proto/index.js +197 -0
  116. package/dist/parsers/psd/index.d.ts +16 -0
  117. package/dist/parsers/psd/index.js +10 -0
  118. package/dist/parsers/shapefile/dbf.d.ts +23 -0
  119. package/dist/parsers/shapefile/dbf.js +112 -0
  120. package/dist/parsers/shapefile/index.d.ts +44 -0
  121. package/dist/parsers/shapefile/index.js +119 -0
  122. package/dist/parsers/shapefile/reproject.d.ts +10 -0
  123. package/dist/parsers/shapefile/reproject.js +41 -0
  124. package/dist/parsers/slide-model.d.ts +106 -0
  125. package/dist/parsers/slide-model.js +1 -0
  126. package/dist/parsers/toml/index.d.ts +15 -0
  127. package/dist/parsers/toml/index.js +18 -0
  128. package/dist/parsers/toml/model.d.ts +15 -0
  129. package/dist/parsers/toml/model.js +1 -0
  130. package/dist/parsers/toml/parse.d.ts +16 -0
  131. package/dist/parsers/toml/parse.js +266 -0
  132. package/dist/parsers/types.d.ts +103 -0
  133. package/dist/parsers/types.js +106 -0
  134. package/dist/parsers/video/index.d.ts +6 -0
  135. package/dist/parsers/video/index.js +2 -0
  136. package/dist/parsers/yaml/index.d.ts +16 -0
  137. package/dist/parsers/yaml/index.js +58 -0
  138. package/dist/parsers/yaml/model.d.ts +22 -0
  139. package/dist/parsers/yaml/model.js +1 -0
  140. package/dist/parsers/yaml/self-loading.d.ts +3 -0
  141. package/dist/parsers/yaml/self-loading.js +19 -0
  142. package/dist/parsers/zip-scan.d.ts +8 -0
  143. package/dist/parsers/zip-scan.js +80 -0
  144. package/dist/registry/container.d.ts +17 -0
  145. package/dist/registry/container.js +49 -0
  146. package/dist/registry/index.d.ts +133 -0
  147. package/dist/registry/index.js +348 -0
  148. package/dist/registry/probe.d.ts +3 -0
  149. package/dist/registry/probe.js +177 -0
  150. package/dist/registry/sniff.d.ts +17 -0
  151. package/dist/registry/sniff.js +57 -0
  152. package/dist/styles/archive.css +10 -0
  153. package/dist/styles/audio.css +66 -0
  154. package/dist/styles/automotive.css +1 -0
  155. package/dist/styles/csv.css +262 -0
  156. package/dist/styles/excel.css +212 -0
  157. package/dist/styles/fallback.css +48 -0
  158. package/dist/styles/hdf5.css +3 -0
  159. package/dist/styles/hwp.css +12 -0
  160. package/dist/styles/image.css +115 -0
  161. package/dist/styles/json.css +342 -0
  162. package/dist/styles/jsonl.css +1 -0
  163. package/dist/styles/markdown.css +10 -0
  164. package/dist/styles/mat.css +2 -0
  165. package/dist/styles/mermaid.css +1 -0
  166. package/dist/styles/parquet.css +2 -0
  167. package/dist/styles/pdf.css +551 -0
  168. package/dist/styles/plantuml.css +1 -0
  169. package/dist/styles/ppt.css +1 -0
  170. package/dist/styles/proto.css +2 -0
  171. package/dist/styles/psd.css +1 -0
  172. package/dist/styles/shapefile.css +25 -0
  173. package/dist/styles/toml.css +1 -0
  174. package/dist/styles/video.css +74 -0
  175. package/dist/styles/word.css +685 -0
  176. package/dist/styles/yaml.css +1 -0
  177. package/dist/viewers/a2l/index.d.ts +15 -0
  178. package/dist/viewers/a2l/index.js +5 -0
  179. package/dist/viewers/archive/archive-preview-decoder.d.ts +4 -0
  180. package/dist/viewers/archive/archive-preview-decoder.js +223 -0
  181. package/dist/viewers/archive/controller.d.ts +24 -0
  182. package/dist/viewers/archive/controller.js +18 -0
  183. package/dist/viewers/archive/index.d.ts +25 -0
  184. package/dist/viewers/archive/index.js +230 -0
  185. package/dist/viewers/archive/preview.d.ts +2 -0
  186. package/dist/viewers/archive/preview.js +2 -0
  187. package/dist/viewers/archive/styles.d.ts +1 -0
  188. package/dist/viewers/archive/styles.js +11 -0
  189. package/dist/viewers/arxml/index.d.ts +15 -0
  190. package/dist/viewers/arxml/index.js +5 -0
  191. package/dist/viewers/asc/index.d.ts +15 -0
  192. package/dist/viewers/asc/index.js +5 -0
  193. package/dist/viewers/audio/controller.d.ts +33 -0
  194. package/dist/viewers/audio/controller.js +49 -0
  195. package/dist/viewers/audio/engine.d.ts +44 -0
  196. package/dist/viewers/audio/engine.js +108 -0
  197. package/dist/viewers/audio/index.d.ts +92 -0
  198. package/dist/viewers/audio/index.js +448 -0
  199. package/dist/viewers/audio/self-loading.d.ts +7 -0
  200. package/dist/viewers/audio/self-loading.js +42 -0
  201. package/dist/viewers/audio/styles.d.ts +1 -0
  202. package/dist/viewers/audio/styles.js +73 -0
  203. package/dist/viewers/automotive/index.d.ts +8 -0
  204. package/dist/viewers/automotive/index.js +152 -0
  205. package/dist/viewers/automotive/styles.d.ts +1 -0
  206. package/dist/viewers/automotive/styles.js +1 -0
  207. package/dist/viewers/avro/index.d.ts +15 -0
  208. package/dist/viewers/avro/index.js +5 -0
  209. package/dist/viewers/bag/index.d.ts +15 -0
  210. package/dist/viewers/bag/index.js +5 -0
  211. package/dist/viewers/blf/index.d.ts +15 -0
  212. package/dist/viewers/blf/index.js +5 -0
  213. package/dist/viewers/csv/controller.d.ts +126 -0
  214. package/dist/viewers/csv/controller.js +598 -0
  215. package/dist/viewers/csv/index.d.ts +48 -0
  216. package/dist/viewers/csv/index.js +846 -0
  217. package/dist/viewers/csv/styles.d.ts +1 -0
  218. package/dist/viewers/csv/styles.js +267 -0
  219. package/dist/viewers/db3/index.d.ts +15 -0
  220. package/dist/viewers/db3/index.js +5 -0
  221. package/dist/viewers/dbc/index.d.ts +15 -0
  222. package/dist/viewers/dbc/index.js +5 -0
  223. package/dist/viewers/diagram.d.ts +14 -0
  224. package/dist/viewers/diagram.js +95 -0
  225. package/dist/viewers/excel/controller.d.ts +108 -0
  226. package/dist/viewers/excel/controller.js +548 -0
  227. package/dist/viewers/excel/grid.d.ts +28 -0
  228. package/dist/viewers/excel/grid.js +99 -0
  229. package/dist/viewers/excel/index.d.ts +37 -0
  230. package/dist/viewers/excel/index.js +620 -0
  231. package/dist/viewers/excel/self-loading.d.ts +6 -0
  232. package/dist/viewers/excel/self-loading.js +13 -0
  233. package/dist/viewers/excel/styles.d.ts +1 -0
  234. package/dist/viewers/excel/styles.js +216 -0
  235. package/dist/viewers/fallback/index.d.ts +17 -0
  236. package/dist/viewers/fallback/index.js +130 -0
  237. package/dist/viewers/fallback/styles.d.ts +1 -0
  238. package/dist/viewers/fallback/styles.js +49 -0
  239. package/dist/viewers/hdf5/index.d.ts +19 -0
  240. package/dist/viewers/hdf5/index.js +170 -0
  241. package/dist/viewers/hdf5/styles.d.ts +1 -0
  242. package/dist/viewers/hdf5/styles.js +4 -0
  243. package/dist/viewers/hwp/controller.d.ts +19 -0
  244. package/dist/viewers/hwp/controller.js +22 -0
  245. package/dist/viewers/hwp/index.d.ts +39 -0
  246. package/dist/viewers/hwp/index.js +271 -0
  247. package/dist/viewers/hwp/self-loading.d.ts +2 -0
  248. package/dist/viewers/hwp/self-loading.js +6 -0
  249. package/dist/viewers/hwp/styles.d.ts +1 -0
  250. package/dist/viewers/hwp/styles.js +13 -0
  251. package/dist/viewers/image/controller.d.ts +210 -0
  252. package/dist/viewers/image/controller.js +336 -0
  253. package/dist/viewers/image/decode.d.ts +54 -0
  254. package/dist/viewers/image/decode.js +150 -0
  255. package/dist/viewers/image/index.d.ts +38 -0
  256. package/dist/viewers/image/index.js +749 -0
  257. package/dist/viewers/image/limits.d.ts +18 -0
  258. package/dist/viewers/image/limits.js +20 -0
  259. package/dist/viewers/image/styles.d.ts +1 -0
  260. package/dist/viewers/image/styles.js +119 -0
  261. package/dist/viewers/json/controller.d.ts +89 -0
  262. package/dist/viewers/json/controller.js +411 -0
  263. package/dist/viewers/json/index.d.ts +25 -0
  264. package/dist/viewers/json/index.js +503 -0
  265. package/dist/viewers/json/styles.d.ts +1 -0
  266. package/dist/viewers/json/styles.js +346 -0
  267. package/dist/viewers/json/transforms.d.ts +27 -0
  268. package/dist/viewers/json/transforms.js +253 -0
  269. package/dist/viewers/jsonl/controller.d.ts +48 -0
  270. package/dist/viewers/jsonl/controller.js +136 -0
  271. package/dist/viewers/jsonl/index.d.ts +22 -0
  272. package/dist/viewers/jsonl/index.js +184 -0
  273. package/dist/viewers/jsonl/styles.d.ts +1 -0
  274. package/dist/viewers/jsonl/styles.js +1 -0
  275. package/dist/viewers/markdown/controller.d.ts +50 -0
  276. package/dist/viewers/markdown/controller.js +62 -0
  277. package/dist/viewers/markdown/index.d.ts +64 -0
  278. package/dist/viewers/markdown/index.js +425 -0
  279. package/dist/viewers/markdown/math.d.ts +21 -0
  280. package/dist/viewers/markdown/math.js +100 -0
  281. package/dist/viewers/markdown/self-loading.d.ts +5 -0
  282. package/dist/viewers/markdown/self-loading.js +48 -0
  283. package/dist/viewers/markdown/styles.d.ts +1 -0
  284. package/dist/viewers/markdown/styles.js +11 -0
  285. package/dist/viewers/mat/index.d.ts +19 -0
  286. package/dist/viewers/mat/index.js +113 -0
  287. package/dist/viewers/mat/styles.d.ts +1 -0
  288. package/dist/viewers/mat/styles.js +3 -0
  289. package/dist/viewers/media.d.ts +9 -0
  290. package/dist/viewers/media.js +77 -0
  291. package/dist/viewers/mermaid/index.d.ts +17 -0
  292. package/dist/viewers/mermaid/index.js +6 -0
  293. package/dist/viewers/mermaid/self-loading.d.ts +2 -0
  294. package/dist/viewers/mermaid/self-loading.js +2 -0
  295. package/dist/viewers/mf4/index.d.ts +15 -0
  296. package/dist/viewers/mf4/index.js +5 -0
  297. package/dist/viewers/parquet/controller.d.ts +37 -0
  298. package/dist/viewers/parquet/controller.js +26 -0
  299. package/dist/viewers/parquet/index.d.ts +23 -0
  300. package/dist/viewers/parquet/index.js +134 -0
  301. package/dist/viewers/parquet/styles.d.ts +1 -0
  302. package/dist/viewers/parquet/styles.js +3 -0
  303. package/dist/viewers/pcap/index.d.ts +15 -0
  304. package/dist/viewers/pcap/index.js +5 -0
  305. package/dist/viewers/pcapng/index.d.ts +15 -0
  306. package/dist/viewers/pcapng/index.js +5 -0
  307. package/dist/viewers/pdf/controller.d.ts +120 -0
  308. package/dist/viewers/pdf/controller.js +191 -0
  309. package/dist/viewers/pdf/editing.d.ts +26 -0
  310. package/dist/viewers/pdf/editing.js +265 -0
  311. package/dist/viewers/pdf/index.d.ts +88 -0
  312. package/dist/viewers/pdf/index.js +1400 -0
  313. package/dist/viewers/pdf/self-loading.d.ts +6 -0
  314. package/dist/viewers/pdf/self-loading.js +14 -0
  315. package/dist/viewers/pdf/styles.d.ts +1 -0
  316. package/dist/viewers/pdf/styles.js +555 -0
  317. package/dist/viewers/plantuml/index.d.ts +17 -0
  318. package/dist/viewers/plantuml/index.js +6 -0
  319. package/dist/viewers/plantuml/self-loading.d.ts +2 -0
  320. package/dist/viewers/plantuml/self-loading.js +2 -0
  321. package/dist/viewers/ppt/chart.d.ts +8 -0
  322. package/dist/viewers/ppt/chart.js +83 -0
  323. package/dist/viewers/ppt/controller.d.ts +34 -0
  324. package/dist/viewers/ppt/controller.js +27 -0
  325. package/dist/viewers/ppt/index.d.ts +33 -0
  326. package/dist/viewers/ppt/index.js +101 -0
  327. package/dist/viewers/ppt/render.d.ts +5 -0
  328. package/dist/viewers/ppt/render.js +144 -0
  329. package/dist/viewers/ppt/self-loading.d.ts +9 -0
  330. package/dist/viewers/ppt/self-loading.js +4 -0
  331. package/dist/viewers/ppt/styles.d.ts +1 -0
  332. package/dist/viewers/ppt/styles.js +1 -0
  333. package/dist/viewers/proto/index.d.ts +17 -0
  334. package/dist/viewers/proto/index.js +170 -0
  335. package/dist/viewers/proto/styles.d.ts +1 -0
  336. package/dist/viewers/proto/styles.js +2 -0
  337. package/dist/viewers/psd/index.d.ts +27 -0
  338. package/dist/viewers/psd/index.js +39 -0
  339. package/dist/viewers/psd/self-loading.d.ts +10 -0
  340. package/dist/viewers/psd/self-loading.js +20 -0
  341. package/dist/viewers/psd/styles.d.ts +1 -0
  342. package/dist/viewers/psd/styles.js +1 -0
  343. package/dist/viewers/reqif/index.d.ts +15 -0
  344. package/dist/viewers/reqif/index.js +5 -0
  345. package/dist/viewers/shapefile/index.d.ts +35 -0
  346. package/dist/viewers/shapefile/index.js +336 -0
  347. package/dist/viewers/shapefile/self-loading.d.ts +7 -0
  348. package/dist/viewers/shapefile/self-loading.js +32 -0
  349. package/dist/viewers/shapefile/styles.d.ts +1 -0
  350. package/dist/viewers/shapefile/styles.js +28 -0
  351. package/dist/viewers/stp/index.d.ts +15 -0
  352. package/dist/viewers/stp/index.js +5 -0
  353. package/dist/viewers/structured-styles.d.ts +1 -0
  354. package/dist/viewers/structured-styles.js +1 -0
  355. package/dist/viewers/structured.d.ts +36 -0
  356. package/dist/viewers/structured.js +138 -0
  357. package/dist/viewers/toml/controller.d.ts +38 -0
  358. package/dist/viewers/toml/controller.js +61 -0
  359. package/dist/viewers/toml/index.d.ts +18 -0
  360. package/dist/viewers/toml/index.js +34 -0
  361. package/dist/viewers/types.d.ts +36 -0
  362. package/dist/viewers/types.js +9 -0
  363. package/dist/viewers/video/controller.d.ts +29 -0
  364. package/dist/viewers/video/controller.js +54 -0
  365. package/dist/viewers/video/index.d.ts +18 -0
  366. package/dist/viewers/video/index.js +305 -0
  367. package/dist/viewers/video/styles.d.ts +1 -0
  368. package/dist/viewers/video/styles.js +79 -0
  369. package/dist/viewers/word/controller.d.ts +19 -0
  370. package/dist/viewers/word/controller.js +22 -0
  371. package/dist/viewers/word/docx-preprocess.d.ts +63 -0
  372. package/dist/viewers/word/docx-preprocess.js +136 -0
  373. package/dist/viewers/word/index.d.ts +32 -0
  374. package/dist/viewers/word/index.js +187 -0
  375. package/dist/viewers/word/normalize-docx.d.ts +2 -0
  376. package/dist/viewers/word/normalize-docx.js +50 -0
  377. package/dist/viewers/word/paginate.d.ts +1 -0
  378. package/dist/viewers/word/paginate.js +1035 -0
  379. package/dist/viewers/word/self-loading.d.ts +2 -0
  380. package/dist/viewers/word/self-loading.js +7 -0
  381. package/dist/viewers/word/styles.d.ts +1 -0
  382. package/dist/viewers/word/styles.js +686 -0
  383. package/dist/viewers/yaml/controller.d.ts +42 -0
  384. package/dist/viewers/yaml/controller.js +41 -0
  385. package/dist/viewers/yaml/index.d.ts +21 -0
  386. package/dist/viewers/yaml/index.js +20 -0
  387. package/package.json +375 -0
@@ -0,0 +1,38 @@
1
+ import { type TomlNode } from '../../parsers/toml/index.js';
2
+ import type { Diagnostic } from '../../parsers/types.js';
3
+ export type TomlAction = {
4
+ type: 'set-mode';
5
+ mode: 'tree' | 'flat' | 'json' | 'raw';
6
+ } | {
7
+ type: 'set-search';
8
+ search: string;
9
+ } | {
10
+ type: 'toggle-node';
11
+ id: string;
12
+ } | {
13
+ type: 'expand-all';
14
+ } | {
15
+ type: 'collapse-all';
16
+ } | {
17
+ type: 'edit-source';
18
+ text: string;
19
+ };
20
+ export interface TomlViewState {
21
+ status: 'ok' | 'partial' | 'failed';
22
+ root: TomlNode | null;
23
+ text: string;
24
+ mode: 'tree' | 'flat' | 'json' | 'raw';
25
+ diagnostics: readonly Diagnostic[];
26
+ search: string;
27
+ expanded: ReadonlySet<string>;
28
+ }
29
+ export interface TomlController {
30
+ readonly state: TomlViewState;
31
+ dispatch(action: TomlAction): void;
32
+ subscribe(listener: (state: TomlViewState) => void): () => void;
33
+ nodePath(id: string): string;
34
+ nodeValue(id: string): string;
35
+ nodeJson(id: string): string;
36
+ documentJson(): string;
37
+ }
38
+ export declare function createTomlController(input: Uint8Array | string): TomlController;
@@ -0,0 +1,61 @@
1
+ import { asciiLower } from '../../parsers/csv/index.js';
2
+ import { parseToml } from '../../parsers/toml/index.js';
3
+ export function createTomlController(input) {
4
+ const listeners = new Set();
5
+ const nodes = new Map();
6
+ const decode = (value) => typeof value === 'string' ? value : new TextDecoder().decode(value);
7
+ const state = { status: 'ok', root: null, text: decode(input), mode: 'tree', diagnostics: [], search: '', expanded: new Set() };
8
+ const index = () => {
9
+ nodes.clear();
10
+ const result = parseToml(state.text).result;
11
+ state.status = result.status;
12
+ state.diagnostics = result.diagnostics;
13
+ state.root = result.status === 'failed' ? null : result.document.root;
14
+ const walk = (node) => { nodes.set(node.path || '$', node); for (const child of node.children ?? [])
15
+ walk(child); };
16
+ if (state.root)
17
+ walk(state.root);
18
+ };
19
+ const plain = (node) => node.children ? node.kind === 'array' ? node.children.map(plain) : Object.fromEntries(node.children.map(child => [child.key, plain(child)])) : node.kind === 'integer' || node.kind === 'float' || node.kind === 'datetime' ? node.raw : node.value;
20
+ const notify = () => listeners.forEach(listener => listener(state));
21
+ index();
22
+ if (state.root)
23
+ state.expanded = new Set([state.root.path || '$', ...(state.root.children ?? []).filter(node => !!node.children?.length).map(node => node.path)]);
24
+ return {
25
+ state,
26
+ subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); },
27
+ nodePath: id => nodes.get(id)?.path ?? '', nodeValue: id => nodes.get(id)?.raw ?? '',
28
+ nodeJson: id => JSON.stringify(plain(nodes.get(id) ?? state.root), null, 2),
29
+ documentJson: () => state.root ? JSON.stringify(plain(state.root), null, 2) : '',
30
+ dispatch(action) {
31
+ if (action.type === 'edit-source') {
32
+ state.text = action.text;
33
+ index();
34
+ }
35
+ else if (action.type === 'set-mode')
36
+ state.mode = action.mode;
37
+ else if (action.type === 'set-search') {
38
+ state.search = action.search;
39
+ const query = asciiLower(action.search);
40
+ if (query)
41
+ nodes.forEach(node => { if (asciiLower(`${node.key} ${node.path} ${node.raw}`).includes(query)) {
42
+ let current = node;
43
+ while (current) {
44
+ state.expanded = new Set([...state.expanded, current.path || '$']);
45
+ current = [...nodes.values()].find(candidate => candidate.children?.includes(current));
46
+ }
47
+ } });
48
+ }
49
+ else if (action.type === 'toggle-node') {
50
+ const expanded = new Set(state.expanded);
51
+ expanded.has(action.id) ? expanded.delete(action.id) : expanded.add(action.id);
52
+ state.expanded = expanded;
53
+ }
54
+ else if (action.type === 'expand-all')
55
+ state.expanded = new Set(nodes.keys());
56
+ else
57
+ state.expanded = new Set();
58
+ notify();
59
+ }
60
+ };
61
+ }
@@ -0,0 +1,18 @@
1
+ import type { ClipboardService, FileSaveService, FileWritebackService, HostContext } from '../../host/index.js';
2
+ import type { MountOptions, ViewerHandle, ViewerInput } from '../types.js';
3
+ export * from './controller.js';
4
+ export { structuredViewerCss as tomlViewerCss } from '../structured-styles.js';
5
+ export declare const TOML_VIEWER_META: {
6
+ id: string;
7
+ displayNameKey: string;
8
+ extensions: string[];
9
+ priority: number;
10
+ requiredServices: readonly [];
11
+ optionalServices: readonly ["clipboard", "save", "writeback"];
12
+ inputOwnership: "borrows";
13
+ };
14
+ export declare function mountTomlViewer(input: ViewerInput, container: HTMLElement, ctx: HostContext & {
15
+ clipboard?: ClipboardService;
16
+ save?: FileSaveService;
17
+ writeback?: FileWritebackService;
18
+ }, options?: MountOptions): Promise<ViewerHandle>;
@@ -0,0 +1,34 @@
1
+ import { mountStructured } from '../structured.js';
2
+ import { structuredViewerCss } from '../structured-styles.js';
3
+ import { createTomlController } from './controller.js';
4
+ export * from './controller.js';
5
+ export { structuredViewerCss as tomlViewerCss } from '../structured-styles.js';
6
+ export const TOML_VIEWER_META = { id: 'toml', displayNameKey: 'toml.treeView', extensions: ['toml'], priority: 10, requiredServices: [], optionalServices: ['clipboard', 'save', 'writeback'], inputOwnership: 'borrows' };
7
+ /** Lightweight TOML source highlighting that preserves the editable textarea. */
8
+ function renderTomlSource(target, text) {
9
+ target.replaceChildren();
10
+ const span = (className, value) => {
11
+ const node = document.createElement('span');
12
+ node.className = className;
13
+ node.textContent = value;
14
+ return node;
15
+ };
16
+ for (const line of text.split('\n')) {
17
+ const commentAt = line.search(/\s#/);
18
+ const source = commentAt >= 0 ? line.slice(0, commentAt) : line;
19
+ const comment = commentAt >= 0 ? line.slice(commentAt) : '';
20
+ const table = /^(\s*\[\[?.+?\]?\]\s*)$/.exec(source);
21
+ const assignment = /^(\s*[^=]+?\s*)(=)(.*)$/.exec(source);
22
+ if (table)
23
+ target.appendChild(span('omni-structured__source-table', source));
24
+ else if (assignment) {
25
+ target.append(span('omni-structured__source-key', assignment[1]), document.createTextNode('='), span('omni-structured__source-value', assignment[3]));
26
+ }
27
+ else
28
+ target.appendChild(document.createTextNode(source));
29
+ if (comment)
30
+ target.appendChild(span('omni-structured__source-comment', comment));
31
+ target.appendChild(document.createTextNode('\n'));
32
+ }
33
+ }
34
+ export function mountTomlViewer(input, container, ctx, options = {}) { return Promise.resolve(mountStructured(input, container, ctx, options, 'omni-viewer--toml', structuredViewerCss, createTomlController(input.data), renderTomlSource)); }
@@ -0,0 +1,36 @@
1
+ export interface ViewerInput {
2
+ fileName: string;
3
+ /** Whole file bytes. Streaming readers are a v2 concern. */
4
+ data: Uint8Array;
5
+ lastModified?: number;
6
+ }
7
+ export interface ViewerHandle {
8
+ /**
9
+ * Tear down the viewer: cancel in-flight async work, remove listeners,
10
+ * terminate workers, clear the container. Nothing may remain after this
11
+ * call (verified by the viewer contract tests).
12
+ */
13
+ dispose(): void;
14
+ }
15
+ export interface MountOptions {
16
+ /**
17
+ * Cancels initialization (tab switch, file reselect). When aborted, mount
18
+ * rejects with an 'aborted' error after cleaning up anything it acquired.
19
+ */
20
+ signal?: AbortSignal;
21
+ /**
22
+ * Style isolation mode (DESIGN.md §6 reverse-contamination contract).
23
+ * 'shadow' (default): render inside a shadow root with core CSS injected
24
+ * there — host global styles cannot leak in, and --omni-* custom
25
+ * properties still pierce the boundary.
26
+ * 'scoped': render directly into the container under a scope class; the
27
+ * adapter is responsible for loading the core CSS into the document.
28
+ */
29
+ styleIsolation?: 'shadow' | 'scoped';
30
+ }
31
+ export declare class MountAbortedError extends Error {
32
+ readonly name = "MountAbortedError";
33
+ constructor();
34
+ }
35
+ /** Root scope class applied to every core viewer root element. */
36
+ export declare const VIEWER_ROOT_CLASS = "omni-viewer";
@@ -0,0 +1,9 @@
1
+ // Viewer layer contracts (DESIGN.md §3-②).
2
+ export class MountAbortedError extends Error {
3
+ name = 'MountAbortedError';
4
+ constructor() {
5
+ super('mount aborted');
6
+ }
7
+ }
8
+ /** Root scope class applied to every core viewer root element. */
9
+ export const VIEWER_ROOT_CLASS = 'omni-viewer';
@@ -0,0 +1,29 @@
1
+ export declare const VIDEO_MIN_ZOOM = 0.25;
2
+ export declare const VIDEO_MAX_ZOOM = 4;
3
+ export declare const VIDEO_ZOOM_STEP = 0.25;
4
+ export declare const VIDEO_SPEED_OPTIONS: readonly [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4];
5
+ export interface VideoViewState {
6
+ zoom: number;
7
+ speed: number;
8
+ }
9
+ export type VideoAction = {
10
+ type: 'zoom-in';
11
+ } | {
12
+ type: 'zoom-out';
13
+ } | {
14
+ type: 'zoom-fit';
15
+ } | {
16
+ type: 'set-zoom';
17
+ zoom: number;
18
+ } | {
19
+ type: 'set-speed';
20
+ speed: number;
21
+ };
22
+ export interface VideoController {
23
+ readonly state: VideoViewState;
24
+ dispatch(action: VideoAction): void;
25
+ subscribe(listener: (state: VideoViewState) => void): () => void;
26
+ }
27
+ export declare function createVideoController(): VideoController;
28
+ /** mm:ss (or h:mm:ss) display used by the progress row and info panel. */
29
+ export declare function formatMediaTime(seconds: number): string;
@@ -0,0 +1,54 @@
1
+ // DOM-free playback presentation state for the video viewer. Time/played
2
+ // state lives on the media element (the browser owns it); the controller only
3
+ // holds the pure, testable knobs the toolbar mutates: zoom and playback speed.
4
+ export const VIDEO_MIN_ZOOM = 0.25;
5
+ export const VIDEO_MAX_ZOOM = 4;
6
+ export const VIDEO_ZOOM_STEP = 0.25;
7
+ export const VIDEO_SPEED_OPTIONS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 4];
8
+ const clampZoom = (zoom) => Math.min(VIDEO_MAX_ZOOM, Math.max(VIDEO_MIN_ZOOM, Math.round(zoom / VIDEO_ZOOM_STEP) * VIDEO_ZOOM_STEP));
9
+ export function createVideoController() {
10
+ let zoom = 1;
11
+ let speed = 1;
12
+ const listeners = new Set();
13
+ const snapshot = () => ({ zoom, speed });
14
+ const emit = () => listeners.forEach((listener) => listener(snapshot()));
15
+ return {
16
+ get state() { return snapshot(); },
17
+ dispatch(action) {
18
+ const before = snapshot();
19
+ switch (action.type) {
20
+ case 'zoom-in':
21
+ zoom = clampZoom(zoom + VIDEO_ZOOM_STEP);
22
+ break;
23
+ case 'zoom-out':
24
+ zoom = clampZoom(zoom - VIDEO_ZOOM_STEP);
25
+ break;
26
+ case 'zoom-fit':
27
+ zoom = 1;
28
+ break;
29
+ case 'set-zoom':
30
+ zoom = clampZoom(action.zoom);
31
+ break;
32
+ case 'set-speed':
33
+ if (VIDEO_SPEED_OPTIONS.includes(action.speed))
34
+ speed = action.speed;
35
+ break;
36
+ }
37
+ if (zoom !== before.zoom || speed !== before.speed)
38
+ emit();
39
+ },
40
+ subscribe(listener) {
41
+ listeners.add(listener);
42
+ return () => listeners.delete(listener);
43
+ }
44
+ };
45
+ }
46
+ /** mm:ss (or h:mm:ss) display used by the progress row and info panel. */
47
+ export function formatMediaTime(seconds) {
48
+ if (!Number.isFinite(seconds) || seconds < 0)
49
+ return '0:00';
50
+ const whole = Math.floor(seconds);
51
+ const h = Math.floor(whole / 3600), m = Math.floor((whole % 3600) / 60), s = whole % 60;
52
+ const ms = `${m}:${String(s).padStart(2, '0')}`;
53
+ return h > 0 ? `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}` : ms;
54
+ }
@@ -0,0 +1,18 @@
1
+ import type { HostContext } from '../../host/index.js';
2
+ import type { MediaMountOptions } from '../media.js';
3
+ import { type ViewerHandle, type ViewerInput } from '../types.js';
4
+ export { parseVideoInfo } from '../../parsers/video/index.js';
5
+ export { videoViewerCss } from './styles.js';
6
+ export { createVideoController, formatMediaTime, VIDEO_MIN_ZOOM, VIDEO_MAX_ZOOM, VIDEO_ZOOM_STEP, VIDEO_SPEED_OPTIONS, type VideoAction, type VideoController, type VideoViewState } from './controller.js';
7
+ export type VideoViewerContext = HostContext;
8
+ export type VideoMountOptions = MediaMountOptions;
9
+ export declare const VIDEO_VIEWER_META: {
10
+ id: string;
11
+ displayNameKey: string;
12
+ extensions: string[];
13
+ priority: number;
14
+ requiredServices: readonly [];
15
+ optionalServices: readonly [];
16
+ inputOwnership: "borrows";
17
+ };
18
+ export declare function mountVideoViewer(input: ViewerInput, container: HTMLElement, ctx: VideoViewerContext, options?: VideoMountOptions): Promise<ViewerHandle>;
@@ -0,0 +1,305 @@
1
+ import { parseVideoInfo } from '../../parsers/video/index.js';
2
+ import { MountAbortedError, VIEWER_ROOT_CLASS } from '../types.js';
3
+ import { createVideoController, formatMediaTime, VIDEO_SPEED_OPTIONS } from './controller.js';
4
+ import { videoViewerCss } from './styles.js';
5
+ export { parseVideoInfo } from '../../parsers/video/index.js';
6
+ export { videoViewerCss } from './styles.js';
7
+ export { createVideoController, formatMediaTime, VIDEO_MIN_ZOOM, VIDEO_MAX_ZOOM, VIDEO_ZOOM_STEP, VIDEO_SPEED_OPTIONS } from './controller.js';
8
+ export const VIDEO_VIEWER_META = {
9
+ id: 'video',
10
+ displayNameKey: 'video.title',
11
+ extensions: ['mp4', 'mts', 'm2ts', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv'],
12
+ priority: 20,
13
+ requiredServices: [],
14
+ optionalServices: [],
15
+ inputOwnership: 'borrows'
16
+ };
17
+ const SKIP_SECONDS = 10;
18
+ const DEFAULT_MAX_BYTES = 128 * 1024 * 1024;
19
+ export async function mountVideoViewer(input, container, ctx, options = {}) {
20
+ if (options.signal?.aborted)
21
+ throw new MountAbortedError();
22
+ const t = (key, args) => ctx.i18n.t(key, args);
23
+ const info = parseVideoInfo(input.fileName, input.data);
24
+ const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
25
+ const root = options.styleIsolation !== 'scoped' && container.attachShadow
26
+ ? (container.shadowRoot ?? container.attachShadow({ mode: 'open' }))
27
+ : container;
28
+ if (root === container)
29
+ container.classList.add(VIEWER_ROOT_CLASS, 'omni-viewer--video');
30
+ else {
31
+ const style = document.createElement('style');
32
+ style.textContent = videoViewerCss;
33
+ root.append(style);
34
+ }
35
+ const controller = createVideoController();
36
+ const disposers = [];
37
+ const listen = (target, type, handler, opts) => {
38
+ target.addEventListener(type, handler, opts);
39
+ disposers.push(() => target.removeEventListener(type, handler, opts));
40
+ };
41
+ const shell = element('section', `${VIEWER_ROOT_CLASS} omni-video`);
42
+ shell.tabIndex = 0;
43
+ // Header: file name + mime/size.
44
+ const header = element('header', 'omni-video__header');
45
+ header.append(element('div', 'omni-video__title', input.fileName), element('div', 'omni-video__meta', `${info.mimeType} · ${formatBytes(input.data.byteLength)}`));
46
+ // File info panel (populated on loadedmetadata).
47
+ const infoPanel = element('div', 'omni-video__info');
48
+ infoPanel.hidden = true;
49
+ const durationValue = infoItem(infoPanel, t('video.info.duration'));
50
+ const resolutionValue = infoItem(infoPanel, t('video.info.resolution'));
51
+ const formatValue = infoItem(infoPanel, t('video.info.format'));
52
+ const sizeValue = infoItem(infoPanel, t('video.info.fileSize'));
53
+ formatValue.textContent = info.format;
54
+ sizeValue.textContent = formatBytes(input.data.byteLength);
55
+ // Toolbar.
56
+ const controls = element('div', 'omni-video__controls');
57
+ const playPause = button(t('video.play'));
58
+ const stop = button(t('video.stop'));
59
+ const skipBack = button(t('video.skipBack', { seconds: SKIP_SECONDS }));
60
+ const skipForward = button(t('video.skipForward', { seconds: SKIP_SECONDS }));
61
+ const transportGroup = element('div', 'omni-video__group');
62
+ transportGroup.append(playPause, stop, skipBack, skipForward);
63
+ const speedGroup = element('div', 'omni-video__group');
64
+ const speedLabel = element('label', 'omni-video__group-label', t('video.speed'));
65
+ const speedSelect = document.createElement('select');
66
+ speedSelect.className = 'omni-video__select';
67
+ for (const speed of VIDEO_SPEED_OPTIONS) {
68
+ const option = document.createElement('option');
69
+ option.value = String(speed);
70
+ option.textContent = `${speed}x`;
71
+ option.selected = speed === 1;
72
+ speedSelect.append(option);
73
+ }
74
+ speedLabel.append(speedSelect);
75
+ speedGroup.append(speedLabel);
76
+ const zoomGroup = element('div', 'omni-video__group');
77
+ const zoomOut = button('−', t('video.zoomOut'));
78
+ const zoomLabel = element('span', 'omni-video__zoom-label', '100%');
79
+ const zoomIn = button('+', t('video.zoomIn'));
80
+ const zoomFit = button(t('video.zoomFit'));
81
+ zoomGroup.append(element('span', 'omni-video__group-label', t('video.zoom')), zoomOut, zoomLabel, zoomIn, zoomFit);
82
+ controls.append(transportGroup, speedGroup, zoomGroup);
83
+ // Progress row.
84
+ const progressRow = element('div', 'omni-video__progress-row');
85
+ const currentTime = element('span', 'omni-video__time', '0:00');
86
+ const bar = element('div', 'omni-video__bar');
87
+ const barFilled = element('div', 'omni-video__bar-filled');
88
+ barFilled.append(element('div', 'omni-video__bar-handle'));
89
+ bar.append(barFilled);
90
+ const totalTime = element('span', 'omni-video__time', '0:00');
91
+ progressRow.append(currentTime, bar, totalTime);
92
+ // Stage.
93
+ const stage = element('main', 'omni-video__stage');
94
+ const wrapper = element('div', 'omni-video__wrapper');
95
+ const video = document.createElement('video');
96
+ video.preload = input.data.byteLength > 50 * 1024 * 1024 ? 'metadata' : 'auto';
97
+ wrapper.append(video);
98
+ const warning = element('div', 'omni-video__warning');
99
+ warning.hidden = true;
100
+ shell.append(header, infoPanel, controls, progressRow, stage, warning);
101
+ root.append(shell);
102
+ const showWarning = (message) => {
103
+ warning.hidden = false;
104
+ warning.textContent = [...info.warnings, message].filter(Boolean).join('\n');
105
+ };
106
+ const setControlsEnabled = (enabled) => {
107
+ for (const control of [playPause, stop, skipBack, skipForward, speedSelect, zoomOut, zoomIn, zoomFit]) {
108
+ control.disabled = !enabled;
109
+ }
110
+ };
111
+ let url;
112
+ let hasSource = false;
113
+ if (input.data.byteLength === 0)
114
+ showWarning(t('video.error.empty'));
115
+ else if (input.data.byteLength > maxBytes)
116
+ showWarning(t('video.error.tooLarge', { limit: formatBytes(maxBytes) }));
117
+ else {
118
+ try {
119
+ const create = options.createObjectUrl ?? URL.createObjectURL.bind(URL);
120
+ url = create(new Blob([blobPart(input.data)], { type: info.mimeType }));
121
+ video.src = url;
122
+ stage.append(wrapper);
123
+ hasSource = true;
124
+ if (info.warnings.length)
125
+ showWarning('');
126
+ }
127
+ catch {
128
+ showWarning(t('video.error.source'));
129
+ }
130
+ }
131
+ setControlsEnabled(hasSource);
132
+ // Media element wiring.
133
+ const refreshProgress = () => {
134
+ currentTime.textContent = formatMediaTime(video.currentTime);
135
+ if (Number.isFinite(video.duration) && video.duration > 0) {
136
+ barFilled.style.width = `${(video.currentTime / video.duration) * 100}%`;
137
+ }
138
+ };
139
+ listen(video, 'loadedmetadata', () => {
140
+ totalTime.textContent = formatMediaTime(video.duration);
141
+ durationValue.textContent = formatMediaTime(video.duration);
142
+ if (video.videoWidth && video.videoHeight)
143
+ resolutionValue.textContent = `${video.videoWidth}×${video.videoHeight}`;
144
+ infoPanel.hidden = false;
145
+ });
146
+ listen(video, 'play', () => { playPause.textContent = t('video.pause'); });
147
+ listen(video, 'pause', () => { playPause.textContent = t('video.play'); });
148
+ listen(video, 'ended', () => { playPause.textContent = t('video.play'); });
149
+ listen(video, 'timeupdate', () => { if (!dragging)
150
+ refreshProgress(); });
151
+ listen(video, 'error', () => showWarning(t('video.error.decode')));
152
+ // Transport.
153
+ listen(playPause, 'click', () => {
154
+ if (video.paused || video.ended)
155
+ void video.play()?.catch?.(() => showWarning(t('video.error.decode')));
156
+ else
157
+ video.pause();
158
+ });
159
+ listen(stop, 'click', () => { video.pause(); video.currentTime = 0; refreshProgress(); });
160
+ listen(skipBack, 'click', () => { video.currentTime = Math.max(0, video.currentTime - SKIP_SECONDS); refreshProgress(); });
161
+ listen(skipForward, 'click', () => {
162
+ const limit = Number.isFinite(video.duration) ? video.duration : video.currentTime + SKIP_SECONDS;
163
+ video.currentTime = Math.min(limit, video.currentTime + SKIP_SECONDS);
164
+ refreshProgress();
165
+ });
166
+ listen(speedSelect, 'change', () => controller.dispatch({ type: 'set-speed', speed: Number(speedSelect.value) }));
167
+ // Seek by click/drag on the progress bar. Document-level listeners are
168
+ // required for drags that leave the bar; both are torn down on dispose.
169
+ let dragging = false;
170
+ const seekToPointer = (event) => {
171
+ const rect = bar.getBoundingClientRect();
172
+ if (rect.width <= 0 || !Number.isFinite(video.duration) || video.duration <= 0)
173
+ return;
174
+ const ratio = Math.max(0, Math.min(1, (event.clientX - rect.left) / rect.width));
175
+ video.currentTime = ratio * video.duration;
176
+ barFilled.style.width = `${ratio * 100}%`;
177
+ currentTime.textContent = formatMediaTime(video.currentTime);
178
+ };
179
+ listen(bar, 'mousedown', (event) => {
180
+ if (!hasSource)
181
+ return;
182
+ dragging = true;
183
+ bar.classList.add('omni-video__bar--dragging');
184
+ seekToPointer(event);
185
+ });
186
+ listen(document, 'mousemove', (event) => { if (dragging)
187
+ seekToPointer(event); });
188
+ listen(document, 'mouseup', () => {
189
+ if (!dragging)
190
+ return;
191
+ dragging = false;
192
+ bar.classList.remove('omni-video__bar--dragging');
193
+ });
194
+ // Zoom.
195
+ listen(zoomIn, 'click', () => controller.dispatch({ type: 'zoom-in' }));
196
+ listen(zoomOut, 'click', () => controller.dispatch({ type: 'zoom-out' }));
197
+ listen(zoomFit, 'click', () => controller.dispatch({ type: 'zoom-fit' }));
198
+ listen(stage, 'wheel', (event) => {
199
+ if (!event.ctrlKey && !event.metaKey)
200
+ return;
201
+ event.preventDefault();
202
+ controller.dispatch({ type: event.deltaY > 0 ? 'zoom-out' : 'zoom-in' });
203
+ }, { passive: false });
204
+ const applyState = (state) => {
205
+ wrapper.style.transform = state.zoom === 1 ? '' : `scale(${state.zoom})`;
206
+ zoomLabel.textContent = `${Math.round(state.zoom * 100)}%`;
207
+ stage.classList.toggle('omni-video__stage--zoomed', state.zoom > 1);
208
+ video.playbackRate = state.speed;
209
+ speedSelect.value = String(state.speed);
210
+ };
211
+ disposers.push(controller.subscribe(applyState));
212
+ // Keyboard shortcuts, scoped to the viewer (shell is focusable).
213
+ listen(shell, 'keydown', (event) => {
214
+ if (!hasSource)
215
+ return;
216
+ const key = event.key;
217
+ if (key === ' ')
218
+ playPause.click();
219
+ else if (key === 'ArrowLeft')
220
+ skipBack.click();
221
+ else if (key === 'ArrowRight')
222
+ skipForward.click();
223
+ else if (key === 'Home') {
224
+ video.currentTime = 0;
225
+ refreshProgress();
226
+ }
227
+ else if (key === 'End' && Number.isFinite(video.duration)) {
228
+ video.currentTime = video.duration;
229
+ refreshProgress();
230
+ }
231
+ else if (key === '+' || key === '=')
232
+ zoomIn.click();
233
+ else if (key === '-')
234
+ zoomOut.click();
235
+ else if (key === '0')
236
+ zoomFit.click();
237
+ else
238
+ return;
239
+ event.preventDefault();
240
+ });
241
+ if (options.signal?.aborted) {
242
+ cleanup();
243
+ throw new MountAbortedError();
244
+ }
245
+ let disposed = false;
246
+ function cleanup() {
247
+ video.pause();
248
+ video.removeAttribute('src');
249
+ video.load();
250
+ disposers.forEach((dispose) => dispose());
251
+ if (url)
252
+ (options.revokeObjectUrl ?? URL.revokeObjectURL.bind(URL))(url);
253
+ shell.remove();
254
+ if (root === container)
255
+ container.classList.remove(VIEWER_ROOT_CLASS, 'omni-viewer--video');
256
+ else
257
+ root.replaceChildren();
258
+ }
259
+ return {
260
+ dispose() {
261
+ if (disposed)
262
+ return;
263
+ disposed = true;
264
+ cleanup();
265
+ }
266
+ };
267
+ }
268
+ function element(tag, className, text) {
269
+ const node = document.createElement(tag);
270
+ if (className)
271
+ node.className = className;
272
+ if (text !== undefined)
273
+ node.textContent = text;
274
+ return node;
275
+ }
276
+ function button(label, title) {
277
+ const node = document.createElement('button');
278
+ node.type = 'button';
279
+ node.className = 'omni-video__btn';
280
+ node.textContent = label;
281
+ if (title)
282
+ node.title = title;
283
+ return node;
284
+ }
285
+ function infoItem(panel, label) {
286
+ const item = element('div', 'omni-video__info-item');
287
+ const value = element('div', 'omni-video__info-value', '--');
288
+ item.append(element('div', 'omni-video__info-label', label), value);
289
+ panel.append(item);
290
+ return value;
291
+ }
292
+ function blobPart(data) {
293
+ return data.buffer instanceof ArrayBuffer ? data : new Uint8Array(data);
294
+ }
295
+ function formatBytes(bytes) {
296
+ if (bytes < 1024)
297
+ return `${bytes} B`;
298
+ const units = ['KiB', 'MiB', 'GiB'];
299
+ let value = bytes / 1024, index = 0;
300
+ while (value >= 1024 && index < 2) {
301
+ value /= 1024;
302
+ index++;
303
+ }
304
+ return `${value.toFixed(value >= 10 ? 1 : 2)} ${units[index]}`;
305
+ }
@@ -0,0 +1 @@
1
+ export declare const videoViewerCss = "\n/* Reverse-contamination guard (DESIGN.md \u00A76). */\n.omni-viewer--video {\n all: initial;\n}\n.omni-viewer--video :where(button, select, option, input, label, video) {\n all: revert;\n}\n\n:host, .omni-viewer--video {\n display: block;\n height: 100%;\n box-sizing: border-box;\n color: var(--omni-fg, #d4d4d4);\n background: var(--omni-bg, #1e1e1e);\n font-family: var(--omni-font, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif);\n font-size: var(--omni-font-size, 13px);\n}\n\n.omni-video { display: flex; flex-direction: column; gap: 12px; box-sizing: border-box; height: 100%; padding: 16px; }\n.omni-video * { box-sizing: border-box; }\n\n.omni-video__header { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; }\n.omni-video__title { font-size: 16px; font-weight: 650; overflow-wrap: anywhere; }\n.omni-video__meta { color: var(--omni-muted, #9d9d9d); white-space: nowrap; }\n\n.omni-video__info { display: flex; gap: 18px; padding: 6px 10px; border: 1px solid var(--omni-border, #444); border-radius: 6px; background: var(--omni-panel-bg, #252526); }\n.omni-video__info[hidden] { display: none; }\n.omni-video__info-item { display: flex; flex-direction: column; align-items: center; gap: 2px; }\n.omni-video__info-label { font-size: 10px; opacity: 0.7; }\n.omni-video__info-value { font-family: var(--omni-mono, ui-monospace, Menlo, monospace); font-weight: 500; }\n\n.omni-video__controls { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 6px; border: 1px solid var(--omni-border, #444); border-radius: 8px; background: var(--omni-panel-bg, #252526); }\n.omni-video__group { display: flex; align-items: center; gap: 5px; }\n.omni-video__group-label { font-size: 12px; color: var(--omni-muted, #9d9d9d); }\n\n.omni-video__btn {\n background: var(--omni-accent, #0e639c); color: var(--omni-accent-fg, #fff);\n border: none; padding: 5px 11px; border-radius: 4px; cursor: pointer; font-size: 12px; font-family: inherit;\n}\n.omni-video__btn:hover { background: var(--omni-accent-hover, #1177bb); }\n.omni-video__btn:disabled { opacity: 0.5; cursor: not-allowed; }\n\n.omni-video__select {\n background: var(--omni-input-bg, #3c3c3c); color: var(--omni-fg, #d4d4d4);\n border: 1px solid var(--omni-border, #444); padding: 4px 8px; border-radius: 4px; font-size: 12px; font-family: inherit;\n}\n.omni-video__zoom-label { font-family: var(--omni-mono, ui-monospace, Menlo, monospace); font-size: 12px; min-width: 42px; text-align: center; color: var(--omni-muted, #9d9d9d); }\n\n.omni-video__progress-row { display: flex; align-items: center; gap: 10px; padding: 4px 6px; border: 1px solid var(--omni-border, #444); border-radius: 8px; background: var(--omni-panel-bg, #252526); }\n.omni-video__time { font-family: var(--omni-mono, ui-monospace, Menlo, monospace); font-size: 12px; min-width: 52px; text-align: center; }\n.omni-video__bar { flex: 1; height: 8px; background: var(--omni-input-bg, #3c3c3c); border-radius: 4px; cursor: pointer; position: relative; }\n.omni-video__bar:hover, .omni-video__bar--dragging { height: 12px; }\n.omni-video__bar-filled { height: 100%; width: 0%; background: var(--omni-accent, #0e639c); border-radius: 4px; pointer-events: none; position: relative; }\n.omni-video__bar-handle {\n width: 14px; height: 14px; background: var(--omni-accent-fg, #fff); border: 2px solid var(--omni-accent, #0e639c);\n border-radius: 50%; position: absolute; right: -7px; top: 50%; transform: translateY(-50%);\n opacity: 0; transition: opacity 0.15s; pointer-events: none;\n}\n.omni-video__bar:hover .omni-video__bar-handle, .omni-video__bar--dragging .omni-video__bar-handle { opacity: 1; }\n\n.omni-video__stage {\n flex: 1; min-height: 240px; display: flex; justify-content: center; align-items: center;\n border: 1px solid var(--omni-border, #444); border-radius: 8px; background: #000; overflow: hidden; position: relative;\n}\n.omni-video__stage--zoomed { overflow: auto; }\n.omni-video__wrapper { transition: transform 0.2s ease; transform-origin: center center; }\n.omni-video video { display: block; max-width: 100%; max-height: 70vh; background: #000; }\n\n.omni-video__warning {\n padding: 10px 12px; border: 1px solid #b98b2f; border-radius: 7px;\n background: #3b2d10; color: #ffd98a; white-space: pre-wrap;\n}\n.omni-video__warning[hidden] { display: none; }\n";