@therealtinhtute/baroiplayer 1.0.6 → 1.0.7

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 (595) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/package.json +1 -1
  3. package/package.json +1 -1
  4. package/dist/context/media.js +0 -2
  5. package/dist/context/media.js.map +0 -1
  6. package/dist/context/media.mjs +0 -15
  7. package/dist/context/media.mjs.map +0 -1
  8. package/dist/context/store.js +0 -2
  9. package/dist/context/store.js.map +0 -1
  10. package/dist/context/store.mjs +0 -5
  11. package/dist/context/store.mjs.map +0 -1
  12. package/dist/context-Af84FynT.js +0 -1179
  13. package/dist/context-Af84FynT.js.map +0 -1
  14. package/dist/context-CwZnPdz0.cjs +0 -23
  15. package/dist/context-CwZnPdz0.cjs.map +0 -1
  16. package/dist/core-events-B5W_j8yU.js +0 -480
  17. package/dist/core-events-B5W_j8yU.js.map +0 -1
  18. package/dist/core-events-CN0-Vhhq.cjs +0 -2
  19. package/dist/core-events-CN0-Vhhq.cjs.map +0 -1
  20. package/dist/core-plugins-Bq9KLany.js +0 -696
  21. package/dist/core-plugins-Bq9KLany.js.map +0 -1
  22. package/dist/core-plugins-CPDSHMiQ.cjs +0 -2
  23. package/dist/core-plugins-CPDSHMiQ.cjs.map +0 -1
  24. package/dist/core.js +0 -37
  25. package/dist/core.js.map +0 -1
  26. package/dist/core.mjs +0 -1217
  27. package/dist/core.mjs.map +0 -1
  28. package/dist/enhanced-components-CXnYiOt6.cjs +0 -2
  29. package/dist/enhanced-components-CXnYiOt6.cjs.map +0 -1
  30. package/dist/enhanced-components-Da0TSvKe.js +0 -1073
  31. package/dist/enhanced-components-Da0TSvKe.js.map +0 -1
  32. package/dist/hooks-BCMilGRf.cjs +0 -4
  33. package/dist/hooks-BCMilGRf.cjs.map +0 -1
  34. package/dist/hooks-BPtHV1ZT.js +0 -2042
  35. package/dist/hooks-BPtHV1ZT.js.map +0 -1
  36. package/dist/index.js.map +0 -1
  37. package/dist/index.mjs.map +0 -1
  38. package/dist/minimal-components-BHJMuaL7.cjs +0 -2
  39. package/dist/minimal-components-BHJMuaL7.cjs.map +0 -1
  40. package/dist/minimal-components-BmqRefl1.js +0 -2002
  41. package/dist/minimal-components-BmqRefl1.js.map +0 -1
  42. package/dist/mona-loading.gif +0 -0
  43. package/dist/performance-monitor--rzKTlbj.js +0 -302
  44. package/dist/performance-monitor--rzKTlbj.js.map +0 -1
  45. package/dist/performance-monitor-cjIvZE2D.cjs +0 -2
  46. package/dist/performance-monitor-cjIvZE2D.cjs.map +0 -1
  47. package/dist/src/adapters/videojs-adapter.d.ts.map +0 -1
  48. package/dist/src/adapters/videojs-adapter.js +0 -350
  49. package/dist/src/assets/mona-loading.gif +0 -0
  50. package/dist/src/components/AnimateLoading.d.ts.map +0 -1
  51. package/dist/src/components/AnimateLoading.js +0 -41
  52. package/dist/src/components/LoadingState.d.ts.map +0 -1
  53. package/dist/src/components/LoadingState.js +0 -111
  54. package/dist/src/components/accessibility/keyboard-help-overlay.d.ts.map +0 -1
  55. package/dist/src/components/accessibility/keyboard-help-overlay.js +0 -90
  56. package/dist/src/components/audio-player.d.ts.map +0 -1
  57. package/dist/src/components/audio-player.js +0 -31
  58. package/dist/src/components/basic/index.d.ts.map +0 -1
  59. package/dist/src/components/basic/index.js +0 -29
  60. package/dist/src/components/enhanced/advanced-features.d.ts.map +0 -1
  61. package/dist/src/components/enhanced/advanced-features.js +0 -64
  62. package/dist/src/components/enhanced/debug-panel.d.ts.map +0 -1
  63. package/dist/src/components/enhanced/debug-panel.js +0 -94
  64. package/dist/src/components/enhanced/enhanced-controls.d.ts.map +0 -1
  65. package/dist/src/components/enhanced/enhanced-controls.js +0 -233
  66. package/dist/src/components/enhanced/enhanced-media-player.d.ts.map +0 -1
  67. package/dist/src/components/enhanced/enhanced-media-player.js +0 -316
  68. package/dist/src/components/enhanced/error-handling.d.ts.map +0 -1
  69. package/dist/src/components/enhanced/error-handling.js +0 -153
  70. package/dist/src/components/enhanced/index.d.ts.map +0 -1
  71. package/dist/src/components/enhanced/index.js +0 -10
  72. package/dist/src/components/enhanced/media-player-enhanced.d.ts.map +0 -1
  73. package/dist/src/components/enhanced/media-player-enhanced.js +0 -250
  74. package/dist/src/components/examples/basic-video-player.d.ts.map +0 -1
  75. package/dist/src/components/examples/basic-video-player.js +0 -16
  76. package/dist/src/components/examples/custom-controls-example.d.ts.map +0 -1
  77. package/dist/src/components/examples/custom-controls-example.js +0 -12
  78. package/dist/src/components/examples/enhanced-controls-example.d.ts.map +0 -1
  79. package/dist/src/components/examples/enhanced-controls-example.js +0 -18
  80. package/dist/src/components/examples/enhanced-media-player-example.d.ts.map +0 -1
  81. package/dist/src/components/examples/enhanced-media-player-example.js +0 -13
  82. package/dist/src/components/examples/loading-states-demo.d.ts.map +0 -1
  83. package/dist/src/components/examples/loading-states-demo.js +0 -41
  84. package/dist/src/components/examples/react-19-demo.d.ts.map +0 -1
  85. package/dist/src/components/examples/react-19-demo.js +0 -104
  86. package/dist/src/components/examples/volume-orientation-demo.d.ts.map +0 -1
  87. package/dist/src/components/examples/volume-orientation-demo.js +0 -31
  88. package/dist/src/components/icon-demo.d.ts.map +0 -1
  89. package/dist/src/components/icon-demo.js +0 -16
  90. package/dist/src/components/icons/index.d.ts.map +0 -1
  91. package/dist/src/components/icons/index.js +0 -59
  92. package/dist/src/components/icons/svg-icons/ArrowLeftIcon.d.ts.map +0 -1
  93. package/dist/src/components/icons/svg-icons/ArrowLeftIcon.js +0 -3
  94. package/dist/src/components/icons/svg-icons/ArrowRightIcon.d.ts.map +0 -1
  95. package/dist/src/components/icons/svg-icons/ArrowRightIcon.js +0 -3
  96. package/dist/src/components/icons/svg-icons/AudioIcon.d.ts.map +0 -1
  97. package/dist/src/components/icons/svg-icons/AudioIcon.js +0 -4
  98. package/dist/src/components/icons/svg-icons/BackwardIcon.d.ts.map +0 -1
  99. package/dist/src/components/icons/svg-icons/BackwardIcon.js +0 -3
  100. package/dist/src/components/icons/svg-icons/CameraIcon.d.ts.map +0 -1
  101. package/dist/src/components/icons/svg-icons/CameraIcon.js +0 -4
  102. package/dist/src/components/icons/svg-icons/CheckIcon.d.ts.map +0 -1
  103. package/dist/src/components/icons/svg-icons/CheckIcon.js +0 -4
  104. package/dist/src/components/icons/svg-icons/EnablePiPIcon.d.ts.map +0 -1
  105. package/dist/src/components/icons/svg-icons/EnablePiPIcon.js +0 -5
  106. package/dist/src/components/icons/svg-icons/ForwardIcon.d.ts.map +0 -1
  107. package/dist/src/components/icons/svg-icons/ForwardIcon.js +0 -3
  108. package/dist/src/components/icons/svg-icons/FullscreenEnterIcon.d.ts.map +0 -1
  109. package/dist/src/components/icons/svg-icons/FullscreenEnterIcon.js +0 -3
  110. package/dist/src/components/icons/svg-icons/FullscreenExitIcon.d.ts.map +0 -1
  111. package/dist/src/components/icons/svg-icons/FullscreenExitIcon.js +0 -3
  112. package/dist/src/components/icons/svg-icons/LoadingIcon.d.ts.map +0 -1
  113. package/dist/src/components/icons/svg-icons/LoadingIcon.js +0 -3
  114. package/dist/src/components/icons/svg-icons/PauseIcon.d.ts.map +0 -1
  115. package/dist/src/components/icons/svg-icons/PauseIcon.js +0 -3
  116. package/dist/src/components/icons/svg-icons/PlayIcon.d.ts.map +0 -1
  117. package/dist/src/components/icons/svg-icons/PlayIcon.js +0 -3
  118. package/dist/src/components/icons/svg-icons/PlaybackSpeedIcon.d.ts.map +0 -1
  119. package/dist/src/components/icons/svg-icons/PlaybackSpeedIcon.js +0 -3
  120. package/dist/src/components/icons/svg-icons/QualityIcon.d.ts.map +0 -1
  121. package/dist/src/components/icons/svg-icons/QualityIcon.js +0 -3
  122. package/dist/src/components/icons/svg-icons/SettingsIcon.d.ts.map +0 -1
  123. package/dist/src/components/icons/svg-icons/SettingsIcon.js +0 -3
  124. package/dist/src/components/icons/svg-icons/SliderIcon.d.ts.map +0 -1
  125. package/dist/src/components/icons/svg-icons/SliderIcon.js +0 -3
  126. package/dist/src/components/icons/svg-icons/SubtitleIcon.d.ts.map +0 -1
  127. package/dist/src/components/icons/svg-icons/SubtitleIcon.js +0 -3
  128. package/dist/src/components/icons/svg-icons/SubtitleOffIcon.d.ts.map +0 -1
  129. package/dist/src/components/icons/svg-icons/SubtitleOffIcon.js +0 -3
  130. package/dist/src/components/icons/svg-icons/UnPiPIcon.d.ts.map +0 -1
  131. package/dist/src/components/icons/svg-icons/UnPiPIcon.js +0 -5
  132. package/dist/src/components/icons/svg-icons/VolumeMutedIcon.d.ts.map +0 -1
  133. package/dist/src/components/icons/svg-icons/VolumeMutedIcon.js +0 -3
  134. package/dist/src/components/icons/svg-icons/VolumeOneIcon.d.ts.map +0 -1
  135. package/dist/src/components/icons/svg-icons/VolumeOneIcon.js +0 -3
  136. package/dist/src/components/icons/svg-icons/VolumeThreeIcon.d.ts.map +0 -1
  137. package/dist/src/components/icons/svg-icons/VolumeThreeIcon.js +0 -3
  138. package/dist/src/components/icons/svg-icons/VolumeTwoIcon.d.ts.map +0 -1
  139. package/dist/src/components/icons/svg-icons/VolumeTwoIcon.js +0 -3
  140. package/dist/src/components/legacy.d.ts.map +0 -1
  141. package/dist/src/components/legacy.js +0 -52
  142. package/dist/src/components/media-metadata-display.d.ts.map +0 -1
  143. package/dist/src/components/media-metadata-display.js +0 -20
  144. package/dist/src/components/media-player-audio.d.ts.map +0 -1
  145. package/dist/src/components/media-player-audio.js +0 -18
  146. package/dist/src/components/media-player-controls.d.ts.map +0 -1
  147. package/dist/src/components/media-player-controls.js +0 -150
  148. package/dist/src/components/media-player-error.d.ts.map +0 -1
  149. package/dist/src/components/media-player-error.js +0 -85
  150. package/dist/src/components/media-player-fullscreen.d.ts.map +0 -1
  151. package/dist/src/components/media-player-fullscreen.js +0 -68
  152. package/dist/src/components/media-player-hls.d.ts.map +0 -1
  153. package/dist/src/components/media-player-hls.js +0 -20
  154. package/dist/src/components/media-player-loading.d.ts.map +0 -1
  155. package/dist/src/components/media-player-loading.js +0 -53
  156. package/dist/src/components/media-player-play.d.ts.map +0 -1
  157. package/dist/src/components/media-player-play.js +0 -44
  158. package/dist/src/components/media-player-root.d.ts.map +0 -1
  159. package/dist/src/components/media-player-root.js +0 -243
  160. package/dist/src/components/media-player-seek.d.ts.map +0 -1
  161. package/dist/src/components/media-player-seek.js +0 -92
  162. package/dist/src/components/media-player-time.d.ts.map +0 -1
  163. package/dist/src/components/media-player-time.js +0 -57
  164. package/dist/src/components/media-player-tooltip.d.ts.map +0 -1
  165. package/dist/src/components/media-player-tooltip.js +0 -14
  166. package/dist/src/components/media-player-video.d.ts.map +0 -1
  167. package/dist/src/components/media-player-video.js +0 -18
  168. package/dist/src/components/media-player-volume.d.ts.map +0 -1
  169. package/dist/src/components/media-player-volume.js +0 -88
  170. package/dist/src/components/media-player.d.ts.map +0 -1
  171. package/dist/src/components/media-player.js +0 -67
  172. package/dist/src/components/media-suspense.d.ts.map +0 -1
  173. package/dist/src/components/media-suspense.js +0 -173
  174. package/dist/src/components/player-settings-form.d.ts.map +0 -1
  175. package/dist/src/components/player-settings-form.js +0 -46
  176. package/dist/src/components/react-player-wrapper.d.ts.map +0 -1
  177. package/dist/src/components/react-player-wrapper.js +0 -163
  178. package/dist/src/components/simple-video-player.d.ts.map +0 -1
  179. package/dist/src/components/simple-video-player.js +0 -41
  180. package/dist/src/components/ui/enhanced-seek-bar.d.ts.map +0 -1
  181. package/dist/src/components/ui/enhanced-seek-bar.js +0 -112
  182. package/dist/src/components/ui/fullscreen-button.d.ts.map +0 -1
  183. package/dist/src/components/ui/fullscreen-button.js +0 -21
  184. package/dist/src/components/ui/media-resource-preloader.d.ts.map +0 -1
  185. package/dist/src/components/ui/media-resource-preloader.js +0 -295
  186. package/dist/src/components/ui/play-button.d.ts.map +0 -1
  187. package/dist/src/components/ui/play-button.js +0 -26
  188. package/dist/src/components/ui/seek-bar.d.ts.map +0 -1
  189. package/dist/src/components/ui/seek-bar.js +0 -54
  190. package/dist/src/components/ui/time-display.d.ts.map +0 -1
  191. package/dist/src/components/ui/time-display.js +0 -18
  192. package/dist/src/components/ui/volume-control.d.ts.map +0 -1
  193. package/dist/src/components/ui/volume-control.js +0 -71
  194. package/dist/src/components/unified/base-media-player.d.ts.map +0 -1
  195. package/dist/src/components/unified/base-media-player.js +0 -104
  196. package/dist/src/components/unified/media-player.d.ts.map +0 -1
  197. package/dist/src/components/unified/media-player.js +0 -41
  198. package/dist/src/components/variants/minimal/AccessibleMinimalPlayer.d.ts.map +0 -1
  199. package/dist/src/components/variants/minimal/AccessibleMinimalPlayer.js +0 -322
  200. package/dist/src/components/variants/minimal/EnhancedMinimalMediaPlayer.d.ts.map +0 -1
  201. package/dist/src/components/variants/minimal/EnhancedMinimalMediaPlayer.js +0 -280
  202. package/dist/src/components/variants/minimal/MinimalControls.d.ts.map +0 -1
  203. package/dist/src/components/variants/minimal/MinimalControls.js +0 -19
  204. package/dist/src/components/variants/minimal/MinimalLoading.d.ts.map +0 -1
  205. package/dist/src/components/variants/minimal/MinimalLoading.js +0 -6
  206. package/dist/src/components/variants/minimal/MinimalMediaPlayer.d.ts.map +0 -1
  207. package/dist/src/components/variants/minimal/MinimalMediaPlayer.js +0 -135
  208. package/dist/src/components/variants/minimal/MinimalOverlay.d.ts.map +0 -1
  209. package/dist/src/components/variants/minimal/MinimalOverlay.js +0 -15
  210. package/dist/src/components/variants/minimal/MinimalPlayButton.d.ts.map +0 -1
  211. package/dist/src/components/variants/minimal/MinimalPlayButton.js +0 -29
  212. package/dist/src/components/variants/minimal/MinimalSeekBar.d.ts.map +0 -1
  213. package/dist/src/components/variants/minimal/MinimalSeekBar.js +0 -73
  214. package/dist/src/components/variants/minimal/MinimalVolumeControl.d.ts.map +0 -1
  215. package/dist/src/components/variants/minimal/MinimalVolumeControl.js +0 -29
  216. package/dist/src/components/variants/minimal/SimpleMinimalPlayer.d.ts.map +0 -1
  217. package/dist/src/components/variants/minimal/SimpleMinimalPlayer.js +0 -51
  218. package/dist/src/components/variants/minimal/components/CenterPlayButton.d.ts.map +0 -1
  219. package/dist/src/components/variants/minimal/components/CenterPlayButton.js +0 -8
  220. package/dist/src/components/variants/minimal/components/ControlBar.d.ts.map +0 -1
  221. package/dist/src/components/variants/minimal/components/ControlBar.js +0 -10
  222. package/dist/src/components/variants/minimal/components/EnhancedSettingsMenu.d.ts.map +0 -1
  223. package/dist/src/components/variants/minimal/components/EnhancedSettingsMenu.js +0 -68
  224. package/dist/src/components/variants/minimal/components/PlaybackControls.d.ts.map +0 -1
  225. package/dist/src/components/variants/minimal/components/PlaybackControls.js +0 -9
  226. package/dist/src/components/variants/minimal/components/RightControls.d.ts.map +0 -1
  227. package/dist/src/components/variants/minimal/components/RightControls.js +0 -40
  228. package/dist/src/components/variants/minimal/components/SeekBar.d.ts.map +0 -1
  229. package/dist/src/components/variants/minimal/components/SeekBar.js +0 -43
  230. package/dist/src/components/variants/minimal/components/SettingsDropdown.d.ts.map +0 -1
  231. package/dist/src/components/variants/minimal/components/SettingsDropdown.js +0 -18
  232. package/dist/src/components/variants/minimal/components/SubtitleDisplay.d.ts.map +0 -1
  233. package/dist/src/components/variants/minimal/components/SubtitleDisplay.js +0 -6
  234. package/dist/src/components/variants/minimal/components/TimeDisplay.d.ts.map +0 -1
  235. package/dist/src/components/variants/minimal/components/TimeDisplay.js +0 -5
  236. package/dist/src/components/variants/minimal/components/VideoElement.d.ts.map +0 -1
  237. package/dist/src/components/variants/minimal/components/VideoElement.js +0 -4
  238. package/dist/src/components/variants/minimal/components/VolumeControl.d.ts.map +0 -1
  239. package/dist/src/components/variants/minimal/components/VolumeControl.js +0 -99
  240. package/dist/src/components/variants/minimal/index.d.ts.map +0 -1
  241. package/dist/src/components/variants/minimal/index.js +0 -8
  242. package/dist/src/components/video-player.d.ts.map +0 -1
  243. package/dist/src/components/video-player.js +0 -38
  244. package/dist/src/context/error-handling.d.ts.map +0 -1
  245. package/dist/src/context/error-handling.js +0 -300
  246. package/dist/src/context/media-context.d.ts.map +0 -1
  247. package/dist/src/context/media-context.js +0 -121
  248. package/dist/src/context/media-provider.d.ts.map +0 -1
  249. package/dist/src/context/media-provider.js +0 -164
  250. package/dist/src/context/media-store.d.ts.map +0 -1
  251. package/dist/src/context/media-store.js +0 -273
  252. package/dist/src/context/persistence.d.ts.map +0 -1
  253. package/dist/src/context/persistence.js +0 -356
  254. package/dist/src/core/events/event-system.d.ts.map +0 -1
  255. package/dist/src/core/events/event-system.js +0 -288
  256. package/dist/src/core/events/hooks.d.ts.map +0 -1
  257. package/dist/src/core/events/hooks.js +0 -198
  258. package/dist/src/core/events/index.d.ts.map +0 -1
  259. package/dist/src/core/events/index.js +0 -7
  260. package/dist/src/core/events/middleware.d.ts.map +0 -1
  261. package/dist/src/core/events/middleware.js +0 -219
  262. package/dist/src/core/index.d.ts.map +0 -1
  263. package/dist/src/core/index.js +0 -15
  264. package/dist/src/core/optimization/bundle-optimizer.d.ts.map +0 -1
  265. package/dist/src/core/optimization/bundle-optimizer.js +0 -217
  266. package/dist/src/core/performance/cicd.d.ts.map +0 -1
  267. package/dist/src/core/performance/cicd.js +0 -83
  268. package/dist/src/core/performance/index.d.ts.map +0 -1
  269. package/dist/src/core/performance/index.js +0 -14
  270. package/dist/src/core/performance/media-loading-optimizer.d.ts.map +0 -1
  271. package/dist/src/core/performance/media-loading-optimizer.js +0 -404
  272. package/dist/src/core/performance/performance-budgets.d.ts.map +0 -1
  273. package/dist/src/core/performance/performance-budgets.js +0 -326
  274. package/dist/src/core/performance/performance-monitor.d.ts.map +0 -1
  275. package/dist/src/core/performance/performance-monitor.js +0 -297
  276. package/dist/src/core/performance/performance-testing.d.ts.map +0 -1
  277. package/dist/src/core/performance/performance-testing.js +0 -314
  278. package/dist/src/core/plugins/base-plugin.d.ts.map +0 -1
  279. package/dist/src/core/plugins/base-plugin.js +0 -151
  280. package/dist/src/core/plugins/enhanced-plugin-system.d.ts.map +0 -1
  281. package/dist/src/core/plugins/enhanced-plugin-system.js +0 -305
  282. package/dist/src/core/plugins/examples/analytics-plugin.d.ts.map +0 -1
  283. package/dist/src/core/plugins/examples/analytics-plugin.js +0 -191
  284. package/dist/src/core/plugins/index.d.ts.map +0 -1
  285. package/dist/src/core/plugins/index.js +0 -9
  286. package/dist/src/core/plugins/registry.d.ts.map +0 -1
  287. package/dist/src/core/plugins/registry.js +0 -261
  288. package/dist/src/core/plugins/types.d.ts.map +0 -1
  289. package/dist/src/core/plugins/types.js +0 -31
  290. package/dist/src/core/plugins/utils.d.ts.map +0 -1
  291. package/dist/src/core/plugins/utils.js +0 -274
  292. package/dist/src/core/progressive-loading.d.ts.map +0 -1
  293. package/dist/src/core/progressive-loading.js +0 -239
  294. package/dist/src/core/providers/enhanced-hls-provider.d.ts.map +0 -1
  295. package/dist/src/core/providers/enhanced-hls-provider.js +0 -273
  296. package/dist/src/core/providers/service-provider.d.ts.map +0 -1
  297. package/dist/src/core/providers/service-provider.js +0 -105
  298. package/dist/src/core/utils.d.ts.map +0 -1
  299. package/dist/src/core/utils.js +0 -21
  300. package/dist/src/features/media-session/media-session-manager.d.ts.map +0 -1
  301. package/dist/src/features/media-session/media-session-manager.js +0 -331
  302. package/dist/src/features/picture-in-picture/pip-manager.d.ts.map +0 -1
  303. package/dist/src/features/picture-in-picture/pip-manager.js +0 -353
  304. package/dist/src/features/playlist/playlist-manager.d.ts.map +0 -1
  305. package/dist/src/features/playlist/playlist-manager.js +0 -475
  306. package/dist/src/features/subtitles/subtitle-manager.d.ts.map +0 -1
  307. package/dist/src/features/subtitles/subtitle-manager.js +0 -335
  308. package/dist/src/features/subtitles/subtitle-parser.d.ts.map +0 -1
  309. package/dist/src/features/subtitles/subtitle-parser.js +0 -217
  310. package/dist/src/features/thumbnails/thumbnail-generator.d.ts.map +0 -1
  311. package/dist/src/features/thumbnails/thumbnail-generator.js +0 -388
  312. package/dist/src/hooks/accessibility/index.d.ts.map +0 -1
  313. package/dist/src/hooks/accessibility/index.js +0 -4
  314. package/dist/src/hooks/accessibility/use-accessibility-preferences.d.ts.map +0 -1
  315. package/dist/src/hooks/accessibility/use-accessibility-preferences.js +0 -156
  316. package/dist/src/hooks/accessibility/use-focus-management.d.ts.map +0 -1
  317. package/dist/src/hooks/accessibility/use-focus-management.js +0 -142
  318. package/dist/src/hooks/accessibility/use-keyboard-shortcuts.d.ts.map +0 -1
  319. package/dist/src/hooks/accessibility/use-keyboard-shortcuts.js +0 -101
  320. package/dist/src/hooks/accessibility/use-screen-reader.d.ts.map +0 -1
  321. package/dist/src/hooks/accessibility/use-screen-reader.js +0 -148
  322. package/dist/src/hooks/core/index.d.ts.map +0 -1
  323. package/dist/src/hooks/core/index.js +0 -19
  324. package/dist/src/hooks/legacy.d.ts.map +0 -1
  325. package/dist/src/hooks/legacy.js +0 -17
  326. package/dist/src/hooks/use-enhanced-media-player.d.ts.map +0 -1
  327. package/dist/src/hooks/use-enhanced-media-player.js +0 -395
  328. package/dist/src/hooks/use-intelligent-preloading.d.ts.map +0 -1
  329. package/dist/src/hooks/use-intelligent-preloading.js +0 -258
  330. package/dist/src/hooks/use-keyboard-controls.d.ts.map +0 -1
  331. package/dist/src/hooks/use-keyboard-controls.js +0 -83
  332. package/dist/src/hooks/use-media-actions.d.ts.map +0 -1
  333. package/dist/src/hooks/use-media-actions.js +0 -121
  334. package/dist/src/hooks/use-media-metadata.d.ts.map +0 -1
  335. package/dist/src/hooks/use-media-metadata.js +0 -74
  336. package/dist/src/hooks/use-media-optimistic.d.ts.map +0 -1
  337. package/dist/src/hooks/use-media-optimistic.js +0 -205
  338. package/dist/src/hooks/use-media-player.d.ts.map +0 -1
  339. package/dist/src/hooks/use-media-player.js +0 -251
  340. package/dist/src/hooks/use-media-state.d.ts.map +0 -1
  341. package/dist/src/hooks/use-media-state.js +0 -162
  342. package/dist/src/hooks/use-memory-optimization.d.ts.map +0 -1
  343. package/dist/src/hooks/use-memory-optimization.js +0 -288
  344. package/dist/src/hooks/use-optimistic-controls.d.ts.map +0 -1
  345. package/dist/src/hooks/use-optimistic-controls.js +0 -60
  346. package/dist/src/hooks/use-optimized-media.d.ts.map +0 -1
  347. package/dist/src/hooks/use-optimized-media.js +0 -211
  348. package/dist/src/hooks/use-touch-gestures.d.ts.map +0 -1
  349. package/dist/src/hooks/use-touch-gestures.js +0 -289
  350. package/dist/src/hooks/useEnhancedSubtitles.d.ts.map +0 -1
  351. package/dist/src/hooks/useEnhancedSubtitles.js +0 -205
  352. package/dist/src/hooks/useKeyboardShortcuts.d.ts.map +0 -1
  353. package/dist/src/hooks/useKeyboardShortcuts.js +0 -59
  354. package/dist/src/hooks/useMediaControls.d.ts.map +0 -1
  355. package/dist/src/hooks/useMediaControls.js +0 -44
  356. package/dist/src/hooks/useScreenshot.d.ts.map +0 -1
  357. package/dist/src/hooks/useScreenshot.js +0 -56
  358. package/dist/src/hooks/useSubtitles.d.ts.map +0 -1
  359. package/dist/src/hooks/useSubtitles.js +0 -73
  360. package/dist/src/hooks/useVideoPlayer.d.ts.map +0 -1
  361. package/dist/src/hooks/useVideoPlayer.js +0 -184
  362. package/dist/src/icons/components/FullscreenIcon.d.ts.map +0 -1
  363. package/dist/src/icons/components/FullscreenIcon.js +0 -11
  364. package/dist/src/icons/components/SettingsIcon.d.ts.map +0 -1
  365. package/dist/src/icons/components/SettingsIcon.js +0 -11
  366. package/dist/src/icons/components/animated/LoadingIcon.d.ts.map +0 -1
  367. package/dist/src/icons/components/animated/LoadingIcon.js +0 -11
  368. package/dist/src/icons/components/animated/PlayPauseIcon.d.ts.map +0 -1
  369. package/dist/src/icons/components/animated/PlayPauseIcon.js +0 -9
  370. package/dist/src/icons/components/media/PauseIcon.d.ts.map +0 -1
  371. package/dist/src/icons/components/media/PauseIcon.js +0 -12
  372. package/dist/src/icons/components/media/PlayIcon.d.ts.map +0 -1
  373. package/dist/src/icons/components/media/PlayIcon.js +0 -12
  374. package/dist/src/icons/components/volume/VolumeIcon.d.ts.map +0 -1
  375. package/dist/src/icons/components/volume/VolumeIcon.js +0 -11
  376. package/dist/src/icons/components/volume/VolumeOffIcon.d.ts.map +0 -1
  377. package/dist/src/icons/components/volume/VolumeOffIcon.js +0 -11
  378. package/dist/src/icons/index.d.ts.map +0 -1
  379. package/dist/src/icons/index.js +0 -45
  380. package/dist/src/icons/provider.d.ts.map +0 -1
  381. package/dist/src/icons/provider.js +0 -37
  382. package/dist/src/icons/types.d.ts.map +0 -1
  383. package/dist/src/icons/types.js +0 -1
  384. package/dist/src/index-enhanced.d.ts.map +0 -1
  385. package/dist/src/index-enhanced.js +0 -16
  386. package/dist/src/index-legacy.d.ts.map +0 -1
  387. package/dist/src/index-legacy.js +0 -97
  388. package/dist/src/index.d.ts.map +0 -1
  389. package/dist/src/index.js +0 -90
  390. package/dist/src/index.minimal.d.ts.map +0 -1
  391. package/dist/src/index.minimal.js +0 -3
  392. package/dist/src/lib/deprecation.d.ts.map +0 -1
  393. package/dist/src/lib/deprecation.js +0 -31
  394. package/dist/src/lib/format-time.d.ts.map +0 -1
  395. package/dist/src/lib/format-time.js +0 -32
  396. package/dist/src/lib/index.d.ts.map +0 -1
  397. package/dist/src/lib/index.js +0 -3
  398. package/dist/src/lib/utils.d.ts.map +0 -1
  399. package/dist/src/lib/utils.js +0 -5
  400. package/dist/src/test/setup.d.ts.map +0 -1
  401. package/dist/src/test/setup.js +0 -65
  402. package/dist/src/types/events.d.ts.map +0 -1
  403. package/dist/src/types/events.js +0 -2
  404. package/dist/src/types/formats.d.ts.map +0 -1
  405. package/dist/src/types/formats.js +0 -63
  406. package/dist/src/types/index.d.ts.map +0 -1
  407. package/dist/src/types/index.js +0 -4
  408. package/dist/utils-Db13763z.cjs +0 -9
  409. package/dist/utils-Db13763z.cjs.map +0 -1
  410. package/dist/utils-nTO4AnHo.js +0 -2809
  411. package/dist/utils-nTO4AnHo.js.map +0 -1
  412. package/dist/utils.js +0 -2
  413. package/dist/utils.js.map +0 -1
  414. package/dist/utils.mjs +0 -7
  415. package/dist/utils.mjs.map +0 -1
  416. package/src/adapters/videojs-adapter.js +0 -350
  417. package/src/components/AnimateLoading.js +0 -41
  418. package/src/components/LoadingState.js +0 -111
  419. package/src/components/accessibility/keyboard-help-overlay.js +0 -90
  420. package/src/components/audio-player.js +0 -31
  421. package/src/components/basic/index.js +0 -29
  422. package/src/components/enhanced/advanced-features.js +0 -64
  423. package/src/components/enhanced/debug-panel.js +0 -94
  424. package/src/components/enhanced/enhanced-controls.js +0 -233
  425. package/src/components/enhanced/enhanced-media-player.js +0 -316
  426. package/src/components/enhanced/error-handling.js +0 -153
  427. package/src/components/enhanced/index.js +0 -10
  428. package/src/components/enhanced/media-player-enhanced.js +0 -250
  429. package/src/components/examples/basic-video-player.js +0 -16
  430. package/src/components/examples/custom-controls-example.js +0 -12
  431. package/src/components/examples/enhanced-controls-example.js +0 -18
  432. package/src/components/examples/enhanced-media-player-example.js +0 -13
  433. package/src/components/examples/loading-states-demo.js +0 -41
  434. package/src/components/examples/react-19-demo.js +0 -104
  435. package/src/components/examples/volume-orientation-demo.js +0 -31
  436. package/src/components/icon-demo.js +0 -16
  437. package/src/components/icons/index.js +0 -59
  438. package/src/components/icons/svg-icons/ArrowLeftIcon.js +0 -3
  439. package/src/components/icons/svg-icons/ArrowRightIcon.js +0 -3
  440. package/src/components/icons/svg-icons/AudioIcon.js +0 -4
  441. package/src/components/icons/svg-icons/BackwardIcon.js +0 -3
  442. package/src/components/icons/svg-icons/CameraIcon.js +0 -4
  443. package/src/components/icons/svg-icons/CheckIcon.js +0 -4
  444. package/src/components/icons/svg-icons/EnablePiPIcon.js +0 -5
  445. package/src/components/icons/svg-icons/ForwardIcon.js +0 -3
  446. package/src/components/icons/svg-icons/FullscreenEnterIcon.js +0 -3
  447. package/src/components/icons/svg-icons/FullscreenExitIcon.js +0 -3
  448. package/src/components/icons/svg-icons/LoadingIcon.js +0 -3
  449. package/src/components/icons/svg-icons/PauseIcon.js +0 -3
  450. package/src/components/icons/svg-icons/PlayIcon.js +0 -3
  451. package/src/components/icons/svg-icons/PlaybackSpeedIcon.js +0 -3
  452. package/src/components/icons/svg-icons/QualityIcon.js +0 -3
  453. package/src/components/icons/svg-icons/SettingsIcon.js +0 -3
  454. package/src/components/icons/svg-icons/SliderIcon.js +0 -3
  455. package/src/components/icons/svg-icons/SubtitleIcon.js +0 -3
  456. package/src/components/icons/svg-icons/SubtitleOffIcon.js +0 -3
  457. package/src/components/icons/svg-icons/UnPiPIcon.js +0 -5
  458. package/src/components/icons/svg-icons/VolumeMutedIcon.js +0 -3
  459. package/src/components/icons/svg-icons/VolumeOneIcon.js +0 -3
  460. package/src/components/icons/svg-icons/VolumeThreeIcon.js +0 -3
  461. package/src/components/icons/svg-icons/VolumeTwoIcon.js +0 -3
  462. package/src/components/legacy.js +0 -52
  463. package/src/components/media-metadata-display.js +0 -20
  464. package/src/components/media-player-audio.js +0 -18
  465. package/src/components/media-player-controls.js +0 -150
  466. package/src/components/media-player-error.js +0 -85
  467. package/src/components/media-player-fullscreen.js +0 -68
  468. package/src/components/media-player-hls.js +0 -20
  469. package/src/components/media-player-loading.js +0 -53
  470. package/src/components/media-player-play.js +0 -44
  471. package/src/components/media-player-root.js +0 -243
  472. package/src/components/media-player-seek.js +0 -92
  473. package/src/components/media-player-time.js +0 -57
  474. package/src/components/media-player-tooltip.js +0 -14
  475. package/src/components/media-player-video.js +0 -18
  476. package/src/components/media-player-volume.js +0 -88
  477. package/src/components/media-player.js +0 -67
  478. package/src/components/media-suspense.js +0 -173
  479. package/src/components/player-settings-form.js +0 -46
  480. package/src/components/react-player-wrapper.js +0 -163
  481. package/src/components/simple-video-player.js +0 -41
  482. package/src/components/ui/enhanced-seek-bar.js +0 -112
  483. package/src/components/ui/fullscreen-button.js +0 -21
  484. package/src/components/ui/media-resource-preloader.js +0 -295
  485. package/src/components/ui/play-button.js +0 -26
  486. package/src/components/ui/seek-bar.js +0 -54
  487. package/src/components/ui/time-display.js +0 -18
  488. package/src/components/ui/volume-control.js +0 -71
  489. package/src/components/unified/base-media-player.js +0 -104
  490. package/src/components/unified/media-player.js +0 -41
  491. package/src/components/variants/minimal/AccessibleMinimalPlayer.js +0 -322
  492. package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.js +0 -280
  493. package/src/components/variants/minimal/MinimalControls.js +0 -19
  494. package/src/components/variants/minimal/MinimalLoading.js +0 -6
  495. package/src/components/variants/minimal/MinimalMediaPlayer.js +0 -135
  496. package/src/components/variants/minimal/MinimalOverlay.js +0 -15
  497. package/src/components/variants/minimal/MinimalPlayButton.js +0 -29
  498. package/src/components/variants/minimal/MinimalSeekBar.js +0 -73
  499. package/src/components/variants/minimal/MinimalVolumeControl.js +0 -29
  500. package/src/components/variants/minimal/SimpleMinimalPlayer.js +0 -51
  501. package/src/components/variants/minimal/components/CenterPlayButton.js +0 -8
  502. package/src/components/variants/minimal/components/ControlBar.js +0 -10
  503. package/src/components/variants/minimal/components/EnhancedSettingsMenu.js +0 -68
  504. package/src/components/variants/minimal/components/PlaybackControls.js +0 -9
  505. package/src/components/variants/minimal/components/RightControls.js +0 -40
  506. package/src/components/variants/minimal/components/SeekBar.js +0 -43
  507. package/src/components/variants/minimal/components/SettingsDropdown.js +0 -18
  508. package/src/components/variants/minimal/components/SubtitleDisplay.js +0 -6
  509. package/src/components/variants/minimal/components/TimeDisplay.js +0 -5
  510. package/src/components/variants/minimal/components/VideoElement.js +0 -4
  511. package/src/components/variants/minimal/components/VolumeControl.js +0 -99
  512. package/src/components/variants/minimal/index.js +0 -8
  513. package/src/components/video-player.js +0 -38
  514. package/src/context/error-handling.js +0 -300
  515. package/src/context/media-context.js +0 -121
  516. package/src/context/media-provider.js +0 -164
  517. package/src/context/media-store.js +0 -273
  518. package/src/context/persistence.js +0 -356
  519. package/src/core/events/event-system.js +0 -288
  520. package/src/core/events/hooks.js +0 -198
  521. package/src/core/events/index.js +0 -7
  522. package/src/core/events/middleware.js +0 -219
  523. package/src/core/index.js +0 -15
  524. package/src/core/optimization/bundle-optimizer.js +0 -217
  525. package/src/core/performance/cicd.js +0 -83
  526. package/src/core/performance/index.js +0 -14
  527. package/src/core/performance/media-loading-optimizer.js +0 -404
  528. package/src/core/performance/performance-budgets.js +0 -326
  529. package/src/core/performance/performance-monitor.js +0 -297
  530. package/src/core/performance/performance-testing.js +0 -314
  531. package/src/core/plugins/base-plugin.js +0 -151
  532. package/src/core/plugins/enhanced-plugin-system.js +0 -305
  533. package/src/core/plugins/examples/analytics-plugin.js +0 -191
  534. package/src/core/plugins/index.js +0 -9
  535. package/src/core/plugins/registry.js +0 -261
  536. package/src/core/plugins/types.js +0 -31
  537. package/src/core/plugins/utils.js +0 -274
  538. package/src/core/progressive-loading.js +0 -239
  539. package/src/core/providers/enhanced-hls-provider.js +0 -273
  540. package/src/core/providers/service-provider.js +0 -105
  541. package/src/core/utils.js +0 -21
  542. package/src/features/media-session/media-session-manager.js +0 -331
  543. package/src/features/picture-in-picture/pip-manager.js +0 -353
  544. package/src/features/playlist/playlist-manager.js +0 -475
  545. package/src/features/subtitles/subtitle-manager.js +0 -335
  546. package/src/features/subtitles/subtitle-parser.js +0 -217
  547. package/src/features/thumbnails/thumbnail-generator.js +0 -388
  548. package/src/hooks/accessibility/index.js +0 -4
  549. package/src/hooks/accessibility/use-accessibility-preferences.js +0 -156
  550. package/src/hooks/accessibility/use-focus-management.js +0 -142
  551. package/src/hooks/accessibility/use-keyboard-shortcuts.js +0 -101
  552. package/src/hooks/accessibility/use-screen-reader.js +0 -148
  553. package/src/hooks/core/index.js +0 -19
  554. package/src/hooks/legacy.js +0 -17
  555. package/src/hooks/use-enhanced-media-player.js +0 -395
  556. package/src/hooks/use-intelligent-preloading.js +0 -258
  557. package/src/hooks/use-keyboard-controls.js +0 -83
  558. package/src/hooks/use-media-actions.js +0 -121
  559. package/src/hooks/use-media-metadata.js +0 -74
  560. package/src/hooks/use-media-optimistic.js +0 -205
  561. package/src/hooks/use-media-player.js +0 -251
  562. package/src/hooks/use-media-state.js +0 -162
  563. package/src/hooks/use-memory-optimization.js +0 -288
  564. package/src/hooks/use-optimistic-controls.js +0 -60
  565. package/src/hooks/use-optimized-media.js +0 -211
  566. package/src/hooks/use-touch-gestures.js +0 -289
  567. package/src/hooks/useEnhancedSubtitles.js +0 -205
  568. package/src/hooks/useKeyboardShortcuts.js +0 -59
  569. package/src/hooks/useMediaControls.js +0 -44
  570. package/src/hooks/useScreenshot.js +0 -56
  571. package/src/hooks/useSubtitles.js +0 -73
  572. package/src/hooks/useVideoPlayer.js +0 -184
  573. package/src/icons/components/FullscreenIcon.js +0 -11
  574. package/src/icons/components/SettingsIcon.js +0 -11
  575. package/src/icons/components/animated/LoadingIcon.js +0 -11
  576. package/src/icons/components/animated/PlayPauseIcon.js +0 -9
  577. package/src/icons/components/media/PauseIcon.js +0 -12
  578. package/src/icons/components/media/PlayIcon.js +0 -12
  579. package/src/icons/components/volume/VolumeIcon.js +0 -11
  580. package/src/icons/components/volume/VolumeOffIcon.js +0 -11
  581. package/src/icons/index.js +0 -45
  582. package/src/icons/provider.js +0 -37
  583. package/src/icons/types.js +0 -1
  584. package/src/index-enhanced.js +0 -16
  585. package/src/index-legacy.js +0 -97
  586. package/src/index.js +0 -90
  587. package/src/index.minimal.js +0 -3
  588. package/src/lib/deprecation.js +0 -31
  589. package/src/lib/format-time.js +0 -32
  590. package/src/lib/index.js +0 -3
  591. package/src/lib/utils.js +0 -5
  592. package/src/test/setup.js +0 -65
  593. package/src/types/events.js +0 -2
  594. package/src/types/formats.js +0 -63
  595. package/src/types/index.js +0 -4
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks-BCMilGRf.cjs","sources":["../src/hooks/use-keyboard-controls.js","../src/hooks/use-media-optimistic.js","../src/hooks/use-media-actions.js","../src/hooks/use-enhanced-media-player.js","../src/hooks/use-memory-optimization.js","../src/hooks/use-keyboard-controls.ts","../src/hooks/use-media-state.js","../src/hooks/use-media-player.ts","../../ui/src/hooks/use-mobile.ts","../src/hooks/use-touch-gestures.ts","../src/hooks/useVideoPlayer.ts","../src/hooks/useEnhancedSubtitles.ts","../src/hooks/useMediaControls.ts","../src/hooks/useKeyboardShortcuts.ts","../src/hooks/useScreenshot.ts","../src/hooks/use-media-actions.ts","../src/hooks/use-media-state.ts","../src/hooks/use-enhanced-media-player.ts","../src/hooks/use-intelligent-preloading.ts","../src/hooks/useSubtitles.ts","../src/hooks/legacy.ts"],"sourcesContent":["\"use client\";\nimport { useEffect } from \"react\";\nexport function useKeyboardControls({ enabled = true, state, controls, seekStep = 10, volumeStep = 0.1 }) {\n const handleKeyDown = (event) => {\n if (!enabled)\n return;\n // Don't handle keyboard events if user is typing in an input\n const target = event.target;\n if (target.tagName === \"INPUT\" ||\n target.tagName === \"TEXTAREA\" ||\n target.contentEditable === \"true\") {\n return;\n }\n switch (event.code) {\n case \"Space\":\n case \"KeyK\":\n event.preventDefault();\n controls.toggle();\n break;\n case \"KeyM\":\n event.preventDefault();\n controls.toggleMute();\n break;\n case \"KeyF\":\n event.preventDefault();\n controls.toggleFullscreen();\n break;\n case \"ArrowLeft\":\n event.preventDefault();\n controls.seek(Math.max(0, state.currentTime - seekStep));\n break;\n case \"ArrowRight\":\n event.preventDefault();\n controls.seek(Math.min(state.duration, state.currentTime + seekStep));\n break;\n case \"ArrowUp\":\n event.preventDefault();\n controls.setVolume(Math.min(1, state.volume + volumeStep));\n break;\n case \"ArrowDown\":\n event.preventDefault();\n controls.setVolume(Math.max(0, state.volume - volumeStep));\n break;\n case \"Digit0\":\n case \"Digit1\":\n case \"Digit2\":\n case \"Digit3\":\n case \"Digit4\":\n case \"Digit5\":\n case \"Digit6\":\n case \"Digit7\":\n case \"Digit8\":\n case \"Digit9\":\n event.preventDefault();\n const digit = parseInt(event.code.replace(\"Digit\", \"\"), 10);\n const percentage = digit / 10;\n controls.seek(state.duration * percentage);\n break;\n case \"Home\":\n event.preventDefault();\n controls.seek(0);\n break;\n case \"End\":\n event.preventDefault();\n controls.seek(state.duration);\n break;\n default:\n // Don't prevent default for unhandled keys\n break;\n }\n };\n useEffect(() => {\n if (!enabled)\n return;\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [enabled, handleKeyDown]);\n return {\n handleKeyDown\n };\n}\n","\"use client\";\nimport React, { useOptimistic } from \"react\";\n// Optimistic update reducer function\nfunction optimisticMediaReducer(state, action) {\n if (!action.optimistic)\n return state;\n // Apply immediate optimistic updates for better UX\n switch (action.type) {\n case \"PLAY\":\n return { ...state, isPlaying: true, error: null };\n case \"PAUSE\":\n return { ...state, isPlaying: false };\n case \"SEEK\":\n return { ...state, currentTime: action.detail };\n case \"SET_VOLUME\":\n return { ...state, volume: Math.max(0, Math.min(1, action.detail)) };\n case \"MUTE\":\n return { ...state, isMuted: true };\n case \"UNMUTE\":\n return { ...state, isMuted: false };\n case \"TOGGLE_MUTE\":\n return { ...state, isMuted: !state.isMuted };\n case \"ENTER_FULLSCREEN\":\n return { ...state, isFullscreen: true };\n case \"EXIT_FULLSCREEN\":\n return { ...state, isFullscreen: false };\n case \"SET_PLAYBACK_RATE\":\n return { ...state, playbackRate: action.detail };\n case \"TOGGLE_SUBTITLES\":\n return { ...state, subtitlesShowing: !state.subtitlesShowing };\n case \"PREVIEW_TIME\":\n return { ...state, previewTime: action.detail };\n case \"CLEAR_PREVIEW\":\n return {\n ...state,\n previewTime: null,\n previewImage: null,\n previewCoords: null\n };\n default:\n return state;\n }\n}\n// Media optimistic state hook using React 19's useOptimistic\nexport function useMediaOptimistic(store) {\n const actualState = React.useSyncExternalStore(store.subscribe, store.getState, store.getState);\n const [optimisticState, addOptimistic] = useOptimistic(actualState, optimisticMediaReducer);\n // Enhanced dispatch that uses optimistic updates\n const dispatchOptimistic = React.useCallback(async (action) => {\n // Add optimistic update immediately\n if (action.optimistic) {\n addOptimistic(action);\n }\n // Dispatch the actual action\n await store.dispatchOptimistic(action);\n }, [store, addOptimistic]);\n // Quick actions with optimistic updates\n const optimisticActions = React.useMemo(() => ({\n // Play/Pause with immediate feedback\n togglePlayPause: async () => {\n const action = {\n type: optimisticState.isPlaying ? \"PAUSE\" : \"PLAY\",\n optimistic: true,\n timestamp: Date.now()\n };\n await dispatchOptimistic(action);\n },\n // Volume control with immediate slider feedback\n setVolumeOptimistic: async (volume) => {\n const action = {\n type: \"SET_VOLUME\",\n detail: Math.max(0, Math.min(1, volume)),\n optimistic: true,\n timestamp: Date.now()\n };\n await dispatchOptimistic(action);\n },\n // Seek with immediate scrub feedback\n seekOptimistic: async (time) => {\n const action = {\n type: \"SEEK\",\n detail: time,\n optimistic: true,\n timestamp: Date.now()\n };\n await dispatchOptimistic(action);\n },\n // Mute toggle with immediate icon change\n toggleMuteOptimistic: async () => {\n const action = {\n type: \"TOGGLE_MUTE\",\n optimistic: true,\n timestamp: Date.now()\n };\n await dispatchOptimistic(action);\n },\n // Fullscreen toggle with immediate layout change\n toggleFullscreenOptimistic: async () => {\n const action = {\n type: optimisticState.isFullscreen ? \"EXIT_FULLSCREEN\" : \"ENTER_FULLSCREEN\",\n optimistic: true,\n timestamp: Date.now()\n };\n await dispatchOptimistic(action);\n },\n // Playback rate with immediate feedback\n setPlaybackRateOptimistic: async (rate) => {\n const action = {\n type: \"SET_PLAYBACK_RATE\",\n detail: rate,\n optimistic: true,\n timestamp: Date.now()\n };\n await dispatchOptimistic(action);\n },\n // Subtitle toggle with immediate visibility change\n toggleSubtitlesOptimistic: async () => {\n const action = {\n type: \"TOGGLE_SUBTITLES\",\n optimistic: true,\n timestamp: Date.now()\n };\n await dispatchOptimistic(action);\n }\n }), [optimisticState, dispatchOptimistic]);\n // State selectors that return optimistic values\n const selectors = React.useMemo(() => ({\n isPlaying: optimisticState.isPlaying,\n currentTime: optimisticState.currentTime,\n volume: optimisticState.volume,\n isMuted: optimisticState.isMuted,\n isFullscreen: optimisticState.isFullscreen,\n playbackRate: optimisticState.playbackRate,\n subtitlesShowing: optimisticState.subtitlesShowing,\n previewTime: optimisticState.previewTime,\n // Computed values\n progress: optimisticState.duration > 0\n ? optimisticState.currentTime / optimisticState.duration\n : 0,\n formattedTime: formatTime(optimisticState.currentTime),\n formattedDuration: formatTime(optimisticState.duration),\n // State checks\n canPlay: !optimisticState.isLoading && !optimisticState.error,\n hasError: !!optimisticState.error,\n isBuffering: optimisticState.isLoading\n }), [optimisticState]);\n return {\n state: optimisticState,\n actualState,\n ...selectors,\n ...optimisticActions,\n dispatchOptimistic\n };\n}\n// Time formatting utility\nfunction formatTime(seconds) {\n if (!seconds || !isFinite(seconds))\n return \"0:00\";\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n const hours = Math.floor(mins / 60);\n if (hours > 0) {\n return `${hours}:${String(mins % 60).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;\n }\n return `${mins}:${String(secs).padStart(2, '0')}`;\n}\n// Hook for components that need to detect optimistic updates\nexport function useOptimisticUpdates(store) {\n const [hasOptimisticUpdates, setHasOptimisticUpdates] = React.useState(false);\n React.useEffect(() => {\n const unsubscribe = store.subscribe(() => {\n const actualState = store.getState();\n const optimisticState = store.getOptimisticState();\n const hasUpdates = JSON.stringify(actualState) !== JSON.stringify(optimisticState);\n setHasOptimisticUpdates(hasUpdates);\n });\n return unsubscribe;\n }, [store]);\n return hasOptimisticUpdates;\n}\n// Hook to get both actual and optimistic state for debugging\nexport function useMediaStateComparison(store) {\n const actualState = React.useSyncExternalStore(store.subscribe, store.getState, store.getState);\n const optimisticState = React.useSyncExternalStore(store.subscribe, store.getOptimisticState, store.getOptimisticState);\n const differences = React.useMemo(() => {\n const diffs = [];\n const stateKeys = Object.keys(actualState);\n stateKeys.forEach(key => {\n if (JSON.stringify(actualState[key]) !== JSON.stringify(optimisticState[key])) {\n diffs.push({\n key: key,\n actual: actualState[key],\n optimistic: optimisticState[key]\n });\n }\n });\n return diffs;\n }, [actualState, optimisticState]);\n return {\n actualState,\n optimisticState,\n differences,\n hasOptimisticUpdates: differences.length > 0\n };\n}\n","\"use client\";\nimport React from \"react\";\nimport { MediaActionTypes } from \"../context/media-context\";\n// Action creator factory\nfunction createOptimisticAction(type, store) {\n return ((payload, optimistic = false) => {\n const action = {\n type,\n detail: payload,\n optimistic,\n timestamp: Date.now()\n };\n if (optimistic) {\n return store.dispatchOptimistic(action);\n }\n else {\n store.dispatch(action);\n return Promise.resolve();\n }\n });\n}\n// React 19 useActionState integration\nexport function useMediaActionState(store) {\n const [actionState, setActionState] = React.useState(store.getActionState());\n // Subscribe to action state changes\n React.useEffect(() => {\n const unsubscribe = store.subscribe(() => {\n const newActionState = store.getActionState();\n setActionState(current => JSON.stringify(current) !== JSON.stringify(newActionState)\n ? newActionState\n : current);\n });\n return unsubscribe;\n }, [store]);\n return actionState;\n}\n// Media actions hook with React 19 optimistic updates\nexport function useMediaActions(store) {\n // Create action creators with optimistic support\n const actions = React.useMemo(() => ({\n // Playback actions\n play: createOptimisticAction(MediaActionTypes.PLAY, store),\n pause: createOptimisticAction(MediaActionTypes.PAUSE, store),\n seek: createOptimisticAction(MediaActionTypes.SEEK, store),\n // Volume actions \n setVolume: createOptimisticAction(MediaActionTypes.SET_VOLUME, store),\n mute: createOptimisticAction(MediaActionTypes.MUTE, store),\n unmute: createOptimisticAction(MediaActionTypes.UNMUTE, store),\n toggleMute: createOptimisticAction(MediaActionTypes.TOGGLE_MUTE, store),\n // Media state actions\n setDuration: createOptimisticAction(MediaActionTypes.SET_DURATION, store),\n setCurrentTime: createOptimisticAction(MediaActionTypes.SET_CURRENT_TIME, store),\n setBuffered: createOptimisticAction(MediaActionTypes.SET_BUFFERED, store),\n setLoading: createOptimisticAction(MediaActionTypes.SET_LOADING, store),\n setError: createOptimisticAction(MediaActionTypes.SET_ERROR, store),\n // Display actions\n enterFullscreen: createOptimisticAction(MediaActionTypes.ENTER_FULLSCREEN, store),\n exitFullscreen: createOptimisticAction(MediaActionTypes.EXIT_FULLSCREEN, store),\n enterPiP: createOptimisticAction(MediaActionTypes.ENTER_PIP, store),\n exitPiP: createOptimisticAction(MediaActionTypes.EXIT_PIP, store),\n // Advanced actions\n setPlaybackRate: createOptimisticAction(MediaActionTypes.SET_PLAYBACK_RATE, store),\n setSubtitleTrack: createOptimisticAction(MediaActionTypes.SET_SUBTITLE_TRACK, store),\n setRendition: createOptimisticAction(MediaActionTypes.SET_RENDITION, store),\n toggleSubtitles: createOptimisticAction(MediaActionTypes.TOGGLE_SUBTITLES, store),\n // Preview actions\n previewTime: createOptimisticAction(MediaActionTypes.PREVIEW_TIME, store),\n clearPreview: createOptimisticAction(MediaActionTypes.CLEAR_PREVIEW, store)\n }), [store]);\n // Get action state for loading/error handling\n const actionState = useMediaActionState(store);\n // Convenience methods that commonly use optimistic updates\n const optimisticActions = React.useMemo(() => ({\n // These actions benefit from immediate UI feedback\n togglePlayPause: async (isPlaying) => {\n if (isPlaying) {\n await actions.pause(true); // optimistic\n }\n else {\n await actions.play(true); // optimistic\n }\n },\n seekWithPreview: async (time) => {\n // Immediate preview update, then actual seek\n await actions.previewTime(time, true);\n await actions.seek(time, true);\n },\n adjustVolume: async (delta, currentVolume) => {\n const newVolume = Math.max(0, Math.min(1, currentVolume + delta));\n await actions.setVolume(newVolume, true);\n },\n toggleFullscreenOptimistic: async (isFullscreen) => {\n if (isFullscreen) {\n await actions.exitFullscreen(true);\n }\n else {\n await actions.enterFullscreen(true);\n }\n }\n }), [actions]);\n // Retry failed action\n const retryLastAction = React.useCallback(async () => {\n const { lastAction } = actionState;\n if (lastAction && actionState.error) {\n await store.dispatchOptimistic({\n ...lastAction,\n retryCount: (lastAction.retryCount || 0) + 1\n });\n }\n }, [store, actionState]);\n return {\n ...actions,\n ...optimisticActions,\n actionState,\n retryLastAction,\n isLoading: actionState.pending,\n hasError: !!actionState.error,\n errorMessage: actionState.error,\n retryCount: actionState.retryCount\n };\n}\n","\"use client\";\nimport React, { useCallback, useEffect, useRef, useMemo, useTransition, useOptimistic } from \"react\";\nimport { useMediaStore, useMediaSelector } from \"../context/media-context\";\nimport { useMediaOptimistic } from \"./use-media-optimistic\";\nimport { useMediaActions } from \"./use-media-actions\";\n// Performance-optimized media player hook with React 19 features\nexport function useEnhancedMediaPlayer(options) {\n const mediaRef = useRef(null);\n const containerRef = useRef(null);\n // React 19 concurrent features\n const [isPending, startTransition] = useTransition();\n const [isSeeking, startSeekTransition] = useTransition();\n // Performance monitoring\n const renderStartTime = React.useRef(0);\n const frameCount = React.useRef(0);\n const lastFrameTime = React.useRef(0);\n // Throttled time update\n const timeUpdateTimeoutRef = useRef();\n const lastTimeUpdate = useRef(0);\n // Store integration\n const store = useMediaStore();\n const isEnhanced = 'getOptimisticState' in store;\n // Select only the state we need to minimize re-renders\n const isPlaying = useMediaSelector(state => state.isPlaying);\n const currentTime = useMediaSelector(state => state.currentTime);\n const duration = useMediaSelector(state => state.duration);\n const volume = useMediaSelector(state => state.volume);\n const isMuted = useMediaSelector(state => state.isMuted);\n const isLoading = useMediaSelector(state => state.isLoading);\n const isBuffering = useMediaSelector(state => state.isBuffering);\n const error = useMediaSelector(state => state.error);\n const buffered = useMediaSelector(state => state.buffered);\n const isFullscreen = useMediaSelector(state => state.isFullscreen);\n // Enhanced features if available\n const enhancedStore = store;\n const optimisticState = isEnhanced ? useMediaOptimistic(enhancedStore) : null;\n const actions = isEnhanced ? useMediaActions(enhancedStore) : null;\n // Performance state\n const [performanceMetrics, setPerformanceMetrics] = React.useState({\n frameRate: 0,\n averageRenderTime: 0,\n droppedFrames: 0,\n bufferHealth: 0\n });\n // Optimistic state updates for immediate UI feedback\n const [optimisticVolume, setOptimisticVolume] = useOptimistic(volume, (state, newVolume) => {\n return Math.max(0, Math.min(1, newVolume));\n });\n const [optimisticTime, setOptimisticTime] = useOptimistic(currentTime, (state, newTime) => {\n return Math.max(0, Math.min(duration || 0, newTime));\n });\n // Initialize media element with performance optimizations\n useEffect(() => {\n const media = mediaRef.current;\n if (!media)\n return;\n // Set initial properties\n const initProps = {\n volume: options.volume,\n muted: options.muted,\n autoplay: options.autoPlay,\n loop: options.loop,\n preload: options.preload,\n crossOrigin: options.crossOrigin\n };\n Object.entries(initProps).forEach(([key, value]) => {\n if (value !== undefined) {\n media[key] = value;\n }\n });\n // Performance optimizations\n media.setAttribute('preload', options.preloadStrategy === 'eager' ? 'auto' : 'metadata');\n if (options.bufferingStrategy === 'aggressive') {\n media.setAttribute('buffered', 'auto');\n }\n // Hardware acceleration\n if (media instanceof HTMLVideoElement) {\n media.style.willChange = 'transform';\n media.style.transform = 'translateZ(0)';\n }\n }, [\n options.volume,\n options.muted,\n options.autoPlay,\n options.loop,\n options.preload,\n options.crossOrigin,\n options.preloadStrategy,\n options.bufferingStrategy\n ]);\n // Optimized event handlers with React 19 patterns\n const handleTimeUpdate = useCallback(() => {\n const media = mediaRef.current;\n if (!media)\n return;\n const now = performance.now();\n // Throttle time updates for performance\n if (options.enableTimeUpdateThrottling !== false) {\n if (now - lastTimeUpdate.current < (options.timeUpdateThrottleMs || 100)) {\n return;\n }\n lastTimeUpdate.current = now;\n }\n startTransition(() => {\n if (isEnhanced && actions) {\n actions.setCurrentTime(media.currentTime);\n }\n });\n }, [options.enableTimeUpdateThrottling, options.timeUpdateThrottleMs, isEnhanced, actions]);\n const handlePlay = useCallback(() => {\n startTransition(() => {\n if (isEnhanced && actions) {\n actions.play(true); // Optimistic update\n }\n });\n options.onPlay?.();\n }, [isEnhanced, actions, options.onPlay]);\n const handlePause = useCallback(() => {\n startTransition(() => {\n if (isEnhanced && actions) {\n actions.pause(true); // Optimistic update\n }\n });\n options.onPause?.();\n }, [isEnhanced, actions, options.onPause]);\n const handleVolumeChange = useCallback(() => {\n const media = mediaRef.current;\n if (!media)\n return;\n startTransition(() => {\n if (isEnhanced && actions) {\n actions.setVolume(media.volume, true); // Optimistic update\n media.muted ? actions.mute(true) : actions.unmute(true);\n }\n });\n }, [isEnhanced, actions]);\n const handleSeeking = useCallback(() => {\n startSeekTransition(() => {\n // Seek operations get their own transition\n });\n }, []);\n const handleSeeked = useCallback(() => {\n // Seek completed\n }, []);\n const handleProgress = useCallback(() => {\n const media = mediaRef.current;\n if (!media)\n return;\n startTransition(() => {\n if (isEnhanced && actions) {\n actions.setBuffered(media.buffered);\n }\n });\n }, [isEnhanced, actions]);\n // Performance monitoring\n const measureRenderTime = useCallback(() => {\n const now = performance.now();\n const deltaTime = now - lastFrameTime.current;\n if (deltaTime > 0) {\n frameCount.current++;\n // Calculate frame rate every second\n if (frameCount.current >= 60) {\n const fps = Math.round((frameCount.current * 1000) / (now - lastFrameTime.current));\n setPerformanceMetrics(prev => ({\n ...prev,\n frameRate: fps,\n droppedFrames: Math.max(0, 60 - fps)\n }));\n frameCount.current = 0;\n lastFrameTime.current = now;\n }\n }\n }, []);\n // Attach event listeners with performance optimization\n useEffect(() => {\n const media = mediaRef.current;\n if (!media)\n return;\n // Use passive listeners where possible for better performance\n const eventListeners = [\n { event: \"timeupdate\", handler: handleTimeUpdate, passive: true },\n { event: \"play\", handler: handlePlay },\n { event: \"pause\", handler: handlePause },\n { event: \"volumechange\", handler: handleVolumeChange },\n { event: \"seeking\", handler: handleSeeking },\n { event: \"seeked\", handler: handleSeeked },\n { event: \"progress\", handler: handleProgress, passive: true },\n { event: \"loadedmetadata\", handler: () => measureRenderTime() },\n { event: \"loadeddata\", handler: () => measureRenderTime() }\n ];\n eventListeners.forEach(({ event, handler, passive }) => {\n const options = passive ? { passive: true } : {};\n media.addEventListener(event, handler, options);\n });\n // Performance monitoring frame loop\n let rafId;\n const performanceLoop = () => {\n measureRenderTime();\n rafId = requestAnimationFrame(performanceLoop);\n };\n if (options.enablePerformanceMonitoring) {\n performanceLoop();\n }\n return () => {\n eventListeners.forEach(({ event, handler }) => {\n media.removeEventListener(event, handler);\n });\n if (rafId) {\n cancelAnimationFrame(rafId);\n }\n };\n }, [\n handleTimeUpdate,\n handlePlay,\n handlePause,\n handleVolumeChange,\n handleSeeking,\n handleSeeked,\n handleProgress,\n measureRenderTime,\n options.enablePerformanceMonitoring\n ]);\n // Optimized control functions with React 19 features\n const controls = useMemo(() => {\n const play = async () => {\n const media = mediaRef.current;\n if (!media)\n return;\n if (isEnhanced && actions) {\n await actions.play(true); // Optimistic\n }\n else {\n try {\n await media.play();\n }\n catch (error) {\n console.error(\"Failed to play media:\", error);\n }\n }\n };\n const pause = () => {\n const media = mediaRef.current;\n if (!media)\n return;\n if (isEnhanced && actions) {\n actions.pause(true); // Optimistic\n }\n else {\n media.pause();\n }\n };\n const toggle = () => {\n if (isPlaying) {\n pause();\n }\n else {\n play();\n }\n };\n const seek = (time) => {\n const media = mediaRef.current;\n if (!media)\n return;\n const clampedTime = Math.max(0, Math.min(time, duration || 0));\n if (isEnhanced && actions) {\n startSeekTransition(() => {\n actions.seek(clampedTime, true); // Optimistic\n });\n }\n else {\n media.currentTime = clampedTime;\n }\n };\n const setVolume = (volume) => {\n const media = mediaRef.current;\n if (!media)\n return;\n const clampedVolume = Math.max(0, Math.min(1, volume));\n if (isEnhanced && actions) {\n setOptimisticVolume(clampedVolume);\n startTransition(() => {\n actions.setVolume(clampedVolume, true);\n });\n }\n else {\n media.volume = clampedVolume;\n }\n };\n const toggleMute = () => {\n const media = mediaRef.current;\n if (!media)\n return;\n if (isEnhanced && actions) {\n actions.toggleMute(true); // Optimistic\n }\n else {\n media.muted = !media.muted;\n }\n };\n const enterFullscreen = async () => {\n const container = containerRef.current;\n if (!container || !document.fullscreenEnabled)\n return;\n try {\n await container.requestFullscreen();\n if (isEnhanced && actions) {\n actions.enterFullscreen(true);\n }\n }\n catch (error) {\n console.error(\"Failed to enter fullscreen:\", error);\n }\n };\n const exitFullscreen = async () => {\n if (!document.fullscreenElement)\n return;\n try {\n await document.exitFullscreen();\n if (isEnhanced && actions) {\n actions.exitFullscreen(true);\n }\n }\n catch (error) {\n console.error(\"Failed to exit fullscreen:\", error);\n }\n };\n return {\n play,\n pause,\n toggle,\n seek,\n setVolume,\n toggleMute,\n enterFullscreen,\n exitFullscreen\n };\n }, [\n isPlaying,\n duration,\n isEnhanced,\n actions,\n startTransition,\n startSeekTransition,\n setOptimisticVolume\n ]);\n // Computed state\n const computedState = useMemo(() => ({\n isPlaying: optimisticState?.isPlaying ?? isPlaying,\n currentTime: optimisticState?.currentTime ?? currentTime,\n duration: optimisticState?.duration ?? duration,\n volume: optimisticState?.volume ?? optimisticVolume,\n isMuted: optimisticState?.isMuted ?? isMuted,\n isLoading: optimisticState?.isBuffering ?? isLoading,\n isBuffering: optimisticState?.isBuffering ?? isBuffering,\n error: optimisticState?.error ?? error,\n buffered: optimisticState?.buffered ?? buffered,\n isFullscreen: optimisticState?.isFullscreen ?? isFullscreen,\n progress: duration > 0 ? currentTime / duration : 0,\n isTransitioning: isPending || isSeeking,\n canPlay: !isLoading && !isBuffering && !error\n }), [\n optimisticState,\n isPlaying,\n currentTime,\n duration,\n optimisticVolume,\n isMuted,\n isLoading,\n isBuffering,\n error,\n buffered,\n isFullscreen,\n isPending,\n isSeeking\n ]);\n return {\n // Refs\n mediaRef,\n containerRef,\n // State\n state: computedState,\n actualState: optimisticState?.actualState,\n // Controls\n controls,\n // Performance metrics\n performanceMetrics,\n isTransitioning: isPending || isSeeking,\n // Enhanced features\n actions: optimisticState?.actions,\n actionState: optimisticState?.actionState,\n // Optimistic features\n optimisticState,\n isEnhanced\n };\n}\n","\"use client\";\nimport React, { useEffect, useRef, useCallback } from \"react\";\n// Memory optimization hook for media players\nexport function useMemoryOptimization(options = {}) {\n const { maxMemoryUsage = 100, // 100MB default\n cleanupInterval = 30000, // 30 seconds default\n enableGC = true, monitorMemory = true } = options;\n const cleanupTimeoutRef = useRef();\n const observersRef = useRef(new Set());\n const eventListenersRef = useRef(new Map());\n const intervalRefs = useRef(new Set());\n const animationFrameRefs = useRef(new Set());\n // Get current memory usage\n const getMemoryUsage = useCallback(() => {\n if (typeof window === 'undefined' || !('memory' in performance)) {\n return { used: 0, total: 0, limit: 0 };\n }\n const memory = performance.memory;\n return {\n used: memory.usedJSHeapSize,\n total: memory.totalJSHeapSize,\n limit: memory.jsHeapSizeLimit\n };\n }, []);\n // Memory monitoring state\n const [memoryStats, setMemoryStats] = React.useState({\n used: 0,\n total: 0,\n limit: 0,\n usage: 0,\n isHighUsage: false\n });\n // Memory monitoring\n useEffect(() => {\n if (!monitorMemory)\n return;\n const checkMemory = () => {\n const memory = getMemoryUsage();\n const usage = (memory.used / 1024 / 1024); // Convert to MB\n const isHighUsage = usage > maxMemoryUsage;\n setMemoryStats({\n ...memory,\n usage,\n isHighUsage\n });\n // Trigger cleanup if memory usage is high\n if (isHighUsage && enableGC) {\n performCleanup();\n }\n };\n checkMemory();\n const interval = setInterval(checkMemory, cleanupInterval);\n intervalRefs.current.add(interval);\n return () => {\n clearInterval(interval);\n intervalRefs.current.delete(interval);\n };\n }, [monitorMemory, getMemoryUsage, maxMemoryUsage, enableGC, cleanupInterval]);\n // Cleanup function\n const performCleanup = useCallback(() => {\n // Clear all timeouts\n intervalRefs.current.forEach(timeout => {\n clearTimeout(timeout);\n });\n intervalRefs.current.clear();\n // Cancel all animation frames\n animationFrameRefs.current.forEach(frameId => {\n cancelAnimationFrame(frameId);\n });\n animationFrameRefs.current.clear();\n // Disconnect all observers\n observersRef.current.forEach(observer => {\n observer.disconnect();\n });\n observersRef.current.clear();\n // Remove all event listeners\n eventListenersRef.current.forEach((listeners, element) => {\n listeners.forEach(({ event, handler }) => {\n element.removeEventListener(event, handler);\n });\n });\n eventListenersRef.current.clear();\n // Trigger garbage collection if available\n if (enableGC && 'gc' in window) {\n window.gc();\n }\n }, [enableGC]);\n // Safe event listener management\n const addEventListener = useCallback((element, event, handler, options) => {\n element.addEventListener(event, handler, options);\n if (!eventListenersRef.current.has(element)) {\n eventListenersRef.current.set(element, []);\n }\n eventListenersRef.current.get(element).push({ event, handler });\n // Return cleanup function\n return () => {\n element.removeEventListener(event, handler);\n const listeners = eventListenersRef.current.get(element);\n if (listeners) {\n const index = listeners.findIndex(l => l.event === event && l.handler === handler);\n if (index > -1) {\n listeners.splice(index, 1);\n }\n if (listeners.length === 0) {\n eventListenersRef.current.delete(element);\n }\n }\n };\n }, []);\n // Safe interval management\n const setInterval = useCallback((callback, delay) => {\n const timeoutId = setInterval(callback, delay);\n intervalRefs.current.add(timeoutId);\n return () => {\n clearInterval(timeoutId);\n intervalRefs.current.delete(timeoutId);\n };\n }, []);\n // Safe timeout management\n const setTimeout = useCallback((callback, delay) => {\n const timeoutId = setTimeout(callback, delay);\n intervalRefs.current.add(timeoutId);\n return () => {\n clearTimeout(timeoutId);\n intervalRefs.current.delete(timeoutId);\n };\n }, []);\n // Safe animation frame management\n const requestAnimationFrame = useCallback((callback) => {\n const frameId = requestAnimationFrame(callback);\n animationFrameRefs.current.add(frameId);\n return () => {\n cancelAnimationFrame(frameId);\n animationFrameRefs.current.delete(frameId);\n };\n }, []);\n // Safe observer management\n const addObserver = useCallback((observer) => {\n observersRef.current.add(observer);\n return () => {\n observer.disconnect();\n observersRef.current.delete(observer);\n };\n }, []);\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n performCleanup();\n };\n }, [performCleanup]);\n return {\n // Memory stats\n memoryStats,\n getMemoryUsage,\n // Cleanup functions\n performCleanup,\n // Safe API functions\n addEventListener,\n setInterval,\n setTimeout,\n requestAnimationFrame,\n addObserver,\n // Utilities\n formatBytes: (bytes) => {\n if (bytes === 0)\n return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n }\n };\n}\n// Resource cleanup hook for media elements\nexport function useMediaResourceCleanup(mediaRef) {\n const { addEventListener, performCleanup } = useMemoryOptimization();\n // Track resource cleanup\n const cleanupResources = useCallback(() => {\n const media = mediaRef.current;\n if (!media)\n return;\n // Stop media playback\n if (!media.paused) {\n _media.pause();\n }\n // Clear source\n if (media.src) {\n media.src = '';\n media.load();\n }\n // Remove source elements\n while (media.firstChild) {\n media.removeChild(media.firstChild);\n }\n // Clear any pending seeks\n media.currentTime = 0;\n // Clear buffered data\n if ('clearBuffered' in media) {\n media.clearBuffered();\n }\n }, [mediaRef]);\n // Enhanced event listener registration\n const registerMediaEventListener = useCallback((event, handler, options) => {\n const media = mediaRef.current;\n if (!media)\n return () => { };\n return addEventListener(media, event, handler, options);\n }, [mediaRef, addEventListener]);\n // Cleanup on unmount\n useEffect(() => {\n return cleanupResources;\n }, [cleanupResources]);\n return {\n cleanupResources,\n registerMediaEventListener\n };\n}\n// Performance monitoring hook\nexport function usePerformanceMonitoring() {\n const [metrics, setMetrics] = React.useState({\n fps: 0,\n frameDrops: 0,\n longTasks: 0,\n totalLongTaskDuration: 0\n });\n const frameCountRef = useRef(0);\n const lastFrameTimeRef = useRef(performance.now());\n const longTaskObserverRef = useRef();\n // FPS monitoring\n useEffect(() => {\n let rafId;\n const measureFrame = () => {\n frameCountRef.current++;\n const now = performance.now();\n // Calculate FPS every second\n if (now - lastFrameTimeRef.current >= 1000) {\n const fps = Math.round((frameCountRef.current * 1000) / (now - lastFrameTimeRef.current));\n const expectedFrames = Math.round((now - lastFrameTimeRef.current) / 16.67); // 60fps\n const frameDrops = Math.max(0, expectedFrames - frameCountRef.current);\n setMetrics(prev => ({\n ...prev,\n fps,\n frameDrops: prev.frameDrops + frameDrops\n }));\n frameCountRef.current = 0;\n lastFrameTimeRef.current = now;\n }\n rafId = requestAnimationFrame(measureFrame);\n };\n rafId = requestAnimationFrame(measureFrame);\n return () => {\n cancelAnimationFrame(rafId);\n };\n }, []);\n // Long task monitoring\n useEffect(() => {\n if (!('PerformanceObserver' in window))\n return;\n try {\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n if (entry.duration > 50) { // Long task threshold\n setMetrics(prev => ({\n ...prev,\n longTasks: prev.longTasks + 1,\n totalLongTaskDuration: prev.totalLongTaskDuration + entry.duration\n }));\n }\n }\n });\n observer.observe({ entryTypes: ['longtask'] });\n longTaskObserverRef.current = observer;\n return () => {\n observer.disconnect();\n };\n }\n catch (error) {\n console.warn('Long task monitoring not supported:', error);\n }\n }, []);\n return {\n ...metrics,\n averageLongTaskDuration: metrics.longTasks > 0\n ? metrics.totalLongTaskDuration / metrics.longTasks\n : 0,\n isPerformanceGood: metrics.fps >= 50 && metrics.frameDrops < 5\n };\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\t\tif (!enabled) return\n\n \t\t\t// Don't handle keyboard events if user is typing in an input\n \t\t\tconst target = event.target as HTMLElement\n \t\t\tif (\n \t\t\t\ttarget.tagName === \"INPUT\" ||\n \t\t\t\ttarget.tagName === \"TEXTAREA\" ||\n \t\t\t\ttarget.contentEditable === \"true\"\n \t\t\t) {\n \t\t\t\treturn\n \t\t\t}\n\n \t\t\tswitch (event.code) {\n \t\t\t\tcase \"Space\":\n \t\t\t\tcase \"KeyK\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tcontrols.toggle()\n \t\t\t\t\tbreak\n\n \t\t\t\tcase \"KeyM\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tcontrols.toggleMute()\n \t\t\t\t\tbreak\n\n \t\t\t\tcase \"KeyF\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tcontrols.toggleFullscreen()\n \t\t\t\t\tbreak\n\n \t\t\t\tcase \"ArrowLeft\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tcontrols.seek(Math.max(0, state.currentTime - seekStep))\n \t\t\t\t\tbreak\n\n \t\t\t\tcase \"ArrowRight\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tcontrols.seek(Math.min(state.duration, state.currentTime + seekStep))\n \t\t\t\t\tbreak\n\n \t\t\t\tcase \"ArrowUp\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tcontrols.setVolume(Math.min(1, state.volume + volumeStep))\n \t\t\t\t\tbreak\n\n \t\t\t\tcase \"ArrowDown\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tcontrols.setVolume(Math.max(0, state.volume - volumeStep))\n \t\t\t\t\tbreak\n\n \t\t\t\tcase \"Digit0\":\n \t\t\t\tcase \"Digit1\":\n \t\t\t\tcase \"Digit2\":\n \t\t\t\tcase \"Digit3\":\n \t\t\t\tcase \"Digit4\":\n \t\t\t\tcase \"Digit5\":\n \t\t\t\tcase \"Digit6\":\n \t\t\t\tcase \"Digit7\":\n \t\t\t\tcase \"Digit8\":\n \t\t\t\tcase \"Digit9\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tconst digit = parseInt(event.code.replace(\"Digit\", \"\"), 10)\n \t\t\t\t\tconst percentage = digit / 10\n \t\t\t\t\tcontrols.seek(state.duration * percentage)\n \t\t\t\t\tbreak\n\n \t\t\t\tcase \"Home\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tcontrols.seek(0)\n \t\t\t\t\tbreak\n\n \t\t\t\tcase \"End\":\n \t\t\t\t\tevent.preventDefault()\n \t\t\t\t\tcontrols.seek(state.duration)\n \t\t\t\t\tbreak\n\n \t\t\t\tdefault:\n \t\t\t\t\t// Don't prevent default for unhandled keys\n \t\t\t\t\tbreak\n \t\t\t}\n \t\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\";\nimport { useState } from \"react\";\nimport { useMediaStore } from \"../context/media-context\";\nimport { useMediaOptimistic } from \"./use-media-optimistic\";\nimport { useMediaActions } from \"./use-media-actions\";\n// Legacy hook for backward compatibility\nexport function useMediaState() {\n const [state, setState] = useState({\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n volume: 1,\n isMuted: false,\n isLoading: false,\n isFullscreen: false,\n error: null,\n buffered: null\n });\n const updateState = (updates) => {\n setState((prev) => ({ ...prev, ...updates }));\n };\n const setPlaying = (isPlaying) => {\n updateState({ isPlaying });\n };\n const setCurrentTime = (currentTime) => {\n updateState({ currentTime });\n };\n const setDuration = (duration) => {\n updateState({ duration });\n };\n const setVolume = (volume) => {\n updateState({ volume: Math.max(0, Math.min(1, volume)) });\n };\n const setMuted = (isMuted) => {\n updateState({ isMuted });\n };\n const setLoading = (isLoading) => {\n updateState({ isLoading });\n };\n const setFullscreen = (isFullscreen) => {\n updateState({ isFullscreen });\n };\n const setError = (error) => {\n updateState({ error });\n };\n const setBuffered = (buffered) => {\n updateState({ buffered });\n };\n return {\n state,\n updateState,\n setPlaying,\n setCurrentTime,\n setDuration,\n setVolume,\n setMuted,\n setLoading,\n setFullscreen,\n setError,\n setBuffered\n };\n}\n// React 19 enhanced media state hook\nexport function useEnhancedMediaState() {\n const store = useMediaStore();\n // Check if this is an enhanced store\n const isEnhanced = 'getOptimisticState' in store;\n if (!isEnhanced) {\n // Fall back to regular media state if not enhanced\n return useMediaState();\n }\n // Cast to enhanced store type\n const enhancedStore = store;\n // Use React 19 optimistic updates\n const optimisticState = useMediaOptimistic(enhancedStore);\n // Get action handlers with React 19 features\n const actions = useMediaActions(enhancedStore);\n return {\n // State (optimistic values for immediate UI feedback)\n state: optimisticState.state,\n actualState: optimisticState.actualState,\n // Individual state selectors\n isPlaying: optimisticState.isPlaying,\n currentTime: optimisticState.currentTime,\n duration: optimisticState.state.duration,\n volume: optimisticState.volume,\n isMuted: optimisticState.isMuted,\n isLoading: optimisticState.isBuffering,\n isFullscreen: optimisticState.isFullscreen,\n error: optimisticState.state.error,\n buffered: optimisticState.state.buffered,\n // Computed values\n progress: optimisticState.progress,\n formattedTime: optimisticState.formattedTime,\n formattedDuration: optimisticState.formattedDuration,\n // Actions with optimistic updates\n actions,\n // Action state for loading/error handling\n isActionLoading: actions.isLoading,\n actionError: actions.errorMessage,\n retryLastAction: actions.retryLastAction,\n // Legacy compatibility methods\n updateState: (updates) => {\n // Map legacy updates to new actions\n if ('isPlaying' in updates) {\n updates.isPlaying ? actions.play() : actions.pause();\n }\n if ('currentTime' in updates) {\n actions.setCurrentTime(updates.currentTime);\n }\n if ('duration' in updates) {\n actions.setDuration(updates.duration);\n }\n if ('volume' in updates) {\n actions.setVolume(updates.volume);\n }\n if ('isMuted' in updates) {\n updates.isMuted ? actions.mute() : actions.unmute();\n }\n if ('isLoading' in updates) {\n actions.setLoading(updates.isLoading);\n }\n if ('isFullscreen' in updates) {\n updates.isFullscreen ? actions.enterFullscreen() : actions.exitFullscreen();\n }\n if ('error' in updates) {\n actions.setError(updates.error ?? null);\n }\n if ('buffered' in updates) {\n actions.setBuffered(updates.buffered ?? null);\n }\n },\n // Individual action methods for legacy compatibility\n setPlaying: (isPlaying) => {\n isPlaying ? actions.play(true) : actions.pause(true); // Use optimistic updates\n },\n setCurrentTime: (time) => actions.setCurrentTime(time),\n setDuration: (duration) => actions.setDuration(duration),\n setVolume: (volume) => actions.setVolume(volume, true),\n setMuted: (muted) => {\n muted ? actions.mute(true) : actions.unmute(true);\n },\n setLoading: (loading) => actions.setLoading(loading),\n setFullscreen: (fullscreen) => {\n fullscreen ? actions.enterFullscreen(true) : actions.exitFullscreen(true);\n },\n setError: (error) => actions.setError(error),\n setBuffered: (buffered) => actions.setBuffered(buffered)\n };\n}\n// Hook that automatically chooses between legacy and enhanced based on context availability\nexport function useAdaptiveMediaState() {\n try {\n // Try to use the enhanced version if MediaStore context is available\n return useEnhancedMediaState();\n }\n catch (error) {\n // Fall back to legacy version if not in MediaProvider context\n console.warn('MediaStore context not available, using legacy state management');\n return useMediaState();\n }\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\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 * as React from \"react\"\nimport { useDeviceInfo, useHapticFeedback } from \"@rp/ui/hooks/use-mobile\"\n\n// Gesture types\nexport type GestureType = \n | 'tap' \n | 'double-tap' \n | 'long-press' \n | 'swipe-left' \n | 'swipe-right' \n | 'swipe-up' \n | 'swipe-down' \n | 'pinch-in' \n | 'pinch-out'\n\n// Gesture event data\nexport interface GestureEvent {\n type: GestureType\n startPoint: { x: number; y: number }\n currentPoint: { x: number; y: number }\n velocity?: { x: number; y: number }\n scale?: number\n rotation?: number\n distance?: number\n duration: number\n preventDefault: () => void\n target: HTMLElement\n}\n\n// Gesture configuration\nexport interface GestureConfig {\n enabledGestures?: GestureType[]\n tapThreshold?: number // ms\n doubleTapThreshold?: number // ms\n longPressThreshold?: number // ms\n swipeThreshold?: number // px\n swipeVelocityThreshold?: number // px/ms\n pinchThreshold?: number // scale difference\n rotationThreshold?: number // degrees\n enableHapticFeedback?: boolean\n}\n\n// Default configuration\nconst defaultConfig: Required<GestureConfig> = {\n enabledGestures: ['tap', 'double-tap', 'long-press', 'swipe-left', 'swipe-right', 'swipe-up', 'swipe-down', 'pinch-in', 'pinch-out'],\n tapThreshold: 200,\n doubleTapThreshold: 300,\n longPressThreshold: 500,\n swipeThreshold: 50,\n swipeVelocityThreshold: 0.5,\n pinchThreshold: 0.1,\n rotationThreshold: 15,\n enableHapticFeedback: true\n}\n\n// Touch point interface\ninterface TouchPoint {\n id: number\n x: number\n y: number\n timestamp: number\n}\n\n// Gesture state\ninterface GestureState {\n isTracking: boolean\n touches: TouchPoint[]\n startTouches: TouchPoint[]\n lastTap?: { timestamp: number; point: { x: number; y: number } }\n longPressTimer?: NodeJS.Timeout\n initialDistance?: number\n initialScale?: number\n lastScale?: number\n}\n\n// Touch gesture hook\nexport function useTouchGestures(\n ref: React.RefObject<HTMLElement>,\n onGesture: (event: GestureEvent) => void,\n config: GestureConfig = {}\n) {\n const mergedConfig = { ...defaultConfig, ...config }\n const { isTouchDevice } = useDeviceInfo()\n const { triggerHaptic } = useHapticFeedback()\n const gestureState = React.useRef<GestureState>({\n isTracking: false,\n touches: [],\n startTouches: []\n })\n\n // Helper functions\n const getTouchPoint = (touch: Touch): TouchPoint => ({\n id: touch.identifier,\n x: touch.clientX,\n y: touch.clientY,\n timestamp: Date.now()\n })\n\n const getDistance = (p1: TouchPoint, p2: TouchPoint): number => \n Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2))\n\n const getVelocity = (start: TouchPoint, end: TouchPoint): { x: number; y: number } => {\n const timeDiff = Math.max(end.timestamp - start.timestamp, 1)\n return {\n x: (end.x - start.x) / timeDiff,\n y: (end.y - start.y) / timeDiff\n }\n }\n\n const createGestureEvent = (\n type: GestureType,\n startPoint: TouchPoint,\n currentPoint: TouchPoint,\n additionalData: Partial<GestureEvent> = {}\n ): GestureEvent => ({\n type,\n startPoint: { x: startPoint.x, y: startPoint.y },\n currentPoint: { x: currentPoint.x, y: currentPoint.y },\n duration: currentPoint.timestamp - startPoint.timestamp,\n target: ref.current!,\n preventDefault: () => {},\n ...additionalData\n })\n\n // Handle touch start\n const handleTouchStart = React.useCallback((e: TouchEvent) => {\n if (!mergedConfig.enabledGestures.length) return\n\n const touches = Array.from(e.touches).map(getTouchPoint)\n const state = gestureState.current\n\n state.isTracking = true\n state.touches = touches\n state.startTouches = [...touches]\n\n // Clear any existing long press timer\n if (state.longPressTimer) {\n clearTimeout(state.longPressTimer)\n }\n\n // Set up long press detection for single touch\n if (touches.length === 1 && mergedConfig.enabledGestures.includes('long-press')) {\n state.longPressTimer = setTimeout(() => {\n if (state.touches.length === 1 && touches[0]) {\n const gestureEvent = createGestureEvent('long-press', touches[0], touches[0])\n onGesture(gestureEvent)\n \n if (mergedConfig.enableHapticFeedback) {\n triggerHaptic('heavy')\n }\n }\n }, mergedConfig.longPressThreshold)\n }\n\n // Handle multi-touch gestures\n if (touches.length === 2 && touches[0] && touches[1]) {\n state.initialDistance = getDistance(touches[0], touches[1])\n state.initialScale = 1\n state.lastScale = 1\n }\n }, [mergedConfig, onGesture, triggerHaptic])\n\n // Handle touch move\n const handleTouchMove = React.useCallback((e: TouchEvent) => {\n const state = gestureState.current\n if (!state.isTracking) return\n\n const touches = Array.from(e.touches).map(getTouchPoint)\n state.touches = touches\n\n // Handle pinch gesture\n if (touches.length === 2 && state.initialDistance && touches[0] && touches[1]) {\n const currentDistance = getDistance(touches[0], touches[1])\n const scale = currentDistance / state.initialDistance\n const scaleDiff = Math.abs(scale - (state.lastScale || 1))\n\n if (scaleDiff > mergedConfig.pinchThreshold) {\n const gestureType = scale > (state.lastScale || 1) ? 'pinch-out' : 'pinch-in'\n \n if (mergedConfig.enabledGestures.includes(gestureType)) {\n const centerPoint = {\n x: (touches[0].x + touches[1].x) / 2,\n y: (touches[0].y + touches[1].y) / 2,\n id: -1,\n timestamp: Date.now()\n }\n \n const startCenterPoint = {\n x: ((state.startTouches[0]?.x ?? 0) + (state.startTouches[1]?.x ?? 0)) / 2,\n y: ((state.startTouches[0]?.y ?? 0) + (state.startTouches[1]?.y ?? 0)) / 2,\n id: -1,\n timestamp: state.startTouches[0]?.timestamp ?? Date.now()\n }\n\n const gestureEvent = createGestureEvent(gestureType, startCenterPoint, centerPoint, {\n scale,\n distance: currentDistance\n })\n \n onGesture(gestureEvent)\n state.lastScale = scale\n }\n }\n }\n\n // Clear long press timer on move\n if (state.longPressTimer && touches.length === 1 && state.startTouches[0] && touches[0]) {\n const startTouch = state.startTouches[0]\n const currentTouch = touches[0]\n const distance = getDistance(startTouch, currentTouch)\n \n if (distance > mergedConfig.swipeThreshold) {\n clearTimeout(state.longPressTimer)\n state.longPressTimer = undefined\n }\n }\n }, [mergedConfig, onGesture])\n\n // Handle touch end\n const handleTouchEnd = React.useCallback((e: TouchEvent) => {\n const state = gestureState.current\n if (!state.isTracking) return\n\n const endTouches = Array.from(e.changedTouches).map(getTouchPoint)\n const currentTime = Date.now()\n\n // Clear long press timer\n if (state.longPressTimer) {\n clearTimeout(state.longPressTimer)\n state.longPressTimer = undefined\n }\n\n // Handle single touch gestures\n if (state.startTouches.length === 1 && endTouches.length === 1 && state.startTouches[0] && endTouches[0]) {\n const startTouch = state.startTouches[0]\n const endTouch = endTouches[0]\n const distance = getDistance(startTouch, endTouch)\n const duration = endTouch.timestamp - startTouch.timestamp\n\n // Check for swipe gestures\n if (distance > mergedConfig.swipeThreshold) {\n const velocity = getVelocity(startTouch, endTouch)\n const absVelX = Math.abs(velocity.x)\n const absVelY = Math.abs(velocity.y)\n\n if (absVelX > mergedConfig.swipeVelocityThreshold || absVelY > mergedConfig.swipeVelocityThreshold) {\n let gestureType: GestureType\n\n if (absVelX > absVelY) {\n gestureType = velocity.x > 0 ? 'swipe-right' : 'swipe-left'\n } else {\n gestureType = velocity.y > 0 ? 'swipe-down' : 'swipe-up'\n }\n\n if (mergedConfig.enabledGestures.includes(gestureType)) {\n const gestureEvent = createGestureEvent(gestureType, startTouch, endTouch, {\n velocity,\n distance\n })\n \n onGesture(gestureEvent)\n \n if (mergedConfig.enableHapticFeedback) {\n triggerHaptic('light')\n }\n }\n }\n }\n // Check for tap gestures\n else if (duration < mergedConfig.tapThreshold && distance < mergedConfig.swipeThreshold) {\n // Check for double tap\n if (state.lastTap && \n currentTime - state.lastTap.timestamp < mergedConfig.doubleTapThreshold &&\n getDistance({...state.lastTap.point, id: -1, timestamp: state.lastTap.timestamp}, endTouch) < mergedConfig.swipeThreshold) {\n \n if (mergedConfig.enabledGestures.includes('double-tap')) {\n const gestureEvent = createGestureEvent('double-tap', startTouch, endTouch)\n onGesture(gestureEvent)\n \n if (mergedConfig.enableHapticFeedback) {\n triggerHaptic('medium')\n }\n }\n \n state.lastTap = undefined\n } else {\n // Single tap\n if (mergedConfig.enabledGestures.includes('tap')) {\n const gestureEvent = createGestureEvent('tap', startTouch, endTouch)\n onGesture(gestureEvent)\n \n if (mergedConfig.enableHapticFeedback) {\n triggerHaptic('light')\n }\n }\n \n state.lastTap = {\n timestamp: currentTime,\n point: { x: endTouch.x, y: endTouch.y }\n }\n }\n }\n }\n\n // Reset gesture state\n if (e.touches.length === 0) {\n state.isTracking = false\n state.touches = []\n state.startTouches = []\n state.initialDistance = undefined\n state.initialScale = undefined\n state.lastScale = undefined\n }\n }, [mergedConfig, onGesture, triggerHaptic])\n\n // Attach event listeners\n React.useEffect(() => {\n const element = ref.current\n if (!element || !isTouchDevice) return\n\n element.addEventListener('touchstart', handleTouchStart, { passive: false })\n element.addEventListener('touchmove', handleTouchMove, { passive: false })\n element.addEventListener('touchend', handleTouchEnd, { passive: false })\n element.addEventListener('touchcancel', handleTouchEnd, { passive: false })\n\n return () => {\n element.removeEventListener('touchstart', handleTouchStart)\n element.removeEventListener('touchmove', handleTouchMove)\n element.removeEventListener('touchend', handleTouchEnd)\n element.removeEventListener('touchcancel', handleTouchEnd)\n }\n }, [handleTouchStart, handleTouchMove, handleTouchEnd, isTouchDevice])\n\n return {\n isGestureEnabled: isTouchDevice && mergedConfig.enabledGestures.length > 0\n }\n}\n\n// Media player specific gesture hook with predefined actions\nexport function useMediaGestures(\n ref: React.RefObject<HTMLElement>,\n actions: {\n onPlayPause?: () => void\n onSeek?: (direction: 'forward' | 'backward', amount: number) => void\n onVolumeChange?: (direction: 'up' | 'down', amount: number) => void\n onToggleFullscreen?: () => void\n onZoom?: (scale: number) => void\n }\n) {\n const handleGesture = React.useCallback((event: GestureEvent) => {\n const { type, velocity, distance, scale } = event\n\n switch (type) {\n case 'double-tap':\n // Double tap to play/pause\n actions.onPlayPause?.()\n break\n\n case 'swipe-left':\n // Swipe left to seek backward\n const backwardAmount = Math.min((distance || 0) / 10, 30) // Max 30 seconds\n actions.onSeek?.('backward', backwardAmount)\n break\n\n case 'swipe-right':\n // Swipe right to seek forward\n const forwardAmount = Math.min((distance || 0) / 10, 30) // Max 30 seconds\n actions.onSeek?.('forward', forwardAmount)\n break\n\n case 'swipe-up':\n // Swipe up on right side for volume up\n if (event.startPoint.x > (ref.current?.clientWidth || 0) / 2) {\n const volumeAmount = Math.min((distance || 0) / 100, 0.2) // Max 20%\n actions.onVolumeChange?.('up', volumeAmount)\n }\n break\n\n case 'swipe-down':\n // Swipe down on right side for volume down\n if (event.startPoint.x > (ref.current?.clientWidth || 0) / 2) {\n const volumeAmount = Math.min((distance || 0) / 100, 0.2) // Max 20%\n actions.onVolumeChange?.('down', volumeAmount)\n }\n break\n\n case 'pinch-out':\n // Pinch out to zoom in (for video zoom functionality)\n actions.onZoom?.(scale || 1)\n break\n\n case 'pinch-in':\n // Pinch in to zoom out\n actions.onZoom?.(scale || 1)\n break\n\n case 'long-press':\n // Long press for fullscreen toggle\n actions.onToggleFullscreen?.()\n break\n\n default:\n break\n }\n }, [actions, ref])\n\n const gestureConfig: GestureConfig = {\n enabledGestures: ['tap', 'double-tap', 'long-press', 'swipe-left', 'swipe-right', 'swipe-up', 'swipe-down', 'pinch-in', 'pinch-out'],\n enableHapticFeedback: true,\n swipeThreshold: 30,\n swipeVelocityThreshold: 0.3\n }\n\n return useTouchGestures(ref, handleGesture, gestureConfig)\n}","import { useState, useRef, useCallback, useEffect } 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}","import { useState, useCallback, useMemo, useEffect } from \"react\"\n\ninterface SubtitleCue {\n start: number\n end: number\n text: string\n}\n\nexport interface SubtitleTrack {\n id: string\n label: string\n language?: string\n src?: string\n}\n\nexport interface UseEnhancedSubtitlesOptions {\n subtitleSrc?: string\n subtitleTracks?: SubtitleTrack[]\n defaultFontSize?: \"small\" | \"medium\" | \"large\"\n onLoadError?: (error: Error) => void\n}\n\nexport function useEnhancedSubtitles({\n subtitleSrc,\n subtitleTracks = [],\n defaultFontSize = \"medium\",\n onLoadError\n}: UseEnhancedSubtitlesOptions = {}) {\n const [subtitlesEnabled, setSubtitlesEnabled] = useState(false)\n const [subtitleCues, setSubtitleCues] = useState<SubtitleCue[]>([])\n const [currentSubtitle, setCurrentSubtitle] = useState(\"\")\n const [currentTrackId, setCurrentTrackId] = useState<string | null>(null)\n const [fontSize, setFontSize] = useState<\"small\" | \"medium\" | \"large\">(defaultFontSize)\n const [loadError, setLoadError] = useState<Error | null>(null)\n const [isLoading, setIsLoading] = useState(false)\n\n // Size mapping for subtitle font sizes\n const sizeMap = {\n small: \"text-sm\",\n medium: \"text-base\", \n large: \"text-lg\"\n }\n\n // Determine if subtitles are available\n const hasSubtitles = !!(subtitleSrc || (subtitleTracks && subtitleTracks.length > 0))\n\n // Parse VTT/WebVTT timestamp\n const parseVTTTime = (timeStr: string): number => {\n const parts = timeStr.split(\":\")\n const seconds = parts[2] ? parseFloat(parts[2]) : 0\n const minutes = parts[1] ? parseInt(parts[1], 10) * 60 : 0\n const hours = parts[0] ? parseInt(parts[0], 10) * 3600 : 0\n return hours + minutes + seconds\n }\n\n // Parse SRT timestamp\n const parseSRTTime = (timeStr: string): number => {\n // SRT format: 00:00:00,000 (hours:minutes:seconds,milliseconds)\n const [time, ms] = timeStr.split(\",\")\n const parts = (time || \"\").split(\":\")\n const milliseconds = ms ? parseInt(ms, 10) / 1000 : 0\n const seconds = parts[2] ? parseInt(parts[2], 10) : 0\n const minutes = parts[1] ? parseInt(parts[1], 10) * 60 : 0\n const hours = parts[0] ? parseInt(parts[0], 10) * 3600 : 0\n return hours + minutes + seconds + milliseconds\n }\n\n // Load and parse subtitle file\n const loadSubtitles = async (url: string) => {\n setIsLoading(true)\n setLoadError(null)\n \n try {\n const response = await fetch(url)\n if (!response.ok) {\n throw new Error(`Failed to load subtitles: ${response.status} ${response.statusText}`)\n }\n \n const text = await response.text()\n const cues: SubtitleCue[] = []\n const lines = text.split(\"\\n\")\n let i = 0\n\n // Detect format (VTT or SRT)\n const isVTT = text.includes(\"WEBVTT\") || url.endsWith(\".vtt\")\n const isSRT = url.endsWith(\".srt\") || /^\\d+$/.test(lines[0]?.trim() || \"\")\n\n if (isVTT) {\n // Parse VTT format\n while (i < lines.length) {\n if (lines[i]?.includes(\"-->\")) {\n const [startStr, endStr] = (lines[i] || \"\").split(\"-->\").map((s) => s.trim())\n const start = parseVTTTime(startStr || \"\")\n const end = parseVTTTime(endStr || \"\")\n\n i++\n let subtitleText = \"\"\n while (i < lines.length && lines[i]?.trim() !== \"\") {\n subtitleText += (subtitleText ? \" \" : \"\") + lines[i]?.trim()\n i++\n }\n\n if (subtitleText) {\n cues.push({ start, end, text: subtitleText })\n }\n }\n i++\n }\n } else if (isSRT) {\n // Parse SRT format\n while (i < lines.length) {\n // Skip the sequence number\n if (/^\\d+$/.test(lines[i]?.trim() || \"\")) {\n i++\n // Parse timestamp line\n if (lines[i]?.includes(\"-->\")) {\n const [startStr, endStr] = (lines[i] || \"\").split(\"-->\").map((s) => s.trim())\n const start = parseSRTTime(startStr || \"\")\n const end = parseSRTTime(endStr || \"\")\n\n i++\n let subtitleText = \"\"\n while (i < lines.length && lines[i]?.trim() !== \"\") {\n subtitleText += (subtitleText ? \" \" : \"\") + lines[i]?.trim()\n i++\n }\n\n if (subtitleText) {\n cues.push({ start, end, text: subtitleText })\n }\n }\n }\n i++\n }\n } else {\n throw new Error(\"Unsupported subtitle format. Only VTT and SRT are supported.\")\n }\n\n if (cues.length === 0) {\n throw new Error(\"No subtitle cues found in file\")\n }\n\n setSubtitleCues(cues)\n setIsLoading(false)\n } catch (error) {\n const err = error instanceof Error ? error : new Error(\"Failed to load subtitles\")\n console.error(\"Failed to load subtitles:\", err)\n setLoadError(err)\n setIsLoading(false)\n setSubtitleCues([])\n onLoadError?.(err)\n }\n }\n\n // Get current subtitle text based on time\n const getCurrentSubtitle = (currentTime: number) => {\n if (!subtitlesEnabled || subtitleCues.length === 0) return \"\"\n \n const currentCue = subtitleCues.find(\n (cue) => currentTime >= cue.start && currentTime <= cue.end\n )\n return currentCue?.text || \"\"\n }\n\n // Toggle subtitles on/off\n const toggleSubtitles = () => {\n setSubtitlesEnabled(prev => {\n const newEnabled = !prev\n \n if (newEnabled && !loadError) {\n // Try to load subtitles if not already loaded\n if (subtitleCues.length === 0 && !isLoading) {\n // Load default subtitle source or first track\n const srcToLoad = subtitleSrc || subtitleTracks[0]?.src\n if (srcToLoad) {\n loadSubtitles(srcToLoad)\n if (subtitleTracks[0]) {\n setCurrentTrackId(subtitleTracks[0].id)\n }\n }\n }\n } else if (!newEnabled) {\n setCurrentSubtitle(\"\")\n }\n \n return newEnabled\n })\n }\n\n // Select a specific subtitle track\n const selectSubtitleTrack = (trackId: string | null) => {\n if (!trackId) {\n // Turn off subtitles\n setSubtitlesEnabled(false)\n setCurrentTrackId(null)\n setCurrentSubtitle(\"\")\n return\n }\n\n const track = subtitleTracks.find(t => t.id === trackId)\n if (track?.src) {\n setCurrentTrackId(trackId)\n loadSubtitles(track.src)\n setSubtitlesEnabled(true)\n }\n }\n\n // Change subtitle font size\n const changeSubtitleFontSize = (size: \"small\" | \"medium\" | \"large\") => {\n setFontSize(size)\n }\n\n // Get CSS classes for subtitle display\n const getSubtitleStyles = {\n fontSize: sizeMap[fontSize],\n className: `${sizeMap[fontSize]} font-medium`\n }\n\n // Clear subtitle on disable\n useEffect(() => {\n if (!subtitlesEnabled) {\n setCurrentSubtitle(\"\")\n }\n }, [subtitlesEnabled])\n\n // Auto-load default subtitles on mount if available\n useEffect(() => {\n if (subtitleSrc && !subtitleCues.length && !loadError && !isLoading) {\n // Don't auto-load, wait for user to enable\n // This prevents errors on initial load\n }\n }, [])\n\n return {\n // State\n subtitlesEnabled,\n currentSubtitle,\n subtitleCues,\n currentTrackId,\n fontSize,\n loadError,\n isLoading,\n hasSubtitles,\n \n // Actions\n toggleSubtitles,\n selectSubtitleTrack,\n changeSubtitleFontSize,\n setCurrentSubtitle,\n \n // Utilities\n getCurrentSubtitle,\n getSubtitleStyles,\n \n // Track info\n availableTracks: subtitleTracks\n }\n}\n","import { useState, useRef, useCallback, useEffect } from \"react\"\n\nexport function useMediaControls(isPlaying: boolean, showSettings: boolean) {\n\tconst [controlsVisible, setControlsVisible] = useState(true)\n\tconst [showVolumeSlider, setShowVolumeSlider] = useState(false)\n const 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}","import { useEffect, useCallback } 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}","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(\"Canvas is tainted - video source may not have proper CORS headers. Try setting crossOrigin='anonymous' on the video element.\")\n \t\t\t\talert(\"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} 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}","\"use client\"\n\nimport React from \"react\"\nimport type { MediaActionType, MediaState } from \"../context/media-context\"\nimport type { OptimisticMediaAction, MediaActionState, EnhancedMediaStore } from \"../context/media-store\"\nimport { MediaActionTypes } from \"../context/media-context\"\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> = MediaActionPayloads[T] extends void\n\t? (optimistic?: boolean) => Promise<void>\n\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) \n\t\t\t\t\t? newActionState \n\t\t\t\t\t: 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// Playback actions\n\t\tplay: createOptimisticAction(MediaActionTypes.PLAY, store),\n\t\tpause: createOptimisticAction(MediaActionTypes.PAUSE, store),\n\t\tseek: createOptimisticAction(MediaActionTypes.SEEK, store),\n\t\t\n\t\t// Volume actions \n\t\tsetVolume: createOptimisticAction(MediaActionTypes.SET_VOLUME, store),\n\t\tmute: createOptimisticAction(MediaActionTypes.MUTE, store),\n\t\tunmute: createOptimisticAction(MediaActionTypes.UNMUTE, store),\n\t\ttoggleMute: createOptimisticAction(MediaActionTypes.TOGGLE_MUTE, store),\n\t\t\n\t\t// Media state actions\n\t\tsetDuration: createOptimisticAction(MediaActionTypes.SET_DURATION, store),\n\t\tsetCurrentTime: createOptimisticAction(MediaActionTypes.SET_CURRENT_TIME, store),\n\t\tsetBuffered: createOptimisticAction(MediaActionTypes.SET_BUFFERED, store),\n\t\tsetLoading: createOptimisticAction(MediaActionTypes.SET_LOADING, store),\n\t\tsetError: createOptimisticAction(MediaActionTypes.SET_ERROR, store),\n\t\t\n\t\t// Display actions\n\t\tenterFullscreen: createOptimisticAction(MediaActionTypes.ENTER_FULLSCREEN, store),\n\t\texitFullscreen: createOptimisticAction(MediaActionTypes.EXIT_FULLSCREEN, store),\n\t\tenterPiP: createOptimisticAction(MediaActionTypes.ENTER_PIP, store),\n\t\texitPiP: createOptimisticAction(MediaActionTypes.EXIT_PIP, store),\n\t\t\n\t\t// Advanced actions\n\t\tsetPlaybackRate: createOptimisticAction(MediaActionTypes.SET_PLAYBACK_RATE, store),\n\t\tsetSubtitleTrack: createOptimisticAction(MediaActionTypes.SET_SUBTITLE_TRACK, store),\n\t\tsetRendition: createOptimisticAction(MediaActionTypes.SET_RENDITION, store),\n\t\ttoggleSubtitles: createOptimisticAction(MediaActionTypes.TOGGLE_SUBTITLES, store),\n\t\t\n\t\t// Preview actions\n\t\tpreviewTime: createOptimisticAction(MediaActionTypes.PREVIEW_TIME, store),\n\t\tclearPreview: createOptimisticAction(MediaActionTypes.CLEAR_PREVIEW, store)\n\t}), [store])\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// These actions benefit from immediate UI feedback\n\t\ttogglePlayPause: async (isPlaying: boolean) => {\n\t\t\tif (isPlaying) {\n\t\t\t\tawait actions.pause(true) // optimistic\n\t\t\t} else {\n\t\t\t\tawait actions.play(true) // optimistic\n\t\t\t}\n\t\t},\n\t\t\n\t\tseekWithPreview: async (time: number) => {\n\t\t\t// Immediate preview update, then actual seek\n\t\t\tawait actions.previewTime(time, true)\n\t\t\tawait actions.seek(time, true)\n\t\t},\n\t\t\n\t\tadjustVolume: async (delta: number, currentVolume: number) => {\n\t\t\tconst newVolume = Math.max(0, Math.min(1, currentVolume + delta))\n\t\t\tawait actions.setVolume(newVolume, true)\n\t\t},\n\t\t\n\t\ttoggleFullscreenOptimistic: async (isFullscreen: boolean) => {\n\t\t\tif (isFullscreen) {\n\t\t\t\tawait actions.exitFullscreen(true)\n\t\t\t} else {\n\t\t\t\tawait actions.enterFullscreen(true)\n\t\t\t}\n\t\t}\n\t}), [actions])\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}","\"use client\"\n\nimport { useCallback, useState, useActionState, useOptimistic } from \"react\"\nimport type { MediaPlayerState } from \"../types/index\"\nimport { useMediaStore, useMediaSelector } from \"../context/media-context\"\nimport { useMediaOptimistic } from \"./use-media-optimistic\"\nimport { useMediaActions } from \"./use-media-actions\"\nimport type { EnhancedMediaStore } from \"../context/media-store\"\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\t\tupdateState({ isPlaying })\n \t\t}\n\n\tconst setCurrentTime = (currentTime: number) => {\n \t\t\tupdateState({ currentTime })\n \t\t}\n\n\tconst setDuration = (duration: number) => {\n \t\t\tupdateState({ duration })\n \t\t}\n\n\tconst setVolume = (volume: number) => {\n \t\t\tupdateState({ volume: Math.max(0, Math.min(1, volume)) })\n \t\t}\n\n\tconst setMuted = (isMuted: boolean) => {\n \t\t\tupdateState({ isMuted })\n \t\t}\n\n\tconst setLoading = (isLoading: boolean) => {\n \t\t\tupdateState({ isLoading })\n \t\t}\n\n\tconst setFullscreen = (isFullscreen: boolean) => {\n \t\t\tupdateState({ isFullscreen })\n \t\t}\n\n\tconst setError = (error: string | null) => {\n \t\t\tupdateState({ error })\n \t\t}\n\n\tconst setBuffered = (buffered: TimeRanges | null) => {\n \t\t\tupdateState({ buffered })\n \t\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\t\n\t// Check if this is an enhanced store\n\tconst isEnhanced = 'getOptimisticState' in store\n\t\n\tif (!isEnhanced) {\n\t\t// Fall back to regular media state if not enhanced\n\t\treturn useMediaState() as any\n\t}\n\t\n\t// Cast to enhanced store type\n\tconst enhancedStore = store as unknown as EnhancedMediaStore\n\t\n\t// Use React 19 optimistic updates\n\tconst optimisticState = useMediaOptimistic(enhancedStore)\n\t\n\t// Get action handlers with React 19 features\n\tconst actions = useMediaActions(enhancedStore)\n\t\n\treturn {\n\t\t// State (optimistic values for immediate UI feedback)\n\t\tstate: optimisticState.state,\n\t\tactualState: optimisticState.actualState,\n\t\t\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\t\t\n\t\t// Computed values\n\t\tprogress: optimisticState.progress,\n\t\tformattedTime: optimisticState.formattedTime,\n\t\tformattedDuration: optimisticState.formattedDuration,\n\t\t\n\t\t// Actions with optimistic updates\n\t\tactions,\n\t\t\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\t\t\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\t\t\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\ttry {\n\t\t// Try to use the enhanced version if MediaStore context is available\n\t\treturn useEnhancedMediaState()\n\t} catch (error) {\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 useMediaState()\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 type { MediaPlayerControls, MediaPlayerState } from \"../types/index\"\nimport { useMediaStore, useMediaSelector } from \"../context/media-context\"\nimport { useMediaOptimistic } from \"./use-media-optimistic\"\nimport { useMediaActions } from \"./use-media-actions\"\nimport type { EnhancedMediaStore } from \"../context/media-store\"\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\t// Event callbacks\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\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 | undefined>(undefined)\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 if available\n\tconst enhancedStore = store as unknown as EnhancedMediaStore\n\tconst optimisticState = isEnhanced ? useMediaOptimistic(enhancedStore) : null\n\tconst actions = isEnhanced ? useMediaActions(enhancedStore) : null\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(volume, (state, newVolume: number) => {\n\t\treturn Math.max(0, Math.min(1, newVolume))\n\t})\n\n\tconst [optimisticTime, setOptimisticTime] = useOptimistic(currentTime, (state, newTime: number) => {\n\t\treturn Math.max(0, Math.min(duration || 0, newTime))\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\ttoggleFullscreen: () => {\n\t\t\t\tif (document.fullscreenElement) {\n\t\t\t\t\texitFullscreen()\n\t\t\t\t} else {\n\t\t\t\t\tenterFullscreen()\n\t\t\t\t}\n\t\t\t}\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\tisPlaying: optimisticState?.state?.isPlaying ?? isPlaying,\n\t\tcurrentTime: optimisticState?.state?.currentTime ?? currentTime,\n\t\tduration: optimisticState?.state?.duration ?? duration,\n\t\tvolume: optimisticState?.state?.volume ?? optimisticVolume,\n\t\tisMuted: optimisticState?.state?.isMuted ?? isMuted,\n\t\tisLoading: optimisticState?.state?.isBuffering ?? isLoading,\n\t\tisBuffering: optimisticState?.state?.isBuffering ?? isBuffering,\n\t\terror: optimisticState?.state?.error ?? error,\n\t\tbuffered: optimisticState?.state?.buffered ?? buffered,\n\t\tisFullscreen: optimisticState?.state?.isFullscreen ?? isFullscreen,\n\t\tprogress: duration > 0 ? currentTime / duration : 0,\n\t\tisTransitioning: isPending || isSeeking,\n\t\tcanPlay: !isLoading && !isBuffering && !error\n\t}), [\n\t\toptimisticState,\n\t\tisPlaying,\n\t\tcurrentTime,\n\t\tduration,\n\t\toptimisticVolume,\n\t\tisMuted,\n\t\tisLoading,\n\t\tisBuffering,\n\t\terror,\n\t\tbuffered,\n\t\tisFullscreen,\n\t\tisPending,\n\t\tisSeeking\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, // The optimisticState object contains all the actions\n\t\tactionState: optimisticState?.state,\n\n\t\t// Optimistic features\n\t\toptimisticState,\n\t\tisEnhanced\n\t}\n}","/**\n * Intelligent Preloading Hook\n * Combines user behavior analysis with network conditions for optimal preloading\n */\n\nimport { useEffect, useRef, useCallback, useMemo } 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\t// Network Information API (if available)\n\tconst networkInfoRef = useRef<{\n\t\teffectiveType?: string;\n\t\tdownlink?: number;\n\t\trtt?: number;\n\t\tsaveData?: boolean;\n\t} | 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((type: keyof UserBehaviorData, increment = 1) => {\n\t\tconst behavior = userBehaviorRef.current;\n\t\tbehavior[type] = typeof behavior[type] === 'number' ? behavior[type] + increment : Date.now();\n\t\tbehavior.engagementScore = calculateEngagementScore();\n\t\tbehavior.lastInteraction = Date.now();\n\t}, [calculateEngagementScore]);\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.effectiveType || '4g', // Use effectiveType as the primary type indicator\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\tsource: MediaSource,\n\t\tindex: number,\n\t\tcurrentIndex: number = 0\n\t): PreloadingDecision => {\n\t\t// Skip if already preloaded\n\t\tif (preloadedItemsRef.current.has(source.src)) {\n\t\t\treturn { shouldPreload: false, priority: 'low', reason: 'Already preloaded' };\n\t\t}\n\n\t\t// Check if within preload radius\n\t\tconst distance = Math.abs(index - currentIndex);\n\t\tif (distance > preloadRadius) {\n\t\t\treturn { shouldPreload: false, priority: 'low', reason: 'Outside preload radius' };\n\t\t}\n\n\t\tconst behavior = userBehaviorRef.current;\n\t\tconst network = getNetworkConditions();\n\t\tconst engagementScore = behavior.engagementScore;\n\t\tconst timeSinceInteraction = Date.now() - behavior.lastInteraction;\n\n\t\t// Network-based decisions\n\t\tif (network.saveData) {\n\t\t\treturn { shouldPreload: false, priority: 'low', reason: 'Data saver mode' };\n\t\t}\n\n\t\t// Strategy-based filtering\n\t\tlet shouldPreload = false;\n\t\tlet priority: 'high' | 'medium' | 'low' = 'medium';\n\t\tlet reason = '';\n\n\t\tswitch (strategy) {\n\t\t\tcase 'conservative':\n\t\t\t\tshouldPreload = engagementScore > 70 && network.effectiveType !== '2g' && distance === 1;\n\t\t\t\tpriority = shouldPreload ? 'medium' : 'low';\n\t\t\t\treason = shouldPreload ? 'High engagement and optimal network' : 'Conservative strategy';\n\t\t\t\tbreak;\n\n\t\t\tcase 'aggressive':\n\t\t\t\tshouldPreload = engagementScore > 30 && network.effectiveType !== 'slow-2g';\n\t\t\t\tpriority = engagementScore > 70 ? 'high' : engagementScore > 50 ? 'medium' : 'low';\n\t\t\t\treason = shouldPreload ? 'Aggressive preloading' : 'Low engagement';\n\t\t\t\tbreak;\n\n\t\t\tcase 'balanced':\n\t\t\tdefault:\n\t\t\t\tconst networkMultiplier = network.effectiveType === '4g' ? 1 :\n\t\t\t\t\t\t\t\t\t\tnetwork.effectiveType === '3g' ? 0.7 : 0.3;\n\t\t\t\tconst adjustedScore = engagementScore * networkMultiplier;\n\n\t\t\t\tshouldPreload = adjustedScore > 40 && distance <= 2;\n\t\t\t\tpriority = adjustedScore > 70 ? 'high' : adjustedScore > 55 ? 'medium' : 'low';\n\t\t\t\treason = shouldPreload ? `Balanced: score ${adjustedScore.toFixed(1)}` : 'Low adjusted score';\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Additional heuristics\n\t\tif (shouldPreload) {\n\t\t\t// Prioritize HLS and adaptive streaming (check URL extension)\n\t\t\tconst sourceUrl = source.src.toLowerCase();\n\t\t\tif (sourceUrl.includes('.m3u8') || sourceUrl.includes('hls')) {\n\t\t\t\tpriority = priority === 'low' ? 'medium' : 'high';\n\t\t\t}\n\n\t\t\t// Boost priority for recent user interaction\n\t\t\tif (timeSinceInteraction < 5000) { // Within 5 seconds\n\t\t\t\tpriority = 'high';\n\t\t\t\treason += ' + Recent interaction';\n\t\t\t}\n\n\t\t\t// Consider content type (video gets higher priority than audio)\n\t\t\tif (source.type?.includes('mp4') || source.type?.includes('webm') ||\n\t\t\t\tsourceUrl.includes('.mp4') || sourceUrl.includes('.webm')) {\n\t\t\t\tpriority = priority === 'low' ? 'medium' : priority;\n\t\t\t}\n\t\t}\n\n\t\treturn { shouldPreload, priority, reason };\n\t}, [strategy, preloadRadius, getNetworkConditions, calculateEngagementScore]);\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 based on URL or MIME type\n\t\t\tconst sourceUrl = source.src.toLowerCase();\n\t\t\tconst mimeType = source.type?.toLowerCase() || '';\n\n\t\t\tif (sourceUrl.includes('.m3u8') || sourceUrl.includes('hls')) {\n\t\t\t\tlink.as = 'fetch';\n\t\t\t} else if (mimeType.includes('mp4') || mimeType.includes('webm') ||\n\t\t\t\tsourceUrl.includes('.mp4') || sourceUrl.includes('.webm')) {\n\t\t\t\tlink.as = 'video';\n\t\t\t} else if (mimeType.includes('mp3') || mimeType.includes('wav') || mimeType.includes('ogg') ||\n\t\t\t\tsourceUrl.includes('.mp3') || sourceUrl.includes('.wav') || sourceUrl.includes('.ogg')) {\n\t\t\t\tlink.as = 'audio';\n\t\t\t} else {\n\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\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((currentIndex: number = 0) => {\n\t\tpreloadQueueRef.current = [];\n\n\t\tsources.forEach((source, index) => {\n\t\t\tconst decision = shouldPreloadSource(source, index, currentIndex);\n\n\t\t\tif (decision.shouldPreload) {\n\t\t\t\tconst priority = decision.priority === 'high' ? 3 :\n\t\t\t\t\t\t\t\tdecision.priority === 'medium' ? 2 : 1;\n\n\t\t\t\tpreloadQueueRef.current.push({ source, priority });\n\t\t\t}\n\t\t});\n\n\t\tprocessPreloadQueue();\n\t}, [sources, shouldPreloadSource, processPreloadQueue]);\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 * Manually trigger preloading for specific index\n\t\t */\n\t\tpreloadAtIndex: (index: number) => {\n\t\t\tupdatePreloading(index);\n\t\t},\n\n\t\t/**\n\t\t * Get current user behavior data\n\t\t */\n\t\tgetUserBehavior: () => ({ ...userBehaviorRef.current }),\n\n\t\t/**\n\t\t * Get current network conditions\n\t\t */\n\t\tgetNetworkConditions: getNetworkConditions,\n\n\t\t/**\n\t\t * Clear preloaded items cache\n\t\t */\n\t\tclearCache: () => {\n\t\t\tpreloadedItemsRef.current.clear();\n\t\t},\n\n\t\t/**\n\t\t * Get preloading statistics\n\t\t */\n\t\tgetStats: () => ({\n\t\t\tpreloadedItems: preloadedItemsRef.current.size,\n\t\t\tengagementScore: userBehaviorRef.current.engagementScore,\n\t\t\tqueueLength: preloadQueueRef.current.length,\n\t\t\tmaxPreloadItems,\n\t\t}),\n\t}), [updatePreloading, getNetworkConditions, maxPreloadItems]);\n\n\treturn controls;\n};\n\nexport default useIntelligentPreloading;","import { useState, useCallback, useMemo, useEffect } 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\t\tif (!subtitlesEnabled || subtitleCues.length === 0) return \"\"\n \t\t\t\n \t\t\tconst currentCue = subtitleCues.find(\n \t\t\t\t(cue) => currentTime >= cue.start && currentTime <= cue.end\n \t\t\t)\n \t\t\treturn currentCue?.text || \"\"\n \t\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 * 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(\n\t\t\"useVideoPlayer\",\n\t\t\"useMediaPlayer (the primary media player hook)\"\n\t)\n\treturn useMediaPlayer(props)\n}\n\nexport function useEnhancedSubtitles(props: any) {\n\tshowDeprecationWarning(\n\t\t\"useEnhancedSubtitles\",\n\t\t\"useSubtitles (the current subtitle hook)\"\n\t)\n\treturn useSubtitles(props)\n}"],"names":["useKeyboardControls","enabled","state","controls","seekStep","volumeStep","handleKeyDown","event","target","percentage","useEffect","optimisticMediaReducer","action","useMediaOptimistic","store","actualState","React","optimisticState","addOptimistic","useOptimistic","dispatchOptimistic","optimisticActions","volume","time","rate","selectors","formatTime","seconds","mins","secs","hours","createOptimisticAction","type","payload","optimistic","useMediaActionState","actionState","setActionState","newActionState","current","useMediaActions","actions","MediaActionTypes","isPlaying","delta","currentVolume","newVolume","isFullscreen","retryLastAction","lastAction","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","media","initProps","key","value","handleTimeUpdate","useCallback","now","handlePlay","handlePause","handleVolumeChange","handleSeeking","handleSeeked","handleProgress","measureRenderTime","fps","prev","eventListeners","handler","passive","rafId","performanceLoop","useMemo","play","pause","clampedTime","clampedVolume","container","computedState","useMemoryOptimization","maxMemoryUsage","cleanupInterval","enableGC","monitorMemory","observersRef","eventListenersRef","intervalRefs","animationFrameRefs","getMemoryUsage","memory","memoryStats","setMemoryStats","checkMemory","usage","isHighUsage","performCleanup","interval","setInterval","timeout","frameId","observer","listeners","element","addEventListener","index","l","callback","delay","timeoutId","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","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","useVideoPlayer","videoRef","video","handleLoadedMetadata","handleWaiting","handlePlaying","handleCanPlay","ranges","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","useMediaControls","showSettings","controlsVisible","setControlsVisible","showVolumeSlider","setShowVolumeSlider","hideTimeoutRef","showControls","handleMouseMove","handleMouseEnter","handleMouseLeave","useKeyboardShortcuts","videoControls","takeScreenshot","useScreenshot","ctrlKey","canvas","ctx","blob","item","a","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","sourceUrl","preloadSource","link","mimeType","processPreloadQueue","itemsToPreload","b","updatePreloading","decision","handleScroll","handleKeyPress","handleFocus","timeInterval","handleNetworkChange","useSubtitles","props","showDeprecationWarning"],"mappings":"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"}