ts-video-player 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +438 -0
  3. package/dist/cdn.d.ts +10 -0
  4. package/dist/cdn.d.ts.map +1 -0
  5. package/dist/cdn.min.js +1046 -0
  6. package/dist/cdn.min.js.map +54 -0
  7. package/dist/cdn.test.d.ts +2 -0
  8. package/dist/cdn.test.d.ts.map +1 -0
  9. package/dist/chunk-36x4yhjn.js +765 -0
  10. package/dist/chunk-36x4yhjn.js.map +12 -0
  11. package/dist/chunk-eajts2jv.js +4243 -0
  12. package/dist/chunk-eajts2jv.js.map +42 -0
  13. package/dist/chunk-z1ehbz9f.js +380 -0
  14. package/dist/chunk-z1ehbz9f.js.map +19 -0
  15. package/dist/config.d.ts +9 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/core/audio-gain.d.ts +67 -0
  18. package/dist/core/audio-gain.d.ts.map +1 -0
  19. package/dist/core/caption-styles.d.ts +121 -0
  20. package/dist/core/caption-styles.d.ts.map +1 -0
  21. package/dist/core/chapters.d.ts +150 -0
  22. package/dist/core/chapters.d.ts.map +1 -0
  23. package/dist/core/error-overlay.d.ts +71 -0
  24. package/dist/core/error-overlay.d.ts.map +1 -0
  25. package/dist/core/events.d.ts +119 -0
  26. package/dist/core/events.d.ts.map +1 -0
  27. package/dist/core/features.d.ts +64 -0
  28. package/dist/core/features.d.ts.map +1 -0
  29. package/dist/core/i18n.d.ts +132 -0
  30. package/dist/core/i18n.d.ts.map +1 -0
  31. package/dist/core/index.d.ts +37 -0
  32. package/dist/core/index.d.ts.map +1 -0
  33. package/dist/core/live.d.ts +130 -0
  34. package/dist/core/live.d.ts.map +1 -0
  35. package/dist/core/media-session.d.ts +38 -0
  36. package/dist/core/media-session.d.ts.map +1 -0
  37. package/dist/core/orientation.d.ts +22 -0
  38. package/dist/core/orientation.d.ts.map +1 -0
  39. package/dist/core/popover.d.ts +42 -0
  40. package/dist/core/popover.d.ts.map +1 -0
  41. package/dist/core/remote-playback.d.ts +195 -0
  42. package/dist/core/remote-playback.d.ts.map +1 -0
  43. package/dist/core/settings-menu.d.ts +132 -0
  44. package/dist/core/settings-menu.d.ts.map +1 -0
  45. package/dist/core/spinner.d.ts +67 -0
  46. package/dist/core/spinner.d.ts.map +1 -0
  47. package/dist/core/state.d.ts +142 -0
  48. package/dist/core/state.d.ts.map +1 -0
  49. package/dist/core/text-tracks.d.ts +162 -0
  50. package/dist/core/text-tracks.d.ts.map +1 -0
  51. package/dist/core/themes.d.ts +213 -0
  52. package/dist/core/themes.d.ts.map +1 -0
  53. package/dist/core/thumbnails.d.ts +124 -0
  54. package/dist/core/thumbnails.d.ts.map +1 -0
  55. package/dist/core/tooltips.d.ts +100 -0
  56. package/dist/core/tooltips.d.ts.map +1 -0
  57. package/dist/elements/base.d.ts +3 -0
  58. package/dist/elements/base.d.ts.map +1 -0
  59. package/dist/elements/index.d.ts +33 -0
  60. package/dist/elements/index.d.ts.map +1 -0
  61. package/dist/elements/index.js +55 -0
  62. package/dist/elements/index.js.map +9 -0
  63. package/dist/elements/media-airplay-button.d.ts +13 -0
  64. package/dist/elements/media-airplay-button.d.ts.map +1 -0
  65. package/dist/elements/media-error-display.d.ts +13 -0
  66. package/dist/elements/media-error-display.d.ts.map +1 -0
  67. package/dist/elements/media-fullscreen-button.d.ts +13 -0
  68. package/dist/elements/media-fullscreen-button.d.ts.map +1 -0
  69. package/dist/elements/media-live-button.d.ts +13 -0
  70. package/dist/elements/media-live-button.d.ts.map +1 -0
  71. package/dist/elements/media-mute-button.d.ts +13 -0
  72. package/dist/elements/media-mute-button.d.ts.map +1 -0
  73. package/dist/elements/media-pip-button.d.ts +13 -0
  74. package/dist/elements/media-pip-button.d.ts.map +1 -0
  75. package/dist/elements/media-play-button.d.ts +14 -0
  76. package/dist/elements/media-play-button.d.ts.map +1 -0
  77. package/dist/elements/media-playback-rate-button.d.ts +10 -0
  78. package/dist/elements/media-playback-rate-button.d.ts.map +1 -0
  79. package/dist/elements/media-preview-time.d.ts +18 -0
  80. package/dist/elements/media-preview-time.d.ts.map +1 -0
  81. package/dist/elements/media-progress-bar.d.ts +16 -0
  82. package/dist/elements/media-progress-bar.d.ts.map +1 -0
  83. package/dist/elements/media-remote-playback-button.d.ts +16 -0
  84. package/dist/elements/media-remote-playback-button.d.ts.map +1 -0
  85. package/dist/elements/media-seek-button.d.ts +9 -0
  86. package/dist/elements/media-seek-button.d.ts.map +1 -0
  87. package/dist/elements/media-settings-menu.d.ts +32 -0
  88. package/dist/elements/media-settings-menu.d.ts.map +1 -0
  89. package/dist/elements/media-time-display.d.ts +21 -0
  90. package/dist/elements/media-time-display.d.ts.map +1 -0
  91. package/dist/elements/media-time-group.d.ts +22 -0
  92. package/dist/elements/media-time-group.d.ts.map +1 -0
  93. package/dist/elements/media-time-separator.d.ts +13 -0
  94. package/dist/elements/media-time-separator.d.ts.map +1 -0
  95. package/dist/elements/media-volume-slider.d.ts +16 -0
  96. package/dist/elements/media-volume-slider.d.ts.map +1 -0
  97. package/dist/elements/utils.d.ts +27 -0
  98. package/dist/elements/utils.d.ts.map +1 -0
  99. package/dist/elements/video-player.d.ts +23 -0
  100. package/dist/elements/video-player.d.ts.map +1 -0
  101. package/dist/elements/video-skin.d.ts +23 -0
  102. package/dist/elements/video-skin.d.ts.map +1 -0
  103. package/dist/features/captions.d.ts +8 -0
  104. package/dist/features/captions.d.ts.map +1 -0
  105. package/dist/features/create-player.d.ts +45 -0
  106. package/dist/features/create-player.d.ts.map +1 -0
  107. package/dist/features/fullscreen.d.ts +8 -0
  108. package/dist/features/fullscreen.d.ts.map +1 -0
  109. package/dist/features/gestures.d.ts +8 -0
  110. package/dist/features/gestures.d.ts.map +1 -0
  111. package/dist/features/index.d.ts +26 -0
  112. package/dist/features/index.d.ts.map +1 -0
  113. package/dist/features/index.js +31 -0
  114. package/dist/features/index.js.map +9 -0
  115. package/dist/features/keyboard.d.ts +8 -0
  116. package/dist/features/keyboard.d.ts.map +1 -0
  117. package/dist/features/pip.d.ts +8 -0
  118. package/dist/features/pip.d.ts.map +1 -0
  119. package/dist/features/playback.d.ts +8 -0
  120. package/dist/features/playback.d.ts.map +1 -0
  121. package/dist/features/quality.d.ts +8 -0
  122. package/dist/features/quality.d.ts.map +1 -0
  123. package/dist/features/types.d.ts +26 -0
  124. package/dist/features/types.d.ts.map +1 -0
  125. package/dist/features/volume.d.ts +8 -0
  126. package/dist/features/volume.d.ts.map +1 -0
  127. package/dist/index.d.ts +84 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +8149 -0
  130. package/dist/index.js.map +31 -0
  131. package/dist/layouts/index.d.ts +58 -0
  132. package/dist/layouts/index.d.ts.map +1 -0
  133. package/dist/player.d.ts +90 -0
  134. package/dist/player.d.ts.map +1 -0
  135. package/dist/plugins/ads.d.ts +311 -0
  136. package/dist/plugins/ads.d.ts.map +1 -0
  137. package/dist/plugins/analytics.d.ts +203 -0
  138. package/dist/plugins/analytics.d.ts.map +1 -0
  139. package/dist/plugins/end-screen.d.ts +184 -0
  140. package/dist/plugins/end-screen.d.ts.map +1 -0
  141. package/dist/plugins/index.d.ts +13 -0
  142. package/dist/plugins/index.d.ts.map +1 -0
  143. package/dist/plugins/index.js +20 -0
  144. package/dist/plugins/index.js.map +9 -0
  145. package/dist/plugins/skip-segments.d.ts +159 -0
  146. package/dist/plugins/skip-segments.d.ts.map +1 -0
  147. package/dist/plugins/watermark.d.ts +157 -0
  148. package/dist/plugins/watermark.d.ts.map +1 -0
  149. package/dist/providers/base.d.ts +56 -0
  150. package/dist/providers/base.d.ts.map +1 -0
  151. package/dist/providers/dash.d.ts +94 -0
  152. package/dist/providers/dash.d.ts.map +1 -0
  153. package/dist/providers/hls.d.ts +182 -0
  154. package/dist/providers/hls.d.ts.map +1 -0
  155. package/dist/providers/html5.d.ts +64 -0
  156. package/dist/providers/html5.d.ts.map +1 -0
  157. package/dist/providers/index.d.ts +41 -0
  158. package/dist/providers/index.d.ts.map +1 -0
  159. package/dist/providers/vimeo.d.ts +157 -0
  160. package/dist/providers/vimeo.d.ts.map +1 -0
  161. package/dist/providers/youtube.d.ts +134 -0
  162. package/dist/providers/youtube.d.ts.map +1 -0
  163. package/dist/stx/index.d.ts +59 -0
  164. package/dist/stx/index.d.ts.map +1 -0
  165. package/dist/stx/index.js +480 -0
  166. package/dist/stx/index.js.map +11 -0
  167. package/dist/types.d.ts +724 -0
  168. package/dist/types.d.ts.map +1 -0
  169. package/dist/ui/components.d.ts +121 -0
  170. package/dist/ui/components.d.ts.map +1 -0
  171. package/dist/ui/index.d.ts +9 -0
  172. package/dist/ui/index.d.ts.map +1 -0
  173. package/dist/ui/index.js +16 -0
  174. package/dist/ui/index.js.map +9 -0
  175. package/package.json +109 -0
  176. package/src/cdn.test.ts +10 -0
  177. package/src/cdn.ts +60 -0
  178. package/src/config.ts +25 -0
  179. package/src/core/audio-gain.ts +171 -0
  180. package/src/core/caption-styles.ts +568 -0
  181. package/src/core/chapters.ts +551 -0
  182. package/src/core/error-overlay.ts +354 -0
  183. package/src/core/events.ts +552 -0
  184. package/src/core/features.ts +287 -0
  185. package/src/core/i18n.ts +590 -0
  186. package/src/core/index.ts +249 -0
  187. package/src/core/live.ts +472 -0
  188. package/src/core/media-session.ts +137 -0
  189. package/src/core/orientation.ts +57 -0
  190. package/src/core/popover.ts +143 -0
  191. package/src/core/remote-playback.ts +661 -0
  192. package/src/core/settings-menu.ts +630 -0
  193. package/src/core/spinner.ts +310 -0
  194. package/src/core/state.ts +476 -0
  195. package/src/core/text-tracks.ts +599 -0
  196. package/src/core/themes.ts +607 -0
  197. package/src/core/thumbnails.ts +457 -0
  198. package/src/core/tooltips.ts +370 -0
  199. package/src/elements/base.ts +2 -0
  200. package/src/elements/index.ts +82 -0
  201. package/src/elements/media-airplay-button.ts +78 -0
  202. package/src/elements/media-error-display.ts +47 -0
  203. package/src/elements/media-fullscreen-button.ts +72 -0
  204. package/src/elements/media-live-button.ts +65 -0
  205. package/src/elements/media-mute-button.ts +69 -0
  206. package/src/elements/media-pip-button.ts +66 -0
  207. package/src/elements/media-play-button.ts +69 -0
  208. package/src/elements/media-playback-rate-button.ts +59 -0
  209. package/src/elements/media-preview-time.ts +75 -0
  210. package/src/elements/media-progress-bar.ts +200 -0
  211. package/src/elements/media-remote-playback-button.ts +108 -0
  212. package/src/elements/media-seek-button.ts +50 -0
  213. package/src/elements/media-settings-menu.ts +302 -0
  214. package/src/elements/media-time-display.ts +99 -0
  215. package/src/elements/media-time-group.ts +41 -0
  216. package/src/elements/media-time-separator.ts +35 -0
  217. package/src/elements/media-volume-slider.ts +140 -0
  218. package/src/elements/utils.ts +82 -0
  219. package/src/elements/video-player.ts +175 -0
  220. package/src/elements/video-skin.ts +127 -0
  221. package/src/features/captions.ts +56 -0
  222. package/src/features/create-player.ts +91 -0
  223. package/src/features/fullscreen.ts +44 -0
  224. package/src/features/gestures.ts +44 -0
  225. package/src/features/index.ts +44 -0
  226. package/src/features/keyboard.ts +89 -0
  227. package/src/features/pip.ts +47 -0
  228. package/src/features/playback.ts +68 -0
  229. package/src/features/quality.ts +19 -0
  230. package/src/features/types.ts +28 -0
  231. package/src/features/volume.ts +46 -0
  232. package/src/index.ts +635 -0
  233. package/src/layouts/index.ts +672 -0
  234. package/src/player.ts +821 -0
  235. package/src/plugins/ads.ts +1045 -0
  236. package/src/plugins/analytics.ts +673 -0
  237. package/src/plugins/end-screen.ts +793 -0
  238. package/src/plugins/index.ts +61 -0
  239. package/src/plugins/skip-segments.ts +537 -0
  240. package/src/plugins/watermark.ts +537 -0
  241. package/src/providers/base.ts +197 -0
  242. package/src/providers/dash.ts +588 -0
  243. package/src/providers/hls.ts +624 -0
  244. package/src/providers/html5.ts +473 -0
  245. package/src/providers/index.ts +97 -0
  246. package/src/providers/vimeo.ts +533 -0
  247. package/src/providers/youtube.ts +542 -0
  248. package/src/stx/index.ts +606 -0
  249. package/src/types.ts +874 -0
  250. package/src/ui/components.ts +910 -0
  251. package/src/ui/index.ts +29 -0
@@ -0,0 +1,42 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/media-session.ts", "../src/core/orientation.ts", "../src/providers/base.ts", "../src/providers/html5.ts", "../src/providers/youtube.ts", "../src/providers/vimeo.ts", "../src/providers/hls.ts", "../src/providers/dash.ts", "../src/providers/index.ts", "../src/player.ts", "../src/elements/base.ts", "../src/elements/video-player.ts", "../src/elements/utils.ts", "../src/elements/video-skin.ts", "../src/elements/media-play-button.ts", "../src/elements/media-mute-button.ts", "../src/elements/media-fullscreen-button.ts", "../src/elements/media-pip-button.ts", "../src/elements/media-time-display.ts", "../src/elements/media-time-group.ts", "../src/elements/media-time-separator.ts", "../src/elements/media-preview-time.ts", "../src/elements/media-progress-bar.ts", "../src/elements/media-volume-slider.ts", "../src/core/popover.ts", "../src/elements/media-settings-menu.ts", "../src/elements/media-seek-button.ts", "../src/elements/media-playback-rate-button.ts", "../src/elements/media-airplay-button.ts", "../src/elements/media-live-button.ts", "../src/elements/media-error-display.ts", "../src/elements/media-remote-playback-button.ts", "../src/elements/index.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * ts-video-player Media Session API Integration\n *\n * Provides lock screen / notification controls via navigator.mediaSession.\n *\n * @module core/media-session\n */\n\nimport type { StateStore } from './state'\n\nexport interface MediaSessionOptions {\n /** Title to display */\n title?: string\n /** Artist name */\n artist?: string\n /** Album name */\n album?: string\n /** Artwork images for lock screen */\n artwork?: MediaImage[]\n}\n\n/**\n * Check if Media Session API is available\n */\nexport function isMediaSessionSupported(): boolean {\n return typeof navigator !== 'undefined' && 'mediaSession' in navigator\n}\n\n/**\n * Create a Media Session controller that syncs player state to the browser's\n * media session (lock screen controls, notification area, etc.)\n */\nexport function createMediaSession(\n store: StateStore,\n actions: {\n play: () => void\n pause: () => void\n seekTo: (time: number) => void\n seekBy: (offset: number) => void\n stop: () => void\n },\n options?: MediaSessionOptions,\n): () => void {\n if (!isMediaSessionSupported()) return () => {}\n\n const session = navigator.mediaSession\n\n // Set metadata\n if (options) {\n updateMetadata(options)\n }\n\n // Action handlers\n const handlers: Array<[MediaSessionAction, MediaSessionActionHandler]> = [\n ['play', () => actions.play()],\n ['pause', () => actions.pause()],\n ['stop', () => actions.stop()],\n ['seekbackward', (details) => {\n const offset = (details as MediaSessionActionDetails & { seekOffset?: number }).seekOffset || -10\n actions.seekBy(offset)\n }],\n ['seekforward', (details) => {\n const offset = (details as MediaSessionActionDetails & { seekOffset?: number }).seekOffset || 10\n actions.seekBy(offset)\n }],\n ['seekto', (details) => {\n const seekTime = (details as MediaSessionActionDetails & { seekTime?: number }).seekTime\n if (seekTime !== undefined) actions.seekTo(seekTime)\n }],\n ]\n\n for (const [action, handler] of handlers) {\n try {\n session.setActionHandler(action, handler)\n } catch {\n // Some actions may not be supported on all platforms\n }\n }\n\n // Sync playback state\n const unsubPaused = store.subscribe('paused', (state) => {\n session.playbackState = state.paused ? 'paused' : 'playing'\n })\n\n // Sync position state\n let positionTimer: ReturnType<typeof setInterval> | null = null\n\n const updatePosition = () => {\n const state = store.getState()\n if (!isFinite(state.duration) || state.duration <= 0) return\n try {\n session.setPositionState({\n duration: state.duration,\n playbackRate: state.playbackRate,\n position: Math.min(state.currentTime, state.duration),\n })\n } catch {\n // Position state may fail if values are invalid\n }\n }\n\n const unsubPlaying = store.subscribe('playing', (state) => {\n if (state.playing) {\n updatePosition()\n if (!positionTimer) {\n positionTimer = setInterval(updatePosition, 1000)\n }\n } else {\n if (positionTimer) { clearInterval(positionTimer); positionTimer = null }\n updatePosition()\n }\n })\n\n return () => {\n if (positionTimer) clearInterval(positionTimer)\n unsubPaused()\n unsubPlaying()\n\n // Clear action handlers\n for (const [action] of handlers) {\n try { session.setActionHandler(action, null) } catch { /* ignore */ }\n }\n }\n}\n\n/**\n * Update media session metadata\n */\nexport function updateMetadata(options: MediaSessionOptions): void {\n if (!isMediaSessionSupported()) return\n navigator.mediaSession.metadata = new MediaMetadata({\n title: options.title || '',\n artist: options.artist || '',\n album: options.album || '',\n artwork: options.artwork || [],\n })\n}\n",
6
+ "/**\n * ts-video-player Orientation Lock\n *\n * Auto-lock screen orientation to landscape when entering fullscreen on mobile.\n *\n * @module core/orientation\n */\n\ntype OrientationType = 'landscape' | 'portrait' | 'any'\n\ninterface ScreenOrientationAPI {\n lock(orientation: string): Promise<void>\n unlock(): void\n}\n\n/**\n * Check if Screen Orientation API is available\n */\nexport function isOrientationLockSupported(): boolean {\n return (\n typeof screen !== 'undefined' &&\n 'orientation' in screen &&\n typeof (screen.orientation as unknown as ScreenOrientationAPI).lock === 'function'\n )\n}\n\n/**\n * Lock the screen orientation (best-effort, silently fails if unsupported)\n */\nexport function lockOrientation(type: OrientationType): void {\n if (!isOrientationLockSupported()) return\n\n const orientationMap: Record<OrientationType, string> = {\n landscape: 'landscape',\n portrait: 'portrait',\n any: 'any',\n }\n\n ;(screen.orientation as unknown as ScreenOrientationAPI)\n .lock(orientationMap[type])\n .catch(() => {\n // Orientation lock may fail if not in fullscreen or unsupported\n })\n}\n\n/**\n * Unlock the screen orientation\n */\nexport function unlockOrientation(): void {\n if (!isOrientationLockSupported()) return\n\n try {\n ;(screen.orientation as unknown as ScreenOrientationAPI).unlock()\n } catch {\n // Unlock may fail if lock was never acquired\n }\n}\n",
7
+ "/**\n * ts-video-player Base Provider\n *\n * Abstract base class for media providers.\n *\n * @module providers/base\n */\n\nimport type {\n Provider,\n ProviderType,\n Src,\n PlayerOptions,\n ProviderEventMap,\n VideoQuality,\n AudioTrack,\n TextTrack,\n MediaError,\n FeatureAvailability,\n} from '../types'\nimport { EventEmitter } from '../core/events'\nimport {\n detectVolumeAvailability,\n detectFullscreenAvailability,\n detectPipAvailability,\n enterFullscreen as fsEnter,\n exitFullscreen as fsExit,\n enterPiP as pipEnter,\n exitPiP as pipExit,\n} from '../core/features'\n\n/**\n * Abstract base provider implementation\n */\nexport abstract class BaseProvider implements Provider {\n abstract readonly name: string\n abstract readonly type: ProviderType\n\n protected container: HTMLElement | null = null\n protected options: PlayerOptions = {}\n protected events: EventEmitter<ProviderEventMap> = new EventEmitter<ProviderEventMap>()\n protected _ready = false\n\n get mediaElement(): HTMLVideoElement | HTMLAudioElement | HTMLIFrameElement | null {\n return null\n }\n\n get ready(): boolean {\n return this._ready\n }\n\n // === Lifecycle ===\n\n async setup(container: HTMLElement, options: PlayerOptions): Promise<void> {\n this.container = container\n this.options = options\n await this.initialize()\n this._ready = true\n this.events.emit('ready')\n }\n\n protected abstract initialize(): Promise<void>\n\n destroy(): void {\n this._ready = false\n this.cleanup()\n this.events.removeAllListeners()\n }\n\n protected abstract cleanup(): void\n\n // === Loading ===\n\n abstract load(src: Src | Src[]): Promise<void>\n abstract canPlay(src: Src): boolean\n\n // === Playback ===\n\n abstract play(): Promise<void>\n abstract pause(): void\n\n stop(): void {\n this.pause()\n this.seekTo(0)\n }\n\n // === Seeking ===\n\n abstract seekTo(time: number): void\n abstract getCurrentTime(): number\n abstract getDuration(): number\n\n // === Volume ===\n\n abstract setVolume(volume: number): void\n abstract getVolume(): number\n abstract setMuted(muted: boolean): void\n abstract getMuted(): boolean\n\n // === Playback Rate ===\n\n abstract setPlaybackRate(rate: number): void\n abstract getPlaybackRate(): number\n\n // === Quality ===\n\n getQualities(): VideoQuality[] {\n return []\n }\n\n setQuality(_quality: VideoQuality | 'auto'): void {\n // Override in subclass if supported\n }\n\n // === Tracks ===\n\n getTextTracks(): TextTrack[] {\n return []\n }\n\n setTextTrackMode(_trackId: string, _mode: 'disabled' | 'hidden' | 'showing'): void {\n // Override in subclass if supported\n }\n\n getAudioTracks(): AudioTrack[] {\n return []\n }\n\n setAudioTrack(_trackId: string): void {\n // Override in subclass if supported\n }\n\n // === Feature Availability ===\n\n getFeatureAvailability(feature: 'volume' | 'fullscreen' | 'pip'): FeatureAvailability {\n // Only pass media element if it's actually an HTMLMediaElement (not an iframe)\n const el = this.mediaElement\n const media = el instanceof HTMLMediaElement ? el : null\n const video = el instanceof HTMLVideoElement ? el : null\n\n switch (feature) {\n case 'volume':\n // Iframe providers (YouTube/Vimeo) handle volume via their own API\n return el && !(el instanceof HTMLMediaElement) ? 'available' : detectVolumeAvailability(media)\n case 'fullscreen':\n return detectFullscreenAvailability(this.container, video)\n case 'pip':\n // PiP is not available for iframe embeds\n return el && !(el instanceof HTMLMediaElement) ? 'unsupported' : detectPipAvailability(video)\n default:\n return 'unsupported'\n }\n }\n\n // === Fullscreen ===\n\n async enterFullscreen(): Promise<void> {\n await fsEnter(this.container, this.mediaElement as HTMLMediaElement | null)\n }\n\n async exitFullscreen(): Promise<void> {\n await fsExit(this.mediaElement as HTMLMediaElement | null)\n }\n\n protected getFullscreenElement(): HTMLElement | null {\n return this.container\n }\n\n // === Picture-in-Picture ===\n\n async enterPiP(): Promise<void> {\n const media = this.mediaElement as HTMLMediaElement | null\n if (!media) return\n await pipEnter(media)\n }\n\n async exitPiP(): Promise<void> {\n await pipExit(this.mediaElement as HTMLMediaElement | null)\n }\n\n // === Events ===\n\n on<K extends keyof ProviderEventMap>(event: K, handler: ProviderEventMap[K]): void {\n this.events.on(event, handler)\n }\n\n off<K extends keyof ProviderEventMap>(event: K, handler: ProviderEventMap[K]): void {\n this.events.off(event, handler)\n }\n\n // === Helpers ===\n\n protected emitError(code: number, message: string, details?: unknown): void {\n const error: MediaError = { code, message, details }\n this.events.emit('error', error)\n }\n}\n",
8
+ "/**\n * ts-video-player HTML5 Provider\n *\n * Native HTML5 video/audio element provider.\n *\n * @module providers/html5\n */\n\nimport type {\n ProviderType,\n Src,\n MediaSource,\n PlayerOptions,\n AudioTrack,\n TextTrack,\n} from '../types'\nimport { BaseProvider } from './base'\nimport { MediaEventsNormalizer, onFullscreenChange, onPiPChange } from '../core/events'\nimport { probeVolumeAvailability } from '../core/features'\n\n/**\n * Check if a source is an HTML5 compatible source\n */\nexport function isHTML5Source(src: Src): boolean {\n if (typeof src === 'string') {\n const extension = getExtension(src)\n // Check for supported extensions\n if (\n extension === 'mp4' ||\n extension === 'webm' ||\n extension === 'ogg' ||\n extension === 'ogv' ||\n extension === 'mov' ||\n extension === 'mp3' ||\n extension === 'wav' ||\n extension === 'flac' ||\n extension === 'm4a' ||\n extension === 'aac' ||\n extension === 'oga' ||\n extension === 'opus'\n ) {\n return true\n }\n // Check for MIME types\n return false\n }\n\n if (typeof src === 'object' && 'type' in src) {\n const type = (src as MediaSource).type?.toLowerCase() || ''\n return (\n type.startsWith('video/') ||\n type.startsWith('audio/') ||\n type === 'application/ogg'\n )\n }\n\n return false\n}\n\nfunction getExtension(src: string): string {\n const path = src.split(/[?#]/, 1)[0]\n return path.slice(path.lastIndexOf('.') + 1).toLowerCase()\n}\n\n/**\n * Get MIME type for a source\n */\nfunction getMimeType(src: string): string {\n const ext = getExtension(src)\n const mimeTypes: Record<string, string> = {\n mp4: 'video/mp4',\n webm: 'video/webm',\n ogg: 'video/ogg',\n ogv: 'video/ogg',\n mov: 'video/quicktime',\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n flac: 'audio/flac',\n m4a: 'audio/mp4',\n aac: 'audio/aac',\n oga: 'audio/ogg',\n opus: 'audio/ogg; codecs=opus',\n }\n return mimeTypes[ext || ''] || 'video/mp4'\n}\n\n/**\n * HTML5 Video/Audio Provider\n */\nexport class HTML5Provider extends BaseProvider {\n readonly name = 'html5'\n readonly type: ProviderType = 'video'\n\n private media: HTMLVideoElement | HTMLAudioElement | null = null\n private eventsNormalizer: MediaEventsNormalizer | null = null\n private cleanupFullscreen: (() => void) | null = null\n private cleanupPiP: (() => void) | null = null\n private isAudio = false\n\n get mediaElement(): HTMLVideoElement | HTMLAudioElement | null {\n return this.media\n }\n\n // === Lifecycle ===\n\n protected async initialize(): Promise<void> {\n if (!this.container) {\n throw new Error('Container element is required')\n }\n\n // Determine if audio or video based on options\n this.isAudio = this.options.mediaType === 'audio'\n\n // Create media element\n this.media = document.createElement(this.isAudio ? 'audio' : 'video')\n this.media.className = 'ts-video-player__media'\n\n // Set attributes\n if (this.options.autoplay) this.media.autoplay = true\n if (this.options.loop) this.media.loop = true\n if (this.options.muted) this.media.muted = true\n if (this.options.playsinline && !this.isAudio) {\n (this.media as HTMLVideoElement).playsInline = true\n }\n if (this.options.preload) this.media.preload = this.options.preload\n if (this.options.crossorigin) this.media.crossOrigin = this.options.crossorigin\n if (this.options.controlsList?.length) this.media.setAttribute('controlslist', this.options.controlsList.join(' '))\n if (!this.isAudio && this.options.disablePictureInPicture) {\n (this.media as HTMLVideoElement).disablePictureInPicture = true\n }\n if (this.options.poster && !this.isAudio) {\n (this.media as HTMLVideoElement).poster = this.options.poster\n }\n\n // Set initial volume\n if (this.options.volume !== undefined) {\n this.media.volume = this.options.volume\n }\n\n // Append to container\n this.container.appendChild(this.media)\n for (const track of this.options.tracks ?? []) this.addTextTrack(track)\n\n // Setup event normalization\n this.eventsNormalizer = new MediaEventsNormalizer(this.media, this.events)\n\n // Setup fullscreen listener\n this.cleanupFullscreen = onFullscreenChange((fullscreen) => {\n this.events.emit('fullscreenchange', fullscreen)\n })\n\n // Setup PiP listener for video\n if (!this.isAudio && this.media instanceof HTMLVideoElement) {\n this.cleanupPiP = onPiPChange(this.media, (pip) => {\n this.events.emit('pipchange', pip)\n })\n }\n\n // Emit state for dimensions and feature availability\n if (!this.isAudio) {\n this.media.addEventListener('loadedmetadata', () => {\n const video = this.media as HTMLVideoElement\n const fullscreenAvailability = this.getFeatureAvailability('fullscreen')\n const pipAvailability = this.getFeatureAvailability('pip')\n const volumeAvailability = this.getFeatureAvailability('volume')\n this.events.emit('statechange', {\n videoWidth: video.videoWidth,\n videoHeight: video.videoHeight,\n aspectRatio: (video.videoHeight > 0 ? video.videoWidth / video.videoHeight : 0) || 16 / 9,\n canFullscreen: fullscreenAvailability === 'available',\n canPictureInPicture: pipAvailability === 'available',\n fullscreenAvailability,\n pipAvailability,\n volumeAvailability,\n })\n this.events.emit('availabilitychange', 'fullscreen', fullscreenAvailability)\n this.events.emit('availabilitychange', 'pip', pipAvailability)\n this.events.emit('availabilitychange', 'volume', volumeAvailability)\n })\n }\n\n // Async volume probe after loadeddata\n this.media.addEventListener('loadeddata', () => {\n if (!this.media) return\n probeVolumeAvailability(this.media).then((availability) => {\n this.events.emit('statechange', {\n volumeAvailability: availability,\n })\n this.events.emit('availabilitychange', 'volume', availability)\n }).catch(() => {\n // Volume probe failed — keep current availability state\n })\n })\n\n // iOS Safari PiP via webkitpresentationmodechanged\n if (!this.isAudio && this.media instanceof HTMLVideoElement) {\n this.media.addEventListener('webkitpresentationmodechanged', () => {\n const video = this.media as any\n if (video?.webkitPresentationMode) {\n const isPiP = video.webkitPresentationMode === 'picture-in-picture'\n this.events.emit('pipchange', isPiP)\n }\n })\n }\n }\n\n protected cleanup(): void {\n this.eventsNormalizer?.destroy()\n this.cleanupFullscreen?.()\n this.cleanupPiP?.()\n\n if (this.media) {\n this.media.pause()\n this.media.removeAttribute('src')\n this.media.load()\n this.media.remove()\n this.media = null\n }\n }\n\n // === Loading ===\n\n canPlay(src: Src): boolean {\n return isHTML5Source(src)\n }\n\n async load(src: Src): Promise<void> {\n if (!this.media) return\n\n // Clear existing sources\n this.media.innerHTML = ''\n this.media.removeAttribute('src')\n\n // Normalize source\n const sources = Array.isArray(src) ? src : [src]\n\n for (const source of sources) {\n if (typeof source === 'string') {\n // Simple URL\n const sourceEl = document.createElement('source')\n sourceEl.src = source\n sourceEl.type = getMimeType(source)\n this.media.appendChild(sourceEl)\n } else if ('src' in source && typeof source.src === 'string') {\n // MediaSource object\n const mediaSource = source as MediaSource\n const sourceEl = document.createElement('source')\n sourceEl.src = mediaSource.src\n sourceEl.type = mediaSource.type || getMimeType(mediaSource.src)\n this.media.appendChild(sourceEl)\n }\n }\n\n // Load the media\n this.media.load()\n }\n\n // === Playback ===\n\n async play(): Promise<void> {\n if (!this.media) return\n try {\n await this.media.play()\n } catch (error) {\n // Handle autoplay blocked\n if ((error as Error).name === 'NotAllowedError') {\n this.emitError(1, 'Playback was blocked. User interaction required.', error)\n } else {\n throw error\n }\n }\n }\n\n pause(): void {\n this.media?.pause()\n }\n\n // === Seeking ===\n\n seekTo(time: number): void {\n if (this.media) {\n this.media.currentTime = Math.max(0, Math.min(time, this.getDuration()))\n }\n }\n\n getCurrentTime(): number {\n return this.media?.currentTime || 0\n }\n\n getDuration(): number {\n return this.media?.duration || 0\n }\n\n // === Volume ===\n\n setVolume(volume: number): void {\n if (this.media) {\n this.media.volume = Math.max(0, Math.min(1, volume))\n }\n }\n\n getVolume(): number {\n return this.media?.volume || 1\n }\n\n setMuted(muted: boolean): void {\n if (this.media) {\n this.media.muted = muted\n }\n }\n\n getMuted(): boolean {\n return this.media?.muted || false\n }\n\n // === Playback Rate ===\n\n setPlaybackRate(rate: number): void {\n if (this.media) {\n this.media.playbackRate = Math.max(0.25, Math.min(4, rate))\n }\n }\n\n getPlaybackRate(): number {\n return this.media?.playbackRate || 1\n }\n\n // === Text Tracks ===\n\n getTextTracks(): TextTrack[] {\n if (!this.media) return []\n\n const tracks: TextTrack[] = []\n const textTracks = this.media.textTracks\n\n for (let i = 0; i < textTracks.length; i++) {\n const track = textTracks[i]\n tracks.push({\n id: String(i),\n kind: track.kind as TextTrack['kind'],\n label: track.label || `Track ${i + 1}`,\n language: track.language || '',\n mode: track.mode as TextTrack['mode'],\n cues: this.getTrackCues(track),\n })\n }\n\n return tracks\n }\n\n private getTrackCues(track: globalThis.TextTrack): TextTrack['cues'] {\n if (!track.cues) return []\n\n const cues: TextTrack['cues'] = []\n for (let i = 0; i < track.cues.length; i++) {\n const cue = track.cues[i] as VTTCue\n cues.push({\n id: cue.id || String(i),\n startTime: cue.startTime,\n endTime: cue.endTime,\n text: cue.text,\n })\n }\n return cues\n }\n\n setTextTrackMode(trackId: string, mode: 'disabled' | 'hidden' | 'showing'): void {\n if (!this.media) return\n\n const index = parseInt(trackId, 10)\n const track = this.media.textTracks[index]\n if (track) {\n track.mode = mode\n this.events.emit('texttrackchange', mode === 'showing' ? this.getTextTracks()[index] : null)\n }\n }\n\n // === Audio Tracks ===\n\n getAudioTracks(): AudioTrack[] {\n if (!this.media || this.isAudio) return []\n\n const video = this.media as HTMLVideoElement\n if (!('audioTracks' in video)) return []\n\n const audioTracks = (video as any).audioTracks\n const tracks: AudioTrack[] = []\n\n for (let i = 0; i < audioTracks.length; i++) {\n const track = audioTracks[i]\n tracks.push({\n id: track.id || String(i),\n label: track.label || `Track ${i + 1}`,\n language: track.language || '',\n kind: track.kind || '',\n selected: track.enabled,\n })\n }\n\n return tracks\n }\n\n setAudioTrack(trackId: string): void {\n if (!this.media || this.isAudio) return\n\n const video = this.media as HTMLVideoElement\n if (!('audioTracks' in video)) return\n\n const audioTracks = (video as any).audioTracks\n for (let i = 0; i < audioTracks.length; i++) {\n const isTarget = audioTracks[i].id === trackId || String(i) === trackId\n audioTracks[i].enabled = isTarget\n }\n\n this.events.emit('audiotrackchange', this.getAudioTracks().find((t) => t.selected) || null)\n }\n\n // === Add Text Track ===\n\n addTextTrack(options: {\n src?: string\n kind?: TextTrack['kind']\n label?: string\n language?: string\n default?: boolean\n }): void {\n if (!this.media) return\n\n const track = document.createElement('track')\n if (options.src) track.src = options.src\n track.kind = options.kind || 'subtitles'\n track.label = options.label || ''\n track.srclang = options.language || ''\n if (options.default) track.default = true\n\n this.media.appendChild(track)\n }\n}\n\n/**\n * HTML5 Provider Loader\n */\nexport const html5Loader = {\n name: 'html5',\n type: 'video' as ProviderType,\n\n canPlay(src: Src): boolean {\n return isHTML5Source(src)\n },\n\n mediaType(src: Src): 'video' | 'audio' | 'unknown' {\n if (typeof src === 'string') {\n const extension = getExtension(src)\n if (['mp3', 'wav', 'flac', 'm4a', 'aac', 'oga', 'opus'].includes(extension)) {\n return 'audio'\n }\n return 'video'\n }\n\n if (typeof src === 'object' && 'type' in src) {\n const type = (src as MediaSource).type?.toLowerCase() || ''\n if (type.startsWith('audio/')) return 'audio'\n }\n\n return 'video'\n },\n\n async load(container: HTMLElement, options: PlayerOptions): Promise<HTML5Provider> {\n const provider = new HTML5Provider()\n await provider.setup(container, options)\n return provider\n },\n}\n",
9
+ "/**\n * ts-video-player YouTube Provider\n *\n * YouTube embed provider using the iframe API.\n *\n * @module providers/youtube\n */\n\nimport type { ProviderType, Src, YouTubeSource, PlayerOptions, VideoQuality } from '../types'\nimport { BaseProvider } from './base'\n\n// =============================================================================\n// YouTube URL Parsing\n// =============================================================================\n\n/**\n * YouTube URL patterns\n */\nconst YOUTUBE_PATTERNS = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/)([a-zA-Z0-9_-]{11})/,\n /youtube\\.com\\/v\\/([a-zA-Z0-9_-]{11})/,\n /youtube\\.com\\/shorts\\/([a-zA-Z0-9_-]{11})/,\n]\n\n/**\n * Extract YouTube video ID from URL\n */\nexport function extractYouTubeId(url: string): string | null {\n for (const pattern of YOUTUBE_PATTERNS) {\n const match = url.match(pattern)\n if (match) return match[1]\n }\n return null\n}\n\n/**\n * Check if source is a YouTube source\n */\nexport function isYouTubeSource(src: Src): boolean {\n if (typeof src === 'string') {\n return extractYouTubeId(src) !== null\n }\n\n if (typeof src === 'object' && 'type' in src) {\n return (src as YouTubeSource).type === 'youtube'\n }\n\n return false\n}\n\n/**\n * Parse YouTube source\n */\nfunction parseYouTubeSource(src: Src): { videoId: string; startTime?: number; endTime?: number } | null {\n if (typeof src === 'string') {\n const videoId = extractYouTubeId(src)\n if (!videoId) return null\n\n // Parse start/end time from URL params\n const url = new URL(src, 'https://youtube.com')\n const start = url.searchParams.get('t') || url.searchParams.get('start')\n const end = url.searchParams.get('end')\n\n return {\n videoId,\n startTime: start ? parseTime(start) : undefined,\n endTime: end ? parseTime(end) : undefined,\n }\n }\n\n if (typeof src === 'object' && 'type' in src && (src as YouTubeSource).type === 'youtube') {\n const ytSrc = src as YouTubeSource\n return {\n videoId: ytSrc.videoId || extractYouTubeId(ytSrc.src) || '',\n startTime: ytSrc.startTime,\n endTime: ytSrc.endTime,\n }\n }\n\n return null\n}\n\n/**\n * Parse time string (e.g., \"1m30s\", \"90\", \"1:30\")\n */\nfunction parseTime(time: string): number {\n // Already a number in seconds\n if (/^\\d+$/.test(time)) return parseInt(time, 10)\n\n // Format: 1m30s\n const match1 = time.match(/(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?/)\n if (match1) {\n const h = parseInt(match1[1] || '0', 10)\n const m = parseInt(match1[2] || '0', 10)\n const s = parseInt(match1[3] || '0', 10)\n return h * 3600 + m * 60 + s\n }\n\n // Format: 1:30 or 1:30:00\n const parts = time.split(':').map((p) => parseInt(p, 10))\n if (parts.length === 2) return parts[0] * 60 + parts[1]\n if (parts.length === 3) return parts[0] * 3600 + parts[1] * 60 + parts[2]\n\n return 0\n}\n\n// =============================================================================\n// YouTube API Types\n// =============================================================================\n\ninterface YTPlayer {\n playVideo(): void\n pauseVideo(): void\n stopVideo(): void\n seekTo(seconds: number, allowSeekAhead: boolean): void\n getCurrentTime(): number\n getDuration(): number\n setVolume(volume: number): void\n getVolume(): number\n mute(): void\n unMute(): void\n isMuted(): boolean\n setPlaybackRate(rate: number): void\n getPlaybackRate(): number\n getAvailablePlaybackRates(): number[]\n setPlaybackQuality(quality: string): void\n getPlaybackQuality(): string\n getAvailableQualityLevels(): string[]\n loadVideoById(options: { videoId: string; startSeconds?: number; endSeconds?: number }): void\n cueVideoById(options: { videoId: string; startSeconds?: number; endSeconds?: number }): void\n getIframe(): HTMLIFrameElement\n getPlayerState(): number\n destroy(): void\n}\n\ninterface YTPlayerEvent {\n target: YTPlayer\n data: number\n}\n\ndeclare global {\n interface Window {\n YT?: {\n Player: new (\n elementId: string | HTMLElement,\n options: {\n videoId?: string\n width?: number | string\n height?: number | string\n playerVars?: Record<string, string | number>\n events?: {\n onReady?: (event: YTPlayerEvent) => void\n onStateChange?: (event: YTPlayerEvent) => void\n onError?: (event: YTPlayerEvent) => void\n onPlaybackQualityChange?: (event: YTPlayerEvent) => void\n onPlaybackRateChange?: (event: YTPlayerEvent) => void\n }\n },\n ) => YTPlayer\n PlayerState: {\n UNSTARTED: -1\n ENDED: 0\n PLAYING: 1\n PAUSED: 2\n BUFFERING: 3\n CUED: 5\n }\n }\n onYouTubeIframeAPIReady?: () => void\n }\n}\n\n// =============================================================================\n// YouTube Provider\n// =============================================================================\n\n/**\n * YouTube embed provider\n */\nexport class YouTubeProvider extends BaseProvider {\n readonly name = 'youtube'\n readonly type: ProviderType = 'youtube'\n\n private player: YTPlayer | null = null\n private iframe: HTMLIFrameElement | null = null\n private pendingVideoId: string | null = null\n private startTime?: number\n private endTime?: number\n private timeUpdateInterval: ReturnType<typeof setInterval> | null = null\n private lastState = -1\n\n get mediaElement(): HTMLIFrameElement | null {\n return this.iframe\n }\n\n // === Lifecycle ===\n\n protected async initialize(): Promise<void> {\n if (!this.container) {\n throw new Error('Container element is required')\n }\n\n // Load YouTube API\n await this.loadYouTubeAPI()\n\n // Create container div for YouTube player\n const playerDiv = document.createElement('div')\n playerDiv.id = `ts-video-player-yt-${Date.now()}`\n playerDiv.className = 'ts-video-player__youtube'\n this.container.appendChild(playerDiv)\n\n // Build player vars\n const playerVars: Record<string, string | number> = {\n autoplay: this.options.autoplay ? 1 : 0,\n controls: 0, // We use our own controls\n disablekb: 1, // Disable keyboard (we handle it)\n enablejsapi: 1,\n iv_load_policy: 3, // Disable annotations\n modestbranding: 1,\n playsinline: this.options.playsinline ? 1 : 0,\n rel: 0, // Don't show related videos\n origin: window.location.origin,\n }\n\n // Apply custom YouTube params\n if (this.options.youtubeParams) {\n Object.assign(playerVars, this.options.youtubeParams)\n }\n\n // Use privacy-enhanced mode\n playerVars.host = 'https://www.youtube-nocookie.com'\n\n // Create player\n this.player = new window.YT!.Player(playerDiv.id, {\n width: '100%',\n height: '100%',\n playerVars,\n events: {\n onReady: () => this.onReady(),\n onStateChange: (e) => this.onStateChange(e),\n onError: (e) => this.onError(e),\n onPlaybackQualityChange: () => this.onQualityChange(),\n onPlaybackRateChange: () => this.onRateChange(),\n },\n })\n\n // Get iframe reference\n this.iframe = this.player.getIframe()\n this.iframe.className = 'ts-video-player__media'\n }\n\n private async loadYouTubeAPI(): Promise<void> {\n if (window.YT?.Player) return\n\n return new Promise((resolve) => {\n // Check if script already loading\n if (document.querySelector('script[src*=\"youtube.com/iframe_api\"]')) {\n const check = () => {\n if (window.YT?.Player) {\n resolve()\n } else {\n setTimeout(check, 100)\n }\n }\n check()\n return\n }\n\n // Load script\n const script = document.createElement('script')\n script.src = 'https://www.youtube.com/iframe_api'\n script.async = true\n\n window.onYouTubeIframeAPIReady = () => {\n resolve()\n }\n\n document.head.appendChild(script)\n })\n }\n\n protected cleanup(): void {\n if (this.timeUpdateInterval) {\n clearInterval(this.timeUpdateInterval)\n this.timeUpdateInterval = null\n }\n\n this.player?.destroy()\n this.player = null\n this.iframe = null\n }\n\n // === Event Handlers ===\n\n private onReady(): void {\n // Start time update polling\n this.timeUpdateInterval = setInterval(() => {\n if (this.player && this.lastState === 1) {\n this.events.emit('timeupdate', this.getCurrentTime())\n }\n }, 250)\n\n // Emit initial state\n this.events.emit('loadedmetadata')\n this.events.emit('canplay')\n\n // Load pending video if any\n if (this.pendingVideoId) {\n this.loadVideo(this.pendingVideoId, this.startTime, this.endTime)\n this.pendingVideoId = null\n }\n }\n\n private onStateChange(event: YTPlayerEvent): void {\n const state = event.data\n this.lastState = state\n\n const PlayerState = window.YT!.PlayerState\n\n switch (state) {\n case PlayerState.UNSTARTED:\n this.events.emit('loadstart')\n break\n case PlayerState.PLAYING:\n this.events.emit('play')\n this.events.emit('playing')\n this.events.emit('statechange', { paused: false, playing: true, waiting: false })\n break\n case PlayerState.PAUSED:\n this.events.emit('pause')\n this.events.emit('statechange', { paused: true, playing: false })\n break\n case PlayerState.BUFFERING:\n this.events.emit('waiting')\n this.events.emit('statechange', { waiting: true })\n break\n case PlayerState.ENDED:\n this.events.emit('ended')\n this.events.emit('statechange', { ended: true, playing: false })\n break\n case PlayerState.CUED:\n this.events.emit('loadeddata')\n this.events.emit('durationchange', this.getDuration())\n break\n }\n }\n\n private onError(event: YTPlayerEvent): void {\n const errorMessages: Record<number, string> = {\n 2: 'Invalid video ID',\n 5: 'HTML5 player error',\n 100: 'Video not found or removed',\n 101: 'Video cannot be embedded',\n 150: 'Video cannot be embedded',\n }\n\n this.emitError(event.data, errorMessages[event.data] || 'Unknown YouTube error')\n }\n\n private onQualityChange(): void {\n const quality = this.player?.getPlaybackQuality() || 'auto'\n const qualities = this.getQualities()\n this.events.emit('qualitychange', qualities.find((q) => q.id === quality) || null)\n }\n\n private onRateChange(): void {\n this.events.emit('ratechange', this.getPlaybackRate())\n }\n\n // === Loading ===\n\n canPlay(src: Src): boolean {\n return isYouTubeSource(src)\n }\n\n async load(src: Src): Promise<void> {\n const parsed = parseYouTubeSource(src)\n if (!parsed) {\n this.emitError(2, 'Invalid YouTube source')\n return\n }\n\n this.startTime = parsed.startTime\n this.endTime = parsed.endTime\n\n if (!this.player || !this._ready) {\n this.pendingVideoId = parsed.videoId\n return\n }\n\n this.loadVideo(parsed.videoId, parsed.startTime, parsed.endTime)\n }\n\n private loadVideo(videoId: string, startTime?: number, endTime?: number): void {\n if (!this.player) return\n\n if (this.options.autoplay) {\n this.player.loadVideoById({\n videoId,\n startSeconds: startTime,\n endSeconds: endTime,\n })\n } else {\n this.player.cueVideoById({\n videoId,\n startSeconds: startTime,\n endSeconds: endTime,\n })\n }\n }\n\n // === Playback ===\n\n async play(): Promise<void> {\n this.player?.playVideo()\n }\n\n pause(): void {\n this.player?.pauseVideo()\n }\n\n stop(): void {\n this.player?.stopVideo()\n }\n\n // === Seeking ===\n\n seekTo(time: number): void {\n this.player?.seekTo(time, true)\n this.events.emit('seeking')\n // YouTube doesn't emit seeked, so we fake it\n setTimeout(() => this.events.emit('seeked'), 100)\n }\n\n getCurrentTime(): number {\n return this.player?.getCurrentTime() || 0\n }\n\n getDuration(): number {\n return this.player?.getDuration() || 0\n }\n\n // === Volume ===\n\n setVolume(volume: number): void {\n this.player?.setVolume(Math.round(volume * 100))\n this.events.emit('volumechange', volume, this.getMuted())\n }\n\n getVolume(): number {\n return (this.player?.getVolume() || 100) / 100\n }\n\n setMuted(muted: boolean): void {\n if (muted) {\n this.player?.mute()\n } else {\n this.player?.unMute()\n }\n this.events.emit('volumechange', this.getVolume(), muted)\n }\n\n getMuted(): boolean {\n return this.player?.isMuted() || false\n }\n\n // === Playback Rate ===\n\n setPlaybackRate(rate: number): void {\n this.player?.setPlaybackRate(rate)\n }\n\n getPlaybackRate(): number {\n return this.player?.getPlaybackRate() || 1\n }\n\n // === Quality ===\n\n getQualities(): VideoQuality[] {\n const levels = this.player?.getAvailableQualityLevels() || []\n const heights: Record<string, number> = {\n highres: 2160,\n hd2160: 2160,\n hd1440: 1440,\n hd1080: 1080,\n hd720: 720,\n large: 480,\n medium: 360,\n small: 240,\n tiny: 144,\n }\n\n const current = this.player?.getPlaybackQuality()\n\n return levels.map((level) => ({\n id: level,\n width: Math.round((heights[level] || 480) * (16 / 9)),\n height: heights[level] || 480,\n bitrate: 0,\n selected: level === current,\n }))\n }\n\n setQuality(quality: VideoQuality | 'auto'): void {\n if (quality === 'auto') {\n this.player?.setPlaybackQuality('default')\n } else {\n this.player?.setPlaybackQuality(quality.id)\n }\n }\n}\n\n/**\n * YouTube Provider Loader\n */\nexport const youtubeLoader = {\n name: 'youtube',\n type: 'youtube' as ProviderType,\n\n canPlay(src: Src): boolean {\n return isYouTubeSource(src)\n },\n\n mediaType(): 'video' {\n return 'video'\n },\n\n preconnect(): string[] {\n return [\n 'https://www.youtube-nocookie.com',\n 'https://www.youtube.com',\n 'https://i.ytimg.com',\n 'https://s.ytimg.com',\n ]\n },\n\n async load(container: HTMLElement, options: PlayerOptions): Promise<YouTubeProvider> {\n const provider = new YouTubeProvider()\n await provider.setup(container, options)\n return provider\n },\n}\n",
10
+ "/**\n * ts-video-player Vimeo Provider\n *\n * Vimeo embed provider using the Vimeo Player API.\n *\n * @module providers/vimeo\n */\n\nimport type { ProviderType, Src, VimeoSource, PlayerOptions, VideoQuality } from '../types'\nimport { BaseProvider } from './base'\n\n// =============================================================================\n// Vimeo URL Parsing\n// =============================================================================\n\n/**\n * Vimeo URL patterns\n */\nconst VIMEO_PATTERNS = [\n /vimeo\\.com\\/(\\d+)/,\n /vimeo\\.com\\/video\\/(\\d+)/,\n /player\\.vimeo\\.com\\/video\\/(\\d+)/,\n /vimeo\\.com\\/channels\\/[\\w]+\\/(\\d+)/,\n /vimeo\\.com\\/groups\\/[\\w]+\\/videos\\/(\\d+)/,\n]\n\n/**\n * Extract Vimeo video ID from URL\n */\nexport function extractVimeoId(url: string): string | null {\n for (const pattern of VIMEO_PATTERNS) {\n const match = url.match(pattern)\n if (match) return match[1]\n }\n return null\n}\n\n/**\n * Extract hash for private videos\n */\nexport function extractVimeoHash(url: string): string | null {\n // Format: vimeo.com/123456789/abcdef123\n const match = url.match(/vimeo\\.com\\/\\d+\\/([a-f0-9]+)/)\n return match ? match[1] : null\n}\n\n/**\n * Check if source is a Vimeo source\n */\nexport function isVimeoSource(src: Src): boolean {\n if (typeof src === 'string') {\n return extractVimeoId(src) !== null\n }\n\n if (typeof src === 'object' && 'type' in src) {\n return (src as VimeoSource).type === 'vimeo'\n }\n\n return false\n}\n\n/**\n * Parse Vimeo source\n */\nfunction parseVimeoSource(src: Src): { videoId: string; hash?: string } | null {\n if (typeof src === 'string') {\n const videoId = extractVimeoId(src)\n if (!videoId) return null\n return { videoId, hash: extractVimeoHash(src) || undefined }\n }\n\n if (typeof src === 'object' && 'type' in src && (src as VimeoSource).type === 'vimeo') {\n const vSrc = src as VimeoSource\n return {\n videoId: vSrc.videoId || extractVimeoId(vSrc.src) || '',\n hash: vSrc.hash,\n }\n }\n\n return null\n}\n\n// =============================================================================\n// Vimeo Player Types\n// =============================================================================\n\ninterface VimeoPlayerOptions {\n id?: number\n url?: string\n autopause?: boolean\n autoplay?: boolean\n background?: boolean\n byline?: boolean\n color?: string\n controls?: boolean\n dnt?: boolean\n height?: number\n loop?: boolean\n maxheight?: number\n maxwidth?: number\n muted?: boolean\n playsinline?: boolean\n portrait?: boolean\n responsive?: boolean\n speed?: boolean\n title?: boolean\n transparent?: boolean\n width?: number\n}\n\ninterface VimeoPlayer {\n ready(): Promise<void>\n play(): Promise<void>\n pause(): Promise<void>\n unload(): Promise<void>\n destroy(): Promise<void>\n getCurrentTime(): Promise<number>\n setCurrentTime(seconds: number): Promise<number>\n getDuration(): Promise<number>\n getVolume(): Promise<number>\n setVolume(volume: number): Promise<number>\n getMuted(): Promise<boolean>\n setMuted(muted: boolean): Promise<boolean>\n getLoop(): Promise<boolean>\n setLoop(loop: boolean): Promise<boolean>\n getPlaybackRate(): Promise<number>\n setPlaybackRate(rate: number): Promise<number>\n getPaused(): Promise<boolean>\n getEnded(): Promise<boolean>\n getVideoTitle(): Promise<string>\n getVideoWidth(): Promise<number>\n getVideoHeight(): Promise<number>\n getVideoId(): Promise<number>\n getVideoUrl(): Promise<string>\n getQualities(): Promise<Array<{ id: string; label: string; active: boolean }>>\n setQuality(quality: string): Promise<string>\n getTextTracks(): Promise<Array<{ label: string; language: string; kind: string; mode: string }>>\n enableTextTrack(language: string, kind?: string): Promise<void>\n disableTextTrack(): Promise<void>\n on(event: string, callback: (...args: any[]) => void): void\n off(event: string, callback?: (...args: any[]) => void): void\n getBuffered(): Promise<Array<{ start: number; end: number }>>\n getChapters(): Promise<Array<{ title: string; startTime: number; index: number }>>\n}\n\ninterface VimeoStatic {\n Player: new (element: HTMLElement | HTMLIFrameElement, options?: VimeoPlayerOptions) => VimeoPlayer\n}\n\ndeclare global {\n interface Window {\n Vimeo?: VimeoStatic\n }\n}\n\n// =============================================================================\n// Vimeo Provider\n// =============================================================================\n\nconst VIMEO_SDK_URL = 'https://player.vimeo.com/api/player.js'\n\n/**\n * Vimeo embed provider\n */\nexport class VimeoProvider extends BaseProvider {\n readonly name = 'vimeo'\n readonly type: ProviderType = 'vimeo'\n\n private container_el: HTMLElement | null = null\n private player: VimeoPlayer | null = null\n private iframe: HTMLIFrameElement | null = null\n private timeUpdateInterval: ReturnType<typeof setInterval> | null = null\n private _qualities: VideoQuality[] = []\n private _duration = 0\n get mediaElement(): HTMLIFrameElement | null {\n return this.iframe\n }\n\n // === Lifecycle ===\n\n protected async initialize(): Promise<void> {\n if (!this.container) {\n throw new Error('Container element is required')\n }\n\n // Load Vimeo SDK\n await this.loadVimeoSDK()\n\n // Create container for Vimeo player\n this.container_el = document.createElement('div')\n this.container_el.className = 'ts-video-player__vimeo'\n this.container.appendChild(this.container_el)\n }\n\n private async loadVimeoSDK(): Promise<void> {\n if (window.Vimeo) return\n\n return new Promise((resolve, reject) => {\n if (document.querySelector(`script[src=\"${VIMEO_SDK_URL}\"]`)) {\n const check = () => {\n if (window.Vimeo) resolve()\n else setTimeout(check, 100)\n }\n check()\n return\n }\n\n const script = document.createElement('script')\n script.src = VIMEO_SDK_URL\n script.async = true\n script.onload = () => resolve()\n script.onerror = () => reject(new Error('Failed to load Vimeo SDK'))\n document.head.appendChild(script)\n })\n }\n\n protected cleanup(): void {\n if (this.timeUpdateInterval) {\n clearInterval(this.timeUpdateInterval)\n this.timeUpdateInterval = null\n }\n\n this.player?.destroy()\n this.player = null\n this.iframe = null\n this.container_el?.remove()\n this.container_el = null\n }\n\n // === Loading ===\n\n canPlay(src: Src): boolean {\n return isVimeoSource(src)\n }\n\n async load(src: Src): Promise<void> {\n const parsed = parseVimeoSource(src)\n if (!parsed || !this.container_el) {\n this.emitError(2, 'Invalid Vimeo source')\n return\n }\n\n // Destroy existing player\n if (this.player) {\n await this.player.destroy()\n this.player = null\n }\n\n // Build player options\n const playerOptions: VimeoPlayerOptions = {\n id: parseInt(parsed.videoId, 10),\n autopause: false,\n autoplay: this.options.autoplay || false,\n controls: false, // We use our own controls\n loop: this.options.loop || false,\n muted: this.options.muted || false,\n playsinline: this.options.playsinline !== false,\n responsive: true,\n dnt: true, // Do Not Track\n }\n\n // Apply custom Vimeo params\n if (this.options.vimeoParams) {\n Object.assign(playerOptions, this.options.vimeoParams)\n }\n\n // Create player\n this.player = new window.Vimeo!.Player(this.container_el, playerOptions)\n\n // Wait for ready\n await this.player.ready()\n\n // Get iframe\n this.iframe = this.container_el.querySelector('iframe')\n if (this.iframe) {\n this.iframe.className = 'ts-video-player__media'\n }\n\n // Setup event listeners\n this.attachVimeoEvents()\n\n // Emit ready\n this.events.emit('loadedmetadata')\n this.events.emit('canplay')\n\n // Get duration\n this._duration = await this.player.getDuration()\n this.events.emit('durationchange', this._duration)\n\n // Get initial qualities\n await this.updateQualities()\n\n // Emit dimensions\n const [width, height] = await Promise.all([this.player.getVideoWidth(), this.player.getVideoHeight()])\n this.events.emit('statechange', {\n videoWidth: width,\n videoHeight: height,\n aspectRatio: width / height || 16 / 9,\n canFullscreen: true,\n canPictureInPicture: false,\n })\n }\n\n private attachVimeoEvents(): void {\n if (!this.player) return\n\n // Play\n this.player.on('play', () => {\n this.events.emit('play')\n this.events.emit('playing')\n this.events.emit('statechange', { paused: false, playing: true })\n })\n\n // Pause\n this.player.on('pause', () => {\n this.events.emit('pause')\n this.events.emit('statechange', { paused: true, playing: false })\n })\n\n // Ended\n this.player.on('ended', () => {\n this.events.emit('ended')\n this.events.emit('statechange', { ended: true, playing: false })\n })\n\n // Time update\n this.player.on('timeupdate', (data: { seconds: number }) => {\n this.events.emit('timeupdate', data.seconds)\n })\n\n // Seeking\n this.player.on('seeking', () => {\n this.events.emit('seeking')\n })\n\n this.player.on('seeked', () => {\n this.events.emit('seeked')\n })\n\n // Buffering\n this.player.on('bufferstart', () => {\n this.events.emit('waiting')\n this.events.emit('statechange', { waiting: true })\n })\n\n this.player.on('bufferend', () => {\n this.events.emit('statechange', { waiting: false })\n })\n\n // Progress\n this.player.on('progress', (data: { percent: number }) => {\n const buffered = [{ start: 0, end: data.percent * this._duration }]\n this.events.emit('progress', buffered)\n })\n\n // Volume\n this.player.on('volumechange', async () => {\n const [volume, muted] = await Promise.all([this.player!.getVolume(), this.player!.getMuted()])\n this.events.emit('volumechange', volume, muted)\n })\n\n // Playback rate\n this.player.on('playbackratechange', (data: { playbackRate: number }) => {\n this.events.emit('ratechange', data.playbackRate)\n })\n\n // Quality change\n this.player.on('qualitychange', async () => {\n await this.updateQualities()\n const current = this._qualities.find((q) => q.selected)\n this.events.emit('qualitychange', current || null)\n })\n\n // Error\n this.player.on('error', (error: { name: string; message: string }) => {\n this.emitError(5, error.message, error)\n })\n }\n\n private async updateQualities(): Promise<void> {\n if (!this.player) return\n\n try {\n const qualities = await this.player.getQualities()\n this._qualities = qualities.map((q) => {\n // Parse resolution from label (e.g., \"1080p\", \"720p\")\n const match = q.label.match(/(\\d+)p/)\n const height = match ? parseInt(match[1], 10) : 0\n\n return {\n id: q.id,\n width: Math.round(height * (16 / 9)),\n height,\n bitrate: 0,\n selected: q.active,\n }\n })\n\n this.events.emit('statechange', { qualities: this._qualities })\n } catch {\n // Quality API not available for all videos\n }\n }\n\n // === Playback ===\n\n async play(): Promise<void> {\n try {\n await this.player?.play()\n } catch (error) {\n if ((error as Error).name === 'NotAllowedError') {\n this.emitError(1, 'Playback was blocked. User interaction required.', error)\n } else {\n throw error\n }\n }\n }\n\n pause(): void {\n this.player?.pause()\n }\n\n stop(): void {\n this.pause()\n this.seekTo(0)\n }\n\n // === Seeking ===\n\n seekTo(time: number): void {\n this.player?.setCurrentTime(time)\n }\n\n getCurrentTime(): number {\n // Sync call not available, return cached or 0\n return 0\n }\n\n getDuration(): number {\n return this._duration\n }\n\n // === Volume ===\n\n setVolume(volume: number): void {\n this.player?.setVolume(Math.max(0, Math.min(1, volume)))\n }\n\n getVolume(): number {\n return 1 // Async, return default\n }\n\n setMuted(muted: boolean): void {\n this.player?.setMuted(muted)\n }\n\n getMuted(): boolean {\n return false // Async, return default\n }\n\n // === Playback Rate ===\n\n setPlaybackRate(rate: number): void {\n this.player?.setPlaybackRate(rate)\n }\n\n getPlaybackRate(): number {\n return 1 // Async, return default\n }\n\n // === Quality ===\n\n getQualities(): VideoQuality[] {\n return this._qualities\n }\n\n setQuality(quality: VideoQuality | 'auto'): void {\n if (!this.player) return\n\n if (quality === 'auto') {\n this.player.setQuality('auto')\n } else {\n this.player.setQuality(quality.id)\n }\n }\n\n // === Text Tracks ===\n\n async enableTextTrack(language: string): Promise<void> {\n await this.player?.enableTextTrack(language)\n }\n\n async disableTextTrack(): Promise<void> {\n await this.player?.disableTextTrack()\n }\n\n // === Chapters ===\n\n async getChapters(): Promise<Array<{ title: string; startTime: number; index: number }>> {\n if (!this.player) return []\n try {\n return await this.player.getChapters()\n } catch {\n return []\n }\n }\n}\n\n/**\n * Vimeo Provider Loader\n */\nexport const vimeoLoader = {\n name: 'vimeo',\n type: 'vimeo' as ProviderType,\n\n canPlay(src: Src): boolean {\n return isVimeoSource(src)\n },\n\n mediaType(): 'video' {\n return 'video'\n },\n\n preconnect(): string[] {\n return ['https://player.vimeo.com', 'https://i.vimeocdn.com', 'https://f.vimeocdn.com']\n },\n\n async load(container: HTMLElement, options: PlayerOptions): Promise<VimeoProvider> {\n const provider = new VimeoProvider()\n await provider.setup(container, options)\n return provider\n },\n}\n",
11
+ "/**\n * ts-video-player HLS Provider\n *\n * HLS streaming provider using hls.js library.\n * Supports adaptive bitrate streaming, quality selection, and live streams.\n *\n * @module providers/hls\n */\n\nimport type {\n ProviderType,\n Src,\n HLSSource,\n PlayerOptions,\n VideoQuality,\n AudioTrack,\n TextTrack,\n} from '../types'\nimport { BaseProvider } from './base'\nimport { MediaEventsNormalizer, onFullscreenChange, onPiPChange } from '../core/events'\n\n// =============================================================================\n// HLS Detection\n// =============================================================================\n\n/**\n * Check if source is an HLS source\n */\nexport function isHLSSource(src: Src): boolean {\n if (typeof src === 'string') {\n const url = src.toLowerCase()\n return url.endsWith('.m3u8') || url.includes('application/x-mpegurl') || url.includes('application/vnd.apple.mpegurl')\n }\n\n if (typeof src === 'object' && 'type' in src) {\n const type = (src as HLSSource).type?.toLowerCase() || ''\n return type === 'application/x-mpegurl' || type === 'application/vnd.apple.mpegurl'\n }\n\n return false\n}\n\n/**\n * Check if native HLS is supported (Safari, iOS)\n */\nexport function isNativeHLSSupported(): boolean {\n const video = document.createElement('video')\n return video.canPlayType('application/vnd.apple.mpegurl') !== ''\n}\n\n// =============================================================================\n// HLS.js Types\n// =============================================================================\n\ninterface HlsConfig {\n enableWorker?: boolean\n lowLatencyMode?: boolean\n backBufferLength?: number\n maxBufferLength?: number\n maxMaxBufferLength?: number\n startLevel?: number\n autoStartLoad?: boolean\n debug?: boolean\n [key: string]: unknown\n}\n\ninterface HlsLevel {\n bitrate: number\n width: number\n height: number\n codecSet: string\n url: string[]\n audioCodec?: string\n videoCodec?: string\n}\n\ninterface HlsAudioTrack {\n id: number\n name: string\n lang?: string\n default: boolean\n autoselect: boolean\n forced: boolean\n url: string\n}\n\ninterface HlsSubtitleTrack {\n id: number\n name: string\n lang?: string\n default: boolean\n autoselect: boolean\n forced: boolean\n url: string\n}\n\ninterface HlsEvents {\n MEDIA_ATTACHED: string\n MEDIA_DETACHED: string\n MANIFEST_LOADED: string\n MANIFEST_PARSED: string\n LEVEL_LOADED: string\n LEVEL_SWITCHED: string\n AUDIO_TRACK_LOADED: string\n AUDIO_TRACK_SWITCHED: string\n SUBTITLE_TRACK_LOADED: string\n SUBTITLE_TRACK_SWITCH: string\n FRAG_LOADED: string\n FRAG_BUFFERED: string\n ERROR: string\n}\n\ninterface Hls {\n config: HlsConfig\n media: HTMLVideoElement | null\n currentLevel: number\n nextLevel: number\n loadLevel: number\n autoLevelEnabled: boolean\n levels: HlsLevel[]\n audioTracks: HlsAudioTrack[]\n audioTrack: number\n subtitleTracks: HlsSubtitleTrack[]\n subtitleTrack: number\n liveSyncPosition: number | null\n\n loadSource(src: string): void\n attachMedia(media: HTMLVideoElement): void\n detachMedia(): void\n startLoad(startPosition?: number): void\n stopLoad(): void\n recoverMediaError(): void\n destroy(): void\n on(event: string, handler: (...args: any[]) => void): void\n off(event: string, handler: (...args: any[]) => void): void\n}\n\ninterface HlsStatic {\n new (config?: HlsConfig): Hls\n isSupported(): boolean\n Events: HlsEvents\n ErrorTypes: {\n NETWORK_ERROR: string\n MEDIA_ERROR: string\n KEY_SYSTEM_ERROR: string\n MUX_ERROR: string\n OTHER_ERROR: string\n }\n ErrorDetails: Record<string, string>\n}\n\ndeclare global {\n interface Window {\n Hls?: HlsStatic\n }\n}\n\n// =============================================================================\n// HLS Provider\n// =============================================================================\n\nconst HLS_CDN_DEFAULT = 'https://cdn.jsdelivr.net/npm/hls.js@latest/dist/hls.min.js'\n\n/**\n * HLS streaming provider\n */\nexport class HLSProvider extends BaseProvider {\n readonly name = 'hls'\n readonly type: ProviderType = 'hls'\n\n private video: HTMLVideoElement | null = null\n private hls: Hls | null = null\n private eventsNormalizer: MediaEventsNormalizer | null = null\n private cleanupFullscreen: (() => void) | null = null\n private cleanupPiP: (() => void) | null = null\n private useNativeHLS = false\n private _qualities: VideoQuality[] = []\n private _audioTracks: AudioTrack[] = []\n private _textTracks: TextTrack[] = []\n private currentQualityIndex = -1 // -1 = auto\n\n get mediaElement(): HTMLVideoElement | null {\n return this.video\n }\n\n /**\n * Whether live sync is supported\n */\n get canLiveSync(): boolean {\n return !this.useNativeHLS && this.hls !== null\n }\n\n /**\n * Get HLS.js config\n */\n get hlsConfig(): HlsConfig {\n return this.hls?.config || {}\n }\n\n // === Lifecycle ===\n\n protected async initialize(): Promise<void> {\n if (!this.container) {\n throw new Error('Container element is required')\n }\n\n // Create video element\n this.video = document.createElement('video')\n this.video.className = 'ts-video-player__media'\n\n // Set attributes\n if (this.options.autoplay) this.video.autoplay = true\n if (this.options.loop) this.video.loop = true\n if (this.options.muted) this.video.muted = true\n if (this.options.playsinline) this.video.playsInline = true\n if (this.options.preload) this.video.preload = this.options.preload\n if (this.options.crossorigin) this.video.crossOrigin = this.options.crossorigin\n if (this.options.poster) this.video.poster = this.options.poster\n if (this.options.volume !== undefined) this.video.volume = this.options.volume\n\n this.container.appendChild(this.video)\n\n // Setup event normalization\n this.eventsNormalizer = new MediaEventsNormalizer(this.video, this.events)\n\n // Setup fullscreen/PiP listeners\n this.cleanupFullscreen = onFullscreenChange((fullscreen) => {\n this.events.emit('fullscreenchange', fullscreen)\n })\n\n this.cleanupPiP = onPiPChange(this.video, (pip) => {\n this.events.emit('pipchange', pip)\n })\n\n // Check for native HLS support\n this.useNativeHLS = isNativeHLSSupported()\n\n // Load HLS.js if needed\n if (!this.useNativeHLS) {\n await this.loadHLSLibrary()\n }\n\n // Emit dimensions and feature availability on load\n this.video.addEventListener('loadedmetadata', () => {\n const fullscreenAvailability = this.getFeatureAvailability('fullscreen')\n const pipAvailability = this.getFeatureAvailability('pip')\n const volumeAvailability = this.getFeatureAvailability('volume')\n this.events.emit('statechange', {\n videoWidth: this.video!.videoWidth,\n videoHeight: this.video!.videoHeight,\n aspectRatio: (this.video!.videoHeight > 0 ? this.video!.videoWidth / this.video!.videoHeight : 0) || 16 / 9,\n canFullscreen: fullscreenAvailability === 'available',\n canPictureInPicture: pipAvailability === 'available',\n fullscreenAvailability,\n pipAvailability,\n volumeAvailability,\n })\n this.events.emit('availabilitychange', 'fullscreen', fullscreenAvailability)\n this.events.emit('availabilitychange', 'pip', pipAvailability)\n this.events.emit('availabilitychange', 'volume', volumeAvailability)\n })\n }\n\n private async loadHLSLibrary(): Promise<void> {\n if (window.Hls) return\n\n return new Promise((resolve, reject) => {\n const script = document.createElement('script')\n script.src = this.options.hlsCdnUrl || HLS_CDN_DEFAULT\n script.async = true\n script.onload = () => resolve()\n script.onerror = () => reject(new Error('Failed to load HLS.js'))\n document.head.appendChild(script)\n })\n }\n\n protected cleanup(): void {\n this.eventsNormalizer?.destroy()\n this.cleanupFullscreen?.()\n this.cleanupPiP?.()\n\n if (this.hls) {\n this.hls.destroy()\n this.hls = null\n }\n\n if (this.video) {\n this.video.pause()\n this.video.removeAttribute('src')\n this.video.load()\n this.video.remove()\n this.video = null\n }\n\n this._qualities = []\n this._audioTracks = []\n this._textTracks = []\n }\n\n // === Loading ===\n\n canPlay(src: Src): boolean {\n return isHLSSource(src)\n }\n\n async load(src: Src): Promise<void> {\n if (!this.video) return\n\n const url = typeof src === 'string' ? src : (src as HLSSource).src\n\n if (this.useNativeHLS) {\n // Use native HLS (Safari/iOS)\n this.video.src = url\n this.video.load()\n return\n }\n\n // Use HLS.js\n if (!window.Hls) {\n await this.loadHLSLibrary()\n }\n\n if (!window.Hls?.isSupported()) {\n this.emitError(4, 'HLS is not supported in this browser')\n return\n }\n\n // Destroy existing instance\n if (this.hls) {\n this.hls.destroy()\n }\n\n // Build config\n const config: HlsConfig = {\n enableWorker: true,\n lowLatencyMode: false,\n ...this.options.hlsConfig,\n }\n\n // Create new HLS instance\n this.hls = new window.Hls(config)\n this.attachHLSEvents()\n\n // Attach and load\n this.hls.attachMedia(this.video)\n this.hls.loadSource(url)\n }\n\n private attachHLSEvents(): void {\n if (!this.hls || !window.Hls) return\n\n const Hls = window.Hls\n\n // Manifest loaded\n this.hls.on(Hls.Events.MANIFEST_PARSED, (_event: string, data: { levels: HlsLevel[] }) => {\n this.updateQualities(data.levels)\n\n // Auto-start load\n if (this.options.autoplay) {\n this.video?.play().catch(() => {})\n }\n })\n\n // Level switched\n this.hls.on(Hls.Events.LEVEL_SWITCHED, (_event: string, data: { level: number }) => {\n this.currentQualityIndex = data.level\n this.updateQualitySelection()\n this.events.emit('qualitychange', this._qualities[data.level] || null)\n })\n\n // Audio tracks loaded\n this.hls.on(Hls.Events.AUDIO_TRACK_LOADED, () => {\n this.updateAudioTracks()\n })\n\n // Audio track switched\n this.hls.on(Hls.Events.AUDIO_TRACK_SWITCHED, () => {\n this.updateAudioTracks()\n const current = this._audioTracks.find((t) => t.selected)\n this.events.emit('audiotrackchange', current || null)\n })\n\n // Subtitle tracks loaded\n this.hls.on(Hls.Events.SUBTITLE_TRACK_LOADED, () => {\n this.updateTextTracks()\n })\n\n // Error handling\n this.hls.on(Hls.Events.ERROR, (_event: string, data: { type: string; details: string; fatal: boolean }) => {\n if (data.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n // Try to recover from network error\n this.hls?.startLoad()\n break\n case Hls.ErrorTypes.MEDIA_ERROR:\n // Try to recover from media error\n this.hls?.recoverMediaError()\n break\n default:\n // Unrecoverable error\n this.emitError(5, `HLS fatal error: ${data.details}`, data)\n this.hls?.destroy()\n break\n }\n }\n })\n }\n\n private updateQualities(levels: HlsLevel[]): void {\n this._qualities = levels.map((level, index) => ({\n id: String(index),\n width: level.width,\n height: level.height,\n bitrate: level.bitrate,\n codec: level.codecSet || level.videoCodec || undefined,\n selected: index === this.currentQualityIndex,\n }))\n\n this.events.emit('statechange', { qualities: this._qualities })\n }\n\n private updateQualitySelection(): void {\n this._qualities = this._qualities.map((q, i) => ({\n ...q,\n selected: i === this.currentQualityIndex,\n }))\n }\n\n private updateAudioTracks(): void {\n if (!this.hls) return\n\n this._audioTracks = this.hls.audioTracks.map((track, index) => ({\n id: String(track.id),\n label: track.name || `Track ${index + 1}`,\n language: track.lang || '',\n kind: track.default ? 'main' : 'alternative',\n selected: index === this.hls!.audioTrack,\n }))\n\n this.events.emit('statechange', { audioTracks: this._audioTracks })\n }\n\n private updateTextTracks(): void {\n if (!this.hls) return\n\n this._textTracks = this.hls.subtitleTracks.map((track, index) => ({\n id: String(track.id),\n kind: 'subtitles' as const,\n label: track.name || `Subtitle ${index + 1}`,\n language: track.lang || '',\n mode: (index === this.hls!.subtitleTrack ? 'showing' : 'disabled') as TextTrack['mode'],\n cues: [],\n }))\n\n this.events.emit('statechange', { textTracks: this._textTracks })\n }\n\n // === Playback ===\n\n async play(): Promise<void> {\n if (!this.video) return\n try {\n await this.video.play()\n } catch (error) {\n if ((error as Error).name === 'NotAllowedError') {\n this.emitError(1, 'Playback was blocked. User interaction required.', error)\n } else {\n throw error\n }\n }\n }\n\n pause(): void {\n this.video?.pause()\n }\n\n // === Seeking ===\n\n seekTo(time: number): void {\n if (this.video) {\n this.video.currentTime = Math.max(0, Math.min(time, this.getDuration()))\n }\n }\n\n getCurrentTime(): number {\n return this.video?.currentTime || 0\n }\n\n getDuration(): number {\n return this.video?.duration || 0\n }\n\n /**\n * Sync to live edge (for live streams)\n */\n syncToLive(): void {\n if (this.hls?.liveSyncPosition != null) {\n this.seekTo(this.hls.liveSyncPosition)\n }\n }\n\n // === Volume ===\n\n setVolume(volume: number): void {\n if (this.video) {\n this.video.volume = Math.max(0, Math.min(1, volume))\n }\n }\n\n getVolume(): number {\n return this.video?.volume || 1\n }\n\n setMuted(muted: boolean): void {\n if (this.video) {\n this.video.muted = muted\n }\n }\n\n getMuted(): boolean {\n return this.video?.muted || false\n }\n\n // === Playback Rate ===\n\n setPlaybackRate(rate: number): void {\n if (this.video) {\n this.video.playbackRate = Math.max(0.25, Math.min(4, rate))\n }\n }\n\n getPlaybackRate(): number {\n return this.video?.playbackRate || 1\n }\n\n // === Quality ===\n\n getQualities(): VideoQuality[] {\n return this._qualities\n }\n\n setQuality(quality: VideoQuality | 'auto'): void {\n if (!this.hls) return\n\n if (quality === 'auto') {\n this.hls.currentLevel = -1 // Auto\n this.currentQualityIndex = -1\n this.events.emit('statechange', { autoQuality: true })\n } else {\n const index = parseInt(quality.id, 10)\n if (!isNaN(index) && index >= 0 && index < this._qualities.length) {\n this.hls.currentLevel = index\n this.currentQualityIndex = index\n this.events.emit('statechange', { autoQuality: false })\n }\n }\n }\n\n // === Audio Tracks ===\n\n getAudioTracks(): AudioTrack[] {\n return this._audioTracks\n }\n\n setAudioTrack(trackId: string): void {\n if (!this.hls) return\n\n const index = parseInt(trackId, 10)\n if (!isNaN(index) && index >= 0 && index < this.hls.audioTracks.length) {\n this.hls.audioTrack = index\n }\n }\n\n // === Text Tracks ===\n\n getTextTracks(): TextTrack[] {\n return this._textTracks\n }\n\n setTextTrackMode(trackId: string, mode: 'disabled' | 'hidden' | 'showing'): void {\n if (!this.hls) return\n\n if (mode === 'showing') {\n const index = parseInt(trackId, 10)\n if (!isNaN(index)) {\n this.hls.subtitleTrack = index\n }\n } else {\n this.hls.subtitleTrack = -1\n }\n\n this.updateTextTracks()\n const current = this._textTracks.find((t) => t.mode === 'showing')\n this.events.emit('texttrackchange', current || null)\n }\n\n}\n\n/**\n * HLS Provider Loader\n */\nexport const hlsLoader = {\n name: 'hls',\n type: 'hls' as ProviderType,\n\n canPlay(src: Src): boolean {\n return isHLSSource(src)\n },\n\n mediaType(): 'video' {\n return 'video'\n },\n\n preconnect(): string[] {\n return ['https://cdn.jsdelivr.net']\n },\n\n async load(container: HTMLElement, options: PlayerOptions): Promise<HLSProvider> {\n const provider = new HLSProvider()\n await provider.setup(container, options)\n return provider\n },\n}\n",
12
+ "/**\n * DASH Provider\n *\n * Media provider for MPEG-DASH streaming using dash.js.\n *\n * @module providers/dash\n */\n\nimport { BaseProvider } from './base'\nimport type {\n Src,\n ProviderLoader,\n VideoQuality,\n AudioTrack,\n TextTrack,\n PlayerOptions,\n DRMConfig,\n} from '../types'\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface DASHSource {\n src: string\n type: 'dash'\n /** DRM configuration */\n drm?: DRMConfig\n}\n\nexport interface DASHProviderConfig {\n /** Custom dash.js settings */\n dashConfig?: Record<string, any>\n /** Enable low latency mode */\n lowLatency?: boolean\n /** Retry parameters */\n retry?: {\n maxAttempts: number\n delay: number\n }\n}\n\n// =============================================================================\n// DASH.js Loading\n// =============================================================================\n\nlet dashjs: any = null\nlet dashLoading: Promise<any> | null = null\n\nconst DASH_CDN_DEFAULT = 'https://cdn.dashjs.org/latest/dash.all.min.js'\n\n/**\n * Load dash.js from CDN\n */\nasync function loadDashJS(cdnUrl?: string): Promise<any> {\n if (dashjs) return dashjs\n\n if (dashLoading) return dashLoading\n\n dashLoading = new Promise((resolve, reject) => {\n // Check if already loaded globally\n if (typeof window !== 'undefined' && (window as any).dashjs) {\n dashjs = (window as any).dashjs\n resolve(dashjs)\n return\n }\n\n const script = document.createElement('script')\n script.src = cdnUrl || DASH_CDN_DEFAULT\n script.async = true\n\n script.onload = () => {\n dashjs = (window as any).dashjs\n resolve(dashjs)\n }\n\n script.onerror = () => {\n reject(new Error('Failed to load dash.js'))\n }\n\n document.head.appendChild(script)\n })\n\n return dashLoading\n}\n\n// =============================================================================\n// Source Detection\n// =============================================================================\n\n/**\n * Check if source is a DASH manifest\n */\nexport function isDASHSource(src: Src): src is DASHSource | string {\n if (typeof src === 'object' && 'type' in src && src.type === 'dash') {\n return true\n }\n\n if (typeof src === 'string') {\n return src.includes('.mpd') || src.includes('manifest(format=mpd')\n }\n\n return false\n}\n\n// =============================================================================\n// DASH Provider\n// =============================================================================\n\nexport class DASHProvider extends BaseProvider {\n readonly name = 'dash'\n readonly type = 'dash' as const\n\n private dash: any = null\n private video: HTMLVideoElement | null = null\n private source: DASHSource | null = null\n private config: DASHProviderConfig = {}\n private _volume = 1\n private _muted = false\n private _playbackRate = 1\n\n get mediaElement(): HTMLVideoElement | null {\n return this.video\n }\n\n /**\n * Initialize the provider\n */\n protected async initialize(): Promise<void> {\n // Create video element\n this.video = document.createElement('video')\n this.video.style.width = '100%'\n this.video.style.height = '100%'\n this.video.style.display = 'block'\n\n // Load dash.js\n await loadDashJS(this.options.dashCdnUrl)\n\n // Create player instance\n this.dash = dashjs.MediaPlayer().create()\n\n // Apply custom config from options\n if (this.options.dashConfig) {\n this.config.dashConfig = this.options.dashConfig as Record<string, any>\n }\n\n if (this.config.dashConfig) {\n Object.entries(this.config.dashConfig).forEach(([key, value]) => {\n this.dash.updateSettings({ [key]: value })\n })\n }\n\n // Enable low latency mode\n if (this.config.lowLatency) {\n this.dash.updateSettings({\n streaming: {\n lowLatencyEnabled: true,\n liveDelay: 3,\n liveCatchUpMinDrift: 0.05,\n liveCatchUpPlaybackRate: 0.5,\n },\n })\n }\n\n // Attach dash.js events\n this.attachDashEvents()\n\n // Append to container\n if (this.container) {\n this.container.appendChild(this.video)\n }\n\n // Add video element events\n this.attachVideoEvents()\n }\n\n /**\n * Attach video element event listeners\n */\n private attachVideoEvents(): void {\n if (!this.video) return\n\n this.video.addEventListener('play', () => this.events.emit('play'))\n this.video.addEventListener('pause', () => this.events.emit('pause'))\n this.video.addEventListener('ended', () => this.events.emit('ended'))\n this.video.addEventListener('timeupdate', () => this.events.emit('timeupdate', this.getCurrentTime()))\n this.video.addEventListener('durationchange', () => this.events.emit('durationchange', this.getDuration()))\n this.video.addEventListener('volumechange', () => {\n this.events.emit('volumechange', this.getVolume(), this.getMuted())\n })\n this.video.addEventListener('waiting', () => this.events.emit('waiting'))\n this.video.addEventListener('playing', () => this.events.emit('playing'))\n this.video.addEventListener('seeking', () => this.events.emit('seeking'))\n this.video.addEventListener('seeked', () => this.events.emit('seeked'))\n this.video.addEventListener('progress', () => {\n const ranges: Array<{ start: number, end: number }> = []\n for (let i = 0; i < this.video!.buffered.length; i++) {\n ranges.push({\n start: this.video!.buffered.start(i),\n end: this.video!.buffered.end(i),\n })\n }\n this.events.emit('progress', ranges)\n })\n this.video.addEventListener('loadedmetadata', () => {\n this.events.emit('loadedmetadata')\n const fullscreenAvailability = this.getFeatureAvailability('fullscreen')\n const pipAvailability = this.getFeatureAvailability('pip')\n const volumeAvailability = this.getFeatureAvailability('volume')\n this.events.emit('statechange', {\n videoWidth: this.video!.videoWidth,\n videoHeight: this.video!.videoHeight,\n aspectRatio: (this.video!.videoHeight > 0 ? this.video!.videoWidth / this.video!.videoHeight : 0) || 16 / 9,\n canFullscreen: fullscreenAvailability === 'available',\n canPictureInPicture: pipAvailability === 'available',\n fullscreenAvailability,\n pipAvailability,\n volumeAvailability,\n })\n this.events.emit('availabilitychange', 'fullscreen', fullscreenAvailability)\n this.events.emit('availabilitychange', 'pip', pipAvailability)\n this.events.emit('availabilitychange', 'volume', volumeAvailability)\n })\n this.video.addEventListener('loadeddata', () => this.events.emit('loadeddata'))\n this.video.addEventListener('canplay', () => this.events.emit('canplay'))\n this.video.addEventListener('canplaythrough', () => this.events.emit('canplaythrough'))\n this.video.addEventListener('ratechange', () => this.events.emit('ratechange', this.getPlaybackRate()))\n }\n\n /**\n * Attach dash.js event listeners\n */\n private attachDashEvents(): void {\n if (!dashjs) return\n\n const MediaPlayer = dashjs.MediaPlayer\n\n // Quality change\n this.dash.on(MediaPlayer.events.QUALITY_CHANGE_RENDERED, () => {\n this.events.emit('qualitychange', this.getQualities().find(q => q.selected) || null)\n })\n\n // Manifest loaded\n this.dash.on(MediaPlayer.events.MANIFEST_LOADED, () => {\n // Qualities and tracks are now available\n })\n\n // Error handling\n this.dash.on(MediaPlayer.events.ERROR, (event: any) => {\n this.emitError(\n event.error?.code || 0,\n event.error?.message || 'DASH playback error',\n event.error\n )\n })\n }\n\n /**\n * Configure DRM protection\n */\n private configureDRM(drm: DRMConfig): void {\n const protectionData: Record<string, any> = {}\n\n if (drm.widevine) {\n protectionData['com.widevine.alpha'] = {\n serverURL: drm.widevine.url,\n httpRequestHeaders: drm.widevine.headers,\n }\n }\n\n if (drm.playready) {\n protectionData['com.microsoft.playready'] = {\n serverURL: drm.playready.url,\n httpRequestHeaders: drm.playready.headers,\n }\n }\n\n if (drm.fairplay) {\n protectionData['com.apple.fps.1_0'] = {\n serverURL: drm.fairplay.url,\n serverCertificateURL: drm.fairplay.certificateUrl,\n httpRequestHeaders: drm.fairplay.headers,\n }\n }\n\n this.dash.setProtectionData(protectionData)\n }\n\n /**\n * Load a source\n */\n async load(src: Src): Promise<void> {\n if (!this.video || !this.dash) return\n\n // Parse source\n if (typeof src === 'string') {\n this.source = { src, type: 'dash' }\n }\n else if (isDASHSource(src)) {\n this.source = src as DASHSource\n }\n else {\n this.emitError(4, 'Invalid DASH source')\n return\n }\n\n // Configure DRM if provided\n if (this.source.drm) {\n this.configureDRM(this.source.drm)\n }\n\n // Initialize with video element and source\n this.dash.initialize(this.video, this.source.src, false)\n }\n\n /**\n * Check if source can be played\n */\n canPlay(src: Src): boolean {\n return isDASHSource(src)\n }\n\n /**\n * Cleanup the provider\n */\n protected cleanup(): void {\n if (this.dash) {\n this.dash.reset()\n this.dash = null\n }\n\n if (this.video) {\n this.video.remove()\n this.video = null\n }\n\n this.source = null\n }\n\n // ==========================================================================\n // Playback\n // ==========================================================================\n\n async play(): Promise<void> {\n if (!this.video) return\n try {\n await this.video.play()\n } catch (error) {\n if ((error as Error).name === 'NotAllowedError') {\n this.emitError(1, 'Playback was blocked. User interaction required.', error)\n } else {\n throw error\n }\n }\n }\n\n pause(): void {\n if (this.video) {\n this.video.pause()\n }\n }\n\n // ==========================================================================\n // Seeking\n // ==========================================================================\n\n seekTo(time: number): void {\n if (this.video) {\n this.video.currentTime = time\n }\n }\n\n getCurrentTime(): number {\n return this.video?.currentTime || 0\n }\n\n getDuration(): number {\n return this.video?.duration || 0\n }\n\n // ==========================================================================\n // Volume\n // ==========================================================================\n\n setVolume(volume: number): void {\n this._volume = Math.max(0, Math.min(1, volume))\n if (this.video) {\n this.video.volume = this._volume\n }\n }\n\n getVolume(): number {\n return this.video?.volume ?? this._volume\n }\n\n setMuted(muted: boolean): void {\n this._muted = muted\n if (this.video) {\n this.video.muted = muted\n }\n }\n\n getMuted(): boolean {\n return this.video?.muted ?? this._muted\n }\n\n // ==========================================================================\n // Playback Rate\n // ==========================================================================\n\n setPlaybackRate(rate: number): void {\n this._playbackRate = rate\n if (this.video) {\n this.video.playbackRate = rate\n }\n }\n\n getPlaybackRate(): number {\n return this.video?.playbackRate ?? this._playbackRate\n }\n\n // ==========================================================================\n // Live\n // ==========================================================================\n\n get isLive(): boolean {\n return this.dash?.isDynamic() ?? false\n }\n\n get liveLatency(): number {\n return this.dash?.getCurrentLiveLatency() ?? 0\n }\n\n get canLiveSync(): boolean {\n return this.isLive\n }\n\n syncToLive(): void {\n if (this.dash && this.isLive) {\n this.dash.seekToOriginalLive()\n }\n }\n\n // ==========================================================================\n // Quality\n // ==========================================================================\n\n getQualities(): VideoQuality[] {\n if (!this.dash) return []\n\n const bitrateInfoList = this.dash.getBitrateInfoListFor('video')\n if (!bitrateInfoList) return []\n\n const currentIndex = this.dash.getQualityFor('video')\n\n return bitrateInfoList.map((info: any, index: number) => ({\n id: `${index}`,\n label: `${info.height}p`,\n width: info.width,\n height: info.height,\n bitrate: info.bitrate,\n selected: index === currentIndex,\n }))\n }\n\n setQuality(quality: VideoQuality | 'auto'): void {\n if (!this.dash) return\n\n if (quality === 'auto') {\n this.dash.updateSettings({\n streaming: { abr: { autoSwitchBitrate: { video: true } } },\n })\n }\n else {\n const index = Number.parseInt(quality.id, 10)\n if (!Number.isNaN(index)) {\n this.dash.updateSettings({\n streaming: { abr: { autoSwitchBitrate: { video: false } } },\n })\n this.dash.setQualityFor('video', index)\n }\n }\n }\n\n get isAutoQuality(): boolean {\n if (!this.dash) return true\n const settings = this.dash.getSettings()\n return settings?.streaming?.abr?.autoSwitchBitrate?.video ?? true\n }\n\n // ==========================================================================\n // Audio Tracks\n // ==========================================================================\n\n getAudioTracks(): AudioTrack[] {\n if (!this.dash) return []\n\n const tracks = this.dash.getTracksFor('audio')\n if (!tracks) return []\n\n const currentTrack = this.dash.getCurrentTrackFor('audio')\n\n return tracks.map((track: any, index: number) => ({\n id: track.id || `${index}`,\n label: track.labels?.[0]?.text || track.lang || `Track ${index + 1}`,\n language: track.lang || '',\n kind: 'main' as const,\n selected: track === currentTrack,\n }))\n }\n\n setAudioTrack(trackId: string): void {\n if (!this.dash) return\n\n const tracks = this.dash.getTracksFor('audio')\n const track = tracks.find((t: any, i: number) => (t.id || `${i}`) === trackId)\n\n if (track) {\n this.dash.setCurrentTrack(track)\n }\n }\n\n // ==========================================================================\n // Text Tracks\n // ==========================================================================\n\n getTextTracks(): TextTrack[] {\n if (!this.dash) return []\n\n const tracks = this.dash.getTracksFor('text')\n if (!tracks) return []\n\n const currentTrack = this.dash.getCurrentTrackFor('text')\n\n return tracks.map((track: any, index: number) => ({\n id: track.id || `${index}`,\n label: track.labels?.[0]?.text || track.lang || `Subtitle ${index + 1}`,\n language: track.lang || '',\n kind: (track.kind || 'subtitles') as TextTrack['kind'],\n mode: (track === currentTrack ? 'showing' : 'disabled') as TextTrack['mode'],\n cues: [],\n }))\n }\n\n setTextTrackMode(trackId: string, mode: 'disabled' | 'hidden' | 'showing'): void {\n if (!this.dash) return\n\n if (mode === 'disabled') {\n this.dash.enableText(false)\n return\n }\n\n const tracks = this.dash.getTracksFor('text')\n const track = tracks.find((t: any, i: number) => (t.id || `${i}`) === trackId)\n\n if (track) {\n this.dash.setCurrentTrack(track)\n this.dash.enableText(mode === 'showing')\n }\n }\n}\n\n// =============================================================================\n// Provider Loader\n// =============================================================================\n\nexport const dashLoader: ProviderLoader = {\n name: 'dash',\n type: 'dash',\n\n canPlay(src: Src): boolean {\n return isDASHSource(src)\n },\n\n mediaType(): 'video' {\n return 'video'\n },\n\n async load(container: HTMLElement, options: PlayerOptions): Promise<DASHProvider> {\n const provider = new DASHProvider()\n await provider.setup(container, options)\n return provider\n },\n\n preconnect(): string[] {\n return ['https://cdn.dashjs.org']\n },\n}\n",
13
+ "/**\n * ts-video-player Providers\n *\n * Export all media providers.\n *\n * @module providers\n */\n\n// Base\nexport { BaseProvider } from './base'\n\n// HTML5 Video/Audio\nexport { HTML5Provider, html5Loader, isHTML5Source } from './html5'\n\n// YouTube\nexport { YouTubeProvider, youtubeLoader, isYouTubeSource, extractYouTubeId } from './youtube'\n\n// Vimeo\nexport { VimeoProvider, vimeoLoader, isVimeoSource, extractVimeoId, extractVimeoHash } from './vimeo'\n\n// HLS\nexport { HLSProvider, hlsLoader, isHLSSource, isNativeHLSSupported } from './hls'\n\n// DASH\nexport { DASHProvider, dashLoader, isDASHSource } from './dash'\n\nexport type { DASHSource, DASHProviderConfig } from './dash'\nexport type { DRMConfig } from '../types'\n\n// Re-export types\nexport type { Provider, ProviderLoader, ProviderType } from '../types'\n\n// =============================================================================\n// Provider Registry\n// =============================================================================\n\nimport type { ProviderLoader, Src } from '../types'\nimport { html5Loader } from './html5'\nimport { youtubeLoader } from './youtube'\nimport { vimeoLoader } from './vimeo'\nimport { hlsLoader } from './hls'\nimport { dashLoader } from './dash'\n\n/**\n * Default provider loaders in priority order\n */\nexport const defaultLoaders: ProviderLoader[] = [\n hlsLoader, // Check HLS first\n dashLoader, // Then DASH\n youtubeLoader, // Then YouTube\n vimeoLoader, // Then Vimeo\n html5Loader, // HTML5 as fallback\n]\n\n/**\n * Find the appropriate provider loader for a source\n */\nexport function findLoader(src: Src, loaders: ProviderLoader[] = defaultLoaders): ProviderLoader | null {\n for (const loader of loaders) {\n if (loader.canPlay(src)) {\n return loader\n }\n }\n return null\n}\n\nexport interface SourceCandidate {\n src: Src\n index: number\n loader: ProviderLoader\n}\n\n/** Resolve every playable source without discarding ordered fallbacks. */\nexport function findSourceCandidates(sources: readonly Src[], loaders: ProviderLoader[] = defaultLoaders): SourceCandidate[] {\n const candidates: SourceCandidate[] = []\n sources.forEach((src, index) => {\n const loader = findLoader(src, loaders)\n if (loader) candidates.push({ src, index, loader })\n })\n return candidates\n}\n\n/**\n * Detect media type from source\n */\nexport function detectMediaType(src: Src, loaders: ProviderLoader[] = defaultLoaders): 'video' | 'audio' | 'unknown' {\n const loader = findLoader(src, loaders)\n return loader?.mediaType(src) || 'unknown'\n}\n\n/**\n * Get preconnect hints for a source\n */\nexport function getPreconnectHints(src: Src, loaders: ProviderLoader[] = defaultLoaders): string[] {\n const loader = findLoader(src, loaders)\n return loader?.preconnect?.() || []\n}\n",
14
+ "/**\n * ts-video-player Player\n *\n * Main player class that orchestrates providers, state, and UI.\n *\n * @module player\n */\n\nimport type {\n Player as IPlayer,\n PlayerOptions,\n PlayerState,\n PlayerEventMap,\n Provider,\n ProviderLoader,\n Src,\n VideoQuality,\n} from './types'\nimport { StateStore, createStorageSync, selectBufferedAmount } from './core/state'\nimport { EventEmitter, createKeyboardHandler, createActivityDetector, type KeyboardActions } from './core/events'\nimport { createMediaSession, type MediaSessionOptions } from './core/media-session'\nimport { lockOrientation, unlockOrientation } from './core/orientation'\nimport { defaultLoaders, findSourceCandidates } from './providers'\n\n// =============================================================================\n// Player Class\n// =============================================================================\n\n/**\n * ts-video-player main class\n */\nexport class Player implements IPlayer {\n private _el: HTMLElement\n private _options: PlayerOptions\n private _store: StateStore\n private _events = new EventEmitter<PlayerEventMap>()\n private _provider: Provider | null = null\n private _loaders: ProviderLoader[]\n private _cleanupFns: Array<() => void> = []\n private _destroyed = false\n private _sourceLoadId = 0\n private _announcer: HTMLElement | null = null\n\n /**\n * Create a new player instance\n */\n constructor(container: HTMLElement | string, options: PlayerOptions = {}) {\n // Resolve container\n if (typeof container === 'string') {\n const el = document.querySelector(container) as HTMLElement\n if (!el) throw new Error(`Container element not found: ${container}`)\n this._el = el\n // eslint-disable-next-line style/brace-style\n } else {\n this._el = container\n }\n\n this._options = { ...defaultOptions, ...options }\n this._loaders = defaultLoaders\n this._store = new StateStore()\n\n // Setup\n this.setupElement()\n this.setupState()\n this.setupKeyboard()\n this.setupActivity()\n this.setupStorage()\n this.setupMediaSession()\n this.setupEvents()\n\n // Load initial source\n if (this._options.src) {\n this.setSrc(this._options.src)\n }\n\n // Emit init event\n this._events.emit('init')\n }\n\n // === Public Properties ===\n\n get el(): HTMLElement {\n return this._el\n }\n\n get state(): PlayerState {\n return this._store.getState()\n }\n\n get provider(): Provider | null {\n return this._provider\n }\n\n get ready(): boolean {\n return this._provider?.ready || false\n }\n\n // === Setup ===\n\n private setupElement(): void {\n this._el.classList.add('ts-video-player')\n this._el.setAttribute('tabindex', '0')\n this._el.setAttribute('role', 'region')\n this._el.setAttribute('aria-roledescription', 'video player')\n this._el.setAttribute('aria-label', this._options.title || 'Video player')\n this._el.setAttribute('aria-keyshortcuts', 'Space K M F I C ArrowLeft ArrowRight J L ArrowUp ArrowDown Home End 0 1 2 3 4 5 6 7 8 9')\n\n // Create inner structure\n const mediaContainer = document.createElement('div')\n mediaContainer.className = 'ts-video-player__container'\n this._el.appendChild(mediaContainer)\n\n // Create ARIA live region for screen reader announcements\n if (this._options.announcements !== false) {\n const liveRegion = document.createElement('div')\n liveRegion.className = 'ts-video-player__announcer'\n liveRegion.setAttribute('role', 'status')\n liveRegion.setAttribute('aria-live', 'polite')\n liveRegion.setAttribute('aria-atomic', 'true')\n // Visually hidden but accessible to screen readers\n liveRegion.style.cssText = 'position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0'\n this._el.appendChild(liveRegion)\n this._announcer = liveRegion\n }\n\n // Store reference\n const _el = this._el as any\n _el.__videoPlayer = this\n }\n\n private setupState(): void {\n // Initial state from options\n this._store.batch({\n volume: this._options.volume ?? 1,\n muted: this._options.muted ?? false,\n loop: this._options.loop ?? false,\n autoplay: this._options.autoplay ?? false,\n playsinline: this._options.playsinline ?? true,\n playbackRate: this._options.playbackRate ?? 1,\n poster: this._options.poster || '',\n title: this._options.title || '',\n preload: this._options.preload || 'metadata',\n })\n\n // Subscribe to state changes\n const unsubscribe = this._store.subscribe((state) => {\n // Update DOM attributes\n this.updateAttributes(state)\n })\n\n this._cleanupFns.push(unsubscribe)\n }\n\n private setupKeyboard(): void {\n if (this._options.keyboard === false) return\n\n const actions: KeyboardActions = {\n togglePlay: () => this.togglePlay(),\n toggleMute: () => this.toggleMute(),\n toggleFullscreen: () => this.toggleFullscreen(),\n togglePiP: () => this.togglePiP(),\n toggleCaptions: () => this.toggleCaptions(),\n seekBackward: () => this.seekBy(-5),\n seekForward: () => this.seekBy(5),\n volumeUp: () => this.setVolume(Math.min(1, this.state.volume + 0.1)),\n volumeDown: () => this.setVolume(Math.max(0, this.state.volume - 0.1)),\n speedUp: () => this.setPlaybackRate(Math.min(4, this.state.playbackRate + 0.25)),\n speedDown: () => this.setPlaybackRate(Math.max(0.25, this.state.playbackRate - 0.25)),\n seekStart: () => this.seekTo(0),\n seekEnd: () => this.seekTo(this.state.duration),\n seekPercent: (percent) => this.seekTo((percent / 100) * this.state.duration),\n }\n\n const config = typeof this._options.keyboard === 'object' ? this._options.keyboard : {}\n const handler = createKeyboardHandler(actions, {\n seekStep: config.seekStep,\n volumeStep: config.volumeStep,\n })\n\n const target = config.global ? document : this._el\n target.addEventListener('keydown', handler as EventListener)\n\n this._cleanupFns.push(() => target.removeEventListener('keydown', handler as EventListener))\n }\n\n private setupActivity(): void {\n const cleanup = createActivityDetector(this._el, {\n timeout: this._options.controlsTimeout || 3000,\n onActive: () => {\n this._store.batch({ userActive: true, controlsVisible: true })\n this._events.emit('useractivitychange', true)\n this._events.emit('controlschange', true)\n },\n onInactive: () => {\n // Only hide controls if playing\n if (this.state.playing) {\n this._store.batch({ userActive: false, controlsVisible: false })\n this._events.emit('useractivitychange', false)\n this._events.emit('controlschange', false)\n }\n },\n })\n\n this._cleanupFns.push(cleanup)\n\n // Pointer over tracking\n const onMouseEnter = () => this._store.set('pointerOver', true)\n const onMouseLeave = () => this._store.set('pointerOver', false)\n this._el.addEventListener('mouseenter', onMouseEnter)\n this._el.addEventListener('mouseleave', onMouseLeave)\n this._cleanupFns.push(\n () => this._el.removeEventListener('mouseenter', onMouseEnter),\n () => this._el.removeEventListener('mouseleave', onMouseLeave),\n )\n }\n\n private setupStorage(): void {\n if (!this._options.storage) return\n\n const config = typeof this._options.storage === 'object' ? this._options.storage : {}\n const storage = config.type === 'session' ? sessionStorage : localStorage\n\n const cleanup = createStorageSync(this._store, config.persist || ['volume', 'muted', 'playbackRate'], storage)\n\n this._cleanupFns.push(cleanup)\n }\n\n private setupMediaSession(): void {\n if (this._options.mediaSession === false) return\n\n const sessionOpts: MediaSessionOptions | undefined =\n typeof this._options.mediaSession === 'object'\n ? this._options.mediaSession\n : this._options.title\n ? { title: this._options.title }\n : undefined\n\n const cleanup = createMediaSession(\n this._store,\n {\n play: () => this.play(),\n pause: () => this.pause(),\n seekTo: (time) => this.seekTo(time),\n seekBy: (offset) => this.seekBy(offset),\n stop: () => this.stop(),\n },\n sessionOpts,\n )\n\n this._cleanupFns.push(cleanup)\n }\n\n private setupEvents(): void {\n // Attach option event listeners\n if (this._options.on) {\n for (const [event, handler] of Object.entries(this._options.on)) {\n if (handler) {\n this.on(event as keyof PlayerEventMap, handler as PlayerEventMap[keyof PlayerEventMap])\n }\n }\n }\n }\n\n private updateAttributes(state: PlayerState): void {\n const el = this._el\n\n // Playback state\n el.dataset.paused = String(state.paused)\n el.dataset.playing = String(state.playing)\n el.dataset.started = String(state.started)\n el.dataset.ended = String(state.ended)\n el.dataset.seeking = String(state.seeking)\n el.dataset.waiting = String(state.waiting)\n el.dataset.loop = String(state.loop)\n el.dataset.autoplay = String(state.autoplay)\n\n // Loading state\n el.dataset.loading = String(state.waiting || state.loadingState === 'loading')\n el.dataset.canPlay = String(state.canPlay)\n el.dataset.loadingState = state.loadingState\n el.setAttribute('aria-busy', String(state.waiting || state.loadingState === 'loading'))\n\n // Volume\n el.dataset.muted = String(state.muted)\n el.dataset.volumeLevel = state.muted || state.volume === 0\n ? 'silent'\n : state.volume < 0.5\n ? 'low'\n : 'high'\n\n // Fullscreen / PiP\n el.dataset.fullscreen = String(state.fullscreen)\n el.dataset.pip = String(state.pictureInPicture)\n\n // UI\n el.dataset.controlsVisible = String(state.controlsVisible)\n el.dataset.userActive = String(state.userActive)\n\n // Media type\n el.dataset.mediaType = state.mediaType\n el.dataset.streamType = state.streamType\n\n // Captions\n const hasActiveCaptions = state.textTracks.some((t) => t.mode === 'showing')\n el.dataset.captions = String(hasActiveCaptions)\n\n // Error\n el.dataset.error = String(!!state.error)\n }\n\n /**\n * Announce a message to screen readers via the ARIA live region\n */\n private announce(message: string): void {\n if (!this._announcer) return\n // Clear and set to force re-announcement of same message\n this._announcer.textContent = ''\n requestAnimationFrame(() => {\n if (this._announcer) this._announcer.textContent = message\n })\n }\n\n // === Lifecycle ===\n\n destroy(): void {\n if (this._destroyed) return\n this._destroyed = true\n this._sourceLoadId++\n\n // Emit destroy event\n this._events.emit('destroy')\n\n // Cleanup\n this._cleanupFns.forEach((fn) => fn())\n this._cleanupFns = []\n\n // Destroy provider\n this._provider?.destroy()\n this._provider = null\n\n // Remove events\n this._events.removeAllListeners()\n\n // Reset store\n this._store.reset()\n\n // Clear element\n this._el.classList.remove('ts-video-player')\n this._el.innerHTML = ''\n delete (this._el as any).__videoPlayer\n }\n\n // === Source ===\n\n async setSrc(src: Src | Src[]): Promise<void> {\n if (this._destroyed) return\n\n // Invalidate any older asynchronous provider load.\n const loadId = ++this._sourceLoadId\n const sources = Array.isArray(src) ? src : [src]\n if (sources.length === 0) {\n return\n }\n\n // Update state\n this._store.batch({\n sources,\n src: sources[0],\n loadingState: 'loading',\n error: null,\n })\n\n this._events.emit('sourceschange', sources)\n\n const candidates = findSourceCandidates(sources, this._loaders)\n if (candidates.length === 0) {\n this._store.batch({\n loadingState: 'error',\n error: { code: 4, message: 'No compatible provider found for source' },\n })\n return\n }\n\n let lastError: unknown\n for (const candidate of candidates) {\n if (this._destroyed || loadId !== this._sourceLoadId) return\n const { loader } = candidate\n\n if (this._provider && this._provider.type !== loader.type) {\n this._provider.destroy()\n this._provider = null\n this._events.emit('providerchange', null)\n }\n\n if (!this._provider) {\n const mediaContainer = this._el.querySelector('.ts-video-player__container') as HTMLElement\n try {\n this._provider = await loader.load(mediaContainer, {\n ...this._options,\n mediaType: loader.mediaType(candidate.src),\n })\n if (this._destroyed || loadId !== this._sourceLoadId) {\n this._provider.destroy()\n this._provider = null\n return\n }\n this._events.emit('providerchange', this._provider)\n this.attachProviderEvents(this._provider)\n }\n catch (error) {\n lastError = error\n this._provider = null\n continue\n }\n }\n\n try {\n // Native media elements should receive all same-provider sources so\n // the browser can choose by MIME and codec support.\n const compatibleSources = loader.type === 'video'\n ? candidates.filter(item => item.loader.type === loader.type).map(item => item.src)\n : [candidate.src]\n await this._provider.load(compatibleSources.length > 1 ? compatibleSources : candidate.src)\n if (this._destroyed || loadId !== this._sourceLoadId) return\n this._store.batch({\n src: candidate.src,\n currentSourceIndex: candidate.index,\n mediaType: loader.mediaType(candidate.src),\n providerType: loader.type,\n })\n return\n }\n catch (error) {\n lastError = error\n if (this._provider) {\n this._provider.destroy()\n this._provider = null\n }\n this._events.emit('providerchange', null)\n }\n }\n\n if (this._destroyed || loadId !== this._sourceLoadId) return\n this._store.batch({\n loadingState: 'error',\n error: { code: 4, message: 'Failed to load all compatible sources', details: lastError },\n })\n }\n\n getSrc(): Src | null {\n return this.state.src\n }\n\n private attachProviderEvents(provider: Provider): void {\n // Forward provider events and update state\n provider.on('loadstart', () => {\n this._store.set('loadingState', 'loading')\n this._events.emit('loadstart')\n })\n\n provider.on('loadedmetadata', () => {\n this._events.emit('loadedmetadata')\n })\n\n provider.on('loadeddata', () => {\n this._events.emit('loadeddata')\n })\n\n provider.on('canplay', () => {\n this._store.batch({ canPlay: true, loadingState: 'loaded' })\n this._events.emit('canplay')\n })\n\n provider.on('canplaythrough', () => {\n this._store.set('canPlayThrough', true)\n this._events.emit('canplaythrough')\n })\n\n provider.on('play', () => {\n this._store.batch({ paused: false, ended: false })\n this._events.emit('play')\n this.announce('Playing')\n })\n\n provider.on('pause', () => {\n this._store.set('paused', true)\n this._events.emit('pause')\n this.announce('Paused')\n })\n\n provider.on('playing', () => {\n this._store.batch({ playing: true, started: true, waiting: false, playbackState: 'playing' })\n this._events.emit('playing')\n })\n\n provider.on('waiting', () => {\n this._store.batch({ waiting: true, playbackState: 'buffering' })\n this._events.emit('waiting')\n })\n\n provider.on('seeking', () => {\n this._store.set('seeking', true)\n this._events.emit('seeking')\n })\n\n provider.on('seeked', () => {\n this._store.set('seeking', false)\n this._events.emit('seeked')\n })\n\n provider.on('timeupdate', (time) => {\n this._store.set('currentTime', time)\n this._events.emit('timeupdate', time)\n })\n\n provider.on('durationchange', (duration) => {\n this._store.set('duration', duration)\n this._events.emit('durationchange', duration)\n })\n\n provider.on('volumechange', (volume, muted) => {\n this._store.batch({ volume, muted })\n this._events.emit('volumechange', volume, muted)\n if (muted) {\n this.announce('Muted')\n // eslint-disable-next-line style/brace-style\n } else {\n this.announce(`Volume ${Math.round(volume * 100)}%`)\n }\n })\n\n provider.on('ratechange', (rate) => {\n this._store.set('playbackRate', rate)\n this._events.emit('ratechange', rate)\n })\n\n provider.on('progress', (buffered) => {\n this._store.batch({\n buffered,\n bufferedAmount: selectBufferedAmount({ ...this.state, buffered }),\n })\n this._events.emit('progress', buffered)\n })\n\n provider.on('ended', () => {\n this._store.batch({ ended: true, playing: false, playbackState: 'ended' })\n this._events.emit('ended')\n this.announce('Playback ended')\n\n // Handle loop\n if (this.state.loop) {\n this.seekTo(0)\n this.play()\n }\n })\n\n provider.on('error', (error) => {\n this._store.batch({ loadingState: 'error', error })\n this._events.emit('error', error)\n this.announce(`Error: ${error.message}`)\n })\n\n provider.on('statechange', (state) => {\n this._store.batch(state)\n this._events.emit('statechange', state)\n })\n\n provider.on('qualitychange', (quality) => {\n this._store.set('qualities', provider.getQualities())\n this._events.emit('qualitychange', quality)\n })\n\n provider.on('fullscreenchange', (fullscreen) => {\n this._store.set('fullscreen', fullscreen)\n this._events.emit('fullscreenchange', fullscreen)\n this.announce(fullscreen ? 'Entered fullscreen' : 'Exited fullscreen')\n })\n\n provider.on('pipchange', (pip) => {\n this._store.set('pictureInPicture', pip)\n this._events.emit('pipchange', pip)\n })\n\n provider.on('availabilitychange', (feature, availability) => {\n if (feature === 'volume') this._store.set('volumeAvailability', availability)\n else if (feature === 'fullscreen') this._store.set('fullscreenAvailability', availability)\n else if (feature === 'pip') this._store.set('pipAvailability', availability)\n this._events.emit('availabilitychange', feature, availability)\n })\n }\n\n // === Playback ===\n\n async play(): Promise<void> {\n if (!this._provider) return\n await this._provider.play()\n }\n\n pause(): void {\n this._provider?.pause()\n }\n\n togglePlay(): void {\n if (this.state.paused) {\n this.play().catch(() => {\n // Play rejection is already handled and emitted as error by provider\n })\n // eslint-disable-next-line style/brace-style\n } else {\n this.pause()\n }\n }\n\n stop(): void {\n this._provider?.stop()\n this._store.batch({ playing: false, paused: true, currentTime: 0, playbackState: 'idle' })\n }\n\n // === Seeking ===\n\n seekTo(time: number): void {\n this._provider?.seekTo(time)\n }\n\n seekBy(offset: number): void {\n const newTime = Math.max(0, Math.min(this.state.currentTime + offset, this.state.duration))\n this.seekTo(newTime)\n }\n\n // === Volume ===\n\n setVolume(volume: number): void {\n if (this.state.volumeAvailability === 'unsupported') return\n const clamped = Math.max(0, Math.min(1, volume))\n this._provider?.setVolume(clamped)\n this._store.set('volume', clamped)\n }\n\n setMuted(muted: boolean): void {\n this._provider?.setMuted(muted)\n this._store.set('muted', muted)\n }\n\n toggleMute(): void {\n this.setMuted(!this.state.muted)\n }\n\n // === Playback Rate ===\n\n setPlaybackRate(rate: number): void {\n const clamped = Math.max(0.25, Math.min(4, rate))\n this._provider?.setPlaybackRate(clamped)\n this._store.set('playbackRate', clamped)\n }\n\n // === Fullscreen ===\n\n async enterFullscreen(): Promise<void> {\n if (this.state.fullscreenAvailability === 'unsupported') return\n // Exit PiP before entering fullscreen (mutual exclusion)\n if (this.state.pictureInPicture) {\n await this.exitPiP()\n }\n await this._provider?.enterFullscreen()\n if (this._options.fullscreenOrientationLock !== false) {\n lockOrientation('landscape')\n }\n }\n\n async exitFullscreen(): Promise<void> {\n await this._provider?.exitFullscreen()\n if (this._options.fullscreenOrientationLock !== false) {\n unlockOrientation()\n }\n }\n\n async toggleFullscreen(): Promise<void> {\n if (this.state.fullscreen) {\n await this.exitFullscreen()\n // eslint-disable-next-line style/brace-style\n } else {\n await this.enterFullscreen()\n }\n }\n\n // === Picture-in-Picture ===\n\n async enterPiP(): Promise<void> {\n if (this.state.pipAvailability === 'unsupported') return\n // Exit fullscreen before entering PiP (mutual exclusion)\n if (this.state.fullscreen) {\n await this.exitFullscreen()\n }\n await this._provider?.enterPiP()\n }\n\n async exitPiP(): Promise<void> {\n await this._provider?.exitPiP()\n }\n\n async togglePiP(): Promise<void> {\n if (this.state.pictureInPicture) {\n await this.exitPiP()\n // eslint-disable-next-line style/brace-style\n } else {\n await this.enterPiP()\n }\n }\n\n // === Tracks ===\n\n setQuality(quality: VideoQuality | 'auto'): void {\n this._provider?.setQuality(quality)\n if (quality === 'auto') {\n this._store.set('autoQuality', true)\n // eslint-disable-next-line style/brace-style\n } else {\n this._store.set('autoQuality', false)\n }\n }\n\n setTextTrack(trackId: string, mode: 'disabled' | 'hidden' | 'showing'): void {\n this._provider?.setTextTrackMode(trackId, mode)\n this._store.set('textTracks', this._provider?.getTextTracks() || [])\n }\n\n setAudioTrack(trackId: string): void {\n this._provider?.setAudioTrack(trackId)\n this._store.set('audioTracks', this._provider?.getAudioTracks() || [])\n }\n\n private toggleCaptions(): void {\n const textTracks = this.state.textTracks\n const showing = textTracks.find((t) => t.mode === 'showing')\n\n if (showing) {\n this.setTextTrack(showing.id, 'disabled')\n // eslint-disable-next-line style/brace-style\n } else {\n const first = textTracks.find((t) => t.kind === 'subtitles' || t.kind === 'captions')\n if (first) {\n this.setTextTrack(first.id, 'showing')\n }\n }\n }\n\n // === Events ===\n\n on<K extends keyof PlayerEventMap>(event: K, handler: PlayerEventMap[K]): void {\n this._events.on(event, handler)\n }\n\n off<K extends keyof PlayerEventMap>(event: K, handler: PlayerEventMap[K]): void {\n this._events.off(event, handler)\n }\n\n once<K extends keyof PlayerEventMap>(event: K, handler: PlayerEventMap[K]): void {\n this._events.once(event, handler)\n }\n\n // === State Subscription ===\n\n subscribe(\n // eslint-disable-next-line pickier/no-unused-vars\n keyOrListener: keyof PlayerState | '*' | ((state: PlayerState, key?: keyof PlayerState) => void),\n listener?: (state: PlayerState, key?: keyof PlayerState) => void,\n ): () => void {\n return this._store.subscribe(keyOrListener, listener)\n }\n}\n\n// =============================================================================\n// Default Options\n// =============================================================================\n\n// eslint-disable-next-line pickier/no-unused-vars\nconst defaultOptions: PlayerOptions = {\n autoplay: false,\n loop: false,\n muted: false,\n volume: 1,\n playbackRate: 1,\n playsinline: true,\n preload: 'metadata',\n controls: true,\n keyboard: true,\n controlsTimeout: 3000,\n storage: true,\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a new player instance\n *\n * @example\n * ```typescript\n * const player = createPlayer('#video-container', {\n * src: 'https://example.com/video.mp4',\n * autoplay: true,\n * })\n *\n * player.on('playing', () => console.log('Video is playing!'))\n * ```\n */\nexport function createPlayer(container: HTMLElement | string, options?: PlayerOptions): Player {\n return new Player(container, options)\n}\n\n// =============================================================================\n// Get Player Instance\n// =============================================================================\n\n/**\n * Get player instance from element\n */\nexport function getPlayer(element: HTMLElement): Player | null {\n return (element as any).__videoPlayer || null\n}\n",
15
+ "/** Browser HTMLElement base with an inert server-side constructor for import-safe SSR. */\nexport const HTMLElementBase: typeof HTMLElement = globalThis.HTMLElement ?? class {} as typeof HTMLElement\n",
16
+ "/**\n * ts-video-player <video-player> Custom Element\n *\n * The root element that wraps the Player class.\n *\n * @module elements/video-player\n */\n\nimport { Player } from '../player'\nimport type { DRMConfig, PlayerOptions, PlayerEventMap, Src, TextTrackSource } from '../types'\n\nconst OBSERVED_ATTRS = ['src', 'poster', 'autoplay', 'loop', 'muted', 'controls', 'volume', 'playback-rate', 'preload', 'playsinline', 'crossorigin', 'controlslist', 'disable-picture-in-picture'] as const\n\nimport { HTMLElementBase } from './base'\n\nexport class VideoPlayerElement extends HTMLElementBase {\n private _player: Player | null = null\n private _container: HTMLElement | null = null\n private _disconnectId = 0\n\n static get observedAttributes(): string[] {\n return [...OBSERVED_ATTRS]\n }\n\n get player(): Player | null {\n return this._player\n }\n\n connectedCallback(): void {\n this._disconnectId++\n if (this._player) return\n\n // Create shadow DOM\n const shadow = this.shadowRoot ?? this.attachShadow({ mode: 'open' })\n\n // Container\n this._container = document.createElement('div')\n this._container.setAttribute('part', 'container')\n this._container.style.cssText = 'position:relative;width:100%;height:100%;'\n\n // Slot for child media elements (buttons, etc.)\n const slot = document.createElement('slot')\n this._container.appendChild(slot)\n\n shadow.appendChild(this._container)\n\n // Build options from attributes\n const options = this.buildOptions()\n\n // Create player\n this._player = new Player(this._container, options)\n\n // Forward player events as DOM events\n this.forwardEvents()\n }\n\n disconnectedCallback(): void {\n if (this.hasAttribute('keep-alive')) return\n const disconnectId = ++this._disconnectId\n queueMicrotask(() => {\n if (this.isConnected || disconnectId !== this._disconnectId) return\n this._player?.destroy()\n this._player = null\n this._container = null\n this.shadowRoot?.replaceChildren()\n })\n }\n\n attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n if (!this._player) return\n\n switch (name) {\n case 'src':\n if (value) this._player.setSrc(value)\n break\n case 'muted':\n this._player.setMuted(value !== null)\n break\n case 'volume':\n if (value !== null) this._player.setVolume(parseFloat(value))\n break\n case 'playback-rate':\n if (value !== null) this._player.setPlaybackRate(parseFloat(value))\n break\n }\n }\n\n private buildOptions(): PlayerOptions {\n const options: PlayerOptions = {}\n\n const config = this.readSourceConfig()\n if (config.sources?.length) options.src = config.sources\n if (config.tracks?.length) options.tracks = config.tracks\n\n const src = this.getAttribute('src')\n if (src && !options.src) options.src = config.drm ? { src, type: 'application/dash+xml', drm: config.drm } : src\n\n const poster = this.getAttribute('poster')\n if (poster) options.poster = poster\n\n const title = this.getAttribute('title')\n if (title) options.title = title\n\n if (this.hasAttribute('autoplay')) options.autoplay = true\n if (this.hasAttribute('loop')) options.loop = true\n if (this.hasAttribute('muted')) options.muted = true\n\n const volume = this.getAttribute('volume')\n if (volume) options.volume = parseFloat(volume)\n\n const rate = this.getAttribute('playback-rate')\n if (rate) options.playbackRate = parseFloat(rate)\n\n const preload = this.getAttribute('preload')\n if (preload) options.preload = preload as PlayerOptions['preload']\n\n if (this.hasAttribute('controls')) options.controls = true\n options.playsinline = this.getAttribute('playsinline') !== 'false'\n\n const crossorigin = this.getAttribute('crossorigin')\n if (crossorigin !== null) options.crossorigin = crossorigin as PlayerOptions['crossorigin']\n\n const controlsList = this.getAttribute('controlslist')\n if (controlsList) options.controlsList = controlsList.split(/\\s+/) as PlayerOptions['controlsList']\n options.disablePictureInPicture = this.hasAttribute('disable-picture-in-picture')\n\n return options\n }\n\n private readSourceConfig(): { sources?: Src[], drm?: DRMConfig, tracks?: TextTrackSource[] } {\n const script = this.querySelector('script[type=\"application/json\"][data-media-config]')\n const value = this.getAttribute('data-media-config')?.trim() || script?.textContent?.trim()\n if (!value) return {}\n if (value.length > 65_536) throw new TypeError('Media player configuration is too large')\n try {\n const parsed = JSON.parse(value) as { sources?: unknown, drm?: unknown, tracks?: unknown }\n if (parsed.sources !== undefined && (!Array.isArray(parsed.sources) || parsed.sources.some(source => !source || typeof source !== 'object' || typeof (source as { src?: unknown }).src !== 'string'))) {\n throw new TypeError('Media player sources are invalid')\n }\n const trackKinds = new Set(['subtitles', 'captions', 'descriptions', 'chapters', 'metadata'])\n if (parsed.tracks !== undefined && (!Array.isArray(parsed.tracks) || parsed.tracks.some(track => !track || typeof track !== 'object' || typeof (track as { src?: unknown }).src !== 'string' || !trackKinds.has(String((track as { kind?: unknown }).kind))))) {\n throw new TypeError('Media player tracks are invalid')\n }\n return { sources: parsed.sources as Src[] | undefined, drm: parsed.drm as DRMConfig | undefined, tracks: parsed.tracks as TextTrackSource[] | undefined }\n }\n catch (error) {\n if (error instanceof TypeError) throw error\n throw new TypeError('Media player configuration is invalid JSON')\n }\n }\n\n private forwardEvents(): void {\n if (!this._player) return\n\n const events: (keyof PlayerEventMap)[] = [\n 'play', 'pause', 'playing', 'waiting', 'ended',\n 'timeupdate', 'durationchange', 'volumechange',\n 'fullscreenchange', 'pipchange', 'error',\n 'loadstart', 'loadeddata', 'loadedmetadata',\n 'canplay', 'canplaythrough', 'seeking', 'seeked',\n 'ratechange', 'qualitychange', 'statechange',\n 'availabilitychange',\n ]\n\n for (const event of events) {\n this._player.on(event, ((...args: unknown[]) => {\n this.dispatchEvent(new CustomEvent(event, {\n detail: args.length === 1 ? args[0] : args,\n bubbles: true,\n composed: true,\n }))\n }) as any)\n }\n }\n}\n",
17
+ "/**\n * ts-video-player Element Utilities\n *\n * Shared helpers for custom elements.\n *\n * @module elements/utils\n */\n\n/**\n * Format time in seconds to MM:SS or HH:MM:SS\n */\nexport function formatTime(seconds: number, guide = 0): string {\n if (!isFinite(seconds) || isNaN(seconds)) return '0:00'\n\n const s = Math.floor(seconds)\n const h = Math.floor(s / 3600)\n const m = Math.floor((s % 3600) / 60)\n const sec = s % 60\n\n const showHours = h > 0 || guide >= 3600\n\n if (showHours) {\n return `${h}:${m.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`\n }\n\n return `${m}:${sec.toString().padStart(2, '0')}`\n}\n\n/**\n * Format time as a human-readable phrase for screen readers.\n * e.g., \"1 minute, 30 seconds\"\n */\nexport function formatTimePhrase(seconds: number): string {\n if (!isFinite(seconds) || isNaN(seconds)) return '0 seconds'\n\n const s = Math.floor(seconds)\n const h = Math.floor(s / 3600)\n const m = Math.floor((s % 3600) / 60)\n const sec = s % 60\n\n const parts: string[] = []\n if (h > 0) parts.push(`${h} ${h === 1 ? 'hour' : 'hours'}`)\n if (m > 0) parts.push(`${m} ${m === 1 ? 'minute' : 'minutes'}`)\n if (sec > 0 || parts.length === 0) parts.push(`${sec} ${sec === 1 ? 'second' : 'seconds'}`)\n\n return parts.join(', ')\n}\n\n/**\n * Convert seconds to ISO 8601 duration string.\n * e.g., 90 -> \"PT1M30S\"\n */\nexport function toISODuration(seconds: number): string {\n if (!isFinite(seconds) || isNaN(seconds)) return 'PT0S'\n\n const s = Math.floor(seconds)\n const h = Math.floor(s / 3600)\n const m = Math.floor((s % 3600) / 60)\n const sec = s % 60\n\n let result = 'PT'\n if (h > 0) result += `${h}H`\n if (m > 0) result += `${m}M`\n if (sec > 0 || result === 'PT') result += `${sec}S`\n\n return result\n}\n\n/**\n * Resolve the player instance from an element.\n * Uses `for` attribute to find by ID, or walks up the DOM to find `<video-player>`.\n */\nexport function resolvePlayer(el: HTMLElement): any | null {\n const forId = el.getAttribute('for')\n if (forId) {\n const target = document.getElementById(forId)\n return (target as any)?.player ?? null\n }\n\n const host = el.closest('video-player')\n return (host as any)?.player ?? null\n}\n",
18
+ "/**\n * ts-video-player <video-skin> Custom Element\n *\n * Adaptive skin wrapper that provides a default layout for player controls.\n * Adjusts visibility of controls based on available features.\n *\n * Follows the v10 layered model:\n * <video-player> ← Behavior\n * <video-skin> ← Appearance (this element)\n * <media-*> ← UI controls\n * </video-skin>\n * </video-player>\n *\n * @module elements/video-skin\n */\n\nimport { resolvePlayer } from './utils'\n\nimport { HTMLElementBase } from './base'\n\nexport class VideoSkin extends HTMLElementBase {\n private _cleanups: Array<() => void> = []\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host {\n display: flex;\n flex-direction: column;\n position: absolute;\n inset: 0;\n z-index: 1;\n pointer-events: none;\n color: white;\n font-family: system-ui, -apple-system, sans-serif;\n font-size: 14px;\n }\n\n /* Click-to-play overlay */\n .overlay {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: auto;\n }\n\n /* Bottom controls bar */\n .controls {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 12px;\n background: linear-gradient(transparent, rgba(0,0,0,0.7));\n pointer-events: auto;\n transition: opacity 0.3s, visibility 0.3s;\n }\n\n :host([controls-hidden]) .controls {\n opacity: 0;\n visibility: hidden;\n }\n\n /* Spacer pushes right-aligned controls */\n .spacer {\n flex: 1;\n }\n\n /* Slots for left/center/right control groups */\n ::slotted(*) {\n pointer-events: auto;\n }\n </style>\n <div class=\"overlay\" part=\"overlay\">\n <slot name=\"overlay\"></slot>\n </div>\n <div class=\"controls\" part=\"controls\">\n <slot name=\"left\"></slot>\n <slot name=\"center\"></slot>\n <div class=\"spacer\"></div>\n <slot name=\"right\"></slot>\n <slot></slot>\n </div>\n `\n }\n\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this._cleanups.forEach((fn) => fn())\n this._cleanups = []\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n // Sync controls visibility\n const unsub = player.subscribe((state: any) => {\n if (state.controlsVisible) {\n this.removeAttribute('controls-hidden')\n } else {\n this.setAttribute('controls-hidden', '')\n }\n\n // Propagate feature availability as data attributes for CSS adaptation\n this.dataset.fullscreen = state.fullscreenAvailability\n this.dataset.pip = state.pipAvailability\n this.dataset.volume = state.volumeAvailability\n this.dataset.captions = String(state.textTracks.length > 0)\n this.dataset.qualities = String(state.qualities.length > 0)\n })\n\n // Click overlay to toggle play\n const overlay = this.shadowRoot!.querySelector('.overlay')!\n const onOverlayClick = () => player.togglePlay()\n overlay.addEventListener('click', onOverlayClick)\n\n this._cleanups.push(\n unsub,\n () => overlay.removeEventListener('click', onOverlayClick),\n )\n }\n}\n",
19
+ "/**\n * ts-video-player <media-play-button> Custom Element\n *\n * @module elements/media-play-button\n */\n\nimport { resolvePlayer } from './utils'\n\nconst PLAY_ICON = 'M8 5v14l11-7z'\nconst PAUSE_ICON = 'M6 19h4V5H6v14zm8-14v14h4V5h-4z'\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaPlayButton extends HTMLElementBase {\n private _cleanup: (() => void) | null = null\n private _onClick: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: inline-flex; }\n button {\n display: inline-flex; align-items: center; justify-content: center;\n width: 40px; height: 40px; padding: 8px;\n background: transparent; border: none; color: inherit; cursor: pointer;\n }\n button:hover { opacity: 0.8; }\n </style>\n <button part=\"button\" type=\"button\" aria-label=\"Play\">\n <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" part=\"icon\">\n <path d=\"${PLAY_ICON}\"/>\n </svg>\n </button>\n `\n }\n\n // Defer player resolution to next microtask (player may not be ready yet)\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n const button = this.shadowRoot?.querySelector('button')\n if (button && this._onClick) button.removeEventListener('click', this._onClick)\n this._cleanup?.()\n this._cleanup = null\n this._onClick = null\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n const btn = this.shadowRoot!.querySelector('button')!\n this._onClick = () => player.togglePlay()\n btn.addEventListener('click', this._onClick)\n\n const unsub = player.subscribe('paused', (state: any) => {\n const paused = state.paused\n btn.setAttribute('aria-label', paused ? 'Play' : 'Pause')\n btn.setAttribute('aria-pressed', String(!paused))\n const path = this.shadowRoot!.querySelector('path')!\n path.setAttribute('d', paused ? PLAY_ICON : PAUSE_ICON)\n })\n\n this._cleanup = unsub\n }\n}\n",
20
+ "/**\n * ts-video-player <media-mute-button> Custom Element\n *\n * @module elements/media-mute-button\n */\n\nimport { resolvePlayer } from './utils'\n\nconst ICON_MUTED = 'M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51A8.796 8.796 0 0 0 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3 3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06a8.99 8.99 0 0 0 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4 9.91 6.09 12 8.18V4z'\nconst ICON_LOW = 'M18.5 12A4.5 4.5 0 0 0 16 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z'\nconst ICON_HIGH = 'M3 9v6h4l5 5V4L7 9H3zm13.5 3A4.5 4.5 0 0 0 14 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z'\n\nfunction getVolumeIcon(muted: boolean, volume: number): string {\n if (muted || volume === 0) return ICON_MUTED\n if (volume < 0.5) return ICON_LOW\n return ICON_HIGH\n}\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaMuteButton extends HTMLElementBase {\n private _cleanup: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: inline-flex; }\n button {\n display: inline-flex; align-items: center; justify-content: center;\n width: 40px; height: 40px; padding: 8px;\n background: transparent; border: none; color: inherit; cursor: pointer;\n }\n button:hover { opacity: 0.8; }\n </style>\n <button part=\"button\" type=\"button\" aria-label=\"Mute\">\n <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" part=\"icon\">\n <path d=\"${ICON_HIGH}\"/>\n </svg>\n </button>\n `\n }\n\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this._cleanup?.()\n this._cleanup = null\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n const btn = this.shadowRoot!.querySelector('button')!\n btn.addEventListener('click', () => player.toggleMute())\n\n const unsub = player.subscribe((state: any) => {\n const icon = getVolumeIcon(state.muted, state.volume)\n btn.setAttribute('aria-label', state.muted ? 'Unmute' : 'Mute')\n const path = this.shadowRoot!.querySelector('path')!\n path.setAttribute('d', icon)\n })\n\n this._cleanup = unsub\n }\n}\n",
21
+ "/**\n * ts-video-player <media-fullscreen-button> Custom Element\n *\n * @module elements/media-fullscreen-button\n */\n\nimport { resolvePlayer } from './utils'\n\nconst ENTER_FS = 'M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z'\nconst EXIT_FS = 'M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z'\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaFullscreenButton extends HTMLElementBase {\n private _cleanup: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: inline-flex; }\n :host([hidden]) { display: none; }\n button {\n display: inline-flex; align-items: center; justify-content: center;\n width: 40px; height: 40px; padding: 8px;\n background: transparent; border: none; color: inherit; cursor: pointer;\n }\n button:hover { opacity: 0.8; }\n button:disabled { opacity: 0.4; cursor: not-allowed; }\n </style>\n <button part=\"button\" type=\"button\" aria-label=\"Enter fullscreen\">\n <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" part=\"icon\">\n <path d=\"${ENTER_FS}\"/>\n </svg>\n </button>\n `\n }\n\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this._cleanup?.()\n this._cleanup = null\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n const btn = this.shadowRoot!.querySelector('button')!\n btn.addEventListener('click', () => player.toggleFullscreen())\n\n const unsub = player.subscribe((state: any) => {\n const avail = state.fullscreenAvailability\n if (avail === 'unsupported') {\n this.setAttribute('hidden', '')\n } else {\n this.removeAttribute('hidden')\n }\n btn.disabled = avail !== 'available'\n\n const fs = state.fullscreen\n btn.setAttribute('aria-label', fs ? 'Exit fullscreen' : 'Enter fullscreen')\n const path = this.shadowRoot!.querySelector('path')!\n path.setAttribute('d', fs ? EXIT_FS : ENTER_FS)\n })\n\n this._cleanup = unsub\n }\n}\n",
22
+ "/**\n * ts-video-player <media-pip-button> Custom Element\n *\n * @module elements/media-pip-button\n */\n\nimport { resolvePlayer } from './utils'\n\nconst PIP_ICON = 'M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14z'\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaPipButton extends HTMLElementBase {\n private _cleanup: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: inline-flex; }\n :host([hidden]) { display: none; }\n button {\n display: inline-flex; align-items: center; justify-content: center;\n width: 40px; height: 40px; padding: 8px;\n background: transparent; border: none; color: inherit; cursor: pointer;\n }\n button:hover { opacity: 0.8; }\n button:disabled { opacity: 0.4; cursor: not-allowed; }\n </style>\n <button part=\"button\" type=\"button\" aria-label=\"Picture in picture\">\n <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" part=\"icon\">\n <path d=\"${PIP_ICON}\"/>\n </svg>\n </button>\n `\n }\n\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this._cleanup?.()\n this._cleanup = null\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n const btn = this.shadowRoot!.querySelector('button')!\n btn.addEventListener('click', () => player.togglePiP())\n\n const unsub = player.subscribe((state: any) => {\n const avail = state.pipAvailability\n if (avail === 'unsupported') {\n this.setAttribute('hidden', '')\n } else {\n this.removeAttribute('hidden')\n }\n btn.disabled = avail !== 'available'\n })\n\n this._cleanup = unsub\n }\n}\n",
23
+ "/**\n * ts-video-player <media-time-display> Custom Element\n *\n * Displays current time, duration, or remaining time with semantic markup.\n * Attributes: type=\"current|duration|remaining\"\n *\n * @module elements/media-time-display\n */\n\nimport { resolvePlayer, formatTime, formatTimePhrase, toISODuration } from './utils'\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaTimeDisplay extends HTMLElementBase {\n private _cleanup: (() => void) | null = null\n private _showRemaining = false\n\n static get observedAttributes(): string[] {\n return ['type']\n }\n\n get type(): string {\n return this.getAttribute('type') || 'current'\n }\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host {\n display: inline-flex;\n font-size: 14px;\n font-variant-numeric: tabular-nums;\n user-select: none;\n cursor: pointer;\n color: inherit;\n }\n time { color: inherit; }\n .separator { margin: 0 2px; }\n </style>\n <time part=\"time\" datetime=\"PT0S\" aria-valuetext=\"0 seconds\">0:00</time>\n `\n }\n\n this.addEventListener('click', this.handleClick)\n\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this._cleanup?.()\n this._cleanup = null\n this.removeEventListener('click', this.handleClick)\n }\n\n private handleClick = (): void => {\n if (this.type === 'duration') {\n this._showRemaining = !this._showRemaining\n // Re-render with current state\n const player = resolvePlayer(this)\n if (player) this.render(player.state)\n }\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n const unsub = player.subscribe((state: any) => {\n this.render(state)\n })\n\n this._cleanup = unsub\n }\n\n private render(state: any): void {\n const timeEl = this.shadowRoot?.querySelector('time')\n if (!timeEl) return\n\n const type = this.type\n let seconds: number\n\n if (type === 'remaining' || (type === 'duration' && this._showRemaining)) {\n seconds = Math.max(state.duration - state.currentTime, 0)\n const formatted = `-${formatTime(seconds, state.duration)}`\n timeEl.textContent = formatted\n } else if (type === 'duration') {\n seconds = state.duration\n timeEl.textContent = formatTime(seconds)\n } else {\n seconds = state.currentTime\n timeEl.textContent = formatTime(seconds, state.duration)\n }\n\n timeEl.setAttribute('datetime', toISODuration(seconds))\n timeEl.setAttribute('aria-valuetext', formatTimePhrase(seconds))\n }\n}\n",
24
+ "/**\n * ts-video-player <media-time-group> Custom Element\n *\n * Container for composing time display elements (current / separator / duration).\n * Provides layout and semantic grouping.\n *\n * @example\n * ```html\n * <media-time-group>\n * <media-time-display type=\"current\"></media-time-display>\n * <media-time-separator></media-time-separator>\n * <media-time-display type=\"duration\"></media-time-display>\n * </media-time-group>\n * ```\n *\n * @module elements/media-time-group\n */\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaTimeGroup extends HTMLElementBase {\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n font-variant-numeric: tabular-nums;\n font-family: inherit;\n font-size: inherit;\n color: inherit;\n }\n </style>\n <slot></slot>\n `\n }\n }\n}\n",
25
+ "/**\n * ts-video-player <media-time-separator> Custom Element\n *\n * Visual separator between time displays (typically \"/\" or \":\").\n * Hidden from screen readers via aria-hidden.\n *\n * @module elements/media-time-separator\n */\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaTimeSeparator extends HTMLElementBase {\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host {\n display: inline-flex;\n align-items: center;\n padding: 0 2px;\n font-family: inherit;\n font-size: inherit;\n color: inherit;\n opacity: 0.7;\n }\n </style>\n <span aria-hidden=\"true\" part=\"separator\"><slot>/</slot></span>\n `\n }\n\n this.setAttribute('role', 'separator')\n this.setAttribute('aria-hidden', 'true')\n }\n}\n",
26
+ "/**\n * ts-video-player <media-preview-time> Custom Element\n *\n * Displays the time at the current pointer position on the seek bar.\n * Intended to be placed inside or near a <media-progress-bar>.\n * Listens for custom 'previewtime' events or pointer events on the progress bar.\n *\n * @module elements/media-preview-time\n */\n\nimport { resolvePlayer, formatTime } from './utils'\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaPreviewTime extends HTMLElementBase {\n private _cleanups: Array<() => void> = []\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host {\n display: inline-block;\n font-variant-numeric: tabular-nums;\n font-family: monospace;\n font-size: 12px;\n color: inherit;\n pointer-events: none;\n }\n </style>\n <span part=\"value\">0:00</span>\n `\n }\n\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this._cleanups.forEach((fn) => fn())\n this._cleanups = []\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n // Find sibling or parent progress bar to listen for pointer events\n const progressBar =\n this.closest('media-progress-bar') ||\n this.parentElement?.querySelector('media-progress-bar')\n\n if (progressBar) {\n const onPointerMove = (e: Event) => {\n const pe = e as PointerEvent\n const track = (progressBar.shadowRoot?.querySelector('.track') ||\n progressBar) as HTMLElement\n const rect = track.getBoundingClientRect()\n const percent = Math.max(0, Math.min(1, (pe.clientX - rect.left) / rect.width))\n const time = percent * (player.state.duration || 0)\n this.updateTime(time, player.state.duration)\n }\n\n progressBar.addEventListener('pointermove', onPointerMove)\n this._cleanups.push(() => progressBar.removeEventListener('pointermove', onPointerMove))\n }\n }\n\n private updateTime(time: number, duration: number): void {\n const span = this.shadowRoot?.querySelector('span')\n if (span) {\n span.textContent = formatTime(time, duration)\n }\n }\n}\n",
27
+ "/**\n * ts-video-player <media-progress-bar> Custom Element\n *\n * Seek bar with buffered overlay, time tooltip, pointer/keyboard interaction.\n *\n * @module elements/media-progress-bar\n */\n\nimport { resolvePlayer, formatTime, formatTimePhrase } from './utils'\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaProgressBar extends HTMLElementBase {\n private _cleanups: Array<() => void> = []\n private _isDragging = false\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: flex; flex: 1; align-items: center; }\n .container {\n position: relative; width: 100%; height: 20px;\n cursor: pointer; touch-action: none;\n }\n .track {\n position: absolute; top: 50%; left: 0; right: 0;\n height: 4px; background: rgba(255,255,255,0.3);\n border-radius: 2px; transform: translateY(-50%);\n }\n :host([waveform]) .track { height: 20px; overflow: hidden; background: rgba(255,255,255,0.16); }\n .waveform { position: absolute; inset: 0; background-position: center; background-repeat: no-repeat; background-size: 100% 100%; opacity: 0.65; }\n .buffered {\n position: absolute; top: 0; left: 0;\n height: 100%; background: rgba(255,255,255,0.4);\n border-radius: 2px; width: 0%;\n }\n .fill {\n position: absolute; top: 0; left: 0;\n height: 100%; background: #fff;\n border-radius: 2px; width: 0%;\n }\n .thumb {\n position: absolute; top: 50%; left: 0%;\n width: 12px; height: 12px; background: #fff;\n border-radius: 50%; transform: translate(-50%, -50%);\n transition: transform 0.1s;\n }\n .container:hover .thumb { transform: translate(-50%, -50%) scale(1.2); }\n .tooltip {\n position: absolute; bottom: 100%; left: 0;\n transform: translateX(-50%);\n background: rgba(0,0,0,0.85); color: #fff;\n padding: 4px 8px; border-radius: 3px;\n font-size: 12px; font-family: monospace;\n white-space: nowrap; pointer-events: none;\n opacity: 0; transition: opacity 0.15s;\n margin-bottom: 8px;\n }\n .tooltip::after {\n content: ''; position: absolute;\n top: 100%; left: 50%; transform: translateX(-50%);\n border: 4px solid transparent;\n border-top-color: rgba(0,0,0,0.85);\n }\n .container:hover .tooltip { opacity: 1; }\n </style>\n <div class=\"container\" part=\"container\" role=\"slider\"\n aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"0\"\n aria-label=\"Seek\" tabindex=\"0\">\n <div class=\"tooltip\" part=\"tooltip\">0:00</div>\n <div class=\"track\" part=\"track\">\n <div class=\"waveform\" part=\"waveform\" aria-hidden=\"true\"></div>\n <div class=\"buffered\" part=\"buffered\"></div>\n <div class=\"fill\" part=\"fill\"></div>\n <div class=\"thumb\" part=\"thumb\"></div>\n </div>\n </div>\n `\n }\n\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this._cleanups.forEach((fn) => fn())\n this._cleanups = []\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n const container = this.shadowRoot!.querySelector('.container') as HTMLElement\n const track = this.shadowRoot!.querySelector('.track') as HTMLElement\n const fill = this.shadowRoot!.querySelector('.fill') as HTMLElement\n const thumb = this.shadowRoot!.querySelector('.thumb') as HTMLElement\n const buffered = this.shadowRoot!.querySelector('.buffered') as HTMLElement\n const tooltip = this.shadowRoot!.querySelector('.tooltip') as HTMLElement\n const waveform = this.getAttribute('waveform')\n if (waveform) {\n const resolved = new URL(waveform, document.baseURI)\n if (['http:', 'https:', 'blob:'].includes(resolved.protocol) || resolved.href.startsWith('data:image/')) {\n const layer = this.shadowRoot!.querySelector('.waveform') as HTMLElement\n layer.style.backgroundImage = `url(${JSON.stringify(resolved.href)})`\n }\n }\n\n const updateTooltip = (e: PointerEvent) => {\n const rect = track.getBoundingClientRect()\n const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width))\n const time = percent * (player.state.duration || 0)\n\n tooltip.textContent = formatTime(time, player.state.duration)\n\n // Position tooltip, clamping to container edges\n const containerRect = container.getBoundingClientRect()\n const tooltipWidth = tooltip.offsetWidth\n const rawLeft = e.clientX - containerRect.left\n const minLeft = tooltipWidth / 2\n const maxLeft = containerRect.width - tooltipWidth / 2\n const clampedLeft = Math.max(minLeft, Math.min(maxLeft, rawLeft))\n\n tooltip.style.left = `${clampedLeft}px`\n }\n\n const seekFromEvent = (e: PointerEvent) => {\n const rect = track.getBoundingClientRect()\n const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width))\n const time = percent * (player.state.duration || 0)\n player.seekTo(time)\n }\n\n const onPointerDown = (e: PointerEvent) => {\n this._isDragging = true\n container.setPointerCapture(e.pointerId)\n seekFromEvent(e)\n }\n\n const onPointerMove = (e: PointerEvent) => {\n updateTooltip(e)\n if (!this._isDragging) return\n seekFromEvent(e)\n }\n\n const onPointerUp = (e: PointerEvent) => {\n if (!this._isDragging) return\n this._isDragging = false\n container.releasePointerCapture(e.pointerId)\n }\n\n const onKeyDown = (e: KeyboardEvent) => {\n const step = 5\n let newTime = player.state.currentTime\n\n switch (e.key) {\n case 'ArrowRight': newTime = Math.min(player.state.duration, newTime + step); break\n case 'ArrowLeft': newTime = Math.max(0, newTime - step); break\n case 'Home': newTime = 0; break\n case 'End': newTime = player.state.duration; break\n default: return\n }\n\n e.preventDefault()\n player.seekTo(newTime)\n }\n\n container.addEventListener('pointerdown', onPointerDown)\n container.addEventListener('pointermove', onPointerMove)\n container.addEventListener('pointerup', onPointerUp)\n container.addEventListener('keydown', onKeyDown)\n\n this._cleanups.push(\n () => container.removeEventListener('pointerdown', onPointerDown),\n () => container.removeEventListener('pointermove', onPointerMove),\n () => container.removeEventListener('pointerup', onPointerUp),\n () => container.removeEventListener('keydown', onKeyDown),\n )\n\n const unsub = player.subscribe((state: any) => {\n if (this._isDragging) return\n\n const duration = state.duration || 0\n const percent = duration > 0 ? (state.currentTime / duration) * 100 : 0\n\n fill.style.width = `${percent}%`\n thumb.style.left = `${percent}%`\n\n container.setAttribute('aria-valuenow', String(Math.round(percent)))\n container.setAttribute('aria-valuetext', `${formatTimePhrase(state.currentTime)} of ${formatTimePhrase(duration)}`)\n\n // Buffered\n const bufferedPct = (state.bufferedAmount || 0) * 100\n buffered.style.width = `${bufferedPct}%`\n })\n\n this._cleanups.push(unsub)\n }\n}\n",
28
+ "/**\n * ts-video-player <media-volume-slider> Custom Element\n *\n * Volume control slider. Hidden when volume is unsupported (iOS Safari).\n *\n * @module elements/media-volume-slider\n */\n\nimport { resolvePlayer } from './utils'\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaVolumeSlider extends HTMLElementBase {\n private _cleanups: Array<() => void> = []\n private _isDragging = false\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: inline-flex; align-items: center; width: 80px; }\n :host([hidden]) { display: none; }\n .container {\n position: relative; width: 100%; height: 20px;\n cursor: pointer; touch-action: none;\n }\n .track {\n position: absolute; top: 50%; left: 0; right: 0;\n height: 4px; background: rgba(255,255,255,0.3);\n border-radius: 2px; transform: translateY(-50%);\n }\n .fill {\n position: absolute; top: 0; left: 0;\n height: 100%; background: #fff;\n border-radius: 2px; width: 100%;\n }\n .thumb {\n position: absolute; top: 50%; left: 100%;\n width: 12px; height: 12px; background: #fff;\n border-radius: 50%; transform: translate(-50%, -50%);\n transition: transform 0.1s;\n }\n .container:hover .thumb { transform: translate(-50%, -50%) scale(1.2); }\n </style>\n <div class=\"container\" part=\"container\" role=\"slider\"\n aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"100\"\n aria-label=\"Volume\" tabindex=\"0\">\n <div class=\"track\" part=\"track\">\n <div class=\"fill\" part=\"fill\"></div>\n <div class=\"thumb\" part=\"thumb\"></div>\n </div>\n </div>\n `\n }\n\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this._cleanups.forEach((fn) => fn())\n this._cleanups = []\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n const container = this.shadowRoot!.querySelector('.container') as HTMLElement\n const track = this.shadowRoot!.querySelector('.track') as HTMLElement\n const fill = this.shadowRoot!.querySelector('.fill') as HTMLElement\n const thumb = this.shadowRoot!.querySelector('.thumb') as HTMLElement\n\n const setFromEvent = (e: PointerEvent) => {\n const rect = track.getBoundingClientRect()\n const volume = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width))\n player.setVolume(volume)\n if (volume > 0 && player.state.muted) player.setMuted(false)\n }\n\n const onPointerDown = (e: PointerEvent) => {\n this._isDragging = true\n container.setPointerCapture(e.pointerId)\n setFromEvent(e)\n }\n const onPointerMove = (e: PointerEvent) => {\n if (!this._isDragging) return\n setFromEvent(e)\n }\n const onPointerUp = (e: PointerEvent) => {\n if (!this._isDragging) return\n this._isDragging = false\n container.releasePointerCapture(e.pointerId)\n }\n const onKeyDown = (e: KeyboardEvent) => {\n let volume = player.state.volume\n const step = 0.05\n\n switch (e.key) {\n case 'ArrowRight':\n case 'ArrowUp': volume = Math.min(1, volume + step); break\n case 'ArrowLeft':\n case 'ArrowDown': volume = Math.max(0, volume - step); break\n default: return\n }\n\n e.preventDefault()\n player.setVolume(volume)\n }\n\n container.addEventListener('pointerdown', onPointerDown)\n container.addEventListener('pointermove', onPointerMove)\n container.addEventListener('pointerup', onPointerUp)\n container.addEventListener('keydown', onKeyDown)\n\n this._cleanups.push(\n () => container.removeEventListener('pointerdown', onPointerDown),\n () => container.removeEventListener('pointermove', onPointerMove),\n () => container.removeEventListener('pointerup', onPointerUp),\n () => container.removeEventListener('keydown', onKeyDown),\n )\n\n const unsub = player.subscribe((state: any) => {\n if (state.volumeAvailability === 'unsupported') {\n this.setAttribute('hidden', '')\n return\n }\n this.removeAttribute('hidden')\n\n const vol = state.muted ? 0 : state.volume\n const percent = vol * 100\n\n fill.style.width = `${percent}%`\n thumb.style.left = `${percent}%`\n container.setAttribute('aria-valuenow', String(Math.round(percent)))\n })\n\n this._cleanups.push(unsub)\n }\n}\n",
29
+ "/**\n * ts-video-player Popover Positioning\n *\n * Collision-aware positioning for menus and tooltips.\n *\n * @module core/popover\n */\n\nexport interface Rect {\n top: number\n left: number\n bottom: number\n right: number\n width: number\n height: number\n}\n\nexport type Placement = 'top' | 'bottom' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end'\n\nexport interface PositionOptions {\n /** Preferred placement */\n placement?: Placement\n /** Gap between anchor and popover in px */\n offset?: number\n /** Boundary element (defaults to viewport) */\n boundary?: HTMLElement | null\n /** Minimum distance from boundary edges in px */\n padding?: number\n}\n\nexport interface PositionResult {\n top: number\n left: number\n placement: Placement\n}\n\n/**\n * Calculate the position of a popover relative to an anchor element,\n * flipping when it would overflow the boundary.\n */\nexport function computePosition(\n anchor: HTMLElement,\n popover: HTMLElement,\n options: PositionOptions = {},\n): PositionResult {\n const {\n placement = 'top',\n offset = 4,\n boundary = null,\n padding = 8,\n } = options\n\n const anchorRect = anchor.getBoundingClientRect()\n const popoverRect = popover.getBoundingClientRect()\n\n const boundaryRect = boundary\n ? boundary.getBoundingClientRect()\n : { top: 0, left: 0, bottom: window.innerHeight, right: window.innerWidth, width: window.innerWidth, height: window.innerHeight }\n\n const availableTop = anchorRect.top - boundaryRect.top - padding\n const availableBottom = boundaryRect.bottom - anchorRect.bottom - padding\n\n // Determine vertical placement (flip if needed)\n let vertical: 'top' | 'bottom'\n if (placement.startsWith('top')) {\n vertical = popoverRect.height + offset <= availableTop ? 'top' : 'bottom'\n } else {\n vertical = popoverRect.height + offset <= availableBottom ? 'bottom' : 'top'\n }\n\n // Calculate top\n let top: number\n if (vertical === 'top') {\n top = anchorRect.top - popoverRect.height - offset\n } else {\n top = anchorRect.bottom + offset\n }\n\n // Determine horizontal alignment\n let align: '' | '-start' | '-end' = ''\n if (placement.endsWith('-start')) align = '-start'\n else if (placement.endsWith('-end')) align = '-end'\n\n // Calculate left\n let left: number\n switch (align) {\n case '-start':\n left = anchorRect.left\n break\n case '-end':\n left = anchorRect.right - popoverRect.width\n break\n default:\n left = anchorRect.left + (anchorRect.width - popoverRect.width) / 2\n break\n }\n\n // Clamp horizontal to boundary\n const minLeft = boundaryRect.left + padding\n const maxLeft = boundaryRect.right - popoverRect.width - padding\n left = Math.max(minLeft, Math.min(maxLeft, left))\n\n // Clamp vertical to boundary\n const minTop = boundaryRect.top + padding\n const maxTop = boundaryRect.bottom - popoverRect.height - padding\n top = Math.max(minTop, Math.min(maxTop, top))\n\n const finalPlacement: Placement = `${vertical}${align}` as Placement\n\n return { top, left, placement: finalPlacement }\n}\n\n/**\n * Apply computed position to a popover element using absolute positioning\n * relative to an offset parent.\n */\nexport function applyPosition(\n anchor: HTMLElement,\n popover: HTMLElement,\n options: PositionOptions = {},\n): Placement {\n // Temporarily make visible for measurement\n const prevVisibility = popover.style.visibility\n popover.style.visibility = 'hidden'\n popover.style.display = 'block'\n\n const result = computePosition(anchor, popover, options)\n\n // Convert to relative coordinates if popover has an offset parent\n const offsetParent = popover.offsetParent as HTMLElement | null\n if (offsetParent) {\n const parentRect = offsetParent.getBoundingClientRect()\n popover.style.top = `${result.top - parentRect.top}px`\n popover.style.left = `${result.left - parentRect.left}px`\n } else {\n popover.style.top = `${result.top}px`\n popover.style.left = `${result.left}px`\n }\n\n popover.style.visibility = prevVisibility\n\n return result.placement\n}\n",
30
+ "/**\n * ts-video-player <media-settings-menu> Custom Element\n *\n * Settings dropdown with quality, speed, captions, and audio track options.\n * Uses collision-aware popover positioning.\n *\n * @module elements/media-settings-menu\n */\n\nimport { resolvePlayer } from './utils'\nimport { computePosition } from '../core/popover'\n\nconst GEAR_ICON = 'M19.14 12.94c.04-.31.06-.63.06-.94 0-.31-.02-.63-.06-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.488.488 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.04.31-.06.63-.06.94s.02.63.06.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z'\n\nconst SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaSettingsMenu extends HTMLElementBase {\n private _cleanup: (() => void) | null = null\n private _isOpen = false\n private _currentPanel: 'main' | 'speed' | 'quality' | 'captions' | 'audio' = 'main'\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: inline-flex; position: relative; }\n button.trigger {\n display: inline-flex; align-items: center; justify-content: center;\n width: 40px; height: 40px; padding: 8px;\n background: transparent; border: none; color: inherit; cursor: pointer;\n }\n button.trigger:hover { opacity: 0.8; }\n .menu {\n position: fixed; z-index: 9999;\n min-width: 160px; max-height: 250px; overflow-y: auto;\n background: rgba(28,28,28,0.95); border-radius: 4px;\n padding: 4px 0; opacity: 0; visibility: hidden;\n transform: translateY(4px);\n transition: opacity 0.2s, transform 0.2s, visibility 0.2s;\n }\n :host([open]) .menu {\n opacity: 1; visibility: visible; transform: translateY(0);\n }\n .item {\n display: flex; align-items: center; gap: 8px;\n width: 100%; padding: 8px 16px;\n background: none; border: none; color: white;\n text-align: left; cursor: pointer; font-size: 14px;\n }\n .item:hover { background: rgba(255,255,255,0.1); }\n .item[aria-checked=\"true\"]::before { content: '\\\\2713'; }\n .item[aria-checked=\"false\"]::before { content: ''; min-width: 12px; display: inline-block; }\n .back { font-weight: bold; border-bottom: 1px solid rgba(255,255,255,0.2); }\n </style>\n <button class=\"trigger\" part=\"trigger\" type=\"button\"\n aria-label=\"Settings\" aria-haspopup=\"true\" aria-expanded=\"false\">\n <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" part=\"icon\">\n <path d=\"${GEAR_ICON}\"/>\n </svg>\n </button>\n <div class=\"menu\" part=\"menu\" role=\"menu\" aria-hidden=\"true\"></div>\n `\n }\n\n const trigger = this.shadowRoot!.querySelector('.trigger')!\n this._onTriggerClick = () => this.toggle()\n trigger.addEventListener('click', this._onTriggerClick)\n\n // Close on outside click\n this._onDocClick = (e: MouseEvent) => {\n if (this._isOpen && !this.contains(e.target as Node)) this.close()\n }\n document.addEventListener('click', this._onDocClick)\n\n // Close on escape\n this._onDocKeydown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && this._isOpen) this.close()\n }\n document.addEventListener('keydown', this._onDocKeydown)\n\n queueMicrotask(() => this.attach())\n }\n\n private _onTriggerClick: (() => void) | null = null\n // eslint-disable-next-line pickier/no-unused-vars\n private _onDocClick: ((e: MouseEvent) => void) | null = null\n // eslint-disable-next-line pickier/no-unused-vars\n private _onDocKeydown: ((e: KeyboardEvent) => void) | null = null\n\n disconnectedCallback(): void {\n this._cleanup?.()\n this._cleanup = null\n if (this._onTriggerClick) {\n this.shadowRoot?.querySelector('.trigger')?.removeEventListener('click', this._onTriggerClick)\n }\n if (this._onDocClick) document.removeEventListener('click', this._onDocClick)\n if (this._onDocKeydown) document.removeEventListener('keydown', this._onDocKeydown)\n }\n\n toggle(): void {\n if (this._isOpen) this.close()\n else this.open()\n }\n\n open(): void {\n this._isOpen = true\n this._currentPanel = 'main'\n this.setAttribute('open', '')\n this.shadowRoot!.querySelector('.trigger')!.setAttribute('aria-expanded', 'true')\n this.shadowRoot!.querySelector('.menu')!.setAttribute('aria-hidden', 'false')\n this.renderPanel()\n this.positionMenu()\n }\n\n close(): void {\n this._isOpen = false\n this.removeAttribute('open')\n this.shadowRoot!.querySelector('.trigger')!.setAttribute('aria-expanded', 'false')\n this.shadowRoot!.querySelector('.menu')!.setAttribute('aria-hidden', 'true')\n }\n\n private positionMenu(): void {\n const trigger = this.shadowRoot!.querySelector('.trigger') as HTMLElement\n const menu = this.shadowRoot!.querySelector('.menu') as HTMLElement\n if (!trigger || !menu) return\n\n // Find the player container as boundary (for fullscreen)\n const playerEl = this.closest('video-player, .ts-video-player') as HTMLElement | null\n\n const result = computePosition(trigger, menu, {\n placement: 'top-end',\n offset: 4,\n boundary: playerEl,\n padding: 8,\n })\n\n menu.style.top = `${result.top}px`\n menu.style.left = `${result.left}px`\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n const unsub = player.subscribe(() => {\n if (this._isOpen) this.renderPanel()\n })\n\n this._cleanup = unsub\n }\n\n private renderPanel(): void {\n const player = resolvePlayer(this)\n if (!player) return\n\n const menu = this.shadowRoot!.querySelector('.menu')!\n menu.innerHTML = ''\n\n switch (this._currentPanel) {\n case 'main': this.renderMain(menu, player); break\n case 'speed': this.renderSpeed(menu, player); break\n case 'quality': this.renderQuality(menu, player); break\n case 'captions': this.renderCaptions(menu, player); break\n case 'audio': this.renderAudio(menu, player); break\n }\n\n // Re-position after content changes\n if (this._isOpen) {\n queueMicrotask(() => this.positionMenu())\n }\n }\n\n private renderMain(menu: Element, player: any): void {\n const state = player.state\n\n // Speed\n this.addItem(menu, `Speed: ${state.playbackRate}x`, () => {\n this._currentPanel = 'speed'\n this.renderPanel()\n })\n\n // Quality\n if (state.qualities.length > 0) {\n const current = state.qualities.find((q: any) => q.selected)\n const label = state.autoQuality ? 'Auto' : (current ? `${current.height}p` : 'Auto')\n this.addItem(menu, `Quality: ${label}`, () => {\n this._currentPanel = 'quality'\n this.renderPanel()\n })\n }\n\n // Captions\n if (state.textTracks.length > 0) {\n const showing = state.textTracks.find((t: any) => t.mode === 'showing')\n this.addItem(menu, `Captions: ${showing?.label || 'Off'}`, () => {\n this._currentPanel = 'captions'\n this.renderPanel()\n })\n }\n\n if (state.audioTracks.length > 1) {\n const selected = state.audioTracks.find((track: { selected: boolean }) => track.selected)\n this.addItem(menu, `Audio: ${selected?.label || 'Default'}`, () => {\n this._currentPanel = 'audio'\n this.renderPanel()\n })\n }\n }\n\n private renderSpeed(menu: Element, player: any): void {\n this.addItem(menu, 'Back', () => {\n this._currentPanel = 'main'\n this.renderPanel()\n }, false, true)\n\n for (const speed of SPEEDS) {\n const checked = player.state.playbackRate === speed\n this.addItem(menu, `${speed}x`, () => {\n player.setPlaybackRate(speed)\n this.close()\n }, checked)\n }\n }\n\n private renderQuality(menu: Element, player: any): void {\n this.addItem(menu, 'Back', () => {\n this._currentPanel = 'main'\n this.renderPanel()\n }, false, true)\n\n // Auto option\n this.addItem(menu, 'Auto', () => {\n player.setQuality('auto')\n this.close()\n }, player.state.autoQuality)\n\n for (const q of player.state.qualities) {\n this.addItem(menu, `${q.height}p`, () => {\n player.setQuality(q)\n this.close()\n }, q.selected && !player.state.autoQuality)\n }\n }\n\n private renderCaptions(menu: Element, player: any): void {\n this.addItem(menu, 'Back', () => {\n this._currentPanel = 'main'\n this.renderPanel()\n }, false, true)\n\n // Off option\n const anyShowing = player.state.textTracks.some((t: any) => t.mode === 'showing')\n this.addItem(menu, 'Off', () => {\n for (const t of player.state.textTracks) {\n if (t.mode === 'showing') player.setTextTrack(t.id, 'disabled')\n }\n this.close()\n }, !anyShowing)\n\n for (const track of player.state.textTracks) {\n if (track.kind === 'subtitles' || track.kind === 'captions') {\n this.addItem(menu, track.label, () => {\n player.setTextTrack(track.id, 'showing')\n this.close()\n }, track.mode === 'showing')\n }\n }\n }\n\n private renderAudio(menu: Element, player: any): void {\n this.addItem(menu, 'Back', () => {\n this._currentPanel = 'main'\n this.renderPanel()\n }, false, true)\n\n for (const track of player.state.audioTracks) {\n this.addItem(menu, track.label || track.language || 'Audio track', () => {\n player.setAudioTrack(track.id)\n this.close()\n }, track.selected)\n }\n }\n\n private addItem(\n menu: Element,\n label: string,\n onClick: () => void,\n checked = false,\n isBack = false,\n ): void {\n const btn = document.createElement('button')\n btn.className = `item${isBack ? ' back' : ''}`\n btn.setAttribute('role', 'menuitem')\n if (!isBack) btn.setAttribute('aria-checked', String(checked))\n btn.textContent = label\n btn.addEventListener('click', onClick)\n menu.appendChild(btn)\n }\n}\n",
31
+ "import { resolvePlayer } from './utils'\nimport type { PlayerState } from '../types'\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaSeekButton extends HTMLElementBase {\n private cleanup: (() => void) | null = null\n private onClick: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: inline-flex; }\n button { min-width: 40px; height: 40px; padding: 0 8px; border: 0; background: transparent; color: inherit; cursor: pointer; font: inherit; }\n button:hover { opacity: .8; }\n button:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }\n button:disabled { cursor: default; opacity: .45; }\n </style>\n <button part=\"button\" type=\"button\"></button>\n `\n }\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n const button = this.shadowRoot?.querySelector('button')\n if (button && this.onClick) button.removeEventListener('click', this.onClick)\n this.cleanup?.()\n this.cleanup = null\n this.onClick = null\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n const button = this.shadowRoot?.querySelector('button')\n if (!player || !button) return\n const seconds = Number.parseFloat(this.getAttribute('seconds') ?? '10')\n const offset = Number.isFinite(seconds) && seconds !== 0 ? seconds : 10\n const label = offset > 0 ? `Forward ${offset} seconds` : `Back ${Math.abs(offset)} seconds`\n button.textContent = offset > 0 ? `+${offset}` : String(offset)\n button.setAttribute('aria-label', label)\n this.onClick = () => player.seekBy(offset)\n button.addEventListener('click', this.onClick)\n this.cleanup = player.subscribe((state: PlayerState) => {\n button.disabled = offset < 0 ? state.currentTime <= 0 : state.duration > 0 && state.currentTime >= state.duration\n })\n }\n}\n",
32
+ "import { resolvePlayer } from './utils'\nimport type { PlayerState } from '../types'\n\nconst defaultRates = [0.5, 0.75, 1, 1.25, 1.5, 2]\n\nimport { HTMLElementBase } from './base'\n\nexport class MediaPlaybackRateButton extends HTMLElementBase {\n private cleanup: (() => void) | null = null\n private onClick: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: inline-flex; }\n button { min-width: 42px; height: 40px; padding: 0 8px; border: 0; background: transparent; color: inherit; cursor: pointer; font: inherit; font-variant-numeric: tabular-nums; }\n button:hover { opacity: .8; }\n button:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; }\n </style>\n <button part=\"button\" type=\"button\" aria-label=\"Playback speed\"></button>\n `\n }\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n const button = this.shadowRoot?.querySelector('button')\n if (button && this.onClick) button.removeEventListener('click', this.onClick)\n this.cleanup?.()\n this.cleanup = null\n this.onClick = null\n }\n\n private getRates(): number[] {\n const rates = (this.getAttribute('rates') ?? '')\n .split(',')\n .map(value => Number.parseFloat(value.trim()))\n .filter(value => Number.isFinite(value) && value >= 0.25 && value <= 4)\n return [...new Set(rates.length > 0 ? rates : defaultRates)].sort((a, b) => a - b)\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n const button = this.shadowRoot?.querySelector('button')\n if (!player || !button) return\n const rates = this.getRates()\n this.onClick = () => {\n const currentIndex = rates.findIndex(rate => rate > player.state.playbackRate + 0.001)\n player.setPlaybackRate(rates[currentIndex < 0 ? 0 : currentIndex])\n }\n button.addEventListener('click', this.onClick)\n this.cleanup = player.subscribe('playbackRate', (state: PlayerState) => {\n button.textContent = `${state.playbackRate}x`\n button.setAttribute('aria-label', `Playback speed ${state.playbackRate}x`)\n })\n }\n}\n",
33
+ "/**\n * ts-video-player <media-airplay-button> Custom Element\n *\n * @module elements/media-airplay-button\n */\n\nimport { HTMLElementBase } from './base'\nimport { resolvePlayer } from './utils'\n\nconst AIRPLAY_ICON = 'M6.2 19h11.6L12 13.2 6.2 19zM19 3H5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h2v-2H5V5h14v10h-2v2h2a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z'\n\ninterface AirPlayVideo extends HTMLVideoElement {\n webkitShowPlaybackTargetPicker?: () => void\n webkitCurrentPlaybackTargetIsWireless?: boolean\n}\n\nexport class MediaAirplayButton extends HTMLElementBase {\n private cleanup: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: none; }\n :host([available]) { display: inline-flex; }\n button { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; padding: 8px; background: transparent; border: 0; color: inherit; cursor: pointer; }\n button:hover { opacity: 0.8; }\n :host([connected]) button { color: var(--media-airplay-active-color, #38bdf8); }\n </style>\n <button part=\"button\" type=\"button\" aria-label=\"Play on AirPlay\">\n <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" part=\"icon\"><path d=\"${AIRPLAY_ICON}\"/></svg>\n </button>\n `\n }\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this.cleanup?.()\n this.cleanup = null\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n const button = this.shadowRoot?.querySelector('button')\n if (!player || !button) return\n\n let video: AirPlayVideo | null = null\n const availability = (): void => update()\n const update = (): void => {\n const media = player.provider?.mediaElement\n const nextVideo = media instanceof HTMLVideoElement ? media as AirPlayVideo : null\n if (nextVideo !== video) {\n video?.removeEventListener('webkitplaybacktargetavailabilitychanged', availability)\n video?.removeEventListener('webkitcurrentplaybacktargetiswirelesschanged', availability)\n nextVideo?.addEventListener('webkitplaybacktargetavailabilitychanged', availability)\n nextVideo?.addEventListener('webkitcurrentplaybacktargetiswirelesschanged', availability)\n video = nextVideo\n }\n const available = typeof video?.webkitShowPlaybackTargetPicker === 'function'\n this.toggleAttribute('available', available)\n this.toggleAttribute('connected', video?.webkitCurrentPlaybackTargetIsWireless === true)\n button.setAttribute('aria-pressed', String(video?.webkitCurrentPlaybackTargetIsWireless === true))\n }\n const click = (): void => video?.webkitShowPlaybackTargetPicker?.()\n button.addEventListener('click', click)\n const unsubscribe = player.subscribe(update)\n update()\n\n this.cleanup = () => {\n unsubscribe()\n button.removeEventListener('click', click)\n video?.removeEventListener('webkitplaybacktargetavailabilitychanged', availability)\n video?.removeEventListener('webkitcurrentplaybacktargetiswirelesschanged', availability)\n }\n }\n}\n",
34
+ "/**\n * ts-video-player <media-live-button> Custom Element\n *\n * @module elements/media-live-button\n */\n\nimport { HTMLElementBase } from './base'\nimport { resolvePlayer } from './utils'\n\nexport class MediaLiveButton extends HTMLElementBase {\n private cleanup: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: none; }\n :host([available]) { display: inline-flex; }\n button { display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 8px; background: transparent; border: 0; color: inherit; cursor: pointer; font: inherit; font-size: 12px; font-weight: 700; }\n i { width: 8px; height: 8px; border-radius: 9999px; background: #ef4444; }\n :host(:not([at-live-edge])) button { opacity: 0.72; }\n </style>\n <button part=\"button\" type=\"button\" aria-label=\"Go to live edge\"><i aria-hidden=\"true\"></i><span>LIVE</span></button>\n `\n }\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this.cleanup?.()\n this.cleanup = null\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n const button = this.shadowRoot?.querySelector('button')\n if (!player || !button) return\n const threshold = Math.max(0, Number(this.getAttribute('threshold') || 10))\n const update = (): void => {\n const state = player.state\n const end = state.seekable.at(-1)?.end\n const providerLive = (player.provider as { isLive?: boolean } | null)?.isLive === true\n const available = end !== undefined && (providerLive || !Number.isFinite(state.duration))\n const atLiveEdge = available && end - state.currentTime <= threshold\n this.toggleAttribute('available', available)\n this.toggleAttribute('at-live-edge', atLiveEdge)\n button.setAttribute('aria-pressed', String(atLiveEdge))\n }\n const click = (): void => {\n const end = player.state.seekable.at(-1)?.end\n if (end !== undefined) {\n player.seekTo(end)\n void player.play()\n }\n }\n button.addEventListener('click', click)\n const unsubscribe = player.subscribe(update)\n update()\n this.cleanup = () => {\n unsubscribe()\n button.removeEventListener('click', click)\n }\n }\n}\n",
35
+ "/**\n * ts-video-player <media-error-display> Custom Element\n *\n * @module elements/media-error-display\n */\n\nimport { HTMLElementBase } from './base'\nimport { resolvePlayer } from './utils'\n\nexport class MediaErrorDisplay extends HTMLElementBase {\n private cleanup: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: none; position: absolute; inset: 0; z-index: 5; place-items: center; padding: 24px; background: rgba(0, 0, 0, 0.76); color: white; text-align: center; }\n :host([open]) { display: grid; }\n p { max-width: 42rem; margin: 0; font: 500 14px/1.5 system-ui, sans-serif; }\n </style>\n <p part=\"message\" role=\"alert\" aria-live=\"assertive\"></p>\n `\n }\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this.cleanup?.()\n this.cleanup = null\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n const message = this.shadowRoot?.querySelector('p')\n if (!player || !message) return\n const update = (): void => {\n const error = player.state.error\n this.toggleAttribute('open', !!error)\n message.textContent = error?.message || ''\n if (error?.code !== undefined) this.setAttribute('data-code', String(error.code))\n else this.removeAttribute('data-code')\n }\n this.cleanup = player.subscribe(update)\n update()\n }\n}\n",
36
+ "/**\n * ts-video-player <media-remote-playback-button> Custom Element\n *\n * Uses the browser Remote Playback API for native device pickers such as\n * Google Cast without loading a vendor SDK.\n *\n * @module elements/media-remote-playback-button\n */\n\nimport { HTMLElementBase } from './base'\nimport { resolvePlayer } from './utils'\n\nconst REMOTE_ICON = 'M1 18v3h3a3 3 0 0 0-3-3zm0-4v2a5 5 0 0 1 5 5h2a7 7 0 0 0-7-7zm0-4v2c5 0 9 4 9 9h2c0-6.1-4.9-11-11-11zm18-7H5a2 2 0 0 0-2 2v3h2V5h14v10h-5v2h5a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2z'\n\ninterface RemotePlaybackHandle extends EventTarget {\n state: 'connecting' | 'connected' | 'disconnected'\n prompt: () => Promise<void>\n watchAvailability: (_callback: (_available: boolean) => void) => Promise<number>\n cancelWatchAvailability: (_id: number) => Promise<void>\n}\n\nexport class MediaRemotePlaybackButton extends HTMLElementBase {\n private cleanup: (() => void) | null = null\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const shadow = this.attachShadow({ mode: 'open' })\n shadow.innerHTML = `\n <style>\n :host { display: none; }\n :host([available]) { display: inline-flex; }\n button { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; padding: 8px; background: transparent; border: 0; color: inherit; cursor: pointer; }\n button:hover { opacity: 0.8; }\n :host([connected]) button { color: var(--media-remote-active-color, #38bdf8); }\n </style>\n <button part=\"button\" type=\"button\" aria-label=\"Play on another device\">\n <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"currentColor\" part=\"icon\"><path d=\"${REMOTE_ICON}\"/></svg>\n </button>\n `\n }\n queueMicrotask(() => this.attach())\n }\n\n disconnectedCallback(): void {\n this.cleanup?.()\n this.cleanup = null\n }\n\n private attach(): void {\n const player = resolvePlayer(this)\n const button = this.shadowRoot?.querySelector('button')\n if (!player || !button) return\n let remote: RemotePlaybackHandle | null = null\n let watchId: number | null = null\n let generation = 0\n\n const stateChanged = (): void => {\n const connected = remote?.state === 'connected'\n this.toggleAttribute('connected', connected)\n button.setAttribute('aria-pressed', String(connected))\n }\n const detachRemote = (): void => {\n generation++\n remote?.removeEventListener('connecting', stateChanged)\n remote?.removeEventListener('connect', stateChanged)\n remote?.removeEventListener('disconnect', stateChanged)\n if (remote && watchId !== null) void remote.cancelWatchAvailability(watchId).catch(() => {})\n remote = null\n watchId = null\n this.removeAttribute('available')\n this.removeAttribute('connected')\n }\n const update = (): void => {\n const media = player.provider?.mediaElement\n const nextRemote = media instanceof HTMLMediaElement\n ? (media as HTMLMediaElement & { remote?: RemotePlaybackHandle }).remote ?? null\n : null\n if (nextRemote === remote) return\n detachRemote()\n if (!nextRemote) return\n remote = nextRemote\n const currentGeneration = generation\n remote.addEventListener('connecting', stateChanged)\n remote.addEventListener('connect', stateChanged)\n remote.addEventListener('disconnect', stateChanged)\n stateChanged()\n void remote.watchAvailability((available) => {\n if (generation === currentGeneration && remote === nextRemote) this.toggleAttribute('available', available)\n })\n .then((id) => {\n if (generation === currentGeneration && remote === nextRemote) watchId = id\n else void nextRemote.cancelWatchAvailability(id).catch(() => {})\n })\n .catch(() => this.removeAttribute('available'))\n }\n const click = (): void => {\n void remote?.prompt().catch(() => {})\n }\n button.addEventListener('click', click)\n const unsubscribe = player.subscribe(update)\n update()\n this.cleanup = () => {\n unsubscribe()\n button.removeEventListener('click', click)\n detachRemote()\n }\n }\n}\n",
37
+ "/**\n * ts-video-player Custom Elements\n *\n * Web Components for building video player interfaces.\n *\n * @module elements\n */\n\nexport { VideoPlayerElement } from './video-player'\nexport { VideoSkin } from './video-skin'\nexport { MediaPlayButton } from './media-play-button'\nexport { MediaMuteButton } from './media-mute-button'\nexport { MediaFullscreenButton } from './media-fullscreen-button'\nexport { MediaPipButton } from './media-pip-button'\nexport { MediaTimeDisplay } from './media-time-display'\nexport { MediaTimeGroup } from './media-time-group'\nexport { MediaTimeSeparator } from './media-time-separator'\nexport { MediaPreviewTime } from './media-preview-time'\nexport { MediaProgressBar } from './media-progress-bar'\nexport { MediaVolumeSlider } from './media-volume-slider'\nexport { MediaSettingsMenu } from './media-settings-menu'\nexport { MediaSeekButton } from './media-seek-button'\nexport { MediaPlaybackRateButton } from './media-playback-rate-button'\nexport { MediaAirplayButton } from './media-airplay-button'\nexport { MediaLiveButton } from './media-live-button'\nexport { MediaErrorDisplay } from './media-error-display'\nexport { MediaRemotePlaybackButton } from './media-remote-playback-button'\nexport { formatTime, formatTimePhrase, toISODuration, resolvePlayer } from './utils'\n\nimport { VideoPlayerElement } from './video-player'\nimport { VideoSkin } from './video-skin'\nimport { MediaPlayButton } from './media-play-button'\nimport { MediaMuteButton } from './media-mute-button'\nimport { MediaFullscreenButton } from './media-fullscreen-button'\nimport { MediaPipButton } from './media-pip-button'\nimport { MediaTimeDisplay } from './media-time-display'\nimport { MediaTimeGroup } from './media-time-group'\nimport { MediaTimeSeparator } from './media-time-separator'\nimport { MediaPreviewTime } from './media-preview-time'\nimport { MediaProgressBar } from './media-progress-bar'\nimport { MediaVolumeSlider } from './media-volume-slider'\nimport { MediaSettingsMenu } from './media-settings-menu'\nimport { MediaSeekButton } from './media-seek-button'\nimport { MediaPlaybackRateButton } from './media-playback-rate-button'\nimport { MediaAirplayButton } from './media-airplay-button'\nimport { MediaLiveButton } from './media-live-button'\nimport { MediaErrorDisplay } from './media-error-display'\nimport { MediaRemotePlaybackButton } from './media-remote-playback-button'\n\nconst elements = [\n ['video-player', VideoPlayerElement],\n ['video-skin', VideoSkin],\n ['media-play-button', MediaPlayButton],\n ['media-mute-button', MediaMuteButton],\n ['media-fullscreen-button', MediaFullscreenButton],\n ['media-pip-button', MediaPipButton],\n ['media-time-display', MediaTimeDisplay],\n ['media-time-group', MediaTimeGroup],\n ['media-time-separator', MediaTimeSeparator],\n ['media-preview-time', MediaPreviewTime],\n ['media-progress-bar', MediaProgressBar],\n ['media-volume-slider', MediaVolumeSlider],\n ['media-settings-menu', MediaSettingsMenu],\n ['media-seek-button', MediaSeekButton],\n ['media-playback-rate-button', MediaPlaybackRateButton],\n ['media-airplay-button', MediaAirplayButton],\n ['media-live-button', MediaLiveButton],\n ['media-error-display', MediaErrorDisplay],\n ['media-remote-playback-button', MediaRemotePlaybackButton],\n] as const\n\n/**\n * Register all custom elements.\n * Safe to call multiple times — skips already-defined elements.\n */\nexport function registerElements(): void {\n for (const [name, ctor] of elements) {\n if (!customElements.get(name)) {\n customElements.define(name, ctor)\n }\n }\n}\n"
38
+ ],
39
+ "mappings": "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",
40
+ "debugId": "BE17C381D5DC647964756E2164756E21",
41
+ "names": []
42
+ }