@editframe/elements 0.23.8-beta.0 → 0.25.0-beta.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 (339) hide show
  1. package/dist/DelayedLoadingState.js +31 -0
  2. package/dist/DelayedLoadingState.js.map +1 -0
  3. package/dist/EF_FRAMEGEN.d.ts +50 -46
  4. package/dist/EF_FRAMEGEN.js +5 -1
  5. package/dist/EF_FRAMEGEN.js.map +1 -0
  6. package/dist/EF_INTERACTIVE.js +4 -0
  7. package/dist/EF_INTERACTIVE.js.map +1 -0
  8. package/dist/EF_RENDERING.js +4 -0
  9. package/dist/EF_RENDERING.js.map +1 -0
  10. package/dist/_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js +4 -1
  11. package/dist/attachContextRoot.js +6 -1
  12. package/dist/attachContextRoot.js.map +1 -0
  13. package/dist/elements/CrossUpdateController.js +4 -0
  14. package/dist/elements/CrossUpdateController.js.map +1 -0
  15. package/dist/elements/EFAudio.d.ts +24 -16
  16. package/dist/elements/EFAudio.js +10 -1
  17. package/dist/elements/EFAudio.js.map +1 -0
  18. package/dist/elements/EFCaptions.d.ts +118 -109
  19. package/dist/elements/EFCaptions.js +11 -6
  20. package/dist/elements/EFCaptions.js.map +1 -0
  21. package/dist/elements/EFImage.d.ts +31 -20
  22. package/dist/elements/EFImage.js +6 -1
  23. package/dist/elements/EFImage.js.map +1 -0
  24. package/dist/elements/EFMedia/AssetIdMediaEngine.js +5 -0
  25. package/dist/elements/EFMedia/AssetIdMediaEngine.js.map +1 -0
  26. package/dist/elements/EFMedia/AssetMediaEngine.js +12 -0
  27. package/dist/elements/EFMedia/AssetMediaEngine.js.map +1 -0
  28. package/dist/elements/EFMedia/BaseMediaEngine.js +53 -0
  29. package/dist/elements/EFMedia/BaseMediaEngine.js.map +1 -0
  30. package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +47 -46
  31. package/dist/elements/EFMedia/BufferedSeekingInput.js +6 -1
  32. package/dist/elements/EFMedia/BufferedSeekingInput.js.map +1 -0
  33. package/dist/elements/EFMedia/JitMediaEngine.js +12 -0
  34. package/dist/elements/EFMedia/JitMediaEngine.js.map +1 -0
  35. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.d.ts +9 -13
  36. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +5 -0
  37. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js.map +1 -0
  38. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +6 -1
  39. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js.map +1 -0
  40. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +5 -0
  41. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js.map +1 -0
  42. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +5 -0
  43. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js.map +1 -0
  44. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +5 -0
  45. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js.map +1 -0
  46. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +5 -0
  47. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js.map +1 -0
  48. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +5 -0
  49. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js.map +1 -0
  50. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +6 -1
  51. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js.map +1 -0
  52. package/dist/elements/EFMedia/shared/AudioSpanUtils.js +18 -2
  53. package/dist/elements/EFMedia/shared/AudioSpanUtils.js.map +1 -0
  54. package/dist/elements/EFMedia/shared/BufferUtils.d.ts +9 -67
  55. package/dist/elements/EFMedia/shared/BufferUtils.js +15 -0
  56. package/dist/elements/EFMedia/shared/BufferUtils.js.map +1 -0
  57. package/dist/elements/EFMedia/shared/GlobalInputCache.js +29 -0
  58. package/dist/elements/EFMedia/shared/GlobalInputCache.js.map +1 -0
  59. package/dist/elements/EFMedia/shared/MediaTaskUtils.d.ts +11 -17
  60. package/dist/elements/EFMedia/shared/PrecisionUtils.js +25 -0
  61. package/dist/elements/EFMedia/shared/PrecisionUtils.js.map +1 -0
  62. package/dist/elements/EFMedia/shared/ThumbnailExtractor.js +22 -0
  63. package/dist/elements/EFMedia/shared/ThumbnailExtractor.js.map +1 -0
  64. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +13 -0
  65. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js.map +1 -0
  66. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js +21 -0
  67. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js.map +1 -0
  68. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +18 -0
  69. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js.map +1 -0
  70. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +10 -0
  71. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js.map +1 -0
  72. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js +5 -0
  73. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js.map +1 -0
  74. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js +5 -0
  75. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js.map +1 -0
  76. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js +6 -1
  77. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js.map +1 -0
  78. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js +5 -0
  79. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js.map +1 -0
  80. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js +5 -0
  81. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js.map +1 -0
  82. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +16 -2
  83. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js.map +1 -0
  84. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.d.ts +9 -13
  85. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +5 -0
  86. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js.map +1 -0
  87. package/dist/elements/EFMedia.d.ts +115 -104
  88. package/dist/elements/EFMedia.js +25 -1
  89. package/dist/elements/EFMedia.js.map +1 -0
  90. package/dist/elements/EFSourceMixin.d.ts +10 -11
  91. package/dist/elements/EFSourceMixin.js +5 -0
  92. package/dist/elements/EFSourceMixin.js.map +1 -0
  93. package/dist/elements/EFSurface.d.ts +35 -27
  94. package/dist/elements/EFSurface.js +6 -1
  95. package/dist/elements/EFSurface.js.map +1 -0
  96. package/dist/elements/EFTemporal.d.ts +200 -213
  97. package/dist/elements/EFTemporal.js +24 -4
  98. package/dist/elements/EFTemporal.js.map +1 -0
  99. package/dist/elements/EFThumbnailStrip.d.ts +91 -83
  100. package/dist/elements/EFThumbnailStrip.js +49 -4
  101. package/dist/elements/EFThumbnailStrip.js.map +1 -0
  102. package/dist/elements/EFTimegroup.d.ts +107 -88
  103. package/dist/elements/EFTimegroup.js +74 -4
  104. package/dist/elements/EFTimegroup.js.map +1 -0
  105. package/dist/elements/EFVideo.d.ts +120 -108
  106. package/dist/elements/EFVideo.js +46 -2
  107. package/dist/elements/EFVideo.js.map +1 -0
  108. package/dist/elements/EFWaveform.d.ts +48 -41
  109. package/dist/elements/EFWaveform.js +6 -1
  110. package/dist/elements/EFWaveform.js.map +1 -0
  111. package/dist/elements/FetchMixin.d.ts +8 -6
  112. package/dist/elements/FetchMixin.js +4 -0
  113. package/dist/elements/FetchMixin.js.map +1 -0
  114. package/dist/elements/SampleBuffer.d.ts +18 -13
  115. package/dist/elements/SampleBuffer.js +5 -0
  116. package/dist/elements/SampleBuffer.js.map +1 -0
  117. package/dist/elements/TargetController.d.ts +23 -24
  118. package/dist/elements/TargetController.js +8 -3
  119. package/dist/elements/TargetController.js.map +1 -0
  120. package/dist/elements/TimegroupController.d.ts +17 -12
  121. package/dist/elements/TimegroupController.js +4 -0
  122. package/dist/elements/TimegroupController.js.map +1 -0
  123. package/dist/elements/durationConverter.js +9 -4
  124. package/dist/elements/durationConverter.js.map +1 -0
  125. package/dist/elements/parseTimeToMs.js +4 -0
  126. package/dist/elements/parseTimeToMs.js.map +1 -0
  127. package/dist/elements/renderTemporalAudio.js +4 -0
  128. package/dist/elements/renderTemporalAudio.js.map +1 -0
  129. package/dist/elements/updateAnimations.js +29 -8
  130. package/dist/elements/updateAnimations.js.map +1 -0
  131. package/dist/elements-ZhsB7B5N.css +9 -0
  132. package/dist/elements-ZhsB7B5N.css.map +1 -0
  133. package/dist/getRenderInfo.d.ts +53 -47
  134. package/dist/getRenderInfo.js +5 -0
  135. package/dist/getRenderInfo.js.map +1 -0
  136. package/dist/gui/ContextMixin.d.ts +19 -20
  137. package/dist/gui/ContextMixin.js +32 -1
  138. package/dist/gui/ContextMixin.js.map +1 -0
  139. package/dist/gui/Controllable.d.ts +13 -14
  140. package/dist/gui/Controllable.js +5 -0
  141. package/dist/gui/Controllable.js.map +1 -0
  142. package/dist/gui/EFConfiguration.d.ts +18 -14
  143. package/dist/gui/EFConfiguration.js +6 -1
  144. package/dist/gui/EFConfiguration.js.map +1 -0
  145. package/dist/gui/EFControls.d.ts +35 -31
  146. package/dist/gui/EFControls.js +8 -3
  147. package/dist/gui/EFControls.js.map +1 -0
  148. package/dist/gui/EFDial.d.ts +23 -16
  149. package/dist/gui/EFDial.js +6 -1
  150. package/dist/gui/EFDial.js.map +1 -0
  151. package/dist/gui/EFFilmstrip.d.ts +183 -177
  152. package/dist/gui/EFFilmstrip.js +30 -25
  153. package/dist/gui/EFFilmstrip.js.map +1 -0
  154. package/dist/gui/EFFitScale.d.ts +30 -24
  155. package/dist/gui/EFFitScale.js +6 -1
  156. package/dist/gui/EFFitScale.js.map +1 -0
  157. package/dist/gui/EFFocusOverlay.d.ts +22 -14
  158. package/dist/gui/EFFocusOverlay.js +6 -1
  159. package/dist/gui/EFFocusOverlay.js.map +1 -0
  160. package/dist/gui/EFPause.d.ts +24 -18
  161. package/dist/gui/EFPause.js +6 -1
  162. package/dist/gui/EFPause.js.map +1 -0
  163. package/dist/gui/EFPlay.d.ts +24 -18
  164. package/dist/gui/EFPlay.js +6 -1
  165. package/dist/gui/EFPlay.js.map +1 -0
  166. package/dist/gui/EFPreview.d.ts +22 -15
  167. package/dist/gui/EFPreview.js +9 -1
  168. package/dist/gui/EFPreview.js.map +1 -0
  169. package/dist/gui/EFResizableBox.d.ts +39 -32
  170. package/dist/gui/EFResizableBox.js +8 -3
  171. package/dist/gui/EFResizableBox.js.map +1 -0
  172. package/dist/gui/EFScrubber.d.ts +31 -25
  173. package/dist/gui/EFScrubber.js +6 -1
  174. package/dist/gui/EFScrubber.js.map +1 -0
  175. package/dist/gui/EFTimeDisplay.d.ts +21 -14
  176. package/dist/gui/EFTimeDisplay.js +6 -1
  177. package/dist/gui/EFTimeDisplay.js.map +1 -0
  178. package/dist/gui/EFToggleLoop.d.ts +19 -13
  179. package/dist/gui/EFToggleLoop.js +6 -1
  180. package/dist/gui/EFToggleLoop.js.map +1 -0
  181. package/dist/gui/EFTogglePlay.d.ts +23 -17
  182. package/dist/gui/EFTogglePlay.js +6 -1
  183. package/dist/gui/EFTogglePlay.js.map +1 -0
  184. package/dist/gui/EFWorkbench.d.ts +24 -16
  185. package/dist/gui/EFWorkbench.js +6 -1
  186. package/dist/gui/EFWorkbench.js.map +1 -0
  187. package/dist/gui/PlaybackController.d.ts +54 -50
  188. package/dist/gui/PlaybackController.js +23 -1
  189. package/dist/gui/PlaybackController.js.map +1 -0
  190. package/dist/gui/TWMixin.js +5 -1
  191. package/dist/gui/TWMixin.js.map +1 -0
  192. package/dist/gui/TWMixin2.js +6 -1
  193. package/dist/gui/TWMixin2.js.map +1 -0
  194. package/dist/gui/TargetOrContextMixin.js +5 -0
  195. package/dist/gui/TargetOrContextMixin.js.map +1 -0
  196. package/dist/gui/currentTimeContext.js +5 -0
  197. package/dist/gui/currentTimeContext.js.map +1 -0
  198. package/dist/gui/durationContext.js +5 -0
  199. package/dist/gui/durationContext.js.map +1 -0
  200. package/dist/gui/efContext.js +5 -0
  201. package/dist/gui/efContext.js.map +1 -0
  202. package/dist/gui/fetchContext.js +5 -0
  203. package/dist/gui/fetchContext.js.map +1 -0
  204. package/dist/gui/focusContext.d.ts +6 -5
  205. package/dist/gui/focusContext.js +5 -0
  206. package/dist/gui/focusContext.js.map +1 -0
  207. package/dist/gui/focusedElementContext.js +5 -0
  208. package/dist/gui/focusedElementContext.js.map +1 -0
  209. package/dist/gui/playingContext.js +5 -0
  210. package/dist/gui/playingContext.js.map +1 -0
  211. package/dist/index.d.ts +27 -26
  212. package/dist/index.js +6 -1
  213. package/dist/index.js.map +1 -0
  214. package/dist/msToTimeCode.js +4 -0
  215. package/dist/msToTimeCode.js.map +1 -0
  216. package/dist/otel/BridgeSpanExporter.js +5 -0
  217. package/dist/otel/BridgeSpanExporter.js.map +1 -0
  218. package/dist/otel/setupBrowserTracing.js +7 -2
  219. package/dist/otel/setupBrowserTracing.js.map +1 -0
  220. package/dist/otel/tracingHelpers.d.ts +7 -34
  221. package/dist/otel/tracingHelpers.js +34 -2
  222. package/dist/otel/tracingHelpers.js.map +1 -0
  223. package/dist/transcoding/cache/RequestDeduplicator.js +25 -0
  224. package/dist/transcoding/cache/RequestDeduplicator.js.map +1 -0
  225. package/dist/transcoding/cache/URLTokenDeduplicator.js +23 -0
  226. package/dist/transcoding/cache/URLTokenDeduplicator.js.map +1 -0
  227. package/dist/transcoding/types/index.d.ts +96 -270
  228. package/dist/transcoding/utils/UrlGenerator.d.ts +30 -25
  229. package/dist/transcoding/utils/UrlGenerator.js +19 -0
  230. package/dist/transcoding/utils/UrlGenerator.js.map +1 -0
  231. package/dist/utils/LRUCache.js +44 -0
  232. package/dist/utils/LRUCache.js.map +1 -0
  233. package/package.json +11 -24
  234. package/src/elements/EFCaptions.browsertest.ts +7 -7
  235. package/src/elements/EFTimegroup.ts +43 -1
  236. package/src/gui/PlaybackController.ts +6 -1
  237. package/tsdown.config.ts +36 -0
  238. package/types.json +1 -1
  239. package/dist/DelayedLoadingState.d.ts +0 -48
  240. package/dist/DelayedLoadingState.integration.test.d.ts +0 -1
  241. package/dist/DelayedLoadingState.test.d.ts +0 -1
  242. package/dist/EF_INTERACTIVE.d.ts +0 -1
  243. package/dist/EF_RENDERING.d.ts +0 -1
  244. package/dist/LoadingDebounce.test.d.ts +0 -1
  245. package/dist/ManualScrubTest.test.d.ts +0 -1
  246. package/dist/ScrubResolvedFlashing.test.d.ts +0 -1
  247. package/dist/ScrubTrackManager.test.d.ts +0 -1
  248. package/dist/VideoSeekFlashing.browsertest.d.ts +0 -0
  249. package/dist/VideoStuckDiagnostic.test.d.ts +0 -1
  250. package/dist/attachContextRoot.d.ts +0 -1
  251. package/dist/elements/ContextProxiesController.d.ts +0 -39
  252. package/dist/elements/CrossUpdateController.d.ts +0 -8
  253. package/dist/elements/EFAudio.browsertest.d.ts +0 -0
  254. package/dist/elements/EFCaptions.browsertest.d.ts +0 -0
  255. package/dist/elements/EFImage.browsertest.d.ts +0 -0
  256. package/dist/elements/EFMedia/AssetIdMediaEngine.d.ts +0 -19
  257. package/dist/elements/EFMedia/AssetIdMediaEngine.test.d.ts +0 -1
  258. package/dist/elements/EFMedia/AssetMediaEngine.browsertest.d.ts +0 -0
  259. package/dist/elements/EFMedia/AssetMediaEngine.d.ts +0 -56
  260. package/dist/elements/EFMedia/BaseMediaEngine.browsertest.d.ts +0 -1
  261. package/dist/elements/EFMedia/BaseMediaEngine.d.ts +0 -103
  262. package/dist/elements/EFMedia/BufferedSeekingInput.browsertest.d.ts +0 -1
  263. package/dist/elements/EFMedia/JitMediaEngine.browsertest.d.ts +0 -0
  264. package/dist/elements/EFMedia/JitMediaEngine.d.ts +0 -46
  265. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.d.ts +0 -9
  266. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.d.ts +0 -3
  267. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.d.ts +0 -9
  268. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.d.ts +0 -4
  269. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.d.ts +0 -9
  270. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.d.ts +0 -3
  271. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.d.ts +0 -0
  272. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.d.ts +0 -7
  273. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.d.ts +0 -4
  274. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.d.ts +0 -4
  275. package/dist/elements/EFMedia/audioTasks/makeAudioTasksVideoOnly.browsertest.d.ts +0 -1
  276. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.d.ts +0 -3
  277. package/dist/elements/EFMedia/shared/AudioSpanUtils.d.ts +0 -7
  278. package/dist/elements/EFMedia/shared/GlobalInputCache.d.ts +0 -39
  279. package/dist/elements/EFMedia/shared/PrecisionUtils.d.ts +0 -28
  280. package/dist/elements/EFMedia/shared/RenditionHelpers.browsertest.d.ts +0 -1
  281. package/dist/elements/EFMedia/shared/RenditionHelpers.d.ts +0 -11
  282. package/dist/elements/EFMedia/shared/ThumbnailExtractor.d.ts +0 -27
  283. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.d.ts +0 -9
  284. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.d.ts +0 -17
  285. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.d.ts +0 -29
  286. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.d.ts +0 -25
  287. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.d.ts +0 -8
  288. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.d.ts +0 -4
  289. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.d.ts +0 -3
  290. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.d.ts +0 -6
  291. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.d.ts +0 -4
  292. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.d.ts +0 -4
  293. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.d.ts +0 -6
  294. package/dist/elements/EFMedia.browsertest.d.ts +0 -10
  295. package/dist/elements/EFSurface.browsertest.d.ts +0 -0
  296. package/dist/elements/EFTemporal.browsertest.d.ts +0 -22
  297. package/dist/elements/EFThumbnailStrip.browsertest.d.ts +0 -0
  298. package/dist/elements/EFThumbnailStrip.media-engine.browsertest.d.ts +0 -0
  299. package/dist/elements/EFTimegroup.browsertest.d.ts +0 -41
  300. package/dist/elements/EFVideo.browsertest.d.ts +0 -0
  301. package/dist/elements/FetchContext.browsertest.d.ts +0 -0
  302. package/dist/elements/TargetController.browsertest.d.ts +0 -19
  303. package/dist/elements/durationConverter.d.ts +0 -16
  304. package/dist/elements/parseTimeToMs.d.ts +0 -1
  305. package/dist/elements/printTaskStatus.d.ts +0 -2
  306. package/dist/elements/renderTemporalAudio.d.ts +0 -10
  307. package/dist/elements/updateAnimations.browsertest.d.ts +0 -13
  308. package/dist/elements/updateAnimations.d.ts +0 -24
  309. package/dist/elements/util.d.ts +0 -3
  310. package/dist/gui/ContextMixin.browsertest.d.ts +0 -15
  311. package/dist/gui/Controllable.browsertest.d.ts +0 -0
  312. package/dist/gui/EFControls.browsertest.d.ts +0 -11
  313. package/dist/gui/EFDial.browsertest.d.ts +0 -0
  314. package/dist/gui/EFFilmstrip.browsertest.d.ts +0 -11
  315. package/dist/gui/EFPause.browsertest.d.ts +0 -0
  316. package/dist/gui/EFPlay.browsertest.d.ts +0 -0
  317. package/dist/gui/EFResizableBox.browsertest.d.ts +0 -0
  318. package/dist/gui/EFTimeDisplay.browsertest.d.ts +0 -0
  319. package/dist/gui/TWMixin.d.ts +0 -2
  320. package/dist/gui/TargetOrContextMixin.d.ts +0 -10
  321. package/dist/gui/currentTimeContext.d.ts +0 -3
  322. package/dist/gui/durationContext.d.ts +0 -3
  323. package/dist/gui/efContext.d.ts +0 -4
  324. package/dist/gui/fetchContext.d.ts +0 -3
  325. package/dist/gui/focusedElementContext.d.ts +0 -3
  326. package/dist/gui/playingContext.d.ts +0 -6
  327. package/dist/msToTimeCode.d.ts +0 -1
  328. package/dist/otel/BridgeSpanExporter.d.ts +0 -13
  329. package/dist/otel/setupBrowserTracing.d.ts +0 -12
  330. package/dist/style.css +0 -2
  331. package/dist/transcoding/cache/RequestDeduplicator.d.ts +0 -29
  332. package/dist/transcoding/cache/RequestDeduplicator.test.d.ts +0 -1
  333. package/dist/transcoding/cache/URLTokenDeduplicator.d.ts +0 -38
  334. package/dist/transcoding/cache/URLTokenDeduplicator.test.d.ts +0 -1
  335. package/dist/transcoding/utils/MediaUtils.d.ts +0 -9
  336. package/dist/transcoding/utils/constants.d.ts +0 -27
  337. package/dist/utils/LRUCache.d.ts +0 -80
  338. package/dist/utils/LRUCache.test.d.ts +0 -1
  339. /package/dist/{LoadingIndicator.browsertest.d.ts → elements.js} +0 -0
@@ -4,6 +4,21 @@ import { durationContext } from "./durationContext.js";
4
4
  import { loopContext, playingContext } from "./playingContext.js";
5
5
  import { ContextProvider } from "@lit/context";
6
6
  import { Task, TaskStatus } from "@lit/task";
7
+
8
+ //#region src/gui/PlaybackController.ts
9
+ /**
10
+ * Manages playback state and audio-driven timing for root temporal elements
11
+ *
12
+ * Created automatically when a temporal element becomes a root (no parent timegroup)
13
+ * Provides playback contexts (playing, loop, currentTimeMs, durationMs) to descendants
14
+ * Handles:
15
+ * - Audio-driven playback with Web Audio API
16
+ * - Seek and frame rendering throttling
17
+ * - Time state management with pending seek handling
18
+ * - Playback loop behavior
19
+ *
20
+ * Works with any temporal element (timegroups or standalone media) via PlaybackHost interface
21
+ */
7
22
  var PlaybackController = class {
8
23
  #host;
9
24
  #playing = false;
@@ -68,7 +83,11 @@ var PlaybackController = class {
68
83
  });
69
84
  }
70
85
  get currentTime() {
71
- return this.#currentTime ?? 0;
86
+ const rawTime = this.#currentTime ?? 0;
87
+ const fps = this.#host.fps ?? 30;
88
+ if (!fps || fps <= 0) return rawTime;
89
+ const frameDurationS = 1 / fps;
90
+ return Math.round(rawTime / frameDurationS) * frameDurationS;
72
91
  }
73
92
  set currentTime(time) {
74
93
  time = Math.max(0, Math.min(this.#host.durationMs / 1e3, time));
@@ -307,4 +326,7 @@ var PlaybackController = class {
307
326
  }
308
327
  }
309
328
  };
329
+
330
+ //#endregion
310
331
  export { PlaybackController };
332
+ //# sourceMappingURL=PlaybackController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlaybackController.js","names":["#FPS","#host","#pendingSeekTime","#currentTime","#currentTimeMsProvider","#notifyListeners","#seekInProgress","#playingProvider","#playing","#loopProvider","#loop","#durationMsProvider","#processingPendingSeek","#frameTaskInProgress","#pendingFrameTaskRun","#processingPendingFrameTask","#listeners","#playbackAudioContext","rawTimeMs: number","#playbackWrapTimeSeconds","#loopingPlayback","#MS_PER_FRAME","#updatePlaybackTime","#playbackAnimationFrameRequest","#syncPlayheadToAudioContext","#AUDIO_PLAYBACK_SLICE_MS"],"sources":["../../src/gui/PlaybackController.ts"],"sourcesContent":["import { ContextProvider } from \"@lit/context\";\nimport { Task, TaskStatus } from \"@lit/task\";\nimport type { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { EF_INTERACTIVE } from \"../EF_INTERACTIVE.js\";\nimport { currentTimeContext } from \"./currentTimeContext.js\";\nimport { durationContext } from \"./durationContext.js\";\nimport { loopContext, playingContext } from \"./playingContext.js\";\n\ninterface PlaybackHost extends HTMLElement, ReactiveControllerHost {\n currentTimeMs: number;\n durationMs: number;\n endTimeMs: number;\n frameTask: { run(): void; taskComplete: Promise<unknown> };\n renderAudio?(fromMs: number, toMs: number): Promise<AudioBuffer>;\n waitForMediaDurations?(): Promise<void>;\n saveTimeToLocalStorage?(time: number): void;\n loadTimeFromLocalStorage?(): number | undefined;\n requestUpdate(property?: string): void;\n updateComplete: Promise<boolean>;\n playing: boolean;\n loop: boolean;\n play(): void;\n pause(): void;\n playbackController?: PlaybackController;\n parentTimegroup?: any;\n rootTimegroup?: any;\n}\n\nexport type PlaybackControllerUpdateEvent = {\n property: \"playing\" | \"loop\" | \"currentTimeMs\";\n value: boolean | number;\n};\n\n/**\n * Manages playback state and audio-driven timing for root temporal elements\n *\n * Created automatically when a temporal element becomes a root (no parent timegroup)\n * Provides playback contexts (playing, loop, currentTimeMs, durationMs) to descendants\n * Handles:\n * - Audio-driven playback with Web Audio API\n * - Seek and frame rendering throttling\n * - Time state management with pending seek handling\n * - Playback loop behavior\n *\n * Works with any temporal element (timegroups or standalone media) via PlaybackHost interface\n */\nexport class PlaybackController implements ReactiveController {\n #host: PlaybackHost;\n #playing = false;\n #loop = false;\n #listeners = new Set<(event: PlaybackControllerUpdateEvent) => void>();\n #playingProvider: ContextProvider<typeof playingContext>;\n #loopProvider: ContextProvider<typeof loopContext>;\n #currentTimeMsProvider: ContextProvider<typeof currentTimeContext>;\n #durationMsProvider: ContextProvider<typeof durationContext>;\n\n #FPS = 30;\n #MS_PER_FRAME = 1000 / this.#FPS;\n #playbackAudioContext: AudioContext | null = null;\n #playbackAnimationFrameRequest: number | null = null;\n #AUDIO_PLAYBACK_SLICE_MS = ((47 * 1024) / 48000) * 1000;\n\n #frameTaskInProgress = false;\n #pendingFrameTaskRun = false;\n #processingPendingFrameTask = false;\n\n #currentTime: number | undefined = undefined;\n #seekInProgress = false;\n #pendingSeekTime: number | undefined;\n #processingPendingSeek = false;\n #loopingPlayback = false; // Track if we're in a looping playback session\n #playbackWrapTimeSeconds = 0; // The AudioContext time when we wrapped\n\n seekTask!: Task<readonly [number | undefined], number | undefined>;\n\n constructor(host: PlaybackHost) {\n this.#host = host;\n host.addController(this);\n\n this.seekTask = new Task(this.#host, {\n autoRun: false,\n args: () => [this.#pendingSeekTime ?? this.#currentTime] as const,\n onComplete: () => {},\n task: async ([targetTime]) => {\n await this.#host.waitForMediaDurations?.();\n const newTime = Math.max(\n 0,\n Math.min(targetTime ?? 0, this.#host.durationMs / 1000),\n );\n this.#currentTime = newTime;\n this.#host.requestUpdate(\"currentTime\");\n this.#currentTimeMsProvider.setValue(this.currentTimeMs);\n this.#notifyListeners({\n property: \"currentTimeMs\",\n value: this.currentTimeMs,\n });\n await this.runThrottledFrameTask();\n this.#host.saveTimeToLocalStorage?.(newTime);\n this.#seekInProgress = false;\n return newTime;\n },\n });\n\n this.#playingProvider = new ContextProvider(host, {\n context: playingContext,\n initialValue: this.#playing,\n });\n this.#loopProvider = new ContextProvider(host, {\n context: loopContext,\n initialValue: this.#loop,\n });\n this.#currentTimeMsProvider = new ContextProvider(host, {\n context: currentTimeContext,\n initialValue: host.currentTimeMs,\n });\n this.#durationMsProvider = new ContextProvider(host, {\n context: durationContext,\n initialValue: host.durationMs,\n });\n }\n\n get currentTime(): number {\n const rawTime = this.#currentTime ?? 0;\n // Quantize to frame boundaries based on host's fps\n const fps = (this.#host as any).fps ?? 30;\n if (!fps || fps <= 0) return rawTime;\n const frameDurationS = 1 / fps;\n return Math.round(rawTime / frameDurationS) * frameDurationS;\n }\n\n set currentTime(time: number) {\n time = Math.max(0, Math.min(this.#host.durationMs / 1000, time));\n if (Number.isNaN(time)) {\n return;\n }\n if (time === this.#currentTime && !this.#processingPendingSeek) {\n return;\n }\n if (this.#pendingSeekTime === time) {\n return;\n }\n\n if (this.#seekInProgress) {\n this.#pendingSeekTime = time;\n this.#currentTime = time;\n return;\n }\n\n this.#currentTime = time;\n this.#seekInProgress = true;\n\n this.seekTask.run().finally(() => {\n if (\n this.#pendingSeekTime !== undefined &&\n this.#pendingSeekTime !== time\n ) {\n const pendingTime = this.#pendingSeekTime;\n this.#pendingSeekTime = undefined;\n this.#processingPendingSeek = true;\n try {\n this.currentTime = pendingTime;\n } finally {\n this.#processingPendingSeek = false;\n }\n } else {\n this.#pendingSeekTime = undefined;\n }\n });\n }\n\n get playing(): boolean {\n return this.#playing;\n }\n\n setPlaying(value: boolean): void {\n if (this.#playing === value) return;\n this.#playing = value;\n this.#playingProvider.setValue(value);\n this.#host.requestUpdate(\"playing\");\n this.#notifyListeners({ property: \"playing\", value });\n\n if (value) {\n this.startPlayback();\n } else {\n this.stopPlayback();\n }\n }\n\n get loop(): boolean {\n return this.#loop;\n }\n\n setLoop(value: boolean): void {\n if (this.#loop === value) return;\n this.#loop = value;\n this.#loopProvider.setValue(value);\n this.#host.requestUpdate(\"loop\");\n this.#notifyListeners({ property: \"loop\", value });\n }\n\n get currentTimeMs(): number {\n return this.currentTime * 1000;\n }\n\n setCurrentTimeMs(value: number): void {\n this.currentTime = value / 1000;\n }\n\n // Update time during playback without triggering a seek\n // Used by #syncPlayheadToAudioContext to avoid frame drops\n #updatePlaybackTime(timeMs: number): void {\n const timeSec = timeMs / 1000;\n if (this.#currentTime === timeSec) {\n return;\n }\n this.#currentTime = timeSec;\n this.#host.requestUpdate(\"currentTime\");\n this.#currentTimeMsProvider.setValue(timeMs);\n this.#notifyListeners({\n property: \"currentTimeMs\",\n value: timeMs,\n });\n // Trigger frame rendering without the async seek mechanism\n this.runThrottledFrameTask();\n }\n\n play(): void {\n this.setPlaying(true);\n }\n\n pause(): void {\n this.setPlaying(false);\n }\n\n hostConnected(): void {\n if (this.#playing) {\n this.startPlayback();\n } else {\n this.#host.waitForMediaDurations?.().then(() => {\n const maybeLoadedTime = this.#host.loadTimeFromLocalStorage?.();\n if (maybeLoadedTime !== undefined) {\n this.currentTime = maybeLoadedTime;\n } else if (this.#currentTime === undefined) {\n this.#currentTime = 0;\n }\n if (EF_INTERACTIVE && this.seekTask.status === TaskStatus.INITIAL) {\n this.seekTask.run();\n }\n });\n }\n }\n\n hostDisconnected(): void {\n this.pause();\n }\n\n hostUpdated(): void {\n this.#durationMsProvider.setValue(this.#host.durationMs);\n this.#currentTimeMsProvider.setValue(this.currentTimeMs);\n }\n\n async runThrottledFrameTask(): Promise<void> {\n if (this.#frameTaskInProgress) {\n this.#pendingFrameTaskRun = true;\n while (this.#frameTaskInProgress) {\n await this.#host.frameTask.taskComplete;\n }\n return;\n }\n\n this.#frameTaskInProgress = true;\n\n try {\n await this.#host.frameTask.run();\n } catch (error) {\n console.error(\"Frame task error:\", error);\n } finally {\n this.#frameTaskInProgress = false;\n\n if (this.#pendingFrameTaskRun && !this.#processingPendingFrameTask) {\n this.#pendingFrameTaskRun = false;\n this.#processingPendingFrameTask = true;\n try {\n await this.runThrottledFrameTask();\n } finally {\n this.#processingPendingFrameTask = false;\n }\n } else {\n this.#pendingFrameTaskRun = false;\n }\n }\n }\n\n addListener(listener: (event: PlaybackControllerUpdateEvent) => void): void {\n this.#listeners.add(listener);\n }\n\n removeListener(\n listener: (event: PlaybackControllerUpdateEvent) => void,\n ): void {\n this.#listeners.delete(listener);\n }\n\n #notifyListeners(event: PlaybackControllerUpdateEvent): void {\n for (const listener of this.#listeners) {\n listener(event);\n }\n }\n\n remove(): void {\n this.stopPlayback();\n this.#listeners.clear();\n this.#host.removeController(this);\n }\n\n #syncPlayheadToAudioContext(startMs: number) {\n const audioContextTime = this.#playbackAudioContext?.currentTime ?? 0;\n const endMs = this.#host.endTimeMs;\n\n // Calculate raw time based on audio context\n let rawTimeMs: number;\n if (\n this.#playbackWrapTimeSeconds > 0 &&\n audioContextTime >= this.#playbackWrapTimeSeconds\n ) {\n // After wrap: time since wrap, wrapped to duration\n const timeSinceWrap =\n (audioContextTime - this.#playbackWrapTimeSeconds) * 1000;\n rawTimeMs = timeSinceWrap % endMs;\n } else {\n // Before wrap or no wrap: normal calculation\n rawTimeMs = startMs + audioContextTime * 1000;\n\n // If looping and we've reached the end, wrap around\n if (this.#loopingPlayback && rawTimeMs >= endMs) {\n rawTimeMs = rawTimeMs % endMs;\n }\n }\n\n const nextTimeMs =\n Math.round(rawTimeMs / this.#MS_PER_FRAME) * this.#MS_PER_FRAME;\n\n // During playback, update time directly without triggering seek\n // This avoids frame drops at the loop boundary\n this.#updatePlaybackTime(nextTimeMs);\n\n // Only check for end if we haven't already handled looping\n if (!this.#loopingPlayback && nextTimeMs >= endMs) {\n this.maybeLoopPlayback();\n return;\n }\n\n this.#playbackAnimationFrameRequest = requestAnimationFrame(() => {\n this.#syncPlayheadToAudioContext(startMs);\n });\n }\n\n private async maybeLoopPlayback() {\n if (this.#loop) {\n // Loop enabled: reset to beginning and restart playback\n // We restart the audio system directly without changing #playing state\n // to keep the play button in sync\n this.setCurrentTimeMs(0);\n // Restart in next frame without awaiting to minimize gap\n requestAnimationFrame(() => {\n this.startPlayback();\n });\n } else {\n // No loop: reset to beginning and stop\n // This ensures play button works when clicked again\n this.setCurrentTimeMs(0);\n this.pause();\n }\n }\n\n private async stopPlayback() {\n if (this.#playbackAudioContext) {\n if (this.#playbackAudioContext.state !== \"closed\") {\n await this.#playbackAudioContext.close();\n }\n }\n if (this.#playbackAnimationFrameRequest) {\n cancelAnimationFrame(this.#playbackAnimationFrameRequest);\n }\n this.#playbackAudioContext = null;\n this.#playbackAnimationFrameRequest = null;\n }\n\n private async startPlayback() {\n await this.stopPlayback();\n const host = this.#host;\n if (!host) {\n return;\n }\n\n if (host.waitForMediaDurations) {\n await host.waitForMediaDurations();\n }\n\n const currentMs = this.currentTimeMs;\n const fromMs = currentMs;\n const toMs = host.endTimeMs;\n\n if (fromMs >= toMs) {\n this.pause();\n return;\n }\n\n let bufferCount = 0;\n this.#playbackAudioContext = new AudioContext({\n latencyHint: \"playback\",\n });\n this.#loopingPlayback = this.#loop; // Remember if we're in a looping session\n this.#playbackWrapTimeSeconds = 0; // Reset wrap time\n\n if (this.#playbackAnimationFrameRequest) {\n cancelAnimationFrame(this.#playbackAnimationFrameRequest);\n }\n this.#syncPlayheadToAudioContext(currentMs);\n const playbackContext = this.#playbackAudioContext;\n if (playbackContext.state === \"suspended\") {\n console.warn(\n \"AudioContext is suspended, media playback will not work until user has interacted with page.\",\n );\n this.setPlaying(false);\n return;\n }\n await playbackContext.suspend();\n\n // Track the logical media time (what position in the media we're rendering)\n // vs the AudioContext schedule time (when to play it)\n let logicalTimeMs = currentMs;\n let audioContextTimeMs = 0; // Tracks the schedule position in the AudioContext timeline\n let hasWrapped = false;\n\n const fillBuffer = async () => {\n if (bufferCount > 2) {\n return;\n }\n const canFillBuffer = await queueBufferSource();\n if (canFillBuffer) {\n fillBuffer();\n }\n };\n\n const queueBufferSource = async () => {\n // Check if we've already wrapped and aren't looping anymore\n if (hasWrapped && !this.#loopingPlayback) {\n return false;\n }\n\n const startMs = logicalTimeMs;\n const endMs = Math.min(\n logicalTimeMs + this.#AUDIO_PLAYBACK_SLICE_MS,\n toMs,\n );\n\n // Will this slice reach the end?\n const willReachEnd = endMs >= toMs;\n\n if (!host.renderAudio) {\n return false;\n }\n\n const audioBuffer = await host.renderAudio(startMs, endMs);\n bufferCount++;\n const source = playbackContext.createBufferSource();\n source.buffer = audioBuffer;\n source.connect(playbackContext.destination);\n // Schedule this buffer to play at the current audioContextTime position\n source.start(audioContextTimeMs / 1000);\n\n const sliceDurationMs = endMs - startMs;\n\n source.onended = () => {\n bufferCount--;\n\n if (willReachEnd) {\n if (!this.#loopingPlayback) {\n // Not looping, end playback\n this.maybeLoopPlayback();\n } else {\n // Looping: continue filling buffer after wrap\n fillBuffer();\n }\n } else {\n // Continue filling buffer\n fillBuffer();\n }\n };\n\n // Advance the AudioContext schedule time\n audioContextTimeMs += sliceDurationMs;\n\n // If this buffer reaches the end and we're looping, immediately queue the wraparound\n if (willReachEnd && this.#loopingPlayback) {\n // Mark that we've wrapped\n hasWrapped = true;\n // Store when we wrapped (relative to when playback started, which is time 0 in AudioContext)\n // This is the duration from start to end\n this.#playbackWrapTimeSeconds = (toMs - fromMs) / 1000;\n // Reset logical time to beginning\n logicalTimeMs = 0;\n // Continue buffering will happen in fillBuffer() call below\n } else {\n // Normal advance\n logicalTimeMs = endMs;\n }\n\n return true;\n };\n\n try {\n await fillBuffer();\n await playbackContext.resume();\n } catch (error) {\n // Ignore errors if AudioContext is closed or during test cleanup\n if (\n error instanceof Error &&\n (error.name === \"InvalidStateError\" || error.message.includes(\"closed\"))\n ) {\n return;\n }\n throw error;\n }\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,6 @@
1
- var TWMixin_default = "*,:before,:after{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:\"\"}html,:host{-webkit-text-size-adjust:100%;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder{opacity:1;color:#9ca3af}textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.invisible{visibility:hidden}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.left-0{left:0}.top-0{top:0}.isolate{isolation:isolate}.z-10{z-index:10}.z-20,.z-\\[20\\]{z-index:20}.z-\\[5\\]{z-index:5}.col-span-2{grid-column:span 2/span 2}.mx-2{margin-left:.5rem;margin-right:.5rem}.mb-\\[1px\\]{margin-bottom:1px}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.grid{display:grid}.contents{display:contents}.hidden{display:none}.size-full{width:100%;height:100%}.h-\\[1\\.1rem\\]{height:1.1rem}.h-\\[200px\\]{height:200px}.h-\\[270px\\]{height:270px}.h-\\[300px\\]{height:300px}.h-\\[360px\\]{height:360px}.h-\\[500px\\]{height:500px}.h-\\[5px\\]{height:5px}.h-full{height:100%}.w-1{width:.25rem}.w-\\[1000px\\]{width:1000px}.w-\\[2px\\]{width:2px}.w-\\[480px\\]{width:480px}.w-\\[600px\\]{width:600px}.w-\\[640px\\]{width:640px}.w-full{width:100%}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.cursor-crosshair{cursor:crosshair}.resize{resize:both}.place-content-center{place-content:center}.items-center{align-items:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.whitespace-nowrap{white-space:nowrap}.text-nowrap{text-wrap:nowrap}.rounded{border-radius:.25rem}.border{border-width:1px}.border-r-2{border-right-width:2px}.border-blue-200{--tw-border-opacity:1;border-color:rgb(191 219 254/var(--tw-border-opacity,1))}.border-blue-500{--tw-border-opacity:1;border-color:rgb(59 130 246/var(--tw-border-opacity,1))}.border-green-200{--tw-border-opacity:1;border-color:rgb(187 247 208/var(--tw-border-opacity,1))}.border-green-500{--tw-border-opacity:1;border-color:rgb(34 197 94/var(--tw-border-opacity,1))}.border-purple-200{--tw-border-opacity:1;border-color:rgb(233 213 255/var(--tw-border-opacity,1))}.border-red-700{--tw-border-opacity:1;border-color:rgb(185 28 28/var(--tw-border-opacity,1))}.border-slate-500{--tw-border-opacity:1;border-color:rgb(100 116 139/var(--tw-border-opacity,1))}.border-slate-600{--tw-border-opacity:1;border-color:rgb(71 85 105/var(--tw-border-opacity,1))}.border-yellow-500{--tw-border-opacity:1;border-color:rgb(234 179 8/var(--tw-border-opacity,1))}.border-b-slate-600{--tw-border-opacity:1;border-bottom-color:rgb(71 85 105/var(--tw-border-opacity,1))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1))}.bg-blue-200{--tw-bg-opacity:1;background-color:rgb(191 219 254/var(--tw-bg-opacity,1))}.bg-blue-50{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity,1))}.bg-green-200{--tw-bg-opacity:1;background-color:rgb(187 247 208/var(--tw-bg-opacity,1))}.bg-green-50{--tw-bg-opacity:1;background-color:rgb(240 253 244/var(--tw-bg-opacity,1))}.bg-lime-400{--tw-bg-opacity:1;background-color:rgb(163 230 53/var(--tw-bg-opacity,1))}.bg-purple-50{--tw-bg-opacity:1;background-color:rgb(250 245 255/var(--tw-bg-opacity,1))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.bg-slate-300{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity,1))}.bg-slate-500{--tw-bg-opacity:1;background-color:rgb(100 116 139/var(--tw-bg-opacity,1))}.bg-slate-800{--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity,1))}.bg-yellow-200{--tw-bg-opacity:1;background-color:rgb(254 240 138/var(--tw-bg-opacity,1))}.bg-yellow-400{--tw-bg-opacity:1;background-color:rgb(250 204 21/var(--tw-bg-opacity,1))}.bg-opacity-20{--tw-bg-opacity:.2}.object-contain{-o-object-fit:contain;object-fit:contain}.p-4{padding:1rem}.p-\\[1px\\]{padding:1px}.px-0\\.5{padding-left:.125rem;padding-right:.125rem}.pb-0{padding-bottom:0}.pl-1{padding-left:.25rem}.pl-2{padding-left:.5rem}.pr-0{padding-right:0}.pr-1{padding-right:.25rem}.pt-\\[8px\\]{padding-top:8px}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\\[8px\\]{font-size:8px}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal)var(--tw-slashed-zero)var(--tw-numeric-figure)var(--tw-numeric-spacing)var(--tw-numeric-fraction)}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity,1))}.text-green-200{--tw-text-opacity:1;color:rgb(187 247 208/var(--tw-text-opacity,1))}.text-green-900{--tw-text-opacity:1;color:rgb(20 83 45/var(--tw-text-opacity,1))}.line-through{text-decoration-line:line-through}.opacity-50{opacity:.5}.shadow{--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-slate-300{--tw-shadow-color:#cbd5e1;--tw-shadow:var(--tw-shadow-colored)}.shadow-slate-600{--tw-shadow-color:#475569;--tw-shadow:var(--tw-shadow-colored)}.outline{outline-style:solid}.blur{--tw-blur:blur(8px);filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.filter{filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur)var(--tw-backdrop-brightness)var(--tw-backdrop-contrast)var(--tw-backdrop-grayscale)var(--tw-backdrop-hue-rotate)var(--tw-backdrop-invert)var(--tw-backdrop-opacity)var(--tw-backdrop-saturate)var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.hover\\:bg-slate-400:hover{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity,1))}.peer:hover~.peer-hover\\:border-slate-400{--tw-border-opacity:1;border-color:rgb(148 163 184/var(--tw-border-opacity,1))}.peer:hover~.peer-hover\\:bg-slate-300{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity,1))}.data-\\[focused\\]\\:bg-slate-400[data-focused]{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity,1))}.peer[data-focused]~.peer-data-\\[focused\\]\\:border-slate-400{--tw-border-opacity:1;border-color:rgb(148 163 184/var(--tw-border-opacity,1))}.peer[data-focused]~.peer-data-\\[focused\\]\\:bg-slate-300{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity,1))}";
1
+ //#region src/gui/TWMixin.css?inline
2
+ var TWMixin_default = "/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\n@tailwind base;\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\n@tailwind components;\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\n@tailwind utilities;\n";
3
+
4
+ //#endregion
2
5
  export { TWMixin_default as default };
6
+ //# sourceMappingURL=TWMixin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TWMixin.js","names":[],"sources":["../../src/gui/TWMixin.css?inline"],"sourcesContent":["export default \"/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\\n@tailwind base;\\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\\n@tailwind components;\\n/* biome-ignore lint/suspicious/noUnknownAtRules: @tailwind is a valid Tailwind CSS directive */\\n@tailwind utilities;\\n\""],"mappings":";AAAA,sBAAe"}
@@ -1,5 +1,7 @@
1
1
  import TWMixin_default from "./TWMixin.js";
2
- var twSheet = null;
2
+
3
+ //#region src/gui/TWMixin.ts
4
+ let twSheet = null;
3
5
  if (typeof window !== "undefined" && typeof CSSStyleSheet !== "undefined") try {
4
6
  twSheet = new CSSStyleSheet();
5
7
  if (typeof twSheet.replaceSync === "function") twSheet.replaceSync(TWMixin_default);
@@ -28,4 +30,7 @@ function TWMixin(Base) {
28
30
  }
29
31
  return TWElement;
30
32
  }
33
+
34
+ //#endregion
31
35
  export { TWMixin };
36
+ //# sourceMappingURL=TWMixin2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TWMixin2.js","names":["twSheet: CSSStyleSheet | null","twStyle","constructorStylesheets: CSSStyleSheet[]"],"sources":["../../src/gui/TWMixin.ts"],"sourcesContent":["import type { CSSResult, LitElement } from \"lit\";\n// @ts-expect-error cannot figure out how to declare this module as a string\nimport twStyle from \"./TWMixin.css?inline\";\n\nlet twSheet: CSSStyleSheet | null = null;\nif (typeof window !== \"undefined\" && typeof CSSStyleSheet !== \"undefined\") {\n try {\n twSheet = new CSSStyleSheet();\n if (typeof twSheet.replaceSync === \"function\") {\n twSheet.replaceSync(twStyle);\n }\n } catch (_error) {\n // CSSStyleSheet or replaceSync not supported in this environment\n twSheet = null;\n }\n}\nexport function TWMixin<T extends new (...args: any[]) => LitElement>(Base: T) {\n class TWElement extends Base {\n createRenderRoot() {\n const renderRoot = super.createRenderRoot();\n if (!(renderRoot instanceof ShadowRoot)) {\n throw new Error(\n \"TWMixin can only be applied to elements with shadow roots\",\n );\n }\n if (!twSheet) {\n throw new Error(\n \"twSheet not found. Probable cause: CSSStyleSheet not supported in this environment\",\n );\n }\n\n const constructorStylesheets: CSSStyleSheet[] = [];\n const constructorStyles = ((\"styles\" in this.constructor &&\n this.constructor.styles) ||\n []) as CSSResult | CSSResult[];\n\n if (Array.isArray(constructorStyles)) {\n for (const item of constructorStyles) {\n if (item.styleSheet) {\n constructorStylesheets.push(item.styleSheet);\n }\n }\n } else if (constructorStyles.styleSheet) {\n constructorStylesheets.push(constructorStyles.styleSheet);\n }\n\n if (renderRoot?.adoptedStyleSheets) {\n renderRoot.adoptedStyleSheets = [\n twSheet,\n ...renderRoot.adoptedStyleSheets,\n ...constructorStylesheets,\n ];\n } else {\n renderRoot.adoptedStyleSheets = [twSheet, ...constructorStylesheets];\n }\n return renderRoot;\n }\n }\n\n return TWElement as T;\n}\n"],"mappings":";;;AAIA,IAAIA,UAAgC;AACpC,IAAI,OAAO,WAAW,eAAe,OAAO,kBAAkB,YAC5D,KAAI;AACF,WAAU,IAAI,eAAe;AAC7B,KAAI,OAAO,QAAQ,gBAAgB,WACjC,SAAQ,YAAYC,gBAAQ;SAEvB,QAAQ;AAEf,WAAU;;AAGd,SAAgB,QAAsD,MAAS;CAC7E,MAAM,kBAAkB,KAAK;EAC3B,mBAAmB;GACjB,MAAM,aAAa,MAAM,kBAAkB;AAC3C,OAAI,EAAE,sBAAsB,YAC1B,OAAM,IAAI,MACR,4DACD;AAEH,OAAI,CAAC,QACH,OAAM,IAAI,MACR,qFACD;GAGH,MAAMC,yBAA0C,EAAE;GAClD,MAAM,oBAAsB,YAAY,KAAK,eAC3C,KAAK,YAAY,UACjB,EAAE;AAEJ,OAAI,MAAM,QAAQ,kBAAkB,EAClC;SAAK,MAAM,QAAQ,kBACjB,KAAI,KAAK,WACP,wBAAuB,KAAK,KAAK,WAAW;cAGvC,kBAAkB,WAC3B,wBAAuB,KAAK,kBAAkB,WAAW;AAG3D,OAAI,YAAY,mBACd,YAAW,qBAAqB;IAC9B;IACA,GAAG,WAAW;IACd,GAAG;IACJ;OAED,YAAW,qBAAqB,CAAC,SAAS,GAAG,uBAAuB;AAEtE,UAAO;;;AAIX,QAAO"}
@@ -7,6 +7,8 @@ import { TargetController } from "../elements/TargetController.js";
7
7
  import { isControllable } from "./Controllable.js";
8
8
  import { consume } from "@lit/context";
9
9
  import { property, state } from "lit/decorators.js";
10
+
11
+ //#region src/gui/TargetOrContextMixin.ts
10
12
  var ContextRequestEvent = class extends Event {
11
13
  constructor(context, contextTarget, callback, subscribe) {
12
14
  super("context-request", {
@@ -95,4 +97,7 @@ function TargetOrContextMixin(superClass, contextToProxy) {
95
97
  })], TargetOrContextClass.prototype, "contextFromParent", void 0);
96
98
  return TargetOrContextClass;
97
99
  }
100
+
101
+ //#endregion
98
102
  export { TargetOrContextMixin };
103
+ //# sourceMappingURL=TargetOrContextMixin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TargetOrContextMixin.js","names":["#targetController","#contextRequestHandler","#contextUnsubscribe","#additionalContextUnsubscribes","additionalContexts: Array<[Context<any, any>, string]>","#subscribeToTargetContext"],"sources":["../../src/gui/TargetOrContextMixin.ts"],"sourcesContent":["import { type Context, consume } from \"@lit/context\";\nimport type { LitElement } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { isEFTemporal } from \"../elements/EFTemporal.js\";\nimport { TargetController } from \"../elements/TargetController.js\";\nimport { type ControllableInterface, isControllable } from \"./Controllable.js\";\nimport { currentTimeContext } from \"./currentTimeContext.js\";\nimport { durationContext } from \"./durationContext.js\";\nimport { loopContext, playingContext } from \"./playingContext.js\";\n\ntype Constructor<T = {}> = new (...args: any[]) => T;\n\nclass ContextRequestEvent extends Event {\n context: Context<any, any>;\n contextTarget: Element;\n callback: (value: any, unsubscribe: () => void) => void;\n subscribe: boolean;\n\n constructor(\n context: Context<any, any>,\n contextTarget: Element,\n callback: (value: any, unsubscribe: () => void) => void,\n subscribe: boolean,\n ) {\n super(\"context-request\", { bubbles: true, composed: true });\n this.context = context;\n this.contextTarget = contextTarget;\n this.callback = callback;\n this.subscribe = subscribe ?? false;\n }\n}\n\nexport function TargetOrContextMixin<T extends Constructor<LitElement>>(\n superClass: T,\n contextToProxy: Context<any, any>,\n) {\n class TargetOrContextClass extends superClass {\n @property({ type: String })\n target = \"\";\n\n @state()\n targetElement: ControllableInterface | null = null;\n\n // @ts-expect-error contextToProxy is generic but provides ControllableInterface at runtime\n @consume({ context: contextToProxy, subscribe: true })\n contextFromParent: ControllableInterface | null = null;\n\n #targetController?: TargetController;\n #contextUnsubscribe?: () => void;\n #contextRequestHandler?: (event: Event) => void;\n #additionalContextUnsubscribes = new Map<Context<any, any>, () => void>();\n\n get effectiveContext(): ControllableInterface | null {\n return this.targetElement ?? this.contextFromParent;\n }\n\n connectedCallback() {\n super.connectedCallback();\n if (this.target) {\n this.#targetController = new TargetController(\n this as any as LitElement & {\n targetElement: Element | null;\n target: string;\n },\n );\n }\n\n // Intercept context-request events and redirect them to targetElement\n this.#contextRequestHandler = (event: Event) => {\n if (this.targetElement && event.type === \"context-request\") {\n event.stopPropagation();\n this.targetElement.dispatchEvent(\n new (event.constructor as any)(event.type, event),\n );\n }\n };\n this.addEventListener(\n \"context-request\",\n this.#contextRequestHandler,\n true,\n );\n }\n\n #subscribeToTargetContext() {\n if (!this.targetElement) return;\n\n this.#contextUnsubscribe?.();\n\n // Unsubscribe from all additional contexts\n for (const unsubscribe of this.#additionalContextUnsubscribes.values()) {\n unsubscribe();\n }\n this.#additionalContextUnsubscribes.clear();\n\n // Subscribe to efContext\n const event = new ContextRequestEvent(\n contextToProxy,\n this,\n (value, unsubscribe) => {\n (this as any).contextFromParent = value;\n this.#contextUnsubscribe = unsubscribe;\n },\n true,\n );\n this.targetElement.dispatchEvent(event);\n\n // Subscribe to additional contexts that controls commonly need\n const additionalContexts: Array<[Context<any, any>, string]> = [\n [playingContext, \"playing\"],\n [loopContext, \"loop\"],\n [currentTimeContext, \"currentTimeMs\"],\n [durationContext, \"durationMs\"],\n ];\n\n for (const [context, propertyName] of additionalContexts) {\n const contextEvent = new ContextRequestEvent(\n context,\n this,\n (value, unsubscribe) => {\n // Update the control's property if it exists\n if (propertyName in this) {\n (this as any)[propertyName] = value;\n }\n this.#additionalContextUnsubscribes.set(context, unsubscribe);\n },\n true,\n );\n this.targetElement.dispatchEvent(contextEvent);\n }\n }\n\n updated(changedProperties: Map<string | number | symbol, unknown>): void {\n super.updated?.(changedProperties);\n\n if (changedProperties.has(\"targetElement\") && this.targetElement) {\n if (\n isEFTemporal(this.targetElement) &&\n !isControllable(this.targetElement)\n ) {\n console.warn(\n \"Control element is targeting a non-root temporal element without playbackController. \" +\n \"Controls can only target root temporal elements (not nested within a timegroup). \" +\n \"Target element:\",\n this.targetElement,\n );\n }\n this.#subscribeToTargetContext();\n }\n\n if (changedProperties.has(\"target\")) {\n if (this.target && !this.#targetController) {\n this.#targetController = new TargetController(\n this as any as LitElement & {\n targetElement: Element | null;\n target: string;\n },\n );\n }\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.#contextUnsubscribe?.();\n for (const unsubscribe of this.#additionalContextUnsubscribes.values()) {\n unsubscribe();\n }\n this.#additionalContextUnsubscribes.clear();\n if (this.#contextRequestHandler) {\n this.removeEventListener(\n \"context-request\",\n this.#contextRequestHandler,\n true,\n );\n }\n }\n }\n\n return TargetOrContextClass as Constructor<{\n target: string;\n targetElement: ControllableInterface | null;\n effectiveContext: ControllableInterface | null;\n }> &\n T;\n}\n"],"mappings":";;;;;;;;;;;AAYA,IAAM,sBAAN,cAAkC,MAAM;CAMtC,YACE,SACA,eACA,UACA,WACA;AACA,QAAM,mBAAmB;GAAE,SAAS;GAAM,UAAU;GAAM,CAAC;AAC3D,OAAK,UAAU;AACf,OAAK,gBAAgB;AACrB,OAAK,WAAW;AAChB,OAAK,YAAY,aAAa;;;AAIlC,SAAgB,qBACd,YACA,gBACA;CACA,MAAM,6BAA6B,WAAW;;;iBAEnC;wBAGqC;4BAII;;EAElD;EACA;EACA;EACA,iDAAiC,IAAI,KAAoC;EAEzE,IAAI,mBAAiD;AACnD,UAAO,KAAK,iBAAiB,KAAK;;EAGpC,oBAAoB;AAClB,SAAM,mBAAmB;AACzB,OAAI,KAAK,OACP,OAAKA,mBAAoB,IAAI,iBAC3B,KAID;AAIH,SAAKC,yBAA0B,UAAiB;AAC9C,QAAI,KAAK,iBAAiB,MAAM,SAAS,mBAAmB;AAC1D,WAAM,iBAAiB;AACvB,UAAK,cAAc,cACjB,IAAK,MAAM,YAAoB,MAAM,MAAM,MAAM,CAClD;;;AAGL,QAAK,iBACH,mBACA,MAAKA,uBACL,KACD;;EAGH,4BAA4B;AAC1B,OAAI,CAAC,KAAK,cAAe;AAEzB,SAAKC,sBAAuB;AAG5B,QAAK,MAAM,eAAe,MAAKC,8BAA+B,QAAQ,CACpE,cAAa;AAEf,SAAKA,8BAA+B,OAAO;GAG3C,MAAM,QAAQ,IAAI,oBAChB,gBACA,OACC,OAAO,gBAAgB;AACtB,IAAC,KAAa,oBAAoB;AAClC,UAAKD,qBAAsB;MAE7B,KACD;AACD,QAAK,cAAc,cAAc,MAAM;GAGvC,MAAME,qBAAyD;IAC7D,CAAC,gBAAgB,UAAU;IAC3B,CAAC,aAAa,OAAO;IACrB,CAAC,oBAAoB,gBAAgB;IACrC,CAAC,iBAAiB,aAAa;IAChC;AAED,QAAK,MAAM,CAAC,SAAS,iBAAiB,oBAAoB;IACxD,MAAM,eAAe,IAAI,oBACvB,SACA,OACC,OAAO,gBAAgB;AAEtB,SAAI,gBAAgB,KAClB,CAAC,KAAa,gBAAgB;AAEhC,WAAKD,8BAA+B,IAAI,SAAS,YAAY;OAE/D,KACD;AACD,SAAK,cAAc,cAAc,aAAa;;;EAIlD,QAAQ,mBAAiE;AACvE,SAAM,UAAU,kBAAkB;AAElC,OAAI,kBAAkB,IAAI,gBAAgB,IAAI,KAAK,eAAe;AAChE,QACE,aAAa,KAAK,cAAc,IAChC,CAAC,eAAe,KAAK,cAAc,CAEnC,SAAQ,KACN,yLAGA,KAAK,cACN;AAEH,UAAKE,0BAA2B;;AAGlC,OAAI,kBAAkB,IAAI,SAAS,EACjC;QAAI,KAAK,UAAU,CAAC,MAAKL,iBACvB,OAAKA,mBAAoB,IAAI,iBAC3B,KAID;;;EAKP,uBAAuB;AACrB,SAAM,sBAAsB;AAC5B,SAAKE,sBAAuB;AAC5B,QAAK,MAAM,eAAe,MAAKC,8BAA+B,QAAQ,CACpE,cAAa;AAEf,SAAKA,8BAA+B,OAAO;AAC3C,OAAI,MAAKF,sBACP,MAAK,oBACH,mBACA,MAAKA,uBACL,KACD;;;aAxIJ,SAAS,EAAE,MAAM,QAAQ,CAAC;aAG1B,OAAO;aAIP,QAAQ;EAAE,SAAS;EAAgB,WAAW;EAAM,CAAC;AAsIxD,QAAO"}
@@ -1,3 +1,8 @@
1
1
  import { createContext } from "@lit/context";
2
+
3
+ //#region src/gui/currentTimeContext.ts
2
4
  const currentTimeContext = createContext(Symbol("currentTimeMs"));
5
+
6
+ //#endregion
3
7
  export { currentTimeContext };
8
+ //# sourceMappingURL=currentTimeContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentTimeContext.js","names":[],"sources":["../../src/gui/currentTimeContext.ts"],"sourcesContent":["import { createContext } from \"@lit/context\";\n\nexport const currentTimeContext = createContext<number>(\n Symbol(\"currentTimeMs\"),\n);\n"],"mappings":";;;AAEA,MAAa,qBAAqB,cAChC,OAAO,gBAAgB,CACxB"}
@@ -1,3 +1,8 @@
1
1
  import { createContext } from "@lit/context";
2
+
3
+ //#region src/gui/durationContext.ts
2
4
  const durationContext = createContext(Symbol("durationMs"));
5
+
6
+ //#endregion
3
7
  export { durationContext };
8
+ //# sourceMappingURL=durationContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durationContext.js","names":[],"sources":["../../src/gui/durationContext.ts"],"sourcesContent":["import { createContext } from \"@lit/context\";\n\nexport const durationContext = createContext<number>(Symbol(\"durationMs\"));\n"],"mappings":";;;AAEA,MAAa,kBAAkB,cAAsB,OAAO,aAAa,CAAC"}
@@ -1,3 +1,8 @@
1
1
  import { createContext } from "@lit/context";
2
+
3
+ //#region src/gui/efContext.ts
2
4
  const efContext = createContext(Symbol("efContext"));
5
+
6
+ //#endregion
3
7
  export { efContext };
8
+ //# sourceMappingURL=efContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"efContext.js","names":[],"sources":["../../src/gui/efContext.ts"],"sourcesContent":["import { createContext } from \"@lit/context\";\nimport type { ControllableInterface } from \"./Controllable.js\";\n\nexport const efContext = createContext<ControllableInterface | null>(\n Symbol(\"efContext\"),\n);\n"],"mappings":";;;AAGA,MAAa,YAAY,cACvB,OAAO,YAAY,CACpB"}
@@ -1,3 +1,8 @@
1
1
  import { createContext } from "@lit/context";
2
+
3
+ //#region src/gui/fetchContext.ts
2
4
  const fetchContext = createContext(Symbol("fetchContext"));
5
+
6
+ //#endregion
3
7
  export { fetchContext };
8
+ //# sourceMappingURL=fetchContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchContext.js","names":[],"sources":["../../src/gui/fetchContext.ts"],"sourcesContent":["import { createContext } from \"@lit/context\";\n\nexport const fetchContext = createContext<\n (url: string, init?: RequestInit) => Promise<Response>\n>(Symbol(\"fetchContext\"));\n"],"mappings":";;;AAEA,MAAa,eAAe,cAE1B,OAAO,eAAe,CAAC"}
@@ -1,6 +1,7 @@
1
- export interface FocusContext {
2
- focusedElement: HTMLElement | null;
1
+ //#region src/gui/focusContext.d.ts
2
+ interface FocusContext {
3
+ focusedElement: HTMLElement | null;
3
4
  }
4
- export declare const focusContext: {
5
- __context__: FocusContext;
6
- };
5
+ //#endregion
6
+ export { FocusContext };
7
+ //# sourceMappingURL=focusContext.d.ts.map
@@ -1,3 +1,8 @@
1
1
  import { createContext } from "@lit/context";
2
+
3
+ //#region src/gui/focusContext.ts
2
4
  const focusContext = createContext(Symbol("focusContext"));
5
+
6
+ //#endregion
3
7
  export { focusContext };
8
+ //# sourceMappingURL=focusContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusContext.js","names":[],"sources":["../../src/gui/focusContext.ts"],"sourcesContent":["import { createContext } from \"@lit/context\";\n\nexport interface FocusContext {\n focusedElement: HTMLElement | null;\n}\n\nexport const focusContext = createContext<FocusContext>(Symbol(\"focusContext\"));\n"],"mappings":";;;AAMA,MAAa,eAAe,cAA4B,OAAO,eAAe,CAAC"}
@@ -1,3 +1,8 @@
1
1
  import { createContext } from "@lit/context";
2
+
3
+ //#region src/gui/focusedElementContext.ts
2
4
  const focusedElementContext = createContext(Symbol("focusedElement"));
5
+
6
+ //#endregion
3
7
  export { focusedElementContext };
8
+ //# sourceMappingURL=focusedElementContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focusedElementContext.js","names":[],"sources":["../../src/gui/focusedElementContext.ts"],"sourcesContent":["import { createContext } from \"@lit/context\";\n\nexport const focusedElementContext = createContext<HTMLElement | undefined>(\n Symbol(\"focusedElement\"),\n);\n"],"mappings":";;;AAEA,MAAa,wBAAwB,cACnC,OAAO,iBAAiB,CACzB"}
@@ -1,4 +1,9 @@
1
1
  import { createContext } from "@lit/context";
2
+
3
+ //#region src/gui/playingContext.ts
2
4
  const playingContext = createContext(Symbol("playingContext"));
3
5
  const loopContext = createContext(Symbol("loopContext"));
6
+
7
+ //#endregion
4
8
  export { loopContext, playingContext };
9
+ //# sourceMappingURL=playingContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playingContext.js","names":[],"sources":["../../src/gui/playingContext.ts"],"sourcesContent":["import { createContext } from \"@lit/context\";\n\nexport const playingContext = createContext<boolean>(Symbol(\"playingContext\"));\n\nexport const loopContext = createContext<boolean>(Symbol(\"loopContext\"));\n"],"mappings":";;;AAEA,MAAa,iBAAiB,cAAuB,OAAO,iBAAiB,CAAC;AAE9E,MAAa,cAAc,cAAuB,OAAO,cAAc,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,26 +1,27 @@
1
- export { EFTimegroup } from './elements/EFTimegroup.js';
2
- export { EFImage } from './elements/EFImage.js';
3
- export type { EFMedia } from './elements/EFMedia.js';
4
- export { EFAudio } from './elements/EFAudio.js';
5
- export { EFVideo } from './elements/EFVideo.js';
6
- export { EFCaptions, EFCaptionsActiveWord, EFCaptionsAfterActiveWord, EFCaptionsBeforeActiveWord, EFCaptionsSegment, } from './elements/EFCaptions.js';
7
- export { EFWaveform } from './elements/EFWaveform.js';
8
- export { EFConfiguration } from './gui/EFConfiguration.ts';
9
- export { EFWorkbench } from './gui/EFWorkbench.js';
10
- export { EFPreview } from './gui/EFPreview.js';
11
- export { EFFilmstrip } from './gui/EFFilmstrip.js';
12
- export { EFTogglePlay } from './gui/EFTogglePlay.js';
13
- export { EFPlay } from './gui/EFPlay.js';
14
- export { EFPause } from './gui/EFPause.js';
15
- export { EFToggleLoop } from './gui/EFToggleLoop.js';
16
- export { EFScrubber } from './gui/EFScrubber.js';
17
- export { EFTimeDisplay } from './gui/EFTimeDisplay.js';
18
- export { type DialChangeDetail, EFDial } from './gui/EFDial.js';
19
- export { EFControls } from './gui/EFControls.js';
20
- export { EFFocusOverlay } from './gui/EFFocusOverlay.js';
21
- export { type BoxBounds, EFResizableBox } from './gui/EFResizableBox.ts';
22
- export { EFFitScale } from './gui/EFFitScale.js';
23
- export { EFSurface } from './elements/EFSurface.ts';
24
- export { EFThumbnailStrip } from './elements/EFThumbnailStrip.ts';
25
- export { getRenderInfo, RenderInfo } from './getRenderInfo.js';
26
- export type { TraceContext } from './otel/tracingHelpers.js';
1
+ import { TraceContext } from "./otel/tracingHelpers.js";
2
+ import { EFMedia } from "./elements/EFMedia.js";
3
+ import { EFTimegroup } from "./elements/EFTimegroup.js";
4
+ import { EFImage } from "./elements/EFImage.js";
5
+ import { EFAudio } from "./elements/EFAudio.js";
6
+ import { EFVideo } from "./elements/EFVideo.js";
7
+ import { EFCaptions, EFCaptionsActiveWord, EFCaptionsAfterActiveWord, EFCaptionsBeforeActiveWord, EFCaptionsSegment } from "./elements/EFCaptions.js";
8
+ import { EFWaveform } from "./elements/EFWaveform.js";
9
+ import { EFConfiguration } from "./gui/EFConfiguration.js";
10
+ import { EFWorkbench } from "./gui/EFWorkbench.js";
11
+ import { EFPreview } from "./gui/EFPreview.js";
12
+ import { EFFilmstrip } from "./gui/EFFilmstrip.js";
13
+ import { EFTogglePlay } from "./gui/EFTogglePlay.js";
14
+ import { EFPlay } from "./gui/EFPlay.js";
15
+ import { EFPause } from "./gui/EFPause.js";
16
+ import { EFToggleLoop } from "./gui/EFToggleLoop.js";
17
+ import { EFScrubber } from "./gui/EFScrubber.js";
18
+ import { EFTimeDisplay } from "./gui/EFTimeDisplay.js";
19
+ import { DialChangeDetail, EFDial } from "./gui/EFDial.js";
20
+ import { EFControls } from "./gui/EFControls.js";
21
+ import { EFFocusOverlay } from "./gui/EFFocusOverlay.js";
22
+ import { BoxBounds, EFResizableBox } from "./gui/EFResizableBox.js";
23
+ import { EFFitScale } from "./gui/EFFitScale.js";
24
+ import { EFSurface } from "./elements/EFSurface.js";
25
+ import { EFThumbnailStrip } from "./elements/EFThumbnailStrip.js";
26
+ import { RenderInfo, getRenderInfo } from "./getRenderInfo.js";
27
+ export { type BoxBounds, type DialChangeDetail, EFAudio, EFCaptions, EFCaptionsActiveWord, EFCaptionsAfterActiveWord, EFCaptionsBeforeActiveWord, EFCaptionsSegment, EFConfiguration, EFControls, EFDial, EFFilmstrip, EFFitScale, EFFocusOverlay, EFImage, type EFMedia, EFPause, EFPlay, EFPreview, EFResizableBox, EFScrubber, EFSurface, EFThumbnailStrip, EFTimeDisplay, EFTimegroup, EFToggleLoop, EFTogglePlay, EFVideo, EFWaveform, EFWorkbench, RenderInfo, type TraceContext, getRenderInfo };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /* empty css */
1
+ import "./elements.js";
2
2
  import { EFConfiguration } from "./gui/EFConfiguration.js";
3
3
  import "./elements/EFMedia.js";
4
4
  import { EFTimegroup } from "./elements/EFTimegroup.js";
@@ -25,5 +25,10 @@ import { EFSurface } from "./elements/EFSurface.js";
25
25
  import { EFThumbnailStrip } from "./elements/EFThumbnailStrip.js";
26
26
  import "./EF_FRAMEGEN.js";
27
27
  import { RenderInfo, getRenderInfo } from "./getRenderInfo.js";
28
+
29
+ //#region src/index.ts
28
30
  if (typeof window !== "undefined") window.EF_REGISTERED = true;
31
+
32
+ //#endregion
29
33
  export { EFAudio, EFCaptions, EFCaptionsActiveWord, EFCaptionsAfterActiveWord, EFCaptionsBeforeActiveWord, EFCaptionsSegment, EFConfiguration, EFControls, EFDial, EFFilmstrip, EFFitScale, EFFocusOverlay, EFImage, EFPause, EFPlay, EFPreview, EFResizableBox, EFScrubber, EFSurface, EFThumbnailStrip, EFTimeDisplay, EFTimegroup, EFToggleLoop, EFTogglePlay, EFVideo, EFWaveform, EFWorkbench, RenderInfo, getRenderInfo };
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import \"./elements.css\";\n\nimport \"./elements/EFTimegroup.js\";\n\nexport { EFTimegroup } from \"./elements/EFTimegroup.js\";\n\nimport \"./elements/EFImage.js\";\n\nexport { EFImage } from \"./elements/EFImage.js\";\n\nimport \"./elements/EFMedia.js\";\n\nexport type { EFMedia } from \"./elements/EFMedia.js\";\n\nimport \"./elements/EFAudio.js\";\n\nexport { EFAudio } from \"./elements/EFAudio.js\";\n\nimport \"./elements/EFVideo.js\";\n\nexport { EFVideo } from \"./elements/EFVideo.js\";\n\nimport \"./elements/EFCaptions.js\";\n\nexport {\n EFCaptions,\n EFCaptionsActiveWord,\n EFCaptionsAfterActiveWord,\n EFCaptionsBeforeActiveWord,\n EFCaptionsSegment,\n} from \"./elements/EFCaptions.js\";\n\nimport \"./elements/EFWaveform.js\";\n\nexport { EFWaveform } from \"./elements/EFWaveform.js\";\n\nimport \"./gui/EFConfiguration.ts\";\n\nexport { EFConfiguration } from \"./gui/EFConfiguration.ts\";\n\nimport \"./gui/EFWorkbench.js\";\n\nexport { EFWorkbench } from \"./gui/EFWorkbench.js\";\n\nimport \"./gui/EFPreview.js\";\n\nexport { EFPreview } from \"./gui/EFPreview.js\";\n\nimport \"./gui/EFFilmstrip.js\";\n\nexport { EFFilmstrip } from \"./gui/EFFilmstrip.js\";\n\nimport \"./gui/EFTogglePlay.js\";\n\nexport { EFTogglePlay } from \"./gui/EFTogglePlay.js\";\n\nimport \"./gui/EFPlay.js\";\n\nexport { EFPlay } from \"./gui/EFPlay.js\";\n\nimport \"./gui/EFPause.js\";\n\nexport { EFPause } from \"./gui/EFPause.js\";\n\nimport \"./gui/EFToggleLoop.js\";\n\nexport { EFToggleLoop } from \"./gui/EFToggleLoop.js\";\n\nimport \"./gui/EFScrubber.js\";\n\nexport { EFScrubber } from \"./gui/EFScrubber.js\";\n\nimport \"./gui/EFTimeDisplay.js\";\n\nexport { EFTimeDisplay } from \"./gui/EFTimeDisplay.js\";\n\nimport \"./gui/EFDial.js\";\n\nexport { type DialChangeDetail, EFDial } from \"./gui/EFDial.js\";\n\nimport \"./gui/EFControls.js\";\n\nexport { EFControls } from \"./gui/EFControls.js\";\n\nimport \"./gui/EFFocusOverlay.js\";\n\nexport { EFFocusOverlay } from \"./gui/EFFocusOverlay.js\";\n\nimport \"./gui/EFResizableBox.ts\";\n\nexport { type BoxBounds, EFResizableBox } from \"./gui/EFResizableBox.ts\";\n\nimport \"./gui/EFFitScale.js\";\n\nexport { EFFitScale } from \"./gui/EFFitScale.js\";\n\nimport \"./elements/EFSurface.ts\";\n\nexport { EFSurface } from \"./elements/EFSurface.ts\";\n\nimport \"./elements/EFThumbnailStrip.ts\";\n\nexport { EFThumbnailStrip } from \"./elements/EFThumbnailStrip.ts\";\n\nif (typeof window !== \"undefined\") {\n // @ts-expect-error\n window.EF_REGISTERED = true;\n}\n\nimport \"./EF_FRAMEGEN.js\";\n\nexport { getRenderInfo, RenderInfo } from \"./getRenderInfo.js\";\nexport type { TraceContext } from \"./otel/tracingHelpers.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwGA,IAAI,OAAO,WAAW,YAEpB,QAAO,gBAAgB"}
@@ -1,3 +1,4 @@
1
+ //#region src/msToTimeCode.ts
1
2
  const msToTimeCode = (ms, subSecond = false) => {
2
3
  const seconds = Math.floor(ms / 1e3);
3
4
  const minutes = Math.floor(seconds / 60);
@@ -10,4 +11,7 @@ const msToTimeCode = (ms, subSecond = false) => {
10
11
  }
11
12
  return timecode;
12
13
  };
14
+
15
+ //#endregion
13
16
  export { msToTimeCode };
17
+ //# sourceMappingURL=msToTimeCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"msToTimeCode.js","names":[],"sources":["../src/msToTimeCode.ts"],"sourcesContent":["export const msToTimeCode = (ms: number, subSecond = false): string => {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n const pad = (num: number): string => num.toString().padStart(2, \"0\");\n\n let timecode = `${pad(hours)}:${pad(minutes % 60)}:${pad(seconds % 60)}`;\n\n if (subSecond) {\n const subSeconds = Math.floor((ms % 1000) / 10);\n timecode += `.${subSeconds.toString().padStart(2, \"0\")}`;\n }\n\n return timecode;\n};\n"],"mappings":";AAAA,MAAa,gBAAgB,IAAY,YAAY,UAAkB;CACrE,MAAM,UAAU,KAAK,MAAM,KAAK,IAAK;CACrC,MAAM,UAAU,KAAK,MAAM,UAAU,GAAG;CACxC,MAAM,QAAQ,KAAK,MAAM,UAAU,GAAG;CAEtC,MAAM,OAAO,QAAwB,IAAI,UAAU,CAAC,SAAS,GAAG,IAAI;CAEpE,IAAI,WAAW,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,UAAU,GAAG,CAAC,GAAG,IAAI,UAAU,GAAG;AAEtE,KAAI,WAAW;EACb,MAAM,aAAa,KAAK,MAAO,KAAK,MAAQ,GAAG;AAC/C,cAAY,IAAI,WAAW,UAAU,CAAC,SAAS,GAAG,IAAI;;AAGxD,QAAO"}
@@ -1,4 +1,6 @@
1
1
  import { ExportResultCode } from "@opentelemetry/core";
2
+
3
+ //#region src/otel/BridgeSpanExporter.ts
2
4
  function toHex(value) {
3
5
  if (typeof value === "string") return value;
4
6
  if (Array.isArray(value)) return value.map((b) => {
@@ -84,4 +86,7 @@ var BridgeSpanExporter = class {
84
86
  return Promise.resolve();
85
87
  }
86
88
  };
89
+
90
+ //#endregion
87
91
  export { BridgeSpanExporter };
92
+ //# sourceMappingURL=BridgeSpanExporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BridgeSpanExporter.js","names":[],"sources":["../../src/otel/BridgeSpanExporter.ts"],"sourcesContent":["import { type ExportResult, ExportResultCode } from \"@opentelemetry/core\";\nimport type { ReadableSpan, SpanExporter } from \"@opentelemetry/sdk-trace-base\";\n\nfunction toHex(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (Array.isArray(value)) {\n return value\n .map((b) => {\n const byte = typeof b === \"number\" ? b : 0;\n return byte.toString(16).padStart(2, \"0\");\n })\n .join(\"\");\n }\n if (ArrayBuffer.isView(value)) {\n return Array.from(value as Uint8Array)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n }\n return String(value);\n}\n\ninterface OtlpAttributeValue {\n stringValue?: string;\n intValue?: number;\n doubleValue?: number;\n boolValue?: boolean;\n arrayValue?: { values: OtlpAttributeValue[] };\n}\n\nfunction convertAttribute(value: unknown): OtlpAttributeValue {\n if (typeof value === \"string\") return { stringValue: value };\n if (typeof value === \"number\")\n return Number.isInteger(value)\n ? { intValue: value }\n : { doubleValue: value };\n if (typeof value === \"boolean\") return { boolValue: value };\n if (Array.isArray(value))\n return { arrayValue: { values: value.map(convertAttribute) } };\n return { stringValue: String(value) };\n}\n\ninterface BridgeWithSpanExport {\n exportSpans?: (endpoint: string, payload: string) => void;\n}\n\nexport class BridgeSpanExporter implements SpanExporter {\n private bridge: BridgeWithSpanExport;\n private endpoint: string;\n\n constructor(bridge: BridgeWithSpanExport, endpoint: string) {\n this.bridge = bridge;\n this.endpoint = endpoint;\n }\n\n export(\n spans: ReadableSpan[],\n resultCallback: (result: ExportResult) => void,\n ): void {\n if (!this.bridge?.exportSpans) {\n resultCallback({ code: ExportResultCode.FAILED });\n return;\n }\n\n try {\n const otlpPayload = {\n resourceSpans: [\n {\n resource: {\n attributes: Object.entries(\n spans[0]?.resource?.attributes || {},\n ).map(([key, value]) => ({\n key,\n value: convertAttribute(value),\n })),\n },\n scopeSpans: [\n {\n scope: {\n name: \"telecine-browser\",\n version: \"1.0.0\",\n },\n spans: spans.map((span) => {\n const ctx = span.spanContext();\n return {\n traceId: toHex(ctx.traceId),\n spanId: toHex(ctx.spanId),\n parentSpanId: span.parentSpanId\n ? toHex(span.parentSpanId)\n : undefined,\n name: span.name,\n kind: span.kind,\n startTimeUnixNano: String(\n span.startTime[0] * 1_000_000_000 + span.startTime[1],\n ),\n endTimeUnixNano: String(\n span.endTime[0] * 1_000_000_000 + span.endTime[1],\n ),\n attributes: Object.entries(span.attributes).map(\n ([key, value]) => ({\n key,\n value: convertAttribute(value),\n }),\n ),\n status: span.status,\n events: span.events.map((event) => ({\n timeUnixNano: String(\n event.time[0] * 1_000_000_000 + event.time[1],\n ),\n name: event.name,\n attributes: Object.entries(event.attributes || {}).map(\n ([key, value]) => ({\n key,\n value: convertAttribute(value),\n }),\n ),\n })),\n links: span.links.map((link) => ({\n traceId: toHex(link.context.traceId),\n spanId: toHex(link.context.spanId),\n attributes: Object.entries(link.attributes || {}).map(\n ([key, value]) => ({\n key,\n value: convertAttribute(value),\n }),\n ),\n })),\n };\n }),\n },\n ],\n },\n ],\n };\n\n const serializedPayload = JSON.stringify(otlpPayload);\n\n this.bridge.exportSpans(this.endpoint, serializedPayload);\n resultCallback({ code: ExportResultCode.SUCCESS });\n } catch (error) {\n resultCallback({\n code: ExportResultCode.FAILED,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n}\n"],"mappings":"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"}
@@ -3,8 +3,10 @@ import { Resource } from "@opentelemetry/resources";
3
3
  import { BatchSpanProcessor, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
4
4
  import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
5
5
  import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
6
- var isInitialized = false;
7
- var provider = null;
6
+
7
+ //#region src/otel/setupBrowserTracing.ts
8
+ let isInitialized = false;
9
+ let provider = null;
8
10
  async function setupBrowserTracing(config) {
9
11
  if (isInitialized) return;
10
12
  try {
@@ -29,4 +31,7 @@ async function setupBrowserTracing(config) {
29
31
  throw error;
30
32
  }
31
33
  }
34
+
35
+ //#endregion
32
36
  export { setupBrowserTracing };
37
+ //# sourceMappingURL=setupBrowserTracing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupBrowserTracing.js","names":["provider: WebTracerProvider | null","spanProcessor: BatchSpanProcessor | SimpleSpanProcessor"],"sources":["../../src/otel/setupBrowserTracing.ts"],"sourcesContent":["import { Resource } from \"@opentelemetry/resources\";\nimport {\n BatchSpanProcessor,\n SimpleSpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport { WebTracerProvider } from \"@opentelemetry/sdk-trace-web\";\nimport { ATTR_SERVICE_NAME } from \"@opentelemetry/semantic-conventions\";\nimport { BridgeSpanExporter } from \"./BridgeSpanExporter.js\";\n\nlet isInitialized = false;\nlet provider: WebTracerProvider | null = null;\n\ninterface BridgeWithSpanExport {\n exportSpans?: (endpoint: string, payload: string) => void;\n}\n\nexport interface BrowserTracingConfig {\n otelEndpoint: string;\n serviceName?: string;\n bridge?: BridgeWithSpanExport;\n useBatching?: boolean;\n}\n\nexport async function setupBrowserTracing(\n config: BrowserTracingConfig,\n): Promise<void> {\n if (isInitialized) {\n return;\n }\n\n try {\n if (!config.bridge) {\n throw new Error(\"Bridge is required for browser tracing\");\n }\n\n const exporter = new BridgeSpanExporter(config.bridge, config.otelEndpoint);\n\n let spanProcessor: BatchSpanProcessor | SimpleSpanProcessor;\n if (config.useBatching) {\n spanProcessor = new BatchSpanProcessor(exporter, {\n maxQueueSize: 100,\n maxExportBatchSize: 10,\n scheduledDelayMillis: 500,\n });\n } else {\n spanProcessor = new SimpleSpanProcessor(exporter);\n }\n\n provider = new WebTracerProvider({\n resource: new Resource({\n [ATTR_SERVICE_NAME]: config.serviceName || \"telecine-browser\",\n }),\n spanProcessors: [spanProcessor],\n });\n\n // Dynamically import ZoneContextManager only when tracing is enabled\n // This prevents zone.js from being loaded for users who don't need tracing\n const { ZoneContextManager } = await import(\"@opentelemetry/context-zone\");\n\n provider.register({\n contextManager: new ZoneContextManager(),\n });\n\n isInitialized = true;\n } catch (error) {\n console.error(\"Failed to initialize browser tracing:\", error);\n throw error;\n }\n}\n\nexport function isBrowserTracingInitialized(): boolean {\n return isInitialized;\n}\n"],"mappings":";;;;;;;AASA,IAAI,gBAAgB;AACpB,IAAIA,WAAqC;AAazC,eAAsB,oBACpB,QACe;AACf,KAAI,cACF;AAGF,KAAI;AACF,MAAI,CAAC,OAAO,OACV,OAAM,IAAI,MAAM,yCAAyC;EAG3D,MAAM,WAAW,IAAI,mBAAmB,OAAO,QAAQ,OAAO,aAAa;EAE3E,IAAIC;AACJ,MAAI,OAAO,YACT,iBAAgB,IAAI,mBAAmB,UAAU;GAC/C,cAAc;GACd,oBAAoB;GACpB,sBAAsB;GACvB,CAAC;MAEF,iBAAgB,IAAI,oBAAoB,SAAS;AAGnD,aAAW,IAAI,kBAAkB;GAC/B,UAAU,IAAI,SAAS,GACpB,oBAAoB,OAAO,eAAe,oBAC5C,CAAC;GACF,gBAAgB,CAAC,cAAc;GAChC,CAAC;EAIF,MAAM,EAAE,uBAAuB,MAAM,OAAO;AAE5C,WAAS,SAAS,EAChB,gBAAgB,IAAI,oBAAoB,EACzC,CAAC;AAEF,kBAAgB;UACT,OAAO;AACd,UAAQ,MAAM,yCAAyC,MAAM;AAC7D,QAAM"}
@@ -1,34 +1,7 @@
1
- import { Context, Span } from '@opentelemetry/api';
2
- export type TraceContext = Record<string, string>;
3
- /**
4
- * Enable tracing globally. Call this during initialization if tracing is requested.
5
- */
6
- export declare function enableTracing(): void;
7
- /**
8
- * Check if tracing is currently enabled.
9
- */
10
- export declare function isTracingEnabled(): boolean;
11
- /**
12
- * Set the current frame's span. Call this when starting a frame render.
13
- * All spans created during this frame will use this as parent if
14
- * Zone.js doesn't provide one via context.active()
15
- */
16
- export declare function setCurrentFrameSpan(span: Span): void;
17
- /**
18
- * Clear the current frame span. Call this when a frame completes.
19
- */
20
- export declare function clearCurrentFrameSpan(): void;
21
- export declare function extractParentContext(traceContext?: TraceContext): Context;
22
- /**
23
- * Get the active span's context to pass to child operations
24
- * Use this when calling functions that create child spans
25
- */
26
- export declare function getActiveContext(): Context;
27
- /**
28
- * Wrapper that passes span context explicitly to the function
29
- * Use this for operations that need to store or propagate context across boundaries
30
- */
31
- export declare function withSpanAndContext<T>(name: string, attributes: Record<string, string | number | boolean> | undefined, parentContext: Context | undefined, fn: (span: Span, activeContext: Context) => Promise<T>): Promise<T>;
32
- export declare function createSpan(name: string, attributes?: Record<string, string | number | boolean>, parentContext?: Context): Span;
33
- export declare function withSpan<T>(name: string, attributes: Record<string, string | number | boolean> | undefined, parentContext: Context | undefined, fn: (span: Span) => Promise<T>): Promise<T>;
34
- export declare function withSpanSync<T>(name: string, attributes: Record<string, string | number | boolean> | undefined, parentContext: Context | undefined, fn: (span: Span) => T): T;
1
+ import "@opentelemetry/api";
2
+
3
+ //#region src/otel/tracingHelpers.d.ts
4
+ type TraceContext = Record<string, string>;
5
+ //#endregion
6
+ export { TraceContext };
7
+ //# sourceMappingURL=tracingHelpers.d.ts.map
@@ -1,15 +1,40 @@
1
1
  import { context, propagation, trace } from "@opentelemetry/api";
2
- var tracingEnabled = false;
2
+
3
+ //#region src/otel/tracingHelpers.ts
4
+ /**
5
+ * Global flag to enable/disable tracing.
6
+ * When false, all tracing functions become no-ops for zero overhead.
7
+ */
8
+ let tracingEnabled = false;
9
+ /**
10
+ * Enable tracing globally. Call this during initialization if tracing is requested.
11
+ */
3
12
  function enableTracing() {
4
13
  tracingEnabled = true;
5
14
  }
15
+ /**
16
+ * Check if tracing is currently enabled.
17
+ */
6
18
  function isTracingEnabled() {
7
19
  return tracingEnabled;
8
20
  }
9
- var currentFrameSpan;
21
+ /**
22
+ * Frame-local span storage for rendering.
23
+ * Since rendering is single-threaded and sequential (one frame at a time),
24
+ * we store the active frame span directly and use it as parent for orphaned spans.
25
+ */
26
+ let currentFrameSpan;
27
+ /**
28
+ * Set the current frame's span. Call this when starting a frame render.
29
+ * All spans created during this frame will use this as parent if
30
+ * Zone.js doesn't provide one via context.active()
31
+ */
10
32
  function setCurrentFrameSpan(span) {
11
33
  currentFrameSpan = span;
12
34
  }
35
+ /**
36
+ * Clear the current frame span. Call this when a frame completes.
37
+ */
13
38
  function clearCurrentFrameSpan() {
14
39
  currentFrameSpan = void 0;
15
40
  }
@@ -21,6 +46,10 @@ function extractParentContext(traceContext) {
21
46
  return context.active();
22
47
  }
23
48
  }
49
+ /**
50
+ * Wrapper that passes span context explicitly to the function
51
+ * Use this for operations that need to store or propagate context across boundaries
52
+ */
24
53
  async function withSpanAndContext(name, attributes, parentContext, fn) {
25
54
  if (!tracingEnabled) {
26
55
  const noopSpan = trace.getTracer("telecine-browser").startSpan(name);
@@ -109,4 +138,7 @@ function withSpanSync(name, attributes, parentContext, fn) {
109
138
  throw error;
110
139
  }
111
140
  }
141
+
142
+ //#endregion
112
143
  export { clearCurrentFrameSpan, enableTracing, extractParentContext, isTracingEnabled, setCurrentFrameSpan, withSpan, withSpanAndContext, withSpanSync };
144
+ //# sourceMappingURL=tracingHelpers.js.map