vidply 1.0.1 → 1.0.2
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.
- package/README.md +58 -4
- package/dist/vidply.css +36 -17
- package/dist/vidply.esm.js +2 -2
- package/dist/vidply.esm.js.map +2 -2
- package/dist/vidply.esm.min.js +2 -2
- package/dist/vidply.esm.min.meta.json +5 -5
- package/dist/vidply.js +2 -2
- package/dist/vidply.js.map +2 -2
- package/dist/vidply.min.css +1 -1
- package/dist/vidply.min.js +2 -2
- package/dist/vidply.min.meta.json +5 -5
- package/package.json +1 -1
- package/src/core/Player.js +2 -2
- package/src/icons/Icons.js +10 -10
- package/src/styles/vidply.css +36 -17
package/dist/vidply.esm.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/renderers/HTML5Renderer.js", "../src/utils/EventEmitter.js", "../src/utils/DOMUtils.js", "../src/utils/TimeUtils.js", "../src/icons/Icons.js", "../src/i18n/translations.js", "../src/i18n/i18n.js", "../src/controls/ControlBar.js", "../src/controls/CaptionManager.js", "../src/controls/KeyboardManager.js", "../src/controls/SettingsDialog.js", "../src/controls/TranscriptManager.js", "../src/core/Player.js", "../src/renderers/YouTubeRenderer.js", "../src/renderers/VimeoRenderer.js", "../src/renderers/HLSRenderer.js", "../src/features/PlaylistManager.js", "../src/index.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * HTML5 Media Renderer\n */\n\nexport class HTML5Renderer {\n constructor(player) {\n this.player = player;\n this.media = player.element;\n }\n\n async init() {\n // Hide native controls\n this.media.controls = false;\n this.media.removeAttribute('controls');\n \n this.attachEvents();\n \n // Set preload\n this.media.preload = this.player.options.preload;\n \n // Load media\n this.media.load();\n }\n\n attachEvents() {\n // Playback events\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n \n // Pause other players if enabled\n if (this.player.options.pauseOthersOnPlay) {\n this.pauseOtherPlayers();\n }\n });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n // Handle loop\n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n \n if (this.player.options.onVolumeChange) {\n this.player.options.onVolumeChange.call(this.player, this.media.volume);\n }\n });\n\n this.media.addEventListener('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n });\n\n this.media.addEventListener('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.media.addEventListener('progress', () => {\n if (this.media.buffered.length > 0) {\n const buffered = this.media.buffered.end(this.media.buffered.length - 1);\n this.player.emit('progress', buffered);\n }\n });\n\n this.media.addEventListener('error', (e) => {\n this.player.handleError(this.media.error);\n });\n\n this.media.addEventListener('ratechange', () => {\n this.player.state.playbackSpeed = this.media.playbackRate;\n this.player.emit('ratechange', this.media.playbackRate);\n });\n }\n\n pauseOtherPlayers() {\n // Pause other VidPly instances\n const allPlayers = document.querySelectorAll('.vidply-player');\n allPlayers.forEach(playerEl => {\n if (playerEl !== this.player.container) {\n const video = playerEl.querySelector('video, audio');\n if (video && !video.paused) {\n video.pause();\n }\n }\n });\n }\n\n play() {\n const promise = this.media.play();\n \n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n \n // If autoplay failed, try muted autoplay\n if (this.player.options.autoplay && !this.player.state.muted) {\n this.player.log('Retrying play with muted audio', 'info');\n this.media.muted = true;\n this.media.play().catch(err => {\n this.player.handleError(err);\n });\n }\n });\n }\n }\n\n pause() {\n this.media.pause();\n }\n\n seek(time) {\n this.media.currentTime = time;\n }\n\n setVolume(volume) {\n this.media.volume = volume;\n }\n\n setMuted(muted) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed) {\n this.media.playbackRate = speed;\n }\n\n /**\n * Get available quality levels from source elements\n * @returns {Array} Array of quality objects with index, height, width, and src\n */\n getQualities() {\n const sources = Array.from(this.media.querySelectorAll('source'));\n \n if (sources.length <= 1) {\n return [];\n }\n\n return sources.map((source, index) => {\n // Try to extract quality from data attributes or label\n const label = source.getAttribute('data-quality') || source.getAttribute('label') || '';\n const height = source.getAttribute('data-height') || this.extractHeightFromLabel(label);\n const width = source.getAttribute('data-width') || '';\n \n return {\n index,\n height: height ? parseInt(height) : 0,\n width: width ? parseInt(width) : 0,\n src: source.src,\n type: source.type,\n name: label || (height ? `${height}p` : `Quality ${index + 1}`)\n };\n }).filter(q => q.height > 0); // Only return qualities with valid height\n }\n\n /**\n * Extract height from quality label (e.g., \"1080p\" -> 1080)\n * @param {string} label \n * @returns {number}\n */\n extractHeightFromLabel(label) {\n const match = label.match(/(\\d+)p/i);\n return match ? parseInt(match[1]) : 0;\n }\n\n /**\n * Switch to a specific quality level\n * @param {number} qualityIndex - Index of the quality level (-1 for auto, not applicable for HTML5)\n */\n switchQuality(qualityIndex) {\n const qualities = this.getQualities();\n \n if (qualityIndex < 0 || qualityIndex >= qualities.length) {\n this.player.log('Invalid quality index', 'warn');\n return;\n }\n\n const quality = qualities[qualityIndex];\n const currentTime = this.media.currentTime;\n const wasPlaying = !this.media.paused;\n\n // Store the current source for comparison\n const currentSrc = this.media.currentSrc;\n \n // Don't switch if already at this quality\n if (currentSrc === quality.src) {\n this.player.log('Already at this quality level', 'info');\n return;\n }\n\n this.player.log(`Switching to quality: ${quality.name}`, 'info');\n\n // Update the src\n this.media.src = quality.src;\n \n // Wait for the new source to load, then restore playback state\n const onLoadedMetadata = () => {\n this.media.removeEventListener('loadedmetadata', onLoadedMetadata);\n \n // Restore playback position\n this.media.currentTime = currentTime;\n \n // Resume playback if it was playing\n if (wasPlaying) {\n this.media.play().catch(err => {\n this.player.log('Failed to resume playback after quality switch', 'warn');\n });\n }\n \n // Emit quality change event\n this.player.emit('qualitychange', { quality: quality.name, index: qualityIndex });\n };\n\n this.media.addEventListener('loadedmetadata', onLoadedMetadata);\n this.media.load();\n }\n\n /**\n * Get current quality index\n * @returns {number}\n */\n getCurrentQuality() {\n const qualities = this.getQualities();\n const currentSrc = this.media.currentSrc;\n \n for (let i = 0; i < qualities.length; i++) {\n if (qualities[i].src === currentSrc) {\n return i;\n }\n }\n \n return 0; // Default to first quality if not found\n }\n\n destroy() {\n // Remove event listeners\n this.media.removeEventListener('loadedmetadata', () => {});\n this.media.removeEventListener('play', () => {});\n this.media.removeEventListener('pause', () => {});\n // ... (other listeners would be removed in a real implementation)\n }\n}\n\n", "/**\n * Simple EventEmitter implementation\n */\n\nexport class EventEmitter {\n constructor() {\n this.events = {};\n }\n\n on(event, listener) {\n if (!this.events[event]) {\n this.events[event] = [];\n }\n this.events[event].push(listener);\n return this;\n }\n\n once(event, listener) {\n const onceListener = (...args) => {\n listener(...args);\n this.off(event, onceListener);\n };\n return this.on(event, onceListener);\n }\n\n off(event, listener) {\n if (!this.events[event]) return this;\n \n if (!listener) {\n delete this.events[event];\n } else {\n this.events[event] = this.events[event].filter(l => l !== listener);\n }\n \n return this;\n }\n\n emit(event, ...args) {\n if (!this.events[event]) return this;\n \n this.events[event].forEach(listener => {\n listener(...args);\n });\n \n return this;\n }\n\n removeAllListeners() {\n this.events = {};\n return this;\n }\n}\n\n", "/**\n * DOM manipulation utilities\n */\n\nexport const DOMUtils = {\n createElement(tag, options = {}) {\n const element = document.createElement(tag);\n \n if (options.className) {\n element.className = options.className;\n }\n \n if (options.attributes) {\n Object.entries(options.attributes).forEach(([key, value]) => {\n element.setAttribute(key, value);\n });\n }\n \n if (options.innerHTML) {\n element.innerHTML = options.innerHTML;\n }\n \n if (options.textContent) {\n element.textContent = options.textContent;\n }\n \n if (options.style) {\n Object.assign(element.style, options.style);\n }\n \n if (options.children) {\n options.children.forEach(child => {\n if (child) element.appendChild(child);\n });\n }\n \n return element;\n },\n\n addClass(element, className) {\n if (element && className) {\n element.classList.add(className);\n }\n },\n\n removeClass(element, className) {\n if (element && className) {\n element.classList.remove(className);\n }\n },\n\n toggleClass(element, className) {\n if (element && className) {\n element.classList.toggle(className);\n }\n },\n\n hasClass(element, className) {\n return element && element.classList.contains(className);\n },\n\n show(element) {\n if (element) {\n element.style.display = '';\n }\n },\n\n hide(element) {\n if (element) {\n element.style.display = 'none';\n }\n },\n\n fadeIn(element, duration = 300) {\n if (!element) return;\n \n element.style.opacity = '0';\n element.style.display = '';\n \n let start = null;\n const animate = (timestamp) => {\n if (!start) start = timestamp;\n const progress = timestamp - start;\n const opacity = Math.min(progress / duration, 1);\n \n element.style.opacity = opacity;\n \n if (progress < duration) {\n requestAnimationFrame(animate);\n }\n };\n \n requestAnimationFrame(animate);\n },\n\n fadeOut(element, duration = 300) {\n if (!element) return;\n \n const startOpacity = parseFloat(getComputedStyle(element).opacity) || 1;\n let start = null;\n \n const animate = (timestamp) => {\n if (!start) start = timestamp;\n const progress = timestamp - start;\n const opacity = Math.max(startOpacity - (progress / duration), 0);\n \n element.style.opacity = opacity;\n \n if (progress < duration) {\n requestAnimationFrame(animate);\n } else {\n element.style.display = 'none';\n }\n };\n \n requestAnimationFrame(animate);\n },\n\n offset(element) {\n if (!element) return { top: 0, left: 0 };\n \n const rect = element.getBoundingClientRect();\n return {\n top: rect.top + window.pageYOffset,\n left: rect.left + window.pageXOffset,\n width: rect.width,\n height: rect.height\n };\n },\n\n escapeHTML(str) {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n },\n\n sanitizeHTML(html) {\n // Basic HTML sanitization - allow safe tags for VTT captions\n // Since we control the HTML (from VTT parsing), we can safely allow these tags\n const temp = document.createElement('div');\n \n // Strip out any potentially dangerous tags/attributes\n // Allow: strong, em, u, span, b, i with class and data-voice attributes\n const safeHtml = html\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\n .replace(/<iframe\\b[^<]*(?:(?!<\\/iframe>)<[^<]*)*<\\/iframe>/gi, '')\n .replace(/on\\w+\\s*=/gi, '') // Remove event handlers\n .replace(/javascript:/gi, ''); // Remove javascript: protocol\n \n temp.innerHTML = safeHtml;\n return temp.innerHTML;\n }\n};\n\n", "/**\n * Time formatting and conversion utilities\n */\n\nexport const TimeUtils = {\n /**\n * Format seconds to time string (HH:MM:SS or MM:SS)\n */\n formatTime(seconds, alwaysShowHours = false) {\n if (!isFinite(seconds) || seconds < 0) {\n return alwaysShowHours ? '00:00:00' : '00:00';\n }\n \n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n \n const pad = (num) => String(num).padStart(2, '0');\n \n if (hours > 0 || alwaysShowHours) {\n return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;\n }\n \n return `${pad(minutes)}:${pad(secs)}`;\n },\n\n /**\n * Parse time string to seconds\n */\n parseTime(timeString) {\n const parts = timeString.split(':').map(p => parseInt(p, 10));\n \n if (parts.length === 3) {\n // HH:MM:SS\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n } else if (parts.length === 2) {\n // MM:SS\n return parts[0] * 60 + parts[1];\n } else if (parts.length === 1) {\n // SS\n return parts[0];\n }\n \n return 0;\n },\n\n /**\n * Format seconds to readable duration\n */\n formatDuration(seconds) {\n if (!isFinite(seconds) || seconds < 0) {\n return '0 seconds';\n }\n \n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n \n const parts = [];\n \n if (hours > 0) {\n parts.push(`${hours} hour${hours !== 1 ? 's' : ''}`);\n }\n if (minutes > 0) {\n parts.push(`${minutes} minute${minutes !== 1 ? 's' : ''}`);\n }\n if (secs > 0 || parts.length === 0) {\n parts.push(`${secs} second${secs !== 1 ? 's' : ''}`);\n }\n \n return parts.join(', ');\n },\n\n /**\n * Format percentage\n */\n formatPercentage(value, total) {\n if (total === 0) return 0;\n return Math.round((value / total) * 100);\n }\n};\n\n", "/**\n * SVG Icon Library for VidPly\n * Optimized with common viewBox and fill attributes\n */\n\n// SVG paths only (viewBox and fill added by wrapper)\nconst iconPaths = {\n play: `<path d=\"M8 5v14l11-7z\"/>`,\n\n pause: `<path d=\"M6 4h4v16H6V4zm8 0h4v16h-4V4z\"/>`,\n\n stop: `<rect x=\"6\" y=\"6\" width=\"12\" height=\"12\"/>`,\n\n rewind: `<path d=\"M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z\"/>`,\n\n forward: `<path d=\"M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z\"/>`,\n\n skipPrevious: `<path d=\"M6 6h2v12H6V6zm3 6l8.5 6V6L9 12z\"/>`,\n\n skipNext: `<path d=\"M16 6h2v12h-2V6zM6 6l8.5 6L6 18V6z\"/>`,\n\n restart: `<path d=\"M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z\"/>`,\n\n volumeHigh: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\"/>`,\n\n volumeMedium: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"/>`,\n\n volumeLow: `<path d=\"M7 9v6h4l5 5V4l-5 5H7z\"/>`,\n\n volumeMuted: `<path d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\"/>`,\n\n fullscreen: `<path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"/>`,\n\n fullscreenExit: `<path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"/>`,\n\n settings: `<path d=\"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z\"/>`,\n\n captions: `<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\"/>`,\n\n captionsOff: `<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\"/><path d=\"M0 0h24v24H0z\" fill=\"none\"/>`,\n\n pip: `<path d=\"M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z\"/>`,\n\n speed: `<path d=\"M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44z\"/><path d=\"M10.59 15.41a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z\"/>`,\n\n close: `<path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/>`,\n\n check: `<path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/>`,\n\n arrowUp: `<path d=\"M7 14l5-5 5 5z\"/>`,\n\n arrowDown: `<path d=\"M7 10l5 5 5-5z\"/>`,\n\n arrowLeft: `<path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/>`,\n\n arrowRight: `<path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/>`,\n\n loading: `<path d=\"M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z\"/>`,\n\n error: `<path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/>`,\n\n download: `<path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"/>`,\n\n link: `<path d=\"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\"/>`,\n\n playlist: `<path d=\"M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z\"/>`,\n\n language: `<path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z\"/>`,\n\n hd: `<path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z\"/>`,\n\n transcript: `<path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\"/>`,\n\n audioDescription: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z\"/><path d=\"M10.5 19c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/>`,\n\n audioDescriptionOn: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z\"/><path d=\"M10.5 19c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/><circle cx=\"19\" cy=\"16\" r=\"3\" fill=\"#3b82f6\"/><path d=\"M18.5 17.5l1-1 1.5 1.5\" stroke=\"white\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n\n signLanguage: `<g transform=\"scale(1.5)\"><path d=\"M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z\"/></g>`,\n\n signLanguageOn: `<g transform=\"scale(1.5)\"><path d=\"M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z\"/></g><circle cx=\"19\" cy=\"19\" r=\"3\" fill=\"#3b82f6\"/><path d=\"M17.5 19l1 1 2-2\" stroke=\"white\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n\n speaker: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"/>`,\n\n music: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7zm-1.5 16c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/>`,\n\n moreVertical: `<path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>`,\n\n moreHorizontal: `<path d=\"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>`\n};\n\n// Optimized wrapper that adds common SVG attributes\nconst svgWrapper = (paths) => `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">${paths}</svg>`;\n\n// Export Icons object with SVG wrappers\nexport const Icons = Object.fromEntries(\n Object.entries(iconPaths).map(([key, value]) => [key, svgWrapper(value)])\n);\n\nexport function getIcon(name) {\n return Icons[name] || Icons.play;\n}\n\nexport function createIconElement(name, className = '') {\n const wrapper = document.createElement('span');\n wrapper.className = `vidply-icon ${className}`.trim();\n wrapper.innerHTML = getIcon(name);\n wrapper.setAttribute('aria-hidden', 'true');\n return wrapper;\n}\n\n/**\n * Create the large centered play button overlay (complete SVG)\n * @returns {SVGElement} Complete SVG element with circle background and play icon\n */\nexport function createPlayOverlay() {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.setAttribute('class', 'vidply-play-overlay');\n svg.setAttribute('viewBox', '0 0 80 80');\n svg.setAttribute('width', '80');\n svg.setAttribute('height', '80');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('role', 'presentation');\n svg.style.cursor = 'pointer';\n \n // Create filter for drop shadow\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n const filterId = `vidply-play-shadow-${Math.random().toString(36).substr(2, 9)}`;\n const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');\n filter.setAttribute('id', filterId);\n filter.setAttribute('x', '-50%');\n filter.setAttribute('y', '-50%');\n filter.setAttribute('width', '200%');\n filter.setAttribute('height', '200%');\n \n const feGaussianBlur = document.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');\n feGaussianBlur.setAttribute('in', 'SourceAlpha');\n feGaussianBlur.setAttribute('stdDeviation', '3');\n \n const feOffset = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');\n feOffset.setAttribute('dx', '0');\n feOffset.setAttribute('dy', '2');\n feOffset.setAttribute('result', 'offsetblur');\n \n const feComponentTransfer = document.createElementNS('http://www.w3.org/2000/svg', 'feComponentTransfer');\n const feFuncA = document.createElementNS('http://www.w3.org/2000/svg', 'feFuncA');\n feFuncA.setAttribute('type', 'linear');\n feFuncA.setAttribute('slope', '0.3');\n feComponentTransfer.appendChild(feFuncA);\n \n const feMerge = document.createElementNS('http://www.w3.org/2000/svg', 'feMerge');\n const feMergeNode1 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\n const feMergeNode2 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\n feMergeNode2.setAttribute('in', 'SourceGraphic');\n feMerge.appendChild(feMergeNode1);\n feMerge.appendChild(feMergeNode2);\n \n filter.appendChild(feGaussianBlur);\n filter.appendChild(feOffset);\n filter.appendChild(feComponentTransfer);\n filter.appendChild(feMerge);\n defs.appendChild(filter);\n svg.appendChild(defs);\n \n // White circle background\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.setAttribute('cx', '40');\n circle.setAttribute('cy', '40');\n circle.setAttribute('r', '40');\n circle.setAttribute('fill', 'rgba(255, 255, 255, 0.95)');\n circle.setAttribute('filter', `url(#${filterId})`);\n circle.setAttribute('class', 'vidply-play-overlay-bg');\n svg.appendChild(circle);\n \n // Play icon triangle (centered with optical adjustment)\n const playTriangle = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');\n playTriangle.setAttribute('points', '32,28 32,52 54,40');\n playTriangle.setAttribute('fill', '#0a406e');\n playTriangle.setAttribute('class', 'vidply-play-overlay-icon');\n svg.appendChild(playTriangle);\n \n return svg;\n}\n\n", "/**\n * Translation strings for VidPly\n */\n\nexport const translations = {\n en: {\n player: {\n label: 'Video Player',\n play: 'Play',\n pause: 'Pause',\n stop: 'Stop',\n restart: 'Restart from beginning',\n rewind: 'Rewind',\n forward: 'Forward',\n rewindSeconds: 'Rewind {seconds} seconds',\n forwardSeconds: 'Forward {seconds} seconds',\n previous: 'Previous track',\n next: 'Next track',\n volume: 'Volume',\n mute: 'Mute',\n unmute: 'Unmute',\n fullscreen: 'Fullscreen',\n exitFullscreen: 'Exit Fullscreen',\n captions: 'Captions',\n chapters: 'Chapters',\n quality: 'Quality',\n captionStyling: 'Caption styling',\n transcript: 'Toggle transcript',\n audioDescription: 'Audio description',\n signLanguage: 'Sign language video',\n settings: 'Settings',\n speed: 'Playback Speed',\n pip: 'Picture in Picture',\n currentTime: 'Current time',\n duration: 'Duration',\n progress: 'Progress',\n seekForward: 'Seek forward {seconds} seconds',\n seekBackward: 'Seek backward {seconds} seconds',\n volumeUp: 'Volume up',\n volumeDown: 'Volume down',\n loading: 'Loading...',\n loadingChapters: 'Loading chapters...',\n error: 'Error loading media',\n buffering: 'Buffering...',\n signLanguageVideo: 'Sign Language Video',\n noChapters: 'No chapters available',\n noCaptions: 'No captions available',\n auto: 'Auto',\n autoQuality: 'Auto (no quality selection available)',\n noQuality: 'Quality selection not available'\n },\n captions: {\n off: 'Off',\n select: 'Select captions',\n fontSize: 'Font Size',\n fontFamily: 'Font Family',\n color: 'Text Color',\n backgroundColor: 'Background Color',\n opacity: 'Opacity'\n },\n fontSizes: {\n small: 'Small',\n medium: 'Medium',\n large: 'Large',\n xlarge: 'X-Large'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Text Color',\n background: 'Background',\n font: 'Font',\n fontSize: 'Font Size',\n opacity: 'Opacity'\n },\n audioDescription: {\n enable: 'Enable audio description',\n disable: 'Disable audio description'\n },\n signLanguage: {\n show: 'Show sign language video',\n hide: 'Hide sign language video'\n },\n transcript: {\n title: 'Transcript',\n close: 'Close transcript',\n loading: 'Loading transcript...',\n noTranscript: 'No transcript available for this video.'\n },\n settings: {\n title: 'Settings',\n quality: 'Quality',\n speed: 'Speed',\n captions: 'Captions',\n language: 'Language',\n reset: 'Reset to defaults',\n close: 'Close'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n \n de: {\n player: {\n label: 'Videoplayer',\n play: 'Abspielen',\n pause: 'Pause',\n stop: 'Stopp',\n restart: 'Von vorne beginnen',\n rewind: 'Zur\u00FCckspulen',\n forward: 'Vorspulen',\n rewindSeconds: '{seconds} Sekunden zur\u00FCckspulen',\n forwardSeconds: '{seconds} Sekunden vorspulen',\n previous: 'Vorheriger Titel',\n next: 'N\u00E4chster Titel',\n volume: 'Lautst\u00E4rke',\n mute: 'Stumm',\n unmute: 'Ton ein',\n fullscreen: 'Vollbild',\n exitFullscreen: 'Vollbild beenden',\n captions: 'Untertitel',\n chapters: 'Kapitel',\n quality: 'Qualit\u00E4t',\n captionStyling: 'Untertitel-Stil',\n transcript: 'Transkript umschalten',\n audioDescription: 'Audiodeskription',\n signLanguage: 'Geb\u00E4rdensprache-Video',\n settings: 'Einstellungen',\n speed: 'Wiedergabegeschwindigkeit',\n pip: 'Bild-in-Bild',\n currentTime: 'Aktuelle Zeit',\n duration: 'Dauer',\n progress: 'Fortschritt',\n seekForward: '{seconds} Sekunden vorspulen',\n seekBackward: '{seconds} Sekunden zur\u00FCckspulen',\n volumeUp: 'Lauter',\n volumeDown: 'Leiser',\n loading: 'L\u00E4dt...',\n loadingChapters: 'Kapitel werden geladen...',\n error: 'Fehler beim Laden',\n buffering: 'Puffern...',\n signLanguageVideo: 'Geb\u00E4rdensprache-Video',\n noChapters: 'Keine Kapitel verf\u00FCgbar',\n noCaptions: 'Keine Untertitel verf\u00FCgbar',\n auto: 'Automatisch',\n autoQuality: 'Automatisch (keine Qualit\u00E4tsauswahl verf\u00FCgbar)',\n noQuality: 'Qualit\u00E4tsauswahl nicht verf\u00FCgbar'\n },\n captions: {\n off: 'Aus',\n select: 'Untertitel ausw\u00E4hlen',\n fontSize: 'Schriftgr\u00F6\u00DFe',\n fontFamily: 'Schriftart',\n color: 'Textfarbe',\n backgroundColor: 'Hintergrundfarbe',\n opacity: 'Deckkraft'\n },\n fontSizes: {\n small: 'Klein',\n medium: 'Mittel',\n large: 'Gro\u00DF',\n xlarge: 'Sehr gro\u00DF'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Textfarbe',\n background: 'Hintergrund',\n font: 'Schrift',\n fontSize: 'Schriftgr\u00F6\u00DFe',\n opacity: 'Deckkraft'\n },\n audioDescription: {\n enable: 'Audiodeskription aktivieren',\n disable: 'Audiodeskription deaktivieren'\n },\n signLanguage: {\n show: 'Geb\u00E4rdensprache-Video anzeigen',\n hide: 'Geb\u00E4rdensprache-Video ausblenden'\n },\n transcript: {\n title: 'Transkript',\n close: 'Transkript schlie\u00DFen',\n loading: 'Transkript wird geladen...',\n noTranscript: 'Kein Transkript f\u00FCr dieses Video verf\u00FCgbar.'\n },\n settings: {\n title: 'Einstellungen',\n quality: 'Qualit\u00E4t',\n speed: 'Geschwindigkeit',\n captions: 'Untertitel',\n language: 'Sprache',\n reset: 'Zur\u00FCcksetzen',\n close: 'Schlie\u00DFen'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n es: {\n player: {\n label: 'Reproductor de video',\n play: 'Reproducir',\n pause: 'Pausa',\n stop: 'Detener',\n restart: 'Reiniciar desde el principio',\n rewind: 'Retroceder',\n forward: 'Avanzar',\n rewindSeconds: 'Retroceder {seconds} segundos',\n forwardSeconds: 'Avanzar {seconds} segundos',\n previous: 'Pista anterior',\n next: 'Siguiente pista',\n volume: 'Volumen',\n mute: 'Silenciar',\n unmute: 'Activar sonido',\n fullscreen: 'Pantalla completa',\n exitFullscreen: 'Salir de pantalla completa',\n captions: 'Subt\u00EDtulos',\n chapters: 'Cap\u00EDtulos',\n quality: 'Calidad',\n captionStyling: 'Estilo de subt\u00EDtulos',\n transcript: 'Alternar transcripci\u00F3n',\n audioDescription: 'Audiodescripci\u00F3n',\n signLanguage: 'Video en lengua de se\u00F1as',\n settings: 'Configuraci\u00F3n',\n speed: 'Velocidad de reproducci\u00F3n',\n pip: 'Imagen en imagen',\n currentTime: 'Tiempo actual',\n duration: 'Duraci\u00F3n',\n progress: 'Progreso',\n seekForward: 'Avanzar {seconds} segundos',\n seekBackward: 'Retroceder {seconds} segundos',\n volumeUp: 'Subir volumen',\n volumeDown: 'Bajar volumen',\n loading: 'Cargando...',\n loadingChapters: 'Cargando cap\u00EDtulos...',\n error: 'Error al cargar',\n buffering: 'Almacenando en b\u00FAfer...',\n signLanguageVideo: 'Video en Lengua de Se\u00F1as',\n noChapters: 'No hay cap\u00EDtulos disponibles',\n noCaptions: 'No hay subt\u00EDtulos disponibles',\n auto: 'Autom\u00E1tico',\n autoQuality: 'Autom\u00E1tico (selecci\u00F3n de calidad no disponible)',\n noQuality: 'Selecci\u00F3n de calidad no disponible'\n },\n captions: {\n off: 'Desactivado',\n select: 'Seleccionar subt\u00EDtulos',\n fontSize: 'Tama\u00F1o de fuente',\n fontFamily: 'Familia de fuente',\n color: 'Color de texto',\n backgroundColor: 'Color de fondo',\n opacity: 'Opacidad'\n },\n fontSizes: {\n small: 'Peque\u00F1o',\n medium: 'Mediano',\n large: 'Grande',\n xlarge: 'Muy grande'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Color de texto',\n background: 'Fondo',\n font: 'Fuente',\n fontSize: 'Tama\u00F1o de fuente',\n opacity: 'Opacidad'\n },\n audioDescription: {\n enable: 'Activar audiodescripci\u00F3n',\n disable: 'Desactivar audiodescripci\u00F3n'\n },\n signLanguage: {\n show: 'Mostrar video en lengua de se\u00F1as',\n hide: 'Ocultar video en lengua de se\u00F1as'\n },\n transcript: {\n title: 'Transcripci\u00F3n',\n close: 'Cerrar transcripci\u00F3n',\n loading: 'Cargando transcripci\u00F3n...',\n noTranscript: 'No hay transcripci\u00F3n disponible para este video.'\n },\n settings: {\n title: 'Configuraci\u00F3n',\n quality: 'Calidad',\n speed: 'Velocidad',\n captions: 'Subt\u00EDtulos',\n language: 'Idioma',\n reset: 'Restablecer',\n close: 'Cerrar'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n fr: {\n player: {\n label: 'Lecteur vid\u00E9o',\n play: 'Lecture',\n pause: 'Pause',\n stop: 'Arr\u00EAt',\n restart: 'Red\u00E9marrer du d\u00E9but',\n rewind: 'Reculer',\n forward: 'Avancer',\n rewindSeconds: 'Reculer de {seconds} secondes',\n forwardSeconds: 'Avancer de {seconds} secondes',\n previous: 'Piste pr\u00E9c\u00E9dente',\n next: 'Piste suivante',\n volume: 'Volume',\n mute: 'Muet',\n unmute: 'Activer le son',\n fullscreen: 'Plein \u00E9cran',\n exitFullscreen: 'Quitter le plein \u00E9cran',\n captions: 'Sous-titres',\n chapters: 'Chapitres',\n quality: 'Qualit\u00E9',\n captionStyling: 'Style des sous-titres',\n transcript: 'Activer/d\u00E9sactiver la transcription',\n audioDescription: 'Audiodescription',\n signLanguage: 'Vid\u00E9o en langue des signes',\n settings: 'Param\u00E8tres',\n speed: 'Vitesse de lecture',\n pip: 'Image dans l\\'image',\n currentTime: 'Temps actuel',\n duration: 'Dur\u00E9e',\n progress: 'Progression',\n seekForward: 'Avancer de {seconds} secondes',\n seekBackward: 'Reculer de {seconds} secondes',\n volumeUp: 'Augmenter le volume',\n volumeDown: 'Diminuer le volume',\n loading: 'Chargement...',\n loadingChapters: 'Chargement des chapitres...',\n error: 'Erreur de chargement',\n buffering: 'Mise en m\u00E9moire tampon...',\n signLanguageVideo: 'Vid\u00E9o en Langue des Signes',\n noChapters: 'Aucun chapitre disponible',\n noCaptions: 'Aucun sous-titre disponible',\n auto: 'Automatique',\n autoQuality: 'Automatique (s\u00E9lection de qualit\u00E9 non disponible)',\n noQuality: 'S\u00E9lection de qualit\u00E9 non disponible'\n },\n captions: {\n off: 'D\u00E9sactiv\u00E9',\n select: 'S\u00E9lectionner les sous-titres',\n fontSize: 'Taille de police',\n fontFamily: 'Police',\n color: 'Couleur du texte',\n backgroundColor: 'Couleur de fond',\n opacity: 'Opacit\u00E9'\n },\n fontSizes: {\n small: 'Petit',\n medium: 'Moyen',\n large: 'Grand',\n xlarge: 'Tr\u00E8s grand'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Couleur du texte',\n background: 'Arri\u00E8re-plan',\n font: 'Police',\n fontSize: 'Taille de police',\n opacity: 'Opacit\u00E9'\n },\n audioDescription: {\n enable: 'Activer l\\'audiodescription',\n disable: 'D\u00E9sactiver l\\'audiodescription'\n },\n signLanguage: {\n show: 'Afficher la vid\u00E9o en langue des signes',\n hide: 'Masquer la vid\u00E9o en langue des signes'\n },\n transcript: {\n title: 'Transcription',\n close: 'Fermer la transcription',\n loading: 'Chargement de la transcription...',\n noTranscript: 'Aucune transcription disponible pour cette vid\u00E9o.'\n },\n settings: {\n title: 'Param\u00E8tres',\n quality: 'Qualit\u00E9',\n speed: 'Vitesse',\n captions: 'Sous-titres',\n language: 'Langue',\n reset: 'R\u00E9initialiser',\n close: 'Fermer'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n ja: {\n player: {\n label: '\u30D3\u30C7\u30AA\u30D7\u30EC\u30FC\u30E4\u30FC',\n play: '\u518D\u751F',\n pause: '\u4E00\u6642\u505C\u6B62',\n stop: '\u505C\u6B62',\n restart: '\u6700\u521D\u304B\u3089\u518D\u751F',\n rewind: '\u5DFB\u304D\u623B\u3057',\n forward: '\u65E9\u9001\u308A',\n rewindSeconds: '{seconds}\u79D2\u623B\u3059',\n forwardSeconds: '{seconds}\u79D2\u9032\u3081\u308B',\n previous: '\u524D\u306E\u30C8\u30E9\u30C3\u30AF',\n next: '\u6B21\u306E\u30C8\u30E9\u30C3\u30AF',\n volume: '\u97F3\u91CF',\n mute: '\u30DF\u30E5\u30FC\u30C8',\n unmute: '\u30DF\u30E5\u30FC\u30C8\u89E3\u9664',\n fullscreen: '\u5168\u753B\u9762\u8868\u793A',\n exitFullscreen: '\u5168\u753B\u9762\u8868\u793A\u3092\u7D42\u4E86',\n captions: '\u5B57\u5E55',\n chapters: '\u30C1\u30E3\u30D7\u30BF\u30FC',\n quality: '\u753B\u8CEA',\n captionStyling: '\u5B57\u5E55\u30B9\u30BF\u30A4\u30EB',\n transcript: '\u6587\u5B57\u8D77\u3053\u3057\u5207\u308A\u66FF\u3048',\n audioDescription: '\u97F3\u58F0\u89E3\u8AAC',\n signLanguage: '\u624B\u8A71\u52D5\u753B',\n settings: '\u8A2D\u5B9A',\n speed: '\u518D\u751F\u901F\u5EA6',\n pip: '\u30D4\u30AF\u30C1\u30E3\u30FC\u30A4\u30F3\u30D4\u30AF\u30C1\u30E3\u30FC',\n currentTime: '\u73FE\u5728\u306E\u6642\u9593',\n duration: '\u518D\u751F\u6642\u9593',\n progress: '\u9032\u884C\u72B6\u6CC1',\n seekForward: '{seconds}\u79D2\u9032\u3081\u308B',\n seekBackward: '{seconds}\u79D2\u623B\u3059',\n volumeUp: '\u97F3\u91CF\u3092\u4E0A\u3052\u308B',\n volumeDown: '\u97F3\u91CF\u3092\u4E0B\u3052\u308B',\n loading: '\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n loadingChapters: '\u30C1\u30E3\u30D7\u30BF\u30FC\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n error: '\u8AAD\u307F\u8FBC\u307F\u30A8\u30E9\u30FC',\n buffering: '\u30D0\u30C3\u30D5\u30A1\u30EA\u30F3\u30B0\u4E2D...',\n signLanguageVideo: '\u624B\u8A71\u52D5\u753B',\n noChapters: '\u30C1\u30E3\u30D7\u30BF\u30FC\u304C\u3042\u308A\u307E\u305B\u3093',\n noCaptions: '\u5B57\u5E55\u304C\u3042\u308A\u307E\u305B\u3093',\n auto: '\u81EA\u52D5',\n autoQuality: '\u81EA\u52D5\uFF08\u753B\u8CEA\u9078\u629E\u4E0D\u53EF\uFF09',\n noQuality: '\u753B\u8CEA\u9078\u629E\u4E0D\u53EF'\n },\n captions: {\n off: '\u30AA\u30D5',\n select: '\u5B57\u5E55\u3092\u9078\u629E',\n fontSize: '\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA',\n fontFamily: '\u30D5\u30A9\u30F3\u30C8',\n color: '\u30C6\u30AD\u30B9\u30C8\u306E\u8272',\n backgroundColor: '\u80CC\u666F\u8272',\n opacity: '\u4E0D\u900F\u660E\u5EA6'\n },\n fontSizes: {\n small: '\u5C0F',\n medium: '\u4E2D',\n large: '\u5927',\n xlarge: '\u7279\u5927'\n },\n fontFamilies: {\n sansSerif: '\u30B5\u30F3\u30BB\u30EA\u30D5',\n serif: '\u30BB\u30EA\u30D5',\n monospace: '\u7B49\u5E45'\n },\n styleLabels: {\n textColor: '\u30C6\u30AD\u30B9\u30C8\u306E\u8272',\n background: '\u80CC\u666F',\n font: '\u30D5\u30A9\u30F3\u30C8',\n fontSize: '\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA',\n opacity: '\u4E0D\u900F\u660E\u5EA6'\n },\n audioDescription: {\n enable: '\u97F3\u58F0\u89E3\u8AAC\u3092\u6709\u52B9\u306B\u3059\u308B',\n disable: '\u97F3\u58F0\u89E3\u8AAC\u3092\u7121\u52B9\u306B\u3059\u308B'\n },\n signLanguage: {\n show: '\u624B\u8A71\u52D5\u753B\u3092\u8868\u793A',\n hide: '\u624B\u8A71\u52D5\u753B\u3092\u975E\u8868\u793A'\n },\n transcript: {\n title: '\u6587\u5B57\u8D77\u3053\u3057',\n close: '\u6587\u5B57\u8D77\u3053\u3057\u3092\u9589\u3058\u308B',\n loading: '\u6587\u5B57\u8D77\u3053\u3057\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n noTranscript: '\u3053\u306E\u30D3\u30C7\u30AA\u306E\u6587\u5B57\u8D77\u3053\u3057\u306F\u3042\u308A\u307E\u305B\u3093\u3002'\n },\n settings: {\n title: '\u8A2D\u5B9A',\n quality: '\u753B\u8CEA',\n speed: '\u901F\u5EA6',\n captions: '\u5B57\u5E55',\n language: '\u8A00\u8A9E',\n reset: '\u30EA\u30BB\u30C3\u30C8',\n close: '\u9589\u3058\u308B'\n },\n speeds: {\n normal: '\u901A\u5E38'\n }\n }\n};\n\n", "/**\n * Internationalization system\n */\n\nimport { translations } from './translations.js';\n\nclass I18n {\n constructor() {\n this.currentLanguage = 'en';\n this.translations = translations;\n }\n\n setLanguage(lang) {\n if (this.translations[lang]) {\n this.currentLanguage = lang;\n } else {\n console.warn(`Language \"${lang}\" not found, falling back to English`);\n this.currentLanguage = 'en';\n }\n }\n\n getLanguage() {\n return this.currentLanguage;\n }\n\n t(key, replacements = {}) {\n const keys = key.split('.');\n let value = this.translations[this.currentLanguage];\n \n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n // Fallback to English\n value = this.translations.en;\n for (const fallbackKey of keys) {\n if (value && typeof value === 'object' && fallbackKey in value) {\n value = value[fallbackKey];\n } else {\n return key; // Return key if not found\n }\n }\n break;\n }\n }\n \n // Replace placeholders\n if (typeof value === 'string') {\n Object.entries(replacements).forEach(([placeholder, replacement]) => {\n value = value.replace(new RegExp(`{${placeholder}}`, 'g'), replacement);\n });\n }\n \n return value;\n }\n\n addTranslation(lang, translations) {\n if (!this.translations[lang]) {\n this.translations[lang] = {};\n }\n Object.assign(this.translations[lang], translations);\n }\n}\n\nexport const i18n = new I18n();\n\n", "/**\n * Control Bar Component\n */\n\nimport {DOMUtils} from '../utils/DOMUtils.js';\nimport {TimeUtils} from '../utils/TimeUtils.js';\nimport {createIconElement} from '../icons/Icons.js';\nimport {i18n} from '../i18n/i18n.js';\n\nexport class ControlBar {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.controls = {};\n this.hideTimeout = null;\n this.isDraggingProgress = false;\n this.isDraggingVolume = false;\n\n this.init();\n }\n\n init() {\n this.createElement();\n this.createControls();\n this.attachEvents();\n this.setupAutoHide();\n }\n\n // Helper method to check if we're on a mobile device\n isMobile() {\n return window.innerWidth < 640;\n }\n\n // Smart menu positioning to avoid overflow\n positionMenu(menu, button) {\n const isMobile = this.isMobile();\n \n if (isMobile) {\n // Use bottom sheet on mobile - already styled via CSS\n return;\n }\n\n // Desktop: Smart positioning\n setTimeout(() => {\n const buttonRect = button.getBoundingClientRect();\n const menuRect = menu.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n \n const spaceAbove = buttonRect.top;\n const spaceBelow = viewportHeight - buttonRect.bottom;\n \n // Prefer above, but switch to below if not enough space\n if (spaceAbove < menuRect.height + 20 && spaceBelow > spaceAbove) {\n menu.style.bottom = 'auto';\n menu.style.top = 'calc(100% + 8px)';\n menu.classList.add('vidply-menu-below');\n }\n \n // Check horizontal overflow\n const menuLeft = buttonRect.left + buttonRect.width / 2 - menuRect.width / 2;\n if (menuLeft < 10) {\n // Too far left, align to left edge\n menu.style.right = 'auto';\n menu.style.left = '0';\n menu.style.transform = 'translateX(0)';\n } else if (menuLeft + menuRect.width > viewportWidth - 10) {\n // Too far right, align to right edge\n menu.style.left = 'auto';\n menu.style.right = '0';\n menu.style.transform = 'translateX(0)';\n }\n }, 0);\n }\n\n\n // Helper method to attach close-on-outside-click behavior to menus\n attachMenuCloseHandler(menu, button, preventCloseOnInteraction = false) {\n // Position menu smartly\n this.positionMenu(menu, button);\n \n setTimeout(() => {\n const closeMenu = (e) => {\n // If this menu has form controls, don't close when clicking inside\n if (preventCloseOnInteraction && menu.contains(e.target)) {\n return;\n }\n\n // Check if click is outside menu and button\n if (!menu.contains(e.target) && !button.contains(e.target)) {\n menu.remove();\n document.removeEventListener('click', closeMenu);\n document.removeEventListener('keydown', handleEscape);\n }\n };\n\n const handleEscape = (e) => {\n if (e.key === 'Escape') {\n menu.remove();\n document.removeEventListener('click', closeMenu);\n document.removeEventListener('keydown', handleEscape);\n // Return focus to button\n button.focus();\n }\n };\n\n document.addEventListener('click', closeMenu);\n document.addEventListener('keydown', handleEscape);\n }, 100);\n }\n\n createElement() {\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls`,\n attributes: {\n 'role': 'region',\n 'aria-label': i18n.t('player.label') + ' controls'\n }\n });\n }\n\n createControls() {\n // Progress bar container\n if (this.player.options.progressBar) {\n this.createProgressBar();\n }\n\n // Button container\n const buttonContainer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-buttons`\n });\n\n // Left buttons\n const leftButtons = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-left`\n });\n\n // Previous track button (if playlist)\n if (this.player.playlistManager) {\n leftButtons.appendChild(this.createPreviousButton());\n }\n\n // Play/Pause button\n if (this.player.options.playPauseButton) {\n leftButtons.appendChild(this.createPlayPauseButton());\n }\n\n // Restart button (right beside play button)\n leftButtons.appendChild(this.createRestartButton());\n\n // Next track button (if playlist)\n if (this.player.playlistManager) {\n leftButtons.appendChild(this.createNextButton());\n }\n\n // Rewind button (not shown in playlist mode)\n if (!this.player.playlistManager) {\n leftButtons.appendChild(this.createRewindButton());\n }\n\n // Forward button (not shown in playlist mode)\n if (!this.player.playlistManager) {\n leftButtons.appendChild(this.createForwardButton());\n }\n\n // Volume control\n if (this.player.options.volumeControl) {\n leftButtons.appendChild(this.createVolumeControl());\n }\n\n // Time display\n if (this.player.options.currentTime || this.player.options.duration) {\n leftButtons.appendChild(this.createTimeDisplay());\n }\n\n // Right buttons\n this.rightButtons = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-right`\n });\n\n // Check for available features\n const hasChapters = this.hasChapterTracks();\n const hasCaptions = this.hasCaptionTracks();\n const hasQualityLevels = this.hasQualityLevels();\n const hasAudioDescription = this.hasAudioDescription();\n\n // Chapters button - only show if chapters are available\n if (this.player.options.chaptersButton && hasChapters) {\n this.rightButtons.appendChild(this.createChaptersButton());\n }\n\n // Quality button - only show if quality levels are available\n if (this.player.options.qualityButton && hasQualityLevels) {\n this.rightButtons.appendChild(this.createQualityButton());\n }\n\n // Caption styling button (font, size, color) - only show if captions are available\n if (this.player.options.captionStyleButton && hasCaptions) {\n this.rightButtons.appendChild(this.createCaptionStyleButton());\n }\n\n // Speed button - always available\n if (this.player.options.speedButton) {\n this.rightButtons.appendChild(this.createSpeedButton());\n }\n\n // Captions language selector button - only show if captions are available\n if (this.player.options.captionsButton && hasCaptions) {\n this.rightButtons.appendChild(this.createCaptionsButton());\n }\n\n // Transcript button - only show if captions/subtitles are available\n if (this.player.options.transcriptButton && hasCaptions) {\n this.rightButtons.appendChild(this.createTranscriptButton());\n }\n\n // Audio Description button - only show if audio description source is available\n if (this.player.options.audioDescriptionButton && hasAudioDescription) {\n this.rightButtons.appendChild(this.createAudioDescriptionButton());\n }\n\n // Sign Language button - only show if sign language source is available\n const hasSignLanguage = this.hasSignLanguage();\n if (this.player.options.signLanguageButton && hasSignLanguage) {\n this.rightButtons.appendChild(this.createSignLanguageButton());\n }\n\n // PiP button\n if (this.player.options.pipButton && 'pictureInPictureEnabled' in document) {\n this.rightButtons.appendChild(this.createPipButton());\n }\n\n // Fullscreen button\n if (this.player.options.fullscreenButton) {\n this.rightButtons.appendChild(this.createFullscreenButton());\n }\n\n buttonContainer.appendChild(leftButtons);\n buttonContainer.appendChild(this.rightButtons);\n this.element.appendChild(buttonContainer);\n }\n\n // Helper methods to check for available features\n hasChapterTracks() {\n const textTracks = this.player.element.textTracks;\n for (let i = 0; i < textTracks.length; i++) {\n if (textTracks[i].kind === 'chapters') {\n return true;\n }\n }\n return false;\n }\n\n hasCaptionTracks() {\n const textTracks = this.player.element.textTracks;\n for (let i = 0; i < textTracks.length; i++) {\n if (textTracks[i].kind === 'captions' || textTracks[i].kind === 'subtitles') {\n return true;\n }\n }\n return false;\n }\n\n hasQualityLevels() {\n // Check if renderer supports quality selection\n if (this.player.renderer && this.player.renderer.getQualities) {\n const qualities = this.player.renderer.getQualities();\n return qualities && qualities.length > 1;\n }\n return false;\n }\n\n hasAudioDescription() {\n return this.player.audioDescriptionSrc && this.player.audioDescriptionSrc.length > 0;\n }\n\n hasSignLanguage() {\n return this.player.signLanguageSrc && this.player.signLanguageSrc.length > 0;\n }\n\n createProgressBar() {\n const progressContainer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-container`,\n attributes: {\n 'role': 'slider',\n 'aria-label': i18n.t('player.progress'),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n 'aria-valuenow': '0',\n 'tabindex': '0'\n }\n });\n\n // Buffered progress\n this.controls.buffered = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-buffered`\n });\n\n // Played progress\n this.controls.played = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-played`\n });\n\n // Progress handle\n this.controls.progressHandle = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-handle`\n });\n\n // Tooltip\n this.controls.progressTooltip = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-tooltip`\n });\n\n progressContainer.appendChild(this.controls.buffered);\n progressContainer.appendChild(this.controls.played);\n this.controls.played.appendChild(this.controls.progressHandle);\n progressContainer.appendChild(this.controls.progressTooltip);\n\n this.controls.progress = progressContainer;\n this.element.appendChild(progressContainer);\n\n // Progress bar events\n this.setupProgressBarEvents();\n }\n\n setupProgressBarEvents() {\n const progress = this.controls.progress;\n\n const updateProgress = (clientX) => {\n const rect = progress.getBoundingClientRect();\n const percent = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n const time = percent * this.player.state.duration;\n return {percent, time};\n };\n\n // Mouse events\n progress.addEventListener('mousedown', (e) => {\n this.isDraggingProgress = true;\n const {time} = updateProgress(e.clientX);\n this.player.seek(time);\n });\n\n document.addEventListener('mousemove', (e) => {\n if (this.isDraggingProgress) {\n const {time} = updateProgress(e.clientX);\n this.player.seek(time);\n }\n });\n\n document.addEventListener('mouseup', () => {\n this.isDraggingProgress = false;\n });\n\n // Hover tooltip\n progress.addEventListener('mousemove', (e) => {\n if (!this.isDraggingProgress) {\n const {time} = updateProgress(e.clientX);\n this.controls.progressTooltip.textContent = TimeUtils.formatTime(time);\n this.controls.progressTooltip.style.left = `${e.clientX - progress.getBoundingClientRect().left}px`;\n this.controls.progressTooltip.style.display = 'block';\n }\n });\n\n progress.addEventListener('mouseleave', () => {\n this.controls.progressTooltip.style.display = 'none';\n });\n\n // Keyboard navigation\n progress.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this.player.seekBackward(5);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n this.player.seekForward(5);\n }\n });\n\n // Touch events\n progress.addEventListener('touchstart', (e) => {\n this.isDraggingProgress = true;\n const touch = e.touches[0];\n const {time} = updateProgress(touch.clientX);\n this.player.seek(time);\n });\n\n progress.addEventListener('touchmove', (e) => {\n if (this.isDraggingProgress) {\n e.preventDefault();\n const touch = e.touches[0];\n const {time} = updateProgress(touch.clientX);\n this.player.seek(time);\n }\n });\n\n progress.addEventListener('touchend', () => {\n this.isDraggingProgress = false;\n });\n }\n\n createPlayPauseButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-play-pause`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.play')\n }\n });\n\n button.appendChild(createIconElement('play'));\n\n button.addEventListener('click', () => {\n this.player.toggle();\n });\n\n this.controls.playPause = button;\n return button;\n }\n\n createRestartButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-restart`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.restart')\n }\n });\n\n button.appendChild(createIconElement('restart'));\n\n button.addEventListener('click', () => {\n this.player.seek(0);\n this.player.play();\n });\n\n return button;\n }\n\n createPreviousButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-previous`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.previous')\n }\n });\n\n button.appendChild(createIconElement('skipPrevious'));\n\n button.addEventListener('click', () => {\n if (this.player.playlistManager) {\n this.player.playlistManager.previous();\n }\n });\n\n // Update button state\n const updateState = () => {\n if (this.player.playlistManager) {\n button.disabled = !this.player.playlistManager.hasPrevious() && !this.player.playlistManager.options.loop;\n }\n };\n this.player.on('playlisttrackchange', updateState);\n updateState();\n\n this.controls.previous = button;\n return button;\n }\n\n createNextButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-next`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.next')\n }\n });\n\n button.appendChild(createIconElement('skipNext'));\n\n button.addEventListener('click', () => {\n if (this.player.playlistManager) {\n this.player.playlistManager.next();\n }\n });\n\n // Update button state\n const updateState = () => {\n if (this.player.playlistManager) {\n button.disabled = !this.player.playlistManager.hasNext() && !this.player.playlistManager.options.loop;\n }\n };\n this.player.on('playlisttrackchange', updateState);\n updateState();\n\n this.controls.next = button;\n return button;\n }\n\n createRewindButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-rewind`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.rewindSeconds', { seconds: 15 })\n }\n });\n\n button.appendChild(createIconElement('rewind'));\n\n button.addEventListener('click', () => {\n this.player.seekBackward(15);\n });\n\n return button;\n }\n\n createForwardButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-forward`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.forwardSeconds', { seconds: 15 })\n }\n });\n\n button.appendChild(createIconElement('forward'));\n\n button.addEventListener('click', () => {\n this.player.seekForward(15);\n });\n\n return button;\n }\n\n createVolumeControl() {\n // Mute/Volume button\n const muteButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-mute`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.volume'),\n 'aria-haspopup': 'true'\n }\n });\n\n muteButton.appendChild(createIconElement('volumeHigh'));\n\n // Toggle mute on right click, show volume slider on left click\n muteButton.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n this.player.toggleMute();\n });\n\n muteButton.addEventListener('click', () => {\n this.showVolumeSlider(muteButton);\n });\n\n this.controls.mute = muteButton;\n\n return muteButton;\n }\n\n showVolumeSlider(button) {\n // Remove existing slider if any\n const existingSlider = document.querySelector(`.${this.player.options.classPrefix}-volume-menu`);\n if (existingSlider) {\n existingSlider.remove();\n return;\n }\n\n // Volume menu container\n const volumeMenu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-menu ${this.player.options.classPrefix}-menu`\n });\n\n const volumeSlider = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-slider`,\n attributes: {\n 'role': 'slider',\n 'aria-label': i18n.t('player.volume'),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n 'aria-valuenow': String(Math.round(this.player.state.volume * 100)),\n 'tabindex': '0'\n }\n });\n\n const volumeTrack = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-track`\n });\n\n const volumeFill = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-fill`\n });\n\n const volumeHandle = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-handle`\n });\n\n volumeTrack.appendChild(volumeFill);\n volumeFill.appendChild(volumeHandle);\n volumeSlider.appendChild(volumeTrack);\n volumeMenu.appendChild(volumeSlider);\n\n // Volume slider events\n const updateVolume = (clientY) => {\n const rect = volumeTrack.getBoundingClientRect();\n const percent = Math.max(0, Math.min(1, 1 - ((clientY - rect.top) / rect.height)));\n this.player.setVolume(percent);\n };\n\n volumeSlider.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n this.isDraggingVolume = true;\n updateVolume(e.clientY);\n });\n\n document.addEventListener('mousemove', (e) => {\n if (this.isDraggingVolume) {\n updateVolume(e.clientY);\n }\n });\n\n document.addEventListener('mouseup', () => {\n this.isDraggingVolume = false;\n });\n\n // Keyboard volume control\n volumeSlider.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n this.player.setVolume(Math.min(1, this.player.state.volume + 0.1));\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n this.player.setVolume(Math.max(0, this.player.state.volume - 0.1));\n }\n });\n\n // Prevent menu from closing when interacting with slider\n volumeMenu.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n // Append menu to button\n button.appendChild(volumeMenu);\n\n this.controls.volumeSlider = volumeSlider;\n this.controls.volumeFill = volumeFill;\n\n // Close menu on outside click\n this.attachMenuCloseHandler(volumeMenu, button, true);\n }\n\n createTimeDisplay() {\n const container = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-time`\n });\n\n this.controls.currentTimeDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-current-time`,\n textContent: '00:00'\n });\n\n const separator = DOMUtils.createElement('span', {\n textContent: ' / ',\n attributes: {\n 'aria-hidden': 'true'\n }\n });\n\n this.controls.durationDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-duration`,\n textContent: '00:00'\n });\n\n container.appendChild(this.controls.currentTimeDisplay);\n container.appendChild(separator);\n container.appendChild(this.controls.durationDisplay);\n\n return container;\n }\n\n createChaptersButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-chapters`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.chapters'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('playlist'));\n\n button.addEventListener('click', () => {\n this.showChaptersMenu(button);\n });\n\n this.controls.chapters = button;\n return button;\n }\n\n showChaptersMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-chapters-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-chapters-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.chapters')\n }\n });\n\n // Get chapter tracks\n const chapterTracks = Array.from(this.player.element.textTracks).filter(\n track => track.kind === 'chapters'\n );\n\n if (chapterTracks.length === 0) {\n // No chapters available\n const noChaptersItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noChapters'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noChaptersItem);\n } else {\n const chapterTrack = chapterTracks[0];\n\n // Ensure track is in 'hidden' mode to load cues\n if (chapterTrack.mode === 'disabled') {\n chapterTrack.mode = 'hidden';\n }\n\n if (!chapterTrack.cues || chapterTrack.cues.length === 0) {\n // Cues not loaded yet - wait for them to load\n const loadingItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.loadingChapters'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(loadingItem);\n\n // Listen for track load event\n const onTrackLoad = () => {\n // Remove loading message and rebuild menu\n menu.remove();\n this.showChaptersMenu(button);\n };\n\n chapterTrack.addEventListener('load', onTrackLoad, {once: true});\n\n // Also try again after a short delay as fallback\n setTimeout(() => {\n if (chapterTrack.cues && chapterTrack.cues.length > 0 && document.contains(menu)) {\n menu.remove();\n this.showChaptersMenu(button);\n }\n }, 500);\n } else {\n // Display chapters\n const cues = chapterTrack.cues;\n for (let i = 0; i < cues.length; i++) {\n const cue = cues[i];\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n const timeLabel = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-chapter-time`,\n textContent: TimeUtils.formatTime(cue.startTime)\n });\n\n const titleLabel = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-chapter-title`,\n textContent: cue.text\n });\n\n item.appendChild(timeLabel);\n item.appendChild(document.createTextNode(' '));\n item.appendChild(titleLabel);\n\n item.addEventListener('click', () => {\n this.player.seek(cue.startTime);\n menu.remove();\n });\n\n menu.appendChild(item);\n }\n }\n }\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createQualityButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-quality`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.quality'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('hd'));\n\n // Add quality indicator text\n const qualityText = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-quality-text`,\n textContent: ''\n });\n button.appendChild(qualityText);\n\n button.addEventListener('click', () => {\n this.showQualityMenu(button);\n });\n\n this.controls.quality = button;\n this.controls.qualityText = qualityText;\n \n // Update quality indicator after a short delay to ensure renderer is ready\n setTimeout(() => this.updateQualityIndicator(), 500);\n \n return button;\n }\n\n showQualityMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-quality-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-quality-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.quality')\n }\n });\n\n // Check if renderer supports quality selection\n if (this.player.renderer && this.player.renderer.getQualities) {\n const qualities = this.player.renderer.getQualities();\n const currentQuality = this.player.renderer.getCurrentQuality ? this.player.renderer.getCurrentQuality() : -1;\n const isHLS = this.player.renderer.hls !== undefined;\n\n if (qualities.length === 0) {\n // No qualities available\n const noQualityItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.autoQuality'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noQualityItem);\n } else {\n // Auto quality option (only for HLS)\n if (isHLS) {\n const autoItem = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.auto'),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n // Check if auto is currently selected\n const isAuto = this.player.renderer.hls && this.player.renderer.hls.currentLevel === -1;\n if (isAuto) {\n autoItem.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n autoItem.appendChild(createIconElement('check'));\n }\n\n autoItem.addEventListener('click', () => {\n if (this.player.renderer.switchQuality) {\n this.player.renderer.switchQuality(-1); // -1 for auto\n }\n menu.remove();\n });\n\n menu.appendChild(autoItem);\n }\n\n // Quality options\n qualities.forEach(quality => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: quality.name || `${quality.height}p`,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n // Highlight current quality\n if (quality.index === currentQuality) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n }\n\n item.addEventListener('click', () => {\n if (this.player.renderer.switchQuality) {\n this.player.renderer.switchQuality(quality.index);\n }\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n }\n } else {\n // No quality support\n const noSupportItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noQuality'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noSupportItem);\n }\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createCaptionStyleButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-caption-style`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.captionStyling'),\n 'aria-haspopup': 'menu',\n 'title': i18n.t('player.captionStyling')\n }\n });\n\n // Create \"Aa\" text icon for styling\n const textIcon = DOMUtils.createElement('span', {\n textContent: 'Aa',\n style: {\n fontSize: '14px',\n fontWeight: 'bold'\n }\n });\n button.appendChild(textIcon);\n\n button.addEventListener('click', () => {\n this.showCaptionStyleMenu(button);\n });\n\n this.controls.captionStyle = button;\n return button;\n }\n\n showCaptionStyleMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-caption-style-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-caption-style-menu ${this.player.options.classPrefix}-menu ${this.player.options.classPrefix}-settings-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.captionStyling')\n }\n });\n\n // Prevent menu from closing when clicking inside\n menu.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n // Check if there are any caption tracks\n if (!this.player.captionManager || this.player.captionManager.tracks.length === 0) {\n // Show \"No captions available\" message\n const noTracksItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noCaptions'),\n style: {opacity: '0.5', cursor: 'default', padding: '12px 16px'}\n });\n menu.appendChild(noTracksItem);\n\n // Append menu to button\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button, true);\n return;\n }\n\n // Font Size\n const fontSizeGroup = this.createStyleControl(\n i18n.t('styleLabels.fontSize'),\n 'captionsFontSize',\n [\n {label: i18n.t('fontSizes.small'), value: '80%'},\n {label: i18n.t('fontSizes.medium'), value: '100%'},\n {label: i18n.t('fontSizes.large'), value: '120%'},\n {label: i18n.t('fontSizes.xlarge'), value: '150%'}\n ]\n );\n menu.appendChild(fontSizeGroup);\n\n // Font Family\n const fontFamilyGroup = this.createStyleControl(\n i18n.t('styleLabels.font'),\n 'captionsFontFamily',\n [\n {label: i18n.t('fontFamilies.sansSerif'), value: 'sans-serif'},\n {label: i18n.t('fontFamilies.serif'), value: 'serif'},\n {label: i18n.t('fontFamilies.monospace'), value: 'monospace'}\n ]\n );\n menu.appendChild(fontFamilyGroup);\n\n // Text Color\n const colorGroup = this.createColorControl(i18n.t('styleLabels.textColor'), 'captionsColor');\n menu.appendChild(colorGroup);\n\n // Background Color\n const bgColorGroup = this.createColorControl(i18n.t('styleLabels.background'), 'captionsBackgroundColor');\n menu.appendChild(bgColorGroup);\n\n // Opacity\n const opacityGroup = this.createOpacityControl(i18n.t('styleLabels.opacity'), 'captionsOpacity');\n menu.appendChild(opacityGroup);\n\n // Set min-width for caption style menu\n menu.style.minWidth = '220px';\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click (but not when interacting with controls)\n this.attachMenuCloseHandler(menu, button, true);\n }\n\n createStyleControl(label, property, options) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-style-select`,\n style: {\n width: '100%',\n padding: '6px',\n background: 'var(--vidply-white)',\n border: '1px solid var(--vidply-white-10)',\n borderRadius: '4px',\n color: 'var(--vidply-black)',\n fontSize: '13px'\n }\n });\n\n const currentValue = this.player.options[property];\n options.forEach(opt => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.label,\n attributes: {value: opt.value}\n });\n if (opt.value === currentValue) {\n option.selected = true;\n }\n select.appendChild(option);\n });\n\n // Prevent clicks from closing the menu\n select.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('change', (e) => {\n e.stopPropagation();\n this.player.options[property] = e.target.value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n e.target.value\n );\n }\n });\n\n group.appendChild(select);\n return group;\n }\n\n createColorControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n type: 'color',\n value: this.player.options[property]\n },\n style: {\n width: '100%',\n height: '32px',\n padding: '2px',\n background: 'rgba(255,255,255,0.1)',\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: '4px',\n cursor: 'pointer'\n }\n });\n\n // Prevent clicks from closing the menu\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('change', (e) => {\n e.stopPropagation();\n this.player.options[property] = e.target.value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n e.target.value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n }\n\n createOpacityControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelContainer = DOMUtils.createElement('div', {\n style: {\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '4px'\n }\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n const valueEl = DOMUtils.createElement('span', {\n textContent: Math.round(this.player.options[property] * 100) + '%',\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n labelContainer.appendChild(labelEl);\n labelContainer.appendChild(valueEl);\n group.appendChild(labelContainer);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n type: 'range',\n min: '0',\n max: '1',\n step: '0.1',\n value: String(this.player.options[property])\n },\n style: {\n width: '100%',\n cursor: 'pointer'\n }\n });\n\n // Prevent clicks from closing the menu\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('input', (e) => {\n e.stopPropagation();\n const value = parseFloat(e.target.value);\n valueEl.textContent = Math.round(value * 100) + '%';\n this.player.options[property] = value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n }\n\n createSpeedButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-speed`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.speed'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('speed'));\n\n const speedText = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-speed-text`,\n textContent: '1x'\n });\n button.appendChild(speedText);\n\n button.addEventListener('click', () => {\n this.showSpeedMenu(button);\n });\n\n this.controls.speed = button;\n this.controls.speedText = speedText;\n return button;\n }\n\n formatSpeedLabel(speed) {\n // Special case: 1x is \"Normal\" (translated)\n if (speed === 1) {\n return i18n.t('speeds.normal');\n }\n \n // For other speeds, format with locale-specific decimal separator\n const speedStr = speed.toLocaleString(i18n.getLanguage(), {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2\n });\n \n return `${speedStr}\u00D7`;\n }\n\n showSpeedMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-speed-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-speed-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu'\n }\n });\n\n const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n\n speeds.forEach(speed => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: this.formatSpeedLabel(speed),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n if (speed === this.player.state.playbackSpeed) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n }\n\n item.addEventListener('click', () => {\n this.player.setPlaybackSpeed(speed);\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createCaptionsButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-captions-button`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.captions'),\n 'aria-pressed': 'false',\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('captionsOff'));\n\n button.addEventListener('click', () => {\n this.showCaptionsMenu(button);\n });\n\n this.controls.captions = button;\n return button;\n }\n\n showCaptionsMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-captions-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-captions-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('captions.select')\n }\n });\n\n // Check if there are any caption tracks\n if (!this.player.captionManager || this.player.captionManager.tracks.length === 0) {\n // Show \"No captions available\" message\n const noTracksItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noCaptions'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noTracksItem);\n\n // Append menu to button\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n return;\n }\n\n // Off option\n const offItem = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('captions.off'),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n if (!this.player.state.captionsEnabled) {\n offItem.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n offItem.appendChild(createIconElement('check'));\n }\n\n offItem.addEventListener('click', () => {\n this.player.disableCaptions();\n this.updateCaptionsButton();\n menu.remove();\n });\n\n menu.appendChild(offItem);\n\n // Available tracks\n const tracks = this.player.captionManager.getAvailableTracks();\n tracks.forEach(track => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: track.label,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem',\n 'lang': track.language\n }\n });\n\n // Check if this is the current track\n if (this.player.state.captionsEnabled &&\n this.player.captionManager.currentTrack === this.player.captionManager.tracks[track.index]) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n }\n\n item.addEventListener('click', () => {\n this.player.captionManager.switchTrack(track.index);\n this.updateCaptionsButton();\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n updateCaptionsButton() {\n if (!this.controls.captions) return;\n\n const icon = this.controls.captions.querySelector('.vidply-icon');\n const isEnabled = this.player.state.captionsEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('captions').innerHTML :\n createIconElement('captionsOff').innerHTML;\n\n this.controls.captions.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n }\n\n createTranscriptButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-transcript`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.transcript'),\n 'aria-pressed': 'false'\n }\n });\n\n button.appendChild(createIconElement('transcript'));\n\n button.addEventListener('click', () => {\n if (this.player.transcriptManager) {\n this.player.transcriptManager.toggleTranscript();\n this.updateTranscriptButton();\n }\n });\n\n this.controls.transcript = button;\n return button;\n }\n\n updateTranscriptButton() {\n if (!this.controls.transcript) return;\n\n const isVisible = this.player.transcriptManager && this.player.transcriptManager.isVisible;\n this.controls.transcript.setAttribute('aria-pressed', isVisible ? 'true' : 'false');\n }\n\n createAudioDescriptionButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-audio-description`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.audioDescription'),\n 'aria-pressed': 'false',\n 'title': i18n.t('player.audioDescription')\n }\n });\n\n button.appendChild(createIconElement('audioDescription'));\n\n button.addEventListener('click', async () => {\n await this.player.toggleAudioDescription();\n this.updateAudioDescriptionButton();\n });\n\n this.controls.audioDescription = button;\n return button;\n }\n\n updateAudioDescriptionButton() {\n if (!this.controls.audioDescription) return;\n\n const icon = this.controls.audioDescription.querySelector('.vidply-icon');\n const isEnabled = this.player.state.audioDescriptionEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('audioDescriptionOn').innerHTML :\n createIconElement('audioDescription').innerHTML;\n\n this.controls.audioDescription.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n this.controls.audioDescription.setAttribute('aria-label',\n isEnabled ? i18n.t('audioDescription.disable') : i18n.t('audioDescription.enable')\n );\n }\n\n createSignLanguageButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-sign-language`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.signLanguage'),\n 'aria-pressed': 'false',\n 'title': i18n.t('player.signLanguage')\n }\n });\n\n button.appendChild(createIconElement('signLanguage'));\n\n button.addEventListener('click', () => {\n this.player.toggleSignLanguage();\n this.updateSignLanguageButton();\n });\n\n this.controls.signLanguage = button;\n return button;\n }\n\n updateSignLanguageButton() {\n if (!this.controls.signLanguage) return;\n\n const icon = this.controls.signLanguage.querySelector('.vidply-icon');\n const isEnabled = this.player.state.signLanguageEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('signLanguageOn').innerHTML :\n createIconElement('signLanguage').innerHTML;\n\n this.controls.signLanguage.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n this.controls.signLanguage.setAttribute('aria-label',\n isEnabled ? i18n.t('signLanguage.hide') : i18n.t('signLanguage.show')\n );\n }\n\n createSettingsButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-settings`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.settings')\n }\n });\n\n button.appendChild(createIconElement('settings'));\n\n button.addEventListener('click', () => {\n this.player.showSettings();\n });\n\n return button;\n }\n\n createPipButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-pip`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.pip')\n }\n });\n\n button.appendChild(createIconElement('pip'));\n\n button.addEventListener('click', () => {\n this.player.togglePiP();\n });\n\n return button;\n }\n\n createFullscreenButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-fullscreen`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.fullscreen')\n }\n });\n\n button.appendChild(createIconElement('fullscreen'));\n\n button.addEventListener('click', () => {\n this.player.toggleFullscreen();\n });\n\n this.controls.fullscreen = button;\n return button;\n }\n\n attachEvents() {\n // Update controls based on player state\n this.player.on('play', () => this.updatePlayPauseButton());\n this.player.on('pause', () => this.updatePlayPauseButton());\n this.player.on('timeupdate', () => this.updateProgress());\n this.player.on('loadedmetadata', () => {\n this.updateDuration();\n this.ensureQualityButton();\n this.updateQualityIndicator();\n });\n this.player.on('volumechange', () => this.updateVolumeDisplay());\n this.player.on('progress', () => this.updateBuffered());\n this.player.on('playbackspeedchange', () => this.updateSpeedDisplay());\n this.player.on('fullscreenchange', () => this.updateFullscreenButton());\n this.player.on('captionsenabled', () => this.updateCaptionsButton());\n this.player.on('captionsdisabled', () => this.updateCaptionsButton());\n this.player.on('audiodescriptionenabled', () => this.updateAudioDescriptionButton());\n this.player.on('audiodescriptiondisabled', () => this.updateAudioDescriptionButton());\n this.player.on('signlanguageenabled', () => this.updateSignLanguageButton());\n this.player.on('signlanguagedisabled', () => this.updateSignLanguageButton());\n this.player.on('qualitychange', () => this.updateQualityIndicator());\n this.player.on('hlslevelswitched', () => this.updateQualityIndicator());\n this.player.on('hlsmanifestparsed', () => {\n this.ensureQualityButton();\n this.updateQualityIndicator();\n });\n }\n\n updatePlayPauseButton() {\n if (!this.controls.playPause) return;\n\n const icon = this.controls.playPause.querySelector('.vidply-icon');\n const isPlaying = this.player.state.playing;\n\n icon.innerHTML = isPlaying ?\n createIconElement('pause').innerHTML :\n createIconElement('play').innerHTML;\n\n this.controls.playPause.setAttribute('aria-label',\n isPlaying ? i18n.t('player.pause') : i18n.t('player.play')\n );\n }\n\n updateProgress() {\n if (!this.controls.played) return;\n\n const percent = (this.player.state.currentTime / this.player.state.duration) * 100;\n this.controls.played.style.width = `${percent}%`;\n this.controls.progress.setAttribute('aria-valuenow', String(Math.round(percent)));\n\n if (this.controls.currentTimeDisplay) {\n this.controls.currentTimeDisplay.textContent = TimeUtils.formatTime(this.player.state.currentTime);\n }\n }\n\n updateDuration() {\n if (this.controls.durationDisplay) {\n this.controls.durationDisplay.textContent = TimeUtils.formatTime(this.player.state.duration);\n }\n }\n\n updateVolumeDisplay() {\n if (!this.controls.volumeFill) return;\n\n const percent = this.player.state.volume * 100;\n this.controls.volumeFill.style.height = `${percent}%`;\n\n // Update mute button icon\n if (this.controls.mute) {\n const icon = this.controls.mute.querySelector('.vidply-icon');\n let iconName;\n\n if (this.player.state.muted || this.player.state.volume === 0) {\n iconName = 'volumeMuted';\n } else if (this.player.state.volume < 0.3) {\n iconName = 'volumeLow';\n } else if (this.player.state.volume < 0.7) {\n iconName = 'volumeMedium';\n } else {\n iconName = 'volumeHigh';\n }\n\n icon.innerHTML = createIconElement(iconName).innerHTML;\n\n this.controls.mute.setAttribute('aria-label',\n this.player.state.muted ? i18n.t('player.unmute') : i18n.t('player.mute')\n );\n }\n\n if (this.controls.volumeSlider) {\n this.controls.volumeSlider.setAttribute('aria-valuenow', String(Math.round(percent)));\n }\n }\n\n updateBuffered() {\n if (!this.controls.buffered || !this.player.element.buffered || this.player.element.buffered.length === 0) return;\n\n const buffered = this.player.element.buffered.end(this.player.element.buffered.length - 1);\n const percent = (buffered / this.player.state.duration) * 100;\n this.controls.buffered.style.width = `${percent}%`;\n }\n\n updateSpeedDisplay() {\n if (this.controls.speedText) {\n this.controls.speedText.textContent = `${this.player.state.playbackSpeed}x`;\n }\n }\n\n updateFullscreenButton() {\n if (!this.controls.fullscreen) return;\n\n const icon = this.controls.fullscreen.querySelector('.vidply-icon');\n const isFullscreen = this.player.state.fullscreen;\n\n icon.innerHTML = isFullscreen ?\n createIconElement('fullscreenExit').innerHTML :\n createIconElement('fullscreen').innerHTML;\n\n this.controls.fullscreen.setAttribute('aria-label',\n isFullscreen ? i18n.t('player.exitFullscreen') : i18n.t('player.fullscreen')\n );\n }\n\n /**\n * Ensure quality button exists if qualities are available\n * This is called after renderer initialization to dynamically add the button\n */\n ensureQualityButton() {\n // Skip if quality button is disabled\n if (!this.player.options.qualityButton) return;\n \n // Skip if button already exists\n if (this.controls.quality) return;\n \n // Check if qualities are now available\n if (!this.hasQualityLevels()) return;\n \n // Create and insert the quality button before the speed button\n const qualityButton = this.createQualityButton();\n \n // Find the speed button or caption style button to insert before\n const speedButton = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-speed`);\n const captionStyleButton = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-caption-style`);\n const insertBefore = captionStyleButton || speedButton;\n \n if (insertBefore) {\n this.rightButtons.insertBefore(qualityButton, insertBefore);\n } else {\n // If no reference button, add it at the beginning of right buttons\n this.rightButtons.insertBefore(qualityButton, this.rightButtons.firstChild);\n }\n \n this.player.log('Quality button added dynamically', 'info');\n }\n\n updateQualityIndicator() {\n if (!this.controls.qualityText) return;\n if (!this.player.renderer || !this.player.renderer.getQualities) return;\n\n const qualities = this.player.renderer.getQualities();\n if (qualities.length === 0) {\n this.controls.qualityText.textContent = '';\n return;\n }\n\n // Get current quality\n let currentQualityText = '';\n \n // Check if it's HLS with auto mode\n if (this.player.renderer.hls && this.player.renderer.hls.currentLevel === -1) {\n currentQualityText = 'Auto';\n } else if (this.player.renderer.getCurrentQuality) {\n const currentIndex = this.player.renderer.getCurrentQuality();\n const currentQuality = qualities.find(q => q.index === currentIndex);\n if (currentQuality) {\n currentQualityText = currentQuality.height ? `${currentQuality.height}p` : '';\n }\n }\n\n this.controls.qualityText.textContent = currentQualityText;\n }\n\n setupAutoHide() {\n if (this.player.element.tagName !== 'VIDEO') return;\n\n const showControls = () => {\n this.element.classList.add(`${this.player.options.classPrefix}-controls-visible`);\n this.player.container.classList.add(`${this.player.options.classPrefix}-controls-visible`);\n this.player.state.controlsVisible = true;\n\n clearTimeout(this.hideTimeout);\n\n if (this.player.state.playing) {\n this.hideTimeout = setTimeout(() => {\n this.element.classList.remove(`${this.player.options.classPrefix}-controls-visible`);\n this.player.container.classList.remove(`${this.player.options.classPrefix}-controls-visible`);\n this.player.state.controlsVisible = false;\n }, this.player.options.hideControlsDelay);\n }\n };\n\n this.player.container.addEventListener('mousemove', showControls);\n this.player.container.addEventListener('touchstart', showControls);\n this.player.container.addEventListener('click', showControls);\n\n // Show controls on focus\n this.element.addEventListener('focusin', showControls);\n\n // Always show when paused\n this.player.on('pause', () => {\n showControls();\n clearTimeout(this.hideTimeout);\n });\n\n this.player.on('play', () => {\n showControls();\n });\n\n // Initial state\n showControls();\n }\n\n show() {\n this.element.style.display = '';\n }\n\n hide() {\n this.element.style.display = 'none';\n }\n\n destroy() {\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout);\n }\n\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n}\n\n", "/**\n * Caption/Subtitle Manager\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class CaptionManager {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.tracks = [];\n this.currentTrack = null;\n this.currentCue = null;\n \n this.init();\n }\n\n init() {\n this.createElement();\n this.loadTracks();\n this.attachEvents();\n \n if (this.player.options.captionsDefault && this.tracks.length > 0) {\n this.enable();\n }\n }\n\n createElement() {\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-captions`,\n attributes: {\n 'aria-live': 'polite',\n 'aria-atomic': 'true',\n 'role': 'region',\n 'aria-label': i18n.t('player.captions')\n }\n });\n\n // Apply caption styles\n this.updateStyles();\n \n // Append to videoWrapper if it exists, otherwise to container\n const target = this.player.videoWrapper || this.player.container;\n target.appendChild(this.element);\n }\n\n loadTracks() {\n const textTracks = this.player.element.textTracks;\n \n for (let i = 0; i < textTracks.length; i++) {\n const track = textTracks[i];\n \n if (track.kind === 'subtitles' || track.kind === 'captions') {\n this.tracks.push({\n track: track,\n language: track.language,\n label: track.label,\n kind: track.kind,\n index: i\n });\n \n // Disable all tracks initially\n track.mode = 'hidden';\n }\n }\n }\n\n attachEvents() {\n this.player.on('timeupdate', () => {\n this.updateCaptions();\n });\n\n this.player.on('captionschange', () => {\n this.updateStyles();\n });\n }\n\n enable(trackIndex = 0) {\n if (this.tracks.length === 0) {\n return;\n }\n\n // Disable current track\n if (this.currentTrack) {\n this.currentTrack.track.mode = 'hidden';\n }\n\n // Enable selected track\n const selectedTrack = this.tracks[trackIndex];\n \n if (selectedTrack) {\n // Set to 'hidden' not 'showing' to prevent browser from displaying native captions\n // We'll handle the display ourselves\n selectedTrack.track.mode = 'hidden';\n this.currentTrack = selectedTrack;\n this.player.state.captionsEnabled = true;\n \n // Remove any existing cuechange listener\n if (this.cueChangeHandler) {\n selectedTrack.track.removeEventListener('cuechange', this.cueChangeHandler);\n }\n \n // Add event listener for cue changes\n this.cueChangeHandler = () => {\n this.updateCaptions();\n };\n selectedTrack.track.addEventListener('cuechange', this.cueChangeHandler);\n \n this.element.style.display = 'block';\n \n this.player.emit('captionsenabled', selectedTrack);\n }\n }\n\n disable() {\n if (this.currentTrack) {\n this.currentTrack.track.mode = 'hidden';\n this.currentTrack = null;\n }\n\n this.element.style.display = 'none';\n this.element.innerHTML = '';\n this.currentCue = null;\n this.player.state.captionsEnabled = false;\n this.player.emit('captionsdisabled');\n }\n\n updateCaptions() {\n if (!this.currentTrack) {\n return;\n }\n \n if (!this.currentTrack.track.activeCues) {\n return;\n }\n\n const activeCues = this.currentTrack.track.activeCues;\n \n if (activeCues.length > 0) {\n const cue = activeCues[0];\n \n // Only update if the cue has changed\n if (this.currentCue !== cue) {\n this.currentCue = cue;\n \n // Parse and display cue text\n let text = cue.text;\n \n // Handle VTT formatting\n text = this.parseVTTFormatting(text);\n \n this.element.innerHTML = DOMUtils.sanitizeHTML(text);\n \n // Make sure it's visible when there's content\n this.element.style.display = 'block';\n \n this.player.emit('captionchange', cue);\n }\n } else if (this.currentCue) {\n // Clear caption\n this.element.innerHTML = '';\n this.element.style.display = 'none';\n this.currentCue = null;\n }\n }\n\n parseVTTFormatting(text) {\n // Basic VTT tag support\n text = text.replace(/<c[^>]*>(.*?)<\\/c>/g, '<span class=\"caption-class\">$1</span>');\n text = text.replace(/<b>(.*?)<\\/b>/g, '<strong>$1</strong>');\n text = text.replace(/<i>(.*?)<\\/i>/g, '<em>$1</em>');\n text = text.replace(/<u>(.*?)<\\/u>/g, '<u>$1</u>');\n \n // Voice tags\n text = text.replace(/<v\\s+([^>]+)>(.*?)<\\/v>/g, '<span class=\"caption-voice\" data-voice=\"$1\">$2</span>');\n \n return text;\n }\n\n updateStyles() {\n if (!this.element) return;\n\n const options = this.player.options;\n \n this.element.style.fontSize = options.captionsFontSize;\n this.element.style.fontFamily = options.captionsFontFamily;\n this.element.style.color = options.captionsColor;\n this.element.style.backgroundColor = this.hexToRgba(\n options.captionsBackgroundColor, \n options.captionsOpacity\n );\n }\n\n hexToRgba(hex, alpha) {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n if (result) {\n return `rgba(${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}, ${alpha})`;\n }\n return hex;\n }\n\n setCaptionStyle(property, value) {\n switch (property) {\n case 'fontSize':\n this.player.options.captionsFontSize = value;\n break;\n case 'fontFamily':\n this.player.options.captionsFontFamily = value;\n break;\n case 'color':\n this.player.options.captionsColor = value;\n break;\n case 'backgroundColor':\n this.player.options.captionsBackgroundColor = value;\n break;\n case 'opacity':\n this.player.options.captionsOpacity = value;\n break;\n }\n \n this.updateStyles();\n this.player.emit('captionschange');\n }\n\n getAvailableTracks() {\n return this.tracks.map((t, index) => ({\n index,\n language: t.language,\n label: t.label || t.language,\n kind: t.kind\n }));\n }\n\n switchTrack(trackIndex) {\n if (trackIndex >= 0 && trackIndex < this.tracks.length) {\n this.disable();\n this.enable(trackIndex);\n }\n }\n\n destroy() {\n this.disable();\n \n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n}\n\n", "/**\n * Keyboard Accessibility Manager\n */\n\nexport class KeyboardManager {\n constructor(player) {\n this.player = player;\n this.shortcuts = player.options.keyboardShortcuts;\n \n this.init();\n }\n\n init() {\n this.attachEvents();\n }\n\n attachEvents() {\n // Listen for keyboard events on the player container\n this.player.container.addEventListener('keydown', (e) => {\n this.handleKeydown(e);\n });\n\n // Make player container focusable\n if (!this.player.container.hasAttribute('tabindex')) {\n this.player.container.setAttribute('tabindex', '0');\n }\n }\n\n handleKeydown(e) {\n // Don't handle if target is an input element\n if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') {\n return;\n }\n\n const key = e.key;\n let handled = false;\n\n // Check each shortcut category\n for (const [action, keys] of Object.entries(this.shortcuts)) {\n if (keys.includes(key)) {\n handled = this.executeAction(action, e);\n if (handled) {\n e.preventDefault();\n e.stopPropagation();\n this.announceAction(action);\n break;\n }\n }\n }\n }\n\n executeAction(action, event) {\n switch (action) {\n case 'play-pause':\n this.player.toggle();\n return true;\n\n case 'volume-up':\n this.player.setVolume(Math.min(1, this.player.state.volume + 0.1));\n return true;\n\n case 'volume-down':\n this.player.setVolume(Math.max(0, this.player.state.volume - 0.1));\n return true;\n\n case 'seek-forward':\n this.player.seekForward();\n return true;\n\n case 'seek-backward':\n this.player.seekBackward();\n return true;\n\n case 'seek-forward-large':\n this.player.seekForward(this.player.options.seekIntervalLarge);\n return true;\n\n case 'seek-backward-large':\n this.player.seekBackward(this.player.options.seekIntervalLarge);\n return true;\n\n case 'mute':\n this.player.toggleMute();\n return true;\n\n case 'fullscreen':\n this.player.toggleFullscreen();\n return true;\n\n case 'captions':\n // If only one caption track, toggle on/off\n // If multiple tracks, open caption menu\n if (this.player.captionManager && this.player.captionManager.tracks.length > 1) {\n const captionsButton = document.querySelector('.vidply-captions');\n if (captionsButton && this.player.controlBar) {\n this.player.controlBar.showCaptionsMenu(captionsButton);\n }\n } else {\n this.player.toggleCaptions();\n }\n return true;\n\n case 'speed-up':\n this.player.setPlaybackSpeed(\n Math.min(2, this.player.state.playbackSpeed + 0.25)\n );\n return true;\n\n case 'speed-down':\n this.player.setPlaybackSpeed(\n Math.max(0.25, this.player.state.playbackSpeed - 0.25)\n );\n return true;\n\n case 'settings':\n this.player.showSettings();\n return true;\n\n default:\n return false;\n }\n }\n\n announceAction(action) {\n if (!this.player.options.screenReaderAnnouncements) return;\n\n let message = '';\n\n switch (action) {\n case 'play-pause':\n message = this.player.state.playing ? 'Playing' : 'Paused';\n break;\n case 'volume-up':\n message = `Volume ${Math.round(this.player.state.volume * 100)}%`;\n break;\n case 'volume-down':\n message = `Volume ${Math.round(this.player.state.volume * 100)}%`;\n break;\n case 'mute':\n message = this.player.state.muted ? 'Muted' : 'Unmuted';\n break;\n case 'fullscreen':\n message = this.player.state.fullscreen ? 'Fullscreen' : 'Exit fullscreen';\n break;\n case 'captions':\n message = this.player.state.captionsEnabled ? 'Captions on' : 'Captions off';\n break;\n case 'speed-up':\n case 'speed-down':\n message = `Speed ${this.player.state.playbackSpeed}x`;\n break;\n }\n\n if (message) {\n this.announce(message);\n }\n }\n\n announce(message, priority = 'polite') {\n // Create or get announcement element\n let announcer = document.getElementById('vidply-announcer');\n \n if (!announcer) {\n announcer = document.createElement('div');\n announcer.id = 'vidply-announcer';\n announcer.className = 'vidply-sr-only';\n announcer.setAttribute('aria-live', priority);\n announcer.setAttribute('aria-atomic', 'true');\n announcer.style.cssText = `\n position: absolute;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n `;\n document.body.appendChild(announcer);\n }\n\n // Clear and set new message\n announcer.textContent = '';\n setTimeout(() => {\n announcer.textContent = message;\n }, 100);\n }\n\n updateShortcut(action, keys) {\n if (Array.isArray(keys)) {\n this.shortcuts[action] = keys;\n }\n }\n\n destroy() {\n // Event listeners are automatically removed when the container is destroyed\n }\n}\n\n", "/**\n * Settings Dialog Component\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class SettingsDialog {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.isOpen = false;\n \n this.init();\n }\n\n init() {\n this.createElement();\n }\n\n createElement() {\n // Create overlay\n this.overlay = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-overlay`,\n attributes: {\n 'role': 'dialog',\n 'aria-modal': 'true',\n 'aria-label': i18n.t('settings.title')\n }\n });\n\n this.overlay.style.display = 'none';\n\n // Create dialog\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-dialog`\n });\n\n // Header\n const header = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-header`\n });\n\n const title = DOMUtils.createElement('h2', {\n textContent: i18n.t('settings.title'),\n attributes: {\n 'id': `${this.player.options.classPrefix}-settings-title`\n }\n });\n\n const closeButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-settings-close`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('settings.close')\n }\n });\n closeButton.appendChild(createIconElement('close'));\n closeButton.addEventListener('click', () => this.hide());\n\n header.appendChild(title);\n header.appendChild(closeButton);\n\n // Content\n const content = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-content`\n });\n\n content.appendChild(this.createSpeedSettings());\n \n if (this.player.captionManager && this.player.captionManager.tracks.length > 0) {\n content.appendChild(this.createCaptionSettings());\n }\n\n // Footer\n const footer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-footer`\n });\n\n const resetButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button`,\n textContent: i18n.t('settings.reset'),\n attributes: {\n 'type': 'button'\n }\n });\n resetButton.addEventListener('click', () => this.resetSettings());\n\n footer.appendChild(resetButton);\n\n // Assemble dialog\n this.element.appendChild(header);\n this.element.appendChild(content);\n this.element.appendChild(footer);\n\n this.overlay.appendChild(this.element);\n this.player.container.appendChild(this.overlay);\n\n // Attach events\n this.overlay.addEventListener('click', (e) => {\n if (e.target === this.overlay) {\n this.hide();\n }\n });\n\n // Escape key to close\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && this.isOpen) {\n this.hide();\n }\n });\n }\n\n formatSpeedLabel(speed) {\n // Special case: 1x is \"Normal\" (translated)\n if (speed === 1) {\n return i18n.t('speeds.normal');\n }\n \n // For other speeds, format with locale-specific decimal separator\n const speedStr = speed.toLocaleString(i18n.getLanguage(), {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2\n });\n \n return `${speedStr}\u00D7`;\n }\n\n createSpeedSettings() {\n const section = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-section`\n });\n\n const label = DOMUtils.createElement('label', {\n textContent: i18n.t('settings.speed'),\n attributes: {\n 'for': `${this.player.options.classPrefix}-speed-select`\n }\n });\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-settings-select`,\n attributes: {\n 'id': `${this.player.options.classPrefix}-speed-select`\n }\n });\n\n const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n \n speeds.forEach(speed => {\n const option = DOMUtils.createElement('option', {\n textContent: this.formatSpeedLabel(speed),\n attributes: {\n 'value': String(speed)\n }\n });\n \n if (speed === this.player.state.playbackSpeed) {\n option.selected = true;\n }\n \n select.appendChild(option);\n });\n\n select.addEventListener('change', (e) => {\n this.player.setPlaybackSpeed(parseFloat(e.target.value));\n });\n\n section.appendChild(label);\n section.appendChild(select);\n\n return section;\n }\n\n createCaptionSettings() {\n const section = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-section`\n });\n\n const heading = DOMUtils.createElement('h3', {\n textContent: i18n.t('settings.captions')\n });\n\n section.appendChild(heading);\n\n // Caption track selection\n const trackLabel = DOMUtils.createElement('label', {\n textContent: i18n.t('captions.select'),\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-track-select`\n }\n });\n\n const trackSelect = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-settings-select`,\n attributes: {\n 'id': `${this.player.options.classPrefix}-caption-track-select`\n }\n });\n\n // Off option\n const offOption = DOMUtils.createElement('option', {\n textContent: i18n.t('captions.off'),\n attributes: { 'value': '-1' }\n });\n trackSelect.appendChild(offOption);\n\n // Available tracks\n const tracks = this.player.captionManager.getAvailableTracks();\n tracks.forEach(track => {\n const option = DOMUtils.createElement('option', {\n textContent: track.label,\n attributes: { 'value': String(track.index) }\n });\n trackSelect.appendChild(option);\n });\n\n trackSelect.addEventListener('change', (e) => {\n const index = parseInt(e.target.value);\n if (index === -1) {\n this.player.disableCaptions();\n } else {\n this.player.captionManager.switchTrack(index);\n }\n });\n\n section.appendChild(trackLabel);\n section.appendChild(trackSelect);\n\n // Font size\n section.appendChild(this.createCaptionStyleControl('fontSize', i18n.t('captions.fontSize'), [\n { label: i18n.t('fontSizes.small'), value: '80%' },\n { label: i18n.t('fontSizes.medium'), value: '100%' },\n { label: i18n.t('fontSizes.large'), value: '120%' },\n { label: i18n.t('fontSizes.xlarge'), value: '150%' }\n ]));\n\n // Font family\n section.appendChild(this.createCaptionStyleControl('fontFamily', i18n.t('captions.fontFamily'), [\n { label: i18n.t('fontFamilies.sansSerif'), value: 'sans-serif' },\n { label: i18n.t('fontFamilies.serif'), value: 'serif' },\n { label: i18n.t('fontFamilies.monospace'), value: 'monospace' }\n ]));\n\n // Color controls\n section.appendChild(this.createColorControl('color', i18n.t('captions.color')));\n section.appendChild(this.createColorControl('backgroundColor', i18n.t('captions.backgroundColor')));\n\n // Opacity\n section.appendChild(this.createRangeControl('opacity', i18n.t('captions.opacity'), 0, 1, 0.1));\n\n return section;\n }\n\n createCaptionStyleControl(property, label, options) {\n const wrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-control`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-settings-select`,\n attributes: {\n 'id': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n options.forEach(opt => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.label,\n attributes: { 'value': opt.value }\n });\n \n if (opt.value === this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`]) {\n option.selected = true;\n }\n \n select.appendChild(option);\n });\n\n select.addEventListener('change', (e) => {\n this.player.captionManager.setCaptionStyle(property, e.target.value);\n });\n\n wrapper.appendChild(labelEl);\n wrapper.appendChild(select);\n\n return wrapper;\n }\n\n createColorControl(property, label) {\n const wrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-control`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n const input = DOMUtils.createElement('input', {\n className: `${this.player.options.classPrefix}-settings-color`,\n attributes: {\n 'type': 'color',\n 'id': `${this.player.options.classPrefix}-caption-${property}`,\n 'value': this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`]\n }\n });\n\n input.addEventListener('change', (e) => {\n this.player.captionManager.setCaptionStyle(property, e.target.value);\n });\n\n wrapper.appendChild(labelEl);\n wrapper.appendChild(input);\n\n return wrapper;\n }\n\n createRangeControl(property, label, min, max, step) {\n const wrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-control`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n const input = DOMUtils.createElement('input', {\n className: `${this.player.options.classPrefix}-settings-range`,\n attributes: {\n 'type': 'range',\n 'id': `${this.player.options.classPrefix}-caption-${property}`,\n 'min': String(min),\n 'max': String(max),\n 'step': String(step),\n 'value': String(this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`])\n }\n });\n\n const valueDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-settings-value`,\n textContent: String(this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`])\n });\n\n input.addEventListener('input', (e) => {\n const value = parseFloat(e.target.value);\n valueDisplay.textContent = value.toFixed(1);\n this.player.captionManager.setCaptionStyle(property, value);\n });\n\n wrapper.appendChild(labelEl);\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n\n return wrapper;\n }\n\n resetSettings() {\n // Reset to default values\n this.player.setPlaybackSpeed(1);\n \n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle('fontSize', '100%');\n this.player.captionManager.setCaptionStyle('fontFamily', 'sans-serif');\n this.player.captionManager.setCaptionStyle('color', '#FFFFFF');\n this.player.captionManager.setCaptionStyle('backgroundColor', '#000000');\n this.player.captionManager.setCaptionStyle('opacity', 0.8);\n }\n\n // Refresh dialog\n this.hide();\n setTimeout(() => this.show(), 100);\n }\n\n show() {\n this.overlay.style.display = 'flex';\n this.isOpen = true;\n \n // Focus the close button\n const closeButton = this.element.querySelector(`.${this.player.options.classPrefix}-settings-close`);\n if (closeButton) {\n closeButton.focus();\n }\n \n this.player.emit('settingsopen');\n }\n\n hide() {\n this.overlay.style.display = 'none';\n this.isOpen = false;\n \n // Return focus to settings button\n this.player.container.focus();\n \n this.player.emit('settingsclose');\n }\n\n destroy() {\n if (this.overlay && this.overlay.parentNode) {\n this.overlay.parentNode.removeChild(this.overlay);\n }\n }\n}\n\n", "/**\n * Transcript Manager Component\n * Manages transcript display and interaction\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { TimeUtils } from '../utils/TimeUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class TranscriptManager {\n constructor(player) {\n this.player = player;\n this.transcriptWindow = null;\n this.transcriptEntries = [];\n this.currentActiveEntry = null;\n this.isVisible = false;\n \n // Dragging state\n this.isDragging = false;\n this.dragOffsetX = 0;\n this.dragOffsetY = 0;\n \n // Store event handlers for cleanup\n this.handlers = {\n timeupdate: () => this.updateActiveEntry(),\n resize: null,\n mousemove: null,\n mouseup: null,\n touchmove: null,\n touchend: null,\n mousedown: null,\n touchstart: null,\n keydown: null\n };\n \n this.init();\n }\n\n init() {\n // Listen for time updates to highlight active transcript entry\n this.player.on('timeupdate', this.handlers.timeupdate);\n \n // Reposition transcript when entering/exiting fullscreen\n this.player.on('fullscreenchange', () => {\n if (this.isVisible) {\n // Add a small delay to ensure DOM has updated after fullscreen transition\n setTimeout(() => this.positionTranscript(), 100);\n }\n });\n }\n\n /**\n * Toggle transcript window visibility\n */\n toggleTranscript() {\n if (this.isVisible) {\n this.hideTranscript();\n } else {\n this.showTranscript();\n }\n }\n\n /**\n * Show transcript window\n */\n showTranscript() {\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'flex';\n this.isVisible = true;\n return;\n }\n\n // Create transcript window\n this.createTranscriptWindow();\n this.loadTranscriptData();\n \n // Show the window\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'flex';\n // Re-position after showing (in case window was resized while hidden)\n setTimeout(() => this.positionTranscript(), 0);\n }\n this.isVisible = true;\n }\n\n /**\n * Hide transcript window\n */\n hideTranscript() {\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'none';\n this.isVisible = false;\n }\n }\n\n /**\n * Create the transcript window UI\n */\n createTranscriptWindow() {\n this.transcriptWindow = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-window`,\n attributes: {\n 'role': 'dialog',\n 'aria-label': 'Video Transcript',\n 'tabindex': '-1'\n }\n });\n\n // Header (draggable)\n this.transcriptHeader = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-header`,\n attributes: {\n 'aria-label': 'Drag to reposition transcript. Use arrow keys to move, Home to reset position, Escape to close.',\n 'tabindex': '0'\n }\n });\n\n const title = DOMUtils.createElement('h3', {\n textContent: i18n.t('transcript.title')\n });\n\n const closeButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-transcript-close`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('transcript.close')\n }\n });\n closeButton.appendChild(createIconElement('close'));\n closeButton.addEventListener('click', () => this.hideTranscript());\n\n this.transcriptHeader.appendChild(title);\n this.transcriptHeader.appendChild(closeButton);\n\n // Content container\n this.transcriptContent = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-content`\n });\n\n this.transcriptWindow.appendChild(this.transcriptHeader);\n this.transcriptWindow.appendChild(this.transcriptContent);\n\n // Append to player container\n this.player.container.appendChild(this.transcriptWindow);\n \n // Position it next to the video wrapper\n this.positionTranscript();\n \n // Setup drag functionality\n this.setupDragAndDrop();\n \n // Re-position on window resize (debounced)\n let resizeTimeout;\n this.handlers.resize = () => {\n clearTimeout(resizeTimeout);\n resizeTimeout = setTimeout(() => this.positionTranscript(), 100);\n };\n window.addEventListener('resize', this.handlers.resize);\n }\n \n /**\n * Position transcript window next to video\n */\n positionTranscript() {\n if (!this.transcriptWindow || !this.player.videoWrapper || !this.isVisible) return;\n \n const isMobile = window.innerWidth < 640;\n const videoRect = this.player.videoWrapper.getBoundingClientRect();\n \n // Check if player is in fullscreen mode\n const isFullscreen = this.player.state.fullscreen;\n \n if (isMobile && !isFullscreen) {\n // Mobile: Position underneath the video and controls as part of the layout\n this.transcriptWindow.style.position = 'relative';\n this.transcriptWindow.style.left = '0';\n this.transcriptWindow.style.right = '0';\n this.transcriptWindow.style.bottom = 'auto';\n this.transcriptWindow.style.top = 'auto';\n this.transcriptWindow.style.width = '100%';\n this.transcriptWindow.style.maxWidth = '100%';\n this.transcriptWindow.style.maxHeight = '400px';\n this.transcriptWindow.style.height = 'auto';\n this.transcriptWindow.style.borderRadius = '0';\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.border = 'none';\n this.transcriptWindow.style.borderTop = '1px solid var(--vidply-border-light)';\n this.transcriptWindow.style.boxShadow = 'none';\n // Disable dragging on mobile\n if (this.transcriptHeader) {\n this.transcriptHeader.style.cursor = 'default';\n }\n \n // Ensure transcript is at the container level for proper stacking\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n } else if (isFullscreen) {\n // In fullscreen: position in bottom right corner inside the video\n this.transcriptWindow.style.position = 'fixed';\n this.transcriptWindow.style.left = 'auto';\n this.transcriptWindow.style.right = '20px';\n this.transcriptWindow.style.bottom = '80px'; // Above controls\n this.transcriptWindow.style.top = 'auto';\n this.transcriptWindow.style.maxHeight = 'calc(100vh - 180px)'; // Leave space for controls\n this.transcriptWindow.style.height = 'auto';\n this.transcriptWindow.style.width = '400px';\n this.transcriptWindow.style.maxWidth = '400px';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n this.transcriptWindow.style.borderTop = '';\n \n // Move back to container for fullscreen\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n } else {\n // Desktop mode: position next to video\n this.transcriptWindow.style.position = 'absolute';\n this.transcriptWindow.style.left = `${videoRect.width + 8}px`;\n this.transcriptWindow.style.right = 'auto';\n this.transcriptWindow.style.bottom = 'auto';\n this.transcriptWindow.style.top = '0';\n this.transcriptWindow.style.height = `${videoRect.height}px`;\n this.transcriptWindow.style.maxHeight = 'none';\n this.transcriptWindow.style.width = '400px';\n this.transcriptWindow.style.maxWidth = '400px';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n this.transcriptWindow.style.borderTop = '';\n // Enable dragging on desktop\n if (this.transcriptHeader) {\n this.transcriptHeader.style.cursor = 'move';\n }\n \n // Move back to container for desktop\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n }\n }\n\n /**\n * Load transcript data from caption/subtitle tracks\n */\n loadTranscriptData() {\n this.transcriptEntries = [];\n this.transcriptContent.innerHTML = '';\n\n // Get caption/subtitle tracks\n const textTracks = Array.from(this.player.element.textTracks);\n const transcriptTrack = textTracks.find(\n track => track.kind === 'captions' || track.kind === 'subtitles'\n );\n\n if (!transcriptTrack) {\n this.showNoTranscriptMessage();\n return;\n }\n\n // Enable track to load cues\n if (transcriptTrack.mode === 'disabled') {\n transcriptTrack.mode = 'hidden';\n }\n\n if (!transcriptTrack.cues || transcriptTrack.cues.length === 0) {\n // Wait for cues to load\n const loadingMessage = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-loading`,\n textContent: i18n.t('transcript.loading')\n });\n this.transcriptContent.appendChild(loadingMessage);\n\n const onLoad = () => {\n this.loadTranscriptData();\n };\n\n transcriptTrack.addEventListener('load', onLoad, { once: true });\n\n // Fallback timeout\n setTimeout(() => {\n if (transcriptTrack.cues && transcriptTrack.cues.length > 0) {\n this.loadTranscriptData();\n }\n }, 500);\n \n return;\n }\n\n // Build transcript from cues\n const cues = Array.from(transcriptTrack.cues);\n cues.forEach((cue, index) => {\n const entry = this.createTranscriptEntry(cue, index);\n this.transcriptEntries.push({\n element: entry,\n cue: cue,\n startTime: cue.startTime,\n endTime: cue.endTime\n });\n this.transcriptContent.appendChild(entry);\n });\n }\n\n /**\n * Create a single transcript entry element\n */\n createTranscriptEntry(cue, index) {\n const entry = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-entry`,\n attributes: {\n 'data-start': String(cue.startTime),\n 'data-end': String(cue.endTime),\n 'role': 'button',\n 'tabindex': '0'\n }\n });\n\n const timestamp = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-time`,\n textContent: TimeUtils.formatTime(cue.startTime)\n });\n\n const text = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-text`,\n textContent: this.stripVTTFormatting(cue.text)\n });\n\n entry.appendChild(timestamp);\n entry.appendChild(text);\n\n // Click to seek\n const seekToTime = () => {\n this.player.seek(cue.startTime);\n if (this.player.state.paused) {\n this.player.play();\n }\n };\n\n entry.addEventListener('click', seekToTime);\n entry.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n seekToTime();\n }\n });\n\n return entry;\n }\n\n /**\n * Strip VTT formatting tags from text\n */\n stripVTTFormatting(text) {\n // Remove VTT tags like <v Speaker>, <c>, etc.\n return text\n .replace(/<[^>]+>/g, '')\n .replace(/\\n/g, ' ')\n .trim();\n }\n\n /**\n * Show message when no transcript is available\n */\n showNoTranscriptMessage() {\n const message = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-empty`,\n textContent: i18n.t('transcript.noTranscript')\n });\n this.transcriptContent.appendChild(message);\n }\n\n /**\n * Update active transcript entry based on current time\n */\n updateActiveEntry() {\n if (!this.isVisible || this.transcriptEntries.length === 0) return;\n\n const currentTime = this.player.state.currentTime;\n \n // Find the entry that matches current time\n const activeEntry = this.transcriptEntries.find(\n entry => currentTime >= entry.startTime && currentTime < entry.endTime\n );\n\n if (activeEntry && activeEntry !== this.currentActiveEntry) {\n // Remove previous active class\n if (this.currentActiveEntry) {\n this.currentActiveEntry.element.classList.remove(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n }\n\n // Add active class to current entry\n activeEntry.element.classList.add(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n \n // Scroll to active entry\n this.scrollToEntry(activeEntry.element);\n \n this.currentActiveEntry = activeEntry;\n } else if (!activeEntry && this.currentActiveEntry) {\n // No active entry, remove active class\n this.currentActiveEntry.element.classList.remove(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n this.currentActiveEntry = null;\n }\n }\n\n /**\n * Scroll transcript window to show active entry\n */\n scrollToEntry(entryElement) {\n if (!this.transcriptContent) return;\n\n const contentRect = this.transcriptContent.getBoundingClientRect();\n const entryRect = entryElement.getBoundingClientRect();\n\n // Check if entry is out of view\n if (entryRect.top < contentRect.top || entryRect.bottom > contentRect.bottom) {\n // Scroll to center the entry\n const scrollTop = entryElement.offsetTop - (this.transcriptContent.clientHeight / 2) + (entryElement.clientHeight / 2);\n this.transcriptContent.scrollTo({\n top: scrollTop,\n behavior: 'smooth'\n });\n }\n }\n\n /**\n * Setup drag and drop functionality\n */\n setupDragAndDrop() {\n if (!this.transcriptHeader || !this.transcriptWindow) return;\n\n // Create and store handler functions\n this.handlers.mousedown = (e) => {\n // Don't drag if clicking on close button\n if (e.target.closest(`.${this.player.options.classPrefix}-transcript-close`)) {\n return;\n }\n \n this.startDragging(e.clientX, e.clientY);\n e.preventDefault();\n };\n\n this.handlers.mousemove = (e) => {\n if (this.isDragging) {\n this.drag(e.clientX, e.clientY);\n }\n };\n\n this.handlers.mouseup = () => {\n if (this.isDragging) {\n this.stopDragging();\n }\n };\n\n this.handlers.touchstart = (e) => {\n if (e.target.closest(`.${this.player.options.classPrefix}-transcript-close`)) {\n return;\n }\n \n const isMobile = window.innerWidth < 640;\n const isFullscreen = this.player.state.fullscreen;\n const touch = e.touches[0];\n \n if (isMobile && !isFullscreen) {\n // Mobile (not fullscreen): No dragging/swiping, transcript is part of layout\n return;\n } else {\n // Desktop or fullscreen: Normal dragging\n this.startDragging(touch.clientX, touch.clientY);\n }\n };\n\n this.handlers.touchmove = (e) => {\n const isMobile = window.innerWidth < 640;\n const isFullscreen = this.player.state.fullscreen;\n \n if (isMobile && !isFullscreen) {\n // Mobile (not fullscreen): No dragging/swiping\n return;\n } else if (this.isDragging) {\n // Desktop or fullscreen: Normal drag\n const touch = e.touches[0];\n this.drag(touch.clientX, touch.clientY);\n e.preventDefault();\n }\n };\n\n this.handlers.touchend = () => {\n if (this.isDragging) {\n // Stop dragging\n this.stopDragging();\n }\n };\n\n this.handlers.keydown = (e) => {\n // Check if this is a navigation key\n if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'Escape'].includes(e.key)) {\n return;\n }\n \n // Prevent default behavior and stop event from bubbling to transcript entries\n e.preventDefault();\n e.stopPropagation();\n \n // Handle special keys first\n if (e.key === 'Home') {\n this.resetPosition();\n return;\n }\n \n if (e.key === 'Escape') {\n this.hideTranscript();\n return;\n }\n \n const step = e.shiftKey ? 50 : 10; // Larger steps with Shift key\n \n // Get current position\n let currentLeft = parseFloat(this.transcriptWindow.style.left) || 0;\n let currentTop = parseFloat(this.transcriptWindow.style.top) || 0;\n \n // If window is still centered with transform, convert to absolute position first\n const computedStyle = window.getComputedStyle(this.transcriptWindow);\n if (computedStyle.transform !== 'none') {\n const rect = this.transcriptWindow.getBoundingClientRect();\n currentLeft = rect.left;\n currentTop = rect.top;\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.left = `${currentLeft}px`;\n this.transcriptWindow.style.top = `${currentTop}px`;\n }\n \n // Calculate new position based on arrow key\n let newX = currentLeft;\n let newY = currentTop;\n\n switch(e.key) {\n case 'ArrowLeft':\n newX -= step;\n break;\n case 'ArrowRight':\n newX += step;\n break;\n case 'ArrowUp':\n newY -= step;\n break;\n case 'ArrowDown':\n newY += step;\n break;\n }\n\n // Set new position directly\n this.transcriptWindow.style.left = `${newX}px`;\n this.transcriptWindow.style.top = `${newY}px`;\n };\n\n // Add event listeners using stored handlers\n this.transcriptHeader.addEventListener('mousedown', this.handlers.mousedown);\n document.addEventListener('mousemove', this.handlers.mousemove);\n document.addEventListener('mouseup', this.handlers.mouseup);\n \n this.transcriptHeader.addEventListener('touchstart', this.handlers.touchstart);\n document.addEventListener('touchmove', this.handlers.touchmove);\n document.addEventListener('touchend', this.handlers.touchend);\n \n this.transcriptHeader.addEventListener('keydown', this.handlers.keydown);\n }\n\n /**\n * Start dragging\n */\n startDragging(clientX, clientY) {\n // Get current rendered position (this is where it actually appears on screen)\n const rect = this.transcriptWindow.getBoundingClientRect();\n \n // Get the parent container position (player container)\n const containerRect = this.player.container.getBoundingClientRect();\n \n // Calculate position RELATIVE to container (not viewport)\n const relativeLeft = rect.left - containerRect.left;\n const relativeTop = rect.top - containerRect.top;\n \n // If window is centered with transform, convert to absolute position\n const computedStyle = window.getComputedStyle(this.transcriptWindow);\n if (computedStyle.transform !== 'none') {\n // Remove transform and set position relative to container\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.left = `${relativeLeft}px`;\n this.transcriptWindow.style.top = `${relativeTop}px`;\n }\n \n // Calculate offset based on viewport coordinates (where user clicked)\n this.dragOffsetX = clientX - rect.left;\n this.dragOffsetY = clientY - rect.top;\n \n this.isDragging = true;\n this.transcriptWindow.classList.add(`${this.player.options.classPrefix}-transcript-dragging`);\n document.body.style.cursor = 'grabbing';\n document.body.style.userSelect = 'none';\n }\n\n /**\n * Perform drag\n */\n drag(clientX, clientY) {\n if (!this.isDragging) return;\n\n // Calculate new viewport position based on mouse position minus the offset\n const newViewportX = clientX - this.dragOffsetX;\n const newViewportY = clientY - this.dragOffsetY;\n \n // Convert to position relative to container\n const containerRect = this.player.container.getBoundingClientRect();\n const newX = newViewportX - containerRect.left;\n const newY = newViewportY - containerRect.top;\n \n // During drag, set position relative to container\n this.transcriptWindow.style.left = `${newX}px`;\n this.transcriptWindow.style.top = `${newY}px`;\n }\n\n /**\n * Stop dragging\n */\n stopDragging() {\n this.isDragging = false;\n this.transcriptWindow.classList.remove(`${this.player.options.classPrefix}-transcript-dragging`);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n\n /**\n * Set window position with boundary constraints\n */\n setPosition(x, y) {\n const rect = this.transcriptWindow.getBoundingClientRect();\n \n // Use document dimensions for fixed positioning\n const viewportWidth = document.documentElement.clientWidth;\n const viewportHeight = document.documentElement.clientHeight;\n \n // Very relaxed boundaries - allow window to go mostly off-screen\n // Just keep a small part visible so user can always drag it back\n const minVisible = 100; // Keep at least 100px visible\n const minX = -(rect.width - minVisible); // Can go way off-screen to the left\n const minY = -(rect.height - minVisible); // Can go way off-screen to the top\n const maxX = viewportWidth - minVisible; // Can go way off-screen to the right\n const maxY = viewportHeight - minVisible; // Can go way off-screen to the bottom\n \n // Clamp position to boundaries (very loose)\n x = Math.max(minX, Math.min(x, maxX));\n y = Math.max(minY, Math.min(y, maxY));\n \n this.transcriptWindow.style.left = `${x}px`;\n this.transcriptWindow.style.top = `${y}px`;\n this.transcriptWindow.style.transform = 'none';\n }\n\n /**\n * Reset position to center\n */\n resetPosition() {\n this.transcriptWindow.style.left = '50%';\n this.transcriptWindow.style.top = '50%';\n this.transcriptWindow.style.transform = 'translate(-50%, -50%)';\n }\n\n /**\n * Cleanup\n */\n destroy() {\n // Remove timeupdate listener from player\n if (this.handlers.timeupdate) {\n this.player.off('timeupdate', this.handlers.timeupdate);\n }\n\n // Remove drag event listeners\n if (this.transcriptHeader) {\n if (this.handlers.mousedown) {\n this.transcriptHeader.removeEventListener('mousedown', this.handlers.mousedown);\n }\n if (this.handlers.touchstart) {\n this.transcriptHeader.removeEventListener('touchstart', this.handlers.touchstart);\n }\n if (this.handlers.keydown) {\n this.transcriptHeader.removeEventListener('keydown', this.handlers.keydown);\n }\n }\n\n // Remove document-level listeners\n if (this.handlers.mousemove) {\n document.removeEventListener('mousemove', this.handlers.mousemove);\n }\n if (this.handlers.mouseup) {\n document.removeEventListener('mouseup', this.handlers.mouseup);\n }\n if (this.handlers.touchmove) {\n document.removeEventListener('touchmove', this.handlers.touchmove);\n }\n if (this.handlers.touchend) {\n document.removeEventListener('touchend', this.handlers.touchend);\n }\n \n // Remove window-level listeners\n if (this.handlers.resize) {\n window.removeEventListener('resize', this.handlers.resize);\n }\n\n // Clear handlers\n this.handlers = null;\n\n // Remove DOM element\n if (this.transcriptWindow && this.transcriptWindow.parentNode) {\n this.transcriptWindow.parentNode.removeChild(this.transcriptWindow);\n }\n \n this.transcriptWindow = null;\n this.transcriptHeader = null;\n this.transcriptContent = null;\n this.transcriptEntries = [];\n }\n}\n", "/**\n * VidPly - Universal Video Player\n * Main Player Class\n */\n\nimport { EventEmitter } from '../utils/EventEmitter.js';\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { TimeUtils } from '../utils/TimeUtils.js';\nimport { ControlBar } from '../controls/ControlBar.js';\nimport { CaptionManager } from '../controls/CaptionManager.js';\nimport { KeyboardManager } from '../controls/KeyboardManager.js';\nimport { SettingsDialog } from '../controls/SettingsDialog.js';\nimport { TranscriptManager } from '../controls/TranscriptManager.js';\nimport { HTML5Renderer } from '../renderers/HTML5Renderer.js';\nimport { YouTubeRenderer } from '../renderers/YouTubeRenderer.js';\nimport { VimeoRenderer } from '../renderers/VimeoRenderer.js';\nimport { HLSRenderer } from '../renderers/HLSRenderer.js';\nimport { createPlayOverlay } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class Player extends EventEmitter {\n constructor(element, options = {}) {\n super();\n \n this.element = typeof element === 'string' ? document.querySelector(element) : element;\n if (!this.element) {\n throw new Error('VidPly: Element not found');\n }\n\n // Auto-create media element if a non-media element is provided\n if (this.element.tagName !== 'VIDEO' && this.element.tagName !== 'AUDIO') {\n const mediaType = options.mediaType || 'video';\n const mediaElement = document.createElement(mediaType);\n \n // Copy attributes from the div to the media element\n Array.from(this.element.attributes).forEach(attr => {\n if (attr.name !== 'id' && attr.name !== 'class' && !attr.name.startsWith('data-')) {\n mediaElement.setAttribute(attr.name, attr.value);\n }\n });\n \n // Copy any track elements from the div\n const tracks = this.element.querySelectorAll('track');\n tracks.forEach(track => {\n mediaElement.appendChild(track.cloneNode(true));\n });\n \n // Clear the div and insert the media element\n this.element.innerHTML = '';\n this.element.appendChild(mediaElement);\n \n // Update element reference to the actual media element\n this.element = mediaElement;\n }\n\n // Default options\n this.options = {\n // Display\n width: null,\n height: null,\n poster: null,\n responsive: true,\n fillContainer: false,\n \n // Playback\n autoplay: false,\n loop: false,\n muted: false,\n volume: 0.8,\n playbackSpeed: 1.0,\n preload: 'metadata',\n startTime: 0,\n \n // Controls\n controls: true,\n hideControlsDelay: 3000,\n playPauseButton: true,\n progressBar: true,\n currentTime: true,\n duration: true,\n volumeControl: true,\n muteButton: true,\n chaptersButton: true,\n qualityButton: true,\n captionStyleButton: true,\n speedButton: true,\n captionsButton: true,\n transcriptButton: true,\n fullscreenButton: true,\n pipButton: true,\n \n // Seeking\n seekInterval: 10,\n seekIntervalLarge: 30,\n \n // Captions\n captions: true,\n captionsDefault: false,\n captionsFontSize: '100%',\n captionsFontFamily: 'sans-serif',\n captionsColor: '#FFFFFF',\n captionsBackgroundColor: '#000000',\n captionsOpacity: 0.8,\n \n // Audio Description\n audioDescription: true,\n audioDescriptionSrc: null, // URL to audio-described version\n audioDescriptionButton: true,\n \n // Sign Language\n signLanguage: true,\n signLanguageSrc: null, // URL to sign language video\n signLanguageButton: true,\n signLanguagePosition: 'bottom-right', // Position: 'bottom-right', 'bottom-left', 'top-right', 'top-left'\n \n // Transcripts\n transcript: false,\n transcriptPosition: 'external',\n transcriptContainer: null,\n \n // Keyboard\n keyboard: true,\n keyboardShortcuts: {\n 'play-pause': [' ', 'p', 'k'],\n 'volume-up': ['ArrowUp'],\n 'volume-down': ['ArrowDown'],\n 'seek-forward': ['ArrowRight', 'f'],\n 'seek-backward': ['ArrowLeft', 'r'],\n 'seek-forward-large': ['l'],\n 'seek-backward-large': ['j'],\n 'mute': ['m'],\n 'fullscreen': ['f'],\n 'captions': ['c'],\n 'speed-up': ['>'],\n 'speed-down': ['<'],\n 'settings': ['s']\n },\n \n // Accessibility\n ariaLabels: {},\n screenReaderAnnouncements: true,\n highContrast: false,\n focusHighlight: true,\n \n // Languages\n language: 'en',\n languages: ['en'],\n \n // Advanced\n debug: false,\n classPrefix: 'vidply',\n iconType: 'svg',\n pauseOthersOnPlay: true,\n \n // Callbacks\n onReady: null,\n onPlay: null,\n onPause: null,\n onEnded: null,\n onTimeUpdate: null,\n onVolumeChange: null,\n onError: null,\n \n ...options\n };\n\n // State\n this.state = {\n ready: false,\n playing: false,\n paused: true,\n ended: false,\n buffering: false,\n seeking: false,\n muted: this.options.muted,\n volume: this.options.volume,\n currentTime: 0,\n duration: 0,\n playbackSpeed: this.options.playbackSpeed,\n fullscreen: false,\n pip: false,\n captionsEnabled: this.options.captionsDefault,\n currentCaption: null,\n controlsVisible: true,\n audioDescriptionEnabled: false,\n signLanguageEnabled: false\n };\n \n // Store original source for toggling\n this.originalSrc = null;\n this.audioDescriptionSrc = this.options.audioDescriptionSrc;\n this.signLanguageSrc = this.options.signLanguageSrc;\n this.signLanguageVideo = null;\n\n // Components\n this.container = null;\n this.renderer = null;\n this.controlBar = null;\n this.captionManager = null;\n this.keyboardManager = null;\n this.settingsDialog = null;\n\n // Initialize\n this.init();\n }\n\n async init() {\n try {\n this.log('Initializing VidPly player');\n \n // Auto-detect language from HTML lang attribute if not explicitly set\n if (!this.options.language || this.options.language === 'en') {\n const htmlLang = this.detectHtmlLanguage();\n if (htmlLang) {\n this.options.language = htmlLang;\n this.log(`Auto-detected language from HTML: ${htmlLang}`);\n }\n }\n \n // Set language\n i18n.setLanguage(this.options.language);\n \n // Create container\n this.createContainer();\n \n // Detect and initialize renderer (only if source exists)\n const src = this.element.src || this.element.querySelector('source')?.src;\n if (src) {\n await this.initializeRenderer();\n } else {\n this.log('No initial source - waiting for playlist or manual load');\n }\n \n // Create controls\n if (this.options.controls) {\n this.controlBar = new ControlBar(this);\n this.videoWrapper.appendChild(this.controlBar.element);\n }\n \n // Initialize captions\n if (this.options.captions) {\n this.captionManager = new CaptionManager(this);\n }\n \n // Initialize transcript\n if (this.options.transcript || this.options.transcriptButton) {\n this.transcriptManager = new TranscriptManager(this);\n }\n \n // Initialize keyboard controls\n if (this.options.keyboard) {\n this.keyboardManager = new KeyboardManager(this);\n }\n \n // Initialize settings dialog\n if (this.options.settingsButton) {\n this.settingsDialog = new SettingsDialog(this);\n }\n \n // Setup responsive handlers\n this.setupResponsiveHandlers();\n \n // Set initial state\n if (this.options.startTime > 0) {\n this.seek(this.options.startTime);\n }\n \n if (this.options.muted) {\n this.mute();\n }\n \n if (this.options.volume !== 0.8) {\n this.setVolume(this.options.volume);\n }\n \n // Mark as ready\n this.state.ready = true;\n this.emit('ready');\n \n if (this.options.onReady) {\n this.options.onReady.call(this);\n }\n \n // Autoplay if enabled\n if (this.options.autoplay) {\n this.play();\n }\n \n this.log('Player initialized successfully');\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Detect language from HTML lang attribute\n * @returns {string|null} Language code if available in translations, null otherwise\n */\n detectHtmlLanguage() {\n // Try to get lang from html element\n const htmlLang = document.documentElement.lang || document.documentElement.getAttribute('lang');\n \n if (!htmlLang) {\n return null;\n }\n \n // Normalize the language code (e.g., \"en-US\" -> \"en\", \"de-DE\" -> \"de\")\n const normalizedLang = htmlLang.toLowerCase().split('-')[0];\n \n // Check if this language is available in our translations\n const availableLanguages = ['en', 'de', 'es', 'fr', 'ja'];\n \n if (availableLanguages.includes(normalizedLang)) {\n return normalizedLang;\n }\n \n // Language not available, will fallback to English\n this.log(`Language \"${htmlLang}\" not available, using English as fallback`);\n return 'en';\n }\n\n createContainer() {\n // Create main container\n this.container = DOMUtils.createElement('div', {\n className: `${this.options.classPrefix}-player`,\n attributes: {\n 'role': 'region',\n 'aria-label': i18n.t('player.label'),\n 'tabindex': '0'\n }\n });\n\n // Add media type class\n const mediaType = this.element.tagName.toLowerCase();\n this.container.classList.add(`${this.options.classPrefix}-${mediaType}`);\n\n // Add responsive class\n if (this.options.responsive) {\n this.container.classList.add(`${this.options.classPrefix}-responsive`);\n }\n\n // Create video wrapper (for proper positioning of controls)\n this.videoWrapper = DOMUtils.createElement('div', {\n className: `${this.options.classPrefix}-video-wrapper`\n });\n\n // Wrap original element\n this.element.parentNode.insertBefore(this.container, this.element);\n this.container.appendChild(this.videoWrapper);\n this.videoWrapper.appendChild(this.element);\n \n // Hide native controls and set dimensions\n this.element.controls = false;\n this.element.removeAttribute('controls');\n this.element.setAttribute('tabindex', '-1'); // Remove from tab order\n this.element.style.width = '100%';\n this.element.style.height = '100%';\n \n // Set dimensions\n if (this.options.width) {\n this.container.style.width = typeof this.options.width === 'number' \n ? `${this.options.width}px` \n : this.options.width;\n }\n \n if (this.options.height) {\n this.container.style.height = typeof this.options.height === 'number'\n ? `${this.options.height}px`\n : this.options.height;\n }\n \n // Set poster\n if (this.options.poster && this.element.tagName === 'VIDEO') {\n this.element.poster = this.options.poster;\n }\n \n // Create centered play button overlay (only for video)\n if (this.element.tagName === 'VIDEO') {\n this.createPlayButtonOverlay();\n }\n \n // Make video/audio element clickable to toggle play/pause\n this.element.style.cursor = 'pointer';\n this.element.addEventListener('click', (e) => {\n // Prevent if clicking on native controls (shouldn't happen but just in case)\n if (e.target === this.element) {\n this.toggle();\n }\n });\n }\n\n createPlayButtonOverlay() {\n // Create complete SVG play button from Icons.js\n this.playButtonOverlay = createPlayOverlay();\n \n // Add click handler\n this.playButtonOverlay.addEventListener('click', () => {\n this.toggle();\n });\n \n // Add to video wrapper\n this.videoWrapper.appendChild(this.playButtonOverlay);\n \n // Show/hide based on play state\n this.on('play', () => {\n this.playButtonOverlay.style.opacity = '0';\n this.playButtonOverlay.style.pointerEvents = 'none';\n });\n \n this.on('pause', () => {\n this.playButtonOverlay.style.opacity = '1';\n this.playButtonOverlay.style.pointerEvents = 'auto';\n });\n \n this.on('ended', () => {\n this.playButtonOverlay.style.opacity = '1';\n this.playButtonOverlay.style.pointerEvents = 'auto';\n });\n }\n\n async initializeRenderer() {\n const src = this.element.src || this.element.querySelector('source')?.src;\n \n if (!src) {\n throw new Error('No media source found');\n }\n\n // Store original source for audio description toggling\n if (!this.originalSrc) {\n this.originalSrc = src;\n }\n\n // Detect media type\n let renderer;\n \n if (src.includes('youtube.com') || src.includes('youtu.be')) {\n renderer = YouTubeRenderer;\n } else if (src.includes('vimeo.com')) {\n renderer = VimeoRenderer;\n } else if (src.includes('.m3u8')) {\n renderer = HLSRenderer;\n } else {\n renderer = HTML5Renderer;\n }\n\n this.log(`Using ${renderer.name} renderer`);\n this.renderer = new renderer(this);\n await this.renderer.init();\n }\n\n /**\n * Load new media source (for playlists)\n * @param {Object} config - Media configuration\n * @param {string} config.src - Media source URL\n * @param {string} config.type - Media MIME type\n * @param {string} [config.poster] - Poster image URL\n * @param {Array} [config.tracks] - Text tracks (captions, chapters, etc.)\n */\n async load(config) {\n try {\n this.log('Loading new media:', config.src);\n \n // Pause current playback\n if (this.renderer) {\n this.pause();\n }\n \n // Clear existing text tracks\n const existingTracks = this.element.querySelectorAll('track');\n existingTracks.forEach(track => track.remove());\n \n // Update media element\n this.element.src = config.src;\n \n if (config.type) {\n this.element.type = config.type;\n }\n \n if (config.poster && this.element.tagName === 'VIDEO') {\n this.element.poster = config.poster;\n }\n \n // Add new text tracks\n if (config.tracks && config.tracks.length > 0) {\n config.tracks.forEach(trackConfig => {\n const track = document.createElement('track');\n track.src = trackConfig.src;\n track.kind = trackConfig.kind || 'captions';\n track.srclang = trackConfig.srclang || 'en';\n track.label = trackConfig.label || trackConfig.srclang;\n \n if (trackConfig.default) {\n track.default = true;\n }\n \n this.element.appendChild(track);\n });\n }\n \n // Check if we need to change renderer type\n const shouldChangeRenderer = this.shouldChangeRenderer(config.src);\n \n // Destroy old renderer if changing types\n if (shouldChangeRenderer && this.renderer) {\n this.renderer.destroy();\n this.renderer = null;\n }\n \n // Initialize or reinitialize renderer\n if (!this.renderer || shouldChangeRenderer) {\n await this.initializeRenderer();\n } else {\n // Just reload the current renderer with the updated element\n this.renderer.media = this.element; // Update media reference\n this.element.load();\n }\n \n // Reinitialize caption manager to pick up new tracks\n if (this.captionManager) {\n this.captionManager.destroy();\n this.captionManager = new CaptionManager(this);\n }\n \n this.emit('sourcechange', config);\n this.log('Media loaded successfully');\n \n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Check if we need to change renderer type\n * @param {string} src - New source URL\n * @returns {boolean}\n */\n shouldChangeRenderer(src) {\n if (!this.renderer) return true;\n \n const isYouTube = src.includes('youtube.com') || src.includes('youtu.be');\n const isVimeo = src.includes('vimeo.com');\n const isHLS = src.includes('.m3u8');\n \n const currentRendererName = this.renderer.constructor.name;\n \n if (isYouTube && currentRendererName !== 'YouTubeRenderer') return true;\n if (isVimeo && currentRendererName !== 'VimeoRenderer') return true;\n if (isHLS && currentRendererName !== 'HLSRenderer') return true;\n if (!isYouTube && !isVimeo && !isHLS && currentRendererName !== 'HTML5Renderer') return true;\n \n return false;\n }\n\n // Playback controls\n play() {\n if (this.renderer) {\n this.renderer.play();\n }\n }\n\n pause() {\n if (this.renderer) {\n this.renderer.pause();\n }\n }\n\n stop() {\n this.pause();\n this.seek(0);\n }\n\n toggle() {\n if (this.state.playing) {\n this.pause();\n } else {\n this.play();\n }\n }\n\n seek(time) {\n if (this.renderer) {\n this.renderer.seek(time);\n }\n }\n\n seekForward(interval = this.options.seekInterval) {\n this.seek(Math.min(this.state.currentTime + interval, this.state.duration));\n }\n\n seekBackward(interval = this.options.seekInterval) {\n this.seek(Math.max(this.state.currentTime - interval, 0));\n }\n\n // Volume controls\n setVolume(volume) {\n const newVolume = Math.max(0, Math.min(1, volume));\n if (this.renderer) {\n this.renderer.setVolume(newVolume);\n }\n this.state.volume = newVolume;\n \n if (newVolume > 0 && this.state.muted) {\n this.state.muted = false;\n }\n }\n\n getVolume() {\n return this.state.volume;\n }\n\n mute() {\n if (this.renderer) {\n this.renderer.setMuted(true);\n }\n this.state.muted = true;\n }\n\n unmute() {\n if (this.renderer) {\n this.renderer.setMuted(false);\n }\n this.state.muted = false;\n }\n\n toggleMute() {\n if (this.state.muted) {\n this.unmute();\n } else {\n this.mute();\n }\n }\n\n // Playback speed\n setPlaybackSpeed(speed) {\n const newSpeed = Math.max(0.25, Math.min(2, speed));\n if (this.renderer) {\n this.renderer.setPlaybackSpeed(newSpeed);\n }\n this.state.playbackSpeed = newSpeed;\n this.emit('playbackspeedchange', newSpeed);\n }\n\n getPlaybackSpeed() {\n return this.state.playbackSpeed;\n }\n\n // Fullscreen\n enterFullscreen() {\n const elem = this.container;\n \n if (elem.requestFullscreen) {\n elem.requestFullscreen();\n } else if (elem.webkitRequestFullscreen) {\n elem.webkitRequestFullscreen();\n } else if (elem.mozRequestFullScreen) {\n elem.mozRequestFullScreen();\n } else if (elem.msRequestFullscreen) {\n elem.msRequestFullscreen();\n }\n \n this.state.fullscreen = true;\n this.container.classList.add(`${this.options.classPrefix}-fullscreen`);\n this.emit('fullscreenchange', true);\n }\n\n exitFullscreen() {\n if (document.exitFullscreen) {\n document.exitFullscreen();\n } else if (document.webkitExitFullscreen) {\n document.webkitExitFullscreen();\n } else if (document.mozCancelFullScreen) {\n document.mozCancelFullScreen();\n } else if (document.msExitFullscreen) {\n document.msExitFullscreen();\n }\n \n this.state.fullscreen = false;\n this.container.classList.remove(`${this.options.classPrefix}-fullscreen`);\n this.emit('fullscreenchange', false);\n }\n\n toggleFullscreen() {\n if (this.state.fullscreen) {\n this.exitFullscreen();\n } else {\n this.enterFullscreen();\n }\n }\n\n // Picture-in-Picture\n enterPiP() {\n if (this.element.requestPictureInPicture) {\n this.element.requestPictureInPicture();\n this.state.pip = true;\n this.emit('pipchange', true);\n }\n }\n\n exitPiP() {\n if (document.pictureInPictureElement) {\n document.exitPictureInPicture();\n this.state.pip = false;\n this.emit('pipchange', false);\n }\n }\n\n togglePiP() {\n if (this.state.pip) {\n this.exitPiP();\n } else {\n this.enterPiP();\n }\n }\n\n // Captions\n enableCaptions() {\n if (this.captionManager) {\n this.captionManager.enable();\n this.state.captionsEnabled = true;\n }\n }\n\n disableCaptions() {\n if (this.captionManager) {\n this.captionManager.disable();\n this.state.captionsEnabled = false;\n }\n }\n\n toggleCaptions() {\n if (this.state.captionsEnabled) {\n this.disableCaptions();\n } else {\n this.enableCaptions();\n }\n }\n\n // Audio Description\n async enableAudioDescription() {\n if (!this.audioDescriptionSrc) {\n console.warn('VidPly: No audio description source provided');\n return;\n }\n\n // Store current playback state\n const currentTime = this.state.currentTime;\n const wasPlaying = this.state.playing;\n\n // Switch to audio-described version\n this.element.src = this.audioDescriptionSrc;\n \n // Wait for new source to load\n await new Promise((resolve) => {\n const onLoadedMetadata = () => {\n this.element.removeEventListener('loadedmetadata', onLoadedMetadata);\n resolve();\n };\n this.element.addEventListener('loadedmetadata', onLoadedMetadata);\n });\n\n // Restore playback position\n this.seek(currentTime);\n \n if (wasPlaying) {\n this.play();\n }\n\n this.state.audioDescriptionEnabled = true;\n this.emit('audiodescriptionenabled');\n }\n\n async disableAudioDescription() {\n if (!this.originalSrc) {\n return;\n }\n\n // Store current playback state\n const currentTime = this.state.currentTime;\n const wasPlaying = this.state.playing;\n\n // Switch back to original version\n this.element.src = this.originalSrc;\n \n // Wait for new source to load\n await new Promise((resolve) => {\n const onLoadedMetadata = () => {\n this.element.removeEventListener('loadedmetadata', onLoadedMetadata);\n resolve();\n };\n this.element.addEventListener('loadedmetadata', onLoadedMetadata);\n });\n\n // Restore playback position\n this.seek(currentTime);\n \n if (wasPlaying) {\n this.play();\n }\n\n this.state.audioDescriptionEnabled = false;\n this.emit('audiodescriptiondisabled');\n }\n\n async toggleAudioDescription() {\n if (this.state.audioDescriptionEnabled) {\n await this.disableAudioDescription();\n } else {\n await this.enableAudioDescription();\n }\n }\n\n // Sign Language\n enableSignLanguage() {\n if (!this.signLanguageSrc) {\n console.warn('No sign language video source provided');\n return;\n }\n\n if (this.signLanguageVideo) {\n // Already exists, just show it\n this.signLanguageVideo.style.display = 'block';\n this.state.signLanguageEnabled = true;\n this.emit('signlanguageenabled');\n return;\n }\n\n // Create sign language video element\n this.signLanguageVideo = document.createElement('video');\n this.signLanguageVideo.className = 'vidply-sign-language-video';\n this.signLanguageVideo.src = this.signLanguageSrc;\n this.signLanguageVideo.setAttribute('aria-label', i18n.t('player.signLanguage'));\n \n // Set position based on options\n const position = this.options.signLanguagePosition || 'bottom-right';\n this.signLanguageVideo.classList.add(`vidply-sign-position-${position}`);\n \n // Sync with main video\n this.signLanguageVideo.muted = true; // Sign language video should be muted\n this.signLanguageVideo.currentTime = this.state.currentTime;\n if (!this.state.paused) {\n this.signLanguageVideo.play();\n }\n\n // Add to container\n this.container.appendChild(this.signLanguageVideo);\n\n // Create bound handlers to store references for cleanup\n this.signLanguageHandlers = {\n play: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.play();\n }\n },\n pause: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.pause();\n }\n },\n timeupdate: () => {\n if (this.signLanguageVideo && Math.abs(this.signLanguageVideo.currentTime - this.state.currentTime) > 0.5) {\n this.signLanguageVideo.currentTime = this.state.currentTime;\n }\n },\n ratechange: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.playbackRate = this.state.playbackSpeed;\n }\n }\n };\n\n // Sync playback\n this.on('play', this.signLanguageHandlers.play);\n this.on('pause', this.signLanguageHandlers.pause);\n this.on('timeupdate', this.signLanguageHandlers.timeupdate);\n this.on('ratechange', this.signLanguageHandlers.ratechange);\n\n this.state.signLanguageEnabled = true;\n this.emit('signlanguageenabled');\n }\n\n disableSignLanguage() {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.style.display = 'none';\n }\n this.state.signLanguageEnabled = false;\n this.emit('signlanguagedisabled');\n }\n\n toggleSignLanguage() {\n if (this.state.signLanguageEnabled) {\n this.disableSignLanguage();\n } else {\n this.enableSignLanguage();\n }\n }\n\n cleanupSignLanguage() {\n // Remove event listeners\n if (this.signLanguageHandlers) {\n this.off('play', this.signLanguageHandlers.play);\n this.off('pause', this.signLanguageHandlers.pause);\n this.off('timeupdate', this.signLanguageHandlers.timeupdate);\n this.off('ratechange', this.signLanguageHandlers.ratechange);\n this.signLanguageHandlers = null;\n }\n\n // Remove video element\n if (this.signLanguageVideo && this.signLanguageVideo.parentNode) {\n this.signLanguageVideo.pause();\n this.signLanguageVideo.src = '';\n this.signLanguageVideo.parentNode.removeChild(this.signLanguageVideo);\n this.signLanguageVideo = null;\n }\n }\n\n // Settings\n showSettings() {\n if (this.settingsDialog) {\n this.settingsDialog.show();\n }\n }\n\n hideSettings() {\n if (this.settingsDialog) {\n this.settingsDialog.hide();\n }\n }\n\n // Utility methods\n getCurrentTime() {\n return this.state.currentTime;\n }\n\n getDuration() {\n return this.state.duration;\n }\n\n isPlaying() {\n return this.state.playing;\n }\n\n isPaused() {\n return this.state.paused;\n }\n\n isEnded() {\n return this.state.ended;\n }\n\n isMuted() {\n return this.state.muted;\n }\n\n isFullscreen() {\n return this.state.fullscreen;\n }\n\n // Error handling\n handleError(error) {\n this.log('Error:', error, 'error');\n this.emit('error', error);\n \n if (this.options.onError) {\n this.options.onError.call(this, error);\n }\n }\n\n // Logging\n log(message, type = 'log') {\n if (this.options.debug) {\n console[type](`[VidPly]`, message);\n }\n }\n\n // Setup responsive handlers\n setupResponsiveHandlers() {\n // Use ResizeObserver for efficient resize tracking\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const width = entry.contentRect.width;\n \n // Update control bar for viewport\n if (this.controlBar && typeof this.controlBar.updateControlsForViewport === 'function') {\n this.controlBar.updateControlsForViewport(width);\n }\n \n // Update transcript positioning\n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n }\n });\n \n this.resizeObserver.observe(this.container);\n } else {\n // Fallback to window resize event\n this.resizeHandler = () => {\n const width = this.container.clientWidth;\n \n if (this.controlBar && typeof this.controlBar.updateControlsForViewport === 'function') {\n this.controlBar.updateControlsForViewport(width);\n }\n \n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n };\n \n window.addEventListener('resize', this.resizeHandler);\n }\n \n // Also listen for orientation changes on mobile\n if (window.matchMedia) {\n this.orientationHandler = (e) => {\n // Wait for layout to settle\n setTimeout(() => {\n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n }, 100);\n };\n \n const orientationQuery = window.matchMedia('(orientation: portrait)');\n if (orientationQuery.addEventListener) {\n orientationQuery.addEventListener('change', this.orientationHandler);\n } else if (orientationQuery.addListener) {\n // Fallback for older browsers\n orientationQuery.addListener(this.orientationHandler);\n }\n \n this.orientationQuery = orientationQuery;\n }\n }\n\n // Cleanup\n destroy() {\n this.log('Destroying player');\n \n if (this.renderer) {\n this.renderer.destroy();\n }\n \n if (this.controlBar) {\n this.controlBar.destroy();\n }\n \n if (this.captionManager) {\n this.captionManager.destroy();\n }\n \n if (this.keyboardManager) {\n this.keyboardManager.destroy();\n }\n \n if (this.settingsDialog) {\n this.settingsDialog.destroy();\n }\n \n if (this.transcriptManager) {\n this.transcriptManager.destroy();\n }\n \n // Cleanup sign language video and listeners\n this.cleanupSignLanguage();\n \n // Cleanup play overlay button\n if (this.playButtonOverlay && this.playButtonOverlay.parentNode) {\n this.playButtonOverlay.remove();\n this.playButtonOverlay = null;\n }\n \n // Cleanup resize observer\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n \n // Cleanup window resize handler\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n this.resizeHandler = null;\n }\n \n // Cleanup orientation change handler\n if (this.orientationQuery && this.orientationHandler) {\n if (this.orientationQuery.removeEventListener) {\n this.orientationQuery.removeEventListener('change', this.orientationHandler);\n } else if (this.orientationQuery.removeListener) {\n this.orientationQuery.removeListener(this.orientationHandler);\n }\n this.orientationQuery = null;\n this.orientationHandler = null;\n }\n \n // Remove container\n if (this.container && this.container.parentNode) {\n this.container.parentNode.insertBefore(this.element, this.container);\n this.container.parentNode.removeChild(this.container);\n }\n \n this.removeAllListeners();\n }\n}\n\n// Static instances tracker for pause others functionality\nPlayer.instances = [];\n\n", "/**\n * YouTube Renderer\n */\n\nexport class YouTubeRenderer {\n constructor(player) {\n this.player = player;\n this.youtube = null;\n this.videoId = null;\n this.isReady = false;\n this.iframe = null;\n }\n\n async init() {\n // Extract video ID from URL\n this.videoId = this.extractVideoId(this.player.element.src);\n \n if (!this.videoId) {\n throw new Error('Invalid YouTube URL');\n }\n\n // Load YouTube IFrame API\n await this.loadYouTubeAPI();\n\n // Create iframe\n this.createIframe();\n\n // Initialize player\n await this.initializePlayer();\n }\n\n extractVideoId(url) {\n const patterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([^&\\s]+)/,\n /youtube\\.com\\/embed\\/([^&\\s]+)/\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n async loadYouTubeAPI() {\n // Check if API is already loaded\n if (window.YT && window.YT.Player) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n // Check if script is already being loaded\n if (window.onYouTubeIframeAPIReady) {\n const originalCallback = window.onYouTubeIframeAPIReady;\n window.onYouTubeIframeAPIReady = () => {\n originalCallback();\n resolve();\n };\n return;\n }\n\n // Load the API script\n const tag = document.createElement('script');\n tag.src = 'https://www.youtube.com/iframe_api';\n \n window.onYouTubeIframeAPIReady = () => {\n resolve();\n };\n\n tag.onerror = () => reject(new Error('Failed to load YouTube API'));\n \n const firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n });\n }\n\n createIframe() {\n // Hide original element\n this.player.element.style.display = 'none';\n\n // Create container for iframe\n this.iframe = document.createElement('div');\n this.iframe.id = `youtube-player-${Math.random().toString(36).substr(2, 9)}`;\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n \n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\n }\n\n async initializePlayer() {\n return new Promise((resolve) => {\n this.youtube = new window.YT.Player(this.iframe.id, {\n videoId: this.videoId,\n width: '100%',\n height: '100%',\n playerVars: {\n controls: 0,\n disablekb: 1,\n fs: 0,\n modestbranding: 1,\n rel: 0,\n showinfo: 0,\n iv_load_policy: 3,\n autoplay: this.player.options.autoplay ? 1 : 0,\n mute: this.player.options.muted ? 1 : 0,\n start: this.player.options.startTime || 0\n },\n events: {\n onReady: (event) => {\n this.isReady = true;\n this.attachEvents();\n resolve();\n },\n onStateChange: (event) => this.handleStateChange(event),\n onError: (event) => this.handleError(event)\n }\n });\n });\n }\n\n attachEvents() {\n // Set up polling for time updates (YouTube doesn't provide timeupdate events)\n this.timeUpdateInterval = setInterval(() => {\n if (this.isReady && this.youtube) {\n const currentTime = this.youtube.getCurrentTime();\n const duration = this.youtube.getDuration();\n \n this.player.state.currentTime = currentTime;\n this.player.state.duration = duration;\n \n this.player.emit('timeupdate', currentTime);\n }\n }, 250);\n\n // Initial metadata\n if (this.youtube.getDuration) {\n this.player.state.duration = this.youtube.getDuration();\n this.player.emit('loadedmetadata');\n }\n }\n\n handleStateChange(event) {\n const states = window.YT.PlayerState;\n\n switch (event.data) {\n case states.PLAYING:\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.state.buffering = false;\n this.player.emit('play');\n this.player.emit('playing');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n break;\n\n case states.PAUSED:\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n break;\n\n case states.ENDED:\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n if (this.player.options.loop) {\n this.youtube.seekTo(0);\n this.youtube.playVideo();\n }\n break;\n\n case states.BUFFERING:\n this.player.state.buffering = true;\n this.player.emit('waiting');\n break;\n\n case states.CUED:\n this.player.emit('loadedmetadata');\n break;\n }\n }\n\n handleError(event) {\n const errors = {\n 2: 'Invalid video ID',\n 5: 'HTML5 player error',\n 100: 'Video not found',\n 101: 'Video not allowed to be played in embedded players',\n 150: 'Video not allowed to be played in embedded players'\n };\n\n const error = new Error(errors[event.data] || 'YouTube player error');\n this.player.handleError(error);\n }\n\n play() {\n if (this.isReady && this.youtube) {\n this.youtube.playVideo();\n }\n }\n\n pause() {\n if (this.isReady && this.youtube) {\n this.youtube.pauseVideo();\n }\n }\n\n seek(time) {\n if (this.isReady && this.youtube) {\n this.youtube.seekTo(time, true);\n }\n }\n\n setVolume(volume) {\n if (this.isReady && this.youtube) {\n this.youtube.setVolume(volume * 100);\n this.player.state.volume = volume;\n }\n }\n\n setMuted(muted) {\n if (this.isReady && this.youtube) {\n if (muted) {\n this.youtube.mute();\n } else {\n this.youtube.unMute();\n }\n this.player.state.muted = muted;\n }\n }\n\n setPlaybackSpeed(speed) {\n if (this.isReady && this.youtube) {\n this.youtube.setPlaybackRate(speed);\n this.player.state.playbackSpeed = speed;\n }\n }\n\n destroy() {\n if (this.timeUpdateInterval) {\n clearInterval(this.timeUpdateInterval);\n }\n\n if (this.youtube && this.youtube.destroy) {\n this.youtube.destroy();\n }\n\n if (this.iframe && this.iframe.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n // Show original element\n if (this.player.element) {\n this.player.element.style.display = '';\n }\n }\n}\n\n", "/**\n * Vimeo Renderer\n */\n\nexport class VimeoRenderer {\n constructor(player) {\n this.player = player;\n this.vimeo = null;\n this.videoId = null;\n this.isReady = false;\n this.iframe = null;\n }\n\n async init() {\n // Extract video ID from URL\n this.videoId = this.extractVideoId(this.player.element.src);\n \n if (!this.videoId) {\n throw new Error('Invalid Vimeo URL');\n }\n\n // Load Vimeo Player API\n await this.loadVimeoAPI();\n\n // Create iframe\n this.createIframe();\n\n // Initialize player\n await this.initializePlayer();\n }\n\n extractVideoId(url) {\n const patterns = [\n /vimeo\\.com\\/(\\d+)/,\n /vimeo\\.com\\/video\\/(\\d+)/,\n /player\\.vimeo\\.com\\/video\\/(\\d+)/\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n async loadVimeoAPI() {\n // Check if API is already loaded\n if (window.Vimeo && window.Vimeo.Player) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://player.vimeo.com/api/player.js';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load Vimeo API'));\n document.head.appendChild(script);\n });\n }\n\n createIframe() {\n // Hide original element\n this.player.element.style.display = 'none';\n\n // Create container for iframe\n this.iframe = document.createElement('div');\n this.iframe.id = `vimeo-player-${Math.random().toString(36).substr(2, 9)}`;\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n \n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\n }\n\n async initializePlayer() {\n const options = {\n id: this.videoId,\n width: '100%',\n height: '100%',\n controls: false,\n autoplay: this.player.options.autoplay,\n muted: this.player.options.muted,\n loop: this.player.options.loop,\n keyboard: false\n };\n\n if (this.player.options.startTime > 0) {\n options.startTime = this.player.options.startTime;\n }\n\n this.vimeo = new window.Vimeo.Player(this.iframe.id, options);\n\n // Wait for player to be ready\n await this.vimeo.ready();\n this.isReady = true;\n\n this.attachEvents();\n\n // Get initial duration\n try {\n const duration = await this.vimeo.getDuration();\n this.player.state.duration = duration;\n this.player.emit('loadedmetadata');\n } catch (error) {\n this.player.log('Error getting duration:', error, 'warn');\n }\n }\n\n attachEvents() {\n this.vimeo.on('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n });\n\n this.vimeo.on('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.vimeo.on('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n });\n\n this.vimeo.on('timeupdate', (data) => {\n this.player.state.currentTime = data.seconds;\n this.player.state.duration = data.duration;\n this.player.emit('timeupdate', data.seconds);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, data.seconds);\n }\n });\n\n this.vimeo.on('volumechange', (data) => {\n this.player.state.volume = data.volume;\n this.player.emit('volumechange', data.volume);\n });\n\n this.vimeo.on('bufferstart', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.vimeo.on('bufferend', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.vimeo.on('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n });\n\n this.vimeo.on('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n });\n\n this.vimeo.on('playbackratechange', (data) => {\n this.player.state.playbackSpeed = data.playbackRate;\n this.player.emit('ratechange', data.playbackRate);\n });\n\n this.vimeo.on('error', (error) => {\n this.player.handleError(new Error(`Vimeo error: ${error.message}`));\n });\n }\n\n play() {\n if (this.isReady && this.vimeo) {\n this.vimeo.play().catch(error => {\n this.player.log('Play error:', error, 'warn');\n });\n }\n }\n\n pause() {\n if (this.isReady && this.vimeo) {\n this.vimeo.pause().catch(error => {\n this.player.log('Pause error:', error, 'warn');\n });\n }\n }\n\n seek(time) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setCurrentTime(time).catch(error => {\n this.player.log('Seek error:', error, 'warn');\n });\n }\n }\n\n setVolume(volume) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setVolume(volume).catch(error => {\n this.player.log('Volume error:', error, 'warn');\n });\n this.player.state.volume = volume;\n }\n }\n\n setMuted(muted) {\n if (this.isReady && this.vimeo) {\n if (muted) {\n this.vimeo.setVolume(0);\n } else {\n this.vimeo.setVolume(this.player.state.volume);\n }\n this.player.state.muted = muted;\n }\n }\n\n setPlaybackSpeed(speed) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setPlaybackRate(speed).catch(error => {\n this.player.log('Playback rate error:', error, 'warn');\n });\n this.player.state.playbackSpeed = speed;\n }\n }\n\n destroy() {\n if (this.vimeo && this.vimeo.destroy) {\n this.vimeo.destroy();\n }\n\n if (this.iframe && this.iframe.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n // Show original element\n if (this.player.element) {\n this.player.element.style.display = '';\n }\n }\n}\n\n", "/**\n * HLS Streaming Renderer\n * Uses hls.js for browsers that don't natively support HLS\n */\n\nexport class HLSRenderer {\n constructor(player) {\n this.player = player;\n this.media = player.element;\n this.hls = null;\n }\n\n async init() {\n // Check if browser natively supports HLS (Safari)\n if (this.canPlayNatively()) {\n this.player.log('Using native HLS support');\n await this.initNative();\n } else {\n this.player.log('Using hls.js for HLS support');\n await this.initHlsJs();\n }\n }\n\n canPlayNatively() {\n const video = document.createElement('video');\n return video.canPlayType('application/vnd.apple.mpegurl') !== '';\n }\n\n async initNative() {\n // Use HTML5 renderer for native HLS support\n const HTML5Renderer = (await import('./HTML5Renderer.js')).HTML5Renderer;\n const renderer = new HTML5Renderer(this.player);\n await renderer.init();\n \n // Copy methods\n Object.getOwnPropertyNames(Object.getPrototypeOf(renderer)).forEach(method => {\n if (method !== 'constructor' && typeof renderer[method] === 'function') {\n this[method] = renderer[method].bind(renderer);\n }\n });\n }\n\n async initHlsJs() {\n // Hide native controls\n this.media.controls = false;\n this.media.removeAttribute('controls');\n \n // Load hls.js if not already loaded\n if (!window.Hls) {\n await this.loadHlsJs();\n }\n\n if (!window.Hls.isSupported()) {\n throw new Error('HLS is not supported in this browser');\n }\n\n // Create hls.js instance with better error recovery\n this.hls = new window.Hls({\n debug: this.player.options.debug,\n enableWorker: true,\n lowLatencyMode: false,\n backBufferLength: 90,\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n maxBufferHole: 0.5,\n // Network retry settings\n manifestLoadingTimeOut: 10000,\n manifestLoadingMaxRetry: 4,\n manifestLoadingRetryDelay: 1000,\n manifestLoadingMaxRetryTimeout: 64000,\n levelLoadingTimeOut: 10000,\n levelLoadingMaxRetry: 4,\n levelLoadingRetryDelay: 1000,\n levelLoadingMaxRetryTimeout: 64000,\n fragLoadingTimeOut: 20000,\n fragLoadingMaxRetry: 6,\n fragLoadingRetryDelay: 1000,\n fragLoadingMaxRetryTimeout: 64000\n });\n\n // Attach media element\n this.hls.attachMedia(this.media);\n\n // Load source - Get from attribute to avoid blob URL conversion\n let src;\n const sourceElement = this.player.element.querySelector('source');\n if (sourceElement) {\n // Use getAttribute to get the original URL, not the blob-converted one\n src = sourceElement.getAttribute('src');\n } else {\n // Fallback to element's src attribute\n src = this.player.element.getAttribute('src') || this.player.element.src;\n }\n \n this.player.log(`Loading HLS source: ${src}`, 'log');\n \n if (!src) {\n throw new Error('No HLS source found');\n }\n \n this.hls.loadSource(src);\n\n // Attach events\n this.attachHlsEvents();\n this.attachMediaEvents();\n }\n\n async loadHlsJs() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load hls.js'));\n document.head.appendChild(script);\n });\n }\n\n attachHlsEvents() {\n this.hls.on(window.Hls.Events.MANIFEST_PARSED, (event, data) => {\n this.player.log('HLS manifest loaded, found ' + data.levels.length + ' quality levels');\n this.player.emit('hlsmanifestparsed', data);\n });\n\n this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {\n this.player.log('HLS level switched to ' + data.level);\n this.player.emit('hlslevelswitched', data);\n });\n\n this.hls.on(window.Hls.Events.ERROR, (event, data) => {\n this.handleHlsError(data);\n });\n\n this.hls.on(window.Hls.Events.FRAG_BUFFERED, () => {\n this.player.state.buffering = false;\n });\n }\n\n attachMediaEvents() {\n // Use same events as HTML5 renderer\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.media.addEventListener('error', () => {\n this.player.handleError(this.media.error);\n });\n }\n\n handleHlsError(data) {\n // Log detailed error info\n this.player.log(`HLS Error - Type: ${data.type}, Details: ${data.details}, Fatal: ${data.fatal}`, 'warn');\n if (data.response) {\n this.player.log(`Response code: ${data.response.code}, URL: ${data.response.url}`, 'warn');\n }\n \n if (data.fatal) {\n switch (data.type) {\n case window.Hls.ErrorTypes.NETWORK_ERROR:\n this.player.log('Fatal network error, trying to recover...', 'error');\n this.player.log(`Network error details: ${data.details}`, 'error');\n setTimeout(() => {\n this.hls.startLoad();\n }, 1000);\n break;\n \n case window.Hls.ErrorTypes.MEDIA_ERROR:\n this.player.log('Fatal media error, trying to recover...', 'error');\n this.hls.recoverMediaError();\n break;\n \n default:\n this.player.log('Fatal error, cannot recover', 'error');\n this.player.handleError(new Error(`HLS Error: ${data.type} - ${data.details}`));\n this.hls.destroy();\n break;\n }\n } else {\n this.player.log('Non-fatal HLS error: ' + data.details, 'warn');\n }\n }\n\n play() {\n const promise = this.media.play();\n \n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n });\n }\n }\n\n pause() {\n this.media.pause();\n }\n\n seek(time) {\n this.media.currentTime = time;\n }\n\n setVolume(volume) {\n this.media.volume = volume;\n }\n\n setMuted(muted) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed) {\n this.media.playbackRate = speed;\n }\n\n switchQuality(levelIndex) {\n if (this.hls) {\n this.hls.currentLevel = levelIndex;\n }\n }\n\n getQualities() {\n if (this.hls && this.hls.levels) {\n return this.hls.levels.map((level, index) => ({\n index,\n height: level.height,\n width: level.width,\n bitrate: level.bitrate,\n name: `${level.height}p`\n }));\n }\n return [];\n }\n\n destroy() {\n if (this.hls) {\n this.hls.destroy();\n this.hls = null;\n }\n }\n}\n\n", "/**\n * VidPly Playlist Manager\n * Manages playlists for audio and video content\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\n\nexport class PlaylistManager {\n constructor(player, options = {}) {\n this.player = player;\n this.tracks = [];\n this.currentIndex = -1;\n \n // Options\n this.options = {\n autoAdvance: options.autoAdvance !== false, // Default true\n loop: options.loop || false,\n showPanel: options.showPanel !== false, // Default true\n ...options\n };\n \n // UI elements\n this.container = null;\n this.playlistPanel = null;\n this.trackInfoElement = null;\n \n // Bind methods\n this.handleTrackEnd = this.handleTrackEnd.bind(this);\n this.handleTrackError = this.handleTrackError.bind(this);\n \n // Initialize\n this.init();\n }\n \n init() {\n // Listen for track end\n this.player.on('ended', this.handleTrackEnd);\n this.player.on('error', this.handleTrackError);\n \n // Create UI if needed\n if (this.options.showPanel) {\n this.createUI();\n }\n }\n \n /**\n * Load a playlist\n * @param {Array} tracks - Array of track objects\n */\n loadPlaylist(tracks) {\n this.tracks = tracks;\n this.currentIndex = -1;\n \n // Add playlist class to container\n if (this.container) {\n this.container.classList.add('vidply-has-playlist');\n }\n \n // Update UI\n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n \n // Auto-play first track\n if (tracks.length > 0) {\n this.play(0);\n }\n }\n \n /**\n * Play a specific track\n * @param {number} index - Track index\n */\n play(index) {\n if (index < 0 || index >= this.tracks.length) {\n console.warn('VidPly Playlist: Invalid track index', index);\n return;\n }\n \n const track = this.tracks[index];\n \n // Update current index\n this.currentIndex = index;\n \n // Load track into player\n this.player.load({\n src: track.src,\n type: track.type,\n poster: track.poster,\n tracks: track.tracks || []\n });\n \n // Update UI\n this.updateTrackInfo(track);\n this.updatePlaylistUI();\n \n // Emit event\n this.player.emit('playlisttrackchange', {\n index: index,\n item: track,\n total: this.tracks.length\n });\n \n // Auto-play\n setTimeout(() => {\n this.player.play();\n }, 100);\n }\n \n /**\n * Play next track\n */\n next() {\n let nextIndex = this.currentIndex + 1;\n \n if (nextIndex >= this.tracks.length) {\n if (this.options.loop) {\n nextIndex = 0;\n } else {\n return;\n }\n }\n \n this.play(nextIndex);\n }\n \n /**\n * Play previous track\n */\n previous() {\n let prevIndex = this.currentIndex - 1;\n \n if (prevIndex < 0) {\n if (this.options.loop) {\n prevIndex = this.tracks.length - 1;\n } else {\n return;\n }\n }\n \n this.play(prevIndex);\n }\n \n /**\n * Handle track end\n */\n handleTrackEnd() {\n if (this.options.autoAdvance) {\n this.next();\n }\n }\n \n /**\n * Handle track error\n */\n handleTrackError(e) {\n console.error('VidPly Playlist: Track error', e);\n \n // Try next track\n if (this.options.autoAdvance) {\n setTimeout(() => {\n this.next();\n }, 1000);\n }\n }\n \n /**\n * Create playlist UI\n */\n createUI() {\n // Find player container\n this.container = this.player.container;\n \n if (!this.container) {\n console.warn('VidPly Playlist: No container found');\n return;\n }\n \n // Create track info element (shows current track)\n this.trackInfoElement = DOMUtils.createElement('div', {\n className: 'vidply-track-info'\n });\n this.trackInfoElement.style.display = 'none';\n \n this.container.appendChild(this.trackInfoElement);\n \n // Create playlist panel\n this.playlistPanel = DOMUtils.createElement('div', {\n className: 'vidply-playlist-panel'\n });\n this.playlistPanel.style.display = 'none';\n \n this.container.appendChild(this.playlistPanel);\n }\n \n /**\n * Update track info display\n */\n updateTrackInfo(track) {\n if (!this.trackInfoElement) return;\n \n const trackNumber = this.currentIndex + 1;\n const totalTracks = this.tracks.length;\n \n this.trackInfoElement.innerHTML = `\n <div class=\"vidply-track-number\">Track ${trackNumber} of ${totalTracks}</div>\n <div class=\"vidply-track-title\">${DOMUtils.escapeHTML(track.title || 'Untitled')}</div>\n ${track.artist ? `<div class=\"vidply-track-artist\">${DOMUtils.escapeHTML(track.artist)}</div>` : ''}\n `;\n \n this.trackInfoElement.style.display = 'block';\n }\n \n /**\n * Render playlist\n */\n renderPlaylist() {\n if (!this.playlistPanel) return;\n \n // Clear existing\n this.playlistPanel.innerHTML = '';\n \n // Create header\n const header = DOMUtils.createElement('div', {\n className: 'vidply-playlist-header'\n });\n header.textContent = `Playlist (${this.tracks.length})`;\n this.playlistPanel.appendChild(header);\n \n // Create list\n const list = DOMUtils.createElement('div', {\n className: 'vidply-playlist-list'\n });\n \n this.tracks.forEach((track, index) => {\n const item = this.createPlaylistItem(track, index);\n list.appendChild(item);\n });\n \n this.playlistPanel.appendChild(list);\n this.playlistPanel.style.display = 'block';\n }\n \n /**\n * Create playlist item element\n */\n createPlaylistItem(track, index) {\n const item = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item',\n role: 'button',\n tabIndex: 0,\n 'aria-label': `Play ${track.title || 'Track ' + (index + 1)}`\n });\n \n // Add active class if current\n if (index === this.currentIndex) {\n item.classList.add('vidply-playlist-item-active');\n }\n \n // Thumbnail or icon\n const thumbnail = DOMUtils.createElement('div', {\n className: 'vidply-playlist-thumbnail'\n });\n \n if (track.poster) {\n thumbnail.style.backgroundImage = `url(${track.poster})`;\n } else {\n // Show music/speaker icon for audio tracks\n const icon = createIconElement('music');\n icon.classList.add('vidply-playlist-thumbnail-icon');\n thumbnail.appendChild(icon);\n }\n \n item.appendChild(thumbnail);\n \n // Info\n const info = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-info'\n });\n \n const title = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-title'\n });\n title.textContent = track.title || `Track ${index + 1}`;\n info.appendChild(title);\n \n if (track.artist) {\n const artist = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-artist'\n });\n artist.textContent = track.artist;\n info.appendChild(artist);\n }\n \n item.appendChild(info);\n \n // Play icon\n const playIcon = createIconElement('play');\n playIcon.classList.add('vidply-playlist-item-icon');\n item.appendChild(playIcon);\n \n // Click handler\n item.addEventListener('click', () => {\n this.play(index);\n });\n \n // Keyboard handler\n item.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.play(index);\n }\n });\n \n return item;\n }\n \n /**\n * Update playlist UI (highlight current track)\n */\n updatePlaylistUI() {\n if (!this.playlistPanel) return;\n \n const items = this.playlistPanel.querySelectorAll('.vidply-playlist-item');\n \n items.forEach((item, index) => {\n if (index === this.currentIndex) {\n item.classList.add('vidply-playlist-item-active');\n \n // Scroll into view\n item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n } else {\n item.classList.remove('vidply-playlist-item-active');\n }\n });\n }\n \n /**\n * Get current track\n */\n getCurrentTrack() {\n return this.tracks[this.currentIndex] || null;\n }\n \n /**\n * Get playlist info\n */\n getPlaylistInfo() {\n return {\n currentIndex: this.currentIndex,\n totalTracks: this.tracks.length,\n currentTrack: this.getCurrentTrack(),\n hasNext: this.currentIndex < this.tracks.length - 1,\n hasPrevious: this.currentIndex > 0\n };\n }\n \n /**\n * Add track to playlist\n */\n addTrack(track) {\n this.tracks.push(track);\n \n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n }\n \n /**\n * Remove track from playlist\n */\n removeTrack(index) {\n if (index < 0 || index >= this.tracks.length) return;\n \n this.tracks.splice(index, 1);\n \n // Adjust current index if needed\n if (index < this.currentIndex) {\n this.currentIndex--;\n } else if (index === this.currentIndex) {\n // Current track was removed, play next or stop\n if (this.currentIndex >= this.tracks.length) {\n this.currentIndex = this.tracks.length - 1;\n }\n \n if (this.currentIndex >= 0) {\n this.play(this.currentIndex);\n }\n }\n \n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n }\n \n /**\n * Clear playlist\n */\n clear() {\n this.tracks = [];\n this.currentIndex = -1;\n \n if (this.playlistPanel) {\n this.playlistPanel.innerHTML = '';\n this.playlistPanel.style.display = 'none';\n }\n \n if (this.trackInfoElement) {\n this.trackInfoElement.innerHTML = '';\n this.trackInfoElement.style.display = 'none';\n }\n }\n \n /**\n * Destroy playlist manager\n */\n destroy() {\n // Remove event listeners\n this.player.off('ended', this.handleTrackEnd);\n this.player.off('error', this.handleTrackError);\n \n // Remove UI\n if (this.trackInfoElement) {\n this.trackInfoElement.remove();\n }\n \n if (this.playlistPanel) {\n this.playlistPanel.remove();\n }\n \n // Clear data\n this.clear();\n }\n}\n\nexport default PlaylistManager;\n", "/**\n * VidPly - Universal Video Player\n * Main Entry Point\n */\n\nimport { Player } from './core/Player.js';\nimport { PlaylistManager } from './features/PlaylistManager.js';\n\n// Auto-initialize players\nfunction initializePlayers() {\n const elements = document.querySelectorAll('[data-vidply]');\n \n elements.forEach(element => {\n // Parse options from data attribute (JSON format)\n const options = element.dataset.vidplyOptions \n ? JSON.parse(element.dataset.vidplyOptions)\n : {};\n \n // Parse individual data attributes and merge with options\n // This allows for easier HTML-based configuration\n const dataOptions = parseDataAttributes(element.dataset);\n const mergedOptions = { ...dataOptions, ...options };\n \n // Create player instance\n new Player(element, mergedOptions);\n });\n}\n\n// Helper function to parse data attributes into options\nfunction parseDataAttributes(dataset) {\n const options = {};\n \n // Map of data attribute names to option keys (camelCase conversion)\n const attributeMap = {\n // Sign Language\n 'signLanguageSrc': 'signLanguageSrc',\n 'signLanguageButton': 'signLanguageButton',\n 'signLanguagePosition': 'signLanguagePosition',\n \n // Audio Description\n 'audioDescriptionSrc': 'audioDescriptionSrc',\n 'audioDescriptionButton': 'audioDescriptionButton',\n \n // Other common options\n 'autoplay': 'autoplay',\n 'loop': 'loop',\n 'muted': 'muted',\n 'controls': 'controls',\n 'poster': 'poster',\n 'width': 'width',\n 'height': 'height',\n 'language': 'language',\n 'captions': 'captions',\n 'captionsDefault': 'captionsDefault',\n 'transcript': 'transcript',\n 'transcriptButton': 'transcriptButton',\n 'keyboard': 'keyboard',\n 'responsive': 'responsive',\n 'pipButton': 'pipButton',\n 'fullscreenButton': 'fullscreenButton'\n };\n \n // Parse each data attribute\n Object.keys(attributeMap).forEach(dataKey => {\n const optionKey = attributeMap[dataKey];\n const value = dataset[dataKey];\n \n if (value !== undefined) {\n // Convert string values to appropriate types\n if (value === 'true') {\n options[optionKey] = true;\n } else if (value === 'false') {\n options[optionKey] = false;\n } else if (!isNaN(value) && value !== '') {\n options[optionKey] = Number(value);\n } else {\n options[optionKey] = value;\n }\n }\n });\n \n return options;\n}\n\n// Auto-initialize on DOM ready\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initializePlayers);\n} else {\n initializePlayers();\n}\n\n// Export for manual initialization\nexport { Player, PlaylistManager };\nexport default Player;\n\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * HTML5 Media Renderer\n */\n\nexport class HTML5Renderer {\n constructor(player) {\n this.player = player;\n this.media = player.element;\n }\n\n async init() {\n // Hide native controls\n this.media.controls = false;\n this.media.removeAttribute('controls');\n \n this.attachEvents();\n \n // Set preload\n this.media.preload = this.player.options.preload;\n \n // Load media\n this.media.load();\n }\n\n attachEvents() {\n // Playback events\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n \n // Pause other players if enabled\n if (this.player.options.pauseOthersOnPlay) {\n this.pauseOtherPlayers();\n }\n });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n // Handle loop\n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n \n if (this.player.options.onVolumeChange) {\n this.player.options.onVolumeChange.call(this.player, this.media.volume);\n }\n });\n\n this.media.addEventListener('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n });\n\n this.media.addEventListener('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.media.addEventListener('progress', () => {\n if (this.media.buffered.length > 0) {\n const buffered = this.media.buffered.end(this.media.buffered.length - 1);\n this.player.emit('progress', buffered);\n }\n });\n\n this.media.addEventListener('error', (e) => {\n this.player.handleError(this.media.error);\n });\n\n this.media.addEventListener('ratechange', () => {\n this.player.state.playbackSpeed = this.media.playbackRate;\n this.player.emit('ratechange', this.media.playbackRate);\n });\n }\n\n pauseOtherPlayers() {\n // Pause other VidPly instances\n const allPlayers = document.querySelectorAll('.vidply-player');\n allPlayers.forEach(playerEl => {\n if (playerEl !== this.player.container) {\n const video = playerEl.querySelector('video, audio');\n if (video && !video.paused) {\n video.pause();\n }\n }\n });\n }\n\n play() {\n const promise = this.media.play();\n \n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n \n // If autoplay failed, try muted autoplay\n if (this.player.options.autoplay && !this.player.state.muted) {\n this.player.log('Retrying play with muted audio', 'info');\n this.media.muted = true;\n this.media.play().catch(err => {\n this.player.handleError(err);\n });\n }\n });\n }\n }\n\n pause() {\n this.media.pause();\n }\n\n seek(time) {\n this.media.currentTime = time;\n }\n\n setVolume(volume) {\n this.media.volume = volume;\n }\n\n setMuted(muted) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed) {\n this.media.playbackRate = speed;\n }\n\n /**\n * Get available quality levels from source elements\n * @returns {Array} Array of quality objects with index, height, width, and src\n */\n getQualities() {\n const sources = Array.from(this.media.querySelectorAll('source'));\n \n if (sources.length <= 1) {\n return [];\n }\n\n return sources.map((source, index) => {\n // Try to extract quality from data attributes or label\n const label = source.getAttribute('data-quality') || source.getAttribute('label') || '';\n const height = source.getAttribute('data-height') || this.extractHeightFromLabel(label);\n const width = source.getAttribute('data-width') || '';\n \n return {\n index,\n height: height ? parseInt(height) : 0,\n width: width ? parseInt(width) : 0,\n src: source.src,\n type: source.type,\n name: label || (height ? `${height}p` : `Quality ${index + 1}`)\n };\n }).filter(q => q.height > 0); // Only return qualities with valid height\n }\n\n /**\n * Extract height from quality label (e.g., \"1080p\" -> 1080)\n * @param {string} label \n * @returns {number}\n */\n extractHeightFromLabel(label) {\n const match = label.match(/(\\d+)p/i);\n return match ? parseInt(match[1]) : 0;\n }\n\n /**\n * Switch to a specific quality level\n * @param {number} qualityIndex - Index of the quality level (-1 for auto, not applicable for HTML5)\n */\n switchQuality(qualityIndex) {\n const qualities = this.getQualities();\n \n if (qualityIndex < 0 || qualityIndex >= qualities.length) {\n this.player.log('Invalid quality index', 'warn');\n return;\n }\n\n const quality = qualities[qualityIndex];\n const currentTime = this.media.currentTime;\n const wasPlaying = !this.media.paused;\n\n // Store the current source for comparison\n const currentSrc = this.media.currentSrc;\n \n // Don't switch if already at this quality\n if (currentSrc === quality.src) {\n this.player.log('Already at this quality level', 'info');\n return;\n }\n\n this.player.log(`Switching to quality: ${quality.name}`, 'info');\n\n // Update the src\n this.media.src = quality.src;\n \n // Wait for the new source to load, then restore playback state\n const onLoadedMetadata = () => {\n this.media.removeEventListener('loadedmetadata', onLoadedMetadata);\n \n // Restore playback position\n this.media.currentTime = currentTime;\n \n // Resume playback if it was playing\n if (wasPlaying) {\n this.media.play().catch(err => {\n this.player.log('Failed to resume playback after quality switch', 'warn');\n });\n }\n \n // Emit quality change event\n this.player.emit('qualitychange', { quality: quality.name, index: qualityIndex });\n };\n\n this.media.addEventListener('loadedmetadata', onLoadedMetadata);\n this.media.load();\n }\n\n /**\n * Get current quality index\n * @returns {number}\n */\n getCurrentQuality() {\n const qualities = this.getQualities();\n const currentSrc = this.media.currentSrc;\n \n for (let i = 0; i < qualities.length; i++) {\n if (qualities[i].src === currentSrc) {\n return i;\n }\n }\n \n return 0; // Default to first quality if not found\n }\n\n destroy() {\n // Remove event listeners\n this.media.removeEventListener('loadedmetadata', () => {});\n this.media.removeEventListener('play', () => {});\n this.media.removeEventListener('pause', () => {});\n // ... (other listeners would be removed in a real implementation)\n }\n}\n\n", "/**\n * Simple EventEmitter implementation\n */\n\nexport class EventEmitter {\n constructor() {\n this.events = {};\n }\n\n on(event, listener) {\n if (!this.events[event]) {\n this.events[event] = [];\n }\n this.events[event].push(listener);\n return this;\n }\n\n once(event, listener) {\n const onceListener = (...args) => {\n listener(...args);\n this.off(event, onceListener);\n };\n return this.on(event, onceListener);\n }\n\n off(event, listener) {\n if (!this.events[event]) return this;\n \n if (!listener) {\n delete this.events[event];\n } else {\n this.events[event] = this.events[event].filter(l => l !== listener);\n }\n \n return this;\n }\n\n emit(event, ...args) {\n if (!this.events[event]) return this;\n \n this.events[event].forEach(listener => {\n listener(...args);\n });\n \n return this;\n }\n\n removeAllListeners() {\n this.events = {};\n return this;\n }\n}\n\n", "/**\n * DOM manipulation utilities\n */\n\nexport const DOMUtils = {\n createElement(tag, options = {}) {\n const element = document.createElement(tag);\n \n if (options.className) {\n element.className = options.className;\n }\n \n if (options.attributes) {\n Object.entries(options.attributes).forEach(([key, value]) => {\n element.setAttribute(key, value);\n });\n }\n \n if (options.innerHTML) {\n element.innerHTML = options.innerHTML;\n }\n \n if (options.textContent) {\n element.textContent = options.textContent;\n }\n \n if (options.style) {\n Object.assign(element.style, options.style);\n }\n \n if (options.children) {\n options.children.forEach(child => {\n if (child) element.appendChild(child);\n });\n }\n \n return element;\n },\n\n addClass(element, className) {\n if (element && className) {\n element.classList.add(className);\n }\n },\n\n removeClass(element, className) {\n if (element && className) {\n element.classList.remove(className);\n }\n },\n\n toggleClass(element, className) {\n if (element && className) {\n element.classList.toggle(className);\n }\n },\n\n hasClass(element, className) {\n return element && element.classList.contains(className);\n },\n\n show(element) {\n if (element) {\n element.style.display = '';\n }\n },\n\n hide(element) {\n if (element) {\n element.style.display = 'none';\n }\n },\n\n fadeIn(element, duration = 300) {\n if (!element) return;\n \n element.style.opacity = '0';\n element.style.display = '';\n \n let start = null;\n const animate = (timestamp) => {\n if (!start) start = timestamp;\n const progress = timestamp - start;\n const opacity = Math.min(progress / duration, 1);\n \n element.style.opacity = opacity;\n \n if (progress < duration) {\n requestAnimationFrame(animate);\n }\n };\n \n requestAnimationFrame(animate);\n },\n\n fadeOut(element, duration = 300) {\n if (!element) return;\n \n const startOpacity = parseFloat(getComputedStyle(element).opacity) || 1;\n let start = null;\n \n const animate = (timestamp) => {\n if (!start) start = timestamp;\n const progress = timestamp - start;\n const opacity = Math.max(startOpacity - (progress / duration), 0);\n \n element.style.opacity = opacity;\n \n if (progress < duration) {\n requestAnimationFrame(animate);\n } else {\n element.style.display = 'none';\n }\n };\n \n requestAnimationFrame(animate);\n },\n\n offset(element) {\n if (!element) return { top: 0, left: 0 };\n \n const rect = element.getBoundingClientRect();\n return {\n top: rect.top + window.pageYOffset,\n left: rect.left + window.pageXOffset,\n width: rect.width,\n height: rect.height\n };\n },\n\n escapeHTML(str) {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n },\n\n sanitizeHTML(html) {\n // Basic HTML sanitization - allow safe tags for VTT captions\n // Since we control the HTML (from VTT parsing), we can safely allow these tags\n const temp = document.createElement('div');\n \n // Strip out any potentially dangerous tags/attributes\n // Allow: strong, em, u, span, b, i with class and data-voice attributes\n const safeHtml = html\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\n .replace(/<iframe\\b[^<]*(?:(?!<\\/iframe>)<[^<]*)*<\\/iframe>/gi, '')\n .replace(/on\\w+\\s*=/gi, '') // Remove event handlers\n .replace(/javascript:/gi, ''); // Remove javascript: protocol\n \n temp.innerHTML = safeHtml;\n return temp.innerHTML;\n }\n};\n\n", "/**\n * Time formatting and conversion utilities\n */\n\nexport const TimeUtils = {\n /**\n * Format seconds to time string (HH:MM:SS or MM:SS)\n */\n formatTime(seconds, alwaysShowHours = false) {\n if (!isFinite(seconds) || seconds < 0) {\n return alwaysShowHours ? '00:00:00' : '00:00';\n }\n \n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n \n const pad = (num) => String(num).padStart(2, '0');\n \n if (hours > 0 || alwaysShowHours) {\n return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;\n }\n \n return `${pad(minutes)}:${pad(secs)}`;\n },\n\n /**\n * Parse time string to seconds\n */\n parseTime(timeString) {\n const parts = timeString.split(':').map(p => parseInt(p, 10));\n \n if (parts.length === 3) {\n // HH:MM:SS\n return parts[0] * 3600 + parts[1] * 60 + parts[2];\n } else if (parts.length === 2) {\n // MM:SS\n return parts[0] * 60 + parts[1];\n } else if (parts.length === 1) {\n // SS\n return parts[0];\n }\n \n return 0;\n },\n\n /**\n * Format seconds to readable duration\n */\n formatDuration(seconds) {\n if (!isFinite(seconds) || seconds < 0) {\n return '0 seconds';\n }\n \n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const secs = Math.floor(seconds % 60);\n \n const parts = [];\n \n if (hours > 0) {\n parts.push(`${hours} hour${hours !== 1 ? 's' : ''}`);\n }\n if (minutes > 0) {\n parts.push(`${minutes} minute${minutes !== 1 ? 's' : ''}`);\n }\n if (secs > 0 || parts.length === 0) {\n parts.push(`${secs} second${secs !== 1 ? 's' : ''}`);\n }\n \n return parts.join(', ');\n },\n\n /**\n * Format percentage\n */\n formatPercentage(value, total) {\n if (total === 0) return 0;\n return Math.round((value / total) * 100);\n }\n};\n\n", "/**\n * SVG Icon Library for VidPly\n * Optimized with common viewBox and fill attributes\n */\n\n// SVG paths only (viewBox and fill added by wrapper)\nconst iconPaths = {\n play: `<path d=\"M8 5v14l11-7z\"/>`,\n\n pause: `<path d=\"M6 4h4v16H6V4zm8 0h4v16h-4V4z\"/>`,\n\n stop: `<rect x=\"6\" y=\"6\" width=\"12\" height=\"12\"/>`,\n\n rewind: `<path d=\"M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z\"/>`,\n\n forward: `<path d=\"M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z\"/>`,\n\n skipPrevious: `<path d=\"M6 6h2v12H6V6zm3 6l8.5 6V6L9 12z\"/>`,\n\n skipNext: `<path d=\"M16 6h2v12h-2V6zM6 6l8.5 6L6 18V6z\"/>`,\n\n restart: `<path d=\"M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z\"/>`,\n\n volumeHigh: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\"/>`,\n\n volumeMedium: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"/>`,\n\n volumeLow: `<path d=\"M7 9v6h4l5 5V4l-5 5H7z\"/>`,\n\n volumeMuted: `<path d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\"/>`,\n\n fullscreen: `<path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"/>`,\n\n fullscreenExit: `<path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"/>`,\n\n settings: `<path d=\"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94L14.4 2.81c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z\"/>`,\n\n captions: `<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\"/>`,\n\n captionsOff: `<path d=\"M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 7H9.5v-.5h-2v3h2V13H11v1c0 .55-.45 1-1 1H7c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1zm7 0h-1.5v-.5h-2v3h2V13H18v1c0 .55-.45 1-1 1h-3c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v1z\"/><path d=\"M0 0h24v24H0z\" fill=\"none\"/>`,\n\n pip: `<path d=\"M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z\"/>`,\n\n speed: `<path d=\"M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44z\"/><path d=\"M10.59 15.41a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z\"/>`,\n\n close: `<path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/>`,\n\n check: `<path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/>`,\n\n arrowUp: `<path d=\"M7 14l5-5 5 5z\"/>`,\n\n arrowDown: `<path d=\"M7 10l5 5 5-5z\"/>`,\n\n arrowLeft: `<path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/>`,\n\n arrowRight: `<path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/>`,\n\n loading: `<path d=\"M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z\"/>`,\n\n error: `<path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/>`,\n\n download: `<path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"/>`,\n\n link: `<path d=\"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\"/>`,\n\n playlist: `<path d=\"M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z\"/>`,\n\n language: `<path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.91 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z\"/>`,\n\n hd: `<path d=\"M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-8 12H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z\"/>`,\n\n transcript: `<path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\"/>`,\n\n audioDescription: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z\"/><path d=\"M10.5 19c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/>`,\n\n audioDescriptionOn: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7z\"/><path d=\"M10.5 19c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/><circle cx=\"19\" cy=\"16\" r=\"3\" fill=\"#3b82f6\"/><path d=\"M18.5 17.5l1-1 1.5 1.5\" stroke=\"white\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n\n signLanguage: `<g transform=\"scale(1.5)\"><path d=\"M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z\"/></g>`,\n\n signLanguageOn: `<g transform=\"scale(1.5)\"><path d=\"M16 11.3c-.1-.9-4.8 1.3-5.4 1.1-2.6-1 5.8-1.3 5.1-2.9s-5.1 1.5-6 1.4C6.5 9.4 16.5 9.1 13.5 8c-1.9-.6-8.8 2.9-6.8.4.7-.6.7-1.9-.7-1.7-9.7 7.2-.7 12.2 8.8 7 0-1.3-3.5.4-4.1.4-2.6 0 5.6-2 5.4-3ZM3.9 7.8c3.2-4.2 3.7 1.2 6 .1s.2-.2.2-.3c.7-2.7 2.5-7.5-1.5-1.3-1.6 0 1.1-4 1-4.6C8.9-1 7.3 4.4 7.2 4.9c-1.6.7-.9-1.4-.7-1.5 3-6-.6-3.1-.9.4-2.5 1.8 0-2.8 0-3.5C2.8-.9 4 9.4 1.1 4.9S.1 4.6 0 5c-.4 2.7 2.6 7.2 3.9 2.8Z\"/></g>`,\n\n speaker: `<path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z\"/>`,\n\n music: `<path d=\"M12 3v9.28c-.47-.17-.97-.28-1.5-.28C8.01 12 6 14.01 6 16.5S8.01 21 10.5 21c2.31 0 4.2-1.75 4.45-4H15V6h4V3h-7zm-1.5 16c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\"/>`,\n\n moreVertical: `<path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>`,\n\n moreHorizontal: `<path d=\"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>`\n};\n\n// Optimized wrapper that adds common SVG attributes\nconst svgWrapper = (paths) => `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\">${paths}</svg>`;\n\n// Export Icons object with SVG wrappers\nexport const Icons = Object.fromEntries(\n Object.entries(iconPaths).map(([key, value]) => [key, svgWrapper(value)])\n);\n\nexport function getIcon(name) {\n return Icons[name] || Icons.play;\n}\n\nexport function createIconElement(name, className = '') {\n const wrapper = document.createElement('span');\n wrapper.className = `vidply-icon ${className}`.trim();\n wrapper.innerHTML = getIcon(name);\n wrapper.setAttribute('aria-hidden', 'true');\n return wrapper;\n}\n\n/**\n * Create the large centered play button overlay (complete SVG)\n * @returns {SVGElement} Complete SVG element with circle background and play icon\n */\nexport function createPlayOverlay() {\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.setAttribute('class', 'vidply-play-overlay');\n svg.setAttribute('viewBox', '0 0 80 80');\n svg.setAttribute('width', '80');\n svg.setAttribute('height', '80');\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('role', 'presentation');\n svg.style.cursor = 'pointer';\n\n // Create filter for drop shadow\n const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n const filterId = `vidply-play-shadow-${Math.random().toString(36).substr(2, 9)}`;\n const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');\n filter.setAttribute('id', filterId);\n filter.setAttribute('x', '-50%');\n filter.setAttribute('y', '-50%');\n filter.setAttribute('width', '200%');\n filter.setAttribute('height', '200%');\n\n const feGaussianBlur = document.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');\n feGaussianBlur.setAttribute('in', 'SourceAlpha');\n feGaussianBlur.setAttribute('stdDeviation', '3');\n\n const feOffset = document.createElementNS('http://www.w3.org/2000/svg', 'feOffset');\n feOffset.setAttribute('dx', '0');\n feOffset.setAttribute('dy', '2');\n feOffset.setAttribute('result', 'offsetblur');\n\n const feComponentTransfer = document.createElementNS('http://www.w3.org/2000/svg', 'feComponentTransfer');\n const feFuncA = document.createElementNS('http://www.w3.org/2000/svg', 'feFuncA');\n feFuncA.setAttribute('type', 'linear');\n feFuncA.setAttribute('slope', '0.3');\n feComponentTransfer.appendChild(feFuncA);\n\n const feMerge = document.createElementNS('http://www.w3.org/2000/svg', 'feMerge');\n const feMergeNode1 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\n const feMergeNode2 = document.createElementNS('http://www.w3.org/2000/svg', 'feMergeNode');\n feMergeNode2.setAttribute('in', 'SourceGraphic');\n feMerge.appendChild(feMergeNode1);\n feMerge.appendChild(feMergeNode2);\n\n filter.appendChild(feGaussianBlur);\n filter.appendChild(feOffset);\n filter.appendChild(feComponentTransfer);\n filter.appendChild(feMerge);\n defs.appendChild(filter);\n svg.appendChild(defs);\n\n // White circle background\n const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n circle.setAttribute('cx', '40');\n circle.setAttribute('cy', '40');\n circle.setAttribute('r', '40');\n circle.setAttribute('fill', 'rgba(255, 255, 255, 0.95)');\n circle.setAttribute('filter', `url(#${filterId})`);\n circle.setAttribute('class', 'vidply-play-overlay-bg');\n svg.appendChild(circle);\n\n // Play icon triangle (centered with optical adjustment)\n const playTriangle = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');\n playTriangle.setAttribute('points', '32,28 32,52 54,40');\n playTriangle.setAttribute('fill', '#0a406e');\n playTriangle.setAttribute('class', 'vidply-play-overlay-icon');\n svg.appendChild(playTriangle);\n\n return svg;\n}\n\n", "/**\n * Translation strings for VidPly\n */\n\nexport const translations = {\n en: {\n player: {\n label: 'Video Player',\n play: 'Play',\n pause: 'Pause',\n stop: 'Stop',\n restart: 'Restart from beginning',\n rewind: 'Rewind',\n forward: 'Forward',\n rewindSeconds: 'Rewind {seconds} seconds',\n forwardSeconds: 'Forward {seconds} seconds',\n previous: 'Previous track',\n next: 'Next track',\n volume: 'Volume',\n mute: 'Mute',\n unmute: 'Unmute',\n fullscreen: 'Fullscreen',\n exitFullscreen: 'Exit Fullscreen',\n captions: 'Captions',\n chapters: 'Chapters',\n quality: 'Quality',\n captionStyling: 'Caption styling',\n transcript: 'Toggle transcript',\n audioDescription: 'Audio description',\n signLanguage: 'Sign language video',\n settings: 'Settings',\n speed: 'Playback Speed',\n pip: 'Picture in Picture',\n currentTime: 'Current time',\n duration: 'Duration',\n progress: 'Progress',\n seekForward: 'Seek forward {seconds} seconds',\n seekBackward: 'Seek backward {seconds} seconds',\n volumeUp: 'Volume up',\n volumeDown: 'Volume down',\n loading: 'Loading...',\n loadingChapters: 'Loading chapters...',\n error: 'Error loading media',\n buffering: 'Buffering...',\n signLanguageVideo: 'Sign Language Video',\n noChapters: 'No chapters available',\n noCaptions: 'No captions available',\n auto: 'Auto',\n autoQuality: 'Auto (no quality selection available)',\n noQuality: 'Quality selection not available'\n },\n captions: {\n off: 'Off',\n select: 'Select captions',\n fontSize: 'Font Size',\n fontFamily: 'Font Family',\n color: 'Text Color',\n backgroundColor: 'Background Color',\n opacity: 'Opacity'\n },\n fontSizes: {\n small: 'Small',\n medium: 'Medium',\n large: 'Large',\n xlarge: 'X-Large'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Text Color',\n background: 'Background',\n font: 'Font',\n fontSize: 'Font Size',\n opacity: 'Opacity'\n },\n audioDescription: {\n enable: 'Enable audio description',\n disable: 'Disable audio description'\n },\n signLanguage: {\n show: 'Show sign language video',\n hide: 'Hide sign language video'\n },\n transcript: {\n title: 'Transcript',\n close: 'Close transcript',\n loading: 'Loading transcript...',\n noTranscript: 'No transcript available for this video.'\n },\n settings: {\n title: 'Settings',\n quality: 'Quality',\n speed: 'Speed',\n captions: 'Captions',\n language: 'Language',\n reset: 'Reset to defaults',\n close: 'Close'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n \n de: {\n player: {\n label: 'Videoplayer',\n play: 'Abspielen',\n pause: 'Pause',\n stop: 'Stopp',\n restart: 'Von vorne beginnen',\n rewind: 'Zur\u00FCckspulen',\n forward: 'Vorspulen',\n rewindSeconds: '{seconds} Sekunden zur\u00FCckspulen',\n forwardSeconds: '{seconds} Sekunden vorspulen',\n previous: 'Vorheriger Titel',\n next: 'N\u00E4chster Titel',\n volume: 'Lautst\u00E4rke',\n mute: 'Stumm',\n unmute: 'Ton ein',\n fullscreen: 'Vollbild',\n exitFullscreen: 'Vollbild beenden',\n captions: 'Untertitel',\n chapters: 'Kapitel',\n quality: 'Qualit\u00E4t',\n captionStyling: 'Untertitel-Stil',\n transcript: 'Transkript umschalten',\n audioDescription: 'Audiodeskription',\n signLanguage: 'Geb\u00E4rdensprache-Video',\n settings: 'Einstellungen',\n speed: 'Wiedergabegeschwindigkeit',\n pip: 'Bild-in-Bild',\n currentTime: 'Aktuelle Zeit',\n duration: 'Dauer',\n progress: 'Fortschritt',\n seekForward: '{seconds} Sekunden vorspulen',\n seekBackward: '{seconds} Sekunden zur\u00FCckspulen',\n volumeUp: 'Lauter',\n volumeDown: 'Leiser',\n loading: 'L\u00E4dt...',\n loadingChapters: 'Kapitel werden geladen...',\n error: 'Fehler beim Laden',\n buffering: 'Puffern...',\n signLanguageVideo: 'Geb\u00E4rdensprache-Video',\n noChapters: 'Keine Kapitel verf\u00FCgbar',\n noCaptions: 'Keine Untertitel verf\u00FCgbar',\n auto: 'Automatisch',\n autoQuality: 'Automatisch (keine Qualit\u00E4tsauswahl verf\u00FCgbar)',\n noQuality: 'Qualit\u00E4tsauswahl nicht verf\u00FCgbar'\n },\n captions: {\n off: 'Aus',\n select: 'Untertitel ausw\u00E4hlen',\n fontSize: 'Schriftgr\u00F6\u00DFe',\n fontFamily: 'Schriftart',\n color: 'Textfarbe',\n backgroundColor: 'Hintergrundfarbe',\n opacity: 'Deckkraft'\n },\n fontSizes: {\n small: 'Klein',\n medium: 'Mittel',\n large: 'Gro\u00DF',\n xlarge: 'Sehr gro\u00DF'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Textfarbe',\n background: 'Hintergrund',\n font: 'Schrift',\n fontSize: 'Schriftgr\u00F6\u00DFe',\n opacity: 'Deckkraft'\n },\n audioDescription: {\n enable: 'Audiodeskription aktivieren',\n disable: 'Audiodeskription deaktivieren'\n },\n signLanguage: {\n show: 'Geb\u00E4rdensprache-Video anzeigen',\n hide: 'Geb\u00E4rdensprache-Video ausblenden'\n },\n transcript: {\n title: 'Transkript',\n close: 'Transkript schlie\u00DFen',\n loading: 'Transkript wird geladen...',\n noTranscript: 'Kein Transkript f\u00FCr dieses Video verf\u00FCgbar.'\n },\n settings: {\n title: 'Einstellungen',\n quality: 'Qualit\u00E4t',\n speed: 'Geschwindigkeit',\n captions: 'Untertitel',\n language: 'Sprache',\n reset: 'Zur\u00FCcksetzen',\n close: 'Schlie\u00DFen'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n es: {\n player: {\n label: 'Reproductor de video',\n play: 'Reproducir',\n pause: 'Pausa',\n stop: 'Detener',\n restart: 'Reiniciar desde el principio',\n rewind: 'Retroceder',\n forward: 'Avanzar',\n rewindSeconds: 'Retroceder {seconds} segundos',\n forwardSeconds: 'Avanzar {seconds} segundos',\n previous: 'Pista anterior',\n next: 'Siguiente pista',\n volume: 'Volumen',\n mute: 'Silenciar',\n unmute: 'Activar sonido',\n fullscreen: 'Pantalla completa',\n exitFullscreen: 'Salir de pantalla completa',\n captions: 'Subt\u00EDtulos',\n chapters: 'Cap\u00EDtulos',\n quality: 'Calidad',\n captionStyling: 'Estilo de subt\u00EDtulos',\n transcript: 'Alternar transcripci\u00F3n',\n audioDescription: 'Audiodescripci\u00F3n',\n signLanguage: 'Video en lengua de se\u00F1as',\n settings: 'Configuraci\u00F3n',\n speed: 'Velocidad de reproducci\u00F3n',\n pip: 'Imagen en imagen',\n currentTime: 'Tiempo actual',\n duration: 'Duraci\u00F3n',\n progress: 'Progreso',\n seekForward: 'Avanzar {seconds} segundos',\n seekBackward: 'Retroceder {seconds} segundos',\n volumeUp: 'Subir volumen',\n volumeDown: 'Bajar volumen',\n loading: 'Cargando...',\n loadingChapters: 'Cargando cap\u00EDtulos...',\n error: 'Error al cargar',\n buffering: 'Almacenando en b\u00FAfer...',\n signLanguageVideo: 'Video en Lengua de Se\u00F1as',\n noChapters: 'No hay cap\u00EDtulos disponibles',\n noCaptions: 'No hay subt\u00EDtulos disponibles',\n auto: 'Autom\u00E1tico',\n autoQuality: 'Autom\u00E1tico (selecci\u00F3n de calidad no disponible)',\n noQuality: 'Selecci\u00F3n de calidad no disponible'\n },\n captions: {\n off: 'Desactivado',\n select: 'Seleccionar subt\u00EDtulos',\n fontSize: 'Tama\u00F1o de fuente',\n fontFamily: 'Familia de fuente',\n color: 'Color de texto',\n backgroundColor: 'Color de fondo',\n opacity: 'Opacidad'\n },\n fontSizes: {\n small: 'Peque\u00F1o',\n medium: 'Mediano',\n large: 'Grande',\n xlarge: 'Muy grande'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Color de texto',\n background: 'Fondo',\n font: 'Fuente',\n fontSize: 'Tama\u00F1o de fuente',\n opacity: 'Opacidad'\n },\n audioDescription: {\n enable: 'Activar audiodescripci\u00F3n',\n disable: 'Desactivar audiodescripci\u00F3n'\n },\n signLanguage: {\n show: 'Mostrar video en lengua de se\u00F1as',\n hide: 'Ocultar video en lengua de se\u00F1as'\n },\n transcript: {\n title: 'Transcripci\u00F3n',\n close: 'Cerrar transcripci\u00F3n',\n loading: 'Cargando transcripci\u00F3n...',\n noTranscript: 'No hay transcripci\u00F3n disponible para este video.'\n },\n settings: {\n title: 'Configuraci\u00F3n',\n quality: 'Calidad',\n speed: 'Velocidad',\n captions: 'Subt\u00EDtulos',\n language: 'Idioma',\n reset: 'Restablecer',\n close: 'Cerrar'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n fr: {\n player: {\n label: 'Lecteur vid\u00E9o',\n play: 'Lecture',\n pause: 'Pause',\n stop: 'Arr\u00EAt',\n restart: 'Red\u00E9marrer du d\u00E9but',\n rewind: 'Reculer',\n forward: 'Avancer',\n rewindSeconds: 'Reculer de {seconds} secondes',\n forwardSeconds: 'Avancer de {seconds} secondes',\n previous: 'Piste pr\u00E9c\u00E9dente',\n next: 'Piste suivante',\n volume: 'Volume',\n mute: 'Muet',\n unmute: 'Activer le son',\n fullscreen: 'Plein \u00E9cran',\n exitFullscreen: 'Quitter le plein \u00E9cran',\n captions: 'Sous-titres',\n chapters: 'Chapitres',\n quality: 'Qualit\u00E9',\n captionStyling: 'Style des sous-titres',\n transcript: 'Activer/d\u00E9sactiver la transcription',\n audioDescription: 'Audiodescription',\n signLanguage: 'Vid\u00E9o en langue des signes',\n settings: 'Param\u00E8tres',\n speed: 'Vitesse de lecture',\n pip: 'Image dans l\\'image',\n currentTime: 'Temps actuel',\n duration: 'Dur\u00E9e',\n progress: 'Progression',\n seekForward: 'Avancer de {seconds} secondes',\n seekBackward: 'Reculer de {seconds} secondes',\n volumeUp: 'Augmenter le volume',\n volumeDown: 'Diminuer le volume',\n loading: 'Chargement...',\n loadingChapters: 'Chargement des chapitres...',\n error: 'Erreur de chargement',\n buffering: 'Mise en m\u00E9moire tampon...',\n signLanguageVideo: 'Vid\u00E9o en Langue des Signes',\n noChapters: 'Aucun chapitre disponible',\n noCaptions: 'Aucun sous-titre disponible',\n auto: 'Automatique',\n autoQuality: 'Automatique (s\u00E9lection de qualit\u00E9 non disponible)',\n noQuality: 'S\u00E9lection de qualit\u00E9 non disponible'\n },\n captions: {\n off: 'D\u00E9sactiv\u00E9',\n select: 'S\u00E9lectionner les sous-titres',\n fontSize: 'Taille de police',\n fontFamily: 'Police',\n color: 'Couleur du texte',\n backgroundColor: 'Couleur de fond',\n opacity: 'Opacit\u00E9'\n },\n fontSizes: {\n small: 'Petit',\n medium: 'Moyen',\n large: 'Grand',\n xlarge: 'Tr\u00E8s grand'\n },\n fontFamilies: {\n sansSerif: 'Sans-serif',\n serif: 'Serif',\n monospace: 'Monospace'\n },\n styleLabels: {\n textColor: 'Couleur du texte',\n background: 'Arri\u00E8re-plan',\n font: 'Police',\n fontSize: 'Taille de police',\n opacity: 'Opacit\u00E9'\n },\n audioDescription: {\n enable: 'Activer l\\'audiodescription',\n disable: 'D\u00E9sactiver l\\'audiodescription'\n },\n signLanguage: {\n show: 'Afficher la vid\u00E9o en langue des signes',\n hide: 'Masquer la vid\u00E9o en langue des signes'\n },\n transcript: {\n title: 'Transcription',\n close: 'Fermer la transcription',\n loading: 'Chargement de la transcription...',\n noTranscript: 'Aucune transcription disponible pour cette vid\u00E9o.'\n },\n settings: {\n title: 'Param\u00E8tres',\n quality: 'Qualit\u00E9',\n speed: 'Vitesse',\n captions: 'Sous-titres',\n language: 'Langue',\n reset: 'R\u00E9initialiser',\n close: 'Fermer'\n },\n speeds: {\n normal: 'Normal'\n }\n },\n\n ja: {\n player: {\n label: '\u30D3\u30C7\u30AA\u30D7\u30EC\u30FC\u30E4\u30FC',\n play: '\u518D\u751F',\n pause: '\u4E00\u6642\u505C\u6B62',\n stop: '\u505C\u6B62',\n restart: '\u6700\u521D\u304B\u3089\u518D\u751F',\n rewind: '\u5DFB\u304D\u623B\u3057',\n forward: '\u65E9\u9001\u308A',\n rewindSeconds: '{seconds}\u79D2\u623B\u3059',\n forwardSeconds: '{seconds}\u79D2\u9032\u3081\u308B',\n previous: '\u524D\u306E\u30C8\u30E9\u30C3\u30AF',\n next: '\u6B21\u306E\u30C8\u30E9\u30C3\u30AF',\n volume: '\u97F3\u91CF',\n mute: '\u30DF\u30E5\u30FC\u30C8',\n unmute: '\u30DF\u30E5\u30FC\u30C8\u89E3\u9664',\n fullscreen: '\u5168\u753B\u9762\u8868\u793A',\n exitFullscreen: '\u5168\u753B\u9762\u8868\u793A\u3092\u7D42\u4E86',\n captions: '\u5B57\u5E55',\n chapters: '\u30C1\u30E3\u30D7\u30BF\u30FC',\n quality: '\u753B\u8CEA',\n captionStyling: '\u5B57\u5E55\u30B9\u30BF\u30A4\u30EB',\n transcript: '\u6587\u5B57\u8D77\u3053\u3057\u5207\u308A\u66FF\u3048',\n audioDescription: '\u97F3\u58F0\u89E3\u8AAC',\n signLanguage: '\u624B\u8A71\u52D5\u753B',\n settings: '\u8A2D\u5B9A',\n speed: '\u518D\u751F\u901F\u5EA6',\n pip: '\u30D4\u30AF\u30C1\u30E3\u30FC\u30A4\u30F3\u30D4\u30AF\u30C1\u30E3\u30FC',\n currentTime: '\u73FE\u5728\u306E\u6642\u9593',\n duration: '\u518D\u751F\u6642\u9593',\n progress: '\u9032\u884C\u72B6\u6CC1',\n seekForward: '{seconds}\u79D2\u9032\u3081\u308B',\n seekBackward: '{seconds}\u79D2\u623B\u3059',\n volumeUp: '\u97F3\u91CF\u3092\u4E0A\u3052\u308B',\n volumeDown: '\u97F3\u91CF\u3092\u4E0B\u3052\u308B',\n loading: '\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n loadingChapters: '\u30C1\u30E3\u30D7\u30BF\u30FC\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n error: '\u8AAD\u307F\u8FBC\u307F\u30A8\u30E9\u30FC',\n buffering: '\u30D0\u30C3\u30D5\u30A1\u30EA\u30F3\u30B0\u4E2D...',\n signLanguageVideo: '\u624B\u8A71\u52D5\u753B',\n noChapters: '\u30C1\u30E3\u30D7\u30BF\u30FC\u304C\u3042\u308A\u307E\u305B\u3093',\n noCaptions: '\u5B57\u5E55\u304C\u3042\u308A\u307E\u305B\u3093',\n auto: '\u81EA\u52D5',\n autoQuality: '\u81EA\u52D5\uFF08\u753B\u8CEA\u9078\u629E\u4E0D\u53EF\uFF09',\n noQuality: '\u753B\u8CEA\u9078\u629E\u4E0D\u53EF'\n },\n captions: {\n off: '\u30AA\u30D5',\n select: '\u5B57\u5E55\u3092\u9078\u629E',\n fontSize: '\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA',\n fontFamily: '\u30D5\u30A9\u30F3\u30C8',\n color: '\u30C6\u30AD\u30B9\u30C8\u306E\u8272',\n backgroundColor: '\u80CC\u666F\u8272',\n opacity: '\u4E0D\u900F\u660E\u5EA6'\n },\n fontSizes: {\n small: '\u5C0F',\n medium: '\u4E2D',\n large: '\u5927',\n xlarge: '\u7279\u5927'\n },\n fontFamilies: {\n sansSerif: '\u30B5\u30F3\u30BB\u30EA\u30D5',\n serif: '\u30BB\u30EA\u30D5',\n monospace: '\u7B49\u5E45'\n },\n styleLabels: {\n textColor: '\u30C6\u30AD\u30B9\u30C8\u306E\u8272',\n background: '\u80CC\u666F',\n font: '\u30D5\u30A9\u30F3\u30C8',\n fontSize: '\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA',\n opacity: '\u4E0D\u900F\u660E\u5EA6'\n },\n audioDescription: {\n enable: '\u97F3\u58F0\u89E3\u8AAC\u3092\u6709\u52B9\u306B\u3059\u308B',\n disable: '\u97F3\u58F0\u89E3\u8AAC\u3092\u7121\u52B9\u306B\u3059\u308B'\n },\n signLanguage: {\n show: '\u624B\u8A71\u52D5\u753B\u3092\u8868\u793A',\n hide: '\u624B\u8A71\u52D5\u753B\u3092\u975E\u8868\u793A'\n },\n transcript: {\n title: '\u6587\u5B57\u8D77\u3053\u3057',\n close: '\u6587\u5B57\u8D77\u3053\u3057\u3092\u9589\u3058\u308B',\n loading: '\u6587\u5B57\u8D77\u3053\u3057\u3092\u8AAD\u307F\u8FBC\u307F\u4E2D...',\n noTranscript: '\u3053\u306E\u30D3\u30C7\u30AA\u306E\u6587\u5B57\u8D77\u3053\u3057\u306F\u3042\u308A\u307E\u305B\u3093\u3002'\n },\n settings: {\n title: '\u8A2D\u5B9A',\n quality: '\u753B\u8CEA',\n speed: '\u901F\u5EA6',\n captions: '\u5B57\u5E55',\n language: '\u8A00\u8A9E',\n reset: '\u30EA\u30BB\u30C3\u30C8',\n close: '\u9589\u3058\u308B'\n },\n speeds: {\n normal: '\u901A\u5E38'\n }\n }\n};\n\n", "/**\n * Internationalization system\n */\n\nimport { translations } from './translations.js';\n\nclass I18n {\n constructor() {\n this.currentLanguage = 'en';\n this.translations = translations;\n }\n\n setLanguage(lang) {\n if (this.translations[lang]) {\n this.currentLanguage = lang;\n } else {\n console.warn(`Language \"${lang}\" not found, falling back to English`);\n this.currentLanguage = 'en';\n }\n }\n\n getLanguage() {\n return this.currentLanguage;\n }\n\n t(key, replacements = {}) {\n const keys = key.split('.');\n let value = this.translations[this.currentLanguage];\n \n for (const k of keys) {\n if (value && typeof value === 'object' && k in value) {\n value = value[k];\n } else {\n // Fallback to English\n value = this.translations.en;\n for (const fallbackKey of keys) {\n if (value && typeof value === 'object' && fallbackKey in value) {\n value = value[fallbackKey];\n } else {\n return key; // Return key if not found\n }\n }\n break;\n }\n }\n \n // Replace placeholders\n if (typeof value === 'string') {\n Object.entries(replacements).forEach(([placeholder, replacement]) => {\n value = value.replace(new RegExp(`{${placeholder}}`, 'g'), replacement);\n });\n }\n \n return value;\n }\n\n addTranslation(lang, translations) {\n if (!this.translations[lang]) {\n this.translations[lang] = {};\n }\n Object.assign(this.translations[lang], translations);\n }\n}\n\nexport const i18n = new I18n();\n\n", "/**\n * Control Bar Component\n */\n\nimport {DOMUtils} from '../utils/DOMUtils.js';\nimport {TimeUtils} from '../utils/TimeUtils.js';\nimport {createIconElement} from '../icons/Icons.js';\nimport {i18n} from '../i18n/i18n.js';\n\nexport class ControlBar {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.controls = {};\n this.hideTimeout = null;\n this.isDraggingProgress = false;\n this.isDraggingVolume = false;\n\n this.init();\n }\n\n init() {\n this.createElement();\n this.createControls();\n this.attachEvents();\n this.setupAutoHide();\n }\n\n // Helper method to check if we're on a mobile device\n isMobile() {\n return window.innerWidth < 640;\n }\n\n // Smart menu positioning to avoid overflow\n positionMenu(menu, button) {\n const isMobile = this.isMobile();\n \n if (isMobile) {\n // Use bottom sheet on mobile - already styled via CSS\n return;\n }\n\n // Desktop: Smart positioning\n setTimeout(() => {\n const buttonRect = button.getBoundingClientRect();\n const menuRect = menu.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n \n const spaceAbove = buttonRect.top;\n const spaceBelow = viewportHeight - buttonRect.bottom;\n \n // Prefer above, but switch to below if not enough space\n if (spaceAbove < menuRect.height + 20 && spaceBelow > spaceAbove) {\n menu.style.bottom = 'auto';\n menu.style.top = 'calc(100% + 8px)';\n menu.classList.add('vidply-menu-below');\n }\n \n // Check horizontal overflow\n const menuLeft = buttonRect.left + buttonRect.width / 2 - menuRect.width / 2;\n if (menuLeft < 10) {\n // Too far left, align to left edge\n menu.style.right = 'auto';\n menu.style.left = '0';\n menu.style.transform = 'translateX(0)';\n } else if (menuLeft + menuRect.width > viewportWidth - 10) {\n // Too far right, align to right edge\n menu.style.left = 'auto';\n menu.style.right = '0';\n menu.style.transform = 'translateX(0)';\n }\n }, 0);\n }\n\n\n // Helper method to attach close-on-outside-click behavior to menus\n attachMenuCloseHandler(menu, button, preventCloseOnInteraction = false) {\n // Position menu smartly\n this.positionMenu(menu, button);\n \n setTimeout(() => {\n const closeMenu = (e) => {\n // If this menu has form controls, don't close when clicking inside\n if (preventCloseOnInteraction && menu.contains(e.target)) {\n return;\n }\n\n // Check if click is outside menu and button\n if (!menu.contains(e.target) && !button.contains(e.target)) {\n menu.remove();\n document.removeEventListener('click', closeMenu);\n document.removeEventListener('keydown', handleEscape);\n }\n };\n\n const handleEscape = (e) => {\n if (e.key === 'Escape') {\n menu.remove();\n document.removeEventListener('click', closeMenu);\n document.removeEventListener('keydown', handleEscape);\n // Return focus to button\n button.focus();\n }\n };\n\n document.addEventListener('click', closeMenu);\n document.addEventListener('keydown', handleEscape);\n }, 100);\n }\n\n createElement() {\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls`,\n attributes: {\n 'role': 'region',\n 'aria-label': i18n.t('player.label') + ' controls'\n }\n });\n }\n\n createControls() {\n // Progress bar container\n if (this.player.options.progressBar) {\n this.createProgressBar();\n }\n\n // Button container\n const buttonContainer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-buttons`\n });\n\n // Left buttons\n const leftButtons = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-left`\n });\n\n // Previous track button (if playlist)\n if (this.player.playlistManager) {\n leftButtons.appendChild(this.createPreviousButton());\n }\n\n // Play/Pause button\n if (this.player.options.playPauseButton) {\n leftButtons.appendChild(this.createPlayPauseButton());\n }\n\n // Restart button (right beside play button)\n leftButtons.appendChild(this.createRestartButton());\n\n // Next track button (if playlist)\n if (this.player.playlistManager) {\n leftButtons.appendChild(this.createNextButton());\n }\n\n // Rewind button (not shown in playlist mode)\n if (!this.player.playlistManager) {\n leftButtons.appendChild(this.createRewindButton());\n }\n\n // Forward button (not shown in playlist mode)\n if (!this.player.playlistManager) {\n leftButtons.appendChild(this.createForwardButton());\n }\n\n // Volume control\n if (this.player.options.volumeControl) {\n leftButtons.appendChild(this.createVolumeControl());\n }\n\n // Time display\n if (this.player.options.currentTime || this.player.options.duration) {\n leftButtons.appendChild(this.createTimeDisplay());\n }\n\n // Right buttons\n this.rightButtons = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-controls-right`\n });\n\n // Check for available features\n const hasChapters = this.hasChapterTracks();\n const hasCaptions = this.hasCaptionTracks();\n const hasQualityLevels = this.hasQualityLevels();\n const hasAudioDescription = this.hasAudioDescription();\n\n // Chapters button - only show if chapters are available\n if (this.player.options.chaptersButton && hasChapters) {\n this.rightButtons.appendChild(this.createChaptersButton());\n }\n\n // Quality button - only show if quality levels are available\n if (this.player.options.qualityButton && hasQualityLevels) {\n this.rightButtons.appendChild(this.createQualityButton());\n }\n\n // Caption styling button (font, size, color) - only show if captions are available\n if (this.player.options.captionStyleButton && hasCaptions) {\n this.rightButtons.appendChild(this.createCaptionStyleButton());\n }\n\n // Speed button - always available\n if (this.player.options.speedButton) {\n this.rightButtons.appendChild(this.createSpeedButton());\n }\n\n // Captions language selector button - only show if captions are available\n if (this.player.options.captionsButton && hasCaptions) {\n this.rightButtons.appendChild(this.createCaptionsButton());\n }\n\n // Transcript button - only show if captions/subtitles are available\n if (this.player.options.transcriptButton && hasCaptions) {\n this.rightButtons.appendChild(this.createTranscriptButton());\n }\n\n // Audio Description button - only show if audio description source is available\n if (this.player.options.audioDescriptionButton && hasAudioDescription) {\n this.rightButtons.appendChild(this.createAudioDescriptionButton());\n }\n\n // Sign Language button - only show if sign language source is available\n const hasSignLanguage = this.hasSignLanguage();\n if (this.player.options.signLanguageButton && hasSignLanguage) {\n this.rightButtons.appendChild(this.createSignLanguageButton());\n }\n\n // PiP button\n if (this.player.options.pipButton && 'pictureInPictureEnabled' in document) {\n this.rightButtons.appendChild(this.createPipButton());\n }\n\n // Fullscreen button\n if (this.player.options.fullscreenButton) {\n this.rightButtons.appendChild(this.createFullscreenButton());\n }\n\n buttonContainer.appendChild(leftButtons);\n buttonContainer.appendChild(this.rightButtons);\n this.element.appendChild(buttonContainer);\n }\n\n // Helper methods to check for available features\n hasChapterTracks() {\n const textTracks = this.player.element.textTracks;\n for (let i = 0; i < textTracks.length; i++) {\n if (textTracks[i].kind === 'chapters') {\n return true;\n }\n }\n return false;\n }\n\n hasCaptionTracks() {\n const textTracks = this.player.element.textTracks;\n for (let i = 0; i < textTracks.length; i++) {\n if (textTracks[i].kind === 'captions' || textTracks[i].kind === 'subtitles') {\n return true;\n }\n }\n return false;\n }\n\n hasQualityLevels() {\n // Check if renderer supports quality selection\n if (this.player.renderer && this.player.renderer.getQualities) {\n const qualities = this.player.renderer.getQualities();\n return qualities && qualities.length > 1;\n }\n return false;\n }\n\n hasAudioDescription() {\n return this.player.audioDescriptionSrc && this.player.audioDescriptionSrc.length > 0;\n }\n\n hasSignLanguage() {\n return this.player.signLanguageSrc && this.player.signLanguageSrc.length > 0;\n }\n\n createProgressBar() {\n const progressContainer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-container`,\n attributes: {\n 'role': 'slider',\n 'aria-label': i18n.t('player.progress'),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n 'aria-valuenow': '0',\n 'tabindex': '0'\n }\n });\n\n // Buffered progress\n this.controls.buffered = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-buffered`\n });\n\n // Played progress\n this.controls.played = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-played`\n });\n\n // Progress handle\n this.controls.progressHandle = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-handle`\n });\n\n // Tooltip\n this.controls.progressTooltip = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-progress-tooltip`\n });\n\n progressContainer.appendChild(this.controls.buffered);\n progressContainer.appendChild(this.controls.played);\n this.controls.played.appendChild(this.controls.progressHandle);\n progressContainer.appendChild(this.controls.progressTooltip);\n\n this.controls.progress = progressContainer;\n this.element.appendChild(progressContainer);\n\n // Progress bar events\n this.setupProgressBarEvents();\n }\n\n setupProgressBarEvents() {\n const progress = this.controls.progress;\n\n const updateProgress = (clientX) => {\n const rect = progress.getBoundingClientRect();\n const percent = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n const time = percent * this.player.state.duration;\n return {percent, time};\n };\n\n // Mouse events\n progress.addEventListener('mousedown', (e) => {\n this.isDraggingProgress = true;\n const {time} = updateProgress(e.clientX);\n this.player.seek(time);\n });\n\n document.addEventListener('mousemove', (e) => {\n if (this.isDraggingProgress) {\n const {time} = updateProgress(e.clientX);\n this.player.seek(time);\n }\n });\n\n document.addEventListener('mouseup', () => {\n this.isDraggingProgress = false;\n });\n\n // Hover tooltip\n progress.addEventListener('mousemove', (e) => {\n if (!this.isDraggingProgress) {\n const {time} = updateProgress(e.clientX);\n this.controls.progressTooltip.textContent = TimeUtils.formatTime(time);\n this.controls.progressTooltip.style.left = `${e.clientX - progress.getBoundingClientRect().left}px`;\n this.controls.progressTooltip.style.display = 'block';\n }\n });\n\n progress.addEventListener('mouseleave', () => {\n this.controls.progressTooltip.style.display = 'none';\n });\n\n // Keyboard navigation\n progress.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n this.player.seekBackward(5);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n this.player.seekForward(5);\n }\n });\n\n // Touch events\n progress.addEventListener('touchstart', (e) => {\n this.isDraggingProgress = true;\n const touch = e.touches[0];\n const {time} = updateProgress(touch.clientX);\n this.player.seek(time);\n });\n\n progress.addEventListener('touchmove', (e) => {\n if (this.isDraggingProgress) {\n e.preventDefault();\n const touch = e.touches[0];\n const {time} = updateProgress(touch.clientX);\n this.player.seek(time);\n }\n });\n\n progress.addEventListener('touchend', () => {\n this.isDraggingProgress = false;\n });\n }\n\n createPlayPauseButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-play-pause`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.play')\n }\n });\n\n button.appendChild(createIconElement('play'));\n\n button.addEventListener('click', () => {\n this.player.toggle();\n });\n\n this.controls.playPause = button;\n return button;\n }\n\n createRestartButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-restart`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.restart')\n }\n });\n\n button.appendChild(createIconElement('restart'));\n\n button.addEventListener('click', () => {\n this.player.seek(0);\n this.player.play();\n });\n\n return button;\n }\n\n createPreviousButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-previous`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.previous')\n }\n });\n\n button.appendChild(createIconElement('skipPrevious'));\n\n button.addEventListener('click', () => {\n if (this.player.playlistManager) {\n this.player.playlistManager.previous();\n }\n });\n\n // Update button state\n const updateState = () => {\n if (this.player.playlistManager) {\n button.disabled = !this.player.playlistManager.hasPrevious() && !this.player.playlistManager.options.loop;\n }\n };\n this.player.on('playlisttrackchange', updateState);\n updateState();\n\n this.controls.previous = button;\n return button;\n }\n\n createNextButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-next`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.next')\n }\n });\n\n button.appendChild(createIconElement('skipNext'));\n\n button.addEventListener('click', () => {\n if (this.player.playlistManager) {\n this.player.playlistManager.next();\n }\n });\n\n // Update button state\n const updateState = () => {\n if (this.player.playlistManager) {\n button.disabled = !this.player.playlistManager.hasNext() && !this.player.playlistManager.options.loop;\n }\n };\n this.player.on('playlisttrackchange', updateState);\n updateState();\n\n this.controls.next = button;\n return button;\n }\n\n createRewindButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-rewind`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.rewindSeconds', { seconds: 15 })\n }\n });\n\n button.appendChild(createIconElement('rewind'));\n\n button.addEventListener('click', () => {\n this.player.seekBackward(15);\n });\n\n return button;\n }\n\n createForwardButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-forward`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.forwardSeconds', { seconds: 15 })\n }\n });\n\n button.appendChild(createIconElement('forward'));\n\n button.addEventListener('click', () => {\n this.player.seekForward(15);\n });\n\n return button;\n }\n\n createVolumeControl() {\n // Mute/Volume button\n const muteButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-mute`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.volume'),\n 'aria-haspopup': 'true'\n }\n });\n\n muteButton.appendChild(createIconElement('volumeHigh'));\n\n // Toggle mute on right click, show volume slider on left click\n muteButton.addEventListener('contextmenu', (e) => {\n e.preventDefault();\n this.player.toggleMute();\n });\n\n muteButton.addEventListener('click', () => {\n this.showVolumeSlider(muteButton);\n });\n\n this.controls.mute = muteButton;\n\n return muteButton;\n }\n\n showVolumeSlider(button) {\n // Remove existing slider if any\n const existingSlider = document.querySelector(`.${this.player.options.classPrefix}-volume-menu`);\n if (existingSlider) {\n existingSlider.remove();\n return;\n }\n\n // Volume menu container\n const volumeMenu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-menu ${this.player.options.classPrefix}-menu`\n });\n\n const volumeSlider = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-slider`,\n attributes: {\n 'role': 'slider',\n 'aria-label': i18n.t('player.volume'),\n 'aria-valuemin': '0',\n 'aria-valuemax': '100',\n 'aria-valuenow': String(Math.round(this.player.state.volume * 100)),\n 'tabindex': '0'\n }\n });\n\n const volumeTrack = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-track`\n });\n\n const volumeFill = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-fill`\n });\n\n const volumeHandle = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-volume-handle`\n });\n\n volumeTrack.appendChild(volumeFill);\n volumeFill.appendChild(volumeHandle);\n volumeSlider.appendChild(volumeTrack);\n volumeMenu.appendChild(volumeSlider);\n\n // Volume slider events\n const updateVolume = (clientY) => {\n const rect = volumeTrack.getBoundingClientRect();\n const percent = Math.max(0, Math.min(1, 1 - ((clientY - rect.top) / rect.height)));\n this.player.setVolume(percent);\n };\n\n volumeSlider.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n this.isDraggingVolume = true;\n updateVolume(e.clientY);\n });\n\n document.addEventListener('mousemove', (e) => {\n if (this.isDraggingVolume) {\n updateVolume(e.clientY);\n }\n });\n\n document.addEventListener('mouseup', () => {\n this.isDraggingVolume = false;\n });\n\n // Keyboard volume control\n volumeSlider.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n this.player.setVolume(Math.min(1, this.player.state.volume + 0.1));\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n this.player.setVolume(Math.max(0, this.player.state.volume - 0.1));\n }\n });\n\n // Prevent menu from closing when interacting with slider\n volumeMenu.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n // Append menu to button\n button.appendChild(volumeMenu);\n\n this.controls.volumeSlider = volumeSlider;\n this.controls.volumeFill = volumeFill;\n\n // Close menu on outside click\n this.attachMenuCloseHandler(volumeMenu, button, true);\n }\n\n createTimeDisplay() {\n const container = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-time`\n });\n\n this.controls.currentTimeDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-current-time`,\n textContent: '00:00'\n });\n\n const separator = DOMUtils.createElement('span', {\n textContent: ' / ',\n attributes: {\n 'aria-hidden': 'true'\n }\n });\n\n this.controls.durationDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-duration`,\n textContent: '00:00'\n });\n\n container.appendChild(this.controls.currentTimeDisplay);\n container.appendChild(separator);\n container.appendChild(this.controls.durationDisplay);\n\n return container;\n }\n\n createChaptersButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-chapters`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.chapters'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('playlist'));\n\n button.addEventListener('click', () => {\n this.showChaptersMenu(button);\n });\n\n this.controls.chapters = button;\n return button;\n }\n\n showChaptersMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-chapters-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-chapters-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.chapters')\n }\n });\n\n // Get chapter tracks\n const chapterTracks = Array.from(this.player.element.textTracks).filter(\n track => track.kind === 'chapters'\n );\n\n if (chapterTracks.length === 0) {\n // No chapters available\n const noChaptersItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noChapters'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noChaptersItem);\n } else {\n const chapterTrack = chapterTracks[0];\n\n // Ensure track is in 'hidden' mode to load cues\n if (chapterTrack.mode === 'disabled') {\n chapterTrack.mode = 'hidden';\n }\n\n if (!chapterTrack.cues || chapterTrack.cues.length === 0) {\n // Cues not loaded yet - wait for them to load\n const loadingItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.loadingChapters'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(loadingItem);\n\n // Listen for track load event\n const onTrackLoad = () => {\n // Remove loading message and rebuild menu\n menu.remove();\n this.showChaptersMenu(button);\n };\n\n chapterTrack.addEventListener('load', onTrackLoad, {once: true});\n\n // Also try again after a short delay as fallback\n setTimeout(() => {\n if (chapterTrack.cues && chapterTrack.cues.length > 0 && document.contains(menu)) {\n menu.remove();\n this.showChaptersMenu(button);\n }\n }, 500);\n } else {\n // Display chapters\n const cues = chapterTrack.cues;\n for (let i = 0; i < cues.length; i++) {\n const cue = cues[i];\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n const timeLabel = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-chapter-time`,\n textContent: TimeUtils.formatTime(cue.startTime)\n });\n\n const titleLabel = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-chapter-title`,\n textContent: cue.text\n });\n\n item.appendChild(timeLabel);\n item.appendChild(document.createTextNode(' '));\n item.appendChild(titleLabel);\n\n item.addEventListener('click', () => {\n this.player.seek(cue.startTime);\n menu.remove();\n });\n\n menu.appendChild(item);\n }\n }\n }\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createQualityButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-quality`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.quality'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('hd'));\n\n // Add quality indicator text\n const qualityText = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-quality-text`,\n textContent: ''\n });\n button.appendChild(qualityText);\n\n button.addEventListener('click', () => {\n this.showQualityMenu(button);\n });\n\n this.controls.quality = button;\n this.controls.qualityText = qualityText;\n \n // Update quality indicator after a short delay to ensure renderer is ready\n setTimeout(() => this.updateQualityIndicator(), 500);\n \n return button;\n }\n\n showQualityMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-quality-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-quality-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.quality')\n }\n });\n\n // Check if renderer supports quality selection\n if (this.player.renderer && this.player.renderer.getQualities) {\n const qualities = this.player.renderer.getQualities();\n const currentQuality = this.player.renderer.getCurrentQuality ? this.player.renderer.getCurrentQuality() : -1;\n const isHLS = this.player.renderer.hls !== undefined;\n\n if (qualities.length === 0) {\n // No qualities available\n const noQualityItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.autoQuality'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noQualityItem);\n } else {\n // Auto quality option (only for HLS)\n if (isHLS) {\n const autoItem = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.auto'),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n // Check if auto is currently selected\n const isAuto = this.player.renderer.hls && this.player.renderer.hls.currentLevel === -1;\n if (isAuto) {\n autoItem.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n autoItem.appendChild(createIconElement('check'));\n }\n\n autoItem.addEventListener('click', () => {\n if (this.player.renderer.switchQuality) {\n this.player.renderer.switchQuality(-1); // -1 for auto\n }\n menu.remove();\n });\n\n menu.appendChild(autoItem);\n }\n\n // Quality options\n qualities.forEach(quality => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: quality.name || `${quality.height}p`,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n // Highlight current quality\n if (quality.index === currentQuality) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n }\n\n item.addEventListener('click', () => {\n if (this.player.renderer.switchQuality) {\n this.player.renderer.switchQuality(quality.index);\n }\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n }\n } else {\n // No quality support\n const noSupportItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noQuality'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noSupportItem);\n }\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createCaptionStyleButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-caption-style`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.captionStyling'),\n 'aria-haspopup': 'menu',\n 'title': i18n.t('player.captionStyling')\n }\n });\n\n // Create \"Aa\" text icon for styling\n const textIcon = DOMUtils.createElement('span', {\n textContent: 'Aa',\n style: {\n fontSize: '14px',\n fontWeight: 'bold'\n }\n });\n button.appendChild(textIcon);\n\n button.addEventListener('click', () => {\n this.showCaptionStyleMenu(button);\n });\n\n this.controls.captionStyle = button;\n return button;\n }\n\n showCaptionStyleMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-caption-style-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-caption-style-menu ${this.player.options.classPrefix}-menu ${this.player.options.classPrefix}-settings-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('player.captionStyling')\n }\n });\n\n // Prevent menu from closing when clicking inside\n menu.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n // Check if there are any caption tracks\n if (!this.player.captionManager || this.player.captionManager.tracks.length === 0) {\n // Show \"No captions available\" message\n const noTracksItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noCaptions'),\n style: {opacity: '0.5', cursor: 'default', padding: '12px 16px'}\n });\n menu.appendChild(noTracksItem);\n\n // Append menu to button\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button, true);\n return;\n }\n\n // Font Size\n const fontSizeGroup = this.createStyleControl(\n i18n.t('styleLabels.fontSize'),\n 'captionsFontSize',\n [\n {label: i18n.t('fontSizes.small'), value: '80%'},\n {label: i18n.t('fontSizes.medium'), value: '100%'},\n {label: i18n.t('fontSizes.large'), value: '120%'},\n {label: i18n.t('fontSizes.xlarge'), value: '150%'}\n ]\n );\n menu.appendChild(fontSizeGroup);\n\n // Font Family\n const fontFamilyGroup = this.createStyleControl(\n i18n.t('styleLabels.font'),\n 'captionsFontFamily',\n [\n {label: i18n.t('fontFamilies.sansSerif'), value: 'sans-serif'},\n {label: i18n.t('fontFamilies.serif'), value: 'serif'},\n {label: i18n.t('fontFamilies.monospace'), value: 'monospace'}\n ]\n );\n menu.appendChild(fontFamilyGroup);\n\n // Text Color\n const colorGroup = this.createColorControl(i18n.t('styleLabels.textColor'), 'captionsColor');\n menu.appendChild(colorGroup);\n\n // Background Color\n const bgColorGroup = this.createColorControl(i18n.t('styleLabels.background'), 'captionsBackgroundColor');\n menu.appendChild(bgColorGroup);\n\n // Opacity\n const opacityGroup = this.createOpacityControl(i18n.t('styleLabels.opacity'), 'captionsOpacity');\n menu.appendChild(opacityGroup);\n\n // Set min-width for caption style menu\n menu.style.minWidth = '220px';\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click (but not when interacting with controls)\n this.attachMenuCloseHandler(menu, button, true);\n }\n\n createStyleControl(label, property, options) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-style-select`,\n style: {\n width: '100%',\n padding: '6px',\n background: 'var(--vidply-white)',\n border: '1px solid var(--vidply-white-10)',\n borderRadius: '4px',\n color: 'var(--vidply-black)',\n fontSize: '13px'\n }\n });\n\n const currentValue = this.player.options[property];\n options.forEach(opt => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.label,\n attributes: {value: opt.value}\n });\n if (opt.value === currentValue) {\n option.selected = true;\n }\n select.appendChild(option);\n });\n\n // Prevent clicks from closing the menu\n select.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n select.addEventListener('change', (e) => {\n e.stopPropagation();\n this.player.options[property] = e.target.value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n e.target.value\n );\n }\n });\n\n group.appendChild(select);\n return group;\n }\n\n createColorControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n display: 'block',\n fontSize: '12px',\n marginBottom: '4px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n group.appendChild(labelEl);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n type: 'color',\n value: this.player.options[property]\n },\n style: {\n width: '100%',\n height: '32px',\n padding: '2px',\n background: 'rgba(255,255,255,0.1)',\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: '4px',\n cursor: 'pointer'\n }\n });\n\n // Prevent clicks from closing the menu\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('change', (e) => {\n e.stopPropagation();\n this.player.options[property] = e.target.value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n e.target.value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n }\n\n createOpacityControl(label, property) {\n const group = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-style-group`\n });\n\n const labelContainer = DOMUtils.createElement('div', {\n style: {\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: '4px'\n }\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n const valueEl = DOMUtils.createElement('span', {\n textContent: Math.round(this.player.options[property] * 100) + '%',\n style: {\n fontSize: '12px',\n color: 'rgba(255,255,255,0.7)'\n }\n });\n\n labelContainer.appendChild(labelEl);\n labelContainer.appendChild(valueEl);\n group.appendChild(labelContainer);\n\n const input = DOMUtils.createElement('input', {\n attributes: {\n type: 'range',\n min: '0',\n max: '1',\n step: '0.1',\n value: String(this.player.options[property])\n },\n style: {\n width: '100%',\n cursor: 'pointer'\n }\n });\n\n // Prevent clicks from closing the menu\n input.addEventListener('mousedown', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n input.addEventListener('input', (e) => {\n e.stopPropagation();\n const value = parseFloat(e.target.value);\n valueEl.textContent = Math.round(value * 100) + '%';\n this.player.options[property] = value;\n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle(\n property.replace('captions', '').charAt(0).toLowerCase() + property.replace('captions', '').slice(1),\n value\n );\n }\n });\n\n group.appendChild(input);\n return group;\n }\n\n createSpeedButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-speed`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.speed'),\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('speed'));\n\n const speedText = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-speed-text`,\n textContent: '1x'\n });\n button.appendChild(speedText);\n\n button.addEventListener('click', () => {\n this.showSpeedMenu(button);\n });\n\n this.controls.speed = button;\n this.controls.speedText = speedText;\n return button;\n }\n\n formatSpeedLabel(speed) {\n // Special case: 1x is \"Normal\" (translated)\n if (speed === 1) {\n return i18n.t('speeds.normal');\n }\n \n // For other speeds, format with locale-specific decimal separator\n const speedStr = speed.toLocaleString(i18n.getLanguage(), {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2\n });\n \n return `${speedStr}\u00D7`;\n }\n\n showSpeedMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-speed-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-speed-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu'\n }\n });\n\n const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n\n speeds.forEach(speed => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: this.formatSpeedLabel(speed),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n if (speed === this.player.state.playbackSpeed) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n }\n\n item.addEventListener('click', () => {\n this.player.setPlaybackSpeed(speed);\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n createCaptionsButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-captions-button`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.captions'),\n 'aria-pressed': 'false',\n 'aria-haspopup': 'menu'\n }\n });\n\n button.appendChild(createIconElement('captionsOff'));\n\n button.addEventListener('click', () => {\n this.showCaptionsMenu(button);\n });\n\n this.controls.captions = button;\n return button;\n }\n\n showCaptionsMenu(button) {\n // Remove existing menu if any\n const existingMenu = document.querySelector(`.${this.player.options.classPrefix}-captions-menu`);\n if (existingMenu) {\n existingMenu.remove();\n return;\n }\n\n const menu = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-captions-menu ${this.player.options.classPrefix}-menu`,\n attributes: {\n 'role': 'menu',\n 'aria-label': i18n.t('captions.select')\n }\n });\n\n // Check if there are any caption tracks\n if (!this.player.captionManager || this.player.captionManager.tracks.length === 0) {\n // Show \"No captions available\" message\n const noTracksItem = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('player.noCaptions'),\n style: {opacity: '0.5', cursor: 'default'}\n });\n menu.appendChild(noTracksItem);\n\n // Append menu to button\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n return;\n }\n\n // Off option\n const offItem = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: i18n.t('captions.off'),\n attributes: {\n 'type': 'button',\n 'role': 'menuitem'\n }\n });\n\n if (!this.player.state.captionsEnabled) {\n offItem.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n offItem.appendChild(createIconElement('check'));\n }\n\n offItem.addEventListener('click', () => {\n this.player.disableCaptions();\n this.updateCaptionsButton();\n menu.remove();\n });\n\n menu.appendChild(offItem);\n\n // Available tracks\n const tracks = this.player.captionManager.getAvailableTracks();\n tracks.forEach(track => {\n const item = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-menu-item`,\n textContent: track.label,\n attributes: {\n 'type': 'button',\n 'role': 'menuitem',\n 'lang': track.language\n }\n });\n\n // Check if this is the current track\n if (this.player.state.captionsEnabled &&\n this.player.captionManager.currentTrack === this.player.captionManager.tracks[track.index]) {\n item.classList.add(`${this.player.options.classPrefix}-menu-item-active`);\n item.appendChild(createIconElement('check'));\n }\n\n item.addEventListener('click', () => {\n this.player.captionManager.switchTrack(track.index);\n this.updateCaptionsButton();\n menu.remove();\n });\n\n menu.appendChild(item);\n });\n\n // Append menu directly to button for proper positioning\n button.appendChild(menu);\n\n // Close menu on outside click\n this.attachMenuCloseHandler(menu, button);\n }\n\n updateCaptionsButton() {\n if (!this.controls.captions) return;\n\n const icon = this.controls.captions.querySelector('.vidply-icon');\n const isEnabled = this.player.state.captionsEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('captions').innerHTML :\n createIconElement('captionsOff').innerHTML;\n\n this.controls.captions.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n }\n\n createTranscriptButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-transcript`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.transcript'),\n 'aria-pressed': 'false'\n }\n });\n\n button.appendChild(createIconElement('transcript'));\n\n button.addEventListener('click', () => {\n if (this.player.transcriptManager) {\n this.player.transcriptManager.toggleTranscript();\n this.updateTranscriptButton();\n }\n });\n\n this.controls.transcript = button;\n return button;\n }\n\n updateTranscriptButton() {\n if (!this.controls.transcript) return;\n\n const isVisible = this.player.transcriptManager && this.player.transcriptManager.isVisible;\n this.controls.transcript.setAttribute('aria-pressed', isVisible ? 'true' : 'false');\n }\n\n createAudioDescriptionButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-audio-description`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.audioDescription'),\n 'aria-pressed': 'false',\n 'title': i18n.t('player.audioDescription')\n }\n });\n\n button.appendChild(createIconElement('audioDescription'));\n\n button.addEventListener('click', async () => {\n await this.player.toggleAudioDescription();\n this.updateAudioDescriptionButton();\n });\n\n this.controls.audioDescription = button;\n return button;\n }\n\n updateAudioDescriptionButton() {\n if (!this.controls.audioDescription) return;\n\n const icon = this.controls.audioDescription.querySelector('.vidply-icon');\n const isEnabled = this.player.state.audioDescriptionEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('audioDescriptionOn').innerHTML :\n createIconElement('audioDescription').innerHTML;\n\n this.controls.audioDescription.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n this.controls.audioDescription.setAttribute('aria-label',\n isEnabled ? i18n.t('audioDescription.disable') : i18n.t('audioDescription.enable')\n );\n }\n\n createSignLanguageButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-sign-language`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.signLanguage'),\n 'aria-pressed': 'false',\n 'title': i18n.t('player.signLanguage')\n }\n });\n\n button.appendChild(createIconElement('signLanguage'));\n\n button.addEventListener('click', () => {\n this.player.toggleSignLanguage();\n this.updateSignLanguageButton();\n });\n\n this.controls.signLanguage = button;\n return button;\n }\n\n updateSignLanguageButton() {\n if (!this.controls.signLanguage) return;\n\n const icon = this.controls.signLanguage.querySelector('.vidply-icon');\n const isEnabled = this.player.state.signLanguageEnabled;\n\n icon.innerHTML = isEnabled ?\n createIconElement('signLanguageOn').innerHTML :\n createIconElement('signLanguage').innerHTML;\n\n this.controls.signLanguage.setAttribute('aria-pressed', isEnabled ? 'true' : 'false');\n this.controls.signLanguage.setAttribute('aria-label',\n isEnabled ? i18n.t('signLanguage.hide') : i18n.t('signLanguage.show')\n );\n }\n\n createSettingsButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-settings`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.settings')\n }\n });\n\n button.appendChild(createIconElement('settings'));\n\n button.addEventListener('click', () => {\n this.player.showSettings();\n });\n\n return button;\n }\n\n createPipButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-pip`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.pip')\n }\n });\n\n button.appendChild(createIconElement('pip'));\n\n button.addEventListener('click', () => {\n this.player.togglePiP();\n });\n\n return button;\n }\n\n createFullscreenButton() {\n const button = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-fullscreen`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('player.fullscreen')\n }\n });\n\n button.appendChild(createIconElement('fullscreen'));\n\n button.addEventListener('click', () => {\n this.player.toggleFullscreen();\n });\n\n this.controls.fullscreen = button;\n return button;\n }\n\n attachEvents() {\n // Update controls based on player state\n this.player.on('play', () => this.updatePlayPauseButton());\n this.player.on('pause', () => this.updatePlayPauseButton());\n this.player.on('timeupdate', () => this.updateProgress());\n this.player.on('loadedmetadata', () => {\n this.updateDuration();\n this.ensureQualityButton();\n this.updateQualityIndicator();\n });\n this.player.on('volumechange', () => this.updateVolumeDisplay());\n this.player.on('progress', () => this.updateBuffered());\n this.player.on('playbackspeedchange', () => this.updateSpeedDisplay());\n this.player.on('fullscreenchange', () => this.updateFullscreenButton());\n this.player.on('captionsenabled', () => this.updateCaptionsButton());\n this.player.on('captionsdisabled', () => this.updateCaptionsButton());\n this.player.on('audiodescriptionenabled', () => this.updateAudioDescriptionButton());\n this.player.on('audiodescriptiondisabled', () => this.updateAudioDescriptionButton());\n this.player.on('signlanguageenabled', () => this.updateSignLanguageButton());\n this.player.on('signlanguagedisabled', () => this.updateSignLanguageButton());\n this.player.on('qualitychange', () => this.updateQualityIndicator());\n this.player.on('hlslevelswitched', () => this.updateQualityIndicator());\n this.player.on('hlsmanifestparsed', () => {\n this.ensureQualityButton();\n this.updateQualityIndicator();\n });\n }\n\n updatePlayPauseButton() {\n if (!this.controls.playPause) return;\n\n const icon = this.controls.playPause.querySelector('.vidply-icon');\n const isPlaying = this.player.state.playing;\n\n icon.innerHTML = isPlaying ?\n createIconElement('pause').innerHTML :\n createIconElement('play').innerHTML;\n\n this.controls.playPause.setAttribute('aria-label',\n isPlaying ? i18n.t('player.pause') : i18n.t('player.play')\n );\n }\n\n updateProgress() {\n if (!this.controls.played) return;\n\n const percent = (this.player.state.currentTime / this.player.state.duration) * 100;\n this.controls.played.style.width = `${percent}%`;\n this.controls.progress.setAttribute('aria-valuenow', String(Math.round(percent)));\n\n if (this.controls.currentTimeDisplay) {\n this.controls.currentTimeDisplay.textContent = TimeUtils.formatTime(this.player.state.currentTime);\n }\n }\n\n updateDuration() {\n if (this.controls.durationDisplay) {\n this.controls.durationDisplay.textContent = TimeUtils.formatTime(this.player.state.duration);\n }\n }\n\n updateVolumeDisplay() {\n if (!this.controls.volumeFill) return;\n\n const percent = this.player.state.volume * 100;\n this.controls.volumeFill.style.height = `${percent}%`;\n\n // Update mute button icon\n if (this.controls.mute) {\n const icon = this.controls.mute.querySelector('.vidply-icon');\n let iconName;\n\n if (this.player.state.muted || this.player.state.volume === 0) {\n iconName = 'volumeMuted';\n } else if (this.player.state.volume < 0.3) {\n iconName = 'volumeLow';\n } else if (this.player.state.volume < 0.7) {\n iconName = 'volumeMedium';\n } else {\n iconName = 'volumeHigh';\n }\n\n icon.innerHTML = createIconElement(iconName).innerHTML;\n\n this.controls.mute.setAttribute('aria-label',\n this.player.state.muted ? i18n.t('player.unmute') : i18n.t('player.mute')\n );\n }\n\n if (this.controls.volumeSlider) {\n this.controls.volumeSlider.setAttribute('aria-valuenow', String(Math.round(percent)));\n }\n }\n\n updateBuffered() {\n if (!this.controls.buffered || !this.player.element.buffered || this.player.element.buffered.length === 0) return;\n\n const buffered = this.player.element.buffered.end(this.player.element.buffered.length - 1);\n const percent = (buffered / this.player.state.duration) * 100;\n this.controls.buffered.style.width = `${percent}%`;\n }\n\n updateSpeedDisplay() {\n if (this.controls.speedText) {\n this.controls.speedText.textContent = `${this.player.state.playbackSpeed}x`;\n }\n }\n\n updateFullscreenButton() {\n if (!this.controls.fullscreen) return;\n\n const icon = this.controls.fullscreen.querySelector('.vidply-icon');\n const isFullscreen = this.player.state.fullscreen;\n\n icon.innerHTML = isFullscreen ?\n createIconElement('fullscreenExit').innerHTML :\n createIconElement('fullscreen').innerHTML;\n\n this.controls.fullscreen.setAttribute('aria-label',\n isFullscreen ? i18n.t('player.exitFullscreen') : i18n.t('player.fullscreen')\n );\n }\n\n /**\n * Ensure quality button exists if qualities are available\n * This is called after renderer initialization to dynamically add the button\n */\n ensureQualityButton() {\n // Skip if quality button is disabled\n if (!this.player.options.qualityButton) return;\n \n // Skip if button already exists\n if (this.controls.quality) return;\n \n // Check if qualities are now available\n if (!this.hasQualityLevels()) return;\n \n // Create and insert the quality button before the speed button\n const qualityButton = this.createQualityButton();\n \n // Find the speed button or caption style button to insert before\n const speedButton = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-speed`);\n const captionStyleButton = this.rightButtons.querySelector(`.${this.player.options.classPrefix}-caption-style`);\n const insertBefore = captionStyleButton || speedButton;\n \n if (insertBefore) {\n this.rightButtons.insertBefore(qualityButton, insertBefore);\n } else {\n // If no reference button, add it at the beginning of right buttons\n this.rightButtons.insertBefore(qualityButton, this.rightButtons.firstChild);\n }\n \n this.player.log('Quality button added dynamically', 'info');\n }\n\n updateQualityIndicator() {\n if (!this.controls.qualityText) return;\n if (!this.player.renderer || !this.player.renderer.getQualities) return;\n\n const qualities = this.player.renderer.getQualities();\n if (qualities.length === 0) {\n this.controls.qualityText.textContent = '';\n return;\n }\n\n // Get current quality\n let currentQualityText = '';\n \n // Check if it's HLS with auto mode\n if (this.player.renderer.hls && this.player.renderer.hls.currentLevel === -1) {\n currentQualityText = 'Auto';\n } else if (this.player.renderer.getCurrentQuality) {\n const currentIndex = this.player.renderer.getCurrentQuality();\n const currentQuality = qualities.find(q => q.index === currentIndex);\n if (currentQuality) {\n currentQualityText = currentQuality.height ? `${currentQuality.height}p` : '';\n }\n }\n\n this.controls.qualityText.textContent = currentQualityText;\n }\n\n setupAutoHide() {\n if (this.player.element.tagName !== 'VIDEO') return;\n\n const showControls = () => {\n this.element.classList.add(`${this.player.options.classPrefix}-controls-visible`);\n this.player.container.classList.add(`${this.player.options.classPrefix}-controls-visible`);\n this.player.state.controlsVisible = true;\n\n clearTimeout(this.hideTimeout);\n\n if (this.player.state.playing) {\n this.hideTimeout = setTimeout(() => {\n this.element.classList.remove(`${this.player.options.classPrefix}-controls-visible`);\n this.player.container.classList.remove(`${this.player.options.classPrefix}-controls-visible`);\n this.player.state.controlsVisible = false;\n }, this.player.options.hideControlsDelay);\n }\n };\n\n this.player.container.addEventListener('mousemove', showControls);\n this.player.container.addEventListener('touchstart', showControls);\n this.player.container.addEventListener('click', showControls);\n\n // Show controls on focus\n this.element.addEventListener('focusin', showControls);\n\n // Always show when paused\n this.player.on('pause', () => {\n showControls();\n clearTimeout(this.hideTimeout);\n });\n\n this.player.on('play', () => {\n showControls();\n });\n\n // Initial state\n showControls();\n }\n\n show() {\n this.element.style.display = '';\n }\n\n hide() {\n this.element.style.display = 'none';\n }\n\n destroy() {\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout);\n }\n\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n}\n\n", "/**\n * Caption/Subtitle Manager\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class CaptionManager {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.tracks = [];\n this.currentTrack = null;\n this.currentCue = null;\n \n this.init();\n }\n\n init() {\n this.createElement();\n this.loadTracks();\n this.attachEvents();\n \n if (this.player.options.captionsDefault && this.tracks.length > 0) {\n this.enable();\n }\n }\n\n createElement() {\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-captions`,\n attributes: {\n 'aria-live': 'polite',\n 'aria-atomic': 'true',\n 'role': 'region',\n 'aria-label': i18n.t('player.captions')\n }\n });\n\n // Apply caption styles\n this.updateStyles();\n \n // Append to videoWrapper if it exists, otherwise to container\n const target = this.player.videoWrapper || this.player.container;\n target.appendChild(this.element);\n }\n\n loadTracks() {\n const textTracks = this.player.element.textTracks;\n \n for (let i = 0; i < textTracks.length; i++) {\n const track = textTracks[i];\n \n if (track.kind === 'subtitles' || track.kind === 'captions') {\n this.tracks.push({\n track: track,\n language: track.language,\n label: track.label,\n kind: track.kind,\n index: i\n });\n \n // Disable all tracks initially\n track.mode = 'hidden';\n }\n }\n }\n\n attachEvents() {\n this.player.on('timeupdate', () => {\n this.updateCaptions();\n });\n\n this.player.on('captionschange', () => {\n this.updateStyles();\n });\n }\n\n enable(trackIndex = 0) {\n if (this.tracks.length === 0) {\n return;\n }\n\n // Disable current track\n if (this.currentTrack) {\n this.currentTrack.track.mode = 'hidden';\n }\n\n // Enable selected track\n const selectedTrack = this.tracks[trackIndex];\n \n if (selectedTrack) {\n // Set to 'hidden' not 'showing' to prevent browser from displaying native captions\n // We'll handle the display ourselves\n selectedTrack.track.mode = 'hidden';\n this.currentTrack = selectedTrack;\n this.player.state.captionsEnabled = true;\n \n // Remove any existing cuechange listener\n if (this.cueChangeHandler) {\n selectedTrack.track.removeEventListener('cuechange', this.cueChangeHandler);\n }\n \n // Add event listener for cue changes\n this.cueChangeHandler = () => {\n this.updateCaptions();\n };\n selectedTrack.track.addEventListener('cuechange', this.cueChangeHandler);\n \n this.element.style.display = 'block';\n \n this.player.emit('captionsenabled', selectedTrack);\n }\n }\n\n disable() {\n if (this.currentTrack) {\n this.currentTrack.track.mode = 'hidden';\n this.currentTrack = null;\n }\n\n this.element.style.display = 'none';\n this.element.innerHTML = '';\n this.currentCue = null;\n this.player.state.captionsEnabled = false;\n this.player.emit('captionsdisabled');\n }\n\n updateCaptions() {\n if (!this.currentTrack) {\n return;\n }\n \n if (!this.currentTrack.track.activeCues) {\n return;\n }\n\n const activeCues = this.currentTrack.track.activeCues;\n \n if (activeCues.length > 0) {\n const cue = activeCues[0];\n \n // Only update if the cue has changed\n if (this.currentCue !== cue) {\n this.currentCue = cue;\n \n // Parse and display cue text\n let text = cue.text;\n \n // Handle VTT formatting\n text = this.parseVTTFormatting(text);\n \n this.element.innerHTML = DOMUtils.sanitizeHTML(text);\n \n // Make sure it's visible when there's content\n this.element.style.display = 'block';\n \n this.player.emit('captionchange', cue);\n }\n } else if (this.currentCue) {\n // Clear caption\n this.element.innerHTML = '';\n this.element.style.display = 'none';\n this.currentCue = null;\n }\n }\n\n parseVTTFormatting(text) {\n // Basic VTT tag support\n text = text.replace(/<c[^>]*>(.*?)<\\/c>/g, '<span class=\"caption-class\">$1</span>');\n text = text.replace(/<b>(.*?)<\\/b>/g, '<strong>$1</strong>');\n text = text.replace(/<i>(.*?)<\\/i>/g, '<em>$1</em>');\n text = text.replace(/<u>(.*?)<\\/u>/g, '<u>$1</u>');\n \n // Voice tags\n text = text.replace(/<v\\s+([^>]+)>(.*?)<\\/v>/g, '<span class=\"caption-voice\" data-voice=\"$1\">$2</span>');\n \n return text;\n }\n\n updateStyles() {\n if (!this.element) return;\n\n const options = this.player.options;\n \n this.element.style.fontSize = options.captionsFontSize;\n this.element.style.fontFamily = options.captionsFontFamily;\n this.element.style.color = options.captionsColor;\n this.element.style.backgroundColor = this.hexToRgba(\n options.captionsBackgroundColor, \n options.captionsOpacity\n );\n }\n\n hexToRgba(hex, alpha) {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n if (result) {\n return `rgba(${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}, ${alpha})`;\n }\n return hex;\n }\n\n setCaptionStyle(property, value) {\n switch (property) {\n case 'fontSize':\n this.player.options.captionsFontSize = value;\n break;\n case 'fontFamily':\n this.player.options.captionsFontFamily = value;\n break;\n case 'color':\n this.player.options.captionsColor = value;\n break;\n case 'backgroundColor':\n this.player.options.captionsBackgroundColor = value;\n break;\n case 'opacity':\n this.player.options.captionsOpacity = value;\n break;\n }\n \n this.updateStyles();\n this.player.emit('captionschange');\n }\n\n getAvailableTracks() {\n return this.tracks.map((t, index) => ({\n index,\n language: t.language,\n label: t.label || t.language,\n kind: t.kind\n }));\n }\n\n switchTrack(trackIndex) {\n if (trackIndex >= 0 && trackIndex < this.tracks.length) {\n this.disable();\n this.enable(trackIndex);\n }\n }\n\n destroy() {\n this.disable();\n \n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n }\n}\n\n", "/**\n * Keyboard Accessibility Manager\n */\n\nexport class KeyboardManager {\n constructor(player) {\n this.player = player;\n this.shortcuts = player.options.keyboardShortcuts;\n \n this.init();\n }\n\n init() {\n this.attachEvents();\n }\n\n attachEvents() {\n // Listen for keyboard events on the player container\n this.player.container.addEventListener('keydown', (e) => {\n this.handleKeydown(e);\n });\n\n // Make player container focusable\n if (!this.player.container.hasAttribute('tabindex')) {\n this.player.container.setAttribute('tabindex', '0');\n }\n }\n\n handleKeydown(e) {\n // Don't handle if target is an input element\n if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') {\n return;\n }\n\n const key = e.key;\n let handled = false;\n\n // Check each shortcut category\n for (const [action, keys] of Object.entries(this.shortcuts)) {\n if (keys.includes(key)) {\n handled = this.executeAction(action, e);\n if (handled) {\n e.preventDefault();\n e.stopPropagation();\n this.announceAction(action);\n break;\n }\n }\n }\n }\n\n executeAction(action, event) {\n switch (action) {\n case 'play-pause':\n this.player.toggle();\n return true;\n\n case 'volume-up':\n this.player.setVolume(Math.min(1, this.player.state.volume + 0.1));\n return true;\n\n case 'volume-down':\n this.player.setVolume(Math.max(0, this.player.state.volume - 0.1));\n return true;\n\n case 'seek-forward':\n this.player.seekForward();\n return true;\n\n case 'seek-backward':\n this.player.seekBackward();\n return true;\n\n case 'seek-forward-large':\n this.player.seekForward(this.player.options.seekIntervalLarge);\n return true;\n\n case 'seek-backward-large':\n this.player.seekBackward(this.player.options.seekIntervalLarge);\n return true;\n\n case 'mute':\n this.player.toggleMute();\n return true;\n\n case 'fullscreen':\n this.player.toggleFullscreen();\n return true;\n\n case 'captions':\n // If only one caption track, toggle on/off\n // If multiple tracks, open caption menu\n if (this.player.captionManager && this.player.captionManager.tracks.length > 1) {\n const captionsButton = document.querySelector('.vidply-captions');\n if (captionsButton && this.player.controlBar) {\n this.player.controlBar.showCaptionsMenu(captionsButton);\n }\n } else {\n this.player.toggleCaptions();\n }\n return true;\n\n case 'speed-up':\n this.player.setPlaybackSpeed(\n Math.min(2, this.player.state.playbackSpeed + 0.25)\n );\n return true;\n\n case 'speed-down':\n this.player.setPlaybackSpeed(\n Math.max(0.25, this.player.state.playbackSpeed - 0.25)\n );\n return true;\n\n case 'settings':\n this.player.showSettings();\n return true;\n\n default:\n return false;\n }\n }\n\n announceAction(action) {\n if (!this.player.options.screenReaderAnnouncements) return;\n\n let message = '';\n\n switch (action) {\n case 'play-pause':\n message = this.player.state.playing ? 'Playing' : 'Paused';\n break;\n case 'volume-up':\n message = `Volume ${Math.round(this.player.state.volume * 100)}%`;\n break;\n case 'volume-down':\n message = `Volume ${Math.round(this.player.state.volume * 100)}%`;\n break;\n case 'mute':\n message = this.player.state.muted ? 'Muted' : 'Unmuted';\n break;\n case 'fullscreen':\n message = this.player.state.fullscreen ? 'Fullscreen' : 'Exit fullscreen';\n break;\n case 'captions':\n message = this.player.state.captionsEnabled ? 'Captions on' : 'Captions off';\n break;\n case 'speed-up':\n case 'speed-down':\n message = `Speed ${this.player.state.playbackSpeed}x`;\n break;\n }\n\n if (message) {\n this.announce(message);\n }\n }\n\n announce(message, priority = 'polite') {\n // Create or get announcement element\n let announcer = document.getElementById('vidply-announcer');\n \n if (!announcer) {\n announcer = document.createElement('div');\n announcer.id = 'vidply-announcer';\n announcer.className = 'vidply-sr-only';\n announcer.setAttribute('aria-live', priority);\n announcer.setAttribute('aria-atomic', 'true');\n announcer.style.cssText = `\n position: absolute;\n left: -10000px;\n width: 1px;\n height: 1px;\n overflow: hidden;\n `;\n document.body.appendChild(announcer);\n }\n\n // Clear and set new message\n announcer.textContent = '';\n setTimeout(() => {\n announcer.textContent = message;\n }, 100);\n }\n\n updateShortcut(action, keys) {\n if (Array.isArray(keys)) {\n this.shortcuts[action] = keys;\n }\n }\n\n destroy() {\n // Event listeners are automatically removed when the container is destroyed\n }\n}\n\n", "/**\n * Settings Dialog Component\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class SettingsDialog {\n constructor(player) {\n this.player = player;\n this.element = null;\n this.isOpen = false;\n \n this.init();\n }\n\n init() {\n this.createElement();\n }\n\n createElement() {\n // Create overlay\n this.overlay = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-overlay`,\n attributes: {\n 'role': 'dialog',\n 'aria-modal': 'true',\n 'aria-label': i18n.t('settings.title')\n }\n });\n\n this.overlay.style.display = 'none';\n\n // Create dialog\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-dialog`\n });\n\n // Header\n const header = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-header`\n });\n\n const title = DOMUtils.createElement('h2', {\n textContent: i18n.t('settings.title'),\n attributes: {\n 'id': `${this.player.options.classPrefix}-settings-title`\n }\n });\n\n const closeButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button ${this.player.options.classPrefix}-settings-close`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('settings.close')\n }\n });\n closeButton.appendChild(createIconElement('close'));\n closeButton.addEventListener('click', () => this.hide());\n\n header.appendChild(title);\n header.appendChild(closeButton);\n\n // Content\n const content = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-content`\n });\n\n content.appendChild(this.createSpeedSettings());\n \n if (this.player.captionManager && this.player.captionManager.tracks.length > 0) {\n content.appendChild(this.createCaptionSettings());\n }\n\n // Footer\n const footer = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-footer`\n });\n\n const resetButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-button`,\n textContent: i18n.t('settings.reset'),\n attributes: {\n 'type': 'button'\n }\n });\n resetButton.addEventListener('click', () => this.resetSettings());\n\n footer.appendChild(resetButton);\n\n // Assemble dialog\n this.element.appendChild(header);\n this.element.appendChild(content);\n this.element.appendChild(footer);\n\n this.overlay.appendChild(this.element);\n this.player.container.appendChild(this.overlay);\n\n // Attach events\n this.overlay.addEventListener('click', (e) => {\n if (e.target === this.overlay) {\n this.hide();\n }\n });\n\n // Escape key to close\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape' && this.isOpen) {\n this.hide();\n }\n });\n }\n\n formatSpeedLabel(speed) {\n // Special case: 1x is \"Normal\" (translated)\n if (speed === 1) {\n return i18n.t('speeds.normal');\n }\n \n // For other speeds, format with locale-specific decimal separator\n const speedStr = speed.toLocaleString(i18n.getLanguage(), {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2\n });\n \n return `${speedStr}\u00D7`;\n }\n\n createSpeedSettings() {\n const section = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-section`\n });\n\n const label = DOMUtils.createElement('label', {\n textContent: i18n.t('settings.speed'),\n attributes: {\n 'for': `${this.player.options.classPrefix}-speed-select`\n }\n });\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-settings-select`,\n attributes: {\n 'id': `${this.player.options.classPrefix}-speed-select`\n }\n });\n\n const speeds = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n \n speeds.forEach(speed => {\n const option = DOMUtils.createElement('option', {\n textContent: this.formatSpeedLabel(speed),\n attributes: {\n 'value': String(speed)\n }\n });\n \n if (speed === this.player.state.playbackSpeed) {\n option.selected = true;\n }\n \n select.appendChild(option);\n });\n\n select.addEventListener('change', (e) => {\n this.player.setPlaybackSpeed(parseFloat(e.target.value));\n });\n\n section.appendChild(label);\n section.appendChild(select);\n\n return section;\n }\n\n createCaptionSettings() {\n const section = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-section`\n });\n\n const heading = DOMUtils.createElement('h3', {\n textContent: i18n.t('settings.captions')\n });\n\n section.appendChild(heading);\n\n // Caption track selection\n const trackLabel = DOMUtils.createElement('label', {\n textContent: i18n.t('captions.select'),\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-track-select`\n }\n });\n\n const trackSelect = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-settings-select`,\n attributes: {\n 'id': `${this.player.options.classPrefix}-caption-track-select`\n }\n });\n\n // Off option\n const offOption = DOMUtils.createElement('option', {\n textContent: i18n.t('captions.off'),\n attributes: { 'value': '-1' }\n });\n trackSelect.appendChild(offOption);\n\n // Available tracks\n const tracks = this.player.captionManager.getAvailableTracks();\n tracks.forEach(track => {\n const option = DOMUtils.createElement('option', {\n textContent: track.label,\n attributes: { 'value': String(track.index) }\n });\n trackSelect.appendChild(option);\n });\n\n trackSelect.addEventListener('change', (e) => {\n const index = parseInt(e.target.value);\n if (index === -1) {\n this.player.disableCaptions();\n } else {\n this.player.captionManager.switchTrack(index);\n }\n });\n\n section.appendChild(trackLabel);\n section.appendChild(trackSelect);\n\n // Font size\n section.appendChild(this.createCaptionStyleControl('fontSize', i18n.t('captions.fontSize'), [\n { label: i18n.t('fontSizes.small'), value: '80%' },\n { label: i18n.t('fontSizes.medium'), value: '100%' },\n { label: i18n.t('fontSizes.large'), value: '120%' },\n { label: i18n.t('fontSizes.xlarge'), value: '150%' }\n ]));\n\n // Font family\n section.appendChild(this.createCaptionStyleControl('fontFamily', i18n.t('captions.fontFamily'), [\n { label: i18n.t('fontFamilies.sansSerif'), value: 'sans-serif' },\n { label: i18n.t('fontFamilies.serif'), value: 'serif' },\n { label: i18n.t('fontFamilies.monospace'), value: 'monospace' }\n ]));\n\n // Color controls\n section.appendChild(this.createColorControl('color', i18n.t('captions.color')));\n section.appendChild(this.createColorControl('backgroundColor', i18n.t('captions.backgroundColor')));\n\n // Opacity\n section.appendChild(this.createRangeControl('opacity', i18n.t('captions.opacity'), 0, 1, 0.1));\n\n return section;\n }\n\n createCaptionStyleControl(property, label, options) {\n const wrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-control`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n const select = DOMUtils.createElement('select', {\n className: `${this.player.options.classPrefix}-settings-select`,\n attributes: {\n 'id': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n options.forEach(opt => {\n const option = DOMUtils.createElement('option', {\n textContent: opt.label,\n attributes: { 'value': opt.value }\n });\n \n if (opt.value === this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`]) {\n option.selected = true;\n }\n \n select.appendChild(option);\n });\n\n select.addEventListener('change', (e) => {\n this.player.captionManager.setCaptionStyle(property, e.target.value);\n });\n\n wrapper.appendChild(labelEl);\n wrapper.appendChild(select);\n\n return wrapper;\n }\n\n createColorControl(property, label) {\n const wrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-control`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n const input = DOMUtils.createElement('input', {\n className: `${this.player.options.classPrefix}-settings-color`,\n attributes: {\n 'type': 'color',\n 'id': `${this.player.options.classPrefix}-caption-${property}`,\n 'value': this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`]\n }\n });\n\n input.addEventListener('change', (e) => {\n this.player.captionManager.setCaptionStyle(property, e.target.value);\n });\n\n wrapper.appendChild(labelEl);\n wrapper.appendChild(input);\n\n return wrapper;\n }\n\n createRangeControl(property, label, min, max, step) {\n const wrapper = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-settings-control`\n });\n\n const labelEl = DOMUtils.createElement('label', {\n textContent: label,\n attributes: {\n 'for': `${this.player.options.classPrefix}-caption-${property}`\n }\n });\n\n const input = DOMUtils.createElement('input', {\n className: `${this.player.options.classPrefix}-settings-range`,\n attributes: {\n 'type': 'range',\n 'id': `${this.player.options.classPrefix}-caption-${property}`,\n 'min': String(min),\n 'max': String(max),\n 'step': String(step),\n 'value': String(this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`])\n }\n });\n\n const valueDisplay = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-settings-value`,\n textContent: String(this.player.options[`captions${property.charAt(0).toUpperCase() + property.slice(1)}`])\n });\n\n input.addEventListener('input', (e) => {\n const value = parseFloat(e.target.value);\n valueDisplay.textContent = value.toFixed(1);\n this.player.captionManager.setCaptionStyle(property, value);\n });\n\n wrapper.appendChild(labelEl);\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n\n return wrapper;\n }\n\n resetSettings() {\n // Reset to default values\n this.player.setPlaybackSpeed(1);\n \n if (this.player.captionManager) {\n this.player.captionManager.setCaptionStyle('fontSize', '100%');\n this.player.captionManager.setCaptionStyle('fontFamily', 'sans-serif');\n this.player.captionManager.setCaptionStyle('color', '#FFFFFF');\n this.player.captionManager.setCaptionStyle('backgroundColor', '#000000');\n this.player.captionManager.setCaptionStyle('opacity', 0.8);\n }\n\n // Refresh dialog\n this.hide();\n setTimeout(() => this.show(), 100);\n }\n\n show() {\n this.overlay.style.display = 'flex';\n this.isOpen = true;\n \n // Focus the close button\n const closeButton = this.element.querySelector(`.${this.player.options.classPrefix}-settings-close`);\n if (closeButton) {\n closeButton.focus();\n }\n \n this.player.emit('settingsopen');\n }\n\n hide() {\n this.overlay.style.display = 'none';\n this.isOpen = false;\n \n // Return focus to settings button\n this.player.container.focus();\n \n this.player.emit('settingsclose');\n }\n\n destroy() {\n if (this.overlay && this.overlay.parentNode) {\n this.overlay.parentNode.removeChild(this.overlay);\n }\n }\n}\n\n", "/**\n * Transcript Manager Component\n * Manages transcript display and interaction\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { TimeUtils } from '../utils/TimeUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class TranscriptManager {\n constructor(player) {\n this.player = player;\n this.transcriptWindow = null;\n this.transcriptEntries = [];\n this.currentActiveEntry = null;\n this.isVisible = false;\n \n // Dragging state\n this.isDragging = false;\n this.dragOffsetX = 0;\n this.dragOffsetY = 0;\n \n // Store event handlers for cleanup\n this.handlers = {\n timeupdate: () => this.updateActiveEntry(),\n resize: null,\n mousemove: null,\n mouseup: null,\n touchmove: null,\n touchend: null,\n mousedown: null,\n touchstart: null,\n keydown: null\n };\n \n this.init();\n }\n\n init() {\n // Listen for time updates to highlight active transcript entry\n this.player.on('timeupdate', this.handlers.timeupdate);\n \n // Reposition transcript when entering/exiting fullscreen\n this.player.on('fullscreenchange', () => {\n if (this.isVisible) {\n // Add a small delay to ensure DOM has updated after fullscreen transition\n setTimeout(() => this.positionTranscript(), 100);\n }\n });\n }\n\n /**\n * Toggle transcript window visibility\n */\n toggleTranscript() {\n if (this.isVisible) {\n this.hideTranscript();\n } else {\n this.showTranscript();\n }\n }\n\n /**\n * Show transcript window\n */\n showTranscript() {\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'flex';\n this.isVisible = true;\n return;\n }\n\n // Create transcript window\n this.createTranscriptWindow();\n this.loadTranscriptData();\n \n // Show the window\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'flex';\n // Re-position after showing (in case window was resized while hidden)\n setTimeout(() => this.positionTranscript(), 0);\n }\n this.isVisible = true;\n }\n\n /**\n * Hide transcript window\n */\n hideTranscript() {\n if (this.transcriptWindow) {\n this.transcriptWindow.style.display = 'none';\n this.isVisible = false;\n }\n }\n\n /**\n * Create the transcript window UI\n */\n createTranscriptWindow() {\n this.transcriptWindow = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-window`,\n attributes: {\n 'role': 'dialog',\n 'aria-label': 'Video Transcript',\n 'tabindex': '-1'\n }\n });\n\n // Header (draggable)\n this.transcriptHeader = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-header`,\n attributes: {\n 'aria-label': 'Drag to reposition transcript. Use arrow keys to move, Home to reset position, Escape to close.',\n 'tabindex': '0'\n }\n });\n\n const title = DOMUtils.createElement('h3', {\n textContent: i18n.t('transcript.title')\n });\n\n const closeButton = DOMUtils.createElement('button', {\n className: `${this.player.options.classPrefix}-transcript-close`,\n attributes: {\n 'type': 'button',\n 'aria-label': i18n.t('transcript.close')\n }\n });\n closeButton.appendChild(createIconElement('close'));\n closeButton.addEventListener('click', () => this.hideTranscript());\n\n this.transcriptHeader.appendChild(title);\n this.transcriptHeader.appendChild(closeButton);\n\n // Content container\n this.transcriptContent = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-content`\n });\n\n this.transcriptWindow.appendChild(this.transcriptHeader);\n this.transcriptWindow.appendChild(this.transcriptContent);\n\n // Append to player container\n this.player.container.appendChild(this.transcriptWindow);\n \n // Position it next to the video wrapper\n this.positionTranscript();\n \n // Setup drag functionality\n this.setupDragAndDrop();\n \n // Re-position on window resize (debounced)\n let resizeTimeout;\n this.handlers.resize = () => {\n clearTimeout(resizeTimeout);\n resizeTimeout = setTimeout(() => this.positionTranscript(), 100);\n };\n window.addEventListener('resize', this.handlers.resize);\n }\n \n /**\n * Position transcript window next to video\n */\n positionTranscript() {\n if (!this.transcriptWindow || !this.player.videoWrapper || !this.isVisible) return;\n \n const isMobile = window.innerWidth < 640;\n const videoRect = this.player.videoWrapper.getBoundingClientRect();\n \n // Check if player is in fullscreen mode\n const isFullscreen = this.player.state.fullscreen;\n \n if (isMobile && !isFullscreen) {\n // Mobile: Position underneath the video and controls as part of the layout\n this.transcriptWindow.style.position = 'relative';\n this.transcriptWindow.style.left = '0';\n this.transcriptWindow.style.right = '0';\n this.transcriptWindow.style.bottom = 'auto';\n this.transcriptWindow.style.top = 'auto';\n this.transcriptWindow.style.width = '100%';\n this.transcriptWindow.style.maxWidth = '100%';\n this.transcriptWindow.style.maxHeight = '400px';\n this.transcriptWindow.style.height = 'auto';\n this.transcriptWindow.style.borderRadius = '0';\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.border = 'none';\n this.transcriptWindow.style.borderTop = '1px solid var(--vidply-border-light)';\n this.transcriptWindow.style.boxShadow = 'none';\n // Disable dragging on mobile\n if (this.transcriptHeader) {\n this.transcriptHeader.style.cursor = 'default';\n }\n \n // Ensure transcript is at the container level for proper stacking\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n } else if (isFullscreen) {\n // In fullscreen: position in bottom right corner inside the video\n this.transcriptWindow.style.position = 'fixed';\n this.transcriptWindow.style.left = 'auto';\n this.transcriptWindow.style.right = '20px';\n this.transcriptWindow.style.bottom = '80px'; // Above controls\n this.transcriptWindow.style.top = 'auto';\n this.transcriptWindow.style.maxHeight = 'calc(100vh - 180px)'; // Leave space for controls\n this.transcriptWindow.style.height = 'auto';\n this.transcriptWindow.style.width = '400px';\n this.transcriptWindow.style.maxWidth = '400px';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n this.transcriptWindow.style.borderTop = '';\n \n // Move back to container for fullscreen\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n } else {\n // Desktop mode: position next to video\n this.transcriptWindow.style.position = 'absolute';\n this.transcriptWindow.style.left = `${videoRect.width + 8}px`;\n this.transcriptWindow.style.right = 'auto';\n this.transcriptWindow.style.bottom = 'auto';\n this.transcriptWindow.style.top = '0';\n this.transcriptWindow.style.height = `${videoRect.height}px`;\n this.transcriptWindow.style.maxHeight = 'none';\n this.transcriptWindow.style.width = '400px';\n this.transcriptWindow.style.maxWidth = '400px';\n this.transcriptWindow.style.borderRadius = '8px';\n this.transcriptWindow.style.border = '1px solid var(--vidply-border)';\n this.transcriptWindow.style.borderTop = '';\n // Enable dragging on desktop\n if (this.transcriptHeader) {\n this.transcriptHeader.style.cursor = 'move';\n }\n \n // Move back to container for desktop\n if (this.transcriptWindow.parentNode !== this.player.container) {\n this.player.container.appendChild(this.transcriptWindow);\n }\n }\n }\n\n /**\n * Load transcript data from caption/subtitle tracks\n */\n loadTranscriptData() {\n this.transcriptEntries = [];\n this.transcriptContent.innerHTML = '';\n\n // Get caption/subtitle tracks\n const textTracks = Array.from(this.player.element.textTracks);\n const transcriptTrack = textTracks.find(\n track => track.kind === 'captions' || track.kind === 'subtitles'\n );\n\n if (!transcriptTrack) {\n this.showNoTranscriptMessage();\n return;\n }\n\n // Enable track to load cues\n if (transcriptTrack.mode === 'disabled') {\n transcriptTrack.mode = 'hidden';\n }\n\n if (!transcriptTrack.cues || transcriptTrack.cues.length === 0) {\n // Wait for cues to load\n const loadingMessage = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-loading`,\n textContent: i18n.t('transcript.loading')\n });\n this.transcriptContent.appendChild(loadingMessage);\n\n const onLoad = () => {\n this.loadTranscriptData();\n };\n\n transcriptTrack.addEventListener('load', onLoad, { once: true });\n\n // Fallback timeout\n setTimeout(() => {\n if (transcriptTrack.cues && transcriptTrack.cues.length > 0) {\n this.loadTranscriptData();\n }\n }, 500);\n \n return;\n }\n\n // Build transcript from cues\n const cues = Array.from(transcriptTrack.cues);\n cues.forEach((cue, index) => {\n const entry = this.createTranscriptEntry(cue, index);\n this.transcriptEntries.push({\n element: entry,\n cue: cue,\n startTime: cue.startTime,\n endTime: cue.endTime\n });\n this.transcriptContent.appendChild(entry);\n });\n }\n\n /**\n * Create a single transcript entry element\n */\n createTranscriptEntry(cue, index) {\n const entry = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-entry`,\n attributes: {\n 'data-start': String(cue.startTime),\n 'data-end': String(cue.endTime),\n 'role': 'button',\n 'tabindex': '0'\n }\n });\n\n const timestamp = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-time`,\n textContent: TimeUtils.formatTime(cue.startTime)\n });\n\n const text = DOMUtils.createElement('span', {\n className: `${this.player.options.classPrefix}-transcript-text`,\n textContent: this.stripVTTFormatting(cue.text)\n });\n\n entry.appendChild(timestamp);\n entry.appendChild(text);\n\n // Click to seek\n const seekToTime = () => {\n this.player.seek(cue.startTime);\n if (this.player.state.paused) {\n this.player.play();\n }\n };\n\n entry.addEventListener('click', seekToTime);\n entry.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n seekToTime();\n }\n });\n\n return entry;\n }\n\n /**\n * Strip VTT formatting tags from text\n */\n stripVTTFormatting(text) {\n // Remove VTT tags like <v Speaker>, <c>, etc.\n return text\n .replace(/<[^>]+>/g, '')\n .replace(/\\n/g, ' ')\n .trim();\n }\n\n /**\n * Show message when no transcript is available\n */\n showNoTranscriptMessage() {\n const message = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-transcript-empty`,\n textContent: i18n.t('transcript.noTranscript')\n });\n this.transcriptContent.appendChild(message);\n }\n\n /**\n * Update active transcript entry based on current time\n */\n updateActiveEntry() {\n if (!this.isVisible || this.transcriptEntries.length === 0) return;\n\n const currentTime = this.player.state.currentTime;\n \n // Find the entry that matches current time\n const activeEntry = this.transcriptEntries.find(\n entry => currentTime >= entry.startTime && currentTime < entry.endTime\n );\n\n if (activeEntry && activeEntry !== this.currentActiveEntry) {\n // Remove previous active class\n if (this.currentActiveEntry) {\n this.currentActiveEntry.element.classList.remove(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n }\n\n // Add active class to current entry\n activeEntry.element.classList.add(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n \n // Scroll to active entry\n this.scrollToEntry(activeEntry.element);\n \n this.currentActiveEntry = activeEntry;\n } else if (!activeEntry && this.currentActiveEntry) {\n // No active entry, remove active class\n this.currentActiveEntry.element.classList.remove(\n `${this.player.options.classPrefix}-transcript-entry-active`\n );\n this.currentActiveEntry = null;\n }\n }\n\n /**\n * Scroll transcript window to show active entry\n */\n scrollToEntry(entryElement) {\n if (!this.transcriptContent) return;\n\n const contentRect = this.transcriptContent.getBoundingClientRect();\n const entryRect = entryElement.getBoundingClientRect();\n\n // Check if entry is out of view\n if (entryRect.top < contentRect.top || entryRect.bottom > contentRect.bottom) {\n // Scroll to center the entry\n const scrollTop = entryElement.offsetTop - (this.transcriptContent.clientHeight / 2) + (entryElement.clientHeight / 2);\n this.transcriptContent.scrollTo({\n top: scrollTop,\n behavior: 'smooth'\n });\n }\n }\n\n /**\n * Setup drag and drop functionality\n */\n setupDragAndDrop() {\n if (!this.transcriptHeader || !this.transcriptWindow) return;\n\n // Create and store handler functions\n this.handlers.mousedown = (e) => {\n // Don't drag if clicking on close button\n if (e.target.closest(`.${this.player.options.classPrefix}-transcript-close`)) {\n return;\n }\n \n this.startDragging(e.clientX, e.clientY);\n e.preventDefault();\n };\n\n this.handlers.mousemove = (e) => {\n if (this.isDragging) {\n this.drag(e.clientX, e.clientY);\n }\n };\n\n this.handlers.mouseup = () => {\n if (this.isDragging) {\n this.stopDragging();\n }\n };\n\n this.handlers.touchstart = (e) => {\n if (e.target.closest(`.${this.player.options.classPrefix}-transcript-close`)) {\n return;\n }\n \n const isMobile = window.innerWidth < 640;\n const isFullscreen = this.player.state.fullscreen;\n const touch = e.touches[0];\n \n if (isMobile && !isFullscreen) {\n // Mobile (not fullscreen): No dragging/swiping, transcript is part of layout\n return;\n } else {\n // Desktop or fullscreen: Normal dragging\n this.startDragging(touch.clientX, touch.clientY);\n }\n };\n\n this.handlers.touchmove = (e) => {\n const isMobile = window.innerWidth < 640;\n const isFullscreen = this.player.state.fullscreen;\n \n if (isMobile && !isFullscreen) {\n // Mobile (not fullscreen): No dragging/swiping\n return;\n } else if (this.isDragging) {\n // Desktop or fullscreen: Normal drag\n const touch = e.touches[0];\n this.drag(touch.clientX, touch.clientY);\n e.preventDefault();\n }\n };\n\n this.handlers.touchend = () => {\n if (this.isDragging) {\n // Stop dragging\n this.stopDragging();\n }\n };\n\n this.handlers.keydown = (e) => {\n // Check if this is a navigation key\n if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'Escape'].includes(e.key)) {\n return;\n }\n \n // Prevent default behavior and stop event from bubbling to transcript entries\n e.preventDefault();\n e.stopPropagation();\n \n // Handle special keys first\n if (e.key === 'Home') {\n this.resetPosition();\n return;\n }\n \n if (e.key === 'Escape') {\n this.hideTranscript();\n return;\n }\n \n const step = e.shiftKey ? 50 : 10; // Larger steps with Shift key\n \n // Get current position\n let currentLeft = parseFloat(this.transcriptWindow.style.left) || 0;\n let currentTop = parseFloat(this.transcriptWindow.style.top) || 0;\n \n // If window is still centered with transform, convert to absolute position first\n const computedStyle = window.getComputedStyle(this.transcriptWindow);\n if (computedStyle.transform !== 'none') {\n const rect = this.transcriptWindow.getBoundingClientRect();\n currentLeft = rect.left;\n currentTop = rect.top;\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.left = `${currentLeft}px`;\n this.transcriptWindow.style.top = `${currentTop}px`;\n }\n \n // Calculate new position based on arrow key\n let newX = currentLeft;\n let newY = currentTop;\n\n switch(e.key) {\n case 'ArrowLeft':\n newX -= step;\n break;\n case 'ArrowRight':\n newX += step;\n break;\n case 'ArrowUp':\n newY -= step;\n break;\n case 'ArrowDown':\n newY += step;\n break;\n }\n\n // Set new position directly\n this.transcriptWindow.style.left = `${newX}px`;\n this.transcriptWindow.style.top = `${newY}px`;\n };\n\n // Add event listeners using stored handlers\n this.transcriptHeader.addEventListener('mousedown', this.handlers.mousedown);\n document.addEventListener('mousemove', this.handlers.mousemove);\n document.addEventListener('mouseup', this.handlers.mouseup);\n \n this.transcriptHeader.addEventListener('touchstart', this.handlers.touchstart);\n document.addEventListener('touchmove', this.handlers.touchmove);\n document.addEventListener('touchend', this.handlers.touchend);\n \n this.transcriptHeader.addEventListener('keydown', this.handlers.keydown);\n }\n\n /**\n * Start dragging\n */\n startDragging(clientX, clientY) {\n // Get current rendered position (this is where it actually appears on screen)\n const rect = this.transcriptWindow.getBoundingClientRect();\n \n // Get the parent container position (player container)\n const containerRect = this.player.container.getBoundingClientRect();\n \n // Calculate position RELATIVE to container (not viewport)\n const relativeLeft = rect.left - containerRect.left;\n const relativeTop = rect.top - containerRect.top;\n \n // If window is centered with transform, convert to absolute position\n const computedStyle = window.getComputedStyle(this.transcriptWindow);\n if (computedStyle.transform !== 'none') {\n // Remove transform and set position relative to container\n this.transcriptWindow.style.transform = 'none';\n this.transcriptWindow.style.left = `${relativeLeft}px`;\n this.transcriptWindow.style.top = `${relativeTop}px`;\n }\n \n // Calculate offset based on viewport coordinates (where user clicked)\n this.dragOffsetX = clientX - rect.left;\n this.dragOffsetY = clientY - rect.top;\n \n this.isDragging = true;\n this.transcriptWindow.classList.add(`${this.player.options.classPrefix}-transcript-dragging`);\n document.body.style.cursor = 'grabbing';\n document.body.style.userSelect = 'none';\n }\n\n /**\n * Perform drag\n */\n drag(clientX, clientY) {\n if (!this.isDragging) return;\n\n // Calculate new viewport position based on mouse position minus the offset\n const newViewportX = clientX - this.dragOffsetX;\n const newViewportY = clientY - this.dragOffsetY;\n \n // Convert to position relative to container\n const containerRect = this.player.container.getBoundingClientRect();\n const newX = newViewportX - containerRect.left;\n const newY = newViewportY - containerRect.top;\n \n // During drag, set position relative to container\n this.transcriptWindow.style.left = `${newX}px`;\n this.transcriptWindow.style.top = `${newY}px`;\n }\n\n /**\n * Stop dragging\n */\n stopDragging() {\n this.isDragging = false;\n this.transcriptWindow.classList.remove(`${this.player.options.classPrefix}-transcript-dragging`);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n\n /**\n * Set window position with boundary constraints\n */\n setPosition(x, y) {\n const rect = this.transcriptWindow.getBoundingClientRect();\n \n // Use document dimensions for fixed positioning\n const viewportWidth = document.documentElement.clientWidth;\n const viewportHeight = document.documentElement.clientHeight;\n \n // Very relaxed boundaries - allow window to go mostly off-screen\n // Just keep a small part visible so user can always drag it back\n const minVisible = 100; // Keep at least 100px visible\n const minX = -(rect.width - minVisible); // Can go way off-screen to the left\n const minY = -(rect.height - minVisible); // Can go way off-screen to the top\n const maxX = viewportWidth - minVisible; // Can go way off-screen to the right\n const maxY = viewportHeight - minVisible; // Can go way off-screen to the bottom\n \n // Clamp position to boundaries (very loose)\n x = Math.max(minX, Math.min(x, maxX));\n y = Math.max(minY, Math.min(y, maxY));\n \n this.transcriptWindow.style.left = `${x}px`;\n this.transcriptWindow.style.top = `${y}px`;\n this.transcriptWindow.style.transform = 'none';\n }\n\n /**\n * Reset position to center\n */\n resetPosition() {\n this.transcriptWindow.style.left = '50%';\n this.transcriptWindow.style.top = '50%';\n this.transcriptWindow.style.transform = 'translate(-50%, -50%)';\n }\n\n /**\n * Cleanup\n */\n destroy() {\n // Remove timeupdate listener from player\n if (this.handlers.timeupdate) {\n this.player.off('timeupdate', this.handlers.timeupdate);\n }\n\n // Remove drag event listeners\n if (this.transcriptHeader) {\n if (this.handlers.mousedown) {\n this.transcriptHeader.removeEventListener('mousedown', this.handlers.mousedown);\n }\n if (this.handlers.touchstart) {\n this.transcriptHeader.removeEventListener('touchstart', this.handlers.touchstart);\n }\n if (this.handlers.keydown) {\n this.transcriptHeader.removeEventListener('keydown', this.handlers.keydown);\n }\n }\n\n // Remove document-level listeners\n if (this.handlers.mousemove) {\n document.removeEventListener('mousemove', this.handlers.mousemove);\n }\n if (this.handlers.mouseup) {\n document.removeEventListener('mouseup', this.handlers.mouseup);\n }\n if (this.handlers.touchmove) {\n document.removeEventListener('touchmove', this.handlers.touchmove);\n }\n if (this.handlers.touchend) {\n document.removeEventListener('touchend', this.handlers.touchend);\n }\n \n // Remove window-level listeners\n if (this.handlers.resize) {\n window.removeEventListener('resize', this.handlers.resize);\n }\n\n // Clear handlers\n this.handlers = null;\n\n // Remove DOM element\n if (this.transcriptWindow && this.transcriptWindow.parentNode) {\n this.transcriptWindow.parentNode.removeChild(this.transcriptWindow);\n }\n \n this.transcriptWindow = null;\n this.transcriptHeader = null;\n this.transcriptContent = null;\n this.transcriptEntries = [];\n }\n}\n", "/**\n * VidPly - Universal Video Player\n * Main Player Class\n */\n\nimport { EventEmitter } from '../utils/EventEmitter.js';\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { TimeUtils } from '../utils/TimeUtils.js';\nimport { ControlBar } from '../controls/ControlBar.js';\nimport { CaptionManager } from '../controls/CaptionManager.js';\nimport { KeyboardManager } from '../controls/KeyboardManager.js';\nimport { SettingsDialog } from '../controls/SettingsDialog.js';\nimport { TranscriptManager } from '../controls/TranscriptManager.js';\nimport { HTML5Renderer } from '../renderers/HTML5Renderer.js';\nimport { YouTubeRenderer } from '../renderers/YouTubeRenderer.js';\nimport { VimeoRenderer } from '../renderers/VimeoRenderer.js';\nimport { HLSRenderer } from '../renderers/HLSRenderer.js';\nimport { createPlayOverlay } from '../icons/Icons.js';\nimport { i18n } from '../i18n/i18n.js';\n\nexport class Player extends EventEmitter {\n constructor(element, options = {}) {\n super();\n \n this.element = typeof element === 'string' ? document.querySelector(element) : element;\n if (!this.element) {\n throw new Error('VidPly: Element not found');\n }\n\n // Auto-create media element if a non-media element is provided\n if (this.element.tagName !== 'VIDEO' && this.element.tagName !== 'AUDIO') {\n const mediaType = options.mediaType || 'video';\n const mediaElement = document.createElement(mediaType);\n \n // Copy attributes from the div to the media element\n Array.from(this.element.attributes).forEach(attr => {\n if (attr.name !== 'id' && attr.name !== 'class' && !attr.name.startsWith('data-')) {\n mediaElement.setAttribute(attr.name, attr.value);\n }\n });\n \n // Copy any track elements from the div\n const tracks = this.element.querySelectorAll('track');\n tracks.forEach(track => {\n mediaElement.appendChild(track.cloneNode(true));\n });\n \n // Clear the div and insert the media element\n this.element.innerHTML = '';\n this.element.appendChild(mediaElement);\n \n // Update element reference to the actual media element\n this.element = mediaElement;\n }\n\n // Default options\n this.options = {\n // Display\n width: null,\n height: null,\n poster: null,\n responsive: true,\n fillContainer: false,\n \n // Playback\n autoplay: false,\n loop: false,\n muted: false,\n volume: 0.8,\n playbackSpeed: 1.0,\n preload: 'metadata',\n startTime: 0,\n \n // Controls\n controls: true,\n hideControlsDelay: 3000,\n playPauseButton: true,\n progressBar: true,\n currentTime: true,\n duration: true,\n volumeControl: true,\n muteButton: true,\n chaptersButton: true,\n qualityButton: true,\n captionStyleButton: true,\n speedButton: true,\n captionsButton: true,\n transcriptButton: true,\n fullscreenButton: true,\n pipButton: true,\n \n // Seeking\n seekInterval: 10,\n seekIntervalLarge: 30,\n \n // Captions\n captions: true,\n captionsDefault: false,\n captionsFontSize: '100%',\n captionsFontFamily: 'sans-serif',\n captionsColor: '#FFFFFF',\n captionsBackgroundColor: '#000000',\n captionsOpacity: 0.8,\n \n // Audio Description\n audioDescription: true,\n audioDescriptionSrc: null, // URL to audio-described version\n audioDescriptionButton: true,\n \n // Sign Language\n signLanguage: true,\n signLanguageSrc: null, // URL to sign language video\n signLanguageButton: true,\n signLanguagePosition: 'bottom-right', // Position: 'bottom-right', 'bottom-left', 'top-right', 'top-left'\n \n // Transcripts\n transcript: false,\n transcriptPosition: 'external',\n transcriptContainer: null,\n \n // Keyboard\n keyboard: true,\n keyboardShortcuts: {\n 'play-pause': [' ', 'p', 'k'],\n 'volume-up': ['ArrowUp'],\n 'volume-down': ['ArrowDown'],\n 'seek-forward': ['ArrowRight', 'f'],\n 'seek-backward': ['ArrowLeft', 'r'],\n 'seek-forward-large': ['l'],\n 'seek-backward-large': ['j'],\n 'mute': ['m'],\n 'fullscreen': ['f'],\n 'captions': ['c'],\n 'speed-up': ['>'],\n 'speed-down': ['<'],\n 'settings': ['s']\n },\n \n // Accessibility\n ariaLabels: {},\n screenReaderAnnouncements: true,\n highContrast: false,\n focusHighlight: true,\n \n // Languages\n language: 'en',\n languages: ['en'],\n \n // Advanced\n debug: false,\n classPrefix: 'vidply',\n iconType: 'svg',\n pauseOthersOnPlay: true,\n \n // Callbacks\n onReady: null,\n onPlay: null,\n onPause: null,\n onEnded: null,\n onTimeUpdate: null,\n onVolumeChange: null,\n onError: null,\n \n ...options\n };\n\n // State\n this.state = {\n ready: false,\n playing: false,\n paused: true,\n ended: false,\n buffering: false,\n seeking: false,\n muted: this.options.muted,\n volume: this.options.volume,\n currentTime: 0,\n duration: 0,\n playbackSpeed: this.options.playbackSpeed,\n fullscreen: false,\n pip: false,\n captionsEnabled: this.options.captionsDefault,\n currentCaption: null,\n controlsVisible: true,\n audioDescriptionEnabled: false,\n signLanguageEnabled: false\n };\n \n // Store original source for toggling\n this.originalSrc = null;\n this.audioDescriptionSrc = this.options.audioDescriptionSrc;\n this.signLanguageSrc = this.options.signLanguageSrc;\n this.signLanguageVideo = null;\n\n // Components\n this.container = null;\n this.renderer = null;\n this.controlBar = null;\n this.captionManager = null;\n this.keyboardManager = null;\n this.settingsDialog = null;\n\n // Initialize\n this.init();\n }\n\n async init() {\n try {\n this.log('Initializing VidPly player');\n \n // Auto-detect language from HTML lang attribute if not explicitly set\n if (!this.options.language || this.options.language === 'en') {\n const htmlLang = this.detectHtmlLanguage();\n if (htmlLang) {\n this.options.language = htmlLang;\n this.log(`Auto-detected language from HTML: ${htmlLang}`);\n }\n }\n \n // Set language\n i18n.setLanguage(this.options.language);\n \n // Create container\n this.createContainer();\n \n // Detect and initialize renderer (only if source exists)\n const src = this.element.src || this.element.querySelector('source')?.src;\n if (src) {\n await this.initializeRenderer();\n } else {\n this.log('No initial source - waiting for playlist or manual load');\n }\n \n // Create controls\n if (this.options.controls) {\n this.controlBar = new ControlBar(this);\n this.videoWrapper.appendChild(this.controlBar.element);\n }\n \n // Initialize captions\n if (this.options.captions) {\n this.captionManager = new CaptionManager(this);\n }\n \n // Initialize transcript\n if (this.options.transcript || this.options.transcriptButton) {\n this.transcriptManager = new TranscriptManager(this);\n }\n \n // Initialize keyboard controls\n if (this.options.keyboard) {\n this.keyboardManager = new KeyboardManager(this);\n }\n \n // Initialize settings dialog\n if (this.options.settingsButton) {\n this.settingsDialog = new SettingsDialog(this);\n }\n \n // Setup responsive handlers\n this.setupResponsiveHandlers();\n \n // Set initial state\n if (this.options.startTime > 0) {\n this.seek(this.options.startTime);\n }\n \n if (this.options.muted) {\n this.mute();\n }\n \n if (this.options.volume !== 0.8) {\n this.setVolume(this.options.volume);\n }\n \n // Mark as ready\n this.state.ready = true;\n this.emit('ready');\n \n if (this.options.onReady) {\n this.options.onReady.call(this);\n }\n \n // Autoplay if enabled\n if (this.options.autoplay) {\n this.play();\n }\n \n this.log('Player initialized successfully');\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Detect language from HTML lang attribute\n * @returns {string|null} Language code if available in translations, null otherwise\n */\n detectHtmlLanguage() {\n // Try to get lang from html element\n const htmlLang = document.documentElement.lang || document.documentElement.getAttribute('lang');\n \n if (!htmlLang) {\n return null;\n }\n \n // Normalize the language code (e.g., \"en-US\" -> \"en\", \"de-DE\" -> \"de\")\n const normalizedLang = htmlLang.toLowerCase().split('-')[0];\n \n // Check if this language is available in our translations\n const availableLanguages = ['en', 'de', 'es', 'fr', 'ja'];\n \n if (availableLanguages.includes(normalizedLang)) {\n return normalizedLang;\n }\n \n // Language not available, will fallback to English\n this.log(`Language \"${htmlLang}\" not available, using English as fallback`);\n return 'en';\n }\n\n createContainer() {\n // Create main container\n this.container = DOMUtils.createElement('div', {\n className: `${this.options.classPrefix}-player`,\n attributes: {\n 'role': 'region',\n 'aria-label': i18n.t('player.label'),\n 'tabindex': '0'\n }\n });\n\n // Add media type class\n const mediaType = this.element.tagName.toLowerCase();\n this.container.classList.add(`${this.options.classPrefix}-${mediaType}`);\n\n // Add responsive class\n if (this.options.responsive) {\n this.container.classList.add(`${this.options.classPrefix}-responsive`);\n }\n\n // Create video wrapper (for proper positioning of controls)\n this.videoWrapper = DOMUtils.createElement('div', {\n className: `${this.options.classPrefix}-video-wrapper`\n });\n\n // Wrap original element\n this.element.parentNode.insertBefore(this.container, this.element);\n this.container.appendChild(this.videoWrapper);\n this.videoWrapper.appendChild(this.element);\n \n // Hide native controls and set dimensions\n this.element.controls = false;\n this.element.removeAttribute('controls');\n this.element.setAttribute('tabindex', '-1'); // Remove from tab order\n this.element.style.width = '100%';\n this.element.style.height = '100%';\n \n // Set dimensions\n if (this.options.width) {\n this.container.style.width = typeof this.options.width === 'number' \n ? `${this.options.width}px` \n : this.options.width;\n }\n \n if (this.options.height) {\n this.container.style.height = typeof this.options.height === 'number'\n ? `${this.options.height}px`\n : this.options.height;\n }\n \n // Set poster\n if (this.options.poster && this.element.tagName === 'VIDEO') {\n this.element.poster = this.options.poster;\n }\n \n // Create centered play button overlay (only for video)\n if (this.element.tagName === 'VIDEO') {\n this.createPlayButtonOverlay();\n }\n \n // Make video/audio element clickable to toggle play/pause\n this.element.style.cursor = 'pointer';\n this.element.addEventListener('click', (e) => {\n // Prevent if clicking on native controls (shouldn't happen but just in case)\n if (e.target === this.element) {\n this.toggle();\n }\n });\n }\n\n createPlayButtonOverlay() {\n // Create complete SVG play button from Icons.js\n this.playButtonOverlay = createPlayOverlay();\n \n // Add click handler\n this.playButtonOverlay.addEventListener('click', () => {\n this.toggle();\n });\n \n // Add to video wrapper\n this.videoWrapper.appendChild(this.playButtonOverlay);\n \n // Show/hide based on play state\n this.on('play', () => {\n this.playButtonOverlay.style.opacity = '0';\n this.playButtonOverlay.style.pointerEvents = 'none';\n });\n \n this.on('pause', () => {\n this.playButtonOverlay.style.opacity = '1';\n this.playButtonOverlay.style.pointerEvents = 'auto';\n });\n \n this.on('ended', () => {\n this.playButtonOverlay.style.opacity = '1';\n this.playButtonOverlay.style.pointerEvents = 'auto';\n });\n }\n\n async initializeRenderer() {\n const src = this.element.src || this.element.querySelector('source')?.src;\n \n if (!src) {\n throw new Error('No media source found');\n }\n\n // Store original source for audio description toggling\n if (!this.originalSrc) {\n this.originalSrc = src;\n }\n\n // Detect media type\n let renderer;\n \n if (src.includes('youtube.com') || src.includes('youtu.be')) {\n renderer = YouTubeRenderer;\n } else if (src.includes('vimeo.com')) {\n renderer = VimeoRenderer;\n } else if (src.includes('.m3u8')) {\n renderer = HLSRenderer;\n } else {\n renderer = HTML5Renderer;\n }\n\n this.log(`Using ${renderer.name} renderer`);\n this.renderer = new renderer(this);\n await this.renderer.init();\n }\n\n /**\n * Load new media source (for playlists)\n * @param {Object} config - Media configuration\n * @param {string} config.src - Media source URL\n * @param {string} config.type - Media MIME type\n * @param {string} [config.poster] - Poster image URL\n * @param {Array} [config.tracks] - Text tracks (captions, chapters, etc.)\n */\n async load(config) {\n try {\n this.log('Loading new media:', config.src);\n \n // Pause current playback\n if (this.renderer) {\n this.pause();\n }\n \n // Clear existing text tracks\n const existingTracks = this.element.querySelectorAll('track');\n existingTracks.forEach(track => track.remove());\n \n // Update media element\n this.element.src = config.src;\n \n if (config.type) {\n this.element.type = config.type;\n }\n \n if (config.poster && this.element.tagName === 'VIDEO') {\n this.element.poster = config.poster;\n }\n \n // Add new text tracks\n if (config.tracks && config.tracks.length > 0) {\n config.tracks.forEach(trackConfig => {\n const track = document.createElement('track');\n track.src = trackConfig.src;\n track.kind = trackConfig.kind || 'captions';\n track.srclang = trackConfig.srclang || 'en';\n track.label = trackConfig.label || trackConfig.srclang;\n \n if (trackConfig.default) {\n track.default = true;\n }\n \n this.element.appendChild(track);\n });\n }\n \n // Check if we need to change renderer type\n const shouldChangeRenderer = this.shouldChangeRenderer(config.src);\n \n // Destroy old renderer if changing types\n if (shouldChangeRenderer && this.renderer) {\n this.renderer.destroy();\n this.renderer = null;\n }\n \n // Initialize or reinitialize renderer\n if (!this.renderer || shouldChangeRenderer) {\n await this.initializeRenderer();\n } else {\n // Just reload the current renderer with the updated element\n this.renderer.media = this.element; // Update media reference\n this.element.load();\n }\n \n // Reinitialize caption manager to pick up new tracks\n if (this.captionManager) {\n this.captionManager.destroy();\n this.captionManager = new CaptionManager(this);\n }\n \n this.emit('sourcechange', config);\n this.log('Media loaded successfully');\n \n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Check if we need to change renderer type\n * @param {string} src - New source URL\n * @returns {boolean}\n */\n shouldChangeRenderer(src) {\n if (!this.renderer) return true;\n \n const isYouTube = src.includes('youtube.com') || src.includes('youtu.be');\n const isVimeo = src.includes('vimeo.com');\n const isHLS = src.includes('.m3u8');\n \n const currentRendererName = this.renderer.constructor.name;\n \n if (isYouTube && currentRendererName !== 'YouTubeRenderer') return true;\n if (isVimeo && currentRendererName !== 'VimeoRenderer') return true;\n if (isHLS && currentRendererName !== 'HLSRenderer') return true;\n if (!isYouTube && !isVimeo && !isHLS && currentRendererName !== 'HTML5Renderer') return true;\n \n return false;\n }\n\n // Playback controls\n play() {\n if (this.renderer) {\n this.renderer.play();\n }\n }\n\n pause() {\n if (this.renderer) {\n this.renderer.pause();\n }\n }\n\n stop() {\n this.pause();\n this.seek(0);\n }\n\n toggle() {\n if (this.state.playing) {\n this.pause();\n } else {\n this.play();\n }\n }\n\n seek(time) {\n if (this.renderer) {\n this.renderer.seek(time);\n }\n }\n\n seekForward(interval = this.options.seekInterval) {\n this.seek(Math.min(this.state.currentTime + interval, this.state.duration));\n }\n\n seekBackward(interval = this.options.seekInterval) {\n this.seek(Math.max(this.state.currentTime - interval, 0));\n }\n\n // Volume controls\n setVolume(volume) {\n const newVolume = Math.max(0, Math.min(1, volume));\n if (this.renderer) {\n this.renderer.setVolume(newVolume);\n }\n this.state.volume = newVolume;\n \n if (newVolume > 0 && this.state.muted) {\n this.state.muted = false;\n }\n }\n\n getVolume() {\n return this.state.volume;\n }\n\n mute() {\n if (this.renderer) {\n this.renderer.setMuted(true);\n }\n this.state.muted = true;\n }\n\n unmute() {\n if (this.renderer) {\n this.renderer.setMuted(false);\n }\n this.state.muted = false;\n }\n\n toggleMute() {\n if (this.state.muted) {\n this.unmute();\n } else {\n this.mute();\n }\n }\n\n // Playback speed\n setPlaybackSpeed(speed) {\n const newSpeed = Math.max(0.25, Math.min(2, speed));\n if (this.renderer) {\n this.renderer.setPlaybackSpeed(newSpeed);\n }\n this.state.playbackSpeed = newSpeed;\n this.emit('playbackspeedchange', newSpeed);\n }\n\n getPlaybackSpeed() {\n return this.state.playbackSpeed;\n }\n\n // Fullscreen\n enterFullscreen() {\n const elem = this.container;\n \n if (elem.requestFullscreen) {\n elem.requestFullscreen();\n } else if (elem.webkitRequestFullscreen) {\n elem.webkitRequestFullscreen();\n } else if (elem.mozRequestFullScreen) {\n elem.mozRequestFullScreen();\n } else if (elem.msRequestFullscreen) {\n elem.msRequestFullscreen();\n }\n \n this.state.fullscreen = true;\n this.container.classList.add(`${this.options.classPrefix}-fullscreen`);\n this.emit('fullscreenchange', true);\n }\n\n exitFullscreen() {\n if (document.exitFullscreen) {\n document.exitFullscreen();\n } else if (document.webkitExitFullscreen) {\n document.webkitExitFullscreen();\n } else if (document.mozCancelFullScreen) {\n document.mozCancelFullScreen();\n } else if (document.msExitFullscreen) {\n document.msExitFullscreen();\n }\n \n this.state.fullscreen = false;\n this.container.classList.remove(`${this.options.classPrefix}-fullscreen`);\n this.emit('fullscreenchange', false);\n }\n\n toggleFullscreen() {\n if (this.state.fullscreen) {\n this.exitFullscreen();\n } else {\n this.enterFullscreen();\n }\n }\n\n // Picture-in-Picture\n enterPiP() {\n if (this.element.requestPictureInPicture) {\n this.element.requestPictureInPicture();\n this.state.pip = true;\n this.emit('pipchange', true);\n }\n }\n\n exitPiP() {\n if (document.pictureInPictureElement) {\n document.exitPictureInPicture();\n this.state.pip = false;\n this.emit('pipchange', false);\n }\n }\n\n togglePiP() {\n if (this.state.pip) {\n this.exitPiP();\n } else {\n this.enterPiP();\n }\n }\n\n // Captions\n enableCaptions() {\n if (this.captionManager) {\n this.captionManager.enable();\n this.state.captionsEnabled = true;\n }\n }\n\n disableCaptions() {\n if (this.captionManager) {\n this.captionManager.disable();\n this.state.captionsEnabled = false;\n }\n }\n\n toggleCaptions() {\n if (this.state.captionsEnabled) {\n this.disableCaptions();\n } else {\n this.enableCaptions();\n }\n }\n\n // Audio Description\n async enableAudioDescription() {\n if (!this.audioDescriptionSrc) {\n console.warn('VidPly: No audio description source provided');\n return;\n }\n\n // Store current playback state\n const currentTime = this.state.currentTime;\n const wasPlaying = this.state.playing;\n\n // Switch to audio-described version\n this.element.src = this.audioDescriptionSrc;\n \n // Wait for new source to load\n await new Promise((resolve) => {\n const onLoadedMetadata = () => {\n this.element.removeEventListener('loadedmetadata', onLoadedMetadata);\n resolve();\n };\n this.element.addEventListener('loadedmetadata', onLoadedMetadata);\n });\n\n // Restore playback position\n this.seek(currentTime);\n \n if (wasPlaying) {\n this.play();\n }\n\n this.state.audioDescriptionEnabled = true;\n this.emit('audiodescriptionenabled');\n }\n\n async disableAudioDescription() {\n if (!this.originalSrc) {\n return;\n }\n\n // Store current playback state\n const currentTime = this.state.currentTime;\n const wasPlaying = this.state.playing;\n\n // Switch back to original version\n this.element.src = this.originalSrc;\n \n // Wait for new source to load\n await new Promise((resolve) => {\n const onLoadedMetadata = () => {\n this.element.removeEventListener('loadedmetadata', onLoadedMetadata);\n resolve();\n };\n this.element.addEventListener('loadedmetadata', onLoadedMetadata);\n });\n\n // Restore playback position\n this.seek(currentTime);\n \n if (wasPlaying) {\n this.play();\n }\n\n this.state.audioDescriptionEnabled = false;\n this.emit('audiodescriptiondisabled');\n }\n\n async toggleAudioDescription() {\n if (this.state.audioDescriptionEnabled) {\n await this.disableAudioDescription();\n } else {\n await this.enableAudioDescription();\n }\n }\n\n // Sign Language\n enableSignLanguage() {\n if (!this.signLanguageSrc) {\n console.warn('No sign language video source provided');\n return;\n }\n\n if (this.signLanguageVideo) {\n // Already exists, just show it\n this.signLanguageVideo.style.display = 'block';\n this.state.signLanguageEnabled = true;\n this.emit('signlanguageenabled');\n return;\n }\n\n // Create sign language video element\n this.signLanguageVideo = document.createElement('video');\n this.signLanguageVideo.className = 'vidply-sign-language-video';\n this.signLanguageVideo.src = this.signLanguageSrc;\n this.signLanguageVideo.setAttribute('aria-label', i18n.t('player.signLanguage'));\n \n // Set position based on options\n const position = this.options.signLanguagePosition || 'bottom-right';\n this.signLanguageVideo.classList.add(`vidply-sign-position-${position}`);\n \n // Sync with main video\n this.signLanguageVideo.muted = true; // Sign language video should be muted\n this.signLanguageVideo.currentTime = this.state.currentTime;\n if (!this.state.paused) {\n this.signLanguageVideo.play();\n }\n\n // Add to video wrapper (so it overlays the video, not the entire container)\n this.videoWrapper.appendChild(this.signLanguageVideo);\n\n // Create bound handlers to store references for cleanup\n this.signLanguageHandlers = {\n play: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.play();\n }\n },\n pause: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.pause();\n }\n },\n timeupdate: () => {\n if (this.signLanguageVideo && Math.abs(this.signLanguageVideo.currentTime - this.state.currentTime) > 0.5) {\n this.signLanguageVideo.currentTime = this.state.currentTime;\n }\n },\n ratechange: () => {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.playbackRate = this.state.playbackSpeed;\n }\n }\n };\n\n // Sync playback\n this.on('play', this.signLanguageHandlers.play);\n this.on('pause', this.signLanguageHandlers.pause);\n this.on('timeupdate', this.signLanguageHandlers.timeupdate);\n this.on('ratechange', this.signLanguageHandlers.ratechange);\n\n this.state.signLanguageEnabled = true;\n this.emit('signlanguageenabled');\n }\n\n disableSignLanguage() {\n if (this.signLanguageVideo) {\n this.signLanguageVideo.style.display = 'none';\n }\n this.state.signLanguageEnabled = false;\n this.emit('signlanguagedisabled');\n }\n\n toggleSignLanguage() {\n if (this.state.signLanguageEnabled) {\n this.disableSignLanguage();\n } else {\n this.enableSignLanguage();\n }\n }\n\n cleanupSignLanguage() {\n // Remove event listeners\n if (this.signLanguageHandlers) {\n this.off('play', this.signLanguageHandlers.play);\n this.off('pause', this.signLanguageHandlers.pause);\n this.off('timeupdate', this.signLanguageHandlers.timeupdate);\n this.off('ratechange', this.signLanguageHandlers.ratechange);\n this.signLanguageHandlers = null;\n }\n\n // Remove video element\n if (this.signLanguageVideo && this.signLanguageVideo.parentNode) {\n this.signLanguageVideo.pause();\n this.signLanguageVideo.src = '';\n this.signLanguageVideo.parentNode.removeChild(this.signLanguageVideo);\n this.signLanguageVideo = null;\n }\n }\n\n // Settings\n showSettings() {\n if (this.settingsDialog) {\n this.settingsDialog.show();\n }\n }\n\n hideSettings() {\n if (this.settingsDialog) {\n this.settingsDialog.hide();\n }\n }\n\n // Utility methods\n getCurrentTime() {\n return this.state.currentTime;\n }\n\n getDuration() {\n return this.state.duration;\n }\n\n isPlaying() {\n return this.state.playing;\n }\n\n isPaused() {\n return this.state.paused;\n }\n\n isEnded() {\n return this.state.ended;\n }\n\n isMuted() {\n return this.state.muted;\n }\n\n isFullscreen() {\n return this.state.fullscreen;\n }\n\n // Error handling\n handleError(error) {\n this.log('Error:', error, 'error');\n this.emit('error', error);\n \n if (this.options.onError) {\n this.options.onError.call(this, error);\n }\n }\n\n // Logging\n log(message, type = 'log') {\n if (this.options.debug) {\n console[type](`[VidPly]`, message);\n }\n }\n\n // Setup responsive handlers\n setupResponsiveHandlers() {\n // Use ResizeObserver for efficient resize tracking\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const width = entry.contentRect.width;\n \n // Update control bar for viewport\n if (this.controlBar && typeof this.controlBar.updateControlsForViewport === 'function') {\n this.controlBar.updateControlsForViewport(width);\n }\n \n // Update transcript positioning\n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n }\n });\n \n this.resizeObserver.observe(this.container);\n } else {\n // Fallback to window resize event\n this.resizeHandler = () => {\n const width = this.container.clientWidth;\n \n if (this.controlBar && typeof this.controlBar.updateControlsForViewport === 'function') {\n this.controlBar.updateControlsForViewport(width);\n }\n \n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n };\n \n window.addEventListener('resize', this.resizeHandler);\n }\n \n // Also listen for orientation changes on mobile\n if (window.matchMedia) {\n this.orientationHandler = (e) => {\n // Wait for layout to settle\n setTimeout(() => {\n if (this.transcriptManager && this.transcriptManager.isVisible) {\n this.transcriptManager.positionTranscript();\n }\n }, 100);\n };\n \n const orientationQuery = window.matchMedia('(orientation: portrait)');\n if (orientationQuery.addEventListener) {\n orientationQuery.addEventListener('change', this.orientationHandler);\n } else if (orientationQuery.addListener) {\n // Fallback for older browsers\n orientationQuery.addListener(this.orientationHandler);\n }\n \n this.orientationQuery = orientationQuery;\n }\n }\n\n // Cleanup\n destroy() {\n this.log('Destroying player');\n \n if (this.renderer) {\n this.renderer.destroy();\n }\n \n if (this.controlBar) {\n this.controlBar.destroy();\n }\n \n if (this.captionManager) {\n this.captionManager.destroy();\n }\n \n if (this.keyboardManager) {\n this.keyboardManager.destroy();\n }\n \n if (this.settingsDialog) {\n this.settingsDialog.destroy();\n }\n \n if (this.transcriptManager) {\n this.transcriptManager.destroy();\n }\n \n // Cleanup sign language video and listeners\n this.cleanupSignLanguage();\n \n // Cleanup play overlay button\n if (this.playButtonOverlay && this.playButtonOverlay.parentNode) {\n this.playButtonOverlay.remove();\n this.playButtonOverlay = null;\n }\n \n // Cleanup resize observer\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n \n // Cleanup window resize handler\n if (this.resizeHandler) {\n window.removeEventListener('resize', this.resizeHandler);\n this.resizeHandler = null;\n }\n \n // Cleanup orientation change handler\n if (this.orientationQuery && this.orientationHandler) {\n if (this.orientationQuery.removeEventListener) {\n this.orientationQuery.removeEventListener('change', this.orientationHandler);\n } else if (this.orientationQuery.removeListener) {\n this.orientationQuery.removeListener(this.orientationHandler);\n }\n this.orientationQuery = null;\n this.orientationHandler = null;\n }\n \n // Remove container\n if (this.container && this.container.parentNode) {\n this.container.parentNode.insertBefore(this.element, this.container);\n this.container.parentNode.removeChild(this.container);\n }\n \n this.removeAllListeners();\n }\n}\n\n// Static instances tracker for pause others functionality\nPlayer.instances = [];\n\n", "/**\n * YouTube Renderer\n */\n\nexport class YouTubeRenderer {\n constructor(player) {\n this.player = player;\n this.youtube = null;\n this.videoId = null;\n this.isReady = false;\n this.iframe = null;\n }\n\n async init() {\n // Extract video ID from URL\n this.videoId = this.extractVideoId(this.player.element.src);\n \n if (!this.videoId) {\n throw new Error('Invalid YouTube URL');\n }\n\n // Load YouTube IFrame API\n await this.loadYouTubeAPI();\n\n // Create iframe\n this.createIframe();\n\n // Initialize player\n await this.initializePlayer();\n }\n\n extractVideoId(url) {\n const patterns = [\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([^&\\s]+)/,\n /youtube\\.com\\/embed\\/([^&\\s]+)/\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n async loadYouTubeAPI() {\n // Check if API is already loaded\n if (window.YT && window.YT.Player) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n // Check if script is already being loaded\n if (window.onYouTubeIframeAPIReady) {\n const originalCallback = window.onYouTubeIframeAPIReady;\n window.onYouTubeIframeAPIReady = () => {\n originalCallback();\n resolve();\n };\n return;\n }\n\n // Load the API script\n const tag = document.createElement('script');\n tag.src = 'https://www.youtube.com/iframe_api';\n \n window.onYouTubeIframeAPIReady = () => {\n resolve();\n };\n\n tag.onerror = () => reject(new Error('Failed to load YouTube API'));\n \n const firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n });\n }\n\n createIframe() {\n // Hide original element\n this.player.element.style.display = 'none';\n\n // Create container for iframe\n this.iframe = document.createElement('div');\n this.iframe.id = `youtube-player-${Math.random().toString(36).substr(2, 9)}`;\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n \n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\n }\n\n async initializePlayer() {\n return new Promise((resolve) => {\n this.youtube = new window.YT.Player(this.iframe.id, {\n videoId: this.videoId,\n width: '100%',\n height: '100%',\n playerVars: {\n controls: 0,\n disablekb: 1,\n fs: 0,\n modestbranding: 1,\n rel: 0,\n showinfo: 0,\n iv_load_policy: 3,\n autoplay: this.player.options.autoplay ? 1 : 0,\n mute: this.player.options.muted ? 1 : 0,\n start: this.player.options.startTime || 0\n },\n events: {\n onReady: (event) => {\n this.isReady = true;\n this.attachEvents();\n resolve();\n },\n onStateChange: (event) => this.handleStateChange(event),\n onError: (event) => this.handleError(event)\n }\n });\n });\n }\n\n attachEvents() {\n // Set up polling for time updates (YouTube doesn't provide timeupdate events)\n this.timeUpdateInterval = setInterval(() => {\n if (this.isReady && this.youtube) {\n const currentTime = this.youtube.getCurrentTime();\n const duration = this.youtube.getDuration();\n \n this.player.state.currentTime = currentTime;\n this.player.state.duration = duration;\n \n this.player.emit('timeupdate', currentTime);\n }\n }, 250);\n\n // Initial metadata\n if (this.youtube.getDuration) {\n this.player.state.duration = this.youtube.getDuration();\n this.player.emit('loadedmetadata');\n }\n }\n\n handleStateChange(event) {\n const states = window.YT.PlayerState;\n\n switch (event.data) {\n case states.PLAYING:\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.state.buffering = false;\n this.player.emit('play');\n this.player.emit('playing');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n break;\n\n case states.PAUSED:\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n break;\n\n case states.ENDED:\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n if (this.player.options.loop) {\n this.youtube.seekTo(0);\n this.youtube.playVideo();\n }\n break;\n\n case states.BUFFERING:\n this.player.state.buffering = true;\n this.player.emit('waiting');\n break;\n\n case states.CUED:\n this.player.emit('loadedmetadata');\n break;\n }\n }\n\n handleError(event) {\n const errors = {\n 2: 'Invalid video ID',\n 5: 'HTML5 player error',\n 100: 'Video not found',\n 101: 'Video not allowed to be played in embedded players',\n 150: 'Video not allowed to be played in embedded players'\n };\n\n const error = new Error(errors[event.data] || 'YouTube player error');\n this.player.handleError(error);\n }\n\n play() {\n if (this.isReady && this.youtube) {\n this.youtube.playVideo();\n }\n }\n\n pause() {\n if (this.isReady && this.youtube) {\n this.youtube.pauseVideo();\n }\n }\n\n seek(time) {\n if (this.isReady && this.youtube) {\n this.youtube.seekTo(time, true);\n }\n }\n\n setVolume(volume) {\n if (this.isReady && this.youtube) {\n this.youtube.setVolume(volume * 100);\n this.player.state.volume = volume;\n }\n }\n\n setMuted(muted) {\n if (this.isReady && this.youtube) {\n if (muted) {\n this.youtube.mute();\n } else {\n this.youtube.unMute();\n }\n this.player.state.muted = muted;\n }\n }\n\n setPlaybackSpeed(speed) {\n if (this.isReady && this.youtube) {\n this.youtube.setPlaybackRate(speed);\n this.player.state.playbackSpeed = speed;\n }\n }\n\n destroy() {\n if (this.timeUpdateInterval) {\n clearInterval(this.timeUpdateInterval);\n }\n\n if (this.youtube && this.youtube.destroy) {\n this.youtube.destroy();\n }\n\n if (this.iframe && this.iframe.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n // Show original element\n if (this.player.element) {\n this.player.element.style.display = '';\n }\n }\n}\n\n", "/**\n * Vimeo Renderer\n */\n\nexport class VimeoRenderer {\n constructor(player) {\n this.player = player;\n this.vimeo = null;\n this.videoId = null;\n this.isReady = false;\n this.iframe = null;\n }\n\n async init() {\n // Extract video ID from URL\n this.videoId = this.extractVideoId(this.player.element.src);\n \n if (!this.videoId) {\n throw new Error('Invalid Vimeo URL');\n }\n\n // Load Vimeo Player API\n await this.loadVimeoAPI();\n\n // Create iframe\n this.createIframe();\n\n // Initialize player\n await this.initializePlayer();\n }\n\n extractVideoId(url) {\n const patterns = [\n /vimeo\\.com\\/(\\d+)/,\n /vimeo\\.com\\/video\\/(\\d+)/,\n /player\\.vimeo\\.com\\/video\\/(\\d+)/\n ];\n\n for (const pattern of patterns) {\n const match = url.match(pattern);\n if (match && match[1]) {\n return match[1];\n }\n }\n\n return null;\n }\n\n async loadVimeoAPI() {\n // Check if API is already loaded\n if (window.Vimeo && window.Vimeo.Player) {\n return Promise.resolve();\n }\n\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://player.vimeo.com/api/player.js';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load Vimeo API'));\n document.head.appendChild(script);\n });\n }\n\n createIframe() {\n // Hide original element\n this.player.element.style.display = 'none';\n\n // Create container for iframe\n this.iframe = document.createElement('div');\n this.iframe.id = `vimeo-player-${Math.random().toString(36).substr(2, 9)}`;\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n \n this.player.element.parentNode.insertBefore(this.iframe, this.player.element);\n }\n\n async initializePlayer() {\n const options = {\n id: this.videoId,\n width: '100%',\n height: '100%',\n controls: false,\n autoplay: this.player.options.autoplay,\n muted: this.player.options.muted,\n loop: this.player.options.loop,\n keyboard: false\n };\n\n if (this.player.options.startTime > 0) {\n options.startTime = this.player.options.startTime;\n }\n\n this.vimeo = new window.Vimeo.Player(this.iframe.id, options);\n\n // Wait for player to be ready\n await this.vimeo.ready();\n this.isReady = true;\n\n this.attachEvents();\n\n // Get initial duration\n try {\n const duration = await this.vimeo.getDuration();\n this.player.state.duration = duration;\n this.player.emit('loadedmetadata');\n } catch (error) {\n this.player.log('Error getting duration:', error, 'warn');\n }\n }\n\n attachEvents() {\n this.vimeo.on('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n });\n\n this.vimeo.on('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.vimeo.on('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n });\n\n this.vimeo.on('timeupdate', (data) => {\n this.player.state.currentTime = data.seconds;\n this.player.state.duration = data.duration;\n this.player.emit('timeupdate', data.seconds);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, data.seconds);\n }\n });\n\n this.vimeo.on('volumechange', (data) => {\n this.player.state.volume = data.volume;\n this.player.emit('volumechange', data.volume);\n });\n\n this.vimeo.on('bufferstart', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.vimeo.on('bufferend', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.vimeo.on('seeking', () => {\n this.player.state.seeking = true;\n this.player.emit('seeking');\n });\n\n this.vimeo.on('seeked', () => {\n this.player.state.seeking = false;\n this.player.emit('seeked');\n });\n\n this.vimeo.on('playbackratechange', (data) => {\n this.player.state.playbackSpeed = data.playbackRate;\n this.player.emit('ratechange', data.playbackRate);\n });\n\n this.vimeo.on('error', (error) => {\n this.player.handleError(new Error(`Vimeo error: ${error.message}`));\n });\n }\n\n play() {\n if (this.isReady && this.vimeo) {\n this.vimeo.play().catch(error => {\n this.player.log('Play error:', error, 'warn');\n });\n }\n }\n\n pause() {\n if (this.isReady && this.vimeo) {\n this.vimeo.pause().catch(error => {\n this.player.log('Pause error:', error, 'warn');\n });\n }\n }\n\n seek(time) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setCurrentTime(time).catch(error => {\n this.player.log('Seek error:', error, 'warn');\n });\n }\n }\n\n setVolume(volume) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setVolume(volume).catch(error => {\n this.player.log('Volume error:', error, 'warn');\n });\n this.player.state.volume = volume;\n }\n }\n\n setMuted(muted) {\n if (this.isReady && this.vimeo) {\n if (muted) {\n this.vimeo.setVolume(0);\n } else {\n this.vimeo.setVolume(this.player.state.volume);\n }\n this.player.state.muted = muted;\n }\n }\n\n setPlaybackSpeed(speed) {\n if (this.isReady && this.vimeo) {\n this.vimeo.setPlaybackRate(speed).catch(error => {\n this.player.log('Playback rate error:', error, 'warn');\n });\n this.player.state.playbackSpeed = speed;\n }\n }\n\n destroy() {\n if (this.vimeo && this.vimeo.destroy) {\n this.vimeo.destroy();\n }\n\n if (this.iframe && this.iframe.parentNode) {\n this.iframe.parentNode.removeChild(this.iframe);\n }\n\n // Show original element\n if (this.player.element) {\n this.player.element.style.display = '';\n }\n }\n}\n\n", "/**\n * HLS Streaming Renderer\n * Uses hls.js for browsers that don't natively support HLS\n */\n\nexport class HLSRenderer {\n constructor(player) {\n this.player = player;\n this.media = player.element;\n this.hls = null;\n }\n\n async init() {\n // Check if browser natively supports HLS (Safari)\n if (this.canPlayNatively()) {\n this.player.log('Using native HLS support');\n await this.initNative();\n } else {\n this.player.log('Using hls.js for HLS support');\n await this.initHlsJs();\n }\n }\n\n canPlayNatively() {\n const video = document.createElement('video');\n return video.canPlayType('application/vnd.apple.mpegurl') !== '';\n }\n\n async initNative() {\n // Use HTML5 renderer for native HLS support\n const HTML5Renderer = (await import('./HTML5Renderer.js')).HTML5Renderer;\n const renderer = new HTML5Renderer(this.player);\n await renderer.init();\n \n // Copy methods\n Object.getOwnPropertyNames(Object.getPrototypeOf(renderer)).forEach(method => {\n if (method !== 'constructor' && typeof renderer[method] === 'function') {\n this[method] = renderer[method].bind(renderer);\n }\n });\n }\n\n async initHlsJs() {\n // Hide native controls\n this.media.controls = false;\n this.media.removeAttribute('controls');\n \n // Load hls.js if not already loaded\n if (!window.Hls) {\n await this.loadHlsJs();\n }\n\n if (!window.Hls.isSupported()) {\n throw new Error('HLS is not supported in this browser');\n }\n\n // Create hls.js instance with better error recovery\n this.hls = new window.Hls({\n debug: this.player.options.debug,\n enableWorker: true,\n lowLatencyMode: false,\n backBufferLength: 90,\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n maxBufferHole: 0.5,\n // Network retry settings\n manifestLoadingTimeOut: 10000,\n manifestLoadingMaxRetry: 4,\n manifestLoadingRetryDelay: 1000,\n manifestLoadingMaxRetryTimeout: 64000,\n levelLoadingTimeOut: 10000,\n levelLoadingMaxRetry: 4,\n levelLoadingRetryDelay: 1000,\n levelLoadingMaxRetryTimeout: 64000,\n fragLoadingTimeOut: 20000,\n fragLoadingMaxRetry: 6,\n fragLoadingRetryDelay: 1000,\n fragLoadingMaxRetryTimeout: 64000\n });\n\n // Attach media element\n this.hls.attachMedia(this.media);\n\n // Load source - Get from attribute to avoid blob URL conversion\n let src;\n const sourceElement = this.player.element.querySelector('source');\n if (sourceElement) {\n // Use getAttribute to get the original URL, not the blob-converted one\n src = sourceElement.getAttribute('src');\n } else {\n // Fallback to element's src attribute\n src = this.player.element.getAttribute('src') || this.player.element.src;\n }\n \n this.player.log(`Loading HLS source: ${src}`, 'log');\n \n if (!src) {\n throw new Error('No HLS source found');\n }\n \n this.hls.loadSource(src);\n\n // Attach events\n this.attachHlsEvents();\n this.attachMediaEvents();\n }\n\n async loadHlsJs() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://cdn.jsdelivr.net/npm/hls.js@latest';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load hls.js'));\n document.head.appendChild(script);\n });\n }\n\n attachHlsEvents() {\n this.hls.on(window.Hls.Events.MANIFEST_PARSED, (event, data) => {\n this.player.log('HLS manifest loaded, found ' + data.levels.length + ' quality levels');\n this.player.emit('hlsmanifestparsed', data);\n });\n\n this.hls.on(window.Hls.Events.LEVEL_SWITCHED, (event, data) => {\n this.player.log('HLS level switched to ' + data.level);\n this.player.emit('hlslevelswitched', data);\n });\n\n this.hls.on(window.Hls.Events.ERROR, (event, data) => {\n this.handleHlsError(data);\n });\n\n this.hls.on(window.Hls.Events.FRAG_BUFFERED, () => {\n this.player.state.buffering = false;\n });\n }\n\n attachMediaEvents() {\n // Use same events as HTML5 renderer\n this.media.addEventListener('loadedmetadata', () => {\n this.player.state.duration = this.media.duration;\n this.player.emit('loadedmetadata');\n });\n\n this.media.addEventListener('play', () => {\n this.player.state.playing = true;\n this.player.state.paused = false;\n this.player.state.ended = false;\n this.player.emit('play');\n \n if (this.player.options.onPlay) {\n this.player.options.onPlay.call(this.player);\n }\n });\n\n this.media.addEventListener('pause', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.emit('pause');\n \n if (this.player.options.onPause) {\n this.player.options.onPause.call(this.player);\n }\n });\n\n this.media.addEventListener('ended', () => {\n this.player.state.playing = false;\n this.player.state.paused = true;\n this.player.state.ended = true;\n this.player.emit('ended');\n \n if (this.player.options.onEnded) {\n this.player.options.onEnded.call(this.player);\n }\n \n if (this.player.options.loop) {\n this.player.seek(0);\n this.player.play();\n }\n });\n\n this.media.addEventListener('timeupdate', () => {\n this.player.state.currentTime = this.media.currentTime;\n this.player.emit('timeupdate', this.media.currentTime);\n \n if (this.player.options.onTimeUpdate) {\n this.player.options.onTimeUpdate.call(this.player, this.media.currentTime);\n }\n });\n\n this.media.addEventListener('volumechange', () => {\n this.player.state.volume = this.media.volume;\n this.player.state.muted = this.media.muted;\n this.player.emit('volumechange', this.media.volume);\n });\n\n this.media.addEventListener('waiting', () => {\n this.player.state.buffering = true;\n this.player.emit('waiting');\n });\n\n this.media.addEventListener('canplay', () => {\n this.player.state.buffering = false;\n this.player.emit('canplay');\n });\n\n this.media.addEventListener('error', () => {\n this.player.handleError(this.media.error);\n });\n }\n\n handleHlsError(data) {\n // Log detailed error info\n this.player.log(`HLS Error - Type: ${data.type}, Details: ${data.details}, Fatal: ${data.fatal}`, 'warn');\n if (data.response) {\n this.player.log(`Response code: ${data.response.code}, URL: ${data.response.url}`, 'warn');\n }\n \n if (data.fatal) {\n switch (data.type) {\n case window.Hls.ErrorTypes.NETWORK_ERROR:\n this.player.log('Fatal network error, trying to recover...', 'error');\n this.player.log(`Network error details: ${data.details}`, 'error');\n setTimeout(() => {\n this.hls.startLoad();\n }, 1000);\n break;\n \n case window.Hls.ErrorTypes.MEDIA_ERROR:\n this.player.log('Fatal media error, trying to recover...', 'error');\n this.hls.recoverMediaError();\n break;\n \n default:\n this.player.log('Fatal error, cannot recover', 'error');\n this.player.handleError(new Error(`HLS Error: ${data.type} - ${data.details}`));\n this.hls.destroy();\n break;\n }\n } else {\n this.player.log('Non-fatal HLS error: ' + data.details, 'warn');\n }\n }\n\n play() {\n const promise = this.media.play();\n \n if (promise !== undefined) {\n promise.catch(error => {\n this.player.log('Play failed:', error, 'warn');\n });\n }\n }\n\n pause() {\n this.media.pause();\n }\n\n seek(time) {\n this.media.currentTime = time;\n }\n\n setVolume(volume) {\n this.media.volume = volume;\n }\n\n setMuted(muted) {\n this.media.muted = muted;\n }\n\n setPlaybackSpeed(speed) {\n this.media.playbackRate = speed;\n }\n\n switchQuality(levelIndex) {\n if (this.hls) {\n this.hls.currentLevel = levelIndex;\n }\n }\n\n getQualities() {\n if (this.hls && this.hls.levels) {\n return this.hls.levels.map((level, index) => ({\n index,\n height: level.height,\n width: level.width,\n bitrate: level.bitrate,\n name: `${level.height}p`\n }));\n }\n return [];\n }\n\n destroy() {\n if (this.hls) {\n this.hls.destroy();\n this.hls = null;\n }\n }\n}\n\n", "/**\n * VidPly Playlist Manager\n * Manages playlists for audio and video content\n */\n\nimport { DOMUtils } from '../utils/DOMUtils.js';\nimport { createIconElement } from '../icons/Icons.js';\n\nexport class PlaylistManager {\n constructor(player, options = {}) {\n this.player = player;\n this.tracks = [];\n this.currentIndex = -1;\n \n // Options\n this.options = {\n autoAdvance: options.autoAdvance !== false, // Default true\n loop: options.loop || false,\n showPanel: options.showPanel !== false, // Default true\n ...options\n };\n \n // UI elements\n this.container = null;\n this.playlistPanel = null;\n this.trackInfoElement = null;\n \n // Bind methods\n this.handleTrackEnd = this.handleTrackEnd.bind(this);\n this.handleTrackError = this.handleTrackError.bind(this);\n \n // Initialize\n this.init();\n }\n \n init() {\n // Listen for track end\n this.player.on('ended', this.handleTrackEnd);\n this.player.on('error', this.handleTrackError);\n \n // Create UI if needed\n if (this.options.showPanel) {\n this.createUI();\n }\n }\n \n /**\n * Load a playlist\n * @param {Array} tracks - Array of track objects\n */\n loadPlaylist(tracks) {\n this.tracks = tracks;\n this.currentIndex = -1;\n \n // Add playlist class to container\n if (this.container) {\n this.container.classList.add('vidply-has-playlist');\n }\n \n // Update UI\n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n \n // Auto-play first track\n if (tracks.length > 0) {\n this.play(0);\n }\n }\n \n /**\n * Play a specific track\n * @param {number} index - Track index\n */\n play(index) {\n if (index < 0 || index >= this.tracks.length) {\n console.warn('VidPly Playlist: Invalid track index', index);\n return;\n }\n \n const track = this.tracks[index];\n \n // Update current index\n this.currentIndex = index;\n \n // Load track into player\n this.player.load({\n src: track.src,\n type: track.type,\n poster: track.poster,\n tracks: track.tracks || []\n });\n \n // Update UI\n this.updateTrackInfo(track);\n this.updatePlaylistUI();\n \n // Emit event\n this.player.emit('playlisttrackchange', {\n index: index,\n item: track,\n total: this.tracks.length\n });\n \n // Auto-play\n setTimeout(() => {\n this.player.play();\n }, 100);\n }\n \n /**\n * Play next track\n */\n next() {\n let nextIndex = this.currentIndex + 1;\n \n if (nextIndex >= this.tracks.length) {\n if (this.options.loop) {\n nextIndex = 0;\n } else {\n return;\n }\n }\n \n this.play(nextIndex);\n }\n \n /**\n * Play previous track\n */\n previous() {\n let prevIndex = this.currentIndex - 1;\n \n if (prevIndex < 0) {\n if (this.options.loop) {\n prevIndex = this.tracks.length - 1;\n } else {\n return;\n }\n }\n \n this.play(prevIndex);\n }\n \n /**\n * Handle track end\n */\n handleTrackEnd() {\n if (this.options.autoAdvance) {\n this.next();\n }\n }\n \n /**\n * Handle track error\n */\n handleTrackError(e) {\n console.error('VidPly Playlist: Track error', e);\n \n // Try next track\n if (this.options.autoAdvance) {\n setTimeout(() => {\n this.next();\n }, 1000);\n }\n }\n \n /**\n * Create playlist UI\n */\n createUI() {\n // Find player container\n this.container = this.player.container;\n \n if (!this.container) {\n console.warn('VidPly Playlist: No container found');\n return;\n }\n \n // Create track info element (shows current track)\n this.trackInfoElement = DOMUtils.createElement('div', {\n className: 'vidply-track-info'\n });\n this.trackInfoElement.style.display = 'none';\n \n this.container.appendChild(this.trackInfoElement);\n \n // Create playlist panel\n this.playlistPanel = DOMUtils.createElement('div', {\n className: 'vidply-playlist-panel'\n });\n this.playlistPanel.style.display = 'none';\n \n this.container.appendChild(this.playlistPanel);\n }\n \n /**\n * Update track info display\n */\n updateTrackInfo(track) {\n if (!this.trackInfoElement) return;\n \n const trackNumber = this.currentIndex + 1;\n const totalTracks = this.tracks.length;\n \n this.trackInfoElement.innerHTML = `\n <div class=\"vidply-track-number\">Track ${trackNumber} of ${totalTracks}</div>\n <div class=\"vidply-track-title\">${DOMUtils.escapeHTML(track.title || 'Untitled')}</div>\n ${track.artist ? `<div class=\"vidply-track-artist\">${DOMUtils.escapeHTML(track.artist)}</div>` : ''}\n `;\n \n this.trackInfoElement.style.display = 'block';\n }\n \n /**\n * Render playlist\n */\n renderPlaylist() {\n if (!this.playlistPanel) return;\n \n // Clear existing\n this.playlistPanel.innerHTML = '';\n \n // Create header\n const header = DOMUtils.createElement('div', {\n className: 'vidply-playlist-header'\n });\n header.textContent = `Playlist (${this.tracks.length})`;\n this.playlistPanel.appendChild(header);\n \n // Create list\n const list = DOMUtils.createElement('div', {\n className: 'vidply-playlist-list'\n });\n \n this.tracks.forEach((track, index) => {\n const item = this.createPlaylistItem(track, index);\n list.appendChild(item);\n });\n \n this.playlistPanel.appendChild(list);\n this.playlistPanel.style.display = 'block';\n }\n \n /**\n * Create playlist item element\n */\n createPlaylistItem(track, index) {\n const item = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item',\n role: 'button',\n tabIndex: 0,\n 'aria-label': `Play ${track.title || 'Track ' + (index + 1)}`\n });\n \n // Add active class if current\n if (index === this.currentIndex) {\n item.classList.add('vidply-playlist-item-active');\n }\n \n // Thumbnail or icon\n const thumbnail = DOMUtils.createElement('div', {\n className: 'vidply-playlist-thumbnail'\n });\n \n if (track.poster) {\n thumbnail.style.backgroundImage = `url(${track.poster})`;\n } else {\n // Show music/speaker icon for audio tracks\n const icon = createIconElement('music');\n icon.classList.add('vidply-playlist-thumbnail-icon');\n thumbnail.appendChild(icon);\n }\n \n item.appendChild(thumbnail);\n \n // Info\n const info = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-info'\n });\n \n const title = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-title'\n });\n title.textContent = track.title || `Track ${index + 1}`;\n info.appendChild(title);\n \n if (track.artist) {\n const artist = DOMUtils.createElement('div', {\n className: 'vidply-playlist-item-artist'\n });\n artist.textContent = track.artist;\n info.appendChild(artist);\n }\n \n item.appendChild(info);\n \n // Play icon\n const playIcon = createIconElement('play');\n playIcon.classList.add('vidply-playlist-item-icon');\n item.appendChild(playIcon);\n \n // Click handler\n item.addEventListener('click', () => {\n this.play(index);\n });\n \n // Keyboard handler\n item.addEventListener('keydown', (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.play(index);\n }\n });\n \n return item;\n }\n \n /**\n * Update playlist UI (highlight current track)\n */\n updatePlaylistUI() {\n if (!this.playlistPanel) return;\n \n const items = this.playlistPanel.querySelectorAll('.vidply-playlist-item');\n \n items.forEach((item, index) => {\n if (index === this.currentIndex) {\n item.classList.add('vidply-playlist-item-active');\n \n // Scroll into view\n item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n } else {\n item.classList.remove('vidply-playlist-item-active');\n }\n });\n }\n \n /**\n * Get current track\n */\n getCurrentTrack() {\n return this.tracks[this.currentIndex] || null;\n }\n \n /**\n * Get playlist info\n */\n getPlaylistInfo() {\n return {\n currentIndex: this.currentIndex,\n totalTracks: this.tracks.length,\n currentTrack: this.getCurrentTrack(),\n hasNext: this.currentIndex < this.tracks.length - 1,\n hasPrevious: this.currentIndex > 0\n };\n }\n \n /**\n * Add track to playlist\n */\n addTrack(track) {\n this.tracks.push(track);\n \n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n }\n \n /**\n * Remove track from playlist\n */\n removeTrack(index) {\n if (index < 0 || index >= this.tracks.length) return;\n \n this.tracks.splice(index, 1);\n \n // Adjust current index if needed\n if (index < this.currentIndex) {\n this.currentIndex--;\n } else if (index === this.currentIndex) {\n // Current track was removed, play next or stop\n if (this.currentIndex >= this.tracks.length) {\n this.currentIndex = this.tracks.length - 1;\n }\n \n if (this.currentIndex >= 0) {\n this.play(this.currentIndex);\n }\n }\n \n if (this.playlistPanel) {\n this.renderPlaylist();\n }\n }\n \n /**\n * Clear playlist\n */\n clear() {\n this.tracks = [];\n this.currentIndex = -1;\n \n if (this.playlistPanel) {\n this.playlistPanel.innerHTML = '';\n this.playlistPanel.style.display = 'none';\n }\n \n if (this.trackInfoElement) {\n this.trackInfoElement.innerHTML = '';\n this.trackInfoElement.style.display = 'none';\n }\n }\n \n /**\n * Destroy playlist manager\n */\n destroy() {\n // Remove event listeners\n this.player.off('ended', this.handleTrackEnd);\n this.player.off('error', this.handleTrackError);\n \n // Remove UI\n if (this.trackInfoElement) {\n this.trackInfoElement.remove();\n }\n \n if (this.playlistPanel) {\n this.playlistPanel.remove();\n }\n \n // Clear data\n this.clear();\n }\n}\n\nexport default PlaylistManager;\n", "/**\n * VidPly - Universal Video Player\n * Main Entry Point\n */\n\nimport { Player } from './core/Player.js';\nimport { PlaylistManager } from './features/PlaylistManager.js';\n\n// Auto-initialize players\nfunction initializePlayers() {\n const elements = document.querySelectorAll('[data-vidply]');\n \n elements.forEach(element => {\n // Parse options from data attribute (JSON format)\n const options = element.dataset.vidplyOptions \n ? JSON.parse(element.dataset.vidplyOptions)\n : {};\n \n // Parse individual data attributes and merge with options\n // This allows for easier HTML-based configuration\n const dataOptions = parseDataAttributes(element.dataset);\n const mergedOptions = { ...dataOptions, ...options };\n \n // Create player instance\n new Player(element, mergedOptions);\n });\n}\n\n// Helper function to parse data attributes into options\nfunction parseDataAttributes(dataset) {\n const options = {};\n \n // Map of data attribute names to option keys (camelCase conversion)\n const attributeMap = {\n // Sign Language\n 'signLanguageSrc': 'signLanguageSrc',\n 'signLanguageButton': 'signLanguageButton',\n 'signLanguagePosition': 'signLanguagePosition',\n \n // Audio Description\n 'audioDescriptionSrc': 'audioDescriptionSrc',\n 'audioDescriptionButton': 'audioDescriptionButton',\n \n // Other common options\n 'autoplay': 'autoplay',\n 'loop': 'loop',\n 'muted': 'muted',\n 'controls': 'controls',\n 'poster': 'poster',\n 'width': 'width',\n 'height': 'height',\n 'language': 'language',\n 'captions': 'captions',\n 'captionsDefault': 'captionsDefault',\n 'transcript': 'transcript',\n 'transcriptButton': 'transcriptButton',\n 'keyboard': 'keyboard',\n 'responsive': 'responsive',\n 'pipButton': 'pipButton',\n 'fullscreenButton': 'fullscreenButton'\n };\n \n // Parse each data attribute\n Object.keys(attributeMap).forEach(dataKey => {\n const optionKey = attributeMap[dataKey];\n const value = dataset[dataKey];\n \n if (value !== undefined) {\n // Convert string values to appropriate types\n if (value === 'true') {\n options[optionKey] = true;\n } else if (value === 'false') {\n options[optionKey] = false;\n } else if (!isNaN(value) && value !== '') {\n options[optionKey] = Number(value);\n } else {\n options[optionKey] = value;\n }\n }\n });\n \n return options;\n}\n\n// Auto-initialize on DOM ready\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', initializePlayers);\n} else {\n initializePlayers();\n}\n\n// Export for manual initialization\nexport { Player, PlaylistManager };\nexport default Player;\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["translations", "HTML5Renderer"]
|
|
7
7
|
}
|