@therealtinhtute/baroiplayer 1.0.7 → 1.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 (1003) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +15 -15
  3. package/dist/context/media.js +2 -0
  4. package/dist/context/media.js.map +1 -0
  5. package/dist/context/media.mjs +15 -0
  6. package/dist/context/media.mjs.map +1 -0
  7. package/dist/context/store.js +2 -0
  8. package/dist/context/store.js.map +1 -0
  9. package/dist/context/store.mjs +5 -0
  10. package/dist/context/store.mjs.map +1 -0
  11. package/dist/context-BYwDoSRX.js +1172 -0
  12. package/dist/context-BYwDoSRX.js.map +1 -0
  13. package/dist/context-eNS62_ac.cjs +23 -0
  14. package/dist/context-eNS62_ac.cjs.map +1 -0
  15. package/dist/core-events-B1iM2F46.cjs +2 -0
  16. package/dist/core-events-B1iM2F46.cjs.map +1 -0
  17. package/dist/core-events-DunPHKRE.js +484 -0
  18. package/dist/core-events-DunPHKRE.js.map +1 -0
  19. package/dist/core-plugins-CROGvQUy.js +686 -0
  20. package/dist/core-plugins-CROGvQUy.js.map +1 -0
  21. package/dist/core-plugins-DtsHBOtF.cjs +2 -0
  22. package/dist/core-plugins-DtsHBOtF.cjs.map +1 -0
  23. package/dist/core.js +37 -0
  24. package/dist/core.js.map +1 -0
  25. package/dist/core.mjs +1233 -0
  26. package/dist/core.mjs.map +1 -0
  27. package/dist/enhanced-components-DUw2KrmQ.js +1142 -0
  28. package/dist/enhanced-components-DUw2KrmQ.js.map +1 -0
  29. package/dist/enhanced-components-DXBCHU0v.cjs +2 -0
  30. package/dist/enhanced-components-DXBCHU0v.cjs.map +1 -0
  31. package/dist/hooks-BW-JjVgP.cjs +4 -0
  32. package/dist/hooks-BW-JjVgP.cjs.map +1 -0
  33. package/dist/hooks-CyX6De5M.js +1693 -0
  34. package/dist/hooks-CyX6De5M.js.map +1 -0
  35. package/dist/index.css +1 -102
  36. package/dist/index.js +112 -27
  37. package/dist/index.js.map +1 -0
  38. package/dist/index.mjs +6275 -17
  39. package/dist/index.mjs.map +1 -0
  40. package/dist/minimal-components-Bdcpxav5.cjs +2 -0
  41. package/dist/minimal-components-Bdcpxav5.cjs.map +1 -0
  42. package/dist/minimal-components-DlRK7Qu_.js +1927 -0
  43. package/dist/minimal-components-DlRK7Qu_.js.map +1 -0
  44. package/dist/minimal-components.css +1 -589
  45. package/dist/mona-loading.gif +0 -0
  46. package/dist/performance-monitor-C5k6FDXw.js +301 -0
  47. package/dist/performance-monitor-C5k6FDXw.js.map +1 -0
  48. package/dist/performance-monitor-lJmuUjQQ.cjs +2 -0
  49. package/dist/performance-monitor-lJmuUjQQ.cjs.map +1 -0
  50. package/dist/utils-CFOue_9K.cjs +9 -0
  51. package/dist/utils-CFOue_9K.cjs.map +1 -0
  52. package/dist/utils-Dzpl2ArK.js +2844 -0
  53. package/dist/utils-Dzpl2ArK.js.map +1 -0
  54. package/dist/utils.js +2 -0
  55. package/dist/utils.js.map +1 -0
  56. package/dist/utils.mjs +11 -0
  57. package/dist/utils.mjs.map +1 -0
  58. package/package.json +11 -40
  59. package/src/adapters/videojs-adapter.tsx +441 -441
  60. package/src/components/AnimateLoading.tsx +85 -93
  61. package/src/components/LoadingState.tsx +199 -208
  62. package/src/components/__tests__/media-player-accessibility.test.tsx +510 -0
  63. package/src/components/__tests__/media-player-react19.test.tsx +457 -0
  64. package/src/components/accessibility/keyboard-help-overlay.tsx +199 -207
  65. package/src/components/basic/index.ts +28 -28
  66. package/src/components/enhanced/advanced-features.tsx +49 -54
  67. package/src/components/enhanced/debug-panel.tsx +148 -122
  68. package/src/components/enhanced/enhanced-controls.tsx +117 -120
  69. package/src/components/enhanced/enhanced-media-player.tsx +228 -214
  70. package/src/components/enhanced/error-handling.tsx +50 -57
  71. package/src/components/enhanced/index.ts +27 -27
  72. package/src/components/enhanced/media-player-enhanced.tsx +117 -83
  73. package/src/components/examples/basic-video-player.tsx +35 -40
  74. package/src/components/examples/enhanced-controls-example.tsx +16 -30
  75. package/src/components/examples/enhanced-media-player-example.tsx +196 -187
  76. package/src/components/examples/loading-states-demo.tsx +113 -113
  77. package/src/components/examples/react-19-demo.tsx +88 -116
  78. package/src/components/examples/volume-orientation-demo.tsx +77 -85
  79. package/src/components/icon-demo.tsx +189 -202
  80. package/src/components/icons/svg-icons/ArrowLeftIcon.tsx +13 -13
  81. package/src/components/icons/svg-icons/ArrowRightIcon.tsx +13 -13
  82. package/src/components/icons/svg-icons/AudioIcon.tsx +16 -16
  83. package/src/components/icons/svg-icons/BackwardIcon.tsx +7 -7
  84. package/src/components/icons/svg-icons/CameraIcon.tsx +13 -13
  85. package/src/components/icons/svg-icons/CheckIcon.tsx +13 -13
  86. package/src/components/icons/svg-icons/EnablePiPIcon.tsx +13 -13
  87. package/src/components/icons/svg-icons/ForwardIcon.tsx +7 -7
  88. package/src/components/icons/svg-icons/FullscreenEnterIcon.tsx +18 -18
  89. package/src/components/icons/svg-icons/FullscreenExitIcon.tsx +18 -18
  90. package/src/components/icons/svg-icons/LoadingIcon.tsx +27 -27
  91. package/src/components/icons/svg-icons/PauseIcon.tsx +18 -18
  92. package/src/components/icons/svg-icons/PlayIcon.tsx +16 -16
  93. package/src/components/icons/svg-icons/PlaybackSpeedIcon.tsx +18 -18
  94. package/src/components/icons/svg-icons/QualityIcon.tsx +16 -16
  95. package/src/components/icons/svg-icons/SettingsIcon.tsx +7 -7
  96. package/src/components/icons/svg-icons/SliderIcon.tsx +16 -16
  97. package/src/components/icons/svg-icons/SubtitleIcon.tsx +16 -16
  98. package/src/components/icons/svg-icons/SubtitleOffIcon.tsx +20 -20
  99. package/src/components/icons/svg-icons/UnPiPIcon.tsx +13 -13
  100. package/src/components/icons/svg-icons/VolumeMutedIcon.tsx +11 -11
  101. package/src/components/icons/svg-icons/VolumeOneIcon.tsx +17 -17
  102. package/src/components/icons/svg-icons/VolumeThreeIcon.tsx +11 -11
  103. package/src/components/icons/svg-icons/VolumeTwoIcon.tsx +11 -11
  104. package/src/components/legacy.tsx +8 -14
  105. package/src/components/media-metadata-display.tsx +78 -79
  106. package/src/components/media-player-controls.tsx +37 -40
  107. package/src/components/media-player-error.tsx +2 -2
  108. package/src/components/media-player-fullscreen.tsx +2 -2
  109. package/src/components/media-player-hls.tsx +89 -89
  110. package/src/components/media-player-play.tsx +2 -2
  111. package/src/components/media-player-root.tsx +20 -22
  112. package/src/components/media-player-seek.tsx +1 -1
  113. package/src/components/media-player-tooltip.tsx +1 -1
  114. package/src/components/media-player-video.tsx +28 -6
  115. package/src/components/media-player-volume.tsx +3 -3
  116. package/src/components/media-player.tsx +209 -174
  117. package/src/components/media-suspense.tsx +71 -89
  118. package/src/components/player-settings-form.tsx +143 -148
  119. package/src/components/react-player-wrapper.tsx +23 -23
  120. package/src/components/simple-video-player.tsx +53 -51
  121. package/src/components/ui/blur-poster.tsx +93 -0
  122. package/src/components/ui/empty-state.tsx +91 -0
  123. package/src/components/ui/enhanced-seek-bar.tsx +75 -56
  124. package/src/components/ui/error-state.tsx +124 -0
  125. package/src/components/ui/fullscreen-button.tsx +71 -50
  126. package/src/components/ui/loading-skeleton.tsx +107 -0
  127. package/src/components/ui/media-resource-preloader.tsx +265 -198
  128. package/src/components/ui/offline-message.tsx +98 -0
  129. package/src/components/ui/play-button.tsx +79 -87
  130. package/src/components/ui/seek-bar.tsx +170 -140
  131. package/src/components/ui/time-display.tsx +33 -12
  132. package/src/components/ui/volume-control.tsx +91 -44
  133. package/src/components/unified/base-media-player.tsx +45 -51
  134. package/src/components/unified/media-player.tsx +3 -3
  135. package/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +508 -502
  136. package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +108 -87
  137. package/src/components/variants/minimal/MinimalControls.tsx +100 -118
  138. package/src/components/variants/minimal/MinimalLoading.tsx +19 -23
  139. package/src/components/variants/minimal/MinimalMediaPlayer.tsx +283 -280
  140. package/src/components/variants/minimal/MinimalOverlay.tsx +43 -49
  141. package/src/components/variants/minimal/MinimalPlayButton.tsx +44 -53
  142. package/src/components/variants/minimal/MinimalSeekBar.tsx +130 -140
  143. package/src/components/variants/minimal/MinimalVolumeControl.tsx +59 -64
  144. package/src/components/variants/minimal/SimpleMinimalPlayer.tsx +29 -32
  145. package/src/components/variants/minimal/components/CenterPlayButton.tsx +1 -1
  146. package/src/components/variants/minimal/components/ControlBar.tsx +7 -11
  147. package/src/components/variants/minimal/components/EnhancedSettingsMenu.tsx +381 -330
  148. package/src/components/variants/minimal/components/PlaybackControls.tsx +6 -11
  149. package/src/components/variants/minimal/components/RightControls.tsx +8 -17
  150. package/src/components/variants/minimal/components/SeekBar.tsx +16 -20
  151. package/src/components/variants/minimal/components/SettingsDropdown.tsx +12 -14
  152. package/src/components/variants/minimal/components/SubtitleDisplay.tsx +1 -1
  153. package/src/components/variants/minimal/components/TimeDisplay.tsx +2 -5
  154. package/src/components/variants/minimal/components/VideoElement.tsx +3 -10
  155. package/src/components/variants/minimal/components/VolumeControl.tsx +42 -39
  156. package/src/components/video-player.tsx +10 -10
  157. package/src/context/__tests__/media-store.test.ts +509 -0
  158. package/src/context/error-handling.ts +106 -102
  159. package/src/context/media-context.tsx +56 -10
  160. package/src/context/media-provider.tsx +16 -17
  161. package/src/context/media-store.ts +68 -60
  162. package/src/context/persistence.ts +74 -65
  163. package/src/core/events/event-system.ts +422 -416
  164. package/src/core/events/hooks.ts +275 -252
  165. package/src/core/events/index.ts +14 -14
  166. package/src/core/events/middleware.ts +269 -252
  167. package/src/core/index.ts +8 -8
  168. package/src/core/optimization/bundle-optimizer.tsx +65 -60
  169. package/src/core/performance/cicd.ts +91 -89
  170. package/src/core/performance/index.ts +22 -22
  171. package/src/core/performance/media-loading-optimizer.ts +518 -512
  172. package/src/core/performance/performance-budgets.ts +414 -409
  173. package/src/core/performance/performance-monitor.tsx +451 -439
  174. package/src/core/performance/performance-testing.ts +439 -437
  175. package/src/core/plugins/__tests__/registry.test.ts +595 -0
  176. package/src/core/plugins/base-plugin.ts +197 -196
  177. package/src/core/plugins/enhanced-plugin-system.ts +136 -136
  178. package/src/core/plugins/examples/analytics-plugin.ts +229 -230
  179. package/src/core/plugins/index.ts +26 -26
  180. package/src/core/plugins/registry.ts +315 -323
  181. package/src/core/plugins/types.ts +97 -105
  182. package/src/core/plugins/utils.ts +292 -291
  183. package/src/core/progressive-loading.tsx +297 -288
  184. package/src/core/providers/enhanced-hls-provider.ts +118 -90
  185. package/src/core/providers/lazy-provider.tsx +51 -0
  186. package/src/core/providers/service-provider.tsx +104 -108
  187. package/src/core/utils.tsx +22 -26
  188. package/src/features/media-session/media-session-manager.ts +406 -402
  189. package/src/features/picture-in-picture/pip-manager.ts +364 -365
  190. package/src/features/playlist/playlist-manager.ts +597 -585
  191. package/src/features/subtitles/subtitle-manager.ts +424 -430
  192. package/src/features/subtitles/subtitle-parser.ts +274 -273
  193. package/src/features/thumbnails/thumbnail-generator.ts +504 -502
  194. package/src/hooks/__tests__/use-media-player.test.ts +712 -0
  195. package/src/hooks/__tests__/use-media-state.test.tsx +316 -0
  196. package/src/hooks/accessibility/index.ts +20 -20
  197. package/src/hooks/accessibility/use-accessibility-preferences.ts +177 -175
  198. package/src/hooks/accessibility/use-focus-management.ts +170 -163
  199. package/src/hooks/accessibility/use-keyboard-shortcuts.ts +132 -124
  200. package/src/hooks/accessibility/use-screen-reader.ts +191 -161
  201. package/src/hooks/core/index.ts +30 -30
  202. package/src/hooks/legacy.ts +3 -9
  203. package/src/hooks/use-buffer-health.ts +218 -0
  204. package/src/hooks/use-enhanced-media-player.ts +74 -82
  205. package/src/hooks/use-focus-trap.tsx +162 -0
  206. package/src/hooks/use-intelligent-preloading.ts +236 -232
  207. package/src/hooks/use-keyboard-controls.ts +80 -80
  208. package/src/hooks/use-keyboard-shortcuts.ts +255 -0
  209. package/src/hooks/use-media-actions.ts +81 -72
  210. package/src/hooks/use-media-metadata.ts +75 -73
  211. package/src/hooks/use-media-optimistic.ts +145 -151
  212. package/src/hooks/use-media-player.ts +109 -107
  213. package/src/hooks/use-media-state.ts +63 -59
  214. package/src/hooks/use-memory-optimization.ts +119 -117
  215. package/src/hooks/use-network-status.ts +124 -0
  216. package/src/hooks/use-optimistic-controls.ts +91 -88
  217. package/src/hooks/use-optimized-media.ts +76 -56
  218. package/src/hooks/use-smart-preload.ts +230 -0
  219. package/src/hooks/use-touch-gestures.ts +427 -383
  220. package/src/hooks/useEnhancedSubtitles.ts +245 -245
  221. package/src/hooks/useKeyboardShortcuts.ts +52 -52
  222. package/src/hooks/useMediaControls.ts +22 -22
  223. package/src/hooks/useScreenshot.ts +51 -47
  224. package/src/hooks/useSubtitles.ts +53 -53
  225. package/src/hooks/useVideoPlayer.ts +61 -61
  226. package/src/icons/components/FullscreenIcon.tsx +34 -35
  227. package/src/icons/components/SettingsIcon.tsx +35 -36
  228. package/src/icons/components/animated/LoadingIcon.tsx +25 -41
  229. package/src/icons/components/animated/PlayPauseIcon.tsx +38 -46
  230. package/src/icons/components/media/PauseIcon.tsx +36 -37
  231. package/src/icons/components/media/PlayIcon.tsx +35 -36
  232. package/src/icons/components/volume/VolumeIcon.tsx +36 -37
  233. package/src/icons/components/volume/VolumeOffIcon.tsx +36 -37
  234. package/src/icons/index.ts +38 -38
  235. package/src/icons/provider.tsx +40 -46
  236. package/src/icons/types.ts +51 -31
  237. package/src/index-enhanced.ts +10 -10
  238. package/src/index-legacy.ts +3 -4
  239. package/src/index.css +80 -80
  240. package/src/index.ts +8 -23
  241. package/src/lib/__tests__/async-utils.test.ts +291 -0
  242. package/src/lib/async-utils.ts +194 -0
  243. package/src/lib/deprecation.ts +4 -4
  244. package/src/lib/index.ts +3 -2
  245. package/src/lib/utils.ts +3 -3
  246. package/src/styles/globals.css +3 -3
  247. package/src/styles/minimal-player.css +606 -574
  248. package/src/styles/pixel-art.css +23 -28
  249. package/src/styles/videojs.css +43 -43
  250. package/src/test/accessibility-utils.ts +208 -0
  251. package/src/test/browser-simulation.ts +235 -0
  252. package/src/test/media-mocks.ts +156 -0
  253. package/src/test/performance-utils.ts +192 -0
  254. package/src/test/setup.ts +241 -44
  255. package/src/types/events.ts +30 -30
  256. package/src/types/formats.ts +56 -72
  257. package/src/types/index.ts +5 -40
  258. package/src/types/videojs-plugins.d.ts +6 -6
  259. package/dist/index.d.ts +0 -1425
  260. package/dist/package.json +0 -62
  261. package/dist/src/adapters/videojs-adapter.d.ts +0 -38
  262. package/dist/src/adapters/videojs-adapter.tsx +0 -470
  263. package/dist/src/components/AnimateLoading.d.ts +0 -9
  264. package/dist/src/components/AnimateLoading.tsx +0 -115
  265. package/dist/src/components/LoadingState.d.ts +0 -33
  266. package/dist/src/components/LoadingState.tsx +0 -248
  267. package/dist/src/components/accessibility/keyboard-help-overlay.d.ts +0 -17
  268. package/dist/src/components/accessibility/keyboard-help-overlay.tsx +0 -213
  269. package/dist/src/components/audio-player.d.ts +0 -3
  270. package/dist/src/components/audio-player.tsx +0 -85
  271. package/dist/src/components/basic/index.d.ts +0 -26
  272. package/dist/src/components/basic/index.ts +0 -37
  273. package/dist/src/components/enhanced/advanced-features.d.ts +0 -45
  274. package/dist/src/components/enhanced/advanced-features.tsx +0 -316
  275. package/dist/src/components/enhanced/debug-panel.d.ts +0 -70
  276. package/dist/src/components/enhanced/debug-panel.tsx +0 -422
  277. package/dist/src/components/enhanced/enhanced-controls.d.ts +0 -50
  278. package/dist/src/components/enhanced/enhanced-controls.tsx +0 -600
  279. package/dist/src/components/enhanced/enhanced-media-player.d.ts +0 -26
  280. package/dist/src/components/enhanced/enhanced-media-player.tsx +0 -509
  281. package/dist/src/components/enhanced/error-handling.d.ts +0 -36
  282. package/dist/src/components/enhanced/error-handling.tsx +0 -345
  283. package/dist/src/components/enhanced/index.d.ts +0 -7
  284. package/dist/src/components/enhanced/index.ts +0 -39
  285. package/dist/src/components/enhanced/media-player-enhanced.d.ts +0 -21
  286. package/dist/src/components/enhanced/media-player-enhanced.tsx +0 -349
  287. package/dist/src/components/examples/basic-video-player.d.ts +0 -10
  288. package/dist/src/components/examples/basic-video-player.tsx +0 -55
  289. package/dist/src/components/examples/custom-controls-example.d.ts +0 -10
  290. package/dist/src/components/examples/custom-controls-example.tsx +0 -63
  291. package/dist/src/components/examples/enhanced-controls-example.d.ts +0 -9
  292. package/dist/src/components/examples/enhanced-controls-example.tsx +0 -114
  293. package/dist/src/components/examples/enhanced-media-player-example.d.ts +0 -9
  294. package/dist/src/components/examples/enhanced-media-player-example.tsx +0 -293
  295. package/dist/src/components/examples/loading-states-demo.d.ts +0 -2
  296. package/dist/src/components/examples/loading-states-demo.tsx +0 -142
  297. package/dist/src/components/examples/react-19-demo.d.ts +0 -10
  298. package/dist/src/components/examples/react-19-demo.tsx +0 -381
  299. package/dist/src/components/examples/volume-orientation-demo.d.ts +0 -2
  300. package/dist/src/components/examples/volume-orientation-demo.tsx +0 -114
  301. package/dist/src/components/icon-demo.d.ts +0 -2
  302. package/dist/src/components/icon-demo.tsx +0 -209
  303. package/dist/src/components/icons/index.d.ts +0 -36
  304. package/dist/src/components/icons/index.tsx +0 -166
  305. package/dist/src/components/icons/svg-icons/ArrowLeftIcon.d.ts +0 -4
  306. package/dist/src/components/icons/svg-icons/ArrowLeftIcon.tsx +0 -18
  307. package/dist/src/components/icons/svg-icons/ArrowRightIcon.d.ts +0 -4
  308. package/dist/src/components/icons/svg-icons/ArrowRightIcon.tsx +0 -18
  309. package/dist/src/components/icons/svg-icons/AudioIcon.d.ts +0 -4
  310. package/dist/src/components/icons/svg-icons/AudioIcon.tsx +0 -22
  311. package/dist/src/components/icons/svg-icons/BackwardIcon.d.ts +0 -4
  312. package/dist/src/components/icons/svg-icons/BackwardIcon.tsx +0 -12
  313. package/dist/src/components/icons/svg-icons/CameraIcon.d.ts +0 -4
  314. package/dist/src/components/icons/svg-icons/CameraIcon.tsx +0 -19
  315. package/dist/src/components/icons/svg-icons/CheckIcon.d.ts +0 -4
  316. package/dist/src/components/icons/svg-icons/CheckIcon.tsx +0 -19
  317. package/dist/src/components/icons/svg-icons/EnablePiPIcon.d.ts +0 -4
  318. package/dist/src/components/icons/svg-icons/EnablePiPIcon.tsx +0 -17
  319. package/dist/src/components/icons/svg-icons/ForwardIcon.d.ts +0 -4
  320. package/dist/src/components/icons/svg-icons/ForwardIcon.tsx +0 -12
  321. package/dist/src/components/icons/svg-icons/FullscreenEnterIcon.d.ts +0 -4
  322. package/dist/src/components/icons/svg-icons/FullscreenEnterIcon.tsx +0 -23
  323. package/dist/src/components/icons/svg-icons/FullscreenExitIcon.d.ts +0 -4
  324. package/dist/src/components/icons/svg-icons/FullscreenExitIcon.tsx +0 -23
  325. package/dist/src/components/icons/svg-icons/LoadingIcon.d.ts +0 -4
  326. package/dist/src/components/icons/svg-icons/LoadingIcon.tsx +0 -32
  327. package/dist/src/components/icons/svg-icons/PauseIcon.d.ts +0 -4
  328. package/dist/src/components/icons/svg-icons/PauseIcon.tsx +0 -23
  329. package/dist/src/components/icons/svg-icons/PlayIcon.d.ts +0 -4
  330. package/dist/src/components/icons/svg-icons/PlayIcon.tsx +0 -21
  331. package/dist/src/components/icons/svg-icons/PlaybackSpeedIcon.d.ts +0 -4
  332. package/dist/src/components/icons/svg-icons/PlaybackSpeedIcon.tsx +0 -23
  333. package/dist/src/components/icons/svg-icons/QualityIcon.d.ts +0 -4
  334. package/dist/src/components/icons/svg-icons/QualityIcon.tsx +0 -21
  335. package/dist/src/components/icons/svg-icons/SettingsIcon.d.ts +0 -4
  336. package/dist/src/components/icons/svg-icons/SettingsIcon.tsx +0 -12
  337. package/dist/src/components/icons/svg-icons/SliderIcon.d.ts +0 -4
  338. package/dist/src/components/icons/svg-icons/SliderIcon.tsx +0 -21
  339. package/dist/src/components/icons/svg-icons/SubtitleIcon.d.ts +0 -4
  340. package/dist/src/components/icons/svg-icons/SubtitleIcon.tsx +0 -21
  341. package/dist/src/components/icons/svg-icons/SubtitleOffIcon.d.ts +0 -4
  342. package/dist/src/components/icons/svg-icons/SubtitleOffIcon.tsx +0 -25
  343. package/dist/src/components/icons/svg-icons/UnPiPIcon.d.ts +0 -4
  344. package/dist/src/components/icons/svg-icons/UnPiPIcon.tsx +0 -17
  345. package/dist/src/components/icons/svg-icons/VolumeMutedIcon.d.ts +0 -4
  346. package/dist/src/components/icons/svg-icons/VolumeMutedIcon.tsx +0 -16
  347. package/dist/src/components/icons/svg-icons/VolumeOneIcon.d.ts +0 -4
  348. package/dist/src/components/icons/svg-icons/VolumeOneIcon.tsx +0 -22
  349. package/dist/src/components/icons/svg-icons/VolumeThreeIcon.d.ts +0 -4
  350. package/dist/src/components/icons/svg-icons/VolumeThreeIcon.tsx +0 -16
  351. package/dist/src/components/icons/svg-icons/VolumeTwoIcon.d.ts +0 -4
  352. package/dist/src/components/icons/svg-icons/VolumeTwoIcon.tsx +0 -16
  353. package/dist/src/components/legacy.d.ts +0 -13
  354. package/dist/src/components/legacy.tsx +0 -93
  355. package/dist/src/components/media-metadata-display.d.ts +0 -11
  356. package/dist/src/components/media-metadata-display.tsx +0 -100
  357. package/dist/src/components/media-player-audio.d.ts +0 -9
  358. package/dist/src/components/media-player-audio.tsx +0 -39
  359. package/dist/src/components/media-player-controls.d.ts +0 -23
  360. package/dist/src/components/media-player-controls.tsx +0 -226
  361. package/dist/src/components/media-player-error.d.ts +0 -16
  362. package/dist/src/components/media-player-error.tsx +0 -163
  363. package/dist/src/components/media-player-fullscreen.d.ts +0 -12
  364. package/dist/src/components/media-player-fullscreen.tsx +0 -109
  365. package/dist/src/components/media-player-hls.d.ts +0 -23
  366. package/dist/src/components/media-player-hls.tsx +0 -111
  367. package/dist/src/components/media-player-loading.d.ts +0 -12
  368. package/dist/src/components/media-player-loading.tsx +0 -76
  369. package/dist/src/components/media-player-play.d.ts +0 -11
  370. package/dist/src/components/media-player-play.tsx +0 -75
  371. package/dist/src/components/media-player-root.d.ts +0 -28
  372. package/dist/src/components/media-player-root.tsx +0 -340
  373. package/dist/src/components/media-player-seek.d.ts +0 -15
  374. package/dist/src/components/media-player-seek.tsx +0 -168
  375. package/dist/src/components/media-player-time.d.ts +0 -12
  376. package/dist/src/components/media-player-time.tsx +0 -99
  377. package/dist/src/components/media-player-tooltip.d.ts +0 -13
  378. package/dist/src/components/media-player-tooltip.tsx +0 -58
  379. package/dist/src/components/media-player-video.d.ts +0 -9
  380. package/dist/src/components/media-player-video.tsx +0 -39
  381. package/dist/src/components/media-player-volume.d.ts +0 -13
  382. package/dist/src/components/media-player-volume.tsx +0 -155
  383. package/dist/src/components/media-player.d.ts +0 -3
  384. package/dist/src/components/media-player.tsx +0 -257
  385. package/dist/src/components/media-suspense.d.ts +0 -78
  386. package/dist/src/components/media-suspense.tsx +0 -362
  387. package/dist/src/components/player-settings-form.d.ts +0 -8
  388. package/dist/src/components/player-settings-form.tsx +0 -163
  389. package/dist/src/components/react-player-wrapper.d.ts +0 -64
  390. package/dist/src/components/react-player-wrapper.tsx +0 -651
  391. package/dist/src/components/simple-video-player.d.ts +0 -9
  392. package/dist/src/components/simple-video-player.tsx +0 -60
  393. package/dist/src/components/ui/button.tsx +0 -49
  394. package/dist/src/components/ui/dropdown-menu.tsx +0 -137
  395. package/dist/src/components/ui/enhanced-seek-bar.d.ts +0 -3
  396. package/dist/src/components/ui/enhanced-seek-bar.tsx +0 -235
  397. package/dist/src/components/ui/fullscreen-button.d.ts +0 -3
  398. package/dist/src/components/ui/fullscreen-button.tsx +0 -60
  399. package/dist/src/components/ui/icons.tsx +0 -174
  400. package/dist/src/components/ui/media-resource-preloader.d.ts +0 -21
  401. package/dist/src/components/ui/media-resource-preloader.tsx +0 -393
  402. package/dist/src/components/ui/play-button.d.ts +0 -3
  403. package/dist/src/components/ui/play-button.tsx +0 -107
  404. package/dist/src/components/ui/seek-bar.d.ts +0 -3
  405. package/dist/src/components/ui/seek-bar.tsx +0 -161
  406. package/dist/src/components/ui/slider.tsx +0 -55
  407. package/dist/src/components/ui/time-display.d.ts +0 -3
  408. package/dist/src/components/ui/time-display.tsx +0 -40
  409. package/dist/src/components/ui/tooltip.tsx +0 -131
  410. package/dist/src/components/ui/volume-control.d.ts +0 -3
  411. package/dist/src/components/ui/volume-control.tsx +0 -143
  412. package/dist/src/components/unified/base-media-player.d.ts +0 -18
  413. package/dist/src/components/unified/base-media-player.tsx +0 -246
  414. package/dist/src/components/unified/media-player.d.ts +0 -37
  415. package/dist/src/components/unified/media-player.tsx +0 -75
  416. package/dist/src/components/variants/minimal/AccessibleMinimalPlayer.d.ts +0 -42
  417. package/dist/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +0 -561
  418. package/dist/src/components/variants/minimal/EnhancedMinimalMediaPlayer.d.ts +0 -44
  419. package/dist/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +0 -552
  420. package/dist/src/components/variants/minimal/MinimalControls.d.ts +0 -19
  421. package/dist/src/components/variants/minimal/MinimalControls.tsx +0 -142
  422. package/dist/src/components/variants/minimal/MinimalLoading.d.ts +0 -10
  423. package/dist/src/components/variants/minimal/MinimalLoading.tsx +0 -32
  424. package/dist/src/components/variants/minimal/MinimalMediaPlayer.d.ts +0 -38
  425. package/dist/src/components/variants/minimal/MinimalMediaPlayer.tsx +0 -315
  426. package/dist/src/components/variants/minimal/MinimalOverlay.d.ts +0 -11
  427. package/dist/src/components/variants/minimal/MinimalOverlay.tsx +0 -64
  428. package/dist/src/components/variants/minimal/MinimalPlayButton.d.ts +0 -9
  429. package/dist/src/components/variants/minimal/MinimalPlayButton.tsx +0 -65
  430. package/dist/src/components/variants/minimal/MinimalSeekBar.d.ts +0 -7
  431. package/dist/src/components/variants/minimal/MinimalSeekBar.tsx +0 -150
  432. package/dist/src/components/variants/minimal/MinimalVolumeControl.d.ts +0 -7
  433. package/dist/src/components/variants/minimal/MinimalVolumeControl.tsx +0 -80
  434. package/dist/src/components/variants/minimal/SimpleMinimalPlayer.d.ts +0 -22
  435. package/dist/src/components/variants/minimal/SimpleMinimalPlayer.tsx +0 -209
  436. package/dist/src/components/variants/minimal/components/CenterPlayButton.d.ts +0 -7
  437. package/dist/src/components/variants/minimal/components/CenterPlayButton.tsx +0 -22
  438. package/dist/src/components/variants/minimal/components/ControlBar.d.ts +0 -43
  439. package/dist/src/components/variants/minimal/components/ControlBar.tsx +0 -146
  440. package/dist/src/components/variants/minimal/components/EnhancedSettingsMenu.d.ts +0 -24
  441. package/dist/src/components/variants/minimal/components/EnhancedSettingsMenu.tsx +0 -361
  442. package/dist/src/components/variants/minimal/components/PlaybackControls.d.ts +0 -9
  443. package/dist/src/components/variants/minimal/components/PlaybackControls.tsx +0 -51
  444. package/dist/src/components/variants/minimal/components/RightControls.d.ts +0 -25
  445. package/dist/src/components/variants/minimal/components/RightControls.tsx +0 -173
  446. package/dist/src/components/variants/minimal/components/SeekBar.d.ts +0 -11
  447. package/dist/src/components/variants/minimal/components/SeekBar.tsx +0 -131
  448. package/dist/src/components/variants/minimal/components/SettingsDropdown.d.ts +0 -9
  449. package/dist/src/components/variants/minimal/components/SettingsDropdown.tsx +0 -70
  450. package/dist/src/components/variants/minimal/components/SubtitleDisplay.d.ts +0 -7
  451. package/dist/src/components/variants/minimal/components/SubtitleDisplay.tsx +0 -21
  452. package/dist/src/components/variants/minimal/components/TimeDisplay.d.ts +0 -7
  453. package/dist/src/components/variants/minimal/components/TimeDisplay.tsx +0 -18
  454. package/dist/src/components/variants/minimal/components/VideoElement.d.ts +0 -13
  455. package/dist/src/components/variants/minimal/components/VideoElement.tsx +0 -40
  456. package/dist/src/components/variants/minimal/components/VolumeControl.d.ts +0 -13
  457. package/dist/src/components/variants/minimal/components/VolumeControl.tsx +0 -217
  458. package/dist/src/components/variants/minimal/index.d.ts +0 -17
  459. package/dist/src/components/variants/minimal/index.ts +0 -23
  460. package/dist/src/components/video-player.d.ts +0 -3
  461. package/dist/src/components/video-player.tsx +0 -100
  462. package/dist/src/context/error-handling.d.ts +0 -72
  463. package/dist/src/context/error-handling.ts +0 -394
  464. package/dist/src/context/media-context.d.ts +0 -104
  465. package/dist/src/context/media-context.tsx +0 -208
  466. package/dist/src/context/media-provider.d.ts +0 -26
  467. package/dist/src/context/media-provider.tsx +0 -265
  468. package/dist/src/context/media-store.d.ts +0 -33
  469. package/dist/src/context/media-store.ts +0 -379
  470. package/dist/src/context/persistence.d.ts +0 -83
  471. package/dist/src/context/persistence.ts +0 -453
  472. package/dist/src/core/events/event-system.d.ts +0 -170
  473. package/dist/src/core/events/event-system.ts +0 -442
  474. package/dist/src/core/events/hooks.d.ts +0 -33
  475. package/dist/src/core/events/hooks.ts +0 -302
  476. package/dist/src/core/events/index.d.ts +0 -6
  477. package/dist/src/core/events/index.ts +0 -22
  478. package/dist/src/core/events/middleware.d.ts +0 -39
  479. package/dist/src/core/events/middleware.ts +0 -269
  480. package/dist/src/core/index.d.ts +0 -8
  481. package/dist/src/core/index.ts +0 -22
  482. package/dist/src/core/optimization/bundle-optimizer.d.ts +0 -44
  483. package/dist/src/core/optimization/bundle-optimizer.tsx +0 -308
  484. package/dist/src/core/performance/cicd.d.ts +0 -8
  485. package/dist/src/core/performance/cicd.ts +0 -96
  486. package/dist/src/core/performance/index.d.ts +0 -10
  487. package/dist/src/core/performance/index.ts +0 -38
  488. package/dist/src/core/performance/media-loading-optimizer.d.ts +0 -105
  489. package/dist/src/core/performance/media-loading-optimizer.ts +0 -538
  490. package/dist/src/core/performance/performance-budgets.d.ts +0 -68
  491. package/dist/src/core/performance/performance-budgets.ts +0 -432
  492. package/dist/src/core/performance/performance-monitor.d.ts +0 -95
  493. package/dist/src/core/performance/performance-monitor.tsx +0 -476
  494. package/dist/src/core/performance/performance-testing.d.ts +0 -69
  495. package/dist/src/core/performance/performance-testing.ts +0 -459
  496. package/dist/src/core/plugins/base-plugin.d.ts +0 -52
  497. package/dist/src/core/plugins/base-plugin.ts +0 -224
  498. package/dist/src/core/plugins/enhanced-plugin-system.d.ts +0 -160
  499. package/dist/src/core/plugins/enhanced-plugin-system.ts +0 -417
  500. package/dist/src/core/plugins/examples/analytics-plugin.d.ts +0 -30
  501. package/dist/src/core/plugins/examples/analytics-plugin.ts +0 -242
  502. package/dist/src/core/plugins/index.d.ts +0 -8
  503. package/dist/src/core/plugins/index.ts +0 -39
  504. package/dist/src/core/plugins/registry.d.ts +0 -31
  505. package/dist/src/core/plugins/registry.ts +0 -327
  506. package/dist/src/core/plugins/types.d.ts +0 -101
  507. package/dist/src/core/plugins/types.ts +0 -159
  508. package/dist/src/core/plugins/utils.d.ts +0 -38
  509. package/dist/src/core/plugins/utils.ts +0 -316
  510. package/dist/src/core/progressive-loading.d.ts +0 -88
  511. package/dist/src/core/progressive-loading.tsx +0 -322
  512. package/dist/src/core/providers/enhanced-hls-provider.d.ts +0 -50
  513. package/dist/src/core/providers/enhanced-hls-provider.ts +0 -308
  514. package/dist/src/core/providers/service-provider.d.ts +0 -49
  515. package/dist/src/core/providers/service-provider.tsx +0 -168
  516. package/dist/src/core/utils.d.ts +0 -25
  517. package/dist/src/core/utils.tsx +0 -38
  518. package/dist/src/features/media-session/media-session-manager.d.ts +0 -132
  519. package/dist/src/features/media-session/media-session-manager.ts +0 -429
  520. package/dist/src/features/picture-in-picture/pip-manager.d.ts +0 -94
  521. package/dist/src/features/picture-in-picture/pip-manager.ts +0 -429
  522. package/dist/src/features/playlist/playlist-manager.d.ts +0 -208
  523. package/dist/src/features/playlist/playlist-manager.ts +0 -606
  524. package/dist/src/features/subtitles/subtitle-manager.d.ts +0 -136
  525. package/dist/src/features/subtitles/subtitle-manager.ts +0 -441
  526. package/dist/src/features/subtitles/subtitle-parser.d.ts +0 -60
  527. package/dist/src/features/subtitles/subtitle-parser.ts +0 -280
  528. package/dist/src/features/thumbnails/thumbnail-generator.d.ts +0 -136
  529. package/dist/src/features/thumbnails/thumbnail-generator.ts +0 -519
  530. package/dist/src/hooks/accessibility/index.d.ts +0 -5
  531. package/dist/src/hooks/accessibility/index.ts +0 -27
  532. package/dist/src/hooks/accessibility/use-accessibility-preferences.d.ts +0 -14
  533. package/dist/src/hooks/accessibility/use-accessibility-preferences.ts +0 -188
  534. package/dist/src/hooks/accessibility/use-focus-management.d.ts +0 -31
  535. package/dist/src/hooks/accessibility/use-focus-management.ts +0 -176
  536. package/dist/src/hooks/accessibility/use-keyboard-shortcuts.d.ts +0 -38
  537. package/dist/src/hooks/accessibility/use-keyboard-shortcuts.ts +0 -144
  538. package/dist/src/hooks/accessibility/use-screen-reader.d.ts +0 -22
  539. package/dist/src/hooks/accessibility/use-screen-reader.ts +0 -182
  540. package/dist/src/hooks/core/index.d.ts +0 -18
  541. package/dist/src/hooks/core/index.ts +0 -47
  542. package/dist/src/hooks/legacy.d.ts +0 -18
  543. package/dist/src/hooks/legacy.ts +0 -27
  544. package/dist/src/hooks/use-enhanced-media-player.d.ts +0 -88
  545. package/dist/src/hooks/use-enhanced-media-player.ts +0 -485
  546. package/dist/src/hooks/use-intelligent-preloading.d.ts +0 -66
  547. package/dist/src/hooks/use-intelligent-preloading.ts +0 -363
  548. package/dist/src/hooks/use-keyboard-controls.d.ts +0 -13
  549. package/dist/src/hooks/use-keyboard-controls.ts +0 -115
  550. package/dist/src/hooks/use-media-actions.d.ts +0 -62
  551. package/dist/src/hooks/use-media-actions.ts +0 -175
  552. package/dist/src/hooks/use-media-metadata.d.ts +0 -11
  553. package/dist/src/hooks/use-media-metadata.ts +0 -89
  554. package/dist/src/hooks/use-media-optimistic.d.ts +0 -36
  555. package/dist/src/hooks/use-media-optimistic.ts +0 -270
  556. package/dist/src/hooks/use-media-player.d.ts +0 -31
  557. package/dist/src/hooks/use-media-player.ts +0 -310
  558. package/dist/src/hooks/use-media-state.d.ts +0 -17
  559. package/dist/src/hooks/use-media-state.ts +0 -190
  560. package/dist/src/hooks/use-memory-optimization.d.ts +0 -40
  561. package/dist/src/hooks/use-memory-optimization.ts +0 -358
  562. package/dist/src/hooks/use-mobile.ts +0 -125
  563. package/dist/src/hooks/use-optimistic-controls.d.ts +0 -22
  564. package/dist/src/hooks/use-optimistic-controls.ts +0 -92
  565. package/dist/src/hooks/use-optimized-media.d.ts +0 -46
  566. package/dist/src/hooks/use-optimized-media.ts +0 -263
  567. package/dist/src/hooks/use-touch-gestures.d.ts +0 -47
  568. package/dist/src/hooks/use-touch-gestures.ts +0 -417
  569. package/dist/src/hooks/useEnhancedSubtitles.d.ts +0 -39
  570. package/dist/src/hooks/useEnhancedSubtitles.ts +0 -258
  571. package/dist/src/hooks/useKeyboardShortcuts.d.ts +0 -10
  572. package/dist/src/hooks/useKeyboardShortcuts.ts +0 -74
  573. package/dist/src/hooks/useMediaControls.d.ts +0 -9
  574. package/dist/src/hooks/useMediaControls.ts +0 -52
  575. package/dist/src/hooks/useScreenshot.d.ts +0 -4
  576. package/dist/src/hooks/useScreenshot.ts +0 -57
  577. package/dist/src/hooks/useSubtitles.d.ts +0 -8
  578. package/dist/src/hooks/useSubtitles.ts +0 -91
  579. package/dist/src/hooks/useVideoPlayer.d.ts +0 -32
  580. package/dist/src/hooks/useVideoPlayer.ts +0 -232
  581. package/dist/src/icons/components/FullscreenIcon.d.ts +0 -3
  582. package/dist/src/icons/components/FullscreenIcon.tsx +0 -37
  583. package/dist/src/icons/components/SettingsIcon.d.ts +0 -3
  584. package/dist/src/icons/components/SettingsIcon.tsx +0 -38
  585. package/dist/src/icons/components/animated/LoadingIcon.d.ts +0 -3
  586. package/dist/src/icons/components/animated/LoadingIcon.tsx +0 -43
  587. package/dist/src/icons/components/animated/PlayPauseIcon.d.ts +0 -7
  588. package/dist/src/icons/components/animated/PlayPauseIcon.tsx +0 -50
  589. package/dist/src/icons/components/media/PauseIcon.d.ts +0 -3
  590. package/dist/src/icons/components/media/PauseIcon.tsx +0 -39
  591. package/dist/src/icons/components/media/PlayIcon.d.ts +0 -3
  592. package/dist/src/icons/components/media/PlayIcon.tsx +0 -38
  593. package/dist/src/icons/components/volume/VolumeIcon.d.ts +0 -3
  594. package/dist/src/icons/components/volume/VolumeIcon.tsx +0 -39
  595. package/dist/src/icons/components/volume/VolumeOffIcon.d.ts +0 -3
  596. package/dist/src/icons/components/volume/VolumeOffIcon.tsx +0 -39
  597. package/dist/src/icons/index.d.ts +0 -28
  598. package/dist/src/icons/index.ts +0 -56
  599. package/dist/src/icons/provider.d.ts +0 -13
  600. package/dist/src/icons/provider.tsx +0 -64
  601. package/dist/src/icons/types.d.ts +0 -18
  602. package/dist/src/icons/types.ts +0 -40
  603. package/dist/src/index-enhanced.d.ts +0 -13
  604. package/dist/src/index-enhanced.ts +0 -35
  605. package/dist/src/index-legacy.d.ts +0 -81
  606. package/dist/src/index-legacy.ts +0 -327
  607. package/dist/src/index.css +0 -102
  608. package/dist/src/index.d.ts +0 -38
  609. package/dist/src/index.minimal.d.ts +0 -2
  610. package/dist/src/index.minimal.ts +0 -4
  611. package/dist/src/index.ts +0 -216
  612. package/dist/src/lib/deprecation.d.ts +0 -7
  613. package/dist/src/lib/deprecation.ts +0 -51
  614. package/dist/src/lib/format-time.d.ts +0 -9
  615. package/dist/src/lib/format-time.ts +0 -37
  616. package/dist/src/lib/index.d.ts +0 -3
  617. package/dist/src/lib/index.ts +0 -3
  618. package/dist/src/lib/utils.d.ts +0 -3
  619. package/dist/src/lib/utils.ts +0 -6
  620. package/dist/src/styles/globals.css +0 -462
  621. package/dist/src/styles/minimal-player.css +0 -589
  622. package/dist/src/styles/pixel-art.css +0 -46
  623. package/dist/src/styles/videojs.css +0 -100
  624. package/dist/src/test/setup.d.ts +0 -2
  625. package/dist/src/test/setup.ts +0 -79
  626. package/dist/src/types/events.d.ts +0 -41
  627. package/dist/src/types/events.ts +0 -47
  628. package/dist/src/types/formats.d.ts +0 -45
  629. package/dist/src/types/formats.ts +0 -95
  630. package/dist/src/types/index.d.ts +0 -128
  631. package/dist/src/types/index.ts +0 -225
  632. package/dist/src/types/videojs-plugins.d.ts +0 -14
  633. package/dist/styles/globals.css +0 -462
  634. package/dist/styles/minimal-player.css +0 -589
  635. package/dist/styles/pixel-art.css +0 -46
  636. package/dist/styles/videojs.css +0 -100
  637. package/src/adapters/videojs-adapter.d.ts +0 -38
  638. package/src/adapters/videojs-adapter.d.ts.map +0 -1
  639. package/src/components/AnimateLoading.d.ts +0 -9
  640. package/src/components/AnimateLoading.d.ts.map +0 -1
  641. package/src/components/LoadingState.d.ts +0 -33
  642. package/src/components/LoadingState.d.ts.map +0 -1
  643. package/src/components/accessibility/keyboard-help-overlay.d.ts +0 -17
  644. package/src/components/accessibility/keyboard-help-overlay.d.ts.map +0 -1
  645. package/src/components/audio-player.d.ts +0 -3
  646. package/src/components/audio-player.d.ts.map +0 -1
  647. package/src/components/basic/index.d.ts +0 -26
  648. package/src/components/basic/index.d.ts.map +0 -1
  649. package/src/components/enhanced/advanced-features.d.ts +0 -45
  650. package/src/components/enhanced/advanced-features.d.ts.map +0 -1
  651. package/src/components/enhanced/debug-panel.d.ts +0 -70
  652. package/src/components/enhanced/debug-panel.d.ts.map +0 -1
  653. package/src/components/enhanced/enhanced-controls.d.ts +0 -50
  654. package/src/components/enhanced/enhanced-controls.d.ts.map +0 -1
  655. package/src/components/enhanced/enhanced-media-player.d.ts +0 -26
  656. package/src/components/enhanced/enhanced-media-player.d.ts.map +0 -1
  657. package/src/components/enhanced/error-handling.d.ts +0 -36
  658. package/src/components/enhanced/error-handling.d.ts.map +0 -1
  659. package/src/components/enhanced/index.d.ts +0 -7
  660. package/src/components/enhanced/index.d.ts.map +0 -1
  661. package/src/components/enhanced/media-player-enhanced.d.ts +0 -21
  662. package/src/components/enhanced/media-player-enhanced.d.ts.map +0 -1
  663. package/src/components/examples/basic-video-player.d.ts +0 -10
  664. package/src/components/examples/basic-video-player.d.ts.map +0 -1
  665. package/src/components/examples/custom-controls-example.d.ts +0 -10
  666. package/src/components/examples/custom-controls-example.d.ts.map +0 -1
  667. package/src/components/examples/enhanced-controls-example.d.ts +0 -9
  668. package/src/components/examples/enhanced-controls-example.d.ts.map +0 -1
  669. package/src/components/examples/enhanced-media-player-example.d.ts +0 -9
  670. package/src/components/examples/enhanced-media-player-example.d.ts.map +0 -1
  671. package/src/components/examples/loading-states-demo.d.ts +0 -2
  672. package/src/components/examples/loading-states-demo.d.ts.map +0 -1
  673. package/src/components/examples/react-19-demo.d.ts +0 -10
  674. package/src/components/examples/react-19-demo.d.ts.map +0 -1
  675. package/src/components/examples/volume-orientation-demo.d.ts +0 -2
  676. package/src/components/examples/volume-orientation-demo.d.ts.map +0 -1
  677. package/src/components/icon-demo.d.ts +0 -2
  678. package/src/components/icon-demo.d.ts.map +0 -1
  679. package/src/components/icons/index.d.ts +0 -36
  680. package/src/components/icons/index.d.ts.map +0 -1
  681. package/src/components/icons/svg-icons/ArrowLeftIcon.d.ts +0 -4
  682. package/src/components/icons/svg-icons/ArrowLeftIcon.d.ts.map +0 -1
  683. package/src/components/icons/svg-icons/ArrowRightIcon.d.ts +0 -4
  684. package/src/components/icons/svg-icons/ArrowRightIcon.d.ts.map +0 -1
  685. package/src/components/icons/svg-icons/AudioIcon.d.ts +0 -4
  686. package/src/components/icons/svg-icons/AudioIcon.d.ts.map +0 -1
  687. package/src/components/icons/svg-icons/BackwardIcon.d.ts +0 -4
  688. package/src/components/icons/svg-icons/BackwardIcon.d.ts.map +0 -1
  689. package/src/components/icons/svg-icons/CameraIcon.d.ts +0 -4
  690. package/src/components/icons/svg-icons/CameraIcon.d.ts.map +0 -1
  691. package/src/components/icons/svg-icons/CheckIcon.d.ts +0 -4
  692. package/src/components/icons/svg-icons/CheckIcon.d.ts.map +0 -1
  693. package/src/components/icons/svg-icons/EnablePiPIcon.d.ts +0 -4
  694. package/src/components/icons/svg-icons/EnablePiPIcon.d.ts.map +0 -1
  695. package/src/components/icons/svg-icons/ForwardIcon.d.ts +0 -4
  696. package/src/components/icons/svg-icons/ForwardIcon.d.ts.map +0 -1
  697. package/src/components/icons/svg-icons/FullscreenEnterIcon.d.ts +0 -4
  698. package/src/components/icons/svg-icons/FullscreenEnterIcon.d.ts.map +0 -1
  699. package/src/components/icons/svg-icons/FullscreenExitIcon.d.ts +0 -4
  700. package/src/components/icons/svg-icons/FullscreenExitIcon.d.ts.map +0 -1
  701. package/src/components/icons/svg-icons/LoadingIcon.d.ts +0 -4
  702. package/src/components/icons/svg-icons/LoadingIcon.d.ts.map +0 -1
  703. package/src/components/icons/svg-icons/PauseIcon.d.ts +0 -4
  704. package/src/components/icons/svg-icons/PauseIcon.d.ts.map +0 -1
  705. package/src/components/icons/svg-icons/PlayIcon.d.ts +0 -4
  706. package/src/components/icons/svg-icons/PlayIcon.d.ts.map +0 -1
  707. package/src/components/icons/svg-icons/PlaybackSpeedIcon.d.ts +0 -4
  708. package/src/components/icons/svg-icons/PlaybackSpeedIcon.d.ts.map +0 -1
  709. package/src/components/icons/svg-icons/QualityIcon.d.ts +0 -4
  710. package/src/components/icons/svg-icons/QualityIcon.d.ts.map +0 -1
  711. package/src/components/icons/svg-icons/SettingsIcon.d.ts +0 -4
  712. package/src/components/icons/svg-icons/SettingsIcon.d.ts.map +0 -1
  713. package/src/components/icons/svg-icons/SliderIcon.d.ts +0 -4
  714. package/src/components/icons/svg-icons/SliderIcon.d.ts.map +0 -1
  715. package/src/components/icons/svg-icons/SubtitleIcon.d.ts +0 -4
  716. package/src/components/icons/svg-icons/SubtitleIcon.d.ts.map +0 -1
  717. package/src/components/icons/svg-icons/SubtitleOffIcon.d.ts +0 -4
  718. package/src/components/icons/svg-icons/SubtitleOffIcon.d.ts.map +0 -1
  719. package/src/components/icons/svg-icons/UnPiPIcon.d.ts +0 -4
  720. package/src/components/icons/svg-icons/UnPiPIcon.d.ts.map +0 -1
  721. package/src/components/icons/svg-icons/VolumeMutedIcon.d.ts +0 -4
  722. package/src/components/icons/svg-icons/VolumeMutedIcon.d.ts.map +0 -1
  723. package/src/components/icons/svg-icons/VolumeOneIcon.d.ts +0 -4
  724. package/src/components/icons/svg-icons/VolumeOneIcon.d.ts.map +0 -1
  725. package/src/components/icons/svg-icons/VolumeThreeIcon.d.ts +0 -4
  726. package/src/components/icons/svg-icons/VolumeThreeIcon.d.ts.map +0 -1
  727. package/src/components/icons/svg-icons/VolumeTwoIcon.d.ts +0 -4
  728. package/src/components/icons/svg-icons/VolumeTwoIcon.d.ts.map +0 -1
  729. package/src/components/legacy.d.ts +0 -13
  730. package/src/components/legacy.d.ts.map +0 -1
  731. package/src/components/media-metadata-display.d.ts +0 -11
  732. package/src/components/media-metadata-display.d.ts.map +0 -1
  733. package/src/components/media-player-audio.d.ts +0 -9
  734. package/src/components/media-player-audio.d.ts.map +0 -1
  735. package/src/components/media-player-controls.d.ts +0 -23
  736. package/src/components/media-player-controls.d.ts.map +0 -1
  737. package/src/components/media-player-error.d.ts +0 -16
  738. package/src/components/media-player-error.d.ts.map +0 -1
  739. package/src/components/media-player-fullscreen.d.ts +0 -12
  740. package/src/components/media-player-fullscreen.d.ts.map +0 -1
  741. package/src/components/media-player-hls.d.ts +0 -23
  742. package/src/components/media-player-hls.d.ts.map +0 -1
  743. package/src/components/media-player-loading.d.ts +0 -12
  744. package/src/components/media-player-loading.d.ts.map +0 -1
  745. package/src/components/media-player-play.d.ts +0 -11
  746. package/src/components/media-player-play.d.ts.map +0 -1
  747. package/src/components/media-player-root.d.ts +0 -28
  748. package/src/components/media-player-root.d.ts.map +0 -1
  749. package/src/components/media-player-seek.d.ts +0 -15
  750. package/src/components/media-player-seek.d.ts.map +0 -1
  751. package/src/components/media-player-time.d.ts +0 -12
  752. package/src/components/media-player-time.d.ts.map +0 -1
  753. package/src/components/media-player-tooltip.d.ts +0 -13
  754. package/src/components/media-player-tooltip.d.ts.map +0 -1
  755. package/src/components/media-player-video.d.ts +0 -9
  756. package/src/components/media-player-video.d.ts.map +0 -1
  757. package/src/components/media-player-volume.d.ts +0 -13
  758. package/src/components/media-player-volume.d.ts.map +0 -1
  759. package/src/components/media-player.d.ts +0 -3
  760. package/src/components/media-player.d.ts.map +0 -1
  761. package/src/components/media-suspense.d.ts +0 -78
  762. package/src/components/media-suspense.d.ts.map +0 -1
  763. package/src/components/player-settings-form.d.ts +0 -8
  764. package/src/components/player-settings-form.d.ts.map +0 -1
  765. package/src/components/react-player-wrapper.d.ts +0 -64
  766. package/src/components/react-player-wrapper.d.ts.map +0 -1
  767. package/src/components/simple-video-player.d.ts +0 -9
  768. package/src/components/simple-video-player.d.ts.map +0 -1
  769. package/src/components/ui/button.tsx +0 -49
  770. package/src/components/ui/dropdown-menu.tsx +0 -137
  771. package/src/components/ui/enhanced-seek-bar.d.ts +0 -3
  772. package/src/components/ui/enhanced-seek-bar.d.ts.map +0 -1
  773. package/src/components/ui/fullscreen-button.d.ts +0 -3
  774. package/src/components/ui/fullscreen-button.d.ts.map +0 -1
  775. package/src/components/ui/icons.tsx +0 -174
  776. package/src/components/ui/media-resource-preloader.d.ts +0 -21
  777. package/src/components/ui/media-resource-preloader.d.ts.map +0 -1
  778. package/src/components/ui/play-button.d.ts +0 -3
  779. package/src/components/ui/play-button.d.ts.map +0 -1
  780. package/src/components/ui/seek-bar.d.ts +0 -3
  781. package/src/components/ui/seek-bar.d.ts.map +0 -1
  782. package/src/components/ui/slider.tsx +0 -55
  783. package/src/components/ui/time-display.d.ts +0 -3
  784. package/src/components/ui/time-display.d.ts.map +0 -1
  785. package/src/components/ui/tooltip.tsx +0 -131
  786. package/src/components/ui/volume-control.d.ts +0 -3
  787. package/src/components/ui/volume-control.d.ts.map +0 -1
  788. package/src/components/unified/base-media-player.d.ts +0 -18
  789. package/src/components/unified/base-media-player.d.ts.map +0 -1
  790. package/src/components/unified/media-player.d.ts +0 -37
  791. package/src/components/unified/media-player.d.ts.map +0 -1
  792. package/src/components/variants/minimal/AccessibleMinimalPlayer.d.ts +0 -42
  793. package/src/components/variants/minimal/AccessibleMinimalPlayer.d.ts.map +0 -1
  794. package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.d.ts +0 -44
  795. package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.d.ts.map +0 -1
  796. package/src/components/variants/minimal/MinimalControls.d.ts +0 -19
  797. package/src/components/variants/minimal/MinimalControls.d.ts.map +0 -1
  798. package/src/components/variants/minimal/MinimalLoading.d.ts +0 -10
  799. package/src/components/variants/minimal/MinimalLoading.d.ts.map +0 -1
  800. package/src/components/variants/minimal/MinimalMediaPlayer.d.ts +0 -38
  801. package/src/components/variants/minimal/MinimalMediaPlayer.d.ts.map +0 -1
  802. package/src/components/variants/minimal/MinimalOverlay.d.ts +0 -11
  803. package/src/components/variants/minimal/MinimalOverlay.d.ts.map +0 -1
  804. package/src/components/variants/minimal/MinimalPlayButton.d.ts +0 -9
  805. package/src/components/variants/minimal/MinimalPlayButton.d.ts.map +0 -1
  806. package/src/components/variants/minimal/MinimalSeekBar.d.ts +0 -7
  807. package/src/components/variants/minimal/MinimalSeekBar.d.ts.map +0 -1
  808. package/src/components/variants/minimal/MinimalVolumeControl.d.ts +0 -7
  809. package/src/components/variants/minimal/MinimalVolumeControl.d.ts.map +0 -1
  810. package/src/components/variants/minimal/SimpleMinimalPlayer.d.ts +0 -22
  811. package/src/components/variants/minimal/SimpleMinimalPlayer.d.ts.map +0 -1
  812. package/src/components/variants/minimal/components/CenterPlayButton.d.ts +0 -7
  813. package/src/components/variants/minimal/components/CenterPlayButton.d.ts.map +0 -1
  814. package/src/components/variants/minimal/components/ControlBar.d.ts +0 -43
  815. package/src/components/variants/minimal/components/ControlBar.d.ts.map +0 -1
  816. package/src/components/variants/minimal/components/EnhancedSettingsMenu.d.ts +0 -24
  817. package/src/components/variants/minimal/components/EnhancedSettingsMenu.d.ts.map +0 -1
  818. package/src/components/variants/minimal/components/PlaybackControls.d.ts +0 -9
  819. package/src/components/variants/minimal/components/PlaybackControls.d.ts.map +0 -1
  820. package/src/components/variants/minimal/components/RightControls.d.ts +0 -25
  821. package/src/components/variants/minimal/components/RightControls.d.ts.map +0 -1
  822. package/src/components/variants/minimal/components/SeekBar.d.ts +0 -11
  823. package/src/components/variants/minimal/components/SeekBar.d.ts.map +0 -1
  824. package/src/components/variants/minimal/components/SettingsDropdown.d.ts +0 -9
  825. package/src/components/variants/minimal/components/SettingsDropdown.d.ts.map +0 -1
  826. package/src/components/variants/minimal/components/SubtitleDisplay.d.ts +0 -7
  827. package/src/components/variants/minimal/components/SubtitleDisplay.d.ts.map +0 -1
  828. package/src/components/variants/minimal/components/TimeDisplay.d.ts +0 -7
  829. package/src/components/variants/minimal/components/TimeDisplay.d.ts.map +0 -1
  830. package/src/components/variants/minimal/components/VideoElement.d.ts +0 -13
  831. package/src/components/variants/minimal/components/VideoElement.d.ts.map +0 -1
  832. package/src/components/variants/minimal/components/VolumeControl.d.ts +0 -13
  833. package/src/components/variants/minimal/components/VolumeControl.d.ts.map +0 -1
  834. package/src/components/variants/minimal/index.d.ts +0 -17
  835. package/src/components/variants/minimal/index.d.ts.map +0 -1
  836. package/src/components/video-player.d.ts +0 -3
  837. package/src/components/video-player.d.ts.map +0 -1
  838. package/src/context/error-handling.d.ts +0 -72
  839. package/src/context/error-handling.d.ts.map +0 -1
  840. package/src/context/media-context.d.ts +0 -104
  841. package/src/context/media-context.d.ts.map +0 -1
  842. package/src/context/media-provider.d.ts +0 -26
  843. package/src/context/media-provider.d.ts.map +0 -1
  844. package/src/context/media-store.d.ts +0 -33
  845. package/src/context/media-store.d.ts.map +0 -1
  846. package/src/context/persistence.d.ts +0 -83
  847. package/src/context/persistence.d.ts.map +0 -1
  848. package/src/core/events/event-system.d.ts +0 -170
  849. package/src/core/events/event-system.d.ts.map +0 -1
  850. package/src/core/events/hooks.d.ts +0 -33
  851. package/src/core/events/hooks.d.ts.map +0 -1
  852. package/src/core/events/index.d.ts +0 -6
  853. package/src/core/events/index.d.ts.map +0 -1
  854. package/src/core/events/middleware.d.ts +0 -39
  855. package/src/core/events/middleware.d.ts.map +0 -1
  856. package/src/core/index.d.ts +0 -8
  857. package/src/core/index.d.ts.map +0 -1
  858. package/src/core/optimization/bundle-optimizer.d.ts +0 -44
  859. package/src/core/optimization/bundle-optimizer.d.ts.map +0 -1
  860. package/src/core/performance/cicd.d.ts +0 -8
  861. package/src/core/performance/cicd.d.ts.map +0 -1
  862. package/src/core/performance/index.d.ts +0 -10
  863. package/src/core/performance/index.d.ts.map +0 -1
  864. package/src/core/performance/media-loading-optimizer.d.ts +0 -105
  865. package/src/core/performance/media-loading-optimizer.d.ts.map +0 -1
  866. package/src/core/performance/performance-budgets.d.ts +0 -68
  867. package/src/core/performance/performance-budgets.d.ts.map +0 -1
  868. package/src/core/performance/performance-monitor.d.ts +0 -95
  869. package/src/core/performance/performance-monitor.d.ts.map +0 -1
  870. package/src/core/performance/performance-testing.d.ts +0 -69
  871. package/src/core/performance/performance-testing.d.ts.map +0 -1
  872. package/src/core/plugins/base-plugin.d.ts +0 -52
  873. package/src/core/plugins/base-plugin.d.ts.map +0 -1
  874. package/src/core/plugins/enhanced-plugin-system.d.ts +0 -160
  875. package/src/core/plugins/enhanced-plugin-system.d.ts.map +0 -1
  876. package/src/core/plugins/examples/analytics-plugin.d.ts +0 -30
  877. package/src/core/plugins/examples/analytics-plugin.d.ts.map +0 -1
  878. package/src/core/plugins/index.d.ts +0 -8
  879. package/src/core/plugins/index.d.ts.map +0 -1
  880. package/src/core/plugins/registry.d.ts +0 -31
  881. package/src/core/plugins/registry.d.ts.map +0 -1
  882. package/src/core/plugins/types.d.ts +0 -101
  883. package/src/core/plugins/types.d.ts.map +0 -1
  884. package/src/core/plugins/utils.d.ts +0 -38
  885. package/src/core/plugins/utils.d.ts.map +0 -1
  886. package/src/core/progressive-loading.d.ts +0 -88
  887. package/src/core/progressive-loading.d.ts.map +0 -1
  888. package/src/core/providers/enhanced-hls-provider.d.ts +0 -50
  889. package/src/core/providers/enhanced-hls-provider.d.ts.map +0 -1
  890. package/src/core/providers/service-provider.d.ts +0 -49
  891. package/src/core/providers/service-provider.d.ts.map +0 -1
  892. package/src/core/utils.d.ts +0 -25
  893. package/src/core/utils.d.ts.map +0 -1
  894. package/src/features/media-session/media-session-manager.d.ts +0 -132
  895. package/src/features/media-session/media-session-manager.d.ts.map +0 -1
  896. package/src/features/picture-in-picture/pip-manager.d.ts +0 -94
  897. package/src/features/picture-in-picture/pip-manager.d.ts.map +0 -1
  898. package/src/features/playlist/playlist-manager.d.ts +0 -208
  899. package/src/features/playlist/playlist-manager.d.ts.map +0 -1
  900. package/src/features/subtitles/subtitle-manager.d.ts +0 -136
  901. package/src/features/subtitles/subtitle-manager.d.ts.map +0 -1
  902. package/src/features/subtitles/subtitle-parser.d.ts +0 -60
  903. package/src/features/subtitles/subtitle-parser.d.ts.map +0 -1
  904. package/src/features/thumbnails/thumbnail-generator.d.ts +0 -136
  905. package/src/features/thumbnails/thumbnail-generator.d.ts.map +0 -1
  906. package/src/hooks/accessibility/index.d.ts +0 -5
  907. package/src/hooks/accessibility/index.d.ts.map +0 -1
  908. package/src/hooks/accessibility/use-accessibility-preferences.d.ts +0 -14
  909. package/src/hooks/accessibility/use-accessibility-preferences.d.ts.map +0 -1
  910. package/src/hooks/accessibility/use-focus-management.d.ts +0 -31
  911. package/src/hooks/accessibility/use-focus-management.d.ts.map +0 -1
  912. package/src/hooks/accessibility/use-keyboard-shortcuts.d.ts +0 -38
  913. package/src/hooks/accessibility/use-keyboard-shortcuts.d.ts.map +0 -1
  914. package/src/hooks/accessibility/use-screen-reader.d.ts +0 -22
  915. package/src/hooks/accessibility/use-screen-reader.d.ts.map +0 -1
  916. package/src/hooks/core/index.d.ts +0 -18
  917. package/src/hooks/core/index.d.ts.map +0 -1
  918. package/src/hooks/legacy.d.ts +0 -18
  919. package/src/hooks/legacy.d.ts.map +0 -1
  920. package/src/hooks/use-enhanced-media-player.d.ts +0 -88
  921. package/src/hooks/use-enhanced-media-player.d.ts.map +0 -1
  922. package/src/hooks/use-intelligent-preloading.d.ts +0 -66
  923. package/src/hooks/use-intelligent-preloading.d.ts.map +0 -1
  924. package/src/hooks/use-keyboard-controls.d.ts +0 -13
  925. package/src/hooks/use-keyboard-controls.d.ts.map +0 -1
  926. package/src/hooks/use-media-actions.d.ts +0 -62
  927. package/src/hooks/use-media-actions.d.ts.map +0 -1
  928. package/src/hooks/use-media-metadata.d.ts +0 -11
  929. package/src/hooks/use-media-metadata.d.ts.map +0 -1
  930. package/src/hooks/use-media-optimistic.d.ts +0 -36
  931. package/src/hooks/use-media-optimistic.d.ts.map +0 -1
  932. package/src/hooks/use-media-player.d.ts +0 -31
  933. package/src/hooks/use-media-player.d.ts.map +0 -1
  934. package/src/hooks/use-media-state.d.ts +0 -17
  935. package/src/hooks/use-media-state.d.ts.map +0 -1
  936. package/src/hooks/use-memory-optimization.d.ts +0 -40
  937. package/src/hooks/use-memory-optimization.d.ts.map +0 -1
  938. package/src/hooks/use-mobile.ts +0 -125
  939. package/src/hooks/use-optimistic-controls.d.ts +0 -22
  940. package/src/hooks/use-optimistic-controls.d.ts.map +0 -1
  941. package/src/hooks/use-optimized-media.d.ts +0 -46
  942. package/src/hooks/use-optimized-media.d.ts.map +0 -1
  943. package/src/hooks/use-touch-gestures.d.ts +0 -47
  944. package/src/hooks/use-touch-gestures.d.ts.map +0 -1
  945. package/src/hooks/useEnhancedSubtitles.d.ts +0 -39
  946. package/src/hooks/useEnhancedSubtitles.d.ts.map +0 -1
  947. package/src/hooks/useKeyboardShortcuts.d.ts +0 -10
  948. package/src/hooks/useKeyboardShortcuts.d.ts.map +0 -1
  949. package/src/hooks/useMediaControls.d.ts +0 -9
  950. package/src/hooks/useMediaControls.d.ts.map +0 -1
  951. package/src/hooks/useScreenshot.d.ts +0 -4
  952. package/src/hooks/useScreenshot.d.ts.map +0 -1
  953. package/src/hooks/useSubtitles.d.ts +0 -8
  954. package/src/hooks/useSubtitles.d.ts.map +0 -1
  955. package/src/hooks/useVideoPlayer.d.ts +0 -32
  956. package/src/hooks/useVideoPlayer.d.ts.map +0 -1
  957. package/src/icons/components/FullscreenIcon.d.ts +0 -3
  958. package/src/icons/components/FullscreenIcon.d.ts.map +0 -1
  959. package/src/icons/components/SettingsIcon.d.ts +0 -3
  960. package/src/icons/components/SettingsIcon.d.ts.map +0 -1
  961. package/src/icons/components/animated/LoadingIcon.d.ts +0 -3
  962. package/src/icons/components/animated/LoadingIcon.d.ts.map +0 -1
  963. package/src/icons/components/animated/PlayPauseIcon.d.ts +0 -7
  964. package/src/icons/components/animated/PlayPauseIcon.d.ts.map +0 -1
  965. package/src/icons/components/media/PauseIcon.d.ts +0 -3
  966. package/src/icons/components/media/PauseIcon.d.ts.map +0 -1
  967. package/src/icons/components/media/PlayIcon.d.ts +0 -3
  968. package/src/icons/components/media/PlayIcon.d.ts.map +0 -1
  969. package/src/icons/components/volume/VolumeIcon.d.ts +0 -3
  970. package/src/icons/components/volume/VolumeIcon.d.ts.map +0 -1
  971. package/src/icons/components/volume/VolumeOffIcon.d.ts +0 -3
  972. package/src/icons/components/volume/VolumeOffIcon.d.ts.map +0 -1
  973. package/src/icons/index.d.ts +0 -28
  974. package/src/icons/index.d.ts.map +0 -1
  975. package/src/icons/provider.d.ts +0 -13
  976. package/src/icons/provider.d.ts.map +0 -1
  977. package/src/icons/types.d.ts +0 -18
  978. package/src/icons/types.d.ts.map +0 -1
  979. package/src/index-enhanced.d.ts +0 -13
  980. package/src/index-enhanced.d.ts.map +0 -1
  981. package/src/index-legacy.d.ts +0 -81
  982. package/src/index-legacy.d.ts.map +0 -1
  983. package/src/index.d.ts +0 -38
  984. package/src/index.d.ts.map +0 -1
  985. package/src/index.minimal.d.ts +0 -2
  986. package/src/index.minimal.d.ts.map +0 -1
  987. package/src/index.minimal.ts +0 -4
  988. package/src/lib/deprecation.d.ts +0 -7
  989. package/src/lib/deprecation.d.ts.map +0 -1
  990. package/src/lib/format-time.d.ts +0 -9
  991. package/src/lib/format-time.d.ts.map +0 -1
  992. package/src/lib/index.d.ts +0 -3
  993. package/src/lib/index.d.ts.map +0 -1
  994. package/src/lib/utils.d.ts +0 -3
  995. package/src/lib/utils.d.ts.map +0 -1
  996. package/src/test/setup.d.ts +0 -2
  997. package/src/test/setup.d.ts.map +0 -1
  998. package/src/types/events.d.ts +0 -41
  999. package/src/types/events.d.ts.map +0 -1
  1000. package/src/types/formats.d.ts +0 -45
  1001. package/src/types/formats.d.ts.map +0 -1
  1002. package/src/types/index.d.ts +0 -128
  1003. package/src/types/index.d.ts.map +0 -1
@@ -0,0 +1,4 @@
1
+ "use strict";const a=require("react"),D=require("./context-eNS62_ac.cjs"),ie=require("./utils-CFOue_9K.cjs");function pe(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const s=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,s.get?s:{enumerable:!0,get:()=>e[n]})}}return t.default=e,Object.freeze(t)}const K=pe(a);function B(e,t){return((n,s=!1)=>{const m={type:e,detail:n,optimistic:s,timestamp:Date.now()};return s?t.dispatchOptimistic(m):(t.dispatch(m),Promise.resolve())})}function oe(e){const[t,n]=a.useState(e.getActionState());return a.useEffect(()=>e.subscribe(()=>{const m=e.getActionState();n(l=>JSON.stringify(l)!==JSON.stringify(m)?m:l)}),[e]),t}function ce(e){const t=a.useMemo(()=>({play:B(D.MediaActionTypes.PLAY,e),pause:B(D.MediaActionTypes.PAUSE,e),seek:B(D.MediaActionTypes.SEEK,e),setVolume:B(D.MediaActionTypes.SET_VOLUME,e),mute:B(D.MediaActionTypes.MUTE,e),unmute:B(D.MediaActionTypes.UNMUTE,e),toggleMute:B(D.MediaActionTypes.TOGGLE_MUTE,e),setDuration:B(D.MediaActionTypes.SET_DURATION,e),setCurrentTime:B(D.MediaActionTypes.SET_CURRENT_TIME,e),setBuffered:B(D.MediaActionTypes.SET_BUFFERED,e),setLoading:B(D.MediaActionTypes.SET_LOADING,e),setError:B(D.MediaActionTypes.SET_ERROR,e),enterFullscreen:B(D.MediaActionTypes.ENTER_FULLSCREEN,e),exitFullscreen:B(D.MediaActionTypes.EXIT_FULLSCREEN,e),enterPiP:B(D.MediaActionTypes.ENTER_PIP,e),exitPiP:B(D.MediaActionTypes.EXIT_PIP,e),setPlaybackRate:B(D.MediaActionTypes.SET_PLAYBACK_RATE,e),setSubtitleTrack:B(D.MediaActionTypes.SET_SUBTITLE_TRACK,e),setRendition:B(D.MediaActionTypes.SET_RENDITION,e),toggleSubtitles:B(D.MediaActionTypes.TOGGLE_SUBTITLES,e),previewTime:B(D.MediaActionTypes.PREVIEW_TIME,e),clearPreview:B(D.MediaActionTypes.CLEAR_PREVIEW,e)}),[e]),n=oe(e),s=a.useMemo(()=>({togglePlayPause:async l=>{l?await t.pause(!0):await t.play(!0)},seekWithPreview:async l=>{await t.previewTime(l,!0),await t.seek(l,!0)},adjustVolume:async(l,i)=>{const d=Math.max(0,Math.min(1,i+l));await t.setVolume(d,!0)},toggleFullscreenOptimistic:async l=>{l?await t.exitFullscreen(!0):await t.enterFullscreen(!0)}}),[t]),m=a.useCallback(async()=>{const{lastAction:l}=n;l&&n.error&&await e.dispatchOptimistic({...l,retryCount:(l.retryCount||0)+1})},[e,n]);return{...t,...s,actionState:n,retryLastAction:m,isLoading:n.pending,hasError:!!n.error,errorMessage:n.error,retryCount:n.retryCount}}function ge(e,t){if(!t.optimistic)return e;switch(t.type){case"PLAY":return{...e,isPlaying:!0,error:null};case"PAUSE":return{...e,isPlaying:!1};case"SEEK":return{...e,currentTime:t.detail};case"SET_VOLUME":return{...e,volume:Math.max(0,Math.min(1,t.detail))};case"MUTE":return{...e,isMuted:!0};case"UNMUTE":return{...e,isMuted:!1};case"TOGGLE_MUTE":return{...e,isMuted:!e.isMuted};case"ENTER_FULLSCREEN":return{...e,isFullscreen:!0};case"EXIT_FULLSCREEN":return{...e,isFullscreen:!1};case"SET_PLAYBACK_RATE":return{...e,playbackRate:t.detail};case"TOGGLE_SUBTITLES":return{...e,subtitlesShowing:!e.subtitlesShowing};case"PREVIEW_TIME":return{...e,previewTime:t.detail};case"CLEAR_PREVIEW":return{...e,previewTime:null,previewImage:null,previewCoords:null};default:return e}}function ve(e){const t=a.useSyncExternalStore(e.subscribe,e.getState,e.getState),[n,s]=a.useOptimistic(t,ge),m=a.useCallback(async d=>{d.optimistic&&s(d),await e.dispatchOptimistic(d)},[e,s]),l=a.useMemo(()=>({togglePlayPause:async()=>{const d={type:n.isPlaying?"PAUSE":"PLAY",optimistic:!0,timestamp:Date.now()};await m(d)},setVolumeOptimistic:async d=>{const S={type:"SET_VOLUME",detail:Math.max(0,Math.min(1,d)),optimistic:!0,timestamp:Date.now()};await m(S)},seekOptimistic:async d=>{const S={type:"SEEK",detail:d,optimistic:!0,timestamp:Date.now()};await m(S)},toggleMuteOptimistic:async()=>{const d={type:"TOGGLE_MUTE",optimistic:!0,timestamp:Date.now()};await m(d)},toggleFullscreenOptimistic:async()=>{const d={type:n.isFullscreen?"EXIT_FULLSCREEN":"ENTER_FULLSCREEN",optimistic:!0,timestamp:Date.now()};await m(d)},setPlaybackRateOptimistic:async d=>{const S={type:"SET_PLAYBACK_RATE",detail:d,optimistic:!0,timestamp:Date.now()};await m(S)},toggleSubtitlesOptimistic:async()=>{const d={type:"TOGGLE_SUBTITLES",optimistic:!0,timestamp:Date.now()};await m(d)}}),[n,m]),i=a.useMemo(()=>({isPlaying:n.isPlaying,currentTime:n.currentTime,volume:n.volume,isMuted:n.isMuted,isFullscreen:n.isFullscreen,playbackRate:n.playbackRate,subtitlesShowing:n.subtitlesShowing,previewTime:n.previewTime,progress:n.duration>0?n.currentTime/n.duration:0,formattedTime:ne(n.currentTime),formattedDuration:ne(n.duration),canPlay:!n.isLoading&&!n.error,hasError:!!n.error,isBuffering:n.isLoading}),[n]);return{state:n,actualState:t,...i,...l,dispatchOptimistic:m}}function ne(e){if(!e||!isFinite(e))return"0:00";const t=Math.floor(e/60),n=Math.floor(e%60),s=Math.floor(t/60);return s>0?`${s}:${String(t%60).padStart(2,"0")}:${String(n).padStart(2,"0")}`:`${t}:${String(n).padStart(2,"0")}`}function ye(e){const t=a.useRef(null),n=a.useRef(null),[s,m]=a.useTransition(),[l,i]=a.useTransition();a.useRef(0);const d=a.useRef(0),S=a.useRef(0);a.useRef();const R=a.useRef(0),F=D.useMediaStore(),w="getOptimisticState"in F,r=D.useMediaSelector(y=>y.isPlaying),E=D.useMediaSelector(y=>y.currentTime),v=D.useMediaSelector(y=>y.duration),c=D.useMediaSelector(y=>y.volume),h=D.useMediaSelector(y=>y.isMuted),L=D.useMediaSelector(y=>y.isLoading),f=D.useMediaSelector(y=>y.isBuffering),o=D.useMediaSelector(y=>y.error),g=D.useMediaSelector(y=>y.buffered),p=D.useMediaSelector(y=>y.isFullscreen),b=F,M=ve(b),T=ce(b),[H,C]=a.useState({frameRate:0,averageRenderTime:0,droppedFrames:0,bufferHealth:0}),[O,P]=a.useOptimistic(c,(y,I)=>Math.max(0,Math.min(1,I)));a.useOptimistic(E,(y,I)=>Math.max(0,Math.min(v||0,I))),a.useEffect(()=>{const y=t.current;if(!y)return;const I={volume:e.volume,muted:e.muted,autoplay:e.autoPlay,loop:e.loop,preload:e.preload,crossOrigin:e.crossOrigin};Object.entries(I).forEach(([$,j])=>{j!==void 0&&(y[$]=j)}),y.setAttribute("preload",e.preloadStrategy==="eager"?"auto":"metadata"),e.bufferingStrategy==="aggressive"&&y.setAttribute("buffered","auto"),y instanceof HTMLVideoElement&&(y.style.willChange="transform",y.style.transform="translateZ(0)")},[e.volume,e.muted,e.autoPlay,e.loop,e.preload,e.crossOrigin,e.preloadStrategy,e.bufferingStrategy]);const k=a.useCallback(()=>{const y=t.current;if(!y)return;const I=performance.now();if(e.enableTimeUpdateThrottling!==!1){if(I-R.current<(e.timeUpdateThrottleMs||100))return;R.current=I}m(()=>{w&&T&&T.setCurrentTime(y.currentTime)})},[e.enableTimeUpdateThrottling,e.timeUpdateThrottleMs,w,T]),A=a.useCallback(()=>{m(()=>{w&&T&&T.play(!0)}),e.onPlay?.()},[w,T,e.onPlay]),V=a.useCallback(()=>{m(()=>{w&&T&&T.pause(!0)}),e.onPause?.()},[w,T,e.onPause]),U=a.useCallback(()=>{const y=t.current;y&&m(()=>{w&&T&&(T.setVolume(y.volume,!0),y.muted?T.mute(!0):T.unmute(!0))})},[w,T]),x=a.useCallback(()=>{i(()=>{})},[]),W=a.useCallback(()=>{},[]),u=a.useCallback(()=>{const y=t.current;y&&m(()=>{w&&T&&T.setBuffered(y.buffered)})},[w,T]),_=a.useCallback(()=>{const y=performance.now();if(y-S.current>0&&(d.current++,d.current>=60)){const $=Math.round(d.current*1e3/(y-S.current));C(j=>({...j,frameRate:$,droppedFrames:Math.max(0,60-$)})),d.current=0,S.current=y}},[]);a.useEffect(()=>{const y=t.current;if(!y)return;const I=[{event:"timeupdate",handler:k,passive:!0},{event:"play",handler:A},{event:"pause",handler:V},{event:"volumechange",handler:U},{event:"seeking",handler:x},{event:"seeked",handler:W},{event:"progress",handler:u,passive:!0},{event:"loadedmetadata",handler:()=>_()},{event:"loadeddata",handler:()=>_()}];I.forEach(({event:X,handler:Z,passive:ee})=>{const te=ee?{passive:!0}:{};y.addEventListener(X,Z,te)});let $;const j=()=>{_(),$=requestAnimationFrame(j)};return e.enablePerformanceMonitoring&&j(),()=>{I.forEach(({event:X,handler:Z})=>{y.removeEventListener(X,Z)}),$&&cancelAnimationFrame($)}},[k,A,V,U,x,W,u,_,e.enablePerformanceMonitoring]);const q=a.useMemo(()=>{const y=async()=>{const N=t.current;if(N)if(w&&T)await T.play(!0);else try{await N.play()}catch(z){console.error("Failed to play media:",z)}},I=()=>{const N=t.current;N&&(w&&T?T.pause(!0):N.pause())};return{play:y,pause:I,toggle:()=>{r?I():y()},seek:N=>{const z=t.current;if(!z)return;const Y=Math.max(0,Math.min(N,v||0));w&&T?i(()=>{T.seek(Y,!0)}):z.currentTime=Y},setVolume:N=>{const z=t.current;if(!z)return;const Y=Math.max(0,Math.min(1,N));w&&T?(P(Y),m(()=>{T.setVolume(Y,!0)})):z.volume=Y},toggleMute:()=>{const N=t.current;N&&(w&&T?T.toggleMute(!0):N.muted=!N.muted)},enterFullscreen:async()=>{const N=n.current;if(!(!N||!document.fullscreenEnabled))try{await N.requestFullscreen(),w&&T&&T.enterFullscreen(!0)}catch(z){console.error("Failed to enter fullscreen:",z)}},exitFullscreen:async()=>{if(document.fullscreenElement)try{await document.exitFullscreen(),w&&T&&T.exitFullscreen(!0)}catch(N){console.error("Failed to exit fullscreen:",N)}}}},[r,v,w,T,m,i,P]),Q=a.useMemo(()=>({isPlaying:M?.isPlaying??r,currentTime:M?.currentTime??E,duration:M?.duration??v,volume:M?.volume??O,isMuted:M?.isMuted??h,isLoading:M?.isBuffering??L,isBuffering:M?.isBuffering??f,error:M?.error??o,buffered:M?.buffered??g,isFullscreen:M?.isFullscreen??p,progress:v>0?E/v:0,isTransitioning:s||l,canPlay:!L&&!f&&!o}),[M,r,E,v,O,h,L,f,o,g,p,s,l]);return{mediaRef:t,containerRef:n,state:Q,actualState:M?.actualState,controls:q,performanceMetrics:H,isTransitioning:s||l,actions:M?.actions,actionState:M?.actionState,optimisticState:M,isEnhanced:w}}function ue({enabled:e=!0,state:t,controls:n,seekStep:s=10,volumeStep:m=.1}){const l=i=>{if(!e)return;const d=i.target;if(!(d.tagName==="INPUT"||d.tagName==="TEXTAREA"||d.contentEditable==="true"))switch(i.code){case"Space":case"KeyK":i.preventDefault(),n.toggle();break;case"KeyM":i.preventDefault(),n.toggleMute();break;case"KeyF":i.preventDefault(),n.toggleFullscreen();break;case"ArrowLeft":i.preventDefault(),n.seek(Math.max(0,t.currentTime-s));break;case"ArrowRight":i.preventDefault(),n.seek(Math.min(t.duration,t.currentTime+s));break;case"ArrowUp":i.preventDefault(),n.setVolume(Math.min(1,t.volume+m));break;case"ArrowDown":i.preventDefault(),n.setVolume(Math.max(0,t.volume-m));break;case"Digit0":case"Digit1":case"Digit2":case"Digit3":case"Digit4":case"Digit5":case"Digit6":case"Digit7":case"Digit8":case"Digit9":i.preventDefault();const R=parseInt(i.code.replace("Digit",""),10)/10;n.seek(t.duration*R);break;case"Home":i.preventDefault(),n.seek(0);break;case"End":i.preventDefault(),n.seek(t.duration);break}};return a.useEffect(()=>{if(e)return document.addEventListener("keydown",l),()=>{document.removeEventListener("keydown",l)}},[e,l]),{handleKeyDown:l}}const Ee=Object.freeze(Object.defineProperty({__proto__:null,useKeyboardControls:ue},Symbol.toStringTag,{value:"Module"}));function Te(e={}){const{maxMemoryUsage:t=100,cleanupInterval:n=3e4,enableGC:s=!0,monitorMemory:m=!0}=e;a.useRef();const l=a.useRef(new Set),i=a.useRef(new Map),d=a.useRef(new Set),S=a.useRef(new Set),R=a.useCallback(()=>{if(typeof window>"u"||!("memory"in performance))return{used:0,total:0,limit:0};const f=performance.memory;return{used:f.usedJSHeapSize,total:f.totalJSHeapSize,limit:f.jsHeapSizeLimit}},[]),[F,w]=a.useState({used:0,total:0,limit:0,usage:0,isHighUsage:!1}),r=a.useCallback(()=>{d.current.forEach(f=>{clearTimeout(f)}),d.current.clear(),S.current.forEach(f=>{cancelAnimationFrame(f)}),S.current.clear(),l.current.forEach(f=>{f.disconnect()}),l.current.clear(),i.current.forEach((f,o)=>{f.forEach(({event:g,handler:p})=>{o.removeEventListener(g,p)})}),i.current.clear(),typeof window<"u"&&"gc"in window&&window.gc()},[]),E=a.useCallback((f,o)=>{const g=setInterval(f,o);return d.current.add(g),()=>{clearInterval(g),d.current.delete(g)}},[]);a.useEffect(()=>{if(!m)return;const f=()=>{const o=R(),g=o.used/1024/1024,p=g>t;w({...o,usage:g,isHighUsage:p}),p&&s&&r()};return f(),E(f,n)},[m,R,t,s,n,r]);const v=a.useCallback((f,o,g,p)=>(f.addEventListener(o,g,p),i.current.has(f)||i.current.set(f,[]),i.current.get(f).push({event:o,handler:g}),()=>{f.removeEventListener(o,g);const b=i.current.get(f);if(b){const M=b.findIndex(T=>T.event===o&&T.handler===g);M>-1&&b.splice(M,1),b.length===0&&i.current.delete(f)}}),[]),c=a.useCallback((f,o)=>{const g=c(f,o);return d.current.add(g),()=>{clearTimeout(g),d.current.delete(g)}},[]),h=a.useCallback(f=>{const o=h(f);return S.current.add(o),()=>{cancelAnimationFrame(o),S.current.delete(o)}},[]),L=a.useCallback(f=>(l.current.add(f),()=>{f.disconnect(),l.current.delete(f)}),[]);return a.useEffect(()=>()=>{r()},[r]),{memoryStats:F,getMemoryUsage:R,performCleanup:r,addEventListener:v,setInterval,setTimeout:c,requestAnimationFrame:h,addObserver:L,formatBytes:f=>{if(f===0)return"0 Bytes";const o=1024,g=["Bytes","KB","MB","GB"],p=Math.floor(Math.log(f)/Math.log(o));return parseFloat((f/Math.pow(o,p)).toFixed(2))+" "+g[p]}}}function le(){const[e,t]=a.useState({isPlaying:!1,currentTime:0,duration:0,volume:1,isMuted:!1,isLoading:!1,isFullscreen:!1,error:null,buffered:null}),n=r=>{t(E=>({...E,...r}))};return{state:e,updateState:n,setPlaying:r=>{n({isPlaying:r})},setCurrentTime:r=>{n({currentTime:r})},setDuration:r=>{n({duration:r})},setVolume:r=>{n({volume:Math.max(0,Math.min(1,r))})},setMuted:r=>{n({isMuted:r})},setLoading:r=>{n({isLoading:r})},setFullscreen:r=>{n({isFullscreen:r})},setError:r=>{n({error:r})},setBuffered:r=>{n({buffered:r})}}}function de(e){const t=a.useRef(null),n=a.useRef(null),{state:s,setPlaying:m,setCurrentTime:l,setDuration:i,setVolume:d,setMuted:S,setLoading:R,setFullscreen:F,setError:w,setBuffered:r}=le();a.useEffect(()=>{const u=t.current;u&&(e.volume!==void 0&&(u.volume=e.volume,d(e.volume)),e.muted!==void 0&&(u.muted=e.muted,S(e.muted)),e.autoPlay!==void 0&&(u.autoplay=e.autoPlay),e.loop!==void 0&&(u.loop=e.loop),e.preload!==void 0&&(u.preload=e.preload),e.crossOrigin!==void 0&&(u.crossOrigin=e.crossOrigin))},[e,d,S]);const E=()=>{m(!0),e.onPlay?.()},v=()=>{m(!1),e.onPause?.()},c=()=>{const u=t.current;u&&(l(u.currentTime),e.onTimeUpdate?.(u.currentTime))},h=()=>{const u=t.current;u&&(i(u.duration),e.onDurationChange?.(u.duration))},L=()=>{const u=t.current;u&&(d(u.volume),S(u.muted),e.onVolumeChange?.(u.volume))},f=()=>{R(!0),w(null),e.onLoadStart?.()},o=()=>{R(!1),e.onLoadedData?.()},g=()=>{const u=t.current;if(!u)return;const _=u.error?.message||"An error occurred while loading the media";w(_),R(!1),e.onError?.(_)},p=()=>{m(!1),e.onEnded?.()},b=()=>{const u=t.current;u&&r(u.buffered)};a.useEffect(()=>{const u=t.current;if(u)return u.addEventListener("play",E),u.addEventListener("pause",v),u.addEventListener("timeupdate",c),u.addEventListener("durationchange",h),u.addEventListener("volumechange",L),u.addEventListener("loadstart",f),u.addEventListener("loadeddata",o),u.addEventListener("error",g),u.addEventListener("ended",p),u.addEventListener("progress",b),()=>{u.removeEventListener("play",E),u.removeEventListener("pause",v),u.removeEventListener("timeupdate",c),u.removeEventListener("durationchange",h),u.removeEventListener("volumechange",L),u.removeEventListener("loadstart",f),u.removeEventListener("loadeddata",o),u.removeEventListener("error",g),u.removeEventListener("ended",p),u.removeEventListener("progress",b)}},[E,v,c,h,L,f,o,g,p,b]);const M=async()=>{const u=t.current;if(u)try{await u.play()}catch(_){console.error("Failed to play media:",_),w("Failed to play media")}},T=()=>{const u=t.current;u&&u.pause()},H=()=>{s.isPlaying?T():M()},C=u=>{const _=t.current;_&&(_.currentTime=Math.max(0,Math.min(u,_.duration||0)))},O=u=>{const _=t.current;if(!_)return;const q=Math.max(0,Math.min(1,u));_.volume=q},P=()=>{const u=t.current;u&&(u.muted=!0)},k=()=>{const u=t.current;u&&(u.muted=!1)},A=()=>{const u=t.current;u&&(u.muted=!u.muted)},V=async()=>{const u=n.current;if(!(!u||!document.fullscreenEnabled))try{await u.requestFullscreen(),F(!0)}catch(_){console.error("Failed to enter fullscreen:",_)}},U=async()=>{if(document.fullscreenElement)try{await document.exitFullscreen(),F(!1)}catch(u){console.error("Failed to exit fullscreen:",u)}},x=()=>{document.fullscreenElement?U():V()};return a.useEffect(()=>{const u=()=>{F(!!document.fullscreenElement)};return document.addEventListener("fullscreenchange",u),()=>{document.removeEventListener("fullscreenchange",u)}},[F]),{state:s,controls:{play:M,pause:T,toggle:H,seek:C,setVolume:O,mute:P,unmute:k,toggleMute:A,enterFullscreen:V,exitFullscreen:U,toggleFullscreen:x},mediaRef:t,containerRef:n}}const G={mobile:768,desktop:1280};function re(){if(typeof window>"u")return"unknown";const e=window.navigator.userAgent.toLowerCase();return/iphone|ipad|ipod/.test(e)?"ios":/android/.test(e)?"android":/windows|mac|linux/.test(e)?"desktop":"unknown"}function se(){return typeof window>"u"?!1:"ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0}function ae(){return typeof window>"u"?!1:"vibrate"in navigator||"vibration"in navigator||"ondevicemotion"in window}function J(){const[e,t]=K.useState(()=>{if(typeof window>"u")return{isMobile:!1,isTablet:!1,isDesktop:!0,isTouchDevice:!1,platform:"unknown",supportsHaptics:!1,screenSize:{width:1920,height:1080},orientation:"landscape"};const n=window.innerWidth,s=window.innerHeight;return{isMobile:n<G.mobile,isTablet:n>=G.mobile&&n<G.desktop,isDesktop:n>=G.desktop,isTouchDevice:se(),platform:re(),supportsHaptics:ae(),screenSize:{width:n,height:s},orientation:n>s?"landscape":"portrait"}});return K.useEffect(()=>{const n=()=>{const i=window.innerWidth,d=window.innerHeight;t({isMobile:i<G.mobile,isTablet:i>=G.mobile&&i<G.desktop,isDesktop:i>=G.desktop,isTouchDevice:se(),platform:re(),supportsHaptics:ae(),screenSize:{width:i,height:d},orientation:i>d?"landscape":"portrait"})};window.addEventListener("resize",n),window.addEventListener("orientationchange",n);const s=window.matchMedia(`(max-width: ${G.mobile-1}px)`),m=window.matchMedia(`(min-width: ${G.mobile}px) and (max-width: ${G.desktop-1}px)`),l=window.matchMedia(`(min-width: ${G.desktop}px)`);return s.addEventListener("change",n),m.addEventListener("change",n),l.addEventListener("change",n),()=>{window.removeEventListener("resize",n),window.removeEventListener("orientationchange",n),s.removeEventListener("change",n),m.removeEventListener("change",n),l.removeEventListener("change",n)}},[]),e}function we(){const{platform:e,isMobile:t}=J();K.useEffect(()=>{if(t){if(e==="ios"){const n=s=>{s.touches.length>1&&s.preventDefault()};return document.addEventListener("touchstart",n,{passive:!1}),document.body.style.webkitOverflowScrolling="touch",()=>{document.removeEventListener("touchstart",n)}}e==="android"&&(document.body.style.touchAction="manipulation"),document.documentElement.style.setProperty("--webkit-transform","translateZ(0)"),document.documentElement.style.setProperty("--transform","translateZ(0)")}},[e,t])}function be(){const{supportsHaptics:e}=J();return{triggerHaptic:K.useCallback((n="light")=>{if(!e)return;const m={light:[10],medium:[20],heavy:[30],success:[10,10,10],warning:[20,20],error:[50,20,50]}[n];"vibrate"in navigator&&navigator.vibrate(m)},[e]),supportsHaptics:e}}const Se={enabledGestures:["tap","double-tap","long-press","swipe-left","swipe-right","swipe-up","swipe-down","pinch-in","pinch-out"],tapThreshold:200,doubleTapThreshold:300,longPressThreshold:500,swipeThreshold:50,swipeVelocityThreshold:.5,pinchThreshold:.1,rotationThreshold:15,enableHapticFeedback:!0};function me(e,t,n={}){const s={...Se,...n},{isTouchDevice:m}=J(),{triggerHaptic:l}=be(),i=K.useRef({isTracking:!1,touches:[],startTouches:[]}),d=v=>({id:v.identifier,x:v.clientX,y:v.clientY,timestamp:Date.now()}),S=(v,c)=>Math.sqrt(Math.pow(c.x-v.x,2)+Math.pow(c.y-v.y,2)),R=(v,c)=>{const h=Math.max(c.timestamp-v.timestamp,1);return{x:(c.x-v.x)/h,y:(c.y-v.y)/h}},F=(v,c,h,L={})=>({type:v,startPoint:{x:c.x,y:c.y},currentPoint:{x:h.x,y:h.y},duration:h.timestamp-c.timestamp,target:e.current,preventDefault:()=>{},...L}),w=K.useCallback(v=>{if(!s.enabledGestures.length)return;const c=Array.from(v.touches).map(d),h=i.current;h.isTracking=!0,h.touches=c,h.startTouches=[...c],h.longPressTimer&&clearTimeout(h.longPressTimer),c.length===1&&s.enabledGestures.includes("long-press")&&(h.longPressTimer=setTimeout(()=>{if(h.touches.length===1&&c[0]){const L=F("long-press",c[0],c[0]);t(L),s.enableHapticFeedback&&l("heavy")}},s.longPressThreshold)),c.length===2&&c[0]&&c[1]&&(h.initialDistance=S(c[0],c[1]),h.initialScale=1,h.lastScale=1)},[s,t,l]),r=K.useCallback(v=>{const c=i.current;if(!c.isTracking)return;const h=Array.from(v.touches).map(d);if(c.touches=h,h.length===2&&c.initialDistance&&h[0]&&h[1]){const L=S(h[0],h[1]),f=L/c.initialDistance;if(Math.abs(f-(c.lastScale||1))>s.pinchThreshold){const g=f>(c.lastScale||1)?"pinch-out":"pinch-in";if(s.enabledGestures.includes(g)){const p={x:(h[0].x+h[1].x)/2,y:(h[0].y+h[1].y)/2,timestamp:Date.now()},b={x:((c.startTouches[0]?.x??0)+(c.startTouches[1]?.x??0))/2,y:((c.startTouches[0]?.y??0)+(c.startTouches[1]?.y??0))/2,timestamp:c.startTouches[0]?.timestamp??Date.now()},M=F(g,b,p,{scale:f,distance:L});t(M),c.lastScale=f}}}if(c.longPressTimer&&h.length===1&&c.startTouches[0]&&h[0]){const L=c.startTouches[0],f=h[0];S(L,f)>s.swipeThreshold&&(clearTimeout(c.longPressTimer),c.longPressTimer=void 0)}},[s,t]),E=K.useCallback(v=>{const c=i.current;if(!c.isTracking)return;const h=Array.from(v.changedTouches).map(d),L=Date.now();if(c.longPressTimer&&(clearTimeout(c.longPressTimer),c.longPressTimer=void 0),c.startTouches.length===1&&h.length===1&&c.startTouches[0]&&h[0]){const f=c.startTouches[0],o=h[0],g=S(f,o),p=o.timestamp-f.timestamp;if(g>s.swipeThreshold){const b=R(f,o),M=Math.abs(b.x),T=Math.abs(b.y);if(M>s.swipeVelocityThreshold||T>s.swipeVelocityThreshold){let H;if(M>T?H=b.x>0?"swipe-right":"swipe-left":H=b.y>0?"swipe-down":"swipe-up",s.enabledGestures.includes(H)){const C=F(H,f,o,{velocity:b,distance:g});t(C),s.enableHapticFeedback&&l("light")}}}else if(p<s.tapThreshold&&g<s.swipeThreshold)if(c.lastTap&&L-c.lastTap.timestamp<s.doubleTapThreshold&&S({...c.lastTap.point},o)<s.swipeThreshold){if(s.enabledGestures.includes("double-tap")){const b=F("double-tap",f,o);t(b),s.enableHapticFeedback&&l("medium")}c.lastTap=void 0}else{if(s.enabledGestures.includes("tap")){const b=F("tap",f,o);t(b),s.enableHapticFeedback&&l("light")}c.lastTap={timestamp:L,point:{x:o.x,y:o.y}}}}v.touches.length===0&&(c.isTracking=!1,c.touches=[],c.startTouches=[],c.initialDistance=void 0,c.initialScale=void 0,c.lastScale=void 0)},[s,t,l]);return K.useEffect(()=>{const v=e.current;if(!(!v||!m))return v.addEventListener("touchstart",w,{passive:!1}),v.addEventListener("touchmove",r,{passive:!1}),v.addEventListener("touchend",E,{passive:!1}),v.addEventListener("touchcancel",E,{passive:!1}),()=>{v.removeEventListener("touchstart",w),v.removeEventListener("touchmove",r),v.removeEventListener("touchend",E),v.removeEventListener("touchcancel",E)}},[w,r,E,m]),{isGestureEnabled:m&&s.enabledGestures.length>0}}function Me(e,t){const n=K.useCallback(m=>{const{type:l,distance:i,scale:d}=m;switch(l){case"double-tap":t.onPlayPause?.();break;case"swipe-left":const S=Math.min((i||0)/10,30);t.onSeek?.("backward",S);break;case"swipe-right":const R=Math.min((i||0)/10,30);t.onSeek?.("forward",R);break;case"swipe-up":if(m.startPoint.x>(e.current?.clientWidth||0)/2){const F=Math.min((i||0)/100,.2);t.onVolumeChange?.("up",F)}break;case"swipe-down":if(m.startPoint.x>(e.current?.clientWidth||0)/2){const F=Math.min((i||0)/100,.2);t.onVolumeChange?.("down",F)}break;case"pinch-out":t.onZoom?.(d||1);break;case"pinch-in":t.onZoom?.(d||1);break;case"long-press":t.onToggleFullscreen?.();break}},[t,e]);return me(e,n,{enabledGestures:["tap","double-tap","long-press","swipe-left","swipe-right","swipe-up","swipe-down","pinch-in","pinch-out"],enableHapticFeedback:!0,swipeThreshold:30,swipeVelocityThreshold:.3})}function fe({subtitleSrc:e,subtitleTracks:t=[],defaultFontSize:n="medium",onLoadError:s}={}){const[m,l]=a.useState(!1),[i,d]=a.useState([]),[S,R]=a.useState(""),[F,w]=a.useState(null),[r,E]=a.useState(n),[v,c]=a.useState(null),[h,L]=a.useState(!1),f={small:"text-sm",medium:"text-base",large:"text-lg"},o=!!(e||t&&t.length>0),g=P=>{const k=P.split(":"),A=k[2]?parseFloat(k[2]):0,V=k[1]?parseInt(k[1],10)*60:0;return(k[0]?parseInt(k[0],10)*3600:0)+V+A},p=P=>{const[k,A]=P.split(","),V=(k||"").split(":"),U=A?parseInt(A,10)/1e3:0,x=V[2]?parseInt(V[2],10):0,W=V[1]?parseInt(V[1],10)*60:0;return(V[0]?parseInt(V[0],10)*3600:0)+W+x+U},b=async P=>{L(!0),c(null);try{const k=await fetch(P);if(!k.ok)throw new Error(`Failed to load subtitles: ${k.status} ${k.statusText}`);const A=await k.text(),V=[],U=A.split(`
2
+ `);let x=0;const W=A.includes("WEBVTT")||P.endsWith(".vtt"),u=P.endsWith(".srt")||/^\d+$/.test(U[0]?.trim()||"");if(W)for(;x<U.length;){if(U[x]?.includes("-->")){const[_,q]=(U[x]||"").split("-->").map($=>$.trim()),Q=g(_||""),y=g(q||"");x++;let I="";for(;x<U.length&&U[x]?.trim()!=="";)I+=(I?" ":"")+U[x]?.trim(),x++;I&&V.push({start:Q,end:y,text:I})}x++}else if(u)for(;x<U.length;){if(/^\d+$/.test(U[x]?.trim()||"")&&(x++,U[x]?.includes("-->"))){const[_,q]=(U[x]||"").split("-->").map($=>$.trim()),Q=p(_||""),y=p(q||"");x++;let I="";for(;x<U.length&&U[x]?.trim()!=="";)I+=(I?" ":"")+U[x]?.trim(),x++;I&&V.push({start:Q,end:y,text:I})}x++}else throw new Error("Unsupported subtitle format. Only VTT and SRT are supported.");if(V.length===0)throw new Error("No subtitle cues found in file");d(V),L(!1)}catch(k){const A=k instanceof Error?k:new Error("Failed to load subtitles");console.error("Failed to load subtitles:",A),c(A),L(!1),d([]),s?.(A)}},M=P=>!m||i.length===0?"":i.find(A=>P>=A.start&&P<=A.end)?.text||"",T=()=>{l(P=>{const k=!P;if(k&&!v){if(i.length===0&&!h){const A=e||t[0]?.src;A&&(b(A),t[0]&&w(t[0].id))}}else k||R("");return k})},H=P=>{if(!P){l(!1),w(null),R("");return}const k=t.find(A=>A.id===P);k?.src&&(w(P),b(k.src),l(!0))},C=P=>{E(P)},O={fontSize:f[r],className:`${f[r]} font-medium`};return a.useEffect(()=>{m||R("")},[m]),a.useEffect(()=>{},[]),{subtitlesEnabled:m,currentSubtitle:S,subtitleCues:i,currentTrackId:F,fontSize:r,loadError:v,isLoading:h,hasSubtitles:o,toggleSubtitles:T,selectSubtitleTrack:H,changeSubtitleFontSize:C,setCurrentSubtitle:R,getCurrentSubtitle:M,getSubtitleStyles:O,availableTracks:t}}const ke=Object.freeze(Object.defineProperty({__proto__:null,useEnhancedSubtitles:fe},Symbol.toStringTag,{value:"Module"}));function Le({videoControls:e,toggleSubtitles:t,takeScreenshot:n,duration:s}){const m=l=>{const i=document.querySelector("video");if(i)switch(l.key.toLowerCase()){case" ":case"k":l.preventDefault(),e.togglePlay();break;case"j":l.preventDefault(),e.seekBackward();break;case"l":l.preventDefault(),e.seekForward();break;case"arrowleft":l.preventDefault(),i.currentTime=Math.max(0,i.currentTime-5);break;case"arrowright":l.preventDefault(),i.currentTime=Math.min(s,i.currentTime+5);break;case"arrowup":l.preventDefault(),i.volume=Math.min(1,i.volume+.1);break;case"arrowdown":l.preventDefault(),i.volume=Math.max(0,i.volume-.1);break;case"m":l.preventDefault(),e.toggleMute();break;case"f":l.preventDefault(),e.toggleFullscreen();break;case"c":l.preventDefault(),t();break;case"s":l.preventDefault(),n(l.ctrlKey||l.metaKey);break}};a.useEffect(()=>(document.addEventListener("keydown",m),()=>document.removeEventListener("keydown",m)),[m])}function Pe(e,t){const[n,s]=a.useState(!0),[m,l]=a.useState(!1),i=a.useRef(null),d=()=>{s(!0),i.current&&clearTimeout(i.current),e&&!t&&(i.current=setTimeout(()=>{s(!1)},3e3))},S=()=>{d()},R=()=>{s(!0)},F=()=>{e&&s(!1)};return a.useEffect(()=>(d(),()=>{i.current&&clearTimeout(i.current)}),[d]),{controlsVisible:n,showVolumeSlider:m,setShowVolumeSlider:l,handleMouseMove:S,handleMouseEnter:R,handleMouseLeave:F}}function Ce(e){return{takeScreenshot:(n=!1)=>{if(!e.current)return;const s=e.current,m=document.createElement("canvas");m.width=s.videoWidth,m.height=s.videoHeight;const l=m.getContext("2d");if(l)try{l.drawImage(s,0,0),m.toBlob(i=>{if(!i){console.error("Failed to create blob from canvas");return}if(n)if(navigator.clipboard&&window.ClipboardItem){const d=new ClipboardItem({"image/png":i});navigator.clipboard.write([d]).catch(S=>{console.error("Failed to copy to clipboard:",S)})}else console.warn("Clipboard API not supported");else{const d=URL.createObjectURL(i),S=document.createElement("a");S.href=d,S.download=`screenshot-${Date.now()}.png`,S.click(),URL.revokeObjectURL(d)}},"image/png")}catch(i){i instanceof Error&&i.message.includes("tainted")?(console.error("Canvas is tainted - video source may not have proper CORS headers. Try setting crossOrigin='anonymous' on the video element."),alert("Screenshot failed: The video source doesn't allow screenshots due to CORS policy. Please ensure the video server includes proper CORS headers or set crossOrigin='anonymous' on the video player.")):(console.error("Screenshot failed:",i),alert("Screenshot failed: "+(i instanceof Error?i.message:"Unknown error")))}}}}function Fe(e){const t=a.useRef(null),[n,s]=a.useState({isPlaying:!1,currentTime:0,duration:0,volume:1,isMuted:!1,isFullscreen:!1,isLoading:!0,isSeeking:!1,isBuffering:!1,bufferedRanges:[]});return a.useEffect(()=>{const r=t.current;if(!r)return;const E=()=>{s(C=>({...C,currentTime:r.currentTime}))},v=()=>{s(C=>({...C,duration:r.duration}))},c=()=>{s(C=>({...C,isPlaying:!0,isBuffering:!1}))},h=()=>{s(C=>({...C,isPlaying:!1}))},L=()=>{s(C=>({...C,volume:r.volume,isMuted:r.muted}))},f=()=>{s(C=>({...C,isLoading:!0}))},o=()=>{s(C=>({...C,isLoading:!1}))},g=()=>{s(C=>({...C,isSeeking:!0}))},p=()=>{s(C=>({...C,isSeeking:!1}))},b=()=>{s(C=>({...C,isBuffering:!0}))},M=()=>{s(C=>({...C,isBuffering:!1,isLoading:!1}))},T=()=>{s(C=>({...C,isLoading:!1,isBuffering:!1}))},H=()=>{if(!r.buffered||r.buffered.length===0||r.duration===0){s(O=>({...O,bufferedRanges:[]}));return}const C=[];for(let O=0;O<r.buffered.length;O++){const P=r.buffered.start(O),k=r.buffered.end(O);C.push({start:P,end:k,percentage:(k-P)/r.duration*100})}s(O=>({...O,bufferedRanges:C}))};return r.addEventListener("timeupdate",E),r.addEventListener("loadedmetadata",v),r.addEventListener("play",c),r.addEventListener("pause",h),r.addEventListener("volumechange",L),r.addEventListener("loadstart",f),r.addEventListener("loadeddata",o),r.addEventListener("seeking",g),r.addEventListener("seeked",p),r.addEventListener("waiting",b),r.addEventListener("playing",M),r.addEventListener("canplay",T),r.addEventListener("progress",H),()=>{r.removeEventListener("timeupdate",E),r.removeEventListener("loadedmetadata",v),r.removeEventListener("play",c),r.removeEventListener("pause",h),r.removeEventListener("volumechange",L),r.removeEventListener("loadstart",f),r.removeEventListener("loadeddata",o),r.removeEventListener("seeking",g),r.removeEventListener("seeked",p),r.removeEventListener("waiting",b),r.removeEventListener("playing",M),r.removeEventListener("canplay",T),r.removeEventListener("progress",H)}},[]),{videoRef:t,state:n,controls:{togglePlay:()=>{const r=t.current;r&&(n.isPlaying?r.pause():r.play())},seekForward:(r=10)=>{const E=t.current;E&&(E.currentTime=Math.min(n.duration,E.currentTime+r))},seekBackward:(r=10)=>{const E=t.current;E&&(E.currentTime=Math.max(0,E.currentTime-r))},toggleMute:()=>{const r=t.current;r&&(r.muted=!n.isMuted)},setVolume:r=>{const E=t.current;E&&(E.volume=r,r>0&&n.isMuted&&(E.muted=!1))},toggleFullscreen:()=>{const r=e.current;r&&(n.isFullscreen?document.exitFullscreen&&document.exitFullscreen():r.requestFullscreen&&r.requestFullscreen(),s(E=>({...E,isFullscreen:!E.isFullscreen})))},seekTo:r=>{const E=t.current;!E||n.duration===0||(E.currentTime=Math.max(0,Math.min(n.duration,r)))}}}}const De=(e,t={})=>{const{trackUserBehavior:n=!0,adaptToNetwork:s=!0,strategy:m="balanced",maxPreloadItems:l=3,preloadRadius:i=2}=t,d=a.useRef({mouseMovements:0,scrollEvents:0,keyPresses:0,focusEvents:0,timeOnPage:0,engagementScore:0,lastInteraction:Date.now()}),S=a.useRef(null),R=a.useRef(new Set),F=a.useRef([]),w=a.useCallback(()=>{const o=d.current,g=Math.min(o.timeOnPage/6e4,1),p=Math.min((o.mouseMovements+o.scrollEvents+o.keyPresses)/100,1);return(g*.4+p*.6)*100},[]),r=a.useCallback((o,g=1)=>{const p=d.current;p[o]=typeof p[o]=="number"?p[o]+g:Date.now(),p.engagementScore=w(),p.lastInteraction=Date.now()},[w]),E=a.useCallback(()=>{if(!S.current||!s)return{type:"unknown",downlink:10,effectiveType:"4g",saveData:!1};const o=S.current;return{type:o.type,downlink:o.downlink||10,effectiveType:o.effectiveType||"4g",saveData:o.saveData||!1,rtt:o.rtt||100}},[s]),v=a.useCallback((o,g,p=0)=>{if(R.current.has(o.src))return{shouldPreload:!1,priority:"low",reason:"Already preloaded"};const b=Math.abs(g-p);if(b>i)return{shouldPreload:!1,priority:"low",reason:"Outside preload radius"};const M=d.current,T=E(),H=M.engagementScore,C=Date.now()-M.lastInteraction;if(T.saveData)return{shouldPreload:!1,priority:"low",reason:"Data saver mode"};let O=!1,P="medium",k="";switch(m){case"conservative":O=H>70&&T.effectiveType!=="2g"&&b===1,P=O?"medium":"low",k=O?"High engagement and optimal network":"Conservative strategy";break;case"aggressive":O=H>30&&T.effectiveType!=="slow-2g",P=H>70?"high":H>50?"medium":"low",k=O?"Aggressive preloading":"Low engagement";break;case"balanced":default:const A=T.effectiveType==="4g"?1:T.effectiveType==="3g"?.7:.3,V=H*A;O=V>40&&b<=2,P=V>70?"high":V>55?"medium":"low",k=O?`Balanced: score ${V.toFixed(1)}`:"Low adjusted score";break}return O&&((o.type==="hls"||o.type==="m3u8")&&(P=P==="low"?"medium":"high"),C<5e3&&(P="high",k+=" + Recent interaction"),(o.type==="mp4"||o.type==="webm")&&(P=P==="low"?"medium":P)),{shouldPreload:O,priority:P,reason:k}},[m,i,E,w]),c=a.useCallback(async(o,g)=>{try{const p=document.createElement("link");switch(p.rel="preload",p.href=o.src,o.type){case"hls":case"m3u8":p.as="fetch";break;case"mp4":case"webm":p.as="video";break;case"mp3":case"wav":case"ogg":p.as="audio";break;default:p.as="fetch"}p.crossOrigin="anonymous",document.head.appendChild(p),R.current.add(o.src),console.debug(`Preloaded: ${o.src} (${g})`),setTimeout(()=>{document.head.contains(p)&&document.head.removeChild(p)},3e4)}catch(p){console.warn("Failed to preload source:",o.src,p)}},[]),h=a.useCallback(()=>{if(F.current.length===0)return;const g=[...F.current].sort((p,b)=>b.priority-p.priority).slice(0,l);F.current=[],g.forEach(({source:p,priority:b})=>{c(p,b)})},[l,c]),L=a.useCallback((o=0)=>{F.current=[],e.forEach((g,p)=>{const b=v(g,p,o);if(b.shouldPreload){const M=b.priority==="high"?3:b.priority==="medium"?2:1;F.current.push({source:g,priority:M})}}),h()},[e,v,h]);return a.useEffect(()=>{if(!n)return;const o=()=>r("mouseMovements"),g=()=>r("scrollEvents"),p=()=>r("keyPresses"),b=()=>r("focusEvents");document.addEventListener("mousemove",o,{passive:!0}),document.addEventListener("scroll",g,{passive:!0}),document.addEventListener("keydown",p,{passive:!0}),document.addEventListener("focusin",b,{passive:!0});const M=setInterval(()=>{r("timeOnPage",1)},1e3);return()=>{document.removeEventListener("mousemove",o),document.removeEventListener("scroll",g),document.removeEventListener("keydown",p),document.removeEventListener("focusin",b),clearInterval(M)}},[n,r]),a.useEffect(()=>{if(!s||!("connection"in navigator))return;const o=navigator.connection;S.current=o;const g=()=>{L()};return o.addEventListener("change",g),()=>{o.removeEventListener("change",g)}},[s,L]),a.useEffect(()=>{L()},[L]),a.useMemo(()=>({preloadAtIndex:o=>{L(o)},getUserBehavior:()=>({...d.current}),getNetworkConditions:E,clearCache:()=>{R.current.clear()},getStats:()=>({preloadedItems:R.current.size,engagementScore:d.current.engagementScore,queueLength:F.current.length,maxPreloadItems:l})}),[L,E,l])};function he(e){const[t,n]=a.useState(!1),[s,m]=a.useState([]),[l,i]=a.useState(""),d=w=>{const r=w.split(":"),E=r[2]?parseFloat(r[2]):0,v=r[1]?parseInt(r[1],10)*60:0;return(r[0]?parseInt(r[0],10)*3600:0)+v+E},S=async w=>{try{const E=await(await fetch(w)).text(),v=[],c=E.split(`
3
+ `);let h=0;for(;h<c.length;){if(c[h]?.includes("-->")){const[L,f]=(c[h]||"").split("-->").map(b=>b.trim()),o=d(L||""),g=d(f||"");h++;let p="";for(;h<c.length&&c[h]?.trim()!=="";)p+=(p?" ":"")+c[h]?.trim(),h++;p&&v.push({start:o,end:g,text:p})}h++}m(v)}catch(r){console.error("Failed to load subtitles:",r)}},R=w=>!t||s.length===0?"":s.find(E=>w>=E.start&&w<=E.end)?.text||"",F=()=>{n(w=>{const r=!w;return r&&e&&s.length===0?S(e):r||i(""),r})};return a.useEffect(()=>{t||i("")},[t]),{subtitlesEnabled:t,currentSubtitle:l,toggleSubtitles:F,getCurrentSubtitle:R,setCurrentSubtitle:i}}function Re(e){return ie.showDeprecationWarning("useVideoPlayer","useMediaPlayer (the primary media player hook)"),de(e)}function xe(e){return ie.showDeprecationWarning("useEnhancedSubtitles","useSubtitles (the current subtitle hook)"),he(e)}exports.useDeviceInfo=J;exports.useEnhancedMediaPlayer=ye;exports.useEnhancedSubtitles=fe;exports.useEnhancedSubtitles$1=xe;exports.useEnhancedSubtitles$2=ke;exports.useIntelligentPreloading=De;exports.useKeyboardControls=ue;exports.useKeyboardControls$1=Ee;exports.useKeyboardShortcuts=Le;exports.useMediaActionState=oe;exports.useMediaActions=ce;exports.useMediaControls=Pe;exports.useMediaGestures=Me;exports.useMediaPlayer=de;exports.useMediaState=le;exports.useMemoryOptimization=Te;exports.useMobileOptimizations=we;exports.useScreenshot=Ce;exports.useSubtitles=he;exports.useTouchGestures=me;exports.useVideoPlayer=Fe;exports.useVideoPlayer$1=Re;
4
+ //# sourceMappingURL=hooks-BW-JjVgP.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-BW-JjVgP.cjs","sources":["../src/hooks/use-media-actions.ts","../src/hooks/use-media-optimistic.ts","../src/hooks/use-enhanced-media-player.ts","../src/hooks/use-keyboard-controls.ts","../src/hooks/use-memory-optimization.ts","../src/hooks/use-media-state.ts","../src/hooks/use-media-player.ts","../../ui/src/hooks/use-mobile.ts","../src/hooks/use-touch-gestures.ts","../src/hooks/useEnhancedSubtitles.ts","../src/hooks/useKeyboardShortcuts.ts","../src/hooks/useMediaControls.ts","../src/hooks/useScreenshot.ts","../src/hooks/useVideoPlayer.ts","../src/hooks/use-intelligent-preloading.ts","../src/hooks/useSubtitles.ts","../src/hooks/legacy.ts"],"sourcesContent":["\"use client\"\n\nimport React from \"react\"\nimport type { MediaActionType, MediaState } from \"../context/media-context\"\nimport { MediaActionTypes } from \"../context/media-context\"\nimport type {\n\tEnhancedMediaStore,\n\tMediaActionState,\n\tOptimisticMediaAction\n} from \"../context/media-store\"\n\n// Action payload types\nexport interface MediaActionPayloads {\n\t[MediaActionTypes.PLAY]: void\n\t[MediaActionTypes.PAUSE]: void\n\t[MediaActionTypes.SEEK]: number\n\t[MediaActionTypes.SET_VOLUME]: number\n\t[MediaActionTypes.MUTE]: void\n\t[MediaActionTypes.UNMUTE]: void\n\t[MediaActionTypes.TOGGLE_MUTE]: void\n\t[MediaActionTypes.SET_DURATION]: number\n\t[MediaActionTypes.SET_CURRENT_TIME]: number\n\t[MediaActionTypes.SET_BUFFERED]: TimeRanges | null\n\t[MediaActionTypes.SET_LOADING]: boolean\n\t[MediaActionTypes.SET_ERROR]: string | null\n\t[MediaActionTypes.ENTER_FULLSCREEN]: void\n\t[MediaActionTypes.EXIT_FULLSCREEN]: void\n\t[MediaActionTypes.ENTER_PIP]: void\n\t[MediaActionTypes.EXIT_PIP]: void\n\t[MediaActionTypes.SET_PLAYBACK_RATE]: number\n\t[MediaActionTypes.SET_SUBTITLE_TRACK]: TextTrack | null\n\t[MediaActionTypes.SET_RENDITION]: string | null\n\t[MediaActionTypes.TOGGLE_SUBTITLES]: void\n\t[MediaActionTypes.PREVIEW_TIME]: number | null\n\t[MediaActionTypes.CLEAR_PREVIEW]: void\n}\n\n// Enhanced action creator that returns a Promise\ntype OptimisticActionCreator<T extends keyof MediaActionPayloads> =\n\tMediaActionPayloads[T] extends void\n\t\t? (optimistic?: boolean) => Promise<void>\n\t\t: (payload: MediaActionPayloads[T], optimistic?: boolean) => Promise<void>\n\n// Action creator factory\nfunction createOptimisticAction<T extends keyof MediaActionPayloads>(\n\ttype: T,\n\tstore: EnhancedMediaStore\n): OptimisticActionCreator<T> {\n\treturn ((payload?: any, optimistic = false) => {\n\t\tconst action: OptimisticMediaAction = {\n\t\t\ttype,\n\t\t\tdetail: payload,\n\t\t\toptimistic,\n\t\t\ttimestamp: Date.now()\n\t\t}\n\n\t\tif (optimistic) {\n\t\t\treturn store.dispatchOptimistic(action)\n\t\t} else {\n\t\t\tstore.dispatch(action)\n\t\t\treturn Promise.resolve()\n\t\t}\n\t}) as OptimisticActionCreator<T>\n}\n\n// React 19 useActionState integration\nexport function useMediaActionState(store: EnhancedMediaStore) {\n\tconst [actionState, setActionState] = React.useState<MediaActionState>(store.getActionState())\n\n\t// Subscribe to action state changes\n\tReact.useEffect(() => {\n\t\tconst unsubscribe = store.subscribe(() => {\n\t\t\tconst newActionState = store.getActionState()\n\t\t\tsetActionState((current) =>\n\t\t\t\tJSON.stringify(current) !== JSON.stringify(newActionState) ? newActionState : current\n\t\t\t)\n\t\t})\n\t\treturn unsubscribe\n\t}, [store])\n\n\treturn actionState\n}\n\n// Media actions hook with React 19 optimistic updates\nexport function useMediaActions(store: EnhancedMediaStore) {\n\t// Create action creators with optimistic support\n\tconst actions = React.useMemo(\n\t\t() => ({\n\t\t\t// Playback actions\n\t\t\tplay: createOptimisticAction(MediaActionTypes.PLAY, store),\n\t\t\tpause: createOptimisticAction(MediaActionTypes.PAUSE, store),\n\t\t\tseek: createOptimisticAction(MediaActionTypes.SEEK, store),\n\n\t\t\t// Volume actions\n\t\t\tsetVolume: createOptimisticAction(MediaActionTypes.SET_VOLUME, store),\n\t\t\tmute: createOptimisticAction(MediaActionTypes.MUTE, store),\n\t\t\tunmute: createOptimisticAction(MediaActionTypes.UNMUTE, store),\n\t\t\ttoggleMute: createOptimisticAction(MediaActionTypes.TOGGLE_MUTE, store),\n\n\t\t\t// Media state actions\n\t\t\tsetDuration: createOptimisticAction(MediaActionTypes.SET_DURATION, store),\n\t\t\tsetCurrentTime: createOptimisticAction(MediaActionTypes.SET_CURRENT_TIME, store),\n\t\t\tsetBuffered: createOptimisticAction(MediaActionTypes.SET_BUFFERED, store),\n\t\t\tsetLoading: createOptimisticAction(MediaActionTypes.SET_LOADING, store),\n\t\t\tsetError: createOptimisticAction(MediaActionTypes.SET_ERROR, store),\n\n\t\t\t// Display actions\n\t\t\tenterFullscreen: createOptimisticAction(MediaActionTypes.ENTER_FULLSCREEN, store),\n\t\t\texitFullscreen: createOptimisticAction(MediaActionTypes.EXIT_FULLSCREEN, store),\n\t\t\tenterPiP: createOptimisticAction(MediaActionTypes.ENTER_PIP, store),\n\t\t\texitPiP: createOptimisticAction(MediaActionTypes.EXIT_PIP, store),\n\n\t\t\t// Advanced actions\n\t\t\tsetPlaybackRate: createOptimisticAction(MediaActionTypes.SET_PLAYBACK_RATE, store),\n\t\t\tsetSubtitleTrack: createOptimisticAction(MediaActionTypes.SET_SUBTITLE_TRACK, store),\n\t\t\tsetRendition: createOptimisticAction(MediaActionTypes.SET_RENDITION, store),\n\t\t\ttoggleSubtitles: createOptimisticAction(MediaActionTypes.TOGGLE_SUBTITLES, store),\n\n\t\t\t// Preview actions\n\t\t\tpreviewTime: createOptimisticAction(MediaActionTypes.PREVIEW_TIME, store),\n\t\t\tclearPreview: createOptimisticAction(MediaActionTypes.CLEAR_PREVIEW, store)\n\t\t}),\n\t\t[store]\n\t)\n\n\t// Get action state for loading/error handling\n\tconst actionState = useMediaActionState(store)\n\n\t// Convenience methods that commonly use optimistic updates\n\tconst optimisticActions = React.useMemo(\n\t\t() => ({\n\t\t\t// These actions benefit from immediate UI feedback\n\t\t\ttogglePlayPause: async (isPlaying: boolean) => {\n\t\t\t\tif (isPlaying) {\n\t\t\t\t\tawait actions.pause(true) // optimistic\n\t\t\t\t} else {\n\t\t\t\t\tawait actions.play(true) // optimistic\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tseekWithPreview: async (time: number) => {\n\t\t\t\t// Immediate preview update, then actual seek\n\t\t\t\tawait actions.previewTime(time, true)\n\t\t\t\tawait actions.seek(time, true)\n\t\t\t},\n\n\t\t\tadjustVolume: async (delta: number, currentVolume: number) => {\n\t\t\t\tconst newVolume = Math.max(0, Math.min(1, currentVolume + delta))\n\t\t\t\tawait actions.setVolume(newVolume, true)\n\t\t\t},\n\n\t\t\ttoggleFullscreenOptimistic: async (isFullscreen: boolean) => {\n\t\t\t\tif (isFullscreen) {\n\t\t\t\t\tawait actions.exitFullscreen(true)\n\t\t\t\t} else {\n\t\t\t\t\tawait actions.enterFullscreen(true)\n\t\t\t\t}\n\t\t\t}\n\t\t}),\n\t\t[actions]\n\t)\n\n\t// Retry failed action\n\tconst retryLastAction = React.useCallback(async () => {\n\t\tconst { lastAction } = actionState\n\t\tif (lastAction && actionState.error) {\n\t\t\tawait store.dispatchOptimistic({\n\t\t\t\t...lastAction,\n\t\t\t\tretryCount: (lastAction.retryCount || 0) + 1\n\t\t\t})\n\t\t}\n\t}, [store, actionState])\n\n\treturn {\n\t\t...actions,\n\t\t...optimisticActions,\n\t\tactionState,\n\t\tretryLastAction,\n\t\tisLoading: actionState.pending,\n\t\thasError: !!actionState.error,\n\t\terrorMessage: actionState.error,\n\t\tretryCount: actionState.retryCount\n\t}\n}\n","\"use client\"\n\nimport React, { useOptimistic } from \"react\"\nimport type { MediaState } from \"../context/media-context\"\nimport type { EnhancedMediaStore, OptimisticMediaAction } from \"../context/media-store\"\n\n// Optimistic update reducer function\nfunction optimisticMediaReducer(state: MediaState, action: OptimisticMediaAction): MediaState {\n\tif (!action.optimistic) return state\n\n\t// Apply immediate optimistic updates for better UX\n\tswitch (action.type) {\n\t\tcase \"PLAY\":\n\t\t\treturn { ...state, isPlaying: true, error: null }\n\n\t\tcase \"PAUSE\":\n\t\t\treturn { ...state, isPlaying: false }\n\n\t\tcase \"SEEK\":\n\t\t\treturn { ...state, currentTime: action.detail }\n\n\t\tcase \"SET_VOLUME\":\n\t\t\treturn { ...state, volume: Math.max(0, Math.min(1, action.detail)) }\n\n\t\tcase \"MUTE\":\n\t\t\treturn { ...state, isMuted: true }\n\n\t\tcase \"UNMUTE\":\n\t\t\treturn { ...state, isMuted: false }\n\n\t\tcase \"TOGGLE_MUTE\":\n\t\t\treturn { ...state, isMuted: !state.isMuted }\n\n\t\tcase \"ENTER_FULLSCREEN\":\n\t\t\treturn { ...state, isFullscreen: true }\n\n\t\tcase \"EXIT_FULLSCREEN\":\n\t\t\treturn { ...state, isFullscreen: false }\n\n\t\tcase \"SET_PLAYBACK_RATE\":\n\t\t\treturn { ...state, playbackRate: action.detail }\n\n\t\tcase \"TOGGLE_SUBTITLES\":\n\t\t\treturn { ...state, subtitlesShowing: !state.subtitlesShowing }\n\n\t\tcase \"PREVIEW_TIME\":\n\t\t\treturn { ...state, previewTime: action.detail }\n\n\t\tcase \"CLEAR_PREVIEW\":\n\t\t\treturn {\n\t\t\t\t...state,\n\t\t\t\tpreviewTime: null,\n\t\t\t\tpreviewImage: null,\n\t\t\t\tpreviewCoords: null\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn state\n\t}\n}\n\n// Media optimistic state hook using React 19's useOptimistic\nexport function useMediaOptimistic(store: EnhancedMediaStore) {\n\tconst actualState = React.useSyncExternalStore(store.subscribe, store.getState, store.getState)\n\n\tconst [optimisticState, addOptimistic] = useOptimistic(actualState, optimisticMediaReducer)\n\n\t// Enhanced dispatch that uses optimistic updates\n\tconst dispatchOptimistic = React.useCallback(\n\t\tasync (action: OptimisticMediaAction) => {\n\t\t\t// Add optimistic update immediately\n\t\t\tif (action.optimistic) {\n\t\t\t\taddOptimistic(action)\n\t\t\t}\n\n\t\t\t// Dispatch the actual action\n\t\t\tawait store.dispatchOptimistic(action)\n\t\t},\n\t\t[store, addOptimistic]\n\t)\n\n\t// Quick actions with optimistic updates\n\tconst optimisticActions = React.useMemo(\n\t\t() => ({\n\t\t\t// Play/Pause with immediate feedback\n\t\t\ttogglePlayPause: async () => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: optimisticState.isPlaying ? \"PAUSE\" : \"PLAY\",\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Volume control with immediate slider feedback\n\t\t\tsetVolumeOptimistic: async (volume: number) => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"SET_VOLUME\",\n\t\t\t\t\tdetail: Math.max(0, Math.min(1, volume)),\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Seek with immediate scrub feedback\n\t\t\tseekOptimistic: async (time: number) => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"SEEK\",\n\t\t\t\t\tdetail: time,\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Mute toggle with immediate icon change\n\t\t\ttoggleMuteOptimistic: async () => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"TOGGLE_MUTE\",\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Fullscreen toggle with immediate layout change\n\t\t\ttoggleFullscreenOptimistic: async () => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: optimisticState.isFullscreen ? \"EXIT_FULLSCREEN\" : \"ENTER_FULLSCREEN\",\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Playback rate with immediate feedback\n\t\t\tsetPlaybackRateOptimistic: async (rate: number) => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"SET_PLAYBACK_RATE\",\n\t\t\t\t\tdetail: rate,\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t},\n\n\t\t\t// Subtitle toggle with immediate visibility change\n\t\t\ttoggleSubtitlesOptimistic: async () => {\n\t\t\t\tconst action: OptimisticMediaAction = {\n\t\t\t\t\ttype: \"TOGGLE_SUBTITLES\",\n\t\t\t\t\toptimistic: true,\n\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t}\n\t\t\t\tawait dispatchOptimistic(action)\n\t\t\t}\n\t\t}),\n\t\t[optimisticState, dispatchOptimistic]\n\t)\n\n\t// State selectors that return optimistic values\n\tconst selectors = React.useMemo(\n\t\t() => ({\n\t\t\tisPlaying: optimisticState.isPlaying,\n\t\t\tcurrentTime: optimisticState.currentTime,\n\t\t\tvolume: optimisticState.volume,\n\t\t\tisMuted: optimisticState.isMuted,\n\t\t\tisFullscreen: optimisticState.isFullscreen,\n\t\t\tplaybackRate: optimisticState.playbackRate,\n\t\t\tsubtitlesShowing: optimisticState.subtitlesShowing,\n\t\t\tpreviewTime: optimisticState.previewTime,\n\n\t\t\t// Computed values\n\t\t\tprogress:\n\t\t\t\toptimisticState.duration > 0 ? optimisticState.currentTime / optimisticState.duration : 0,\n\n\t\t\tformattedTime: formatTime(optimisticState.currentTime),\n\t\t\tformattedDuration: formatTime(optimisticState.duration),\n\n\t\t\t// State checks\n\t\t\tcanPlay: !optimisticState.isLoading && !optimisticState.error,\n\t\t\thasError: !!optimisticState.error,\n\t\t\tisBuffering: optimisticState.isLoading\n\t\t}),\n\t\t[optimisticState]\n\t)\n\n\treturn {\n\t\tstate: optimisticState,\n\t\tactualState,\n\t\t...selectors,\n\t\t...optimisticActions,\n\t\tdispatchOptimistic\n\t}\n}\n\n// Time formatting utility\nfunction formatTime(seconds: number): string {\n\tif (!seconds || !isFinite(seconds)) return \"0:00\"\n\n\tconst mins = Math.floor(seconds / 60)\n\tconst secs = Math.floor(seconds % 60)\n\tconst hours = Math.floor(mins / 60)\n\n\tif (hours > 0) {\n\t\treturn `${hours}:${String(mins % 60).padStart(2, \"0\")}:${String(secs).padStart(2, \"0\")}`\n\t}\n\n\treturn `${mins}:${String(secs).padStart(2, \"0\")}`\n}\n\n// Hook for components that need to detect optimistic updates\nexport function useOptimisticUpdates(store: EnhancedMediaStore) {\n\tconst [hasOptimisticUpdates, setHasOptimisticUpdates] = React.useState(false)\n\n\tReact.useEffect(() => {\n\t\tconst unsubscribe = store.subscribe(() => {\n\t\t\tconst actualState = store.getState()\n\t\t\tconst optimisticState = store.getOptimisticState()\n\n\t\t\tconst hasUpdates = JSON.stringify(actualState) !== JSON.stringify(optimisticState)\n\t\t\tsetHasOptimisticUpdates(hasUpdates)\n\t\t})\n\n\t\treturn unsubscribe\n\t}, [store])\n\n\treturn hasOptimisticUpdates\n}\n\n// Hook to get both actual and optimistic state for debugging\nexport function useMediaStateComparison(store: EnhancedMediaStore) {\n\tconst actualState = React.useSyncExternalStore(store.subscribe, store.getState, store.getState)\n\n\tconst optimisticState = React.useSyncExternalStore(\n\t\tstore.subscribe,\n\t\tstore.getOptimisticState,\n\t\tstore.getOptimisticState\n\t)\n\n\tconst differences = React.useMemo(() => {\n\t\tconst diffs: any[] = []\n\n\t\tconst stateKeys = Object.keys(actualState) as Array<keyof MediaState>\n\t\tstateKeys.forEach((key) => {\n\t\t\tif (JSON.stringify(actualState[key]) !== JSON.stringify(optimisticState[key])) {\n\t\t\t\tdiffs.push({\n\t\t\t\t\tkey: key as string,\n\t\t\t\t\tactual: actualState[key],\n\t\t\t\t\toptimistic: optimisticState[key]\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\n\t\treturn diffs\n\t}, [actualState, optimisticState])\n\n\treturn {\n\t\tactualState,\n\t\toptimisticState,\n\t\tdifferences,\n\t\thasOptimisticUpdates: differences.length > 0\n\t}\n}\n","\"use client\"\n\nimport React, {\n\tuseCallback,\n\tuseEffect,\n\tuseRef,\n\tuseMemo,\n\tuseTransition,\n\tuseOptimistic,\n\tuseActionState\n} from \"react\"\nimport { useMediaSelector, useMediaStore } from \"../context/media-context\"\nimport type { EnhancedMediaStore } from \"../context/media-store\"\nimport type { MediaPlayerControls, MediaPlayerState } from \"../types/index\"\nimport { useMediaActions } from \"./use-media-actions\"\nimport { useMediaOptimistic } from \"./use-media-optimistic\"\n\ninterface UseEnhancedMediaPlayerOptions {\n\tsrc: string | string[]\n\tautoPlay?: boolean\n\tloop?: boolean\n\tmuted?: boolean\n\tvolume?: number\n\tpreload?: \"none\" | \"metadata\" | \"auto\"\n\tcrossOrigin?: \"anonymous\" | \"use-credentials\"\n\tplaybackRates?: number[]\n\tkeyboardControls?: boolean\n\tshowControls?: boolean\n\tcustomControls?: boolean\n\tenablePerformanceMonitoring?: boolean\n\tbufferingStrategy?: \"aggressive\" | \"conservative\" | \"adaptive\"\n\t// Performance optimizations\n\tenableTimeUpdateThrottling?: boolean\n\ttimeUpdateThrottleMs?: number\n\tenableSeekPreview?: boolean\n\tpreloadStrategy?: \"eager\" | \"lazy\" | \"progressive\"\n}\n\n// Performance-optimized media player hook with React 19 features\nexport function useEnhancedMediaPlayer(options: UseEnhancedMediaPlayerOptions) {\n\tconst mediaRef = useRef<HTMLVideoElement | HTMLAudioElement>(null)\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\n\t// React 19 concurrent features\n\tconst [isPending, startTransition] = useTransition()\n\tconst [isSeeking, startSeekTransition] = useTransition()\n\n\t// Performance monitoring\n\tconst renderStartTime = React.useRef<number>(0)\n\tconst frameCount = React.useRef<number>(0)\n\tconst lastFrameTime = React.useRef<number>(0)\n\n\t// Throttled time update\n\tconst timeUpdateTimeoutRef = useRef<NodeJS.Timeout>()\n\tconst lastTimeUpdate = useRef<number>(0)\n\n\t// Store integration\n\tconst store = useMediaStore()\n\tconst isEnhanced = \"getOptimisticState\" in store\n\n\t// Select only the state we need to minimize re-renders\n\tconst isPlaying = useMediaSelector((state) => state.isPlaying)\n\tconst currentTime = useMediaSelector((state) => state.currentTime)\n\tconst duration = useMediaSelector((state) => state.duration)\n\tconst volume = useMediaSelector((state) => state.volume)\n\tconst isMuted = useMediaSelector((state) => state.isMuted)\n\tconst isLoading = useMediaSelector((state) => state.isLoading)\n\tconst isBuffering = useMediaSelector((state) => state.isBuffering)\n\tconst error = useMediaSelector((state) => state.error)\n\tconst buffered = useMediaSelector((state) => state.buffered)\n\tconst isFullscreen = useMediaSelector((state) => state.isFullscreen)\n\n\t// Enhanced features - always call hooks unconditionally\n\tconst enhancedStore = store as unknown as EnhancedMediaStore\n\tconst optimisticState = useMediaOptimistic(enhancedStore)\n\tconst actions = useMediaActions(enhancedStore)\n\n\t// Performance state\n\tconst [performanceMetrics, setPerformanceMetrics] = React.useState({\n\t\tframeRate: 0,\n\t\taverageRenderTime: 0,\n\t\tdroppedFrames: 0,\n\t\tbufferHealth: 0\n\t})\n\n\t// Optimistic state updates for immediate UI feedback\n\tconst [optimisticVolume, setOptimisticVolume] = useOptimistic(\n\t\tvolume,\n\t\t(state, newVolume: number) => {\n\t\t\treturn Math.max(0, Math.min(1, newVolume))\n\t\t}\n\t)\n\n\tconst [optimisticTime, setOptimisticTime] = useOptimistic(\n\t\tcurrentTime,\n\t\t(state, newTime: number) => {\n\t\t\treturn Math.max(0, Math.min(duration || 0, newTime))\n\t\t}\n\t)\n\n\t// Initialize media element with performance optimizations\n\tuseEffect(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\t// Set initial properties\n\t\tconst initProps = {\n\t\t\tvolume: options.volume,\n\t\t\tmuted: options.muted,\n\t\t\tautoplay: options.autoPlay,\n\t\t\tloop: options.loop,\n\t\t\tpreload: options.preload,\n\t\t\tcrossOrigin: options.crossOrigin\n\t\t}\n\n\t\tObject.entries(initProps).forEach(([key, value]) => {\n\t\t\tif (value !== undefined) {\n\t\t\t\t;(media as any)[key] = value\n\t\t\t}\n\t\t})\n\n\t\t// Performance optimizations\n\t\tmedia.setAttribute(\"preload\", options.preloadStrategy === \"eager\" ? \"auto\" : \"metadata\")\n\n\t\tif (options.bufferingStrategy === \"aggressive\") {\n\t\t\tmedia.setAttribute(\"buffered\", \"auto\")\n\t\t}\n\n\t\t// Hardware acceleration\n\t\tif (media instanceof HTMLVideoElement) {\n\t\t\tmedia.style.willChange = \"transform\"\n\t\t\tmedia.style.transform = \"translateZ(0)\"\n\t\t}\n\t}, [\n\t\toptions.volume,\n\t\toptions.muted,\n\t\toptions.autoPlay,\n\t\toptions.loop,\n\t\toptions.preload,\n\t\toptions.crossOrigin,\n\t\toptions.preloadStrategy,\n\t\toptions.bufferingStrategy\n\t])\n\n\t// Optimized event handlers with React 19 patterns\n\tconst handleTimeUpdate = useCallback(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tconst now = performance.now()\n\n\t\t// Throttle time updates for performance\n\t\tif (options.enableTimeUpdateThrottling !== false) {\n\t\t\tif (now - lastTimeUpdate.current < (options.timeUpdateThrottleMs || 100)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tlastTimeUpdate.current = now\n\t\t}\n\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.setCurrentTime(media.currentTime)\n\t\t\t}\n\t\t})\n\t}, [options.enableTimeUpdateThrottling, options.timeUpdateThrottleMs, isEnhanced, actions])\n\n\tconst handlePlay = useCallback(() => {\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.play(true) // Optimistic update\n\t\t\t}\n\t\t})\n\t\toptions.onPlay?.()\n\t}, [isEnhanced, actions, options.onPlay])\n\n\tconst handlePause = useCallback(() => {\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.pause(true) // Optimistic update\n\t\t\t}\n\t\t})\n\t\toptions.onPause?.()\n\t}, [isEnhanced, actions, options.onPause])\n\n\tconst handleVolumeChange = useCallback(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.setVolume(media.volume, true) // Optimistic update\n\t\t\t\tmedia.muted ? actions.mute(true) : actions.unmute(true)\n\t\t\t}\n\t\t})\n\t}, [isEnhanced, actions])\n\n\tconst handleSeeking = useCallback(() => {\n\t\tstartSeekTransition(() => {\n\t\t\t// Seek operations get their own transition\n\t\t})\n\t}, [])\n\n\tconst handleSeeked = useCallback(() => {\n\t\t// Seek completed\n\t}, [])\n\n\tconst handleProgress = useCallback(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tstartTransition(() => {\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.setBuffered(media.buffered)\n\t\t\t}\n\t\t})\n\t}, [isEnhanced, actions])\n\n\t// Performance monitoring\n\tconst measureRenderTime = useCallback(() => {\n\t\tconst now = performance.now()\n\t\tconst deltaTime = now - lastFrameTime.current\n\n\t\tif (deltaTime > 0) {\n\t\t\tframeCount.current++\n\n\t\t\t// Calculate frame rate every second\n\t\t\tif (frameCount.current >= 60) {\n\t\t\t\tconst fps = Math.round((frameCount.current * 1000) / (now - lastFrameTime.current))\n\t\t\t\tsetPerformanceMetrics((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tframeRate: fps,\n\t\t\t\t\tdroppedFrames: Math.max(0, 60 - fps)\n\t\t\t\t}))\n\t\t\t\tframeCount.current = 0\n\t\t\t\tlastFrameTime.current = now\n\t\t\t}\n\t\t}\n\t}, [])\n\n\t// Attach event listeners with performance optimization\n\tuseEffect(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\t// Use passive listeners where possible for better performance\n\t\tconst eventListeners = [\n\t\t\t{ event: \"timeupdate\", handler: handleTimeUpdate, passive: true },\n\t\t\t{ event: \"play\", handler: handlePlay },\n\t\t\t{ event: \"pause\", handler: handlePause },\n\t\t\t{ event: \"volumechange\", handler: handleVolumeChange },\n\t\t\t{ event: \"seeking\", handler: handleSeeking },\n\t\t\t{ event: \"seeked\", handler: handleSeeked },\n\t\t\t{ event: \"progress\", handler: handleProgress, passive: true },\n\t\t\t{ event: \"loadedmetadata\", handler: () => measureRenderTime() },\n\t\t\t{ event: \"loadeddata\", handler: () => measureRenderTime() }\n\t\t]\n\n\t\teventListeners.forEach(({ event, handler, passive }) => {\n\t\t\tconst options = passive ? { passive: true } : {}\n\t\t\tmedia.addEventListener(event, handler, options)\n\t\t})\n\n\t\t// Performance monitoring frame loop\n\t\tlet rafId: number\n\t\tconst performanceLoop = () => {\n\t\t\tmeasureRenderTime()\n\t\t\trafId = requestAnimationFrame(performanceLoop)\n\t\t}\n\n\t\tif (options.enablePerformanceMonitoring) {\n\t\t\tperformanceLoop()\n\t\t}\n\n\t\treturn () => {\n\t\t\teventListeners.forEach(({ event, handler }) => {\n\t\t\t\tmedia.removeEventListener(event, handler)\n\t\t\t})\n\t\t\tif (rafId) {\n\t\t\t\tcancelAnimationFrame(rafId)\n\t\t\t}\n\t\t}\n\t}, [\n\t\thandleTimeUpdate,\n\t\thandlePlay,\n\t\thandlePause,\n\t\thandleVolumeChange,\n\t\thandleSeeking,\n\t\thandleSeeked,\n\t\thandleProgress,\n\t\tmeasureRenderTime,\n\t\toptions.enablePerformanceMonitoring\n\t])\n\n\t// Optimized control functions with React 19 features\n\tconst controls = useMemo(() => {\n\t\tconst play = async () => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tawait actions.play(true) // Optimistic\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tawait media.play()\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"Failed to play media:\", error)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst pause = () => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.pause(true) // Optimistic\n\t\t\t} else {\n\t\t\t\tmedia.pause()\n\t\t\t}\n\t\t}\n\n\t\tconst toggle = () => {\n\t\t\tif (isPlaying) {\n\t\t\t\tpause()\n\t\t\t} else {\n\t\t\t\tplay()\n\t\t\t}\n\t\t}\n\n\t\tconst seek = (time: number) => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tconst clampedTime = Math.max(0, Math.min(time, duration || 0))\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tstartSeekTransition(() => {\n\t\t\t\t\tactions.seek(clampedTime, true) // Optimistic\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tmedia.currentTime = clampedTime\n\t\t\t}\n\t\t}\n\n\t\tconst setVolume = (volume: number) => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tconst clampedVolume = Math.max(0, Math.min(1, volume))\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tsetOptimisticVolume(clampedVolume)\n\t\t\t\tstartTransition(() => {\n\t\t\t\t\tactions.setVolume(clampedVolume, true)\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tmedia.volume = clampedVolume\n\t\t\t}\n\t\t}\n\n\t\tconst toggleMute = () => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return\n\n\t\t\tif (isEnhanced && actions) {\n\t\t\t\tactions.toggleMute(true) // Optimistic\n\t\t\t} else {\n\t\t\t\tmedia.muted = !media.muted\n\t\t\t}\n\t\t}\n\n\t\tconst enterFullscreen = async () => {\n\t\t\tconst container = containerRef.current\n\t\t\tif (!container || !document.fullscreenEnabled) return\n\n\t\t\ttry {\n\t\t\t\tawait container.requestFullscreen()\n\t\t\t\tif (isEnhanced && actions) {\n\t\t\t\t\tactions.enterFullscreen(true)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to enter fullscreen:\", error)\n\t\t\t}\n\t\t}\n\n\t\tconst exitFullscreen = async () => {\n\t\t\tif (!document.fullscreenElement) return\n\n\t\t\ttry {\n\t\t\t\tawait document.exitFullscreen()\n\t\t\t\tif (isEnhanced && actions) {\n\t\t\t\t\tactions.exitFullscreen(true)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to exit fullscreen:\", error)\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tplay,\n\t\t\tpause,\n\t\t\ttoggle,\n\t\t\tseek,\n\t\t\tsetVolume,\n\t\t\ttoggleMute,\n\t\t\tenterFullscreen,\n\t\t\texitFullscreen\n\t\t}\n\t}, [\n\t\tisPlaying,\n\t\tduration,\n\t\tisEnhanced,\n\t\tactions,\n\t\tstartTransition,\n\t\tstartSeekTransition,\n\t\tsetOptimisticVolume\n\t])\n\n\t// Computed state\n\tconst computedState = useMemo(\n\t\t() => ({\n\t\t\tisPlaying: optimisticState?.isPlaying ?? isPlaying,\n\t\t\tcurrentTime: optimisticState?.currentTime ?? currentTime,\n\t\t\tduration: optimisticState?.duration ?? duration,\n\t\t\tvolume: optimisticState?.volume ?? optimisticVolume,\n\t\t\tisMuted: optimisticState?.isMuted ?? isMuted,\n\t\t\tisLoading: optimisticState?.isBuffering ?? isLoading,\n\t\t\tisBuffering: optimisticState?.isBuffering ?? isBuffering,\n\t\t\terror: optimisticState?.error ?? error,\n\t\t\tbuffered: optimisticState?.buffered ?? buffered,\n\t\t\tisFullscreen: optimisticState?.isFullscreen ?? isFullscreen,\n\t\t\tprogress: duration > 0 ? currentTime / duration : 0,\n\t\t\tisTransitioning: isPending || isSeeking,\n\t\t\tcanPlay: !isLoading && !isBuffering && !error\n\t\t}),\n\t\t[\n\t\t\toptimisticState,\n\t\t\tisPlaying,\n\t\t\tcurrentTime,\n\t\t\tduration,\n\t\t\toptimisticVolume,\n\t\t\tisMuted,\n\t\t\tisLoading,\n\t\t\tisBuffering,\n\t\t\terror,\n\t\t\tbuffered,\n\t\t\tisFullscreen,\n\t\t\tisPending,\n\t\t\tisSeeking\n\t\t]\n\t)\n\n\treturn {\n\t\t// Refs\n\t\tmediaRef,\n\t\tcontainerRef,\n\n\t\t// State\n\t\tstate: computedState,\n\t\tactualState: optimisticState?.actualState,\n\n\t\t// Controls\n\t\tcontrols,\n\n\t\t// Performance metrics\n\t\tperformanceMetrics,\n\t\tisTransitioning: isPending || isSeeking,\n\n\t\t// Enhanced features\n\t\tactions: optimisticState?.actions,\n\t\tactionState: optimisticState?.actionState,\n\n\t\t// Optimistic features\n\t\toptimisticState,\n\t\tisEnhanced\n\t}\n}\n","\"use client\"\n\nimport { useCallback, useEffect } from \"react\"\nimport type { MediaPlayerControls, MediaPlayerState } from \"../types/index\"\n\ninterface UseKeyboardControlsOptions {\n\tenabled?: boolean\n\tstate: MediaPlayerState\n\tcontrols: MediaPlayerControls\n\tseekStep?: number // seconds to seek forward/backward\n\tvolumeStep?: number // volume step (0-1)\n}\n\nexport function useKeyboardControls({\n\tenabled = true,\n\tstate,\n\tcontrols,\n\tseekStep = 10,\n\tvolumeStep = 0.1\n}: UseKeyboardControlsOptions) {\n\tconst handleKeyDown = (event: KeyboardEvent) => {\n\t\tif (!enabled) return\n\n\t\t// Don't handle keyboard events if user is typing in an input\n\t\tconst target = event.target as HTMLElement\n\t\tif (\n\t\t\ttarget.tagName === \"INPUT\" ||\n\t\t\ttarget.tagName === \"TEXTAREA\" ||\n\t\t\ttarget.contentEditable === \"true\"\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tswitch (event.code) {\n\t\t\tcase \"Space\":\n\t\t\tcase \"KeyK\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.toggle()\n\t\t\t\tbreak\n\n\t\t\tcase \"KeyM\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.toggleMute()\n\t\t\t\tbreak\n\n\t\t\tcase \"KeyF\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.toggleFullscreen()\n\t\t\t\tbreak\n\n\t\t\tcase \"ArrowLeft\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.seek(Math.max(0, state.currentTime - seekStep))\n\t\t\t\tbreak\n\n\t\t\tcase \"ArrowRight\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.seek(Math.min(state.duration, state.currentTime + seekStep))\n\t\t\t\tbreak\n\n\t\t\tcase \"ArrowUp\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.setVolume(Math.min(1, state.volume + volumeStep))\n\t\t\t\tbreak\n\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.setVolume(Math.max(0, state.volume - volumeStep))\n\t\t\t\tbreak\n\n\t\t\tcase \"Digit0\":\n\t\t\tcase \"Digit1\":\n\t\t\tcase \"Digit2\":\n\t\t\tcase \"Digit3\":\n\t\t\tcase \"Digit4\":\n\t\t\tcase \"Digit5\":\n\t\t\tcase \"Digit6\":\n\t\t\tcase \"Digit7\":\n\t\t\tcase \"Digit8\":\n\t\t\tcase \"Digit9\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tconst digit = parseInt(event.code.replace(\"Digit\", \"\"), 10)\n\t\t\t\tconst percentage = digit / 10\n\t\t\t\tcontrols.seek(state.duration * percentage)\n\t\t\t\tbreak\n\n\t\t\tcase \"Home\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.seek(0)\n\t\t\t\tbreak\n\n\t\t\tcase \"End\":\n\t\t\t\tevent.preventDefault()\n\t\t\t\tcontrols.seek(state.duration)\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\t// Don't prevent default for unhandled keys\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tuseEffect(() => {\n\t\tif (!enabled) return\n\n\t\tdocument.addEventListener(\"keydown\", handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"keydown\", handleKeyDown)\n\t\t}\n\t}, [enabled, handleKeyDown])\n\n\treturn {\n\t\thandleKeyDown\n\t}\n}\n","\"use client\"\n\nimport React, { useEffect, useRef, useCallback, useMemo } from \"react\"\n\n// Memory optimization hook for media players\nexport function useMemoryOptimization(\n\toptions: {\n\t\tmaxMemoryUsage?: number // in MB\n\t\tcleanupInterval?: number // in ms\n\t\tenableGC?: boolean\n\t\tmonitorMemory?: boolean\n\t} = {}\n) {\n\tconst {\n\t\tmaxMemoryUsage = 100, // 100MB default\n\t\tcleanupInterval = 30000, // 30 seconds default\n\t\tenableGC = true,\n\t\tmonitorMemory = true\n\t} = options\n\n\tconst cleanupTimeoutRef = useRef<NodeJS.Timeout>()\n\tconst observersRef = useRef<Set<MutationObserver>>(new Set())\n\tconst eventListenersRef = useRef<Map<Element, Array<{ event: string; handler: EventListener }>>>(\n\t\tnew Map()\n\t)\n\tconst intervalRefs = useRef<Set<NodeJS.Timeout>>(new Set())\n\tconst animationFrameRefs = useRef<Set<number>>(new Set())\n\n\t// Get current memory usage\n\tconst getMemoryUsage = useCallback(() => {\n\t\tif (typeof window === \"undefined\" || !(\"memory\" in performance)) {\n\t\t\treturn { used: 0, total: 0, limit: 0 }\n\t\t}\n\n\t\tconst memory = (performance as any).memory\n\t\treturn {\n\t\t\tused: memory.usedJSHeapSize,\n\t\t\ttotal: memory.totalJSHeapSize,\n\t\t\tlimit: memory.jsHeapSizeLimit\n\t\t}\n\t}, [])\n\n\t// Memory monitoring state\n\tconst [memoryStats, setMemoryStats] = React.useState({\n\t\tused: 0,\n\t\ttotal: 0,\n\t\tlimit: 0,\n\t\tusage: 0,\n\t\tisHighUsage: false\n\t})\n\n\t// Cleanup function (must be declared before use)\n\tconst performCleanup = useCallback(() => {\n\t\t// Clear all timeouts\n\t\tintervalRefs.current.forEach((timeout) => {\n\t\t\tclearTimeout(timeout)\n\t\t})\n\t\tintervalRefs.current.clear()\n\n\t\t// Cancel all animation frames\n\t\tanimationFrameRefs.current.forEach((frameId) => {\n\t\t\tcancelAnimationFrame(frameId)\n\t\t})\n\t\tanimationFrameRefs.current.clear()\n\n\t\t// Disconnect all observers\n\t\tobserversRef.current.forEach((observer) => {\n\t\t\tobserver.disconnect()\n\t\t})\n\t\tobserversRef.current.clear()\n\n\t\t// Remove all event listeners\n\t\teventListenersRef.current.forEach((listeners, element) => {\n\t\t\tlisteners.forEach(({ event, handler }) => {\n\t\t\t\telement.removeEventListener(event, handler)\n\t\t\t})\n\t\t})\n\t\teventListenersRef.current.clear()\n\n\t\t// Force garbage collection if available\n\t\tif (typeof window !== \"undefined\" && \"gc\" in window) {\n\t\t\t;(window as any).gc()\n\t\t}\n\t}, [])\n\n\t// Safe interval management (must be declared before use)\n\tconst useInterval = useCallback((callback: () => void, delay: number) => {\n\t\tconst timeoutId = setInterval(callback, delay)\n\t\tintervalRefs.current.add(timeoutId)\n\n\t\treturn () => {\n\t\t\tclearInterval(timeoutId)\n\t\t\tintervalRefs.current.delete(timeoutId)\n\t\t}\n\t}, [])\n\n\t// Memory monitoring\n\tuseEffect(() => {\n\t\tif (!monitorMemory) return\n\n\t\tconst checkMemory = () => {\n\t\t\tconst memory = getMemoryUsage()\n\t\t\tconst usage = memory.used / 1024 / 1024 // Convert to MB\n\t\t\tconst isHighUsage = usage > maxMemoryUsage\n\n\t\t\tsetMemoryStats({\n\t\t\t\t...memory,\n\t\t\t\tusage,\n\t\t\t\tisHighUsage\n\t\t\t})\n\n\t\t\t// Trigger cleanup if memory usage is high\n\t\t\tif (isHighUsage && enableGC) {\n\t\t\t\tperformCleanup()\n\t\t\t}\n\t\t}\n\n\t\tcheckMemory()\n\t\treturn useInterval(checkMemory, cleanupInterval)\n\t}, [monitorMemory, getMemoryUsage, maxMemoryUsage, enableGC, cleanupInterval, performCleanup])\n\n\t// Safe event listener management\n\tconst addEventListener = useCallback(\n\t\t(\n\t\t\telement: Element,\n\t\t\tevent: string,\n\t\t\thandler: EventListener,\n\t\t\toptions?: AddEventListenerOptions\n\t\t) => {\n\t\t\telement.addEventListener(event, handler, options)\n\n\t\t\tif (!eventListenersRef.current.has(element)) {\n\t\t\t\teventListenersRef.current.set(element, [])\n\t\t\t}\n\t\t\teventListenersRef.current.get(element)!.push({ event, handler })\n\n\t\t\t// Return cleanup function\n\t\t\treturn () => {\n\t\t\t\telement.removeEventListener(event, handler)\n\t\t\t\tconst listeners = eventListenersRef.current.get(element)\n\t\t\t\tif (listeners) {\n\t\t\t\t\tconst index = listeners.findIndex((l) => l.event === event && l.handler === handler)\n\t\t\t\t\tif (index > -1) {\n\t\t\t\t\t\tlisteners.splice(index, 1)\n\t\t\t\t\t}\n\t\t\t\t\tif (listeners.length === 0) {\n\t\t\t\t\t\teventListenersRef.current.delete(element)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[]\n\t)\n\n\t// Safe timeout management\n\tconst setTimeout = useCallback((callback: () => void, delay: number) => {\n\t\tconst timeoutId = setTimeout(callback, delay)\n\t\tintervalRefs.current.add(timeoutId)\n\n\t\treturn () => {\n\t\t\tclearTimeout(timeoutId)\n\t\t\tintervalRefs.current.delete(timeoutId)\n\t\t}\n\t}, [])\n\n\t// Safe animation frame management\n\tconst requestAnimationFrame = useCallback((callback: FrameRequestCallback) => {\n\t\tconst frameId = requestAnimationFrame(callback)\n\t\tanimationFrameRefs.current.add(frameId)\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(frameId)\n\t\t\tanimationFrameRefs.current.delete(frameId)\n\t\t}\n\t}, [])\n\n\t// Safe observer management\n\tconst addObserver = useCallback((observer: MutationObserver) => {\n\t\tobserversRef.current.add(observer)\n\n\t\treturn () => {\n\t\t\tobserver.disconnect()\n\t\t\tobserversRef.current.delete(observer)\n\t\t}\n\t}, [])\n\n\t// Cleanup on unmount\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tperformCleanup()\n\t\t}\n\t}, [performCleanup])\n\n\treturn {\n\t\t// Memory stats\n\t\tmemoryStats,\n\t\tgetMemoryUsage,\n\n\t\t// Cleanup functions\n\t\tperformCleanup,\n\n\t\t// Safe API functions\n\t\taddEventListener,\n\t\tsetInterval,\n\t\tsetTimeout,\n\t\trequestAnimationFrame,\n\t\taddObserver,\n\n\t\t// Utilities\n\t\tformatBytes: (bytes: number) => {\n\t\t\tif (bytes === 0) return \"0 Bytes\"\n\t\t\tconst k = 1024\n\t\t\tconst sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"]\n\t\t\tconst i = Math.floor(Math.log(bytes) / Math.log(k))\n\t\t\treturn parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + \" \" + sizes[i]\n\t\t}\n\t}\n}\n\n// Resource cleanup hook for media elements\nexport function useMediaResourceCleanup(\n\tmediaRef: React.RefObject<HTMLVideoElement | HTMLAudioElement>\n) {\n\tconst { addEventListener, performCleanup } = useMemoryOptimization()\n\n\t// Track resource cleanup\n\tconst cleanupResources = useCallback(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\t// Stop media playback\n\t\tif (!media.paused) {\n\t\t\t_media.pause()\n\t\t}\n\n\t\t// Clear source\n\t\tif (media.src) {\n\t\t\tmedia.src = \"\"\n\t\t\tmedia.load()\n\t\t}\n\n\t\t// Remove source elements\n\t\twhile (media.firstChild) {\n\t\t\tmedia.removeChild(media.firstChild)\n\t\t}\n\n\t\t// Clear any pending seeks\n\t\tmedia.currentTime = 0\n\n\t\t// Clear buffered data\n\t\tif (\"clearBuffered\" in media) {\n\t\t\t;(media as any).clearBuffered()\n\t\t}\n\t}, [mediaRef])\n\n\t// Enhanced event listener registration\n\tconst registerMediaEventListener = useCallback(\n\t\t(event: string, handler: EventListener, options?: AddEventListenerOptions) => {\n\t\t\tconst media = mediaRef.current\n\t\t\tif (!media) return () => {}\n\n\t\t\treturn addEventListener(media, event, handler, options)\n\t\t},\n\t\t[mediaRef, addEventListener]\n\t)\n\n\t// Cleanup on unmount\n\tuseEffect(() => {\n\t\treturn cleanupResources\n\t}, [cleanupResources])\n\n\treturn {\n\t\tcleanupResources,\n\t\tregisterMediaEventListener\n\t}\n}\n\n// Performance monitoring hook\nexport function usePerformanceMonitoring() {\n\tconst [metrics, setMetrics] = React.useState({\n\t\tfps: 0,\n\t\tframeDrops: 0,\n\t\tlongTasks: 0,\n\t\ttotalLongTaskDuration: 0\n\t})\n\n\tconst frameCountRef = useRef(0)\n\tconst lastFrameTimeRef = useRef(performance.now())\n\tconst longTaskObserverRef = useRef<PerformanceObserver>()\n\n\t// FPS monitoring\n\tuseEffect(() => {\n\t\tlet rafId: number\n\n\t\tconst measureFrame = () => {\n\t\t\tframeCountRef.current++\n\t\t\tconst now = performance.now()\n\n\t\t\t// Calculate FPS every second\n\t\t\tif (now - lastFrameTimeRef.current >= 1000) {\n\t\t\t\tconst fps = Math.round((frameCountRef.current * 1000) / (now - lastFrameTimeRef.current))\n\t\t\t\tconst expectedFrames = Math.round((now - lastFrameTimeRef.current) / 16.67) // 60fps\n\t\t\t\tconst frameDrops = Math.max(0, expectedFrames - frameCountRef.current)\n\n\t\t\t\tsetMetrics((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tfps,\n\t\t\t\t\tframeDrops: prev.frameDrops + frameDrops\n\t\t\t\t}))\n\n\t\t\t\tframeCountRef.current = 0\n\t\t\t\tlastFrameTimeRef.current = now\n\t\t\t}\n\n\t\t\trafId = requestAnimationFrame(measureFrame)\n\t\t}\n\n\t\trafId = requestAnimationFrame(measureFrame)\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(rafId)\n\t\t}\n\t}, [])\n\n\t// Long task monitoring\n\tuseEffect(() => {\n\t\tif (!(\"PerformanceObserver\" in window)) return\n\n\t\ttry {\n\t\t\tconst observer = new PerformanceObserver((list) => {\n\t\t\t\tfor (const entry of list.getEntries()) {\n\t\t\t\t\tif (entry.duration > 50) {\n\t\t\t\t\t\t// Long task threshold\n\t\t\t\t\t\tsetMetrics((prev) => ({\n\t\t\t\t\t\t\t...prev,\n\t\t\t\t\t\t\tlongTasks: prev.longTasks + 1,\n\t\t\t\t\t\t\ttotalLongTaskDuration: prev.totalLongTaskDuration + entry.duration\n\t\t\t\t\t\t}))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tobserver.observe({ entryTypes: [\"longtask\"] })\n\t\t\tlongTaskObserverRef.current = observer\n\n\t\t\treturn () => {\n\t\t\t\tobserver.disconnect()\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.warn(\"Long task monitoring not supported:\", error)\n\t\t}\n\t}, [])\n\n\treturn {\n\t\t...metrics,\n\t\taverageLongTaskDuration:\n\t\t\tmetrics.longTasks > 0 ? metrics.totalLongTaskDuration / metrics.longTasks : 0,\n\t\tisPerformanceGood: metrics.fps >= 50 && metrics.frameDrops < 5\n\t}\n}\n","\"use client\"\n\nimport { useActionState, useCallback, useOptimistic, useState } from \"react\"\nimport { useMediaSelector, useMediaStore } from \"../context/media-context\"\nimport type { EnhancedMediaStore } from \"../context/media-store\"\nimport type { MediaPlayerState } from \"../types/index\"\nimport { useMediaActions } from \"./use-media-actions\"\nimport { useMediaOptimistic } from \"./use-media-optimistic\"\n\n// Legacy hook for backward compatibility\nexport function useMediaState() {\n\tconst [state, setState] = useState<MediaPlayerState>({\n\t\tisPlaying: false,\n\t\tcurrentTime: 0,\n\t\tduration: 0,\n\t\tvolume: 1,\n\t\tisMuted: false,\n\t\tisLoading: false,\n\t\tisFullscreen: false,\n\t\terror: null,\n\t\tbuffered: null\n\t})\n\n\tconst updateState = (updates: Partial<MediaPlayerState>) => {\n\t\tsetState((prev: MediaPlayerState) => ({ ...prev, ...updates }))\n\t}\n\n\tconst setPlaying = (isPlaying: boolean) => {\n\t\tupdateState({ isPlaying })\n\t}\n\n\tconst setCurrentTime = (currentTime: number) => {\n\t\tupdateState({ currentTime })\n\t}\n\n\tconst setDuration = (duration: number) => {\n\t\tupdateState({ duration })\n\t}\n\n\tconst setVolume = (volume: number) => {\n\t\tupdateState({ volume: Math.max(0, Math.min(1, volume)) })\n\t}\n\n\tconst setMuted = (isMuted: boolean) => {\n\t\tupdateState({ isMuted })\n\t}\n\n\tconst setLoading = (isLoading: boolean) => {\n\t\tupdateState({ isLoading })\n\t}\n\n\tconst setFullscreen = (isFullscreen: boolean) => {\n\t\tupdateState({ isFullscreen })\n\t}\n\n\tconst setError = (error: string | null) => {\n\t\tupdateState({ error })\n\t}\n\n\tconst setBuffered = (buffered: TimeRanges | null) => {\n\t\tupdateState({ buffered })\n\t}\n\n\treturn {\n\t\tstate,\n\t\tupdateState,\n\t\tsetPlaying,\n\t\tsetCurrentTime,\n\t\tsetDuration,\n\t\tsetVolume,\n\t\tsetMuted,\n\t\tsetLoading,\n\t\tsetFullscreen,\n\t\tsetError,\n\t\tsetBuffered\n\t}\n}\n\n// React 19 enhanced media state hook\nexport function useEnhancedMediaState() {\n\tconst store = useMediaStore()\n\n\t// Check if this is an enhanced store\n\tconst isEnhanced = \"getOptimisticState\" in store\n\n\t// Always call hooks unconditionally\n\tconst regularState = useMediaState()\n\tconst enhancedStore = store as unknown as EnhancedMediaStore\n\tconst optimisticState = useMediaOptimistic(enhancedStore)\n\tconst actions = useMediaActions(enhancedStore)\n\n\t// Return appropriate state based on store type\n\tif (!isEnhanced) {\n\t\t// Fall back to regular media state if not enhanced\n\t\treturn regularState as any\n\t}\n\n\treturn {\n\t\t// State (optimistic values for immediate UI feedback)\n\t\tstate: optimisticState.state,\n\t\tactualState: optimisticState.actualState,\n\n\t\t// Individual state selectors\n\t\tisPlaying: optimisticState.isPlaying,\n\t\tcurrentTime: optimisticState.currentTime,\n\t\tduration: optimisticState.state.duration,\n\t\tvolume: optimisticState.volume,\n\t\tisMuted: optimisticState.isMuted,\n\t\tisLoading: optimisticState.isBuffering,\n\t\tisFullscreen: optimisticState.isFullscreen,\n\t\terror: optimisticState.state.error,\n\t\tbuffered: optimisticState.state.buffered,\n\n\t\t// Computed values\n\t\tprogress: optimisticState.progress,\n\t\tformattedTime: optimisticState.formattedTime,\n\t\tformattedDuration: optimisticState.formattedDuration,\n\n\t\t// Actions with optimistic updates\n\t\tactions,\n\n\t\t// Action state for loading/error handling\n\t\tisActionLoading: actions.isLoading,\n\t\tactionError: actions.errorMessage,\n\t\tretryLastAction: actions.retryLastAction,\n\n\t\t// Legacy compatibility methods\n\t\tupdateState: (updates: Partial<MediaPlayerState>) => {\n\t\t\t// Map legacy updates to new actions\n\t\t\tif (\"isPlaying\" in updates) {\n\t\t\t\tupdates.isPlaying ? actions.play() : actions.pause()\n\t\t\t}\n\t\t\tif (\"currentTime\" in updates) {\n\t\t\t\tactions.setCurrentTime(updates.currentTime!)\n\t\t\t}\n\t\t\tif (\"duration\" in updates) {\n\t\t\t\tactions.setDuration(updates.duration!)\n\t\t\t}\n\t\t\tif (\"volume\" in updates) {\n\t\t\t\tactions.setVolume(updates.volume!)\n\t\t\t}\n\t\t\tif (\"isMuted\" in updates) {\n\t\t\t\tupdates.isMuted ? actions.mute() : actions.unmute()\n\t\t\t}\n\t\t\tif (\"isLoading\" in updates) {\n\t\t\t\tactions.setLoading(updates.isLoading!)\n\t\t\t}\n\t\t\tif (\"isFullscreen\" in updates) {\n\t\t\t\tupdates.isFullscreen ? actions.enterFullscreen() : actions.exitFullscreen()\n\t\t\t}\n\t\t\tif (\"error\" in updates) {\n\t\t\t\tactions.setError(updates.error ?? null)\n\t\t\t}\n\t\t\tif (\"buffered\" in updates) {\n\t\t\t\tactions.setBuffered(updates.buffered ?? null)\n\t\t\t}\n\t\t},\n\n\t\t// Individual action methods for legacy compatibility\n\t\tsetPlaying: (isPlaying: boolean) => {\n\t\t\tisPlaying ? actions.play(true) : actions.pause(true) // Use optimistic updates\n\t\t},\n\t\tsetCurrentTime: (time: number) => actions.setCurrentTime(time),\n\t\tsetDuration: (duration: number) => actions.setDuration(duration),\n\t\tsetVolume: (volume: number) => actions.setVolume(volume, true),\n\t\tsetMuted: (muted: boolean) => {\n\t\t\tmuted ? actions.mute(true) : actions.unmute(true)\n\t\t},\n\t\tsetLoading: (loading: boolean) => actions.setLoading(loading),\n\t\tsetFullscreen: (fullscreen: boolean) => {\n\t\t\tfullscreen ? actions.enterFullscreen(true) : actions.exitFullscreen(true)\n\t\t},\n\t\tsetError: (error: string | null) => actions.setError(error),\n\t\tsetBuffered: (buffered: TimeRanges | null) => actions.setBuffered(buffered)\n\t}\n}\n\n// Hook that automatically chooses between legacy and enhanced based on context availability\nexport function useAdaptiveMediaState() {\n\t// Always call hooks unconditionally\n\tconst enhancedState = useEnhancedMediaState()\n\tconst regularState = useMediaState()\n\n\t// Check if we're in an enhanced context by testing a property that would only exist in enhanced mode\n\tconst isEnhancedContext = \"getOptimisticState\" in enhancedState\n\n\tif (!isEnhancedContext) {\n\t\t// Fall back to legacy version if not in MediaProvider context\n\t\tconsole.warn(\"MediaStore context not available, using legacy state management\")\n\t\treturn regularState\n\t}\n\n\treturn enhancedState\n}\n","\"use client\"\n\nimport { useCallback, useEffect, useRef } from \"react\"\nimport type { MediaPlayerControls } from \"../types/index\"\nimport { useMediaState } from \"./use-media-state\"\n\ninterface UseMediaPlayerOptions {\n\tsrc: string | string[]\n\tautoPlay?: boolean\n\tloop?: boolean\n\tmuted?: boolean\n\tvolume?: number\n\tpreload?: \"none\" | \"metadata\" | \"auto\"\n\tcrossOrigin?: \"anonymous\" | \"use-credentials\"\n\tplaybackRates?: number[]\n\tkeyboardControls?: boolean\n\tshowControls?: boolean\n\tcustomControls?: boolean\n\tonPlay?: () => void\n\tonPause?: () => void\n\tonTimeUpdate?: (currentTime: number) => void\n\tonDurationChange?: (duration: number) => void\n\tonVolumeChange?: (volume: number) => void\n\tonError?: (error: string) => void\n\tonLoadStart?: () => void\n\tonLoadedData?: () => void\n\tonEnded?: () => void\n}\n\nexport function useMediaPlayer(options: UseMediaPlayerOptions) {\n\tconst mediaRef = useRef<HTMLVideoElement | HTMLAudioElement>(null)\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\n\tconst {\n\t\tstate,\n\t\tsetPlaying,\n\t\tsetCurrentTime,\n\t\tsetDuration,\n\t\tsetVolume,\n\t\tsetMuted,\n\t\tsetLoading,\n\t\tsetFullscreen,\n\t\tsetError,\n\t\tsetBuffered\n\t} = useMediaState()\n\n\t// Initialize media element with options\n\tuseEffect(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\t// Set initial properties\n\t\tif (options.volume !== undefined) {\n\t\t\tmedia.volume = options.volume\n\t\t\tsetVolume(options.volume)\n\t\t}\n\t\tif (options.muted !== undefined) {\n\t\t\tmedia.muted = options.muted\n\t\t\tsetMuted(options.muted)\n\t\t}\n\t\tif (options.autoPlay !== undefined) {\n\t\t\tmedia.autoplay = options.autoPlay\n\t\t}\n\t\tif (options.loop !== undefined) {\n\t\t\tmedia.loop = options.loop\n\t\t}\n\t\tif (options.preload !== undefined) {\n\t\t\tmedia.preload = options.preload\n\t\t}\n\t\tif (options.crossOrigin !== undefined) {\n\t\t\tmedia.crossOrigin = options.crossOrigin\n\t\t}\n\t}, [options, setVolume, setMuted])\n\n\t// Event handlers\n\tconst handlePlay = () => {\n\t\tsetPlaying(true)\n\t\toptions.onPlay?.()\n\t}\n\n\tconst handlePause = () => {\n\t\tsetPlaying(false)\n\t\toptions.onPause?.()\n\t}\n\n\tconst handleTimeUpdate = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tsetCurrentTime(media.currentTime)\n\t\toptions.onTimeUpdate?.(media.currentTime)\n\t}\n\n\tconst handleDurationChange = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tsetDuration(media.duration)\n\t\toptions.onDurationChange?.(media.duration)\n\t}\n\n\tconst handleVolumeChange = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tsetVolume(media.volume)\n\t\tsetMuted(media.muted)\n\t\toptions.onVolumeChange?.(media.volume)\n\t}\n\n\tconst handleLoadStart = () => {\n\t\tsetLoading(true)\n\t\tsetError(null)\n\t\toptions.onLoadStart?.()\n\t}\n\n\tconst handleLoadedData = () => {\n\t\tsetLoading(false)\n\t\toptions.onLoadedData?.()\n\t}\n\n\tconst handleError = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tconst errorMessage = media.error?.message || \"An error occurred while loading the media\"\n\t\tsetError(errorMessage)\n\t\tsetLoading(false)\n\t\toptions.onError?.(errorMessage)\n\t}\n\n\tconst handleEnded = () => {\n\t\tsetPlaying(false)\n\t\toptions.onEnded?.()\n\t}\n\n\tconst handleProgress = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tsetBuffered(media.buffered)\n\t}\n\n\t// Attach event listeners\n\tuseEffect(() => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.addEventListener(\"play\", handlePlay)\n\t\tmedia.addEventListener(\"pause\", handlePause)\n\t\tmedia.addEventListener(\"timeupdate\", handleTimeUpdate)\n\t\tmedia.addEventListener(\"durationchange\", handleDurationChange)\n\t\tmedia.addEventListener(\"volumechange\", handleVolumeChange)\n\t\tmedia.addEventListener(\"loadstart\", handleLoadStart)\n\t\tmedia.addEventListener(\"loadeddata\", handleLoadedData)\n\t\tmedia.addEventListener(\"error\", handleError)\n\t\tmedia.addEventListener(\"ended\", handleEnded)\n\t\tmedia.addEventListener(\"progress\", handleProgress)\n\n\t\treturn () => {\n\t\t\tmedia.removeEventListener(\"play\", handlePlay)\n\t\t\tmedia.removeEventListener(\"pause\", handlePause)\n\t\t\tmedia.removeEventListener(\"timeupdate\", handleTimeUpdate)\n\t\t\tmedia.removeEventListener(\"durationchange\", handleDurationChange)\n\t\t\tmedia.removeEventListener(\"volumechange\", handleVolumeChange)\n\t\t\tmedia.removeEventListener(\"loadstart\", handleLoadStart)\n\t\t\tmedia.removeEventListener(\"loadeddata\", handleLoadedData)\n\t\t\tmedia.removeEventListener(\"error\", handleError)\n\t\t\tmedia.removeEventListener(\"ended\", handleEnded)\n\t\t\tmedia.removeEventListener(\"progress\", handleProgress)\n\t\t}\n\t}, [\n\t\thandlePlay,\n\t\thandlePause,\n\t\thandleTimeUpdate,\n\t\thandleDurationChange,\n\t\thandleVolumeChange,\n\t\thandleLoadStart,\n\t\thandleLoadedData,\n\t\thandleError,\n\t\thandleEnded,\n\t\thandleProgress\n\t])\n\n\t// Control functions\n\tconst play = async () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\ttry {\n\t\t\tawait media.play()\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to play media:\", error)\n\t\t\tsetError(\"Failed to play media\")\n\t\t}\n\t}\n\n\tconst pause = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.pause()\n\t}\n\n\tconst toggle = () => {\n\t\tif (state.isPlaying) {\n\t\t\tpause()\n\t\t} else {\n\t\t\tplay()\n\t\t}\n\t}\n\n\tconst seek = (time: number) => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.currentTime = Math.max(0, Math.min(time, media.duration || 0))\n\t}\n\n\tconst setVolumeControl = (volume: number) => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tconst clampedVolume = Math.max(0, Math.min(1, volume))\n\t\tmedia.volume = clampedVolume\n\t}\n\n\tconst mute = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.muted = true\n\t}\n\n\tconst unmute = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.muted = false\n\t}\n\n\tconst toggleMute = () => {\n\t\tconst media = mediaRef.current\n\t\tif (!media) return\n\n\t\tmedia.muted = !media.muted\n\t}\n\n\tconst enterFullscreen = async () => {\n\t\tconst container = containerRef.current\n\t\tif (!container || !document.fullscreenEnabled) return\n\n\t\ttry {\n\t\t\tawait container.requestFullscreen()\n\t\t\tsetFullscreen(true)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to enter fullscreen:\", error)\n\t\t}\n\t}\n\n\tconst exitFullscreen = async () => {\n\t\tif (!document.fullscreenElement) return\n\n\t\ttry {\n\t\t\tawait document.exitFullscreen()\n\t\t\tsetFullscreen(false)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to exit fullscreen:\", error)\n\t\t}\n\t}\n\n\tconst toggleFullscreen = () => {\n\t\tif (document.fullscreenElement) {\n\t\t\texitFullscreen()\n\t\t} else {\n\t\t\tenterFullscreen()\n\t\t}\n\t}\n\n\t// Listen for fullscreen changes\n\tuseEffect(() => {\n\t\tconst handleFullscreenChange = () => {\n\t\t\tsetFullscreen(!!document.fullscreenElement)\n\t\t}\n\n\t\tdocument.addEventListener(\"fullscreenchange\", handleFullscreenChange)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"fullscreenchange\", handleFullscreenChange)\n\t\t}\n\t}, [setFullscreen])\n\n\tconst controls: MediaPlayerControls = {\n\t\tplay,\n\t\tpause,\n\t\ttoggle,\n\t\tseek,\n\t\tsetVolume: setVolumeControl,\n\t\tmute,\n\t\tunmute,\n\t\ttoggleMute,\n\t\tenterFullscreen,\n\t\texitFullscreen,\n\t\ttoggleFullscreen\n\t}\n\n\treturn {\n\t\tstate,\n\t\tcontrols,\n\t\tmediaRef,\n\t\tcontainerRef\n\t}\n}\n","import * as React from \"react\"\n\n// Mobile breakpoints following mobile-first approach\nconst BREAKPOINTS = {\n mobile: 768,\n tablet: 1024,\n desktop: 1280\n} as const\n\n// Device detection utilities\nfunction detectPlatform(): 'ios' | 'android' | 'desktop' | 'unknown' {\n if (typeof window === 'undefined') return 'unknown'\n \n const userAgent = window.navigator.userAgent.toLowerCase()\n \n if (/iphone|ipad|ipod/.test(userAgent)) return 'ios'\n if (/android/.test(userAgent)) return 'android'\n if (/windows|mac|linux/.test(userAgent)) return 'desktop'\n \n return 'unknown'\n}\n\nfunction isTouchDevice(): boolean {\n if (typeof window === 'undefined') return false\n \n return (\n 'ontouchstart' in window ||\n navigator.maxTouchPoints > 0 ||\n // @ts-ignore - for older browsers\n navigator.msMaxTouchPoints > 0\n )\n}\n\nfunction supportsHaptics(): boolean {\n if (typeof window === 'undefined') return false\n \n // Check for haptic feedback support\n return (\n 'vibrate' in navigator ||\n // @ts-ignore - for newer Vibration API\n 'vibration' in navigator ||\n // @ts-ignore - for iOS haptic feedback\n 'ondevicemotion' in window\n )\n}\n\n// Enhanced device information interface\nexport interface DeviceInfo {\n isMobile: boolean\n isTablet: boolean\n isDesktop: boolean\n isTouchDevice: boolean\n platform: 'ios' | 'android' | 'desktop' | 'unknown'\n supportsHaptics: boolean\n screenSize: {\n width: number\n height: number\n }\n orientation: 'portrait' | 'landscape'\n}\n\n// Legacy hook for backward compatibility\nexport function useIsMobile(): boolean {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${BREAKPOINTS.mobile - 1}px)`)\n const onChange = () => {\n setIsMobile(window.innerWidth < BREAKPOINTS.mobile)\n }\n mql.addEventListener(\"change\", onChange)\n setIsMobile(window.innerWidth < BREAKPOINTS.mobile)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isMobile\n}\n\n// Enhanced mobile detection hook with comprehensive device information\nexport function useDeviceInfo(): DeviceInfo {\n const [deviceInfo, setDeviceInfo] = React.useState<DeviceInfo>(() => {\n if (typeof window === 'undefined') {\n return {\n isMobile: false,\n isTablet: false,\n isDesktop: true,\n isTouchDevice: false,\n platform: 'unknown',\n supportsHaptics: false,\n screenSize: { width: 1920, height: 1080 },\n orientation: 'landscape'\n }\n }\n \n const width = window.innerWidth\n const height = window.innerHeight\n \n return {\n isMobile: width < BREAKPOINTS.mobile,\n isTablet: width >= BREAKPOINTS.mobile && width < BREAKPOINTS.desktop,\n isDesktop: width >= BREAKPOINTS.desktop,\n isTouchDevice: isTouchDevice(),\n platform: detectPlatform(),\n supportsHaptics: supportsHaptics(),\n screenSize: { width, height },\n orientation: width > height ? 'landscape' : 'portrait'\n }\n })\n\n React.useEffect(() => {\n const updateDeviceInfo = () => {\n const width = window.innerWidth\n const height = window.innerHeight\n \n setDeviceInfo({\n isMobile: width < BREAKPOINTS.mobile,\n isTablet: width >= BREAKPOINTS.mobile && width < BREAKPOINTS.desktop,\n isDesktop: width >= BREAKPOINTS.desktop,\n isTouchDevice: isTouchDevice(),\n platform: detectPlatform(),\n supportsHaptics: supportsHaptics(),\n screenSize: { width, height },\n orientation: width > height ? 'landscape' : 'portrait'\n })\n }\n\n // Listen for resize events\n window.addEventListener('resize', updateDeviceInfo)\n \n // Listen for orientation changes\n window.addEventListener('orientationchange', updateDeviceInfo)\n \n // Listen for media query changes for better performance\n const mobileQuery = window.matchMedia(`(max-width: ${BREAKPOINTS.mobile - 1}px)`)\n const tabletQuery = window.matchMedia(`(min-width: ${BREAKPOINTS.mobile}px) and (max-width: ${BREAKPOINTS.desktop - 1}px)`)\n const desktopQuery = window.matchMedia(`(min-width: ${BREAKPOINTS.desktop}px)`)\n \n mobileQuery.addEventListener('change', updateDeviceInfo)\n tabletQuery.addEventListener('change', updateDeviceInfo)\n desktopQuery.addEventListener('change', updateDeviceInfo)\n \n return () => {\n window.removeEventListener('resize', updateDeviceInfo)\n window.removeEventListener('orientationchange', updateDeviceInfo)\n mobileQuery.removeEventListener('change', updateDeviceInfo)\n tabletQuery.removeEventListener('change', updateDeviceInfo)\n desktopQuery.removeEventListener('change', updateDeviceInfo)\n }\n }, [])\n\n return deviceInfo\n}\n\n// Hook for container queries support (Tailwind CSS v4)\nexport function useContainerQuery(containerRef: React.RefObject<HTMLElement>, query: string) {\n const [matches, setMatches] = React.useState(false)\n\n React.useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const size = entry.contentBoxSize[0]\n const width = size?.inlineSize || 0\n const height = size?.blockSize || 0\n \n // Simple container query evaluation\n // This is a basic implementation - in production you might want to use a library\n const queryMatch = evaluateContainerQuery(query, { width, height })\n setMatches(queryMatch)\n }\n })\n\n observer.observe(container)\n\n return () => {\n observer.disconnect()\n }\n }, [query])\n\n return matches\n}\n\n// Simple container query evaluator\nfunction evaluateContainerQuery(query: string, dimensions: { width: number; height: number }): boolean {\n // Basic implementation - supports (min-width: Xpx) and (max-width: Xpx)\n const minWidthMatch = query.match(/\\(min-width:\\s*(\\d+)px\\)/)\n const maxWidthMatch = query.match(/\\(max-width:\\s*(\\d+)px\\)/)\n \n if (minWidthMatch && minWidthMatch[1]) {\n const minWidth = parseInt(minWidthMatch[1], 10)\n return dimensions.width >= minWidth\n }\n \n if (maxWidthMatch && maxWidthMatch[1]) {\n const maxWidth = parseInt(maxWidthMatch[1], 10)\n return dimensions.width <= maxWidth\n }\n \n return false\n}\n\n// Performance optimization hook for mobile devices\nexport function useMobileOptimizations() {\n const { platform, isMobile } = useDeviceInfo()\n \n React.useEffect(() => {\n if (!isMobile) return\n \n // iOS-specific optimizations\n if (platform === 'ios') {\n // Prevent zoom on double tap for iOS Safari\n const preventZoom = (e: TouchEvent) => {\n if (e.touches.length > 1) {\n e.preventDefault()\n }\n }\n \n document.addEventListener('touchstart', preventZoom, { passive: false })\n \n // Enable momentum scrolling\n ;(document.body.style as any).webkitOverflowScrolling = 'touch'\n \n return () => {\n document.removeEventListener('touchstart', preventZoom)\n }\n }\n \n // Android-specific optimizations\n if (platform === 'android') {\n // Improve touch responsiveness\n document.body.style.touchAction = 'manipulation'\n }\n \n // General mobile optimizations\n // Improve rendering performance\n document.documentElement.style.setProperty('--webkit-transform', 'translateZ(0)')\n document.documentElement.style.setProperty('--transform', 'translateZ(0)')\n \n }, [platform, isMobile])\n}\n\n// Haptic feedback utility\nexport function useHapticFeedback() {\n const { supportsHaptics } = useDeviceInfo()\n \n const triggerHaptic = React.useCallback((type: 'light' | 'medium' | 'heavy' | 'success' | 'warning' | 'error' = 'light') => {\n if (!supportsHaptics) return\n \n // Map haptic types to vibration patterns\n const patterns = {\n light: [10],\n medium: [20],\n heavy: [30],\n success: [10, 10, 10],\n warning: [20, 20],\n error: [50, 20, 50]\n }\n \n const pattern = patterns[type]\n \n if ('vibrate' in navigator) {\n navigator.vibrate(pattern)\n }\n }, [supportsHaptics])\n \n return { triggerHaptic, supportsHaptics }\n}\n","\"use client\"\n\nimport { useDeviceInfo, useHapticFeedback } from \"@rp/ui/hooks/use-mobile\"\nimport * as React from \"react\"\n\n// Gesture types\nexport type GestureType =\n\t| \"tap\"\n\t| \"double-tap\"\n\t| \"long-press\"\n\t| \"swipe-left\"\n\t| \"swipe-right\"\n\t| \"swipe-up\"\n\t| \"swipe-down\"\n\t| \"pinch-in\"\n\t| \"pinch-out\"\n\n// Gesture event data\nexport interface GestureEvent {\n\ttype: GestureType\n\tstartPoint: { x: number; y: number }\n\tcurrentPoint: { x: number; y: number }\n\tvelocity?: { x: number; y: number }\n\tscale?: number\n\trotation?: number\n\tdistance?: number\n\tduration: number\n\tpreventDefault: () => void\n\ttarget: HTMLElement\n}\n\n// Gesture configuration\nexport interface GestureConfig {\n\tenabledGestures?: GestureType[]\n\ttapThreshold?: number // ms\n\tdoubleTapThreshold?: number // ms\n\tlongPressThreshold?: number // ms\n\tswipeThreshold?: number // px\n\tswipeVelocityThreshold?: number // px/ms\n\tpinchThreshold?: number // scale difference\n\trotationThreshold?: number // degrees\n\tenableHapticFeedback?: boolean\n}\n\n// Default configuration\nconst defaultConfig: Required<GestureConfig> = {\n\tenabledGestures: [\n\t\t\"tap\",\n\t\t\"double-tap\",\n\t\t\"long-press\",\n\t\t\"swipe-left\",\n\t\t\"swipe-right\",\n\t\t\"swipe-up\",\n\t\t\"swipe-down\",\n\t\t\"pinch-in\",\n\t\t\"pinch-out\"\n\t],\n\ttapThreshold: 200,\n\tdoubleTapThreshold: 300,\n\tlongPressThreshold: 500,\n\tswipeThreshold: 50,\n\tswipeVelocityThreshold: 0.5,\n\tpinchThreshold: 0.1,\n\trotationThreshold: 15,\n\tenableHapticFeedback: true\n}\n\n// Touch point interface\ninterface TouchPoint {\n\tid: number\n\tx: number\n\ty: number\n\ttimestamp: number\n}\n\n// Gesture state\ninterface GestureState {\n\tisTracking: boolean\n\ttouches: TouchPoint[]\n\tstartTouches: TouchPoint[]\n\tlastTap?: { timestamp: number; point: { x: number; y: number } }\n\tlongPressTimer?: NodeJS.Timeout\n\tinitialDistance?: number\n\tinitialScale?: number\n\tlastScale?: number\n}\n\n// Touch gesture hook\nexport function useTouchGestures(\n\tref: React.RefObject<HTMLElement>,\n\tonGesture: (event: GestureEvent) => void,\n\tconfig: GestureConfig = {}\n) {\n\tconst mergedConfig = { ...defaultConfig, ...config }\n\tconst { isTouchDevice } = useDeviceInfo()\n\tconst { triggerHaptic } = useHapticFeedback()\n\tconst gestureState = React.useRef<GestureState>({\n\t\tisTracking: false,\n\t\ttouches: [],\n\t\tstartTouches: []\n\t})\n\n\t// Helper functions\n\tconst getTouchPoint = (touch: Touch): TouchPoint => ({\n\t\tid: touch.identifier,\n\t\tx: touch.clientX,\n\t\ty: touch.clientY,\n\t\ttimestamp: Date.now()\n\t})\n\n\tconst getDistance = (p1: TouchPoint, p2: TouchPoint): number =>\n\t\tMath.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2))\n\n\tconst getVelocity = (start: TouchPoint, end: TouchPoint): { x: number; y: number } => {\n\t\tconst timeDiff = Math.max(end.timestamp - start.timestamp, 1)\n\t\treturn {\n\t\t\tx: (end.x - start.x) / timeDiff,\n\t\t\ty: (end.y - start.y) / timeDiff\n\t\t}\n\t}\n\n\tconst createGestureEvent = (\n\t\ttype: GestureType,\n\t\tstartPoint: TouchPoint,\n\t\tcurrentPoint: TouchPoint,\n\t\tadditionalData: Partial<GestureEvent> = {}\n\t): GestureEvent => ({\n\t\ttype,\n\t\tstartPoint: { x: startPoint.x, y: startPoint.y },\n\t\tcurrentPoint: { x: currentPoint.x, y: currentPoint.y },\n\t\tduration: currentPoint.timestamp - startPoint.timestamp,\n\t\ttarget: ref.current!,\n\t\tpreventDefault: () => {},\n\t\t...additionalData\n\t})\n\n\t// Handle touch start\n\tconst handleTouchStart = React.useCallback(\n\t\t(e: TouchEvent) => {\n\t\t\tif (!mergedConfig.enabledGestures.length) return\n\n\t\t\tconst touches = Array.from(e.touches).map(getTouchPoint)\n\t\t\tconst state = gestureState.current\n\n\t\t\tstate.isTracking = true\n\t\t\tstate.touches = touches\n\t\t\tstate.startTouches = [...touches]\n\n\t\t\t// Clear any existing long press timer\n\t\t\tif (state.longPressTimer) {\n\t\t\t\tclearTimeout(state.longPressTimer)\n\t\t\t}\n\n\t\t\t// Set up long press detection for single touch\n\t\t\tif (touches.length === 1 && mergedConfig.enabledGestures.includes(\"long-press\")) {\n\t\t\t\tstate.longPressTimer = setTimeout(() => {\n\t\t\t\t\tif (state.touches.length === 1 && touches[0]) {\n\t\t\t\t\t\tconst gestureEvent = createGestureEvent(\"long-press\", touches[0], touches[0])\n\t\t\t\t\t\tonGesture(gestureEvent)\n\n\t\t\t\t\t\tif (mergedConfig.enableHapticFeedback) {\n\t\t\t\t\t\t\ttriggerHaptic(\"heavy\")\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, mergedConfig.longPressThreshold)\n\t\t\t}\n\n\t\t\t// Handle multi-touch gestures\n\t\t\tif (touches.length === 2 && touches[0] && touches[1]) {\n\t\t\t\tstate.initialDistance = getDistance(touches[0], touches[1])\n\t\t\t\tstate.initialScale = 1\n\t\t\t\tstate.lastScale = 1\n\t\t\t}\n\t\t},\n\t\t[mergedConfig, onGesture, triggerHaptic]\n\t)\n\n\t// Handle touch move\n\tconst handleTouchMove = React.useCallback(\n\t\t(e: TouchEvent) => {\n\t\t\tconst state = gestureState.current\n\t\t\tif (!state.isTracking) return\n\n\t\t\tconst touches = Array.from(e.touches).map(getTouchPoint)\n\t\t\tstate.touches = touches\n\n\t\t\t// Handle pinch gesture\n\t\t\tif (touches.length === 2 && state.initialDistance && touches[0] && touches[1]) {\n\t\t\t\tconst currentDistance = getDistance(touches[0], touches[1])\n\t\t\t\tconst scale = currentDistance / state.initialDistance\n\t\t\t\tconst scaleDiff = Math.abs(scale - (state.lastScale || 1))\n\n\t\t\t\tif (scaleDiff > mergedConfig.pinchThreshold) {\n\t\t\t\t\tconst gestureType = scale > (state.lastScale || 1) ? \"pinch-out\" : \"pinch-in\"\n\n\t\t\t\t\tif (mergedConfig.enabledGestures.includes(gestureType)) {\n\t\t\t\t\t\tconst centerPoint = {\n\t\t\t\t\t\t\tx: (touches[0].x + touches[1].x) / 2,\n\t\t\t\t\t\t\ty: (touches[0].y + touches[1].y) / 2,\n\t\t\t\t\t\t\tid: -1,\n\t\t\t\t\t\t\ttimestamp: Date.now()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst startCenterPoint = {\n\t\t\t\t\t\t\tx: ((state.startTouches[0]?.x ?? 0) + (state.startTouches[1]?.x ?? 0)) / 2,\n\t\t\t\t\t\t\ty: ((state.startTouches[0]?.y ?? 0) + (state.startTouches[1]?.y ?? 0)) / 2,\n\t\t\t\t\t\t\tid: -1,\n\t\t\t\t\t\t\ttimestamp: state.startTouches[0]?.timestamp ?? Date.now()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst gestureEvent = createGestureEvent(gestureType, startCenterPoint, centerPoint, {\n\t\t\t\t\t\t\tscale,\n\t\t\t\t\t\t\tdistance: currentDistance\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tonGesture(gestureEvent)\n\t\t\t\t\t\tstate.lastScale = scale\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Clear long press timer on move\n\t\t\tif (state.longPressTimer && touches.length === 1 && state.startTouches[0] && touches[0]) {\n\t\t\t\tconst startTouch = state.startTouches[0]\n\t\t\t\tconst currentTouch = touches[0]\n\t\t\t\tconst distance = getDistance(startTouch, currentTouch)\n\n\t\t\t\tif (distance > mergedConfig.swipeThreshold) {\n\t\t\t\t\tclearTimeout(state.longPressTimer)\n\t\t\t\t\tstate.longPressTimer = undefined\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[mergedConfig, onGesture]\n\t)\n\n\t// Handle touch end\n\tconst handleTouchEnd = React.useCallback(\n\t\t(e: TouchEvent) => {\n\t\t\tconst state = gestureState.current\n\t\t\tif (!state.isTracking) return\n\n\t\t\tconst endTouches = Array.from(e.changedTouches).map(getTouchPoint)\n\t\t\tconst currentTime = Date.now()\n\n\t\t\t// Clear long press timer\n\t\t\tif (state.longPressTimer) {\n\t\t\t\tclearTimeout(state.longPressTimer)\n\t\t\t\tstate.longPressTimer = undefined\n\t\t\t}\n\n\t\t\t// Handle single touch gestures\n\t\t\tif (\n\t\t\t\tstate.startTouches.length === 1 &&\n\t\t\t\tendTouches.length === 1 &&\n\t\t\t\tstate.startTouches[0] &&\n\t\t\t\tendTouches[0]\n\t\t\t) {\n\t\t\t\tconst startTouch = state.startTouches[0]\n\t\t\t\tconst endTouch = endTouches[0]\n\t\t\t\tconst distance = getDistance(startTouch, endTouch)\n\t\t\t\tconst duration = endTouch.timestamp - startTouch.timestamp\n\n\t\t\t\t// Check for swipe gestures\n\t\t\t\tif (distance > mergedConfig.swipeThreshold) {\n\t\t\t\t\tconst velocity = getVelocity(startTouch, endTouch)\n\t\t\t\t\tconst absVelX = Math.abs(velocity.x)\n\t\t\t\t\tconst absVelY = Math.abs(velocity.y)\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tabsVelX > mergedConfig.swipeVelocityThreshold ||\n\t\t\t\t\t\tabsVelY > mergedConfig.swipeVelocityThreshold\n\t\t\t\t\t) {\n\t\t\t\t\t\tlet gestureType: GestureType\n\n\t\t\t\t\t\tif (absVelX > absVelY) {\n\t\t\t\t\t\t\tgestureType = velocity.x > 0 ? \"swipe-right\" : \"swipe-left\"\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tgestureType = velocity.y > 0 ? \"swipe-down\" : \"swipe-up\"\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (mergedConfig.enabledGestures.includes(gestureType)) {\n\t\t\t\t\t\t\tconst gestureEvent = createGestureEvent(gestureType, startTouch, endTouch, {\n\t\t\t\t\t\t\t\tvelocity,\n\t\t\t\t\t\t\t\tdistance\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tonGesture(gestureEvent)\n\n\t\t\t\t\t\t\tif (mergedConfig.enableHapticFeedback) {\n\t\t\t\t\t\t\t\ttriggerHaptic(\"light\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Check for tap gestures\n\t\t\t\telse if (duration < mergedConfig.tapThreshold && distance < mergedConfig.swipeThreshold) {\n\t\t\t\t\t// Check for double tap\n\t\t\t\t\tif (\n\t\t\t\t\t\tstate.lastTap &&\n\t\t\t\t\t\tcurrentTime - state.lastTap.timestamp < mergedConfig.doubleTapThreshold &&\n\t\t\t\t\t\tgetDistance(\n\t\t\t\t\t\t\t{ ...state.lastTap.point, id: -1, timestamp: state.lastTap.timestamp },\n\t\t\t\t\t\t\tendTouch\n\t\t\t\t\t\t) < mergedConfig.swipeThreshold\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (mergedConfig.enabledGestures.includes(\"double-tap\")) {\n\t\t\t\t\t\t\tconst gestureEvent = createGestureEvent(\"double-tap\", startTouch, endTouch)\n\t\t\t\t\t\t\tonGesture(gestureEvent)\n\n\t\t\t\t\t\t\tif (mergedConfig.enableHapticFeedback) {\n\t\t\t\t\t\t\t\ttriggerHaptic(\"medium\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstate.lastTap = undefined\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Single tap\n\t\t\t\t\t\tif (mergedConfig.enabledGestures.includes(\"tap\")) {\n\t\t\t\t\t\t\tconst gestureEvent = createGestureEvent(\"tap\", startTouch, endTouch)\n\t\t\t\t\t\t\tonGesture(gestureEvent)\n\n\t\t\t\t\t\t\tif (mergedConfig.enableHapticFeedback) {\n\t\t\t\t\t\t\t\ttriggerHaptic(\"light\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstate.lastTap = {\n\t\t\t\t\t\t\ttimestamp: currentTime,\n\t\t\t\t\t\t\tpoint: { x: endTouch.x, y: endTouch.y }\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Reset gesture state\n\t\t\tif (e.touches.length === 0) {\n\t\t\t\tstate.isTracking = false\n\t\t\t\tstate.touches = []\n\t\t\t\tstate.startTouches = []\n\t\t\t\tstate.initialDistance = undefined\n\t\t\t\tstate.initialScale = undefined\n\t\t\t\tstate.lastScale = undefined\n\t\t\t}\n\t\t},\n\t\t[mergedConfig, onGesture, triggerHaptic]\n\t)\n\n\t// Attach event listeners\n\tReact.useEffect(() => {\n\t\tconst element = ref.current\n\t\tif (!element || !isTouchDevice) return\n\n\t\telement.addEventListener(\"touchstart\", handleTouchStart, { passive: false })\n\t\telement.addEventListener(\"touchmove\", handleTouchMove, { passive: false })\n\t\telement.addEventListener(\"touchend\", handleTouchEnd, { passive: false })\n\t\telement.addEventListener(\"touchcancel\", handleTouchEnd, { passive: false })\n\n\t\treturn () => {\n\t\t\telement.removeEventListener(\"touchstart\", handleTouchStart)\n\t\t\telement.removeEventListener(\"touchmove\", handleTouchMove)\n\t\t\telement.removeEventListener(\"touchend\", handleTouchEnd)\n\t\t\telement.removeEventListener(\"touchcancel\", handleTouchEnd)\n\t\t}\n\t}, [handleTouchStart, handleTouchMove, handleTouchEnd, isTouchDevice])\n\n\treturn {\n\t\tisGestureEnabled: isTouchDevice && mergedConfig.enabledGestures.length > 0\n\t}\n}\n\n// Media player specific gesture hook with predefined actions\nexport function useMediaGestures(\n\tref: React.RefObject<HTMLElement>,\n\tactions: {\n\t\tonPlayPause?: () => void\n\t\tonSeek?: (direction: \"forward\" | \"backward\", amount: number) => void\n\t\tonVolumeChange?: (direction: \"up\" | \"down\", amount: number) => void\n\t\tonToggleFullscreen?: () => void\n\t\tonZoom?: (scale: number) => void\n\t}\n) {\n\tconst handleGesture = React.useCallback(\n\t\t(event: GestureEvent) => {\n\t\t\tconst { type, velocity, distance, scale } = event\n\n\t\t\tswitch (type) {\n\t\t\t\tcase \"double-tap\":\n\t\t\t\t\t// Double tap to play/pause\n\t\t\t\t\tactions.onPlayPause?.()\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"swipe-left\":\n\t\t\t\t\t// Swipe left to seek backward\n\t\t\t\t\tconst backwardAmount = Math.min((distance || 0) / 10, 30) // Max 30 seconds\n\t\t\t\t\tactions.onSeek?.(\"backward\", backwardAmount)\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"swipe-right\":\n\t\t\t\t\t// Swipe right to seek forward\n\t\t\t\t\tconst forwardAmount = Math.min((distance || 0) / 10, 30) // Max 30 seconds\n\t\t\t\t\tactions.onSeek?.(\"forward\", forwardAmount)\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"swipe-up\":\n\t\t\t\t\t// Swipe up on right side for volume up\n\t\t\t\t\tif (event.startPoint.x > (ref.current?.clientWidth || 0) / 2) {\n\t\t\t\t\t\tconst volumeAmount = Math.min((distance || 0) / 100, 0.2) // Max 20%\n\t\t\t\t\t\tactions.onVolumeChange?.(\"up\", volumeAmount)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"swipe-down\":\n\t\t\t\t\t// Swipe down on right side for volume down\n\t\t\t\t\tif (event.startPoint.x > (ref.current?.clientWidth || 0) / 2) {\n\t\t\t\t\t\tconst volumeAmount = Math.min((distance || 0) / 100, 0.2) // Max 20%\n\t\t\t\t\t\tactions.onVolumeChange?.(\"down\", volumeAmount)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"pinch-out\":\n\t\t\t\t\t// Pinch out to zoom in (for video zoom functionality)\n\t\t\t\t\tactions.onZoom?.(scale || 1)\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"pinch-in\":\n\t\t\t\t\t// Pinch in to zoom out\n\t\t\t\t\tactions.onZoom?.(scale || 1)\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"long-press\":\n\t\t\t\t\t// Long press for fullscreen toggle\n\t\t\t\t\tactions.onToggleFullscreen?.()\n\t\t\t\t\tbreak\n\n\t\t\t\tdefault:\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t},\n\t\t[actions, ref]\n\t)\n\n\tconst gestureConfig: GestureConfig = {\n\t\tenabledGestures: [\n\t\t\t\"tap\",\n\t\t\t\"double-tap\",\n\t\t\t\"long-press\",\n\t\t\t\"swipe-left\",\n\t\t\t\"swipe-right\",\n\t\t\t\"swipe-up\",\n\t\t\t\"swipe-down\",\n\t\t\t\"pinch-in\",\n\t\t\t\"pinch-out\"\n\t\t],\n\t\tenableHapticFeedback: true,\n\t\tswipeThreshold: 30,\n\t\tswipeVelocityThreshold: 0.3\n\t}\n\n\treturn useTouchGestures(ref, handleGesture, gestureConfig)\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\"\n\ninterface SubtitleCue {\n\tstart: number\n\tend: number\n\ttext: string\n}\n\nexport interface SubtitleTrack {\n\tid: string\n\tlabel: string\n\tlanguage?: string\n\tsrc?: string\n}\n\nexport interface UseEnhancedSubtitlesOptions {\n\tsubtitleSrc?: string\n\tsubtitleTracks?: SubtitleTrack[]\n\tdefaultFontSize?: \"small\" | \"medium\" | \"large\"\n\tonLoadError?: (error: Error) => void\n}\n\nexport function useEnhancedSubtitles({\n\tsubtitleSrc,\n\tsubtitleTracks = [],\n\tdefaultFontSize = \"medium\",\n\tonLoadError\n}: UseEnhancedSubtitlesOptions = {}) {\n\tconst [subtitlesEnabled, setSubtitlesEnabled] = useState(false)\n\tconst [subtitleCues, setSubtitleCues] = useState<SubtitleCue[]>([])\n\tconst [currentSubtitle, setCurrentSubtitle] = useState(\"\")\n\tconst [currentTrackId, setCurrentTrackId] = useState<string | null>(null)\n\tconst [fontSize, setFontSize] = useState<\"small\" | \"medium\" | \"large\">(defaultFontSize)\n\tconst [loadError, setLoadError] = useState<Error | null>(null)\n\tconst [isLoading, setIsLoading] = useState(false)\n\n\t// Size mapping for subtitle font sizes\n\tconst sizeMap = {\n\t\tsmall: \"text-sm\",\n\t\tmedium: \"text-base\",\n\t\tlarge: \"text-lg\"\n\t}\n\n\t// Determine if subtitles are available\n\tconst hasSubtitles = !!(subtitleSrc || (subtitleTracks && subtitleTracks.length > 0))\n\n\t// Parse VTT/WebVTT timestamp\n\tconst parseVTTTime = (timeStr: string): number => {\n\t\tconst parts = timeStr.split(\":\")\n\t\tconst seconds = parts[2] ? parseFloat(parts[2]) : 0\n\t\tconst minutes = parts[1] ? parseInt(parts[1], 10) * 60 : 0\n\t\tconst hours = parts[0] ? parseInt(parts[0], 10) * 3600 : 0\n\t\treturn hours + minutes + seconds\n\t}\n\n\t// Parse SRT timestamp\n\tconst parseSRTTime = (timeStr: string): number => {\n\t\t// SRT format: 00:00:00,000 (hours:minutes:seconds,milliseconds)\n\t\tconst [time, ms] = timeStr.split(\",\")\n\t\tconst parts = (time || \"\").split(\":\")\n\t\tconst milliseconds = ms ? parseInt(ms, 10) / 1000 : 0\n\t\tconst seconds = parts[2] ? parseInt(parts[2], 10) : 0\n\t\tconst minutes = parts[1] ? parseInt(parts[1], 10) * 60 : 0\n\t\tconst hours = parts[0] ? parseInt(parts[0], 10) * 3600 : 0\n\t\treturn hours + minutes + seconds + milliseconds\n\t}\n\n\t// Load and parse subtitle file\n\tconst loadSubtitles = async (url: string) => {\n\t\tsetIsLoading(true)\n\t\tsetLoadError(null)\n\n\t\ttry {\n\t\t\tconst response = await fetch(url)\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to load subtitles: ${response.status} ${response.statusText}`)\n\t\t\t}\n\n\t\t\tconst text = await response.text()\n\t\t\tconst cues: SubtitleCue[] = []\n\t\t\tconst lines = text.split(\"\\n\")\n\t\t\tlet i = 0\n\n\t\t\t// Detect format (VTT or SRT)\n\t\t\tconst isVTT = text.includes(\"WEBVTT\") || url.endsWith(\".vtt\")\n\t\t\tconst isSRT = url.endsWith(\".srt\") || /^\\d+$/.test(lines[0]?.trim() || \"\")\n\n\t\t\tif (isVTT) {\n\t\t\t\t// Parse VTT format\n\t\t\t\twhile (i < lines.length) {\n\t\t\t\t\tif (lines[i]?.includes(\"-->\")) {\n\t\t\t\t\t\tconst [startStr, endStr] = (lines[i] || \"\").split(\"-->\").map((s) => s.trim())\n\t\t\t\t\t\tconst start = parseVTTTime(startStr || \"\")\n\t\t\t\t\t\tconst end = parseVTTTime(endStr || \"\")\n\n\t\t\t\t\t\ti++\n\t\t\t\t\t\tlet subtitleText = \"\"\n\t\t\t\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"\") {\n\t\t\t\t\t\t\tsubtitleText += (subtitleText ? \" \" : \"\") + lines[i]?.trim()\n\t\t\t\t\t\t\ti++\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (subtitleText) {\n\t\t\t\t\t\t\tcues.push({ start, end, text: subtitleText })\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t} else if (isSRT) {\n\t\t\t\t// Parse SRT format\n\t\t\t\twhile (i < lines.length) {\n\t\t\t\t\t// Skip the sequence number\n\t\t\t\t\tif (/^\\d+$/.test(lines[i]?.trim() || \"\")) {\n\t\t\t\t\t\ti++\n\t\t\t\t\t\t// Parse timestamp line\n\t\t\t\t\t\tif (lines[i]?.includes(\"-->\")) {\n\t\t\t\t\t\t\tconst [startStr, endStr] = (lines[i] || \"\").split(\"-->\").map((s) => s.trim())\n\t\t\t\t\t\t\tconst start = parseSRTTime(startStr || \"\")\n\t\t\t\t\t\t\tconst end = parseSRTTime(endStr || \"\")\n\n\t\t\t\t\t\t\ti++\n\t\t\t\t\t\t\tlet subtitleText = \"\"\n\t\t\t\t\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"\") {\n\t\t\t\t\t\t\t\tsubtitleText += (subtitleText ? \" \" : \"\") + lines[i]?.trim()\n\t\t\t\t\t\t\t\ti++\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (subtitleText) {\n\t\t\t\t\t\t\t\tcues.push({ start, end, text: subtitleText })\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Unsupported subtitle format. Only VTT and SRT are supported.\")\n\t\t\t}\n\n\t\t\tif (cues.length === 0) {\n\t\t\t\tthrow new Error(\"No subtitle cues found in file\")\n\t\t\t}\n\n\t\t\tsetSubtitleCues(cues)\n\t\t\tsetIsLoading(false)\n\t\t} catch (error) {\n\t\t\tconst err = error instanceof Error ? error : new Error(\"Failed to load subtitles\")\n\t\t\tconsole.error(\"Failed to load subtitles:\", err)\n\t\t\tsetLoadError(err)\n\t\t\tsetIsLoading(false)\n\t\t\tsetSubtitleCues([])\n\t\t\tonLoadError?.(err)\n\t\t}\n\t}\n\n\t// Get current subtitle text based on time\n\tconst getCurrentSubtitle = (currentTime: number) => {\n\t\tif (!subtitlesEnabled || subtitleCues.length === 0) return \"\"\n\n\t\tconst currentCue = subtitleCues.find(\n\t\t\t(cue) => currentTime >= cue.start && currentTime <= cue.end\n\t\t)\n\t\treturn currentCue?.text || \"\"\n\t}\n\n\t// Toggle subtitles on/off\n\tconst toggleSubtitles = () => {\n\t\tsetSubtitlesEnabled((prev) => {\n\t\t\tconst newEnabled = !prev\n\n\t\t\tif (newEnabled && !loadError) {\n\t\t\t\t// Try to load subtitles if not already loaded\n\t\t\t\tif (subtitleCues.length === 0 && !isLoading) {\n\t\t\t\t\t// Load default subtitle source or first track\n\t\t\t\t\tconst srcToLoad = subtitleSrc || subtitleTracks[0]?.src\n\t\t\t\t\tif (srcToLoad) {\n\t\t\t\t\t\tloadSubtitles(srcToLoad)\n\t\t\t\t\t\tif (subtitleTracks[0]) {\n\t\t\t\t\t\t\tsetCurrentTrackId(subtitleTracks[0].id)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (!newEnabled) {\n\t\t\t\tsetCurrentSubtitle(\"\")\n\t\t\t}\n\n\t\t\treturn newEnabled\n\t\t})\n\t}\n\n\t// Select a specific subtitle track\n\tconst selectSubtitleTrack = (trackId: string | null) => {\n\t\tif (!trackId) {\n\t\t\t// Turn off subtitles\n\t\t\tsetSubtitlesEnabled(false)\n\t\t\tsetCurrentTrackId(null)\n\t\t\tsetCurrentSubtitle(\"\")\n\t\t\treturn\n\t\t}\n\n\t\tconst track = subtitleTracks.find((t) => t.id === trackId)\n\t\tif (track?.src) {\n\t\t\tsetCurrentTrackId(trackId)\n\t\t\tloadSubtitles(track.src)\n\t\t\tsetSubtitlesEnabled(true)\n\t\t}\n\t}\n\n\t// Change subtitle font size\n\tconst changeSubtitleFontSize = (size: \"small\" | \"medium\" | \"large\") => {\n\t\tsetFontSize(size)\n\t}\n\n\t// Get CSS classes for subtitle display\n\tconst getSubtitleStyles = {\n\t\tfontSize: sizeMap[fontSize],\n\t\tclassName: `${sizeMap[fontSize]} font-medium`\n\t}\n\n\t// Clear subtitle on disable\n\tuseEffect(() => {\n\t\tif (!subtitlesEnabled) {\n\t\t\tsetCurrentSubtitle(\"\")\n\t\t}\n\t}, [subtitlesEnabled])\n\n\t// Auto-load default subtitles on mount if available\n\tuseEffect(() => {\n\t\tif (subtitleSrc && !subtitleCues.length && !loadError && !isLoading) {\n\t\t\t// Don't auto-load, wait for user to enable\n\t\t\t// This prevents errors on initial load\n\t\t}\n\t}, [])\n\n\treturn {\n\t\t// State\n\t\tsubtitlesEnabled,\n\t\tcurrentSubtitle,\n\t\tsubtitleCues,\n\t\tcurrentTrackId,\n\t\tfontSize,\n\t\tloadError,\n\t\tisLoading,\n\t\thasSubtitles,\n\n\t\t// Actions\n\t\ttoggleSubtitles,\n\t\tselectSubtitleTrack,\n\t\tchangeSubtitleFontSize,\n\t\tsetCurrentSubtitle,\n\n\t\t// Utilities\n\t\tgetCurrentSubtitle,\n\t\tgetSubtitleStyles,\n\n\t\t// Track info\n\t\tavailableTracks: subtitleTracks\n\t}\n}\n","import { useCallback, useEffect } from \"react\"\nimport type { VideoControls } from \"./useVideoPlayer\"\n\ninterface UseKeyboardShortcutsProps {\n\tvideoControls: VideoControls\n\ttoggleSubtitles: () => void\n\ttakeScreenshot: (ctrlKey?: boolean) => void\n\tduration: number\n}\n\nexport function useKeyboardShortcuts({\n\tvideoControls,\n\ttoggleSubtitles,\n\ttakeScreenshot,\n\tduration\n}: UseKeyboardShortcutsProps) {\n\tconst handleKeyDown = (e: KeyboardEvent) => {\n\t\tconst video = document.querySelector(\"video\")\n\t\tif (!video) return\n\n\t\tswitch (e.key.toLowerCase()) {\n\t\t\tcase \" \":\n\t\t\tcase \"k\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.togglePlay()\n\t\t\t\tbreak\n\t\t\tcase \"j\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.seekBackward()\n\t\t\t\tbreak\n\t\t\tcase \"l\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.seekForward()\n\t\t\t\tbreak\n\t\t\tcase \"arrowleft\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideo.currentTime = Math.max(0, video.currentTime - 5)\n\t\t\t\tbreak\n\t\t\tcase \"arrowright\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideo.currentTime = Math.min(duration, video.currentTime + 5)\n\t\t\t\tbreak\n\t\t\tcase \"arrowup\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideo.volume = Math.min(1, video.volume + 0.1)\n\t\t\t\tbreak\n\t\t\tcase \"arrowdown\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideo.volume = Math.max(0, video.volume - 0.1)\n\t\t\t\tbreak\n\t\t\tcase \"m\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.toggleMute()\n\t\t\t\tbreak\n\t\t\tcase \"f\":\n\t\t\t\te.preventDefault()\n\t\t\t\tvideoControls.toggleFullscreen()\n\t\t\t\tbreak\n\t\t\tcase \"c\":\n\t\t\t\te.preventDefault()\n\t\t\t\ttoggleSubtitles()\n\t\t\t\tbreak\n\t\t\tcase \"s\":\n\t\t\t\te.preventDefault()\n\t\t\t\ttakeScreenshot(e.ctrlKey || e.metaKey)\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tuseEffect(() => {\n\t\tdocument.addEventListener(\"keydown\", handleKeyDown)\n\t\treturn () => document.removeEventListener(\"keydown\", handleKeyDown)\n\t}, [handleKeyDown])\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\n\nexport function useMediaControls(isPlaying: boolean, showSettings: boolean) {\n\tconst [controlsVisible, setControlsVisible] = useState(true)\n\tconst [showVolumeSlider, setShowVolumeSlider] = useState(false)\n\tconst hideTimeoutRef = useRef<NodeJS.Timeout | null>(null)\n\n\tconst showControls = () => {\n\t\tsetControlsVisible(true)\n\t\tif (hideTimeoutRef.current) {\n\t\t\tclearTimeout(hideTimeoutRef.current)\n\t\t}\n\n\t\tif (isPlaying && !showSettings) {\n\t\t\thideTimeoutRef.current = setTimeout(() => {\n\t\t\t\tsetControlsVisible(false)\n\t\t\t}, 3000)\n\t\t}\n\t}\n\n\tconst handleMouseMove = () => {\n\t\tshowControls()\n\t}\n\n\tconst handleMouseEnter = () => {\n\t\tsetControlsVisible(true)\n\t}\n\n\tconst handleMouseLeave = () => {\n\t\tif (isPlaying) {\n\t\t\tsetControlsVisible(false)\n\t\t}\n\t}\n\n\tuseEffect(() => {\n\t\tshowControls()\n\t\treturn () => {\n\t\t\tif (hideTimeoutRef.current) {\n\t\t\t\tclearTimeout(hideTimeoutRef.current)\n\t\t\t}\n\t\t}\n\t}, [showControls])\n\n\treturn {\n\t\tcontrolsVisible,\n\t\tshowVolumeSlider,\n\t\tsetShowVolumeSlider,\n\t\thandleMouseMove,\n\t\thandleMouseEnter,\n\t\thandleMouseLeave\n\t}\n}\n","import { useCallback } from \"react\"\n\nexport function useScreenshot(videoRef: React.RefObject<HTMLVideoElement | null>) {\n\tconst takeScreenshot = (ctrlKey: boolean = false) => {\n\t\tif (!videoRef.current) return\n\n\t\tconst video = videoRef.current\n\t\tconst canvas = document.createElement(\"canvas\")\n\t\tcanvas.width = video.videoWidth\n\t\tcanvas.height = video.videoHeight\n\t\tconst ctx = canvas.getContext(\"2d\")\n\t\tif (!ctx) return\n\n\t\ttry {\n\t\t\t// Draw the video frame to canvas\n\t\t\tctx.drawImage(video, 0, 0)\n\n\t\t\t// Try to export the canvas\n\t\t\tcanvas.toBlob((blob) => {\n\t\t\t\tif (!blob) {\n\t\t\t\t\tconsole.error(\"Failed to create blob from canvas\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (ctrlKey) {\n\t\t\t\t\t// Copy to clipboard\n\t\t\t\t\tif (navigator.clipboard && window.ClipboardItem) {\n\t\t\t\t\t\tconst item = new ClipboardItem({ \"image/png\": blob })\n\t\t\t\t\t\tnavigator.clipboard.write([item]).catch((err) => {\n\t\t\t\t\t\t\tconsole.error(\"Failed to copy to clipboard:\", err)\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.warn(\"Clipboard API not supported\")\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Download\n\t\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\t\tconst a = document.createElement(\"a\")\n\t\t\t\t\ta.href = url\n\t\t\t\t\ta.download = `screenshot-${Date.now()}.png`\n\t\t\t\t\ta.click()\n\t\t\t\t\tURL.revokeObjectURL(url)\n\t\t\t\t}\n\t\t\t}, \"image/png\")\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && error.message.includes(\"tainted\")) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t\"Canvas is tainted - video source may not have proper CORS headers. Try setting crossOrigin='anonymous' on the video element.\"\n\t\t\t\t)\n\t\t\t\talert(\n\t\t\t\t\t\"Screenshot failed: The video source doesn't allow screenshots due to CORS policy. Please ensure the video server includes proper CORS headers or set crossOrigin='anonymous' on the video player.\"\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tconsole.error(\"Screenshot failed:\", error)\n\t\t\t\talert(\"Screenshot failed: \" + (error instanceof Error ? error.message : \"Unknown error\"))\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { takeScreenshot }\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\n\nexport interface BufferedRange {\n\tstart: number\n\tend: number\n\tpercentage: number\n}\n\nexport interface VideoState {\n\tisPlaying: boolean\n\tcurrentTime: number\n\tduration: number\n\tvolume: number\n\tisMuted: boolean\n\tisFullscreen: boolean\n\tisLoading: boolean\n\tisSeeking: boolean\n\tisBuffering: boolean\n\tbufferedRanges: BufferedRange[]\n}\n\nexport interface VideoControls {\n\ttogglePlay: () => void\n\tseekForward: (seconds?: number) => void\n\tseekBackward: (seconds?: number) => void\n\ttoggleMute: () => void\n\tsetVolume: (volume: number) => void\n\ttoggleFullscreen: () => void\n\tseekTo: (time: number) => void\n}\n\nexport function useVideoPlayer(containerRef: React.RefObject<HTMLDivElement | null>) {\n\tconst videoRef = useRef<HTMLVideoElement>(null)\n\tconst [state, setState] = useState<VideoState>({\n\t\tisPlaying: false,\n\t\tcurrentTime: 0,\n\t\tduration: 0,\n\t\tvolume: 1,\n\t\tisMuted: false,\n\t\tisFullscreen: false,\n\t\tisLoading: true,\n\t\tisSeeking: false,\n\t\tisBuffering: false,\n\t\tbufferedRanges: []\n\t})\n\n\tuseEffect(() => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\n\t\tconst handleTimeUpdate = () => {\n\t\t\tsetState((prev) => ({ ...prev, currentTime: video.currentTime }))\n\t\t}\n\n\t\tconst handleLoadedMetadata = () => {\n\t\t\tsetState((prev) => ({ ...prev, duration: video.duration }))\n\t\t}\n\n\t\tconst handlePlay = () => {\n\t\t\tsetState((prev) => ({ ...prev, isPlaying: true, isBuffering: false }))\n\t\t}\n\n\t\tconst handlePause = () => {\n\t\t\tsetState((prev) => ({ ...prev, isPlaying: false }))\n\t\t}\n\n\t\tconst handleVolumeChange = () => {\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tvolume: video.volume,\n\t\t\t\tisMuted: video.muted\n\t\t\t}))\n\t\t}\n\n\t\t// Loading state handlers\n\t\tconst handleLoadStart = () => {\n\t\t\tsetState((prev) => ({ ...prev, isLoading: true }))\n\t\t}\n\n\t\tconst handleLoadedData = () => {\n\t\t\tsetState((prev) => ({ ...prev, isLoading: false }))\n\t\t}\n\n\t\t// Seeking state handlers\n\t\tconst handleSeeking = () => {\n\t\t\tsetState((prev) => ({ ...prev, isSeeking: true }))\n\t\t}\n\n\t\tconst handleSeeked = () => {\n\t\t\tsetState((prev) => ({ ...prev, isSeeking: false }))\n\t\t}\n\n\t\t// Buffering state handlers\n\t\tconst handleWaiting = () => {\n\t\t\tsetState((prev) => ({ ...prev, isBuffering: true }))\n\t\t}\n\n\t\tconst handlePlaying = () => {\n\t\t\tsetState((prev) => ({ ...prev, isBuffering: false, isLoading: false }))\n\t\t}\n\n\t\tconst handleCanPlay = () => {\n\t\t\tsetState((prev) => ({ ...prev, isLoading: false, isBuffering: false }))\n\t\t}\n\n\t\t// Progress handler for buffered ranges\n\t\tconst handleProgress = () => {\n\t\t\tif (!video.buffered || video.buffered.length === 0 || video.duration === 0) {\n\t\t\t\tsetState((prev) => ({ ...prev, bufferedRanges: [] }))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst ranges: BufferedRange[] = []\n\t\t\tfor (let i = 0; i < video.buffered.length; i++) {\n\t\t\t\tconst start = video.buffered.start(i)\n\t\t\t\tconst end = video.buffered.end(i)\n\t\t\t\tranges.push({\n\t\t\t\t\tstart,\n\t\t\t\t\tend,\n\t\t\t\t\tpercentage: ((end - start) / video.duration) * 100\n\t\t\t\t})\n\t\t\t}\n\t\t\tsetState((prev) => ({ ...prev, bufferedRanges: ranges }))\n\t\t}\n\n\t\tvideo.addEventListener(\"timeupdate\", handleTimeUpdate)\n\t\tvideo.addEventListener(\"loadedmetadata\", handleLoadedMetadata)\n\t\tvideo.addEventListener(\"play\", handlePlay)\n\t\tvideo.addEventListener(\"pause\", handlePause)\n\t\tvideo.addEventListener(\"volumechange\", handleVolumeChange)\n\t\tvideo.addEventListener(\"loadstart\", handleLoadStart)\n\t\tvideo.addEventListener(\"loadeddata\", handleLoadedData)\n\t\tvideo.addEventListener(\"seeking\", handleSeeking)\n\t\tvideo.addEventListener(\"seeked\", handleSeeked)\n\t\tvideo.addEventListener(\"waiting\", handleWaiting)\n\t\tvideo.addEventListener(\"playing\", handlePlaying)\n\t\tvideo.addEventListener(\"canplay\", handleCanPlay)\n\t\tvideo.addEventListener(\"progress\", handleProgress)\n\n\t\treturn () => {\n\t\t\tvideo.removeEventListener(\"timeupdate\", handleTimeUpdate)\n\t\t\tvideo.removeEventListener(\"loadedmetadata\", handleLoadedMetadata)\n\t\t\tvideo.removeEventListener(\"play\", handlePlay)\n\t\t\tvideo.removeEventListener(\"pause\", handlePause)\n\t\t\tvideo.removeEventListener(\"volumechange\", handleVolumeChange)\n\t\t\tvideo.removeEventListener(\"loadstart\", handleLoadStart)\n\t\t\tvideo.removeEventListener(\"loadeddata\", handleLoadedData)\n\t\t\tvideo.removeEventListener(\"seeking\", handleSeeking)\n\t\t\tvideo.removeEventListener(\"seeked\", handleSeeked)\n\t\t\tvideo.removeEventListener(\"waiting\", handleWaiting)\n\t\t\tvideo.removeEventListener(\"playing\", handlePlaying)\n\t\t\tvideo.removeEventListener(\"canplay\", handleCanPlay)\n\t\t\tvideo.removeEventListener(\"progress\", handleProgress)\n\t\t}\n\t}, [])\n\n\tconst togglePlay = () => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\n\t\tif (state.isPlaying) {\n\t\t\tvideo.pause()\n\t\t} else {\n\t\t\tvideo.play()\n\t\t}\n\t}\n\n\tconst seekForward = (seconds = 10) => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\t\tvideo.currentTime = Math.min(state.duration, video.currentTime + seconds)\n\t}\n\n\tconst seekBackward = (seconds = 10) => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\t\tvideo.currentTime = Math.max(0, video.currentTime - seconds)\n\t}\n\n\tconst toggleMute = () => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\t\tvideo.muted = !state.isMuted\n\t}\n\n\tconst setVolume = (volume: number) => {\n\t\tconst video = videoRef.current\n\t\tif (!video) return\n\t\tvideo.volume = volume\n\t\tif (volume > 0 && state.isMuted) {\n\t\t\tvideo.muted = false\n\t\t}\n\t}\n\n\tconst toggleFullscreen = () => {\n\t\tconst container = containerRef.current\n\t\tif (!container) return\n\n\t\tif (!state.isFullscreen) {\n\t\t\tif (container.requestFullscreen) {\n\t\t\t\tcontainer.requestFullscreen()\n\t\t\t}\n\t\t} else {\n\t\t\tif (document.exitFullscreen) {\n\t\t\t\tdocument.exitFullscreen()\n\t\t\t}\n\t\t}\n\t\tsetState((prev) => ({ ...prev, isFullscreen: !prev.isFullscreen }))\n\t}\n\n\tconst seekTo = (time: number) => {\n\t\tconst video = videoRef.current\n\t\tif (!video || state.duration === 0) return\n\t\tvideo.currentTime = Math.max(0, Math.min(state.duration, time))\n\t}\n\n\tconst controls: VideoControls = {\n\t\ttogglePlay,\n\t\tseekForward,\n\t\tseekBackward,\n\t\ttoggleMute,\n\t\tsetVolume,\n\t\ttoggleFullscreen,\n\t\tseekTo\n\t}\n\n\treturn {\n\t\tvideoRef,\n\t\tstate,\n\t\tcontrols\n\t}\n}\n","/**\n * Intelligent Preloading Hook\n * Combines user behavior analysis with network conditions for optimal preloading\n */\n\nimport { useCallback, useEffect, useMemo, useRef } from \"react\"\nimport { MediaSource } from \"../types\"\n\ninterface IntelligentPreloadingOptions {\n\t/** Enable user behavior tracking */\n\ttrackUserBehavior?: boolean\n\t/** Adapt to network conditions */\n\tadaptToNetwork?: boolean\n\t/** Preload strategy */\n\tstrategy?: \"conservative\" | \"balanced\" | \"aggressive\"\n\t/** Maximum number of items to preload */\n\tmaxPreloadItems?: number\n\t/** Preload radius for playlist items */\n\tpreloadRadius?: number\n}\n\ninterface UserBehaviorData {\n\tmouseMovements: number\n\tscrollEvents: number\n\tkeyPresses: number\n\tfocusEvents: number\n\ttimeOnPage: number\n\tengagementScore: number\n\tlastInteraction: number\n}\n\ninterface PreloadingDecision {\n\tshouldPreload: boolean\n\tpriority: \"high\" | \"medium\" | \"low\"\n\treason: string\n}\n\nexport const useIntelligentPreloading = (\n\tsources: MediaSource[],\n\toptions: IntelligentPreloadingOptions = {}\n) => {\n\tconst {\n\t\ttrackUserBehavior = true,\n\t\tadaptToNetwork = true,\n\t\tstrategy = \"balanced\",\n\t\tmaxPreloadItems = 3,\n\t\tpreloadRadius = 2\n\t} = options\n\n\tconst userBehaviorRef = useRef<UserBehaviorData>({\n\t\tmouseMovements: 0,\n\t\tscrollEvents: 0,\n\t\tkeyPresses: 0,\n\t\tfocusEvents: 0,\n\t\ttimeOnPage: 0,\n\t\tengagementScore: 0,\n\t\tlastInteraction: Date.now()\n\t})\n\n\tconst networkInfoRef = useRef<NetworkInformation | null>(null)\n\tconst preloadedItemsRef = useRef<Set<string>>(new Set())\n\tconst preloadQueueRef = useRef<Array<{ source: MediaSource; priority: number }>>([])\n\n\t// Calculate user engagement score\n\tconst calculateEngagementScore = useCallback((): number => {\n\t\tconst behavior = userBehaviorRef.current\n\t\tconst timeFactor = Math.min(behavior.timeOnPage / 60000, 1) // Cap at 1 minute\n\t\tconst interactionFactor = Math.min(\n\t\t\t(behavior.mouseMovements + behavior.scrollEvents + behavior.keyPresses) / 100,\n\t\t\t1\n\t\t)\n\n\t\treturn (timeFactor * 0.4 + interactionFactor * 0.6) * 100\n\t}, [])\n\n\t// Update user behavior tracking\n\tconst updateUserBehavior = useCallback(\n\t\t(type: keyof UserBehaviorData, increment = 1) => {\n\t\t\tconst behavior = userBehaviorRef.current\n\t\t\tbehavior[type] = typeof behavior[type] === \"number\" ? behavior[type] + increment : Date.now()\n\t\t\tbehavior.engagementScore = calculateEngagementScore()\n\t\t\tbehavior.lastInteraction = Date.now()\n\t\t},\n\t\t[calculateEngagementScore]\n\t)\n\n\t// Get current network conditions\n\tconst getNetworkConditions = useCallback(() => {\n\t\tif (!networkInfoRef.current || !adaptToNetwork) {\n\t\t\treturn { type: \"unknown\", downlink: 10, effectiveType: \"4g\", saveData: false }\n\t\t}\n\n\t\tconst network = networkInfoRef.current\n\t\treturn {\n\t\t\ttype: network.type,\n\t\t\tdownlink: network.downlink || 10,\n\t\t\teffectiveType: network.effectiveType || \"4g\",\n\t\t\tsaveData: network.saveData || false,\n\t\t\trtt: network.rtt || 100\n\t\t}\n\t}, [adaptToNetwork])\n\n\t// Determine if a source should be preloaded\n\tconst shouldPreloadSource = useCallback(\n\t\t(source: MediaSource, index: number, currentIndex: number = 0): PreloadingDecision => {\n\t\t\t// Skip if already preloaded\n\t\t\tif (preloadedItemsRef.current.has(source.src)) {\n\t\t\t\treturn { shouldPreload: false, priority: \"low\", reason: \"Already preloaded\" }\n\t\t\t}\n\n\t\t\t// Check if within preload radius\n\t\t\tconst distance = Math.abs(index - currentIndex)\n\t\t\tif (distance > preloadRadius) {\n\t\t\t\treturn { shouldPreload: false, priority: \"low\", reason: \"Outside preload radius\" }\n\t\t\t}\n\n\t\t\tconst behavior = userBehaviorRef.current\n\t\t\tconst network = getNetworkConditions()\n\t\t\tconst engagementScore = behavior.engagementScore\n\t\t\tconst timeSinceInteraction = Date.now() - behavior.lastInteraction\n\n\t\t\t// Network-based decisions\n\t\t\tif (network.saveData) {\n\t\t\t\treturn { shouldPreload: false, priority: \"low\", reason: \"Data saver mode\" }\n\t\t\t}\n\n\t\t\t// Strategy-based filtering\n\t\t\tlet shouldPreload = false\n\t\t\tlet priority: \"high\" | \"medium\" | \"low\" = \"medium\"\n\t\t\tlet reason = \"\"\n\n\t\t\tswitch (strategy) {\n\t\t\t\tcase \"conservative\":\n\t\t\t\t\tshouldPreload = engagementScore > 70 && network.effectiveType !== \"2g\" && distance === 1\n\t\t\t\t\tpriority = shouldPreload ? \"medium\" : \"low\"\n\t\t\t\t\treason = shouldPreload ? \"High engagement and optimal network\" : \"Conservative strategy\"\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"aggressive\":\n\t\t\t\t\tshouldPreload = engagementScore > 30 && network.effectiveType !== \"slow-2g\"\n\t\t\t\t\tpriority = engagementScore > 70 ? \"high\" : engagementScore > 50 ? \"medium\" : \"low\"\n\t\t\t\t\treason = shouldPreload ? \"Aggressive preloading\" : \"Low engagement\"\n\t\t\t\t\tbreak\n\n\t\t\t\tcase \"balanced\":\n\t\t\t\tdefault:\n\t\t\t\t\tconst networkMultiplier =\n\t\t\t\t\t\tnetwork.effectiveType === \"4g\" ? 1 : network.effectiveType === \"3g\" ? 0.7 : 0.3\n\t\t\t\t\tconst adjustedScore = engagementScore * networkMultiplier\n\n\t\t\t\t\tshouldPreload = adjustedScore > 40 && distance <= 2\n\t\t\t\t\tpriority = adjustedScore > 70 ? \"high\" : adjustedScore > 55 ? \"medium\" : \"low\"\n\t\t\t\t\treason = shouldPreload\n\t\t\t\t\t\t? `Balanced: score ${adjustedScore.toFixed(1)}`\n\t\t\t\t\t\t: \"Low adjusted score\"\n\t\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Additional heuristics\n\t\t\tif (shouldPreload) {\n\t\t\t\t// Prioritize HLS and adaptive streaming\n\t\t\t\tif (source.type === \"hls\" || source.type === \"m3u8\") {\n\t\t\t\t\tpriority = priority === \"low\" ? \"medium\" : \"high\"\n\t\t\t\t}\n\n\t\t\t\t// Boost priority for recent user interaction\n\t\t\t\tif (timeSinceInteraction < 5000) {\n\t\t\t\t\t// Within 5 seconds\n\t\t\t\t\tpriority = \"high\"\n\t\t\t\t\treason += \" + Recent interaction\"\n\t\t\t\t}\n\n\t\t\t\t// Consider content type (video gets higher priority than audio)\n\t\t\t\tif (source.type === \"mp4\" || source.type === \"webm\") {\n\t\t\t\t\tpriority = priority === \"low\" ? \"medium\" : priority\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { shouldPreload, priority, reason }\n\t\t},\n\t\t[strategy, preloadRadius, getNetworkConditions, calculateEngagementScore]\n\t)\n\n\t// Preload a specific source\n\tconst preloadSource = useCallback(async (source: MediaSource, priority: number) => {\n\t\ttry {\n\t\t\t// Create a preload link element\n\t\t\tconst link = document.createElement(\"link\")\n\t\t\tlink.rel = \"preload\"\n\t\t\tlink.href = source.src\n\n\t\t\t// Determine the correct 'as' attribute\n\t\t\tswitch (source.type) {\n\t\t\t\tcase \"hls\":\n\t\t\t\tcase \"m3u8\":\n\t\t\t\t\tlink.as = \"fetch\"\n\t\t\t\t\tbreak\n\t\t\t\tcase \"mp4\":\n\t\t\t\tcase \"webm\":\n\t\t\t\t\tlink.as = \"video\"\n\t\t\t\t\tbreak\n\t\t\t\tcase \"mp3\":\n\t\t\t\tcase \"wav\":\n\t\t\t\tcase \"ogg\":\n\t\t\t\t\tlink.as = \"audio\"\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tlink.as = \"fetch\"\n\t\t\t}\n\n\t\t\tlink.crossOrigin = \"anonymous\"\n\n\t\t\t// Add to document head\n\t\t\tdocument.head.appendChild(link)\n\n\t\t\t// Mark as preloaded\n\t\t\tpreloadedItemsRef.current.add(source.src)\n\n\t\t\tconsole.debug(`Preloaded: ${source.src} (${priority})`)\n\n\t\t\t// Cleanup after 30 seconds to prevent memory issues\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (document.head.contains(link)) {\n\t\t\t\t\tdocument.head.removeChild(link)\n\t\t\t\t}\n\t\t\t}, 30000)\n\t\t} catch (error) {\n\t\t\tconsole.warn(\"Failed to preload source:\", source.src, error)\n\t\t}\n\t}, [])\n\n\t// Process preload queue\n\tconst processPreloadQueue = useCallback(() => {\n\t\tif (preloadQueueRef.current.length === 0) return\n\n\t\t// Sort by priority (higher number = higher priority)\n\t\tconst sortedQueue = [...preloadQueueRef.current].sort((a, b) => b.priority - a.priority)\n\n\t\t// Take top items based on maxPreloadItems\n\t\tconst itemsToPreload = sortedQueue.slice(0, maxPreloadItems)\n\n\t\t// Clear queue\n\t\tpreloadQueueRef.current = []\n\n\t\t// Preload items\n\t\titemsToPreload.forEach(({ source, priority }) => {\n\t\t\tpreloadSource(source, priority)\n\t\t})\n\t}, [maxPreloadItems, preloadSource])\n\n\t// Update preloading decisions\n\tconst updatePreloading = useCallback(\n\t\t(currentIndex: number = 0) => {\n\t\t\tpreloadQueueRef.current = []\n\n\t\t\tsources.forEach((source, index) => {\n\t\t\t\tconst decision = shouldPreloadSource(source, index, currentIndex)\n\n\t\t\t\tif (decision.shouldPreload) {\n\t\t\t\t\tconst priority = decision.priority === \"high\" ? 3 : decision.priority === \"medium\" ? 2 : 1\n\n\t\t\t\t\tpreloadQueueRef.current.push({ source, priority })\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tprocessPreloadQueue()\n\t\t},\n\t\t[sources, shouldPreloadSource, processPreloadQueue]\n\t)\n\n\t// Set up user behavior tracking\n\tuseEffect(() => {\n\t\tif (!trackUserBehavior) return\n\n\t\tconst handleMouseMove = () => updateUserBehavior(\"mouseMovements\")\n\t\tconst handleScroll = () => updateUserBehavior(\"scrollEvents\")\n\t\tconst handleKeyPress = () => updateUserBehavior(\"keyPresses\")\n\t\tconst handleFocus = () => updateUserBehavior(\"focusEvents\")\n\n\t\t// Add event listeners\n\t\tdocument.addEventListener(\"mousemove\", handleMouseMove, { passive: true })\n\t\tdocument.addEventListener(\"scroll\", handleScroll, { passive: true })\n\t\tdocument.addEventListener(\"keydown\", handleKeyPress, { passive: true })\n\t\tdocument.addEventListener(\"focusin\", handleFocus, { passive: true })\n\n\t\t// Update time on page every second\n\t\tconst timeInterval = setInterval(() => {\n\t\t\tupdateUserBehavior(\"timeOnPage\", 1)\n\t\t}, 1000)\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"mousemove\", handleMouseMove)\n\t\t\tdocument.removeEventListener(\"scroll\", handleScroll)\n\t\t\tdocument.removeEventListener(\"keydown\", handleKeyPress)\n\t\t\tdocument.removeEventListener(\"focusin\", handleFocus)\n\t\t\tclearInterval(timeInterval)\n\t\t}\n\t}, [trackUserBehavior, updateUserBehavior])\n\n\t// Set up network monitoring\n\tuseEffect(() => {\n\t\tif (!adaptToNetwork || !(\"connection\" in navigator)) return\n\n\t\tconst network = (navigator as any).connection\n\t\tnetworkInfoRef.current = network\n\n\t\tconst handleNetworkChange = () => {\n\t\t\t// Re-evaluate preloading when network conditions change\n\t\t\tupdatePreloading()\n\t\t}\n\n\t\tnetwork.addEventListener(\"change\", handleNetworkChange)\n\n\t\treturn () => {\n\t\t\tnetwork.removeEventListener(\"change\", handleNetworkChange)\n\t\t}\n\t}, [adaptToNetwork, updatePreloading])\n\n\t// Initial preloading\n\tuseEffect(() => {\n\t\tupdatePreloading()\n\t}, [updatePreloading])\n\n\t// Memoize return values\n\tconst controls = useMemo(\n\t\t() => ({\n\t\t\t/**\n\t\t\t * Manually trigger preloading for specific index\n\t\t\t */\n\t\t\tpreloadAtIndex: (index: number) => {\n\t\t\t\tupdatePreloading(index)\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Get current user behavior data\n\t\t\t */\n\t\t\tgetUserBehavior: () => ({ ...userBehaviorRef.current }),\n\n\t\t\t/**\n\t\t\t * Get current network conditions\n\t\t\t */\n\t\t\tgetNetworkConditions: getNetworkConditions,\n\n\t\t\t/**\n\t\t\t * Clear preloaded items cache\n\t\t\t */\n\t\t\tclearCache: () => {\n\t\t\t\tpreloadedItemsRef.current.clear()\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Get preloading statistics\n\t\t\t */\n\t\t\tgetStats: () => ({\n\t\t\t\tpreloadedItems: preloadedItemsRef.current.size,\n\t\t\t\tengagementScore: userBehaviorRef.current.engagementScore,\n\t\t\t\tqueueLength: preloadQueueRef.current.length,\n\t\t\t\tmaxPreloadItems\n\t\t\t})\n\t\t}),\n\t\t[updatePreloading, getNetworkConditions, maxPreloadItems]\n\t)\n\n\treturn controls\n}\n\nexport default useIntelligentPreloading\n","import { useCallback, useEffect, useMemo, useState } from \"react\"\n\ninterface SubtitleCue {\n\tstart: number\n\tend: number\n\ttext: string\n}\n\nexport function useSubtitles(subtitleSrc?: string) {\n\tconst [subtitlesEnabled, setSubtitlesEnabled] = useState(false)\n\tconst [subtitleCues, setSubtitleCues] = useState<SubtitleCue[]>([])\n\tconst [currentSubtitle, setCurrentSubtitle] = useState(\"\")\n\n\tconst parseVTTTime = (timeStr: string): number => {\n\t\tconst parts = timeStr.split(\":\")\n\t\tconst seconds = parts[2] ? parseFloat(parts[2]) : 0\n\t\tconst minutes = parts[1] ? parseInt(parts[1], 10) * 60 : 0\n\t\tconst hours = parts[0] ? parseInt(parts[0], 10) * 3600 : 0\n\t\treturn hours + minutes + seconds\n\t}\n\n\tconst loadSubtitles = async (url: string) => {\n\t\ttry {\n\t\t\tconst response = await fetch(url)\n\t\t\tconst text = await response.text()\n\n\t\t\tconst cues: SubtitleCue[] = []\n\t\t\tconst lines = text.split(\"\\n\")\n\t\t\tlet i = 0\n\n\t\t\twhile (i < lines.length) {\n\t\t\t\tif (lines[i]?.includes(\"-->\")) {\n\t\t\t\t\tconst [startStr, endStr] = (lines[i] || \"\").split(\"-->\").map((s) => s.trim())\n\t\t\t\t\tconst start = parseVTTTime(startStr || \"\")\n\t\t\t\t\tconst end = parseVTTTime(endStr || \"\")\n\n\t\t\t\t\ti++\n\t\t\t\t\tlet subtitleText = \"\"\n\t\t\t\t\twhile (i < lines.length && lines[i]?.trim() !== \"\") {\n\t\t\t\t\t\tsubtitleText += (subtitleText ? \" \" : \"\") + lines[i]?.trim()\n\t\t\t\t\t\ti++\n\t\t\t\t\t}\n\n\t\t\t\t\tif (subtitleText) {\n\t\t\t\t\t\tcues.push({ start, end, text: subtitleText })\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\tsetSubtitleCues(cues)\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Failed to load subtitles:\", error)\n\t\t}\n\t}\n\n\tconst getCurrentSubtitle = (currentTime: number) => {\n\t\tif (!subtitlesEnabled || subtitleCues.length === 0) return \"\"\n\n\t\tconst currentCue = subtitleCues.find(\n\t\t\t(cue) => currentTime >= cue.start && currentTime <= cue.end\n\t\t)\n\t\treturn currentCue?.text || \"\"\n\t}\n\n\tconst toggleSubtitles = () => {\n\t\tsetSubtitlesEnabled((prev) => {\n\t\t\tconst newEnabled = !prev\n\t\t\tif (newEnabled && subtitleSrc && subtitleCues.length === 0) {\n\t\t\t\tloadSubtitles(subtitleSrc)\n\t\t\t} else if (!newEnabled) {\n\t\t\t\tsetCurrentSubtitle(\"\")\n\t\t\t}\n\t\t\treturn newEnabled\n\t\t})\n\t}\n\n\tuseEffect(() => {\n\t\tif (!subtitlesEnabled) {\n\t\t\tsetCurrentSubtitle(\"\")\n\t\t}\n\t}, [subtitlesEnabled])\n\n\treturn {\n\t\tsubtitlesEnabled,\n\t\tcurrentSubtitle,\n\t\ttoggleSubtitles,\n\t\tgetCurrentSubtitle,\n\t\tsetCurrentSubtitle\n\t}\n}\n","/**\n * Legacy Hooks (Deprecated)\n * These hooks are wrapped with deprecation warnings\n */\n\nimport { showDeprecationWarning } from \"../lib/deprecation\"\n\n// Import current hooks\nimport { useMediaPlayer } from \"./use-media-player\"\nimport { useSubtitles } from \"./useSubtitles\"\n\n// Legacy hook wrappers with deprecation warnings\nexport function useVideoPlayer(props: any) {\n\tshowDeprecationWarning(\"useVideoPlayer\", \"useMediaPlayer (the primary media player hook)\")\n\treturn useMediaPlayer(props)\n}\n\nexport function useEnhancedSubtitles(props: any) {\n\tshowDeprecationWarning(\"useEnhancedSubtitles\", \"useSubtitles (the current subtitle hook)\")\n\treturn useSubtitles(props)\n}\n"],"names":["createOptimisticAction","type","store","payload","optimistic","action","useMediaActionState","actionState","setActionState","React","newActionState","current","useMediaActions","actions","MediaActionTypes","optimisticActions","isPlaying","time","delta","currentVolume","newVolume","isFullscreen","retryLastAction","lastAction","optimisticMediaReducer","state","useMediaOptimistic","actualState","optimisticState","addOptimistic","useOptimistic","dispatchOptimistic","volume","rate","selectors","formatTime","seconds","mins","secs","hours","useEnhancedMediaPlayer","options","mediaRef","useRef","containerRef","isPending","startTransition","useTransition","isSeeking","startSeekTransition","frameCount","lastFrameTime","lastTimeUpdate","useMediaStore","isEnhanced","useMediaSelector","currentTime","duration","isMuted","isLoading","isBuffering","error","buffered","enhancedStore","performanceMetrics","setPerformanceMetrics","optimisticVolume","setOptimisticVolume","newTime","useEffect","media","initProps","key","value","handleTimeUpdate","useCallback","now","handlePlay","handlePause","handleVolumeChange","handleSeeking","handleSeeked","handleProgress","measureRenderTime","fps","prev","eventListeners","event","handler","passive","rafId","performanceLoop","controls","useMemo","play","pause","clampedTime","clampedVolume","container","computedState","useKeyboardControls","enabled","seekStep","volumeStep","handleKeyDown","target","percentage","useMemoryOptimization","maxMemoryUsage","cleanupInterval","enableGC","monitorMemory","observersRef","eventListenersRef","intervalRefs","animationFrameRefs","getMemoryUsage","memory","memoryStats","setMemoryStats","performCleanup","timeout","frameId","observer","listeners","element","useInterval","callback","delay","timeoutId","checkMemory","usage","isHighUsage","addEventListener","index","l","setTimeout","requestAnimationFrame","addObserver","bytes","k","sizes","i","useMediaState","setState","useState","updateState","updates","useMediaPlayer","setPlaying","setCurrentTime","setDuration","setVolume","setMuted","setLoading","setFullscreen","setError","setBuffered","handleDurationChange","handleLoadStart","handleLoadedData","handleError","errorMessage","handleEnded","toggle","seek","setVolumeControl","mute","unmute","toggleMute","enterFullscreen","exitFullscreen","toggleFullscreen","handleFullscreenChange","BREAKPOINTS","detectPlatform","userAgent","isTouchDevice","supportsHaptics","useDeviceInfo","deviceInfo","setDeviceInfo","width","height","updateDeviceInfo","mobileQuery","tabletQuery","desktopQuery","useMobileOptimizations","platform","isMobile","preventZoom","e","useHapticFeedback","pattern","defaultConfig","useTouchGestures","ref","onGesture","config","mergedConfig","triggerHaptic","gestureState","getTouchPoint","touch","getDistance","p1","p2","getVelocity","start","end","timeDiff","createGestureEvent","startPoint","currentPoint","additionalData","handleTouchStart","touches","gestureEvent","handleTouchMove","currentDistance","scale","gestureType","centerPoint","startCenterPoint","startTouch","currentTouch","handleTouchEnd","endTouches","endTouch","distance","velocity","absVelX","absVelY","useMediaGestures","handleGesture","backwardAmount","forwardAmount","volumeAmount","useEnhancedSubtitles","subtitleSrc","subtitleTracks","defaultFontSize","onLoadError","subtitlesEnabled","setSubtitlesEnabled","subtitleCues","setSubtitleCues","currentSubtitle","setCurrentSubtitle","currentTrackId","setCurrentTrackId","fontSize","setFontSize","loadError","setLoadError","setIsLoading","sizeMap","hasSubtitles","parseVTTTime","timeStr","parts","minutes","parseSRTTime","ms","milliseconds","loadSubtitles","url","response","text","cues","lines","isVTT","isSRT","startStr","endStr","s","subtitleText","err","getCurrentSubtitle","cue","toggleSubtitles","newEnabled","srcToLoad","selectSubtitleTrack","trackId","track","t","changeSubtitleFontSize","size","getSubtitleStyles","useKeyboardShortcuts","videoControls","takeScreenshot","video","useMediaControls","showSettings","controlsVisible","setControlsVisible","showVolumeSlider","setShowVolumeSlider","hideTimeoutRef","showControls","handleMouseMove","handleMouseEnter","handleMouseLeave","useScreenshot","videoRef","ctrlKey","canvas","ctx","blob","item","a","useVideoPlayer","handleLoadedMetadata","handleWaiting","handlePlaying","handleCanPlay","ranges","useIntelligentPreloading","sources","trackUserBehavior","adaptToNetwork","strategy","maxPreloadItems","preloadRadius","userBehaviorRef","networkInfoRef","preloadedItemsRef","preloadQueueRef","calculateEngagementScore","behavior","timeFactor","interactionFactor","updateUserBehavior","increment","getNetworkConditions","network","shouldPreloadSource","source","currentIndex","engagementScore","timeSinceInteraction","shouldPreload","priority","reason","networkMultiplier","adjustedScore","preloadSource","link","processPreloadQueue","itemsToPreload","updatePreloading","decision","handleScroll","handleKeyPress","handleFocus","timeInterval","handleNetworkChange","useSubtitles","props","showDeprecationWarning"],"mappings":"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"}