@editframe/elements 0.47.2 → 0.48.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 (405) hide show
  1. package/dist/DelayedLoadingState.js +1 -1
  2. package/dist/DelayedLoadingState.js.map +1 -1
  3. package/dist/EF_FRAMEGEN.js +1 -2
  4. package/dist/EF_FRAMEGEN.js.map +1 -1
  5. package/dist/EF_RENDERING.js +1 -1
  6. package/dist/EF_RENDERING.js.map +1 -1
  7. package/dist/_virtual/{_@oxc-project_runtime@0.95.0 → _@oxc-project_runtime@0.122.0}/helpers/decorate.js +2 -3
  8. package/dist/attachContextRoot.js +1 -2
  9. package/dist/attachContextRoot.js.map +1 -1
  10. package/dist/canvas/EFCanvas.d.ts +4 -7
  11. package/dist/canvas/EFCanvas.js +20 -21
  12. package/dist/canvas/EFCanvas.js.map +1 -1
  13. package/dist/canvas/EFCanvasItem.d.ts +4 -5
  14. package/dist/canvas/EFCanvasItem.js +3 -4
  15. package/dist/canvas/EFCanvasItem.js.map +1 -1
  16. package/dist/canvas/api/CanvasAPI.d.ts +0 -1
  17. package/dist/canvas/api/CanvasAPI.js +1 -1
  18. package/dist/canvas/api/CanvasAPI.js.map +1 -1
  19. package/dist/canvas/coordinateTransform.js +1 -1
  20. package/dist/canvas/coordinateTransform.js.map +1 -1
  21. package/dist/canvas/getElementBounds.js +1 -1
  22. package/dist/canvas/getElementBounds.js.map +1 -1
  23. package/dist/canvas/overlays/SelectionOverlay.d.ts +4 -4
  24. package/dist/canvas/overlays/SelectionOverlay.js +6 -7
  25. package/dist/canvas/overlays/SelectionOverlay.js.map +1 -1
  26. package/dist/canvas/overlays/overlayState.js +1 -2
  27. package/dist/canvas/overlays/overlayState.js.map +1 -1
  28. package/dist/canvas/selection/SelectionController.js +1 -2
  29. package/dist/canvas/selection/SelectionController.js.map +1 -1
  30. package/dist/canvas/selection/SelectionModel.d.ts +0 -1
  31. package/dist/canvas/selection/SelectionModel.js +1 -1
  32. package/dist/canvas/selection/SelectionModel.js.map +1 -1
  33. package/dist/canvas/selection/selectionContext.d.ts +0 -1
  34. package/dist/canvas/selection/selectionContext.js +1 -2
  35. package/dist/canvas/selection/selectionContext.js.map +1 -1
  36. package/dist/elements/ContainerInfo.js +1 -1
  37. package/dist/elements/ContainerInfo.js.map +1 -1
  38. package/dist/elements/CrossUpdateController.js +1 -1
  39. package/dist/elements/CrossUpdateController.js.map +1 -1
  40. package/dist/elements/EFAudio.d.ts +4 -4
  41. package/dist/elements/EFAudio.js +4 -6
  42. package/dist/elements/EFAudio.js.map +1 -1
  43. package/dist/elements/EFCaptions.d.ts +4 -4
  44. package/dist/elements/EFCaptions.js +8 -10
  45. package/dist/elements/EFCaptions.js.map +1 -1
  46. package/dist/elements/EFImage.d.ts +7 -7
  47. package/dist/elements/EFImage.js +4 -6
  48. package/dist/elements/EFImage.js.map +1 -1
  49. package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +2 -2
  50. package/dist/elements/EFMedia/BufferedSeekingInput.js +8 -9
  51. package/dist/elements/EFMedia/BufferedSeekingInput.js.map +1 -1
  52. package/dist/elements/EFMedia/CachedFetcher.js +1 -2
  53. package/dist/elements/EFMedia/CachedFetcher.js.map +1 -1
  54. package/dist/elements/EFMedia/MediaEngine.d.ts +0 -2
  55. package/dist/elements/EFMedia/MediaEngine.js +1 -2
  56. package/dist/elements/EFMedia/MediaEngine.js.map +1 -1
  57. package/dist/elements/EFMedia/SegmentIndex.d.ts +0 -3
  58. package/dist/elements/EFMedia/SegmentIndex.js +1 -2
  59. package/dist/elements/EFMedia/SegmentIndex.js.map +1 -1
  60. package/dist/elements/EFMedia/SegmentTransport.d.ts +0 -2
  61. package/dist/elements/EFMedia/SegmentTransport.js +1 -1
  62. package/dist/elements/EFMedia/SegmentTransport.js.map +1 -1
  63. package/dist/elements/EFMedia/TimingModel.d.ts +0 -2
  64. package/dist/elements/EFMedia/TimingModel.js +1 -1
  65. package/dist/elements/EFMedia/TimingModel.js.map +1 -1
  66. package/dist/elements/EFMedia/shared/AudioSpanUtils.js +1 -1
  67. package/dist/elements/EFMedia/shared/AudioSpanUtils.js.map +1 -1
  68. package/dist/elements/EFMedia/shared/GlobalInputCache.js +1 -2
  69. package/dist/elements/EFMedia/shared/GlobalInputCache.js.map +1 -1
  70. package/dist/elements/EFMedia/shared/PrecisionUtils.js +1 -1
  71. package/dist/elements/EFMedia/shared/PrecisionUtils.js.map +1 -1
  72. package/dist/elements/EFMedia/shared/ThumbnailExtractor.js +1 -2
  73. package/dist/elements/EFMedia/shared/ThumbnailExtractor.js.map +1 -1
  74. package/dist/elements/EFMedia/shared/timeoutUtils.js +1 -2
  75. package/dist/elements/EFMedia/shared/timeoutUtils.js.map +1 -1
  76. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js +1 -1
  77. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js.map +1 -1
  78. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.d.ts +0 -1
  79. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +12 -12
  80. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js.map +1 -1
  81. package/dist/elements/EFMedia.d.ts +2 -2
  82. package/dist/elements/EFMedia.js +2 -3
  83. package/dist/elements/EFMedia.js.map +1 -1
  84. package/dist/elements/EFMotionBlur.d.ts +0 -1
  85. package/dist/elements/EFMotionBlur.js +8 -15
  86. package/dist/elements/EFMotionBlur.js.map +1 -1
  87. package/dist/elements/EFPanZoom.d.ts +4 -4
  88. package/dist/elements/EFPanZoom.js +3 -4
  89. package/dist/elements/EFPanZoom.js.map +1 -1
  90. package/dist/elements/EFSourceMixin.js +2 -3
  91. package/dist/elements/EFSourceMixin.js.map +1 -1
  92. package/dist/elements/EFSurface.d.ts +6 -6
  93. package/dist/elements/EFSurface.js +3 -4
  94. package/dist/elements/EFSurface.js.map +1 -1
  95. package/dist/elements/EFTemporal.d.ts +0 -1
  96. package/dist/elements/EFTemporal.js +6 -7
  97. package/dist/elements/EFTemporal.js.map +1 -1
  98. package/dist/elements/EFText.d.ts +4 -4
  99. package/dist/elements/EFText.js +6 -7
  100. package/dist/elements/EFText.js.map +1 -1
  101. package/dist/elements/EFTextSegment.d.ts +4 -4
  102. package/dist/elements/EFTextSegment.js +3 -4
  103. package/dist/elements/EFTextSegment.js.map +1 -1
  104. package/dist/elements/EFTimegroup.d.ts +4 -10
  105. package/dist/elements/EFTimegroup.js +11 -12
  106. package/dist/elements/EFTimegroup.js.map +1 -1
  107. package/dist/elements/EFVideo.d.ts +6 -7
  108. package/dist/elements/EFVideo.js +7 -9
  109. package/dist/elements/EFVideo.js.map +1 -1
  110. package/dist/elements/EFWaveform.d.ts +4 -4
  111. package/dist/elements/EFWaveform.js +4 -6
  112. package/dist/elements/EFWaveform.js.map +1 -1
  113. package/dist/elements/ElementPositionInfo.js +1 -1
  114. package/dist/elements/ElementPositionInfo.js.map +1 -1
  115. package/dist/elements/FetchMixin.js +1 -1
  116. package/dist/elements/FetchMixin.js.map +1 -1
  117. package/dist/elements/SampleBuffer.js +1 -2
  118. package/dist/elements/SampleBuffer.js.map +1 -1
  119. package/dist/elements/TargetController.d.ts +0 -1
  120. package/dist/elements/TargetController.js +1 -1
  121. package/dist/elements/TargetController.js.map +1 -1
  122. package/dist/elements/TimegroupController.js +1 -1
  123. package/dist/elements/TimegroupController.js.map +1 -1
  124. package/dist/elements/cloneFactoryRegistry.js +1 -1
  125. package/dist/elements/cloneFactoryRegistry.js.map +1 -1
  126. package/dist/elements/durationConverter.js +4 -5
  127. package/dist/elements/durationConverter.js.map +1 -1
  128. package/dist/elements/easingUtils.js +1 -1
  129. package/dist/elements/easingUtils.js.map +1 -1
  130. package/dist/elements/findRootTemporal.js +1 -2
  131. package/dist/elements/findRootTemporal.js.map +1 -1
  132. package/dist/elements/parseTimeToMs.js +1 -1
  133. package/dist/elements/parseTimeToMs.js.map +1 -1
  134. package/dist/elements/renderTemporalAudio.js +1 -2
  135. package/dist/elements/renderTemporalAudio.js.map +1 -1
  136. package/dist/elements/setupTemporalHierarchy.js +1 -1
  137. package/dist/elements/setupTemporalHierarchy.js.map +1 -1
  138. package/dist/elements/updateAnimations.js +1 -2
  139. package/dist/elements/updateAnimations.js.map +1 -1
  140. package/dist/getRenderInfo.d.ts +0 -1
  141. package/dist/getRenderInfo.js +1 -2
  142. package/dist/getRenderInfo.js.map +1 -1
  143. package/dist/gui/ContextMixin.d.ts +0 -1
  144. package/dist/gui/ContextMixin.js +2 -3
  145. package/dist/gui/ContextMixin.js.map +1 -1
  146. package/dist/gui/Controllable.d.ts +0 -2
  147. package/dist/gui/Controllable.js +1 -2
  148. package/dist/gui/Controllable.js.map +1 -1
  149. package/dist/gui/EFActiveRootTemporal.d.ts +4 -5
  150. package/dist/gui/EFActiveRootTemporal.js +3 -4
  151. package/dist/gui/EFActiveRootTemporal.js.map +1 -1
  152. package/dist/gui/EFConfiguration.d.ts +4 -4
  153. package/dist/gui/EFConfiguration.js +3 -4
  154. package/dist/gui/EFConfiguration.js.map +1 -1
  155. package/dist/gui/EFControls.d.ts +2 -3
  156. package/dist/gui/EFControls.js +4 -5
  157. package/dist/gui/EFControls.js.map +1 -1
  158. package/dist/gui/EFDial.d.ts +4 -4
  159. package/dist/gui/EFDial.js +3 -4
  160. package/dist/gui/EFDial.js.map +1 -1
  161. package/dist/gui/EFFilmstrip.d.ts +6 -7
  162. package/dist/gui/EFFilmstrip.js +3 -4
  163. package/dist/gui/EFFilmstrip.js.map +1 -1
  164. package/dist/gui/EFFitScale.d.ts +3 -3
  165. package/dist/gui/EFFitScale.js +6 -7
  166. package/dist/gui/EFFitScale.js.map +1 -1
  167. package/dist/gui/EFFocusOverlay.d.ts +6 -6
  168. package/dist/gui/EFFocusOverlay.js +3 -4
  169. package/dist/gui/EFFocusOverlay.js.map +1 -1
  170. package/dist/gui/EFOverlayItem.d.ts +4 -4
  171. package/dist/gui/EFOverlayItem.js +3 -4
  172. package/dist/gui/EFOverlayItem.js.map +1 -1
  173. package/dist/gui/EFOverlayLayer.d.ts +4 -5
  174. package/dist/gui/EFOverlayLayer.js +3 -4
  175. package/dist/gui/EFOverlayLayer.js.map +1 -1
  176. package/dist/gui/EFPause.d.ts +4 -4
  177. package/dist/gui/EFPause.js +3 -4
  178. package/dist/gui/EFPause.js.map +1 -1
  179. package/dist/gui/EFPlay.d.ts +4 -4
  180. package/dist/gui/EFPlay.js +3 -4
  181. package/dist/gui/EFPlay.js.map +1 -1
  182. package/dist/gui/EFPreview.d.ts +4 -4
  183. package/dist/gui/EFPreview.js +3 -4
  184. package/dist/gui/EFPreview.js.map +1 -1
  185. package/dist/gui/EFResizableBox.d.ts +4 -4
  186. package/dist/gui/EFResizableBox.js +3 -4
  187. package/dist/gui/EFResizableBox.js.map +1 -1
  188. package/dist/gui/EFScrubber.d.ts +4 -4
  189. package/dist/gui/EFScrubber.js +3 -4
  190. package/dist/gui/EFScrubber.js.map +1 -1
  191. package/dist/gui/EFTimeDisplay.d.ts +4 -4
  192. package/dist/gui/EFTimeDisplay.js +3 -4
  193. package/dist/gui/EFTimeDisplay.js.map +1 -1
  194. package/dist/gui/EFTimelineRuler.d.ts +4 -4
  195. package/dist/gui/EFTimelineRuler.js +5 -6
  196. package/dist/gui/EFTimelineRuler.js.map +1 -1
  197. package/dist/gui/EFToggleLoop.d.ts +4 -4
  198. package/dist/gui/EFToggleLoop.js +3 -4
  199. package/dist/gui/EFToggleLoop.js.map +1 -1
  200. package/dist/gui/EFTogglePlay.d.ts +4 -4
  201. package/dist/gui/EFTogglePlay.js +3 -4
  202. package/dist/gui/EFTogglePlay.js.map +1 -1
  203. package/dist/gui/EFTransformHandles.d.ts +4 -4
  204. package/dist/gui/EFTransformHandles.js +3 -4
  205. package/dist/gui/EFTransformHandles.js.map +1 -1
  206. package/dist/gui/EFWorkbench.d.ts +6 -7
  207. package/dist/gui/EFWorkbench.js +13 -15
  208. package/dist/gui/EFWorkbench.js.map +1 -1
  209. package/dist/gui/EFWorkbench.spacebar.js +1 -1
  210. package/dist/gui/EFWorkbench.spacebar.js.map +1 -1
  211. package/dist/gui/FitScaleHelpers.js +1 -2
  212. package/dist/gui/FitScaleHelpers.js.map +1 -1
  213. package/dist/gui/PlaybackController.js +3 -4
  214. package/dist/gui/PlaybackController.js.map +1 -1
  215. package/dist/gui/TWMixin.js +1 -1
  216. package/dist/gui/TWMixin.js.map +1 -1
  217. package/dist/gui/TWMixin2.js +1 -2
  218. package/dist/gui/TWMixin2.js.map +1 -1
  219. package/dist/gui/TargetOrContextMixin.js +2 -3
  220. package/dist/gui/TargetOrContextMixin.js.map +1 -1
  221. package/dist/gui/currentTimeContext.js +1 -2
  222. package/dist/gui/currentTimeContext.js.map +1 -1
  223. package/dist/gui/durationContext.js +1 -2
  224. package/dist/gui/durationContext.js.map +1 -1
  225. package/dist/gui/efContext.js +1 -2
  226. package/dist/gui/efContext.js.map +1 -1
  227. package/dist/gui/fetchContext.js +1 -2
  228. package/dist/gui/fetchContext.js.map +1 -1
  229. package/dist/gui/focusContext.js +1 -2
  230. package/dist/gui/focusContext.js.map +1 -1
  231. package/dist/gui/focusedElementContext.js +1 -2
  232. package/dist/gui/focusedElementContext.js.map +1 -1
  233. package/dist/gui/hierarchy/EFHierarchy.d.ts +4 -4
  234. package/dist/gui/hierarchy/EFHierarchy.js +3 -4
  235. package/dist/gui/hierarchy/EFHierarchy.js.map +1 -1
  236. package/dist/gui/hierarchy/EFHierarchyItem.d.ts +2 -2
  237. package/dist/gui/hierarchy/EFHierarchyItem.js +13 -14
  238. package/dist/gui/hierarchy/EFHierarchyItem.js.map +1 -1
  239. package/dist/gui/hierarchy/hierarchyContext.js +1 -2
  240. package/dist/gui/hierarchy/hierarchyContext.js.map +1 -1
  241. package/dist/gui/icons.js +1 -2
  242. package/dist/gui/icons.js.map +1 -1
  243. package/dist/gui/panZoomTransformContext.js +1 -2
  244. package/dist/gui/panZoomTransformContext.js.map +1 -1
  245. package/dist/gui/playingContext.js +1 -2
  246. package/dist/gui/playingContext.js.map +1 -1
  247. package/dist/gui/previewSettingsContext.d.ts +0 -1
  248. package/dist/gui/previewSettingsContext.js +1 -2
  249. package/dist/gui/previewSettingsContext.js.map +1 -1
  250. package/dist/gui/shouldSignUrl.js +1 -1
  251. package/dist/gui/shouldSignUrl.js.map +1 -1
  252. package/dist/gui/theme.js +1 -1
  253. package/dist/gui/theme.js.map +1 -1
  254. package/dist/gui/timeline/EFTimeline.d.ts +2 -5
  255. package/dist/gui/timeline/EFTimeline.js +19 -20
  256. package/dist/gui/timeline/EFTimeline.js.map +1 -1
  257. package/dist/gui/timeline/EFTimelineRow.d.ts +2 -2
  258. package/dist/gui/timeline/EFTimelineRow.js +3 -4
  259. package/dist/gui/timeline/EFTimelineRow.js.map +1 -1
  260. package/dist/gui/timeline/TrimHandles.d.ts +4 -4
  261. package/dist/gui/timeline/TrimHandles.js +3 -4
  262. package/dist/gui/timeline/TrimHandles.js.map +1 -1
  263. package/dist/gui/timeline/flattenHierarchy.js +1 -2
  264. package/dist/gui/timeline/flattenHierarchy.js.map +1 -1
  265. package/dist/gui/timeline/timelineEditingContext.js +1 -2
  266. package/dist/gui/timeline/timelineEditingContext.js.map +1 -1
  267. package/dist/gui/timeline/timelineStateContext.js +1 -14
  268. package/dist/gui/timeline/timelineStateContext.js.map +1 -1
  269. package/dist/gui/timeline/tracks/AudioTrack.d.ts +0 -1
  270. package/dist/gui/timeline/tracks/AudioTrack.js +3 -4
  271. package/dist/gui/timeline/tracks/AudioTrack.js.map +1 -1
  272. package/dist/gui/timeline/tracks/CaptionsTrack.d.ts +2 -2
  273. package/dist/gui/timeline/tracks/CaptionsTrack.js +9 -9
  274. package/dist/gui/timeline/tracks/CaptionsTrack.js.map +1 -1
  275. package/dist/gui/timeline/tracks/EFThumbnailStrip.d.ts +4 -4
  276. package/dist/gui/timeline/tracks/EFThumbnailStrip.js +3 -4
  277. package/dist/gui/timeline/tracks/EFThumbnailStrip.js.map +1 -1
  278. package/dist/gui/timeline/tracks/HTMLTrack.d.ts +2 -2
  279. package/dist/gui/timeline/tracks/HTMLTrack.js +3 -4
  280. package/dist/gui/timeline/tracks/HTMLTrack.js.map +1 -1
  281. package/dist/gui/timeline/tracks/ImageTrack.d.ts +2 -2
  282. package/dist/gui/timeline/tracks/ImageTrack.js +3 -4
  283. package/dist/gui/timeline/tracks/ImageTrack.js.map +1 -1
  284. package/dist/gui/timeline/tracks/TextTrack.d.ts +2 -2
  285. package/dist/gui/timeline/tracks/TextTrack.js +4 -5
  286. package/dist/gui/timeline/tracks/TextTrack.js.map +1 -1
  287. package/dist/gui/timeline/tracks/TimegroupTrack.d.ts +5 -6
  288. package/dist/gui/timeline/tracks/TimegroupTrack.js +3 -4
  289. package/dist/gui/timeline/tracks/TimegroupTrack.js.map +1 -1
  290. package/dist/gui/timeline/tracks/TrackItem.d.ts +2 -2
  291. package/dist/gui/timeline/tracks/TrackItem.js +3 -4
  292. package/dist/gui/timeline/tracks/TrackItem.js.map +1 -1
  293. package/dist/gui/timeline/tracks/VideoTrack.d.ts +6 -7
  294. package/dist/gui/timeline/tracks/VideoTrack.js +3 -4
  295. package/dist/gui/timeline/tracks/VideoTrack.js.map +1 -1
  296. package/dist/gui/timeline/tracks/WaveformTrack.js +3 -4
  297. package/dist/gui/timeline/tracks/WaveformTrack.js.map +1 -1
  298. package/dist/gui/timeline/tracks/ensureTrackItemInit.js +1 -1
  299. package/dist/gui/timeline/tracks/preloadTracks.d.ts +1 -9
  300. package/dist/gui/timeline/tracks/renderTrackChildren.js +1 -2
  301. package/dist/gui/timeline/tracks/renderTrackChildren.js.map +1 -1
  302. package/dist/gui/timeline/tracks/waveformUtils.js +3 -6
  303. package/dist/gui/timeline/tracks/waveformUtils.js.map +1 -1
  304. package/dist/gui/transformCalculations.js +1 -2
  305. package/dist/gui/transformCalculations.js.map +1 -1
  306. package/dist/gui/transformUtils.js +1 -1
  307. package/dist/gui/transformUtils.js.map +1 -1
  308. package/dist/gui/tree/EFTree.d.ts +4 -6
  309. package/dist/gui/tree/EFTree.js +3 -4
  310. package/dist/gui/tree/EFTree.js.map +1 -1
  311. package/dist/gui/tree/EFTreeItem.d.ts +4 -5
  312. package/dist/gui/tree/EFTreeItem.js +3 -4
  313. package/dist/gui/tree/EFTreeItem.js.map +1 -1
  314. package/dist/gui/tree/treeContext.d.ts +0 -1
  315. package/dist/gui/tree/treeContext.js +1 -2
  316. package/dist/gui/tree/treeContext.js.map +1 -1
  317. package/dist/index.d.ts +0 -2
  318. package/dist/index.js +1 -2
  319. package/dist/index.js.map +1 -1
  320. package/dist/node.js +1 -2
  321. package/dist/node_modules/lit-html/development/directives/ref.d.ts +14 -0
  322. package/dist/node_modules/lit-html/development/lit-html.d.ts +46 -0
  323. package/dist/otel/BridgeSpanExporter.js +1 -2
  324. package/dist/otel/BridgeSpanExporter.js.map +1 -1
  325. package/dist/otel/setupBrowserTracing.js +1 -2
  326. package/dist/otel/setupBrowserTracing.js.map +1 -1
  327. package/dist/otel/tracingHelpers.d.ts +0 -2
  328. package/dist/otel/tracingHelpers.js +1 -2
  329. package/dist/otel/tracingHelpers.js.map +1 -1
  330. package/dist/preview/AdaptiveResolutionTracker.js +11 -2
  331. package/dist/preview/AdaptiveResolutionTracker.js.map +1 -1
  332. package/dist/preview/FrameController.d.ts +0 -1
  333. package/dist/preview/FrameController.js +2 -32
  334. package/dist/preview/FrameController.js.map +1 -1
  335. package/dist/preview/QualityUpgradeScheduler.js +1 -1
  336. package/dist/preview/QualityUpgradeScheduler.js.map +1 -1
  337. package/dist/preview/RenderContext.d.ts +0 -1
  338. package/dist/preview/RenderContext.js +11 -2
  339. package/dist/preview/RenderContext.js.map +1 -1
  340. package/dist/preview/RenderProfiler.js +1 -1
  341. package/dist/preview/RenderProfiler.js.map +1 -1
  342. package/dist/preview/RenderStats.js +1 -1
  343. package/dist/preview/RenderStats.js.map +1 -1
  344. package/dist/preview/encoding/canvasEncoder.js +7 -2
  345. package/dist/preview/encoding/canvasEncoder.js.map +1 -1
  346. package/dist/preview/encoding/mainThreadEncoder.js +1 -1
  347. package/dist/preview/encoding/mainThreadEncoder.js.map +1 -1
  348. package/dist/preview/encoding/workerEncoder.js +1 -1
  349. package/dist/preview/encoding/workerEncoder.js.map +1 -1
  350. package/dist/preview/logger.js +1 -1
  351. package/dist/preview/logger.js.map +1 -1
  352. package/dist/preview/previewSettings.js +1 -1
  353. package/dist/preview/previewSettings.js.map +1 -1
  354. package/dist/preview/previewTypes.js +1 -1
  355. package/dist/preview/previewTypes.js.map +1 -1
  356. package/dist/preview/renderElementToCanvas.d.ts +0 -1
  357. package/dist/preview/renderElementToCanvas.js +12 -5
  358. package/dist/preview/renderElementToCanvas.js.map +1 -1
  359. package/dist/preview/renderTimegroupToCanvas.d.ts +0 -1
  360. package/dist/preview/renderTimegroupToCanvas.js +6 -7
  361. package/dist/preview/renderTimegroupToCanvas.js.map +1 -1
  362. package/dist/preview/renderTimegroupToVideo.d.ts +0 -1
  363. package/dist/preview/renderTimegroupToVideo.js +20 -8
  364. package/dist/preview/renderTimegroupToVideo.js.map +1 -1
  365. package/dist/preview/renderVideoToVideo.js +11 -2
  366. package/dist/preview/renderVideoToVideo.js.map +1 -1
  367. package/dist/preview/renderers.d.ts +0 -1
  368. package/dist/preview/renderers.js +5 -2
  369. package/dist/preview/renderers.js.map +1 -1
  370. package/dist/preview/rendering/ScaleConfig.js +2 -3
  371. package/dist/preview/rendering/ScaleConfig.js.map +1 -1
  372. package/dist/preview/rendering/inlineImages.d.ts +0 -1
  373. package/dist/preview/rendering/inlineImages.js +1 -1
  374. package/dist/preview/rendering/inlineImages.js.map +1 -1
  375. package/dist/preview/rendering/loadImage.js +1 -2
  376. package/dist/preview/rendering/loadImage.js.map +1 -1
  377. package/dist/preview/rendering/renderToImageNative.js +4 -5
  378. package/dist/preview/rendering/renderToImageNative.js.map +1 -1
  379. package/dist/preview/rendering/serializeTimelineDirect.js +16 -4
  380. package/dist/preview/rendering/serializeTimelineDirect.js.map +1 -1
  381. package/dist/preview/statsTrackingStrategy.js +1 -1
  382. package/dist/preview/statsTrackingStrategy.js.map +1 -1
  383. package/dist/preview/workers/WorkerPool.js +5 -2
  384. package/dist/preview/workers/WorkerPool.js.map +1 -1
  385. package/dist/preview/workers/encoderWorkerInline.js +1 -1
  386. package/dist/preview/workers/encoderWorkerInline.js.map +1 -1
  387. package/dist/render/EFRenderAPI.d.ts +0 -1
  388. package/dist/render/EFRenderAPI.js +1 -2
  389. package/dist/render/EFRenderAPI.js.map +1 -1
  390. package/dist/render/getRenderData.js +1 -1
  391. package/dist/render/getRenderData.js.map +1 -1
  392. package/dist/transcoding/cache/RequestDeduplicator.js +1 -1
  393. package/dist/transcoding/cache/RequestDeduplicator.js.map +1 -1
  394. package/dist/transcoding/cache/URLTokenDeduplicator.js +1 -1
  395. package/dist/transcoding/cache/URLTokenDeduplicator.js.map +1 -1
  396. package/dist/transcoding/types/index.d.ts +0 -1
  397. package/dist/transcoding/utils/UrlGenerator.js +1 -1
  398. package/dist/transcoding/utils/UrlGenerator.js.map +1 -1
  399. package/dist/utils/LRUCache.js +1 -1
  400. package/dist/utils/LRUCache.js.map +1 -1
  401. package/dist/utils/frameTime.js +2 -9
  402. package/dist/utils/frameTime.js.map +1 -1
  403. package/dist/version.js +2 -2
  404. package/dist/version.js.map +1 -1
  405. package/package.json +5 -4
@@ -1 +1 @@
1
- {"version":3,"file":"mainThreadEncoder.js","names":["dataUrl: string"],"sources":["../../../src/preview/encoding/mainThreadEncoder.ts"],"sourcesContent":["/**\n * Main thread canvas encoding (fallback implementation).\n */\n\n// JPEG quality constants\nexport const JPEG_QUALITY_HIGH = 0.92;\nexport const JPEG_QUALITY_MEDIUM = 0.85;\n\n/**\n * Encode a single canvas to a data URL on the main thread (fallback).\n * @param canvas - The canvas to encode\n * @param canvasScale - Scale factor for encoding (default: 1)\n * @returns Encoded result or null if encoding fails\n */\nexport function encodeCanvasOnMainThread(\n canvas: HTMLCanvasElement,\n canvasScale: number,\n): { dataUrl: string; preserveAlpha: boolean } | null {\n try {\n if (canvas.width === 0 || canvas.height === 0) {\n return null;\n }\n\n const preserveAlpha = canvas.dataset.preserveAlpha === \"true\";\n let dataUrl: string;\n\n if (canvasScale < 1) {\n // Scale down canvas before encoding\n const scaledWidth = Math.floor(canvas.width * canvasScale);\n const scaledHeight = Math.floor(canvas.height * canvasScale);\n const scaledCanvas = document.createElement(\"canvas\");\n scaledCanvas.width = scaledWidth;\n scaledCanvas.height = scaledHeight;\n const scaledCtx = scaledCanvas.getContext(\"2d\");\n if (scaledCtx) {\n scaledCtx.drawImage(canvas, 0, 0, scaledWidth, scaledHeight);\n const quality = canvasScale < 0.5 ? JPEG_QUALITY_MEDIUM : JPEG_QUALITY_HIGH;\n dataUrl = preserveAlpha\n ? scaledCanvas.toDataURL(\"image/png\")\n : scaledCanvas.toDataURL(\"image/jpeg\", quality);\n } else {\n dataUrl = preserveAlpha\n ? canvas.toDataURL(\"image/png\")\n : canvas.toDataURL(\"image/jpeg\", JPEG_QUALITY_HIGH);\n }\n } else {\n dataUrl = preserveAlpha\n ? canvas.toDataURL(\"image/png\")\n : canvas.toDataURL(\"image/jpeg\", JPEG_QUALITY_HIGH);\n }\n\n return { dataUrl, preserveAlpha };\n } catch (_e) {\n // Cross-origin canvas or other error - skip\n return null;\n }\n}\n"],"mappings":";;;;AAKA,MAAa,oBAAoB;AACjC,MAAa,sBAAsB;;;;;;;AAQnC,SAAgB,yBACd,QACA,aACoD;AACpD,KAAI;AACF,MAAI,OAAO,UAAU,KAAK,OAAO,WAAW,EAC1C,QAAO;EAGT,MAAM,gBAAgB,OAAO,QAAQ,kBAAkB;EACvD,IAAIA;AAEJ,MAAI,cAAc,GAAG;GAEnB,MAAM,cAAc,KAAK,MAAM,OAAO,QAAQ,YAAY;GAC1D,MAAM,eAAe,KAAK,MAAM,OAAO,SAAS,YAAY;GAC5D,MAAM,eAAe,SAAS,cAAc,SAAS;AACrD,gBAAa,QAAQ;AACrB,gBAAa,SAAS;GACtB,MAAM,YAAY,aAAa,WAAW,KAAK;AAC/C,OAAI,WAAW;AACb,cAAU,UAAU,QAAQ,GAAG,GAAG,aAAa,aAAa;IAC5D,MAAM,UAAU,cAAc,KAAM,sBAAsB;AAC1D,cAAU,gBACN,aAAa,UAAU,YAAY,GACnC,aAAa,UAAU,cAAc,QAAQ;SAEjD,WAAU,gBACN,OAAO,UAAU,YAAY,GAC7B,OAAO,UAAU,cAAc,kBAAkB;QAGvD,WAAU,gBACN,OAAO,UAAU,YAAY,GAC7B,OAAO,UAAU,cAAc,kBAAkB;AAGvD,SAAO;GAAE;GAAS;GAAe;UAC1B,IAAI;AAEX,SAAO"}
1
+ {"version":3,"file":"mainThreadEncoder.js","names":[],"sources":["../../../src/preview/encoding/mainThreadEncoder.ts"],"mappings":";;;;AAKA,MAAa,oBAAoB;AACjC,MAAa,sBAAsB;;;;;;;AAQnC,SAAgB,yBACd,QACA,aACoD;AACpD,KAAI;AACF,MAAI,OAAO,UAAU,KAAK,OAAO,WAAW,EAC1C,QAAO;EAGT,MAAM,gBAAgB,OAAO,QAAQ,kBAAkB;EACvD,IAAI;AAEJ,MAAI,cAAc,GAAG;GAEnB,MAAM,cAAc,KAAK,MAAM,OAAO,QAAQ,YAAY;GAC1D,MAAM,eAAe,KAAK,MAAM,OAAO,SAAS,YAAY;GAC5D,MAAM,eAAe,SAAS,cAAc,SAAS;AACrD,gBAAa,QAAQ;AACrB,gBAAa,SAAS;GACtB,MAAM,YAAY,aAAa,WAAW,KAAK;AAC/C,OAAI,WAAW;AACb,cAAU,UAAU,QAAQ,GAAG,GAAG,aAAa,aAAa;IAC5D,MAAM,UAAU,cAAc,KAAM,sBAAsB;AAC1D,cAAU,gBACN,aAAa,UAAU,YAAY,GACnC,aAAa,UAAU,cAAc,QAAQ;SAEjD,WAAU,gBACN,OAAO,UAAU,YAAY,GAC7B,OAAO,UAAU,cAAc,kBAAkB;QAGvD,WAAU,gBACN,OAAO,UAAU,YAAY,GAC7B,OAAO,UAAU,cAAc,kBAAkB;AAGvD,SAAO;GAAE;GAAS;GAAe;UAC1B,IAAI;AAEX,SAAO"}
@@ -52,7 +52,7 @@ async function encodeCanvasInWorker(worker, canvas, preserveAlpha) {
52
52
  });
53
53
  });
54
54
  }
55
-
56
55
  //#endregion
57
56
  export { encodeCanvasInWorker };
57
+
58
58
  //# sourceMappingURL=workerEncoder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workerEncoder.js","names":["timeoutId: number | null"],"sources":["../../../src/preview/encoding/workerEncoder.ts"],"sourcesContent":["/**\n * Worker-based canvas encoding.\n */\n\nconst WORKER_TASK_TIMEOUT_MS = 30000;\n\n/**\n * Encode a canvas using a worker.\n * @param worker - The worker to use for encoding\n * @param canvas - The canvas to encode\n * @param preserveAlpha - Whether to preserve alpha channel (PNG vs JPEG)\n * @returns Promise resolving to the encoded data URL\n */\nexport async function encodeCanvasInWorker(\n worker: Worker,\n canvas: HTMLCanvasElement,\n preserveAlpha: boolean,\n): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n const taskId = `task-${Date.now()}-${Math.random()}-${performance.now()}`;\n let timeoutId: number | null = null;\n\n const cleanup = () => {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n worker.removeEventListener(\"message\", messageHandler);\n worker.removeEventListener(\"messageerror\", messageErrorHandler);\n };\n\n const messageHandler = (event: MessageEvent) => {\n const result = event.data as {\n taskId: string;\n dataUrl: string;\n error?: string;\n };\n if (result.taskId === taskId) {\n cleanup();\n if (result.error) {\n reject(new Error(`Worker encoding failed: ${result.error}`));\n } else {\n resolve(result.dataUrl);\n }\n }\n };\n\n const messageErrorHandler = () => {\n cleanup();\n reject(new Error(\"Worker message error\"));\n };\n\n worker.addEventListener(\"message\", messageHandler);\n worker.addEventListener(\"messageerror\", messageErrorHandler);\n\n // Set timeout to detect if worker never responds\n timeoutId = window.setTimeout(() => {\n cleanup();\n reject(new Error(\"Worker task timed out\"));\n }, WORKER_TASK_TIMEOUT_MS);\n\n // Create ImageBitmap from canvas\n createImageBitmap(canvas)\n .then((bitmap) => {\n // Transfer bitmap to worker (zero-copy)\n worker.postMessage(\n {\n taskId,\n bitmap,\n preserveAlpha,\n },\n [bitmap],\n );\n })\n .catch((error) => {\n cleanup();\n reject(error instanceof Error ? error : new Error(String(error)));\n });\n });\n}\n"],"mappings":";;;;AAIA,MAAM,yBAAyB;;;;;;;;AAS/B,eAAsB,qBACpB,QACA,QACA,eACiB;AACjB,QAAO,IAAI,SAAiB,SAAS,WAAW;EAC9C,MAAM,SAAS,QAAQ,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,YAAY,KAAK;EACvE,IAAIA,YAA2B;EAE/B,MAAM,gBAAgB;AACpB,OAAI,cAAc,MAAM;AACtB,iBAAa,UAAU;AACvB,gBAAY;;AAEd,UAAO,oBAAoB,WAAW,eAAe;AACrD,UAAO,oBAAoB,gBAAgB,oBAAoB;;EAGjE,MAAM,kBAAkB,UAAwB;GAC9C,MAAM,SAAS,MAAM;AAKrB,OAAI,OAAO,WAAW,QAAQ;AAC5B,aAAS;AACT,QAAI,OAAO,MACT,wBAAO,IAAI,MAAM,2BAA2B,OAAO,QAAQ,CAAC;QAE5D,SAAQ,OAAO,QAAQ;;;EAK7B,MAAM,4BAA4B;AAChC,YAAS;AACT,0BAAO,IAAI,MAAM,uBAAuB,CAAC;;AAG3C,SAAO,iBAAiB,WAAW,eAAe;AAClD,SAAO,iBAAiB,gBAAgB,oBAAoB;AAG5D,cAAY,OAAO,iBAAiB;AAClC,YAAS;AACT,0BAAO,IAAI,MAAM,wBAAwB,CAAC;KACzC,uBAAuB;AAG1B,oBAAkB,OAAO,CACtB,MAAM,WAAW;AAEhB,UAAO,YACL;IACE;IACA;IACA;IACD,EACD,CAAC,OAAO,CACT;IACD,CACD,OAAO,UAAU;AAChB,YAAS;AACT,UAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC,CAAC;IACjE;GACJ"}
1
+ {"version":3,"file":"workerEncoder.js","names":[],"sources":["../../../src/preview/encoding/workerEncoder.ts"],"mappings":";;;;AAIA,MAAM,yBAAyB;;;;;;;;AAS/B,eAAsB,qBACpB,QACA,QACA,eACiB;AACjB,QAAO,IAAI,SAAiB,SAAS,WAAW;EAC9C,MAAM,SAAS,QAAQ,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,YAAY,KAAK;EACvE,IAAI,YAA2B;EAE/B,MAAM,gBAAgB;AACpB,OAAI,cAAc,MAAM;AACtB,iBAAa,UAAU;AACvB,gBAAY;;AAEd,UAAO,oBAAoB,WAAW,eAAe;AACrD,UAAO,oBAAoB,gBAAgB,oBAAoB;;EAGjE,MAAM,kBAAkB,UAAwB;GAC9C,MAAM,SAAS,MAAM;AAKrB,OAAI,OAAO,WAAW,QAAQ;AAC5B,aAAS;AACT,QAAI,OAAO,MACT,wBAAO,IAAI,MAAM,2BAA2B,OAAO,QAAQ,CAAC;QAE5D,SAAQ,OAAO,QAAQ;;;EAK7B,MAAM,4BAA4B;AAChC,YAAS;AACT,0BAAO,IAAI,MAAM,uBAAuB,CAAC;;AAG3C,SAAO,iBAAiB,WAAW,eAAe;AAClD,SAAO,iBAAiB,gBAAgB,oBAAoB;AAG5D,cAAY,OAAO,iBAAiB;AAClC,YAAS;AACT,0BAAO,IAAI,MAAM,wBAAwB,CAAC;KACzC,uBAAuB;AAG1B,oBAAkB,OAAO,CACtB,MAAM,WAAW;AAEhB,UAAO,YACL;IACE;IACA;IACA;IACD,EACD,CAAC,OAAO,CACT;IACD,CACD,OAAO,UAAU;AAChB,YAAS;AACT,UAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC,CAAC;IACjE;GACJ"}
@@ -35,7 +35,7 @@ const logger = {
35
35
  if (shouldLog("error")) console.error(...args);
36
36
  }
37
37
  };
38
-
39
38
  //#endregion
40
39
  export { logger };
40
+
41
41
  //# sourceMappingURL=logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","names":["LOG_LEVELS: Record<LogLevel, number>"],"sources":["../../src/preview/logger.ts"],"sourcesContent":["/**\n * Centralized logging utility for the preview module.\n *\n * Logging is disabled by default. To enable logging, set:\n * - Environment variable: EF_LOG_LEVEL=debug (or info, warn, error)\n * - Global flag: globalThis.EF_LOG_LEVEL = 'debug'\n *\n * Log levels (in order of verbosity):\n * - debug: All logs including performance metrics\n * - info: Informational messages\n * - warn: Warnings\n * - error: Errors only\n * - silent: No logging (default)\n */\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n silent: 4,\n};\n\nfunction getLogLevel(): LogLevel {\n // Check global flag first\n if (typeof globalThis !== \"undefined\" && \"EF_LOG_LEVEL\" in globalThis) {\n const level = (globalThis as { EF_LOG_LEVEL?: string }).EF_LOG_LEVEL;\n if (level && level in LOG_LEVELS) {\n return level as LogLevel;\n }\n }\n\n // Check environment variable (works in Node.js and some bundlers)\n if (typeof process !== \"undefined\" && process.env?.EF_LOG_LEVEL) {\n const level = process.env.EF_LOG_LEVEL;\n if (level in LOG_LEVELS) {\n return level as LogLevel;\n }\n }\n\n // Default to silent\n return \"silent\";\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n const currentLevel = getLogLevel();\n return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];\n}\n\nexport const logger = {\n debug: (...args: unknown[]): void => {\n if (shouldLog(\"debug\")) {\n console.log(...args);\n }\n },\n\n info: (...args: unknown[]): void => {\n if (shouldLog(\"info\")) {\n console.log(...args);\n }\n },\n\n warn: (...args: unknown[]): void => {\n if (shouldLog(\"warn\")) {\n console.warn(...args);\n }\n },\n\n error: (...args: unknown[]): void => {\n if (shouldLog(\"error\")) {\n console.error(...args);\n }\n },\n};\n"],"mappings":";AAiBA,MAAMA,aAAuC;CAC3C,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACP,QAAQ;CACT;AAED,SAAS,cAAwB;AAE/B,KAAI,OAAO,eAAe,eAAe,kBAAkB,YAAY;EACrE,MAAM,QAAS,WAAyC;AACxD,MAAI,SAAS,SAAS,WACpB,QAAO;;AAKX,KAAI,OAAO,YAAY,eAAe,QAAQ,KAAK,cAAc;EAC/D,MAAM,QAAQ,QAAQ,IAAI;AAC1B,MAAI,SAAS,WACX,QAAO;;AAKX,QAAO;;AAGT,SAAS,UAAU,OAA0B;CAC3C,MAAM,eAAe,aAAa;AAClC,QAAO,WAAW,UAAU,WAAW;;AAGzC,MAAa,SAAS;CACpB,QAAQ,GAAG,SAA0B;AACnC,MAAI,UAAU,QAAQ,CACpB,SAAQ,IAAI,GAAG,KAAK;;CAIxB,OAAO,GAAG,SAA0B;AAClC,MAAI,UAAU,OAAO,CACnB,SAAQ,IAAI,GAAG,KAAK;;CAIxB,OAAO,GAAG,SAA0B;AAClC,MAAI,UAAU,OAAO,CACnB,SAAQ,KAAK,GAAG,KAAK;;CAIzB,QAAQ,GAAG,SAA0B;AACnC,MAAI,UAAU,QAAQ,CACpB,SAAQ,MAAM,GAAG,KAAK;;CAG3B"}
1
+ {"version":3,"file":"logger.js","names":[],"sources":["../../src/preview/logger.ts"],"mappings":";AAiBA,MAAM,aAAuC;CAC3C,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACP,QAAQ;CACT;AAED,SAAS,cAAwB;AAE/B,KAAI,OAAO,eAAe,eAAe,kBAAkB,YAAY;EACrE,MAAM,QAAS,WAAyC;AACxD,MAAI,SAAS,SAAS,WACpB,QAAO;;AAKX,KAAI,OAAO,YAAY,eAAe,QAAQ,KAAK,cAAc;EAC/D,MAAM,QAAQ,QAAQ,IAAI;AAC1B,MAAI,SAAS,WACX,QAAO;;AAKX,QAAO;;AAGT,SAAS,UAAU,OAA0B;CAC3C,MAAM,eAAe,aAAa;AAClC,QAAO,WAAW,UAAU,WAAW;;AAGzC,MAAa,SAAS;CACpB,QAAQ,GAAG,SAA0B;AACnC,MAAI,UAAU,QAAQ,CACpB,SAAQ,IAAI,GAAG,KAAK;;CAIxB,OAAO,GAAG,SAA0B;AAClC,MAAI,UAAU,OAAO,CACnB,SAAQ,IAAI,GAAG,KAAK;;CAIxB,OAAO,GAAG,SAA0B;AAClC,MAAI,UAAU,OAAO,CACnB,SAAQ,KAAK,GAAG,KAAK;;CAIzB,QAAQ,GAAG,SAA0B;AACnC,MAAI,UAAU,QAAQ,CACpB,SAAQ,MAAM,GAAG,KAAK;;CAG3B"}
@@ -142,7 +142,7 @@ function setShowThumbnailTimestamps(enabled) {
142
142
  } catch {}
143
143
  window.dispatchEvent(new CustomEvent("ef-preview-settings-changed", { detail: { showThumbnailTimestamps: enabled } }));
144
144
  }
145
-
146
145
  //#endregion
147
146
  export { getPreviewPresentationMode, getPreviewResolutionScale, getRenderMode, getShowStats, getShowThumbnailTimestamps, isNativeCanvasApiAvailable, setPreviewPresentationMode, setRenderMode, setShowStats, setShowThumbnailTimestamps };
147
+
148
148
  //# sourceMappingURL=previewSettings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"previewSettings.js","names":["_nativeApiAvailable: boolean | null","VALID_NUMERIC_SCALES: number[]"],"sources":["../../src/preview/previewSettings.ts"],"sourcesContent":["/**\n * Preview settings module with localStorage persistence.\n * Manages configuration for the preview rendering system.\n */\n\nconst STORAGE_KEY_NATIVE_CANVAS_API = \"ef-preview-native-canvas-api-enabled\";\nconst STORAGE_KEY_PRESENTATION_MODE = \"ef-preview-presentation-mode\";\nconst STORAGE_KEY_RENDER_MODE = \"ef-preview-render-mode\";\nconst STORAGE_KEY_RESOLUTION_SCALE = \"ef-preview-resolution-scale\";\nconst STORAGE_KEY_SHOW_STATS = \"ef-preview-show-stats\";\nconst STORAGE_KEY_SHOW_THUMBNAIL_TIMESTAMPS = \"ef-preview-show-thumbnail-timestamps\";\n\n/**\n * Render mode for HTML-to-canvas capture operations.\n * - \"foreignObject\": SVG foreignObject serialization (fallback, works everywhere)\n * - \"native\": Chrome's experimental drawElementImage API (fastest when available)\n */\nexport type RenderMode = \"foreignObject\" | \"native\";\n\n/**\n * Preview resolution scale factor.\n * Controls how much to reduce the preview render resolution for better performance.\n * - 1: Full resolution (default)\n * - 0.75: 3/4 resolution\n * - 0.5: Half resolution\n * - 0.25: Quarter resolution\n * - \"auto\": Adaptive resolution that scales down during motion to prevent dropped frames,\n * and renders at full resolution when at rest\n */\nexport type PreviewResolutionScale = 1 | 0.75 | 0.5 | 0.25 | \"auto\";\n\n/**\n * Preview presentation mode determines how content is rendered in the workbench.\n * - \"clone\": Show a clone with computed styles applied (alias for \"computed\")\n * - \"dom\": Show the original DOM content directly (alias for \"original\")\n * - \"original\": Show the original DOM content directly\n * - \"computed\": Show a clone with computed styles applied\n * - \"canvas\": Render to canvas using the active rendering path\n */\nexport type PreviewPresentationMode = \"dom\" | \"canvas\";\n\n/**\n * Cached detection result for native HTML-in-Canvas API availability.\n * This is separate from the user preference - it detects browser capability.\n */\nlet _nativeApiAvailable: boolean | null = null;\n\n/**\n * Detect if the native HTML-in-Canvas API (drawElementImage) is available in this browser.\n * This checks browser capability, not user preference.\n *\n * The API is available in Chrome Canary with chrome://flags/#canvas-draw-element\n * @see https://github.com/WICG/html-in-canvas\n */\nexport function isNativeCanvasApiAvailable(): boolean {\n if (_nativeApiAvailable === null) {\n const canvas = document.createElement(\"canvas\");\n const ctx = canvas.getContext(\"2d\");\n _nativeApiAvailable = ctx !== null && \"drawElementImage\" in ctx;\n }\n return _nativeApiAvailable;\n}\n\n/**\n * Check if the native Canvas API is enabled by the user.\n * Returns true only if:\n * 1. The API is available in the browser\n * 2. The user has not explicitly disabled it\n *\n * Default is enabled when available (opt-out model).\n */\nexport function isNativeCanvasApiEnabled(): boolean {\n if (!isNativeCanvasApiAvailable()) {\n return false;\n }\n\n try {\n const stored = localStorage.getItem(STORAGE_KEY_NATIVE_CANVAS_API);\n // Default to true (enabled) when available, unless explicitly disabled\n if (stored === null) {\n return true;\n }\n return stored === \"true\";\n } catch {\n // localStorage not available (e.g., private browsing)\n return true;\n }\n}\n\n/**\n * Set whether the native Canvas API should be used (when available).\n * Persists to localStorage and dispatches a change event.\n */\nexport function setNativeCanvasApiEnabled(enabled: boolean): void {\n try {\n localStorage.setItem(STORAGE_KEY_NATIVE_CANVAS_API, String(enabled));\n } catch {\n // localStorage not available\n }\n\n // Dispatch event so components can react to the change\n window.dispatchEvent(\n new CustomEvent(\"ef-preview-settings-changed\", {\n detail: { nativeCanvasApiEnabled: enabled },\n }),\n );\n}\n\n/**\n * Get the current raw user preference (ignoring availability).\n * Returns null if no preference is set.\n */\nexport function getNativeCanvasApiPreference(): boolean | null {\n try {\n const stored = localStorage.getItem(STORAGE_KEY_NATIVE_CANVAS_API);\n if (stored === null) {\n return null;\n }\n return stored === \"true\";\n } catch {\n return null;\n }\n}\n\n/**\n * Subscribe to preview settings changes.\n * @returns Unsubscribe function\n */\nexport function onPreviewSettingsChanged(\n callback: (detail: PreviewSettingsChangedDetail) => void,\n): () => void {\n const handler = (event: Event) => {\n callback((event as CustomEvent).detail);\n };\n window.addEventListener(\"ef-preview-settings-changed\", handler);\n return () => window.removeEventListener(\"ef-preview-settings-changed\", handler);\n}\n\n/**\n * Detail object for preview settings change events.\n */\nexport interface PreviewSettingsChangedDetail {\n nativeCanvasApiEnabled?: boolean;\n presentationMode?: PreviewPresentationMode;\n renderMode?: RenderMode;\n resolutionScale?: PreviewResolutionScale;\n showStats?: boolean;\n showThumbnailTimestamps?: boolean;\n}\n\n/**\n * Get the current preview presentation mode.\n * Defaults to \"dom\" if not set.\n */\nexport function getPreviewPresentationMode(): PreviewPresentationMode {\n try {\n const stored = localStorage.getItem(STORAGE_KEY_PRESENTATION_MODE);\n if (stored === \"dom\" || stored === \"canvas\") {\n return stored;\n }\n return \"dom\";\n } catch {\n return \"dom\";\n }\n}\n\n/**\n * Set the preview presentation mode.\n * Persists to localStorage and dispatches a change event.\n */\nexport function setPreviewPresentationMode(mode: PreviewPresentationMode): void {\n try {\n localStorage.setItem(STORAGE_KEY_PRESENTATION_MODE, mode);\n } catch {\n // localStorage not available\n }\n\n // Dispatch event so components can react to the change\n window.dispatchEvent(\n new CustomEvent(\"ef-preview-settings-changed\", {\n detail: { presentationMode: mode },\n }),\n );\n}\n\n/**\n * Get the current render mode for HTML-to-canvas capture.\n * Defaults to \"native\" if available, otherwise \"foreignObject\".\n *\n * Checks EF_NATIVE_RENDER URL parameter to force native mode when set.\n */\nexport function getRenderMode(): RenderMode {\n // Check URL parameter first (CLI flag override)\n try {\n const urlParams = new URLSearchParams(window.location.search);\n if (urlParams.get(\"EF_NATIVE_RENDER\") === \"1\") {\n // Force native mode if available, otherwise fall back to foreignObject\n return isNativeCanvasApiAvailable() ? \"native\" : \"foreignObject\";\n }\n } catch {\n // URL parsing failed, continue with normal logic\n }\n\n try {\n const stored = localStorage.getItem(STORAGE_KEY_RENDER_MODE);\n if (stored === \"foreignObject\" || stored === \"native\") {\n return stored;\n }\n // Default: prefer native if available, otherwise foreignObject\n return isNativeCanvasApiAvailable() ? \"native\" : \"foreignObject\";\n } catch {\n return isNativeCanvasApiAvailable() ? \"native\" : \"foreignObject\";\n }\n}\n\n/**\n * Set the render mode for HTML-to-canvas capture.\n * Persists to localStorage and dispatches a change event.\n */\nexport function setRenderMode(mode: RenderMode): void {\n try {\n localStorage.setItem(STORAGE_KEY_RENDER_MODE, mode);\n } catch {\n // localStorage not available\n }\n\n // Dispatch event so components can react to the change\n window.dispatchEvent(\n new CustomEvent(\"ef-preview-settings-changed\", {\n detail: { renderMode: mode },\n }),\n );\n}\n\n/**\n * Valid numeric resolution scale values.\n */\nconst VALID_NUMERIC_SCALES: number[] = [1, 0.75, 0.5, 0.25];\n\n/**\n * Get the current preview resolution scale.\n * Defaults to 1 (full resolution) if not set.\n */\nexport function getPreviewResolutionScale(): PreviewResolutionScale {\n try {\n const stored = localStorage.getItem(STORAGE_KEY_RESOLUTION_SCALE);\n if (stored !== null) {\n // Check for \"auto\" string first\n if (stored === \"auto\") {\n return \"auto\";\n }\n // Then check numeric values\n const parsed = parseFloat(stored);\n if (VALID_NUMERIC_SCALES.includes(parsed)) {\n return parsed as PreviewResolutionScale;\n }\n }\n return 1;\n } catch {\n return 1;\n }\n}\n\n/**\n * Set the preview resolution scale.\n * Persists to localStorage and dispatches a change event.\n */\nexport function setPreviewResolutionScale(scale: PreviewResolutionScale): void {\n try {\n localStorage.setItem(STORAGE_KEY_RESOLUTION_SCALE, String(scale));\n } catch {\n // localStorage not available\n }\n\n // Dispatch event so components can react to the change\n window.dispatchEvent(\n new CustomEvent(\"ef-preview-settings-changed\", {\n detail: { resolutionScale: scale },\n }),\n );\n}\n\n/**\n * Get whether performance stats should be shown.\n * Defaults to false (stats hidden by default).\n */\nexport function getShowStats(): boolean {\n try {\n const stored = localStorage.getItem(STORAGE_KEY_SHOW_STATS);\n return stored === \"true\";\n } catch {\n return false;\n }\n}\n\n/**\n * Set whether performance stats should be shown.\n * Persists to localStorage and dispatches a change event.\n */\nexport function setShowStats(enabled: boolean): void {\n try {\n localStorage.setItem(STORAGE_KEY_SHOW_STATS, String(enabled));\n } catch {\n // localStorage not available\n }\n\n // Dispatch event so components can react to the change\n window.dispatchEvent(\n new CustomEvent(\"ef-preview-settings-changed\", {\n detail: { showStats: enabled },\n }),\n );\n}\n\n/**\n * Get whether thumbnail timestamps should be shown.\n * Defaults to false (timestamps hidden by default).\n */\nexport function getShowThumbnailTimestamps(): boolean {\n try {\n const stored = localStorage.getItem(STORAGE_KEY_SHOW_THUMBNAIL_TIMESTAMPS);\n return stored === \"true\";\n } catch {\n return false;\n }\n}\n\n/**\n * Set whether thumbnail timestamps should be shown.\n * Persists to localStorage and dispatches a change event.\n */\nexport function setShowThumbnailTimestamps(enabled: boolean): void {\n try {\n localStorage.setItem(STORAGE_KEY_SHOW_THUMBNAIL_TIMESTAMPS, String(enabled));\n } catch {\n // localStorage not available\n }\n\n // Dispatch event so components can react to the change\n window.dispatchEvent(\n new CustomEvent(\"ef-preview-settings-changed\", {\n detail: { showThumbnailTimestamps: enabled },\n }),\n );\n}\n"],"mappings":";AAMA,MAAM,gCAAgC;AACtC,MAAM,0BAA0B;AAChC,MAAM,+BAA+B;AACrC,MAAM,yBAAyB;AAC/B,MAAM,wCAAwC;;;;;AAmC9C,IAAIA,sBAAsC;;;;;;;;AAS1C,SAAgB,6BAAsC;AACpD,KAAI,wBAAwB,MAAM;EAEhC,MAAM,MADS,SAAS,cAAc,SAAS,CAC5B,WAAW,KAAK;AACnC,wBAAsB,QAAQ,QAAQ,sBAAsB;;AAE9D,QAAO;;;;;;AA8FT,SAAgB,6BAAsD;AACpE,KAAI;EACF,MAAM,SAAS,aAAa,QAAQ,8BAA8B;AAClE,MAAI,WAAW,SAAS,WAAW,SACjC,QAAO;AAET,SAAO;SACD;AACN,SAAO;;;;;;;AAQX,SAAgB,2BAA2B,MAAqC;AAC9E,KAAI;AACF,eAAa,QAAQ,+BAA+B,KAAK;SACnD;AAKR,QAAO,cACL,IAAI,YAAY,+BAA+B,EAC7C,QAAQ,EAAE,kBAAkB,MAAM,EACnC,CAAC,CACH;;;;;;;;AASH,SAAgB,gBAA4B;AAE1C,KAAI;AAEF,MADkB,IAAI,gBAAgB,OAAO,SAAS,OAAO,CAC/C,IAAI,mBAAmB,KAAK,IAExC,QAAO,4BAA4B,GAAG,WAAW;SAE7C;AAIR,KAAI;EACF,MAAM,SAAS,aAAa,QAAQ,wBAAwB;AAC5D,MAAI,WAAW,mBAAmB,WAAW,SAC3C,QAAO;AAGT,SAAO,4BAA4B,GAAG,WAAW;SAC3C;AACN,SAAO,4BAA4B,GAAG,WAAW;;;;;;;AAQrD,SAAgB,cAAc,MAAwB;AACpD,KAAI;AACF,eAAa,QAAQ,yBAAyB,KAAK;SAC7C;AAKR,QAAO,cACL,IAAI,YAAY,+BAA+B,EAC7C,QAAQ,EAAE,YAAY,MAAM,EAC7B,CAAC,CACH;;;;;AAMH,MAAMC,uBAAiC;CAAC;CAAG;CAAM;CAAK;CAAK;;;;;AAM3D,SAAgB,4BAAoD;AAClE,KAAI;EACF,MAAM,SAAS,aAAa,QAAQ,6BAA6B;AACjE,MAAI,WAAW,MAAM;AAEnB,OAAI,WAAW,OACb,QAAO;GAGT,MAAM,SAAS,WAAW,OAAO;AACjC,OAAI,qBAAqB,SAAS,OAAO,CACvC,QAAO;;AAGX,SAAO;SACD;AACN,SAAO;;;;;;;AA2BX,SAAgB,eAAwB;AACtC,KAAI;AAEF,SADe,aAAa,QAAQ,uBAAuB,KACzC;SACZ;AACN,SAAO;;;;;;;AAQX,SAAgB,aAAa,SAAwB;AACnD,KAAI;AACF,eAAa,QAAQ,wBAAwB,OAAO,QAAQ,CAAC;SACvD;AAKR,QAAO,cACL,IAAI,YAAY,+BAA+B,EAC7C,QAAQ,EAAE,WAAW,SAAS,EAC/B,CAAC,CACH;;;;;;AAOH,SAAgB,6BAAsC;AACpD,KAAI;AAEF,SADe,aAAa,QAAQ,sCAAsC,KACxD;SACZ;AACN,SAAO;;;;;;;AAQX,SAAgB,2BAA2B,SAAwB;AACjE,KAAI;AACF,eAAa,QAAQ,uCAAuC,OAAO,QAAQ,CAAC;SACtE;AAKR,QAAO,cACL,IAAI,YAAY,+BAA+B,EAC7C,QAAQ,EAAE,yBAAyB,SAAS,EAC7C,CAAC,CACH"}
1
+ {"version":3,"file":"previewSettings.js","names":[],"sources":["../../src/preview/previewSettings.ts"],"mappings":";AAMA,MAAM,gCAAgC;AACtC,MAAM,0BAA0B;AAChC,MAAM,+BAA+B;AACrC,MAAM,yBAAyB;AAC/B,MAAM,wCAAwC;;;;;AAmC9C,IAAI,sBAAsC;;;;;;;;AAS1C,SAAgB,6BAAsC;AACpD,KAAI,wBAAwB,MAAM;EAEhC,MAAM,MADS,SAAS,cAAc,SAAS,CAC5B,WAAW,KAAK;AACnC,wBAAsB,QAAQ,QAAQ,sBAAsB;;AAE9D,QAAO;;;;;;AA8FT,SAAgB,6BAAsD;AACpE,KAAI;EACF,MAAM,SAAS,aAAa,QAAQ,8BAA8B;AAClE,MAAI,WAAW,SAAS,WAAW,SACjC,QAAO;AAET,SAAO;SACD;AACN,SAAO;;;;;;;AAQX,SAAgB,2BAA2B,MAAqC;AAC9E,KAAI;AACF,eAAa,QAAQ,+BAA+B,KAAK;SACnD;AAKR,QAAO,cACL,IAAI,YAAY,+BAA+B,EAC7C,QAAQ,EAAE,kBAAkB,MAAM,EACnC,CAAC,CACH;;;;;;;;AASH,SAAgB,gBAA4B;AAE1C,KAAI;AAEF,MADkB,IAAI,gBAAgB,OAAO,SAAS,OAAO,CAC/C,IAAI,mBAAmB,KAAK,IAExC,QAAO,4BAA4B,GAAG,WAAW;SAE7C;AAIR,KAAI;EACF,MAAM,SAAS,aAAa,QAAQ,wBAAwB;AAC5D,MAAI,WAAW,mBAAmB,WAAW,SAC3C,QAAO;AAGT,SAAO,4BAA4B,GAAG,WAAW;SAC3C;AACN,SAAO,4BAA4B,GAAG,WAAW;;;;;;;AAQrD,SAAgB,cAAc,MAAwB;AACpD,KAAI;AACF,eAAa,QAAQ,yBAAyB,KAAK;SAC7C;AAKR,QAAO,cACL,IAAI,YAAY,+BAA+B,EAC7C,QAAQ,EAAE,YAAY,MAAM,EAC7B,CAAC,CACH;;;;;AAMH,MAAM,uBAAiC;CAAC;CAAG;CAAM;CAAK;CAAK;;;;;AAM3D,SAAgB,4BAAoD;AAClE,KAAI;EACF,MAAM,SAAS,aAAa,QAAQ,6BAA6B;AACjE,MAAI,WAAW,MAAM;AAEnB,OAAI,WAAW,OACb,QAAO;GAGT,MAAM,SAAS,WAAW,OAAO;AACjC,OAAI,qBAAqB,SAAS,OAAO,CACvC,QAAO;;AAGX,SAAO;SACD;AACN,SAAO;;;;;;;AA2BX,SAAgB,eAAwB;AACtC,KAAI;AAEF,SADe,aAAa,QAAQ,uBAAuB,KACzC;SACZ;AACN,SAAO;;;;;;;AAQX,SAAgB,aAAa,SAAwB;AACnD,KAAI;AACF,eAAa,QAAQ,wBAAwB,OAAO,QAAQ,CAAC;SACvD;AAKR,QAAO,cACL,IAAI,YAAY,+BAA+B,EAC7C,QAAQ,EAAE,WAAW,SAAS,EAC/B,CAAC,CACH;;;;;;AAOH,SAAgB,6BAAsC;AACpD,KAAI;AAEF,SADe,aAAa,QAAQ,sCAAsC,KACxD;SACZ;AACN,SAAO;;;;;;;AAQX,SAAgB,2BAA2B,SAAwB;AACjE,KAAI;AACF,eAAa,QAAQ,uCAAuC,OAAO,QAAQ,CAAC;SACtE;AAKR,QAAO,cACL,IAAI,YAAY,+BAA+B,EAC7C,QAAQ,EAAE,yBAAyB,SAAS,EAC7C,CAAC,CACH"}
@@ -59,7 +59,7 @@ function createPreviewContainer(options) {
59
59
  `;
60
60
  return container;
61
61
  }
62
-
63
62
  //#endregion
64
63
  export { DEFAULT_BLOCKING_TIMEOUT_MS, DEFAULT_CAPTURE_SCALE, DEFAULT_HEIGHT, DEFAULT_WIDTH, createPreviewContainer, isTemporal, isVisibleAtTime };
64
+
65
65
  //# sourceMappingURL=previewTypes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"previewTypes.js","names":[],"sources":["../../src/preview/previewTypes.ts"],"sourcesContent":["/**\n * Shared types and constants for preview rendering.\n *\n * Consolidates duplicate definitions from renderTimegroupToCanvas.ts and\n * renderTimegroupPreview.ts into a single source of truth.\n */\n\n// ============================================================================\n// Temporal Types\n// ============================================================================\n\n/**\n * Element with temporal properties (startTimeMs, endTimeMs).\n * Used for temporal visibility checks during preview rendering.\n */\nexport interface TemporalElement extends Element {\n startTimeMs?: number;\n endTimeMs?: number;\n src?: string;\n}\n\n/**\n * Type guard to check if an element has temporal properties.\n */\nexport function isTemporal(el: Element): el is TemporalElement {\n return \"startTimeMs\" in el && \"endTimeMs\" in el;\n}\n\n/**\n * Get temporal bounds for an element, treating invalid ranges as unbounded.\n * Invalid range (end <= start) means element hasn't computed its duration yet.\n *\n * NOTE: No caching - bounds are computed dynamically by timegroups based on\n * composition mode (sequence/contain/fit) and may change between frames.\n */\nexport function getTemporalBounds(el: Element): {\n startMs: number;\n endMs: number;\n} {\n // Non-temporal elements are always visible\n if (!isTemporal(el)) {\n return { startMs: -Infinity, endMs: Infinity };\n }\n\n // Compute bounds fresh each time\n const temporal = el as TemporalElement;\n let startMs = temporal.startTimeMs ?? -Infinity;\n let endMs = temporal.endTimeMs ?? Infinity;\n\n // If end <= start, treat as always visible (element hasn't computed duration yet)\n if (endMs <= startMs) {\n startMs = -Infinity;\n endMs = Infinity;\n }\n\n return { startMs, endMs };\n}\n\n/**\n * Check if an element is temporally visible at the given time.\n */\nexport function isVisibleAtTime(element: Element, timeMs: number): boolean {\n const { startMs, endMs } = getTemporalBounds(element);\n return timeMs >= startMs && timeMs <= endMs;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Default timegroup dimensions when not measurable */\nexport const DEFAULT_WIDTH = 1920;\nexport const DEFAULT_HEIGHT = 1080;\n\n/** Default scale for capture operations */\nexport const DEFAULT_CAPTURE_SCALE = 0.25;\n\n/** Default timeout for blocking content readiness mode (ms) */\nexport const DEFAULT_BLOCKING_TIMEOUT_MS = 5000;\n\n// ============================================================================\n// Container Creation\n// ============================================================================\n\n/**\n * Options for creating a preview container.\n */\nexport interface PreviewContainerOptions {\n width: number;\n height: number;\n background?: string;\n position?: \"relative\" | \"absolute\" | \"fixed\";\n}\n\n/**\n * Create a preview container with standard styling.\n * Consolidates the repeated container creation pattern across preview functions.\n */\nexport function createPreviewContainer(options: PreviewContainerOptions): HTMLDivElement {\n const { width, height, background = \"#000\", position = \"relative\" } = options;\n\n const container = document.createElement(\"div\");\n container.style.cssText = `\n width: ${width}px;\n height: ${height}px;\n position: ${position};\n overflow: hidden;\n background: ${background};\n `;\n return container;\n}\n\n// ============================================================================\n// Style Injection\n// ============================================================================\n\n/**\n * Inject document styles into a container for foreignObject rendering.\n * SVG foreignObject needs all CSS rules inlined since it can't access\n * the document's stylesheets.\n */\nexport function injectDocumentStyles(\n container: HTMLElement,\n collectStyles: () => string,\n): HTMLStyleElement {\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = collectStyles();\n container.appendChild(styleEl);\n return styleEl;\n}\n"],"mappings":";;;;AAwBA,SAAgB,WAAW,IAAoC;AAC7D,QAAO,iBAAiB,MAAM,eAAe;;;;;;;;;AAU/C,SAAgB,kBAAkB,IAGhC;AAEA,KAAI,CAAC,WAAW,GAAG,CACjB,QAAO;EAAE,SAAS;EAAW,OAAO;EAAU;CAIhD,MAAM,WAAW;CACjB,IAAI,UAAU,SAAS,eAAe;CACtC,IAAI,QAAQ,SAAS,aAAa;AAGlC,KAAI,SAAS,SAAS;AACpB,YAAU;AACV,UAAQ;;AAGV,QAAO;EAAE;EAAS;EAAO;;;;;AAM3B,SAAgB,gBAAgB,SAAkB,QAAyB;CACzE,MAAM,EAAE,SAAS,UAAU,kBAAkB,QAAQ;AACrD,QAAO,UAAU,WAAW,UAAU;;;AAQxC,MAAa,gBAAgB;AAC7B,MAAa,iBAAiB;;AAG9B,MAAa,wBAAwB;;AAGrC,MAAa,8BAA8B;;;;;AAoB3C,SAAgB,uBAAuB,SAAkD;CACvF,MAAM,EAAE,OAAO,QAAQ,aAAa,QAAQ,WAAW,eAAe;CAEtE,MAAM,YAAY,SAAS,cAAc,MAAM;AAC/C,WAAU,MAAM,UAAU;aACf,MAAM;cACL,OAAO;gBACL,SAAS;;kBAEP,WAAW;;AAE3B,QAAO"}
1
+ {"version":3,"file":"previewTypes.js","names":[],"sources":["../../src/preview/previewTypes.ts"],"mappings":";;;;AAwBA,SAAgB,WAAW,IAAoC;AAC7D,QAAO,iBAAiB,MAAM,eAAe;;;;;;;;;AAU/C,SAAgB,kBAAkB,IAGhC;AAEA,KAAI,CAAC,WAAW,GAAG,CACjB,QAAO;EAAE,SAAS;EAAW,OAAO;EAAU;CAIhD,MAAM,WAAW;CACjB,IAAI,UAAU,SAAS,eAAe;CACtC,IAAI,QAAQ,SAAS,aAAa;AAGlC,KAAI,SAAS,SAAS;AACpB,YAAU;AACV,UAAQ;;AAGV,QAAO;EAAE;EAAS;EAAO;;;;;AAM3B,SAAgB,gBAAgB,SAAkB,QAAyB;CACzE,MAAM,EAAE,SAAS,UAAU,kBAAkB,QAAQ;AACrD,QAAO,UAAU,WAAW,UAAU;;;AAQxC,MAAa,gBAAgB;AAC7B,MAAa,iBAAiB;;AAG9B,MAAa,wBAAwB;;AAGrC,MAAa,8BAA8B;;;;;AAoB3C,SAAgB,uBAAuB,SAAkD;CACvF,MAAM,EAAE,OAAO,QAAQ,aAAa,QAAQ,WAAW,eAAe;CAEtE,MAAM,YAAY,SAAS,cAAc,MAAM;AAC/C,WAAU,MAAM,UAAU;aACf,MAAM;cACL,OAAO;gBACL,SAAS;;kBAEP,WAAW;;AAE3B,QAAO"}
@@ -2,7 +2,6 @@ import { RenderMode } from "./previewSettings.js";
2
2
  import { RenderContext } from "./RenderContext.js";
3
3
 
4
4
  //#region src/preview/renderElementToCanvas.d.ts
5
-
6
5
  /**
7
6
  * Options for rendering an element to canvas.
8
7
  */
@@ -1,12 +1,19 @@
1
1
  import { RenderContext } from "./RenderContext.js";
2
- import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from "./previewTypes.js";
2
+ import "./previewTypes.js";
3
3
  import { captureTimelineToDataUri } from "./rendering/serializeTimelineDirect.js";
4
4
  import { getEffectiveRenderMode } from "./renderers.js";
5
5
  import { loadImageFromDataUri } from "./rendering/loadImage.js";
6
6
  import { renderToImageNative } from "./rendering/renderToImageNative.js";
7
-
8
7
  //#region src/preview/renderElementToCanvas.ts
9
8
  /**
9
+ * Render any DOM element to canvas.
10
+ *
11
+ * Low-level rendering function that renders elements as-is.
12
+ * Supports both native (drawElementImage) and foreignObject render modes.
13
+ *
14
+ * Caller is responsible for clone management and seeking.
15
+ */
16
+ /**
10
17
  * Render any element to canvas or image.
11
18
  *
12
19
  * This is a low-level rendering function that renders the element as-is.
@@ -34,8 +41,8 @@ async function renderElementToCanvas(element, options) {
34
41
  async function renderElementToImage(element, options) {
35
42
  const { timeMs, scale = 1 } = options;
36
43
  const computedStyle = getComputedStyle(element);
37
- const width = options.width ?? (parseFloat(computedStyle.width) || DEFAULT_WIDTH);
38
- const height = options.height ?? (parseFloat(computedStyle.height) || DEFAULT_HEIGHT);
44
+ const width = options.width ?? (parseFloat(computedStyle.width) || 1920);
45
+ const height = options.height ?? (parseFloat(computedStyle.height) || 1080);
39
46
  const renderContext = options.renderContext ?? new RenderContext();
40
47
  const shouldDisposeContext = !options.renderContext;
41
48
  try {
@@ -66,7 +73,7 @@ async function renderElementToImage(element, options) {
66
73
  if (shouldDisposeContext) renderContext.dispose();
67
74
  }
68
75
  }
69
-
70
76
  //#endregion
71
77
  export { renderElementToCanvas };
78
+
72
79
  //# sourceMappingURL=renderElementToCanvas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderElementToCanvas.js","names":[],"sources":["../../src/preview/renderElementToCanvas.ts"],"sourcesContent":["/**\n * Render any DOM element to canvas.\n *\n * Low-level rendering function that renders elements as-is.\n * Supports both native (drawElementImage) and foreignObject render modes.\n *\n * Caller is responsible for clone management and seeking.\n */\n\nimport { getEffectiveRenderMode } from \"./renderers.js\";\nimport type { RenderMode } from \"./previewSettings.js\";\nimport { RenderContext } from \"./RenderContext.js\";\nimport { captureTimelineToDataUri } from \"./rendering/serializeTimelineDirect.js\";\nimport { loadImageFromDataUri } from \"./rendering/loadImage.js\";\nimport { renderToImageNative } from \"./rendering/renderToImageNative.js\";\nimport { DEFAULT_WIDTH, DEFAULT_HEIGHT } from \"./previewTypes.js\";\n\n/**\n * Options for rendering an element to canvas.\n */\nexport interface RenderElementOptions {\n /** Time to render at in milliseconds (used for serialization metadata) */\n timeMs: number;\n /** Scale factor for canvas encoding (default: 1.0) */\n scale?: number;\n /** Output width in pixels (defaults to element's computed width or 1920) */\n width?: number;\n /** Output height in pixels (defaults to element's computed height or 1080) */\n height?: number;\n /** Render context for canvas pixel caching */\n renderContext?: RenderContext;\n /** Override render mode (native or foreignObject) */\n renderMode?: RenderMode;\n}\n\n/**\n * Render any element to canvas or image.\n *\n * This is a low-level rendering function that renders the element as-is.\n * The caller is responsible for:\n * - Creating clones if needed\n * - Seeking to the correct time\n * - Finding the correct element to render\n *\n * Use cases:\n * - Preview: Pass prime timeline element (already at correct time)\n * - Video/thumbnails: Pass element from reused clone (already seeked)\n * - One-off capture: Create clone, seek, pass element, clean up\n *\n * @param element - Element to render (timegroup, temporal element, or plain DOM)\n * @param options - Render options\n * @returns Canvas or Image (both are CanvasImageSource)\n */\nexport async function renderElementToCanvas(\n element: Element,\n options: RenderElementOptions,\n): Promise<CanvasImageSource> {\n return await renderElementToImage(element, options);\n}\n\n/**\n * Render an element using either native or foreignObject mode.\n * Returns Canvas or Image directly without unnecessary copying.\n */\nasync function renderElementToImage(\n element: Element,\n options: RenderElementOptions,\n): Promise<CanvasImageSource> {\n const { timeMs, scale = 1.0 } = options;\n\n // Get element dimensions\n const computedStyle = getComputedStyle(element);\n const width = options.width ?? (parseFloat(computedStyle.width) || DEFAULT_WIDTH);\n const height = options.height ?? (parseFloat(computedStyle.height) || DEFAULT_HEIGHT);\n\n // Create render context for caching\n const renderContext = options.renderContext ?? new RenderContext();\n const shouldDisposeContext = !options.renderContext;\n\n try {\n // Determine render mode\n const renderMode = options.renderMode ?? getEffectiveRenderMode();\n\n if (renderMode === \"native\") {\n // NATIVE PATH: Render element using drawElementImage\n const elementContainer = document.createElement(\"div\");\n elementContainer.style.cssText = `\n position: fixed;\n left: 0;\n top: 0;\n width: ${width}px;\n height: ${height}px;\n pointer-events: none;\n overflow: hidden;\n `;\n\n // Clone element into container\n elementContainer.appendChild(element.cloneNode(true));\n document.body.appendChild(elementContainer);\n\n try {\n // Return canvas directly - no copy needed!\n return await renderToImageNative(elementContainer, width, height, {\n skipDprScaling: true,\n });\n } finally {\n elementContainer.remove();\n }\n } else {\n // FOREIGNOBJECT PATH: Direct serialization\n const dataUri = await captureTimelineToDataUri(element, width, height, {\n renderContext,\n canvasScale: scale,\n timeMs,\n });\n\n // Return image directly - no copy needed!\n return await loadImageFromDataUri(dataUri);\n }\n } finally {\n if (shouldDisposeContext) {\n renderContext.dispose();\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,eAAsB,sBACpB,SACA,SAC4B;AAC5B,QAAO,MAAM,qBAAqB,SAAS,QAAQ;;;;;;AAOrD,eAAe,qBACb,SACA,SAC4B;CAC5B,MAAM,EAAE,QAAQ,QAAQ,MAAQ;CAGhC,MAAM,gBAAgB,iBAAiB,QAAQ;CAC/C,MAAM,QAAQ,QAAQ,UAAU,WAAW,cAAc,MAAM,IAAI;CACnE,MAAM,SAAS,QAAQ,WAAW,WAAW,cAAc,OAAO,IAAI;CAGtE,MAAM,gBAAgB,QAAQ,iBAAiB,IAAI,eAAe;CAClE,MAAM,uBAAuB,CAAC,QAAQ;AAEtC,KAAI;AAIF,OAFmB,QAAQ,cAAc,wBAAwB,MAE9C,UAAU;GAE3B,MAAM,mBAAmB,SAAS,cAAc,MAAM;AACtD,oBAAiB,MAAM,UAAU;;;;iBAItB,MAAM;kBACL,OAAO;;;;AAMnB,oBAAiB,YAAY,QAAQ,UAAU,KAAK,CAAC;AACrD,YAAS,KAAK,YAAY,iBAAiB;AAE3C,OAAI;AAEF,WAAO,MAAM,oBAAoB,kBAAkB,OAAO,QAAQ,EAChE,gBAAgB,MACjB,CAAC;aACM;AACR,qBAAiB,QAAQ;;QAW3B,QAAO,MAAM,qBAPG,MAAM,yBAAyB,SAAS,OAAO,QAAQ;GACrE;GACA,aAAa;GACb;GACD,CAAC,CAGwC;WAEpC;AACR,MAAI,qBACF,eAAc,SAAS"}
1
+ {"version":3,"file":"renderElementToCanvas.js","names":[],"sources":["../../src/preview/renderElementToCanvas.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,eAAsB,sBACpB,SACA,SAC4B;AAC5B,QAAO,MAAM,qBAAqB,SAAS,QAAQ;;;;;;AAOrD,eAAe,qBACb,SACA,SAC4B;CAC5B,MAAM,EAAE,QAAQ,QAAQ,MAAQ;CAGhC,MAAM,gBAAgB,iBAAiB,QAAQ;CAC/C,MAAM,QAAQ,QAAQ,UAAU,WAAW,cAAc,MAAM,IAAA;CAC/D,MAAM,SAAS,QAAQ,WAAW,WAAW,cAAc,OAAO,IAAA;CAGlE,MAAM,gBAAgB,QAAQ,iBAAiB,IAAI,eAAe;CAClE,MAAM,uBAAuB,CAAC,QAAQ;AAEtC,KAAI;AAIF,OAFmB,QAAQ,cAAc,wBAAwB,MAE9C,UAAU;GAE3B,MAAM,mBAAmB,SAAS,cAAc,MAAM;AACtD,oBAAiB,MAAM,UAAU;;;;iBAItB,MAAM;kBACL,OAAO;;;;AAMnB,oBAAiB,YAAY,QAAQ,UAAU,KAAK,CAAC;AACrD,YAAS,KAAK,YAAY,iBAAiB;AAE3C,OAAI;AAEF,WAAO,MAAM,oBAAoB,kBAAkB,OAAO,QAAQ,EAChE,gBAAgB,MACjB,CAAC;aACM;AACR,qBAAiB,QAAQ;;QAW3B,QAAO,MAAM,qBAPG,MAAM,yBAAyB,SAAS,OAAO,QAAQ;GACrE;GACA,aAAa;GACb;GACD,CAAC,CAGwC;WAEpC;AACR,MAAI,qBACF,eAAc,SAAS"}
@@ -5,7 +5,6 @@ import { loadImageFromDataUri } from "./rendering/loadImage.js";
5
5
  import { clearInlineImageCache, getInlineImageCacheSize } from "./rendering/inlineImages.js";
6
6
 
7
7
  //#region src/preview/renderTimegroupToCanvas.d.ts
8
-
9
8
  /**
10
9
  * Error thrown when video content is not ready within the blocking timeout.
11
10
  */
@@ -2,7 +2,7 @@ import { FrameController } from "./FrameController.js";
2
2
  import { updateAnimations } from "../elements/updateAnimations.js";
3
3
  import { logger } from "./logger.js";
4
4
  import { RenderContext } from "./RenderContext.js";
5
- import { DEFAULT_BLOCKING_TIMEOUT_MS, DEFAULT_CAPTURE_SCALE, DEFAULT_HEIGHT, DEFAULT_WIDTH, isVisibleAtTime } from "./previewTypes.js";
5
+ import { DEFAULT_BLOCKING_TIMEOUT_MS, DEFAULT_CAPTURE_SCALE, isVisibleAtTime } from "./previewTypes.js";
6
6
  import { captureTimelineToDataUri } from "./rendering/serializeTimelineDirect.js";
7
7
  import { getRenderMode, isNativeCanvasApiAvailable } from "./previewSettings.js";
8
8
  import { getEffectiveRenderMode, isCanvas, isImage } from "./renderers.js";
@@ -10,7 +10,6 @@ import { defaultProfiler } from "./RenderProfiler.js";
10
10
  import { loadImageFromDataUri } from "./rendering/loadImage.js";
11
11
  import { createDprCanvas, renderToImageNative } from "./rendering/renderToImageNative.js";
12
12
  import { clearInlineImageCache, getInlineImageCacheSize } from "./rendering/inlineImages.js";
13
-
14
13
  //#region src/preview/renderTimegroupToCanvas.ts
15
14
  /** Number of rows to sample when checking canvas content */
16
15
  const CANVAS_SAMPLE_STRIP_HEIGHT = 4;
@@ -188,8 +187,8 @@ async function captureFromClone(renderClone, _renderContainer, options = {}) {
188
187
  const { scale = DEFAULT_CAPTURE_SCALE, contentReadyMode = "immediate", blockingTimeoutMs = DEFAULT_BLOCKING_TIMEOUT_MS, originalTimegroup, timeMs: explicitTimeMs, canvasMode } = options;
189
188
  const timeMs = explicitTimeMs ?? renderClone.currentTimeMs;
190
189
  const sourceForDimensions = originalTimegroup ?? renderClone;
191
- const width = sourceForDimensions.offsetWidth || DEFAULT_WIDTH;
192
- const height = sourceForDimensions.offsetHeight || DEFAULT_HEIGHT;
190
+ const width = sourceForDimensions.offsetWidth || 1920;
191
+ const height = sourceForDimensions.offsetHeight || 1080;
193
192
  if (contentReadyMode === "blocking") {
194
193
  const result = await waitForVideoContent(renderClone, timeMs, blockingTimeoutMs);
195
194
  if (!result.ready) throw new ContentNotReadyError(timeMs, blockingTimeoutMs, result.blankVideos);
@@ -402,8 +401,8 @@ function renderTimegroupToCanvas(timegroup, scaleOrOptions = DEFAULT_PREVIEW_SCA
402
401
  const options = typeof scaleOrOptions === "number" ? { scale: scaleOrOptions } : scaleOrOptions;
403
402
  const scale = options.scale ?? DEFAULT_PREVIEW_SCALE;
404
403
  let currentResolutionScale = options.resolutionScale ?? DEFAULT_RESOLUTION_SCALE;
405
- const width = timegroup.offsetWidth || DEFAULT_WIDTH;
406
- const height = timegroup.offsetHeight || DEFAULT_HEIGHT;
404
+ const width = timegroup.offsetWidth || 1920;
405
+ const height = timegroup.offsetHeight || 1080;
407
406
  const dpr = (typeof window !== "undefined" ? window.devicePixelRatio : 1) || 1;
408
407
  let renderWidth = Math.floor(width * currentResolutionScale);
409
408
  let renderHeight = Math.floor(height * currentResolutionScale);
@@ -581,7 +580,7 @@ function renderTimegroupToCanvas(timegroup, scaleOrOptions = DEFAULT_PREVIEW_SCA
581
580
  dispose
582
581
  };
583
582
  }
584
-
585
583
  //#endregion
586
584
  export { ContentNotReadyError, captureFromClone, captureTimegroupAtTime, clearInlineImageCache, generateThumbnails, generateThumbnailsFromClone, getCacheMetrics, getEffectiveRenderMode, getInlineImageCacheSize, getRenderState, isCanvas, isImage, loadImageFromDataUri, renderTimegroupToCanvas, resetCacheMetrics, resetRenderState, waitForVideoContent };
585
+
587
586
  //# sourceMappingURL=renderTimegroupToCanvas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderTimegroupToCanvas.js","names":["timeMs: number","timeoutMs: number","blankVideos: string[]","renderState: RenderState","options: CanvasPreviewOptions","pendingResolutionScale: number | null","captureCanvas: HTMLCanvasElement | null","captureCtx: HtmlInCanvasContext | null","originalParent: ParentNode | null","originalNextSibling: ChildNode | null"],"sources":["../../src/preview/renderTimegroupToCanvas.ts"],"sourcesContent":["import type { EFTimegroup } from \"../elements/EFTimegroup.js\";\nimport type {\n CaptureOptions,\n CaptureFromCloneOptions,\n GeneratedThumbnail,\n GenerateThumbnailsOptions,\n ThumbnailQueue,\n CanvasPreviewResult,\n CanvasPreviewOptions,\n} from \"./renderTimegroupToCanvas.types.js\";\nimport { RenderContext } from \"./RenderContext.js\";\nimport { FrameController } from \"./FrameController.js\";\nimport { captureTimelineToDataUri } from \"./rendering/serializeTimelineDirect.js\";\nimport { updateAnimations, type AnimatableElement } from \"../elements/updateAnimations.js\";\n\n// Re-export renderer types for external use\nexport type { RenderOptions, RenderResult, Renderer } from \"./renderers.js\";\nexport { getEffectiveRenderMode, isCanvas, isImage } from \"./renderers.js\";\nimport {\n isVisibleAtTime,\n DEFAULT_WIDTH,\n DEFAULT_HEIGHT,\n DEFAULT_CAPTURE_SCALE,\n DEFAULT_BLOCKING_TIMEOUT_MS,\n} from \"./previewTypes.js\";\nimport { defaultProfiler } from \"./RenderProfiler.js\";\nimport { logger } from \"./logger.js\";\n\n// Import rendering modules\nimport { loadImageFromDataUri } from \"./rendering/loadImage.js\";\nimport { createDprCanvas, renderToImageNative } from \"./rendering/renderToImageNative.js\";\nimport { clearInlineImageCache, getInlineImageCacheSize } from \"./rendering/inlineImages.js\";\nimport { isNativeCanvasApiAvailable, getRenderMode } from \"./previewSettings.js\";\nimport type { HtmlInCanvasContext, HtmlInCanvasElement } from \"./rendering/types.js\";\n\n// Re-export rendering types and functions for external use\nexport { loadImageFromDataUri };\n\n// ============================================================================\n// Constants (module-specific, not shared)\n// ============================================================================\n\n/** Number of rows to sample when checking canvas content */\nconst CANVAS_SAMPLE_STRIP_HEIGHT = 4;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n// Re-export types from type-only module (zero side effects)\nexport type {\n ContentReadyMode,\n CaptureOptions,\n CaptureFromCloneOptions,\n GeneratedThumbnail,\n GenerateThumbnailsOptions,\n ThumbnailQueue,\n CanvasPreviewResult,\n CanvasPreviewOptions,\n} from \"./renderTimegroupToCanvas.types.js\";\n\n/**\n * Error thrown when video content is not ready within the blocking timeout.\n */\nexport class ContentNotReadyError extends Error {\n constructor(\n public readonly timeMs: number,\n public readonly timeoutMs: number,\n public readonly blankVideos: string[],\n ) {\n super(\n `Video content not ready at ${timeMs}ms after ${timeoutMs}ms timeout. Blank videos: ${blankVideos.join(\", \")}`,\n );\n this.name = \"ContentNotReadyError\";\n }\n}\n\n// ============================================================================\n// Module State (reset via resetRenderState)\n// ============================================================================\n\n/**\n * Module-level render state including caches and reusable objects.\n */\ninterface RenderState {\n inlineImageCache: Map<string, string>;\n layoutInitializedCanvases: WeakSet<HTMLCanvasElement>;\n xmlSerializer: XMLSerializer | null;\n textEncoder: TextEncoder;\n metrics: {\n inlineImageCacheHits: number;\n inlineImageCacheMisses: number;\n inlineImageCacheEvictions: number;\n };\n}\n\n/**\n * Module-level state for render operations.\n * Note: xmlSerializer is lazy-initialized for Node.js compatibility\n */\nconst renderState: RenderState = {\n inlineImageCache: new Map(),\n layoutInitializedCanvases: new WeakSet(),\n xmlSerializer: null, // Lazy-initialized in browser context\n textEncoder: new TextEncoder(),\n metrics: {\n inlineImageCacheHits: 0,\n inlineImageCacheMisses: 0,\n inlineImageCacheEvictions: 0,\n },\n};\n\n/**\n * Get the current render state for testing and debugging.\n * @returns The module-level render state object\n */\nexport function getRenderState(): RenderState {\n return renderState;\n}\n\n/**\n * Get cache metrics for monitoring performance.\n * @returns Object with cache hit/miss/eviction counts\n */\nexport function getCacheMetrics(): RenderState[\"metrics\"] {\n return { ...renderState.metrics };\n}\n\n/**\n * Reset cache metrics to zero.\n */\nexport function resetCacheMetrics(): void {\n renderState.metrics.inlineImageCacheHits = 0;\n renderState.metrics.inlineImageCacheMisses = 0;\n renderState.metrics.inlineImageCacheEvictions = 0;\n}\n\n/**\n * Reset all module state including profiling counters, caches, and logging flags.\n * Call at the start of export sessions to ensure clean state.\n */\nexport function resetRenderState(): void {\n defaultProfiler.reset();\n clearInlineImageCache();\n resetCacheMetrics();\n}\n\n// Re-export cache management functions\nexport { clearInlineImageCache, getInlineImageCacheSize };\n\n/**\n * DEBUG: Capture a single thumbnail at the current time.\n * Call from console: window.debugCaptureThumbnail()\n */\nif (typeof window !== \"undefined\") {\n (window as any).debugCaptureThumbnail = async function () {\n const timegroup = document.querySelector(\"ef-timegroup\") as any;\n if (!timegroup) {\n console.error(\"No timegroup found\");\n return;\n }\n\n const currentTime = timegroup.currentTimeMs ?? 0;\n\n try {\n const result = await captureTimegroupAtTime(timegroup, {\n timeMs: currentTime,\n scale: 0.25,\n contentReadyMode: \"blocking\",\n blockingTimeoutMs: 1000,\n });\n\n // Create a temporary img element to display the result\n const img = document.createElement(\"img\");\n if (result instanceof HTMLCanvasElement) {\n img.src = result.toDataURL();\n } else if (result instanceof HTMLImageElement) {\n img.src = result.src;\n }\n img.style.cssText = \"position:fixed;top:10px;right:10px;border:2px solid red;z-index:99999;\";\n document.body.appendChild(img);\n\n return result;\n } catch (err) {\n console.error(\"[DEBUG] Capture failed:\", err);\n throw err;\n }\n };\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\n/**\n * Wait for next animation frame (allows browser to complete layout)\n */\nfunction waitForFrame(): Promise<void> {\n return new Promise((resolve) => requestAnimationFrame(() => resolve()));\n}\n\n/**\n * Check if a canvas has any rendered content (not all transparent/uninitialized).\n * Returns true if there's ANY non-transparent pixel.\n */\nfunction canvasHasContent(canvas: HTMLCanvasElement): boolean {\n const ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\n if (!ctx) return false;\n\n try {\n const width = canvas.width;\n const height = canvas.height;\n if (width === 0 || height === 0) return false;\n\n // Sample a horizontal strip across the middle of the canvas\n // This catches most video content even if edges are black\n const stripY = Math.floor(height / 2);\n const imageData = ctx.getImageData(0, stripY, width, CANVAS_SAMPLE_STRIP_HEIGHT);\n const data = imageData.data;\n\n // Check if ANY pixel has non-zero alpha (is not transparent)\n // A truly blank/uninitialized canvas has all pixels at [0,0,0,0]\n // A black video frame would have pixels at [0,0,0,255] (opaque black)\n for (let i = 3; i < data.length; i += 4) {\n if (data[i] !== 0) {\n return true;\n }\n }\n\n return false;\n } catch {\n // Canvas might be tainted, assume it has content\n return true;\n }\n}\n\ninterface WaitForVideoContentResult {\n ready: boolean;\n blankVideos: string[];\n}\n\n/**\n * Returns true if the element is visible at the given time and all its\n * ancestor timegroups (up to but not including `timegroup`) are also visible.\n */\nfunction isVisibleInContext(element: Element, timegroup: EFTimegroup, timeMs: number): boolean {\n if (!isVisibleAtTime(element, timeMs)) return false;\n let parent = element.parentElement;\n while (parent && parent !== timegroup) {\n if (parent.tagName === \"EF-TIMEGROUP\" && !isVisibleAtTime(parent, timeMs)) return false;\n parent = parent.parentElement;\n }\n return true;\n}\n\n/**\n * Wait for media content (videos and images) within a timegroup to be ready.\n * - ef-video: waits for the shadow canvas to have non-transparent pixels.\n * - ef-image: waits for contentReadyState to reach \"ready\" or \"error\".\n * Only checks elements that should be visible at the current time.\n */\nexport async function waitForVideoContent(\n timegroup: EFTimegroup,\n timeMs: number,\n maxWaitMs: number,\n): Promise<WaitForVideoContentResult> {\n const startTime = performance.now();\n\n // Collect all media elements that need to be ready\n const allVideos = Array.from(timegroup.querySelectorAll(\"ef-video\")).filter((el) =>\n isVisibleInContext(el, timegroup, timeMs),\n );\n const allImages = Array.from(timegroup.querySelectorAll(\"ef-image\")).filter((el) =>\n isVisibleInContext(el, timegroup, timeMs),\n );\n\n if (allVideos.length === 0 && allImages.length === 0) return { ready: true, blankVideos: [] };\n\n const isVideoReady = (video: Element): boolean => {\n const shadowCanvas = video.shadowRoot?.querySelector(\"canvas\");\n if (!shadowCanvas || shadowCanvas.width === 0 || shadowCanvas.height === 0) return true;\n return canvasHasContent(shadowCanvas);\n };\n\n const isImageReady = (image: Element): boolean => {\n const state = (image as any).contentReadyState as string | undefined;\n return state === \"ready\" || state === \"error\";\n };\n\n const getBlankNames = () => [\n ...allVideos.filter((v) => !isVideoReady(v)).map((v) => (v as any).src || v.id || \"unnamed\"),\n ...allImages.filter((i) => !isImageReady(i)).map((i) => (i as any).src || i.id || \"unnamed\"),\n ];\n\n while (performance.now() - startTime < maxWaitMs) {\n if (allVideos.every(isVideoReady) && allImages.every(isImageReady)) {\n return { ready: true, blankVideos: [] };\n }\n await waitForFrame();\n }\n\n return { ready: false, blankVideos: getBlankNames() };\n}\n\n/**\n * Captures a frame from an already-seeked render clone.\n * Used internally by captureBatch for efficiency (reuses one clone across all captures).\n *\n * @param renderClone - A render clone that has already been seeked to the target time\n * @param renderContainer - The container holding the render clone (from createRenderClone)\n * @param options - Capture options\n * @returns Canvas or Image with the rendered frame (both are CanvasImageSource)\n */\nexport async function captureFromClone(\n renderClone: EFTimegroup,\n _renderContainer: HTMLElement,\n options: CaptureFromCloneOptions = {},\n): Promise<CanvasImageSource> {\n const {\n scale = DEFAULT_CAPTURE_SCALE,\n contentReadyMode = \"immediate\",\n blockingTimeoutMs = DEFAULT_BLOCKING_TIMEOUT_MS,\n originalTimegroup,\n timeMs: explicitTimeMs,\n canvasMode,\n } = options;\n\n // Use explicit time if provided, otherwise fall back to clone's currentTimeMs\n // CRITICAL: Using explicit time ensures temporal visibility checks are accurate\n // NOTE: Must be defined BEFORE any logging that references timeMs\n const timeMs = explicitTimeMs ?? renderClone.currentTimeMs;\n\n // Use original timegroup dimensions if available, otherwise clone dimensions\n const sourceForDimensions = originalTimegroup ?? renderClone;\n const width = sourceForDimensions.offsetWidth || DEFAULT_WIDTH;\n const height = sourceForDimensions.offsetHeight || DEFAULT_HEIGHT;\n\n // NOTE: seekForRender() has already:\n // 1. Called frameController.renderFrame() to coordinate FrameRenderable elements\n // 2. Awaited #executeCustomFrameTasks() so frame tasks are complete\n // No need to call frameController.renderFrame() again - it would fire tasks redundantly\n\n if (contentReadyMode === \"blocking\") {\n const result = await waitForVideoContent(renderClone, timeMs, blockingTimeoutMs);\n if (!result.ready) {\n throw new ContentNotReadyError(timeMs, blockingTimeoutMs, result.blankVideos);\n }\n }\n\n // Determine effective canvas mode:\n // 1. If explicitly specified, use that\n // 2. If \"native\" is requested but not available, fall back to foreignObject\n // 3. If not specified, default to foreignObject for compatibility\n const effectiveCanvasMode = (() => {\n if (!canvasMode) return \"foreignObject\";\n if (canvasMode === \"native\" && !isNativeCanvasApiAvailable()) {\n logger.debug(\n \"[captureFromClone] Native canvas mode requested but not available, falling back to foreignObject\",\n );\n return \"foreignObject\";\n }\n return canvasMode;\n })();\n\n // Create RenderContext for caching during this capture operation (only needed for foreignObject)\n const renderContext = new RenderContext();\n\n try {\n if (effectiveCanvasMode === \"native\") {\n // NATIVE PATH: Use drawElementImage API (~1.76x faster than foreignObject)\n // No DOM serialization, no canvas-to-dataURL encoding, no image loading\n // Direct browser-native rendering\n\n const t0 = performance.now();\n const canvas = await renderToImageNative(renderClone, width, height, {\n skipDprScaling: true, // Use 1x DPR for video export (4x fewer pixels!)\n });\n const renderTime = performance.now() - t0;\n\n logger.debug(\n `[captureFromClone] native render=${renderTime.toFixed(0)}ms (canvasScale=${scale})`,\n );\n\n return canvas;\n } else {\n // FOREIGNOBJECT PATH: Serialize DOM → SVG → Image → Canvas\n // More compatible but slower than native path\n\n // NOTE: seekForRender() has already ensured rendering is complete, including:\n // - Lit updates propagated\n // - All LitElement descendants updated\n // - frameController.renderFrame() called for FrameRenderable elements\n // - Layout stabilization complete\n // No additional RAF wait needed - can serialize immediately\n\n const t0 = performance.now();\n const dataUri = await captureTimelineToDataUri(renderClone, width, height, {\n renderContext,\n canvasScale: scale,\n timeMs,\n });\n const serializeTime = performance.now() - t0;\n\n const t1 = performance.now();\n const image = await loadImageFromDataUri(dataUri);\n const loadTime = performance.now() - t1;\n\n logger.debug(\n `[captureFromClone] foreignObject serialize=${serializeTime.toFixed(0)}ms, load=${loadTime.toFixed(0)}ms (canvasScale=${scale})`,\n );\n\n // Return image directly - no copy needed!\n return image;\n }\n } finally {\n // Ensure RenderContext is disposed even if an error occurs\n renderContext.dispose();\n }\n}\n\n/**\n * Captures a single frame from a timegroup at a specific time.\n *\n * CLONE-TIMELINE ARCHITECTURE:\n * Creates an independent render clone, seeks it to the target time, and captures.\n * Prime-timeline is NEVER seeked - user can continue previewing/editing during capture.\n *\n * @param timegroup - The source timegroup\n * @param options - Capture options including timeMs, scale, contentReadyMode\n * @returns Canvas with the rendered frame\n * @throws ContentNotReadyError if blocking mode times out waiting for video content\n */\nexport async function captureTimegroupAtTime(\n timegroup: EFTimegroup,\n options: CaptureOptions,\n): Promise<CanvasImageSource> {\n const {\n timeMs,\n scale = DEFAULT_CAPTURE_SCALE,\n // skipRestore is deprecated with Clone-timeline (Prime is never seeked)\n contentReadyMode = \"immediate\",\n blockingTimeoutMs = DEFAULT_BLOCKING_TIMEOUT_MS,\n canvasMode,\n skipClone = false,\n } = options;\n\n if (skipClone) {\n // DIRECT RENDERING: Skip clone creation for headless server rendering\n // Seek prime timeline directly and capture from it\n // WARNING: This modifies the prime timeline! Only use in headless contexts.\n\n const seekStart = performance.now();\n await timegroup.seekForRender(timeMs);\n const seekMs = performance.now() - seekStart;\n\n const renderStart = performance.now();\n // Use timegroup's actual container (parentElement or document.body as fallback)\n const container = (timegroup.parentElement || document.body) as HTMLElement;\n const result = await captureFromClone(timegroup, container, {\n scale,\n contentReadyMode,\n blockingTimeoutMs,\n originalTimegroup: undefined, // No original since we're rendering the prime\n canvasMode,\n timeMs, // Pass explicit time since we're not using a clone\n });\n const renderMs = performance.now() - renderStart;\n\n // Store timing (no clone time since we skipped it)\n if (typeof result === \"object\" && result !== null) {\n (result as any).__perfTiming = { cloneMs: 0, seekMs, renderMs };\n }\n\n return result;\n }\n\n // CLONE-TIMELINE: Create a short-lived render clone for this capture\n // Prime-timeline is NEVER seeked - clone is fully independent\n const cloneStart = performance.now();\n const {\n clone: renderClone,\n container: renderContainer,\n cleanup: cleanupRenderClone,\n } = await timegroup.createRenderClone();\n const cloneMs = performance.now() - cloneStart;\n\n try {\n // Seek the clone to target time (Prime stays at user position)\n // Use seekForRender which bypasses duration clamping - render clones may have\n // zero duration initially until media durations are computed, but we still\n // want to seek to the requested time for capture purposes.\n const seekStart = performance.now();\n await renderClone.seekForRender(timeMs);\n const seekMs = performance.now() - seekStart;\n\n // Use the shared capture helper\n const renderStart = performance.now();\n const result = await captureFromClone(renderClone, renderContainer, {\n scale,\n contentReadyMode,\n blockingTimeoutMs,\n originalTimegroup: timegroup,\n canvasMode,\n });\n const renderMs = performance.now() - renderStart;\n\n // Store timing on the result for access by callers (if they need it)\n // Note: CanvasImageSource doesn't support custom properties, but we can attach them anyway\n if (typeof result === \"object\" && result !== null) {\n (result as any).__perfTiming = { cloneMs, seekMs, renderMs };\n }\n\n return result;\n } finally {\n // Clean up the render clone\n cleanupRenderClone();\n }\n}\n\n/**\n * Generate thumbnails using an existing render clone and mutable queue.\n * The queue can be modified while generation is in progress.\n *\n * @param renderClone - Pre-created render clone to use\n * @param renderContainer - Container for the render clone\n * @param queue - Mutable queue that provides timestamps\n * @param options - Capture options (scale, contentReadyMode, etc.)\n * @yields Objects with { timeMs, canvas } for each captured thumbnail\n *\n * @example\n * ```ts\n * const queue = new MutableTimestampQueue();\n * queue.reset([0, 100, 200]);\n *\n * for await (const { timeMs, canvas } of generateThumbnailsFromClone(clone, container, queue)) {\n * cache.set(timeMs, canvas);\n * // Queue can be modified here while generator continues\n * }\n * ```\n */\nexport async function* generateThumbnailsFromClone(\n renderClone: EFTimegroup,\n renderContainer: HTMLElement,\n queue: ThumbnailQueue,\n options: GenerateThumbnailsOptions = {},\n): AsyncGenerator<GeneratedThumbnail> {\n const {\n scale = DEFAULT_CAPTURE_SCALE,\n contentReadyMode = \"immediate\",\n blockingTimeoutMs = DEFAULT_BLOCKING_TIMEOUT_MS,\n signal,\n } = options;\n\n while (true) {\n // Check if aborted before starting work\n if (signal?.aborted) {\n break;\n }\n\n const timeMs = queue.shift();\n if (timeMs === undefined) {\n // Queue is empty, generator exits\n break;\n }\n\n // Seek the clone to the target time\n await renderClone.seekForRender(timeMs);\n\n // Check if aborted after seek (before expensive capture)\n if (signal?.aborted) {\n break;\n }\n\n // Capture from the seeked clone, passing explicit timeMs\n const canvas = await captureFromClone(renderClone, renderContainer, {\n scale,\n contentReadyMode,\n blockingTimeoutMs,\n timeMs, // CRITICAL: Pass explicit time for accurate temporal visibility\n });\n\n // Yield the result with explicit timestamp association\n yield { timeMs, canvas };\n }\n}\n\n/**\n * Generate thumbnails for multiple timestamps efficiently using a single render clone.\n * This avoids the overhead of creating/destroying a clone for each thumbnail.\n *\n * @param timegroup - The timegroup to capture\n * @param timestamps - Array of timestamps to capture (in milliseconds)\n * @param options - Capture options (scale, contentReadyMode, etc.)\n * @param signal - Optional AbortSignal to cancel generation\n * @yields Objects with { timeMs, canvas } for each captured thumbnail\n *\n * @example\n * ```ts\n * for await (const { timeMs, canvas } of generateThumbnails(tg, [0, 100, 200])) {\n * console.log(`Got thumbnail for ${timeMs}ms`);\n * thumbnailCache.set(timeMs, canvas);\n * }\n * ```\n */\nexport async function* generateThumbnails(\n timegroup: EFTimegroup,\n timestamps: number[],\n options: GenerateThumbnailsOptions = {},\n signal?: AbortSignal,\n): AsyncGenerator<GeneratedThumbnail> {\n const {\n scale = DEFAULT_CAPTURE_SCALE,\n contentReadyMode = \"immediate\",\n blockingTimeoutMs = DEFAULT_BLOCKING_TIMEOUT_MS,\n } = options;\n\n // Create a single render clone for all thumbnails\n const {\n clone: renderClone,\n container: renderContainer,\n cleanup: cleanupRenderClone,\n } = await timegroup.createRenderClone();\n\n try {\n for (const timeMs of timestamps) {\n // Check for abort before each capture\n signal?.throwIfAborted();\n\n // Seek the clone to the target time\n await renderClone.seekForRender(timeMs);\n\n // Capture from the seeked clone\n const canvas = await captureFromClone(renderClone, renderContainer, {\n scale,\n contentReadyMode,\n blockingTimeoutMs,\n originalTimegroup: timegroup,\n });\n\n // Yield the result with explicit timestamp association\n yield { timeMs, canvas };\n }\n } finally {\n // Always clean up the render clone\n cleanupRenderClone();\n }\n}\n\n/** Epsilon for comparing time values (ms) - times within this are considered equal */\nconst TIME_EPSILON_MS = 1;\n\n/** Default scale for preview rendering */\nconst DEFAULT_PREVIEW_SCALE = 1;\n\n/** Default resolution scale (full resolution) */\nconst DEFAULT_RESOLUTION_SCALE = 1;\n\n/**\n * Convert relative time to absolute time for a timegroup.\n * Nested timegroup children have ABSOLUTE startTimeMs values,\n * so relative capture times must be converted for temporal culling.\n */\nfunction toAbsoluteTime(timegroup: EFTimegroup, relativeTimeMs: number): number {\n return relativeTimeMs + (timegroup.startTimeMs ?? 0);\n}\n\n/**\n * Renders a timegroup preview to a canvas using SVG foreignObject.\n *\n * Captures the prime timeline's current visual state including DOM changes\n * from frame tasks (SVG paths, canvas content, text updates, etc.).\n *\n * Optimized with:\n * - Passive clone structure rebuilt each frame from prime's current state\n * - Temporal bucketing for time-based culling\n * - RenderContext for canvas pixel caching across frames\n * - Resolution scaling for performance (renders at lower resolution, CSS upscales)\n *\n * @param timegroup - The source timegroup to preview (prime timeline)\n * @param scaleOrOptions - Scale factor (default 1) or options object\n * @returns Object with canvas and refresh function\n */\nexport function renderTimegroupToCanvas(\n timegroup: EFTimegroup,\n scaleOrOptions: number | CanvasPreviewOptions = DEFAULT_PREVIEW_SCALE,\n): CanvasPreviewResult {\n // Normalize options\n const options: CanvasPreviewOptions =\n typeof scaleOrOptions === \"number\" ? { scale: scaleOrOptions } : scaleOrOptions;\n\n const scale = options.scale ?? DEFAULT_PREVIEW_SCALE;\n // These are mutable to support dynamic resolution changes\n let currentResolutionScale = options.resolutionScale ?? DEFAULT_RESOLUTION_SCALE;\n\n const width = timegroup.offsetWidth || DEFAULT_WIDTH;\n const height = timegroup.offsetHeight || DEFAULT_HEIGHT;\n const dpr = (typeof window !== \"undefined\" ? window.devicePixelRatio : 1) || 1;\n\n // Calculate effective render dimensions (internal resolution) - mutable\n let renderWidth = Math.floor(width * currentResolutionScale);\n let renderHeight = Math.floor(height * currentResolutionScale);\n\n // Create canvas with proper DPR handling\n const canvas = createDprCanvas({\n renderWidth,\n renderHeight,\n scale,\n fullWidth: width,\n fullHeight: height,\n dpr,\n });\n\n // Return canvas directly - no wrapper needed\n const wrapperContainer = canvas;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Failed to get canvas 2d context\");\n }\n\n // Track render state\n let rendering = false;\n let lastTimeMs = -1;\n let disposed = false;\n\n // Invalidate lastTimeMs when composition structure or attributes change so\n // refresh() re-renders even when currentTimeMs hasn't changed (e.g. paused edits).\n const compositionObserver = new MutationObserver(() => {\n if (!rendering) lastTimeMs = -1;\n });\n compositionObserver.observe(timegroup, {\n attributes: true,\n childList: true,\n subtree: true,\n });\n\n // Create RenderContext for caching across refresh calls (foreignObject only)\n const renderContext = new RenderContext();\n\n // Create FrameController for coordinating element rendering\n // Cached for the lifetime of this preview instance\n const frameController = new FrameController(timegroup);\n\n // Log resolution scale on first render for debugging\n let hasLoggedScale = false;\n\n // Pending resolution change - applied at start of next refresh to avoid blanking\n let pendingResolutionScale: number | null = null;\n\n // Use the user's render mode preference. Native requires the timegroup to be\n // inside a <canvas layoutsubtree> for drawElementImage to work.\n const useNative = getRenderMode() === \"native\" && isNativeCanvasApiAvailable();\n let captureCanvas: HTMLCanvasElement | null = null;\n let captureCtx: HtmlInCanvasContext | null = null;\n let originalParent: ParentNode | null = null;\n let originalNextSibling: ChildNode | null = null;\n let savedClipPath = \"\";\n let savedPointerEvents = \"\";\n\n if (useNative) {\n captureCanvas = document.createElement(\"canvas\");\n captureCanvas.setAttribute(\"layoutsubtree\", \"\");\n (captureCanvas as HtmlInCanvasElement).layoutSubtree = true;\n captureCanvas.width = renderWidth;\n captureCanvas.height = renderHeight;\n captureCanvas.style.cssText = `position:fixed;left:0;top:0;width:${width}px;height:${height}px;opacity:0;pointer-events:none;z-index:-9999;`;\n originalParent = timegroup.parentNode;\n originalNextSibling = timegroup.nextSibling;\n savedClipPath = timegroup.style.clipPath;\n savedPointerEvents = timegroup.style.pointerEvents;\n timegroup.style.clipPath = \"\";\n timegroup.style.pointerEvents = \"\";\n captureCanvas.appendChild(timegroup);\n document.body.appendChild(captureCanvas);\n captureCtx = captureCanvas.getContext(\"2d\") as HtmlInCanvasContext;\n void captureCanvas.offsetHeight;\n void timegroup.offsetHeight;\n }\n\n /**\n * Apply pending resolution scale changes.\n * Called at the start of refresh() before rendering, so the old content\n * stays visible until new content is ready to be drawn.\n */\n const applyPendingResolutionChange = (): void => {\n if (pendingResolutionScale === null) return;\n\n const newScale = pendingResolutionScale;\n pendingResolutionScale = null;\n\n currentResolutionScale = newScale;\n renderWidth = Math.floor(width * currentResolutionScale);\n renderHeight = Math.floor(height * currentResolutionScale);\n\n if (captureCanvas) {\n captureCanvas.width = renderWidth;\n captureCanvas.height = renderHeight;\n }\n };\n\n /**\n * Dynamically change resolution scale without rebuilding clone structure.\n * The actual change is deferred until next refresh() to avoid blanking -\n * old content stays visible until new content is ready.\n */\n const setResolutionScale = (newScale: number): void => {\n // Clamp to valid range\n newScale = Math.max(0.1, Math.min(1, newScale));\n\n if (newScale === currentResolutionScale && pendingResolutionScale === null) return;\n\n // Queue the change - will be applied at start of next refresh\n pendingResolutionScale = newScale;\n\n // Force re-render on next refresh by invalidating lastTimeMs\n lastTimeMs = -1;\n };\n\n const getResolutionScale = (): number => pendingResolutionScale ?? currentResolutionScale;\n\n const refresh = async (): Promise<void> => {\n if (disposed) return;\n\n const sourceTimeMs = timegroup.currentTimeMs ?? 0;\n const userTimeMs = timegroup.userTimeMs ?? 0;\n\n if (Math.abs(sourceTimeMs - userTimeMs) > TIME_EPSILON_MS) return;\n if (userTimeMs === lastTimeMs) return;\n if (rendering) return;\n\n lastTimeMs = userTimeMs;\n rendering = true;\n\n applyPendingResolutionChange();\n\n if (!hasLoggedScale) {\n hasLoggedScale = true;\n const mode = useNative ? \"native\" : \"foreignObject\";\n logger.debug(\n `[renderTimegroupToCanvas] Resolution scale: ${currentResolutionScale} (${width}x${height} → ${renderWidth}x${renderHeight}), canvas buffer: ${canvas.width}x${canvas.height}, CSS size: ${canvas.style.width}x${canvas.style.height}, renderMode: ${mode}`,\n );\n }\n\n try {\n await frameController.renderFrame(userTimeMs, {\n waitForLitUpdate: false,\n onAnimationsUpdate: (root) => {\n updateAnimations(root as AnimatableElement);\n },\n });\n\n if (useNative && captureCanvas && captureCtx) {\n if (captureCanvas.width !== width || captureCanvas.height !== height) {\n captureCtx.save();\n captureCtx.scale(captureCanvas.width / width, captureCanvas.height / height);\n captureCtx.drawElementImage(timegroup, 0, 0);\n captureCtx.restore();\n } else {\n captureCtx.drawElementImage(timegroup, 0, 0);\n }\n const targetWidth = Math.floor(renderWidth * scale * dpr);\n const targetHeight = Math.floor(renderHeight * scale * dpr);\n if (canvas.width !== targetWidth || canvas.height !== targetHeight) {\n canvas.width = targetWidth;\n canvas.height = targetHeight;\n } else {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n ctx.drawImage(captureCanvas, 0, 0, canvas.width, canvas.height);\n\n defaultProfiler.incrementRenderCount();\n } else {\n const absoluteTimeMs = toAbsoluteTime(timegroup, userTimeMs);\n\n const dataUri = await captureTimelineToDataUri(timegroup, width, height, {\n renderContext,\n canvasScale: currentResolutionScale,\n timeMs: absoluteTimeMs,\n });\n const image = await loadImageFromDataUri(dataUri);\n\n const targetWidth = Math.floor(renderWidth * scale * dpr);\n const targetHeight = Math.floor(renderHeight * scale * dpr);\n if (canvas.width !== targetWidth || canvas.height !== targetHeight) {\n canvas.width = targetWidth;\n canvas.height = targetHeight;\n } else {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n\n ctx.save();\n ctx.scale(dpr * scale, dpr * scale);\n ctx.drawImage(image, 0, 0, renderWidth, renderHeight);\n ctx.restore();\n\n defaultProfiler.incrementRenderCount();\n }\n } catch (e) {\n logger.error(\"Canvas preview render failed:\", e);\n } finally {\n rendering = false;\n }\n };\n\n /**\n * Dispose the preview and release resources.\n */\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n compositionObserver.disconnect();\n frameController.abort();\n renderContext.dispose();\n\n // Restore timegroup to original DOM position if native mode moved it\n if (useNative && originalParent) {\n timegroup.style.clipPath = savedClipPath;\n timegroup.style.pointerEvents = savedPointerEvents;\n if (originalNextSibling) {\n originalParent.insertBefore(timegroup, originalNextSibling);\n } else {\n originalParent.appendChild(timegroup);\n }\n captureCanvas?.remove();\n }\n };\n\n const invalidate = (): void => {\n lastTimeMs = -1;\n };\n\n // Do initial render\n refresh();\n\n return {\n container: wrapperContainer,\n canvas,\n refresh,\n invalidate,\n setResolutionScale,\n getResolutionScale,\n dispose,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"renderTimegroupToCanvas.js","names":[],"sources":["../../src/preview/renderTimegroupToCanvas.ts"],"mappings":"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"}
@@ -3,7 +3,6 @@ import { EFTimegroup } from "../elements/EFTimegroup.js";
3
3
  import { AudioCodec, QUALITY_HIGH } from "mediabunny";
4
4
 
5
5
  //#region src/preview/renderTimegroupToVideo.d.ts
6
-
7
6
  declare class NoSupportedAudioCodecError extends Error {
8
7
  constructor(requestedCodecs: AudioCodec[], availableCodecs: AudioCodec[]);
9
8
  }
@@ -7,8 +7,20 @@ import { renderToImageNative } from "./rendering/renderToImageNative.js";
7
7
  import { resetRenderState, waitForVideoContent } from "./renderTimegroupToCanvas.js";
8
8
  import { EFMotionBlur } from "../elements/EFMotionBlur.js";
9
9
  import { AudioBufferSource, BufferTarget, CanvasSource, Mp4OutputFormat, Output, QUALITY_HIGH, StreamTarget, canEncodeAudio, getEncodableAudioCodecs } from "mediabunny";
10
-
11
10
  //#region src/preview/renderTimegroupToVideo.ts
11
+ /**
12
+ * Video rendering for timegroups using direct serialization.
13
+ *
14
+ * Architecture:
15
+ * - Creates a render clone of the timeline
16
+ * - For each frame:
17
+ * 1. Seeks the clone to the target time
18
+ * 2. Executes frame tasks (SVG updates, canvas draws, etc.)
19
+ * 3. Serializes the live DOM directly to SVG+foreignObject data URI
20
+ * 4. Renders to image and encodes to video
21
+ *
22
+ * RenderContext provides pixel caching across frames for performance.
23
+ */
12
24
  var NoSupportedAudioCodecError = class extends Error {
13
25
  constructor(requestedCodecs, availableCodecs) {
14
26
  super(`No supported audio codec found. Requested: [${requestedCodecs.join(", ")}], Available: [${availableCodecs.length > 0 ? availableCodecs.join(", ") : "none"}]`);
@@ -288,16 +300,16 @@ async function renderTimegroupToVideo(timegroup, options = {}) {
288
300
  timeMs
289
301
  }).then((dataUri) => {
290
302
  return new Promise((resolve, reject) => {
291
- const image$1 = new Image();
292
- image$1.onload = () => {
293
- entry.resolved = image$1;
294
- resolve(image$1);
303
+ const image = new Image();
304
+ image.onload = () => {
305
+ entry.resolved = image;
306
+ resolve(image);
295
307
  };
296
- image$1.onerror = (e) => {
308
+ image.onerror = (e) => {
297
309
  console.error(`[Render] frame ${fi} image load error:`, e);
298
310
  reject(/* @__PURE__ */ new Error(`Failed to load image from data URI`));
299
311
  };
300
- image$1.src = dataUri;
312
+ image.src = dataUri;
301
313
  });
302
314
  });
303
315
  pendingFrames.push(entry);
@@ -391,7 +403,7 @@ async function renderTimegroupToVideo(timegroup, options = {}) {
391
403
  cleanupRenderClone();
392
404
  }
393
405
  }
394
-
395
406
  //#endregion
396
407
  export { NoSupportedAudioCodecError, QUALITY_HIGH, RenderCancelledError, getSupportedAudioCodecs, renderTimegroupToVideo };
408
+
397
409
  //# sourceMappingURL=renderTimegroupToVideo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderTimegroupToVideo.js","names":["timestamps: number[]","output: Output | null","videoSource: CanvasSource | null","audioSource: AudioBufferSource | null","target: BufferTarget | StreamTarget | null","fileStream: {\n writable: WritableStream<Uint8Array>;\n close: () => Promise<void>;\n } | null","encodingCanvas: OffscreenCanvas | null","encodingCtx: OffscreenCanvasRenderingContext2D | null","videoConfig: VideoEncodingConfig","thumbCanvas: HTMLCanvasElement | null","thumbCtx: CanvasRenderingContext2D | null","pendingFrames: PendingFrame[]","entry: PendingFrame","image","image: HTMLImageElement","headers: Record<string, string>"],"sources":["../../src/preview/renderTimegroupToVideo.ts"],"sourcesContent":["/**\n * Video rendering for timegroups using direct serialization.\n *\n * Architecture:\n * - Creates a render clone of the timeline\n * - For each frame:\n * 1. Seeks the clone to the target time\n * 2. Executes frame tasks (SVG updates, canvas draws, etc.)\n * 3. Serializes the live DOM directly to SVG+foreignObject data URI\n * 4. Renders to image and encodes to video\n *\n * RenderContext provides pixel caching across frames for performance.\n */\n\nimport { logger } from \"./logger.js\";\nimport {\n Output,\n Mp4OutputFormat,\n BufferTarget,\n StreamTarget,\n CanvasSource,\n AudioBufferSource,\n QUALITY_HIGH,\n canEncodeAudio,\n getEncodableAudioCodecs,\n type VideoEncodingConfig,\n type AudioEncodingConfig,\n type AudioCodec,\n} from \"mediabunny\";\nimport type { EFTimegroup } from \"../elements/EFTimegroup.js\";\nimport type { RenderToVideoOptions } from \"./renderTimegroupToVideo.types.js\";\nimport type { ContentReadyMode } from \"./renderTimegroupToCanvas.types.js\";\nimport { resetRenderState, waitForVideoContent } from \"./renderTimegroupToCanvas.js\";\nimport { captureTimelineToDataUri } from \"./rendering/serializeTimelineDirect.js\";\nimport { renderToImageNative } from \"./rendering/renderToImageNative.js\";\nimport { isNativeCanvasApiAvailable } from \"./previewSettings.js\";\nimport { createPreviewContainer } from \"./previewTypes.js\";\nimport { RenderContext } from \"./RenderContext.js\";\nimport { EFMotionBlur } from \"../elements/EFMotionBlur.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n// Re-export types from type-only module (zero side effects)\nexport type { RenderProgress, RenderToVideoOptions } from \"./renderTimegroupToVideo.types.js\";\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nexport class NoSupportedAudioCodecError extends Error {\n constructor(requestedCodecs: AudioCodec[], availableCodecs: AudioCodec[]) {\n super(\n `No supported audio codec found. Requested: [${requestedCodecs.join(\", \")}], ` +\n `Available: [${availableCodecs.length > 0 ? availableCodecs.join(\", \") : \"none\"}]`,\n );\n this.name = \"NoSupportedAudioCodecError\";\n }\n}\n\nexport class RenderCancelledError extends Error {\n constructor() {\n super(\"Render cancelled\");\n this.name = \"RenderCancelledError\";\n }\n}\n\n// ============================================================================\n// Configuration\n// ============================================================================\n\ninterface ResolvedConfig {\n fps: number;\n codec: \"avc\" | \"hevc\" | \"vp9\" | \"av1\" | \"vp8\";\n bitrate: number;\n filename: string;\n scale: number;\n keyFrameInterval: number;\n startMs: number;\n endMs: number;\n renderDurationMs: number;\n width: number;\n height: number;\n videoWidth: number;\n videoHeight: number;\n totalFrames: number;\n frameDurationMs: number;\n frameDurationS: number;\n streaming: boolean;\n includeAudio: boolean;\n audioBitrate: number;\n contentReadyMode: ContentReadyMode;\n blockingTimeoutMs: number;\n returnBuffer: boolean;\n preferredAudioCodecs: AudioCodec[];\n benchmarkMode: boolean;\n progressPreviewInterval: number;\n canvasMode: \"native\" | \"foreignObject\";\n}\n\nfunction resolveConfig(timegroup: EFTimegroup, options: RenderToVideoOptions = {}): ResolvedConfig {\n const fps = options.fps ?? timegroup.effectiveFps ?? 30;\n const codec = options.codec ?? \"avc\";\n const bitrate = options.bitrate ?? 8_000_000;\n const filename = options.filename ?? \"timegroup-video.mp4\";\n const scale = options.scale ?? 1;\n const keyFrameInterval = options.keyFrameInterval ?? 2;\n const streaming = options.streaming ?? true;\n const includeAudio = options.includeAudio ?? true;\n const audioBitrate = options.audioBitrate ?? 128_000;\n const contentReadyMode = options.contentReadyMode ?? \"blocking\";\n const blockingTimeoutMs = options.blockingTimeoutMs ?? 5000;\n const returnBuffer = options.returnBuffer ?? false;\n const preferredAudioCodecs = options.preferredAudioCodecs ?? [\"aac\", \"opus\"];\n const benchmarkMode = options.benchmarkMode ?? false;\n // Preview generation now uses canvas reference (no encoding) - cheap to enable!\n // Defaults to 60 frames (every 2 seconds at 30fps). Set to 0 to disable.\n const progressPreviewInterval = options.progressPreviewInterval ?? 60;\n\n const totalDurationMs = timegroup.durationMs;\n if (!totalDurationMs || totalDurationMs <= 0) {\n throw new Error(\"Timegroup has no duration\");\n }\n\n const startMs = Math.max(0, options.fromMs ?? 0);\n const endMs =\n options.toMs !== undefined ? Math.min(options.toMs, totalDurationMs) : totalDurationMs;\n const renderDurationMs = endMs - startMs;\n\n if (renderDurationMs <= 0) {\n throw new Error(`Invalid render range: from ${startMs}ms to ${endMs}ms`);\n }\n\n // Force layout reflow before reading dimensions\n void timegroup.offsetHeight;\n\n // Try multiple sources for dimensions (offsetWidth can be 0 in headless browsers)\n let timegroupWidth = timegroup.offsetWidth;\n let timegroupHeight = timegroup.offsetHeight;\n\n if (!timegroupWidth || !timegroupHeight) {\n const rect = timegroup.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) {\n timegroupWidth = rect.width;\n timegroupHeight = rect.height;\n }\n }\n\n if (!timegroupWidth || !timegroupHeight) {\n const computed = getComputedStyle(timegroup);\n const cw = parseFloat(computed.width);\n const ch = parseFloat(computed.height);\n if (cw > 0 && ch > 0) {\n timegroupWidth = cw;\n timegroupHeight = ch;\n }\n }\n\n if (!timegroupWidth || !timegroupHeight) {\n throw new Error(\n `Timegroup has no dimensions (${timegroupWidth}x${timegroupHeight}). ` +\n `Ensure the timegroup element is in the document and has explicit width/height styles ` +\n `(e.g., class=\"w-[1920px] h-[1080px]\")`,\n );\n }\n const width = Math.floor(timegroupWidth * scale);\n const height = Math.floor(timegroupHeight * scale);\n\n const videoWidth = width % 2 === 0 ? width : width - 1;\n const videoHeight = height % 2 === 0 ? height : height - 1;\n\n const frameDurationMs = 1000 / fps;\n const totalFrames = Math.ceil(renderDurationMs / frameDurationMs);\n const frameDurationS = frameDurationMs / 1000;\n\n // Determine effective canvas mode:\n // 1. If explicitly specified, use that (with fallback if native not available)\n // 2. If not specified, default to foreignObject for compatibility\n const canvasMode = (() => {\n const requested = options.canvasMode;\n if (!requested) return \"foreignObject\";\n if (requested === \"native\" && !isNativeCanvasApiAvailable()) {\n logger.debug(\n \"[renderTimegroupToVideo] Native canvas mode requested but not available, falling back to foreignObject\",\n );\n return \"foreignObject\";\n }\n return requested;\n })();\n\n return {\n fps,\n codec,\n bitrate,\n filename,\n scale,\n keyFrameInterval,\n startMs,\n endMs,\n renderDurationMs,\n width,\n height,\n videoWidth,\n videoHeight,\n totalFrames,\n frameDurationMs,\n frameDurationS,\n streaming,\n includeAudio,\n audioBitrate,\n contentReadyMode,\n blockingTimeoutMs,\n returnBuffer,\n preferredAudioCodecs,\n benchmarkMode,\n progressPreviewInterval,\n canvasMode,\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction isFileSystemAccessSupported(): boolean {\n return typeof window !== \"undefined\" && \"showSaveFilePicker\" in window;\n}\n\nasync function getFileWritableStream(filename: string): Promise<{\n writable: WritableStream<Uint8Array>;\n close: () => Promise<void>;\n} | null> {\n if (!isFileSystemAccessSupported()) {\n return null;\n }\n\n try {\n const fileHandle = await (window as any).showSaveFilePicker({\n suggestedName: filename,\n types: [{ description: \"MP4 Video\", accept: { \"video/mp4\": [\".mp4\"] } }],\n });\n const writable = await fileHandle.createWritable();\n return {\n writable,\n close: async () => {\n await writable.close();\n },\n };\n } catch (e) {\n if ((e as Error).name !== \"AbortError\") {\n logger.warn(\"[renderToVideo] File System Access failed:\", e);\n }\n return null;\n }\n}\n\nasync function selectAudioCodec(\n preferredCodecs: AudioCodec[],\n encodingOptions: {\n numberOfChannels: number;\n sampleRate: number;\n bitrate: number;\n },\n): Promise<AudioCodec> {\n for (const codec of preferredCodecs) {\n try {\n const isSupported = await canEncodeAudio(codec, encodingOptions);\n if (isSupported) return codec;\n } catch (e) {\n logger.warn(`[selectAudioCodec] Check failed for ${codec}:`, e);\n }\n }\n const availableCodecs = await getEncodableAudioCodecs(undefined, encodingOptions);\n throw new NoSupportedAudioCodecError(preferredCodecs, availableCodecs);\n}\n\nfunction downloadBlob(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport async function getSupportedAudioCodecs(options?: {\n numberOfChannels?: number;\n sampleRate?: number;\n bitrate?: number;\n}): Promise<AudioCodec[]> {\n const { numberOfChannels = 2, sampleRate = 48000, bitrate = 128000 } = options ?? {};\n return getEncodableAudioCodecs(undefined, {\n numberOfChannels,\n sampleRate,\n bitrate,\n });\n}\n\n/**\n * Renders a timegroup to an MP4 video file.\n *\n * Uses the EXACT same code path as thumbnail generation (captureFromClone).\n * This ensures consistency - if thumbnails work, video export works.\n */\nexport async function renderTimegroupToVideo(\n timegroup: EFTimegroup,\n options: RenderToVideoOptions = {},\n): Promise<Uint8Array | undefined> {\n const config = resolveConfig(timegroup, options);\n const { signal, onProgress } = options;\n\n const checkCancelled = () => {\n if (signal?.aborted) throw new RenderCancelledError();\n };\n\n resetRenderState();\n\n // =========================================================================\n // Create render clone - EXACT same as captureBatch in EFTimegroup\n // =========================================================================\n const {\n clone: renderClone,\n container: cloneContainer,\n cleanup: cleanupRenderClone,\n } = await timegroup.createRenderClone();\n\n // Build timestamps array for frame loop\n const timestamps: number[] = [];\n for (let i = 0; i < config.totalFrames; i++) {\n timestamps.push(config.startMs + i * config.frameDurationMs);\n }\n\n // =========================================================================\n // Set up video encoding\n // =========================================================================\n let output: Output | null = null;\n let videoSource: CanvasSource | null = null;\n let audioSource: AudioBufferSource | null = null;\n let target: BufferTarget | StreamTarget | null = null;\n let fileStream: {\n writable: WritableStream<Uint8Array>;\n close: () => Promise<void>;\n } | null = null;\n let useStreaming = false;\n let encodingCanvas: OffscreenCanvas | null = null;\n let encodingCtx: OffscreenCanvasRenderingContext2D | null = null;\n\n if (!config.benchmarkMode) {\n // Check for custom writable stream first (for programmatic streaming)\n if (options.customWritableStream) {\n target = new StreamTarget(options.customWritableStream as any);\n output = new Output({\n format: new Mp4OutputFormat({ fastStart: \"fragmented\" }),\n target,\n });\n useStreaming = true;\n } else if (config.streaming) {\n fileStream = await getFileWritableStream(config.filename);\n useStreaming = fileStream !== null;\n\n if (useStreaming && fileStream) {\n target = new StreamTarget(fileStream.writable as any);\n output = new Output({\n format: new Mp4OutputFormat({ fastStart: \"fragmented\" }),\n target,\n });\n }\n }\n\n if (!target) {\n target = new BufferTarget();\n output = new Output({ format: new Mp4OutputFormat(), target });\n }\n\n encodingCanvas = new OffscreenCanvas(config.videoWidth, config.videoHeight);\n encodingCtx = encodingCanvas.getContext(\"2d\");\n if (!encodingCtx) {\n cleanupRenderClone();\n throw new Error(\"Failed to get encoding canvas context\");\n }\n\n if (!output) {\n throw new Error(\"Output not initialized\");\n }\n\n const videoConfig: VideoEncodingConfig = {\n codec: config.codec,\n bitrate: config.bitrate,\n keyFrameInterval: config.keyFrameInterval,\n };\n videoSource = new CanvasSource(encodingCanvas, videoConfig);\n output.addVideoTrack(videoSource);\n\n if (config.includeAudio) {\n const selectedCodec = await selectAudioCodec(config.preferredAudioCodecs, {\n numberOfChannels: 2,\n sampleRate: 48000,\n bitrate: config.audioBitrate,\n });\n const audioConfig: AudioEncodingConfig = {\n codec: selectedCodec,\n bitrate: config.audioBitrate,\n };\n audioSource = new AudioBufferSource(audioConfig);\n output.addAudioTrack(audioSource);\n }\n\n await output.start();\n }\n\n // =========================================================================\n // Setup for per-frame passive structure rebuilding (like live preview)\n // =========================================================================\n // Create RenderContext for caching across all frames\n const renderContext = new RenderContext();\n\n // Create preview container with proper styling (reusable, content rebuilt each frame)\n // Use unscaled dimensions for the preview container (which holds the full-size clone)\n const containerWidth = timegroup.offsetWidth || 1920;\n const containerHeight = timegroup.offsetHeight || 1080;\n const previewContainer = createPreviewContainer({\n width: containerWidth,\n height: containerHeight,\n background: getComputedStyle(timegroup).background || \"#000\",\n });\n\n // Setup for direct serialization\n logger.debug(`[renderTimegroupToVideo] Using direct timeline serialization`);\n\n // Attach clone container (keeps renderClone in its React-managed DOM position)\n previewContainer.appendChild(cloneContainer);\n\n // Add ef-render-clone-container class for CSS selectors and debugging\n previewContainer.classList.add(\"ef-render-clone-container\");\n\n // CRITICAL: Attach container to document so getComputedStyle returns actual values\n // Without this, all computed styles are empty strings!\n // Hide the container OFF-SCREEN but do NOT use visibility:hidden because:\n // 1. visibility:hidden is inherited by all children\n // 2. seekForRender checks getComputedStyle().visibility and skips \"hidden\" subtrees\n // 3. This would cause FrameController to skip rendering all nested content\n previewContainer.style.cssText +=\n \";position:fixed;left:-99999px;top:-99999px;pointer-events:none;\";\n document.body.appendChild(previewContainer);\n\n // Force layout/reflow so getComputedStyle returns correct values\n void renderClone.offsetHeight;\n logger.debug(\n `[renderTimegroupToVideo] Attached previewContainer to document.body (off-screen) for style computation`,\n );\n\n // =========================================================================\n // Frame loop - DEEP PIPELINE: overlap encode + render + prepare\n // =========================================================================\n const renderStartTime = performance.now();\n let lastRenderedAudioEndMs = config.startMs;\n const audioChunkDurationMs = 2000;\n\n // Reusable thumbnail canvas for preview (no encoding, just draw to canvas)\n let thumbCanvas: HTMLCanvasElement | null = null;\n let thumbCtx: CanvasRenderingContext2D | null = null;\n if (onProgress && config.progressPreviewInterval > 0) {\n const previewWidth = 160;\n const previewHeight = Math.round(previewWidth * (config.videoHeight / config.videoWidth));\n thumbCanvas = document.createElement(\"canvas\");\n thumbCanvas.width = previewWidth;\n thumbCanvas.height = previewHeight;\n thumbCtx = thumbCanvas.getContext(\"2d\");\n }\n\n try {\n // ========================================================================\n // OVERLAPPED PIPELINE: image loading runs parallel with seek+serialize\n // ========================================================================\n // The clone can only seek one frame at a time, and serialization must\n // capture the DOM before the next seek. But image loading (data URI →\n // Image) is independent of the clone and runs in the background.\n //\n // Per-frame timeline:\n // [seek(N)] → [serialize(N)] → [image.load(N) in background...]\n // └─ [seek(N+1)] → [serialize(N+1)] → ...\n // └─ encode(N) when image resolves\n\n type PendingFrame = {\n frameIndex: number;\n timeMs: number;\n timestampS: number;\n resolved: HTMLImageElement | null;\n promise: Promise<HTMLImageElement>;\n };\n\n const MAX_AHEAD = 2;\n const pendingFrames: PendingFrame[] = [];\n let nextSeekFrame = 0;\n let encodedFrames = 0;\n\n EFMotionBlur.renderQuality = \"render\";\n while (encodedFrames < config.totalFrames) {\n checkCancelled();\n\n // ==================================================================\n // PHASE 1: Fill pipeline — seek+serialize ahead while images load\n // ==================================================================\n while (nextSeekFrame < config.totalFrames && pendingFrames.length < MAX_AHEAD) {\n const fi = nextSeekFrame;\n const timeMs = timestamps[fi]!;\n const timestampS = (fi * config.frameDurationMs) / 1000;\n\n await renderClone.seekForRender(timeMs);\n\n const entry: PendingFrame = {\n frameIndex: fi,\n timeMs,\n timestampS,\n resolved: null,\n promise: null!,\n };\n\n // Wait for video content if using blocking mode\n if (config.contentReadyMode === \"blocking\") {\n await waitForVideoContent(renderClone, timeMs, config.blockingTimeoutMs);\n }\n\n if (config.canvasMode === \"native\") {\n const canvas = await renderToImageNative(renderClone, config.width, config.height, {\n skipDprScaling: true,\n });\n entry.resolved = canvas as any as HTMLImageElement;\n entry.promise = Promise.resolve(entry.resolved);\n } else {\n // Synchronous capture: walks DOM + snapshots canvas pixels.\n // Returns immediately — clone is free for next seek.\n // Encoding (canvas→base64, SVG assembly) and image loading\n // all resolve in the background.\n const dataUriPromise = captureTimelineToDataUri(\n renderClone,\n config.width,\n config.height,\n {\n renderContext,\n canvasScale: config.scale,\n timeMs,\n },\n );\n\n entry.promise = dataUriPromise.then((dataUri) => {\n return new Promise<HTMLImageElement>((resolve, reject) => {\n const image = new Image();\n image.onload = () => {\n entry.resolved = image;\n resolve(image);\n };\n image.onerror = (e) => {\n console.error(`[Render] frame ${fi} image load error:`, e);\n reject(new Error(`Failed to load image from data URI`));\n };\n image.src = dataUri;\n });\n });\n }\n\n pendingFrames.push(entry);\n nextSeekFrame++;\n }\n\n // ==================================================================\n // PHASE 2: Encode next frame in order (await if not yet loaded)\n // ==================================================================\n const head = pendingFrames.shift()!;\n const preloaded = head.resolved !== null;\n let image: HTMLImageElement;\n if (preloaded) {\n image = head.resolved!;\n } else {\n image = await head.promise;\n }\n\n if (audioSource && head.timeMs >= lastRenderedAudioEndMs + audioChunkDurationMs) {\n const chunkEndMs = Math.min(head.timeMs + audioChunkDurationMs, config.endMs);\n try {\n const audioBuffer = await timegroup.renderAudio(\n lastRenderedAudioEndMs,\n chunkEndMs,\n signal,\n );\n if (audioBuffer && audioBuffer.length > 0) {\n await audioSource.add(audioBuffer);\n }\n } catch (_e) {\n /* Audio render failures are non-fatal */\n }\n lastRenderedAudioEndMs = chunkEndMs;\n }\n\n if (videoSource && output && encodingCtx) {\n encodingCtx.drawImage(\n image,\n 0,\n 0,\n image.width,\n image.height,\n 0,\n 0,\n config.videoWidth,\n config.videoHeight,\n );\n await videoSource.add(head.timestampS, config.frameDurationS);\n }\n\n // ==================================================================\n // Progress reporting\n // ==================================================================\n encodedFrames++;\n const currentFrame = encodedFrames;\n const progress = currentFrame / config.totalFrames;\n const renderedMs = currentFrame * config.frameDurationMs;\n const elapsedMs = performance.now() - renderStartTime;\n const msPerFrame = elapsedMs / currentFrame;\n const remainingFrames = config.totalFrames - currentFrame;\n const estimatedRemainingMs = remainingFrames * msPerFrame;\n const speedMultiplier = renderedMs / elapsedMs;\n\n if (thumbCanvas && thumbCtx && head.frameIndex % config.progressPreviewInterval === 0) {\n thumbCtx.drawImage(image, 0, 0, thumbCanvas.width, thumbCanvas.height);\n }\n\n onProgress?.({\n progress,\n currentFrame,\n totalFrames: config.totalFrames,\n renderedMs,\n totalDurationMs: config.renderDurationMs,\n elapsedMs,\n estimatedRemainingMs,\n speedMultiplier,\n framePreviewCanvas: thumbCanvas || undefined,\n });\n }\n\n // Render remaining audio\n if (audioSource && lastRenderedAudioEndMs < config.endMs) {\n try {\n const audioBuffer = await timegroup.renderAudio(\n lastRenderedAudioEndMs,\n config.endMs,\n signal,\n );\n if (audioBuffer && audioBuffer.length > 0) {\n await audioSource.add(audioBuffer);\n }\n } catch (_e) {\n /* Audio render failures are non-fatal */\n }\n }\n\n if (config.benchmarkMode) {\n return undefined;\n }\n\n await output!.finalize();\n\n if (typeof __EF_TELEMETRY_ENABLED__ !== \"undefined\" && __EF_TELEMETRY_ENABLED__) {\n const elapsedMs = Math.round(performance.now() - renderStartTime);\n const endpoint = options.telemetryEndpoint ?? \"https://editframe.com\";\n const efMediaCount = timegroup.querySelectorAll(\"ef-video,ef-audio\").length;\n const efImageCount = timegroup.querySelectorAll(\"ef-image\").length;\n const efCaptionsCount = timegroup.querySelectorAll(\"ef-captions\").length;\n const efTextCount = timegroup.querySelectorAll(\"ef-text\").length;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (options.telemetryToken) {\n headers[\"Authorization\"] = `Bearer ${options.telemetryToken}`;\n }\n fetch(`${endpoint}/api/v1/telemetry`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n event_type: \"render\",\n render_path: \"client\",\n duration_ms: elapsedMs,\n width: config.videoWidth,\n height: config.videoHeight,\n fps: config.fps,\n feature_usage: {\n efMediaCount,\n efImageCount,\n efCaptionsCount,\n efTextCount,\n },\n }),\n keepalive: true,\n }).catch(() => {\n // Telemetry errors must never surface to users.\n });\n }\n\n if (useStreaming) {\n // Streaming mode: chunks already sent via customWritableStream or file stream\n return undefined;\n } else {\n const bufferTarget = target as BufferTarget;\n const videoBuffer = bufferTarget.buffer;\n if (!videoBuffer) {\n throw new Error(\"Video encoding failed: no buffer produced\");\n }\n\n if (config.returnBuffer) {\n return new Uint8Array(videoBuffer);\n }\n\n const videoBlob = new Blob([videoBuffer], { type: \"video/mp4\" });\n downloadBlob(videoBlob, config.filename);\n return undefined;\n }\n } finally {\n EFMotionBlur.renderQuality = \"preview\";\n renderContext.dispose();\n if (previewContainer.parentNode) {\n previewContainer.parentNode.removeChild(previewContainer);\n }\n cleanupRenderClone();\n }\n}\n\nexport { QUALITY_HIGH };\nexport type { AudioCodec };\n"],"mappings":"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"}
1
+ {"version":3,"file":"renderTimegroupToVideo.js","names":[],"sources":["../../src/preview/renderTimegroupToVideo.ts"],"mappings":"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"}
@@ -1,8 +1,17 @@
1
1
  import { logger } from "./logger.js";
2
2
  import { NoSupportedAudioCodecError, RenderCancelledError } from "./renderTimegroupToVideo.js";
3
3
  import { AudioBufferSource, BufferTarget, CanvasSource, Mp4OutputFormat, Output, StreamTarget, canEncodeAudio, getEncodableAudioCodecs } from "mediabunny";
4
-
5
4
  //#region src/preview/renderVideoToVideo.ts
5
+ /**
6
+ * Direct video-to-video rendering — fast path for single video elements.
7
+ *
8
+ * Bypasses the full DOM serialization pipeline (foreignObject/native canvas)
9
+ * by decoding frames directly from the media engine and re-encoding to MP4.
10
+ *
11
+ * Supports CSS effects via canvas 2D context:
12
+ * - filter (ctx.filter)
13
+ * - opacity (ctx.globalAlpha)
14
+ */
6
15
  async function resolveVideoConfig(video, options = {}) {
7
16
  const fps = options.fps ?? 30;
8
17
  const codec = options.codec ?? "avc";
@@ -279,7 +288,7 @@ async function renderVideoToVideo(video, options = {}) {
279
288
  pc?.resumeSelfRender();
280
289
  }
281
290
  }
282
-
283
291
  //#endregion
284
292
  export { renderVideoToVideo };
293
+
285
294
  //# sourceMappingURL=renderVideoToVideo.js.map