vidply 1.2.0 → 1.2.1
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 +946 -946
- package/dist/dev/{vidply.AudioDescriptionManager-R47Q4YR4.js → vidply.AudioDescriptionManager-6RFVF27Z.js} +275 -19
- package/dist/dev/vidply.AudioDescriptionManager-6RFVF27Z.js.map +7 -0
- package/dist/dev/{vidply.CaptionStyleMenu-7XHRBWUM.js → vidply.CaptionStyleMenu-R2SCQ6VP.js} +4 -4
- package/dist/dev/{vidply.DASHRenderer-PWEMC3BT.js → vidply.DASHRenderer-EOVEW73H.js} +3 -3
- package/dist/dev/vidply.DASHRenderer-EOVEW73H.js.map +7 -0
- package/dist/dev/{vidply.FloatingPlayerManager-PKNNNAS2.js → vidply.FloatingPlayerManager-V5XQWS75.js} +5 -5
- package/dist/dev/vidply.FloatingPlayerManager-V5XQWS75.js.map +7 -0
- package/dist/dev/{vidply.HLSRenderer-E7RQ74HI.js → vidply.HLSRenderer-ZBEFVH5W.js} +4 -4
- package/dist/dev/vidply.HLSRenderer-ZBEFVH5W.js.map +7 -0
- package/dist/dev/vidply.HTML5Renderer-P7ICKYU4.js +12 -0
- package/dist/dev/{vidply.SignLanguageManager-FET5FQZ7.js → vidply.SignLanguageManager-7IAJOVF6.js} +8 -8
- package/dist/dev/vidply.SignLanguageManager-7IAJOVF6.js.map +7 -0
- package/dist/dev/{vidply.SoundCloudRenderer-RVSJZODO.js → vidply.SoundCloudRenderer-OA7QQYGN.js} +3 -3
- package/dist/dev/vidply.SoundCloudRenderer-OA7QQYGN.js.map +7 -0
- package/dist/dev/{vidply.TranscriptManager-5GXOQCLX.js → vidply.TranscriptManager-BPM3T23L.js} +10 -10
- package/dist/dev/vidply.TranscriptManager-BPM3T23L.js.map +7 -0
- package/dist/dev/{vidply.VimeoRenderer-ER2LSBBW.js → vidply.VimeoRenderer-BRHFYPNJ.js} +3 -3
- package/dist/dev/vidply.VimeoRenderer-BRHFYPNJ.js.map +7 -0
- package/dist/dev/{vidply.YouTubeRenderer-NFTOWJAB.js → vidply.YouTubeRenderer-HRTN4EJ5.js} +3 -3
- package/dist/dev/vidply.YouTubeRenderer-HRTN4EJ5.js.map +7 -0
- package/dist/dev/{vidply.chunk-6RQA4ROD.js → vidply.chunk-5IK3IC5V.js} +2 -2
- package/dist/dev/{vidply.chunk-JJ47NO24.js → vidply.chunk-C55OBT5H.js} +2 -2
- package/dist/dev/vidply.chunk-C55OBT5H.js.map +7 -0
- package/dist/dev/{vidply.chunk-DZSDO3B7.js → vidply.chunk-HOYEMJSD.js} +2 -2
- package/dist/dev/{vidply.chunk-VMSQAZM7.js → vidply.chunk-JAKZNGOR.js} +2 -2
- package/dist/dev/{vidply.chunk-64WXMTGL.js → vidply.chunk-LDVFAFGC.js} +5 -5
- package/dist/dev/vidply.chunk-LDVFAFGC.js.map +7 -0
- package/dist/dev/{vidply.chunk-RZWZGDV7.js → vidply.chunk-NSMAZCMB.js} +6 -6
- package/dist/dev/vidply.chunk-NSMAZCMB.js.map +7 -0
- package/dist/dev/{vidply.chunk-KI7C3QVL.js → vidply.chunk-RQG3MA7W.js} +2 -2
- package/dist/dev/vidply.chunk-RQG3MA7W.js.map +7 -0
- package/dist/dev/{vidply.chunk-BNFIUL2Z.js → vidply.chunk-UHMVDBDB.js} +3 -3
- package/dist/dev/vidply.chunk-UHMVDBDB.js.map +7 -0
- package/dist/dev/{vidply.chunk-NQPURMQY.js → vidply.chunk-W5BR65JY.js} +6 -6
- package/dist/dev/vidply.chunk-W5BR65JY.js.map +7 -0
- package/dist/dev/{vidply.chunk-W25HUCHS.js → vidply.chunk-XAK3DPTO.js} +2 -2
- package/dist/dev/vidply.chunk-XAK3DPTO.js.map +7 -0
- package/dist/dev/{vidply.chunk-SK4V2DAU.js → vidply.chunk-YVCYQZJI.js} +3 -3
- package/dist/dev/{vidply.de-4YAT7FFM.js → vidply.de-5W5LBFSJ.js} +2 -2
- package/dist/dev/vidply.de-5W5LBFSJ.js.map +7 -0
- package/dist/dev/{vidply.es-LEWIRUBH.js → vidply.es-SHDAT6L6.js} +2 -2
- package/dist/dev/vidply.es-SHDAT6L6.js.map +7 -0
- package/dist/dev/vidply.esm.js +73 -34
- package/dist/dev/vidply.esm.js.map +2 -2
- package/dist/dev/{vidply.fr-Q4GV2NOE.js → vidply.fr-2JANOMNB.js} +2 -2
- package/dist/dev/vidply.fr-2JANOMNB.js.map +7 -0
- package/dist/dev/{vidply.ja-S6ITA6WU.js → vidply.ja-WWMSTEJH.js} +2 -2
- package/dist/dev/vidply.ja-WWMSTEJH.js.map +7 -0
- package/dist/legacy/vidply.js +345 -32
- package/dist/legacy/vidply.js.map +3 -3
- package/dist/legacy/vidply.min.js +2 -2
- package/dist/legacy/vidply.min.meta.json +66 -47
- package/dist/prod/vidply.AudioDescriptionManager-YTDVDQBO.min.js +6 -0
- package/dist/prod/{vidply.CaptionStyleMenu-M3KVQWB5.min.js → vidply.CaptionStyleMenu-2AFF3HF2.min.js} +2 -2
- package/dist/prod/{vidply.DASHRenderer-DN3S27AV.min.js → vidply.DASHRenderer-URDOTOKS.min.js} +2 -2
- package/dist/prod/{vidply.FloatingPlayerManager-SKAZ4J43.min.js → vidply.FloatingPlayerManager-QUBFK7CQ.min.js} +2 -2
- package/dist/prod/{vidply.HLSRenderer-62HH4YTK.min.js → vidply.HLSRenderer-46KNUVAB.min.js} +2 -2
- package/dist/prod/vidply.HTML5Renderer-7TQDMIGY.min.js +6 -0
- package/dist/prod/{vidply.SignLanguageManager-V3OBTSSF.min.js → vidply.SignLanguageManager-H4C36EVL.min.js} +2 -2
- package/dist/prod/{vidply.SoundCloudRenderer-CXRVZIAJ.min.js → vidply.SoundCloudRenderer-OYSWMW7D.min.js} +2 -2
- package/dist/prod/{vidply.TranscriptManager-SYM3DFUY.min.js → vidply.TranscriptManager-BA3DAS63.min.js} +2 -2
- package/dist/prod/{vidply.VimeoRenderer-72TWRYFQ.min.js → vidply.VimeoRenderer-NF3COTHU.min.js} +2 -2
- package/dist/prod/{vidply.YouTubeRenderer-UMHEV3KD.min.js → vidply.YouTubeRenderer-UCQKYIJ4.min.js} +2 -2
- package/dist/prod/{vidply.chunk-Z3YDSA7O.min.js → vidply.chunk-2HNCP64N.min.js} +1 -1
- package/dist/prod/{vidply.chunk-EKEYJWMG.min.js → vidply.chunk-6ECBIYVI.min.js} +2 -2
- package/dist/prod/{vidply.chunk-YEENJS3Q.min.js → vidply.chunk-7S5AFTST.min.js} +2 -2
- package/dist/prod/{vidply.chunk-P4UXOHWA.min.js → vidply.chunk-EUOA2DJK.min.js} +1 -1
- package/dist/prod/{vidply.chunk-2TB6MUHO.min.js → vidply.chunk-G6KGXNEW.min.js} +1 -1
- package/dist/prod/{vidply.chunk-ABPXVDLZ.min.js → vidply.chunk-JPMAK3NS.min.js} +1 -1
- package/dist/prod/{vidply.chunk-P3PQBY7N.min.js → vidply.chunk-L4O44K63.min.js} +1 -1
- package/dist/prod/{vidply.chunk-WX3MVEAL.min.js → vidply.chunk-M76ABMKB.min.js} +1 -1
- package/dist/prod/{vidply.chunk-TM6AXJVD.min.js → vidply.chunk-WRVDVD33.min.js} +2 -2
- package/dist/prod/{vidply.chunk-RI3X7WHK.min.js → vidply.chunk-X2FQEQYR.min.js} +2 -2
- package/dist/prod/{vidply.chunk-UK7YGOB5.min.js → vidply.chunk-XXUH7ADU.min.js} +2 -2
- package/dist/prod/{vidply.de-BCHXRQ53.min.js → vidply.de-JMCATTKZ.min.js} +1 -1
- package/dist/prod/{vidply.es-PICAKMZD.min.js → vidply.es-YVG37V7Z.min.js} +1 -1
- package/dist/prod/vidply.esm.min.js +2 -2
- package/dist/prod/{vidply.fr-ZILI7CDR.min.js → vidply.fr-OGKGN2R4.min.js} +1 -1
- package/dist/prod/{vidply.ja-5WQ4OK4J.min.js → vidply.ja-Z6DS7QLS.min.js} +1 -1
- package/dist/vidply.css +5796 -5796
- package/dist/vidply.esm.min.meta.json +148 -135
- package/package.json +7 -7
- package/src/controls/CaptionManager.ts +598 -598
- package/src/controls/ControlBar.ts +4159 -4159
- package/src/controls/KeyboardManager.ts +383 -383
- package/src/controls/SettingsDialog.ts +488 -488
- package/src/controls/TranscriptManager.ts +2426 -2426
- package/src/core/AudioDescriptionManager.ts +863 -774
- package/src/core/DescriptionSpeechManager.ts +232 -0
- package/src/core/FloatingPlayerManager.ts +674 -674
- package/src/core/LazyInit.ts +80 -80
- package/src/core/MetadataAlertsManager.ts +514 -514
- package/src/core/Player.ts +2915 -2872
- package/src/core/PosterManager.ts +169 -169
- package/src/core/PseudoFullscreen.ts +179 -179
- package/src/core/ResponsiveManager.ts +231 -231
- package/src/core/ResumeManager.ts +236 -236
- package/src/core/SignLanguageManager.ts +1308 -1308
- package/src/core/ThemeManager.ts +157 -157
- package/src/features/PlaylistManager.ts +1838 -1827
- package/src/i18n/i18n.ts +223 -223
- package/src/i18n/languages/de.ts +217 -217
- package/src/i18n/languages/en.ts +218 -218
- package/src/i18n/languages/es.ts +214 -214
- package/src/i18n/languages/fr.ts +214 -214
- package/src/i18n/languages/ja.ts +214 -214
- package/src/icons/Icons.ts +167 -167
- package/src/index.ts +196 -193
- package/src/renderers/DASHRenderer.ts +1077 -1077
- package/src/renderers/HLSRenderer.ts +944 -944
- package/src/renderers/HTML5Renderer.ts +389 -389
- package/src/renderers/SoundCloudRenderer.ts +437 -437
- package/src/renderers/VimeoRenderer.ts +298 -298
- package/src/renderers/YouTubeRenderer.ts +290 -290
- package/src/styles/vidply.css +5796 -5796
- package/src/types/events.ts +124 -122
- package/src/types/globals.d.ts +313 -313
- package/src/types/options.ts +185 -182
- package/src/types/renderer.ts +58 -58
- package/src/utils/DOMUtils.ts +281 -281
- package/src/utils/DownloadInfo.ts +171 -171
- package/src/utils/DraggablePanel.ts +539 -539
- package/src/utils/DraggablePanelMenu.ts +195 -195
- package/src/utils/DraggableResizable.ts +997 -997
- package/src/utils/EventEmitter.ts +59 -59
- package/src/utils/FormUtils.ts +95 -95
- package/src/utils/MenuFactory.ts +483 -483
- package/src/utils/Sanitize.ts +70 -70
- package/src/utils/SettingsMenuFactory.ts +289 -289
- package/src/utils/StorageManager.ts +287 -287
- package/src/utils/TrackLabelUtils.ts +52 -52
- package/src/utils/UrlSafe.ts +69 -69
- package/src/utils/VideoFrameCapture.ts +114 -114
- package/src/utils/WindowComponents.ts +250 -250
- package/dist/dev/vidply.AudioDescriptionManager-R47Q4YR4.js.map +0 -7
- package/dist/dev/vidply.DASHRenderer-PWEMC3BT.js.map +0 -7
- package/dist/dev/vidply.FloatingPlayerManager-PKNNNAS2.js.map +0 -7
- package/dist/dev/vidply.HLSRenderer-E7RQ74HI.js.map +0 -7
- package/dist/dev/vidply.HTML5Renderer-BU4QJJJY.js +0 -12
- package/dist/dev/vidply.SignLanguageManager-FET5FQZ7.js.map +0 -7
- package/dist/dev/vidply.SoundCloudRenderer-RVSJZODO.js.map +0 -7
- package/dist/dev/vidply.TranscriptManager-5GXOQCLX.js.map +0 -7
- package/dist/dev/vidply.VimeoRenderer-ER2LSBBW.js.map +0 -7
- package/dist/dev/vidply.YouTubeRenderer-NFTOWJAB.js.map +0 -7
- package/dist/dev/vidply.chunk-64WXMTGL.js.map +0 -7
- package/dist/dev/vidply.chunk-BNFIUL2Z.js.map +0 -7
- package/dist/dev/vidply.chunk-JJ47NO24.js.map +0 -7
- package/dist/dev/vidply.chunk-KI7C3QVL.js.map +0 -7
- package/dist/dev/vidply.chunk-NQPURMQY.js.map +0 -7
- package/dist/dev/vidply.chunk-RZWZGDV7.js.map +0 -7
- package/dist/dev/vidply.chunk-W25HUCHS.js.map +0 -7
- package/dist/dev/vidply.de-4YAT7FFM.js.map +0 -7
- package/dist/dev/vidply.es-LEWIRUBH.js.map +0 -7
- package/dist/dev/vidply.fr-Q4GV2NOE.js.map +0 -7
- package/dist/dev/vidply.ja-S6ITA6WU.js.map +0 -7
- package/dist/prod/vidply.AudioDescriptionManager-RHLIJW5C.min.js +0 -6
- package/dist/prod/vidply.HTML5Renderer-IU5T3WEW.min.js +0 -6
- /package/dist/dev/{vidply.CaptionStyleMenu-7XHRBWUM.js.map → vidply.CaptionStyleMenu-R2SCQ6VP.js.map} +0 -0
- /package/dist/dev/{vidply.HTML5Renderer-BU4QJJJY.js.map → vidply.HTML5Renderer-P7ICKYU4.js.map} +0 -0
- /package/dist/dev/{vidply.chunk-6RQA4ROD.js.map → vidply.chunk-5IK3IC5V.js.map} +0 -0
- /package/dist/dev/{vidply.chunk-DZSDO3B7.js.map → vidply.chunk-HOYEMJSD.js.map} +0 -0
- /package/dist/dev/{vidply.chunk-VMSQAZM7.js.map → vidply.chunk-JAKZNGOR.js.map} +0 -0
- /package/dist/dev/{vidply.chunk-SK4V2DAU.js.map → vidply.chunk-YVCYQZJI.js.map} +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/DraggableResizable.ts"],
|
|
4
|
+
"sourcesContent": ["import type { StorageManager } from './StorageManager.js';\n\nexport interface DraggableResizableOptions {\n dragHandle?: HTMLElement | null;\n resizeHandles?: HTMLElement[];\n onDragStart?: ((e: Event) => boolean | void) | null;\n onDrag?: ((pos: { x?: number; y?: number; centered?: boolean }) => void) | null;\n onDragEnd?: (() => void) | null;\n onResizeStart?: (() => void) | null;\n onResize?: ((dims: { width: number; height: number; left?: number; top?: number }) => void) | null;\n onResizeEnd?: (() => void) | null;\n constrainToViewport?: boolean;\n minWidth?: number;\n minHeight?: number;\n maintainAspectRatio?: boolean;\n keyboardDragKey?: string;\n keyboardResizeKey?: string;\n keyboardStep?: number;\n keyboardStepLarge?: number;\n maxWidth?: number | (() => number) | null;\n maxHeight?: number | (() => number) | null;\n pointerResizeIndicatorText?: string | null;\n onPointerResizeToggle?: ((enabled: boolean) => void) | null;\n classPrefix?: string;\n storage?: StorageManager | null;\n storageKey?: string | null;\n}\n\ninterface ResolvedOptions extends Required<Omit<DraggableResizableOptions, 'maxWidth' | 'maxHeight'>> {\n maxWidth: number | (() => number) | null;\n maxHeight: number | (() => number) | null;\n}\n\nexport class DraggableResizable {\n element: HTMLElement;\n options: ResolvedOptions;\n isDragging: boolean;\n isResizing: boolean;\n resizeDirection: string | null;\n dragOffsetX: number;\n dragOffsetY: number;\n positionOffsetX: number;\n positionOffsetY: number;\n initialMouseX: number;\n initialMouseY: number;\n needsPositionConversion: boolean;\n resizeStartX: number;\n resizeStartY: number;\n resizeStartWidth: number;\n resizeStartHeight: number;\n resizeStartLeft: number;\n resizeStartTop: number;\n keyboardDragMode: boolean;\n keyboardResizeMode: boolean;\n pointerResizeMode: boolean;\n manuallyPositioned: boolean;\n resizeHandlesManaged: Map<HTMLElement, boolean>;\n resizeIndicatorElement: HTMLElement | null;\n handlers: {\n mousedown: (e: MouseEvent) => void;\n mousemove: (e: MouseEvent) => void;\n mouseup: () => void;\n touchstart: (e: TouchEvent) => void;\n touchmove: (e: TouchEvent) => void;\n touchend: () => void;\n pointerdown: (e: PointerEvent) => void;\n pointermove: (e: PointerEvent) => void;\n pointerup: (e: PointerEvent) => void;\n pointercancel: (e: PointerEvent) => void;\n keydown: (e: KeyboardEvent) => void;\n resizeHandleMousedown: (e: MouseEvent | TouchEvent) => void;\n resizeHandlePointerDown: (e: PointerEvent) => void;\n };\n activePointerId: number | null;\n activePointerType: string | null;\n\n constructor(element: HTMLElement, options: DraggableResizableOptions = {}) {\n this.element = element;\n this.options = {\n dragHandle: null,\n resizeHandles: [],\n onDragStart: null,\n onDrag: null,\n onDragEnd: null,\n onResizeStart: null,\n onResize: null,\n onResizeEnd: null,\n constrainToViewport: true,\n minWidth: 150,\n minHeight: 100,\n maintainAspectRatio: false,\n keyboardDragKey: 'd',\n keyboardResizeKey: 'r',\n keyboardStep: 5,\n keyboardStepLarge: 10,\n maxWidth: null,\n maxHeight: null,\n pointerResizeIndicatorText: null,\n onPointerResizeToggle: null,\n classPrefix: 'draggable',\n storage: null,\n storageKey: null,\n ...options\n } as ResolvedOptions;\n\n // State\n this.isDragging = false;\n this.isResizing = false;\n this.resizeDirection = null;\n this.dragOffsetX = 0;\n this.dragOffsetY = 0;\n this.positionOffsetX = 0;\n this.positionOffsetY = 0;\n this.initialMouseX = 0;\n this.initialMouseY = 0;\n this.needsPositionConversion = false;\n this.resizeStartX = 0;\n this.resizeStartY = 0;\n this.resizeStartWidth = 0;\n this.resizeStartHeight = 0;\n this.resizeStartLeft = 0;\n this.resizeStartTop = 0;\n this.keyboardDragMode = false;\n this.keyboardResizeMode = false;\n this.pointerResizeMode = false;\n this.manuallyPositioned = false; // Flag to track if user has manually moved/resized\n this.resizeHandlesManaged = new Map();\n this.resizeIndicatorElement = null;\n\n // Event handlers\n this.handlers = {\n mousedown: this.onMouseDown.bind(this),\n mousemove: this.onMouseMove.bind(this),\n mouseup: this.onMouseUp.bind(this),\n touchstart: this.onTouchStart.bind(this),\n touchmove: this.onTouchMove.bind(this),\n touchend: this.onTouchEnd.bind(this),\n pointerdown: this.onPointerDown.bind(this),\n pointermove: this.onPointerMove.bind(this),\n pointerup: this.onPointerUp.bind(this),\n pointercancel: this.onPointerUp.bind(this),\n keydown: this.onKeyDown.bind(this),\n resizeHandleMousedown: this.onResizeHandleMouseDown.bind(this),\n resizeHandlePointerDown: this.onResizeHandlePointerDown.bind(this)\n };\n\n // Pointer tracking (Pointer Events unify mouse + touch)\n this.activePointerId = null;\n this.activePointerType = null;\n\n this.init();\n }\n\n hasManagedResizeHandles(): boolean {\n return Array.from(this.resizeHandlesManaged.values()).some(Boolean);\n }\n\n storeOriginalHandleDisplay(handle: HTMLElement): void {\n if (!handle.dataset.originalDisplay) {\n handle.dataset.originalDisplay = handle.style.display || '';\n }\n }\n\n hideResizeHandle(handle: HTMLElement): void {\n handle.style.display = 'none';\n handle.setAttribute('aria-hidden', 'true');\n }\n\n showResizeHandle(handle: HTMLElement): void {\n const original = handle.dataset.originalDisplay !== undefined ? handle.dataset.originalDisplay : '';\n handle.style.display = original;\n handle.removeAttribute('aria-hidden');\n }\n\n setManagedHandlesVisible(visible: boolean): void {\n if (!this.options.resizeHandles || this.options.resizeHandles.length === 0) {\n return;\n }\n\n this.options.resizeHandles.forEach(handle => {\n if (!this.resizeHandlesManaged.get(handle)) {\n return;\n }\n\n if (visible) {\n this.showResizeHandle(handle);\n } else {\n this.hideResizeHandle(handle);\n }\n });\n }\n\n init(): void {\n const dragHandle = this.options.dragHandle || this.element;\n \n // Prefer Pointer Events when available (covers mouse + touch in one codepath)\n if (typeof window !== 'undefined' && 'PointerEvent' in window) {\n dragHandle.addEventListener('pointerdown', this.handlers.pointerdown);\n\n // Document-level up/cancel events (always needed to end a drag/resize that\n // started inside the element even when the pointer leaves the element).\n // pointermove is NOT registered here — it is added lazily in startDragging()\n // and startResizing() with { passive: false } so that it can call\n // e.preventDefault() to suppress scroll during an active interaction, and\n // removed again in stopDragging() / stopResizing(). Keeping the listener\n // absent while the element is merely visible prevents the non-passive\n // handler from blocking compositor-threaded scroll on the rest of the page.\n document.addEventListener('pointerup', this.handlers.pointerup);\n document.addEventListener('pointercancel', this.handlers.pointercancel);\n } else {\n // Fallback for very old browsers\n dragHandle.addEventListener('mousedown', this.handlers.mousedown);\n dragHandle.addEventListener('touchstart', this.handlers.touchstart, { passive: false });\n\n // Document-level move/up events\n document.addEventListener('mousemove', this.handlers.mousemove);\n document.addEventListener('mouseup', this.handlers.mouseup);\n document.addEventListener('touchmove', this.handlers.touchmove, { passive: false });\n document.addEventListener('touchend', this.handlers.touchend);\n }\n \n // Keyboard events\n this.element.addEventListener('keydown', this.handlers.keydown);\n \n // Resize handles\n if (this.options.resizeHandles && this.options.resizeHandles.length > 0) {\n this.options.resizeHandles.forEach(handle => {\n if (typeof window !== 'undefined' && 'PointerEvent' in window) {\n handle.addEventListener('pointerdown', this.handlers.resizeHandlePointerDown);\n } else {\n handle.addEventListener('mousedown', this.handlers.resizeHandleMousedown);\n handle.addEventListener('touchstart', this.handlers.resizeHandleMousedown, { passive: false });\n }\n\n const managed = handle.dataset.vidplyManagedResize === 'true';\n this.resizeHandlesManaged.set(handle, managed);\n if (managed) {\n this.storeOriginalHandleDisplay(handle);\n this.hideResizeHandle(handle);\n }\n });\n }\n }\n\n onPointerDown(e: PointerEvent): void {\n if (e.isPrimary === false) return;\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n\n const target = e.target as HTMLElement;\n if (target.classList.contains(`${this.options.classPrefix}-resize-handle`)) {\n return;\n }\n\n if (this.options.onDragStart && !this.options.onDragStart(e)) {\n return;\n }\n\n this.activePointerId = e.pointerId;\n this.activePointerType = e.pointerType;\n\n try {\n (e.currentTarget as HTMLElement)?.setPointerCapture?.(e.pointerId);\n } catch {\n // ignore\n }\n\n this.startDragging(e.clientX, e.clientY);\n e.preventDefault();\n }\n\n onPointerMove(e: PointerEvent): void {\n if (this.activePointerId !== null && e.pointerId !== this.activePointerId) return;\n\n if (this.isDragging) {\n this.drag(e.clientX, e.clientY);\n e.preventDefault();\n } else if (this.isResizing) {\n this.resize(e.clientX, e.clientY);\n e.preventDefault();\n }\n }\n\n onPointerUp(e: PointerEvent): void {\n if (this.activePointerId !== null && e.pointerId !== this.activePointerId) return;\n\n if (this.isDragging) {\n this.stopDragging();\n } else if (this.isResizing) {\n this.stopResizing();\n }\n\n this.activePointerId = null;\n this.activePointerType = null;\n }\n\n onMouseDown(e: MouseEvent): void {\n const target = e.target as HTMLElement;\n if (target.classList.contains(`${this.options.classPrefix}-resize-handle`)) {\n return;\n }\n \n // Call custom handler if provided\n if (this.options.onDragStart && !this.options.onDragStart(e)) {\n return;\n }\n\n this.startDragging(e.clientX, e.clientY);\n e.preventDefault();\n }\n\n onTouchStart(e: TouchEvent): void {\n const target = e.target as HTMLElement;\n if (target.classList.contains(`${this.options.classPrefix}-resize-handle`)) {\n return;\n }\n \n // Call custom handler if provided\n if (this.options.onDragStart && !this.options.onDragStart(e)) {\n return;\n }\n\n const touch = e.touches[0];\n if (!touch) return;\n this.startDragging(touch.clientX, touch.clientY);\n // Prevent page scroll while dragging (requires passive:false listener)\n e.preventDefault();\n }\n\n onResizeHandlePointerDown(e: PointerEvent): void {\n // Only handle primary pointer\n if (e.isPrimary === false) return;\n\n // Only left click for mouse\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n\n e.preventDefault();\n e.stopPropagation();\n\n const handle = e.target as HTMLElement;\n this.resizeDirection = handle.getAttribute('data-direction');\n\n this.activePointerId = e.pointerId;\n this.activePointerType = e.pointerType;\n\n try {\n (e.currentTarget as HTMLElement)?.setPointerCapture?.(e.pointerId);\n } catch {\n // ignore\n }\n\n this.startResizing(e.clientX, e.clientY);\n }\n\n onResizeHandleMouseDown(e: MouseEvent | TouchEvent): void {\n e.preventDefault();\n e.stopPropagation();\n \n const handle = e.target as HTMLElement;\n this.resizeDirection = handle.getAttribute('data-direction');\n \n const clientX = 'clientX' in e ? e.clientX : e.touches?.[0]?.clientX;\n const clientY = 'clientY' in e ? e.clientY : e.touches?.[0]?.clientY;\n if (clientX === undefined || clientY === undefined) return;\n\n this.startResizing(clientX, clientY);\n }\n\n onMouseMove(e: MouseEvent): void {\n if (this.isDragging) {\n this.drag(e.clientX, e.clientY);\n e.preventDefault();\n } else if (this.isResizing) {\n this.resize(e.clientX, e.clientY);\n e.preventDefault();\n }\n }\n\n onTouchMove(e: TouchEvent): void {\n if (this.isDragging || this.isResizing) {\n const touch = e.touches[0];\n if (!touch) return;\n if (this.isDragging) {\n this.drag(touch.clientX, touch.clientY);\n } else {\n this.resize(touch.clientX, touch.clientY);\n }\n e.preventDefault();\n }\n }\n\n onMouseUp(): void {\n if (this.isDragging) {\n this.stopDragging();\n } else if (this.isResizing) {\n this.stopResizing();\n }\n }\n\n onTouchEnd(): void {\n if (this.isDragging) {\n this.stopDragging();\n } else if (this.isResizing) {\n this.stopResizing();\n }\n }\n\n onKeyDown(e: KeyboardEvent): void {\n // Toggle drag mode\n if (e.key.toLowerCase() === this.options.keyboardDragKey.toLowerCase()) {\n e.preventDefault();\n this.toggleKeyboardDragMode();\n return;\n }\n\n // Toggle resize mode\n if (e.key.toLowerCase() === this.options.keyboardResizeKey.toLowerCase()) {\n e.preventDefault();\n if (this.hasManagedResizeHandles()) {\n this.togglePointerResizeMode();\n } else {\n this.toggleKeyboardResizeMode();\n }\n return;\n }\n\n // Exit modes with Escape\n if (e.key === 'Escape') {\n if (this.pointerResizeMode) {\n e.preventDefault();\n this.disablePointerResizeMode();\n return;\n }\n if (this.keyboardDragMode || this.keyboardResizeMode) {\n e.preventDefault();\n this.disableKeyboardDragMode();\n this.disableKeyboardResizeMode();\n return;\n }\n }\n\n // Arrow keys for drag/resize\n if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(e.key)) {\n if (this.keyboardDragMode) {\n e.preventDefault();\n e.stopPropagation();\n this.keyboardDrag(e.key, e.shiftKey);\n } else if (this.keyboardResizeMode) {\n e.preventDefault();\n e.stopPropagation();\n this.keyboardResize(e.key, e.shiftKey);\n }\n }\n\n // Home key to reset position\n if (e.key === 'Home' && (this.keyboardDragMode || this.keyboardResizeMode)) {\n e.preventDefault();\n this.resetPosition();\n }\n }\n\n startDragging(clientX: number, clientY: number): void {\n // Get current rendered position BEFORE any changes\n const rect = this.element.getBoundingClientRect();\n \n // Convert position to left/top IMMEDIATELY (before setting any state)\n // Check if element is using right/bottom/transform positioning\n const computedStyle = window.getComputedStyle(this.element);\n const needsConversion = computedStyle.right !== 'auto' || \n computedStyle.bottom !== 'auto' || \n computedStyle.transform !== 'none';\n \n this.positionOffsetX = 0;\n this.positionOffsetY = 0;\n\n if (needsConversion) {\n // Determine the correct left/top values based on position type\n let targetLeft, targetTop;\n \n if (computedStyle.position === 'absolute') {\n // position: absolute uses container-relative coordinates\n const offsetParent = this.element.offsetParent || document.body;\n const parentRect = offsetParent.getBoundingClientRect();\n targetLeft = rect.left - parentRect.left;\n targetTop = rect.top - parentRect.top;\n this.positionOffsetX = parentRect.left;\n this.positionOffsetY = parentRect.top;\n } else if (computedStyle.position === 'fixed') {\n const parsedLeft = parseFloat(computedStyle.left);\n const parsedTop = parseFloat(computedStyle.top);\n const hasLeft = Number.isFinite(parsedLeft);\n const hasTop = Number.isFinite(parsedTop);\n targetLeft = hasLeft ? parsedLeft : rect.left;\n targetTop = hasTop ? parsedTop : rect.top;\n this.positionOffsetX = rect.left - targetLeft;\n this.positionOffsetY = rect.top - targetTop;\n } else {\n // fallback: treat as viewport-relative\n targetLeft = rect.left;\n targetTop = rect.top;\n this.positionOffsetX = rect.left - targetLeft;\n this.positionOffsetY = rect.top - targetTop;\n }\n \n // Build complete style update atomically\n const currentCssText = this.element.style.cssText;\n let newCssText = currentCssText\n .split(';')\n .filter(rule => {\n const trimmed = rule.trim();\n // Filter out empty rules\n if (!trimmed) return false;\n \n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) return false;\n \n const property = trimmed.substring(0, colonIndex).trim();\n const value = trimmed.substring(colonIndex + 1).trim();\n \n // Skip if value is empty or just whitespace (this catches empty border properties)\n if (!value || value === '') return false;\n \n // Skip positioning properties\n if (property === 'right' || property === 'bottom' || property === 'transform' ||\n property === 'left' || property === 'top' || property === 'inset') {\n return false;\n }\n \n // Skip border-image properties (these can have empty values that cause parse errors)\n if (property.startsWith('border-image')) {\n return false;\n }\n \n return true;\n })\n .join('; ');\n \n if (newCssText) newCssText += '; ';\n newCssText += `left: ${targetLeft}px; top: ${targetTop}px; right: auto; bottom: auto; transform: none`;\n \n // Apply all at once\n this.element.style.cssText = newCssText;\n }\n \n // Now calculate offsets based on CURRENT position (after conversion)\n // Re-get rect after potential position change\n const finalRect = this.element.getBoundingClientRect();\n this.dragOffsetX = clientX - finalRect.left;\n this.dragOffsetY = clientY - finalRect.top;\n \n this.isDragging = true;\n this.element.classList.add(`${this.options.classPrefix}-dragging`);\n document.body.style.cursor = 'grabbing';\n document.body.style.userSelect = 'none';\n\n // Register the non-passive pointermove listener only for the duration of\n // the drag so it does not block compositor-threaded scroll at other times.\n if ('PointerEvent' in window) {\n document.addEventListener('pointermove', this.handlers.pointermove, { passive: false });\n }\n }\n\n drag(clientX: number, clientY: number): void {\n if (!this.isDragging) return;\n\n // Calculate new position: current mouse position minus the offset where user clicked\n let newX = clientX - this.dragOffsetX - this.positionOffsetX;\n let newY = clientY - this.dragOffsetY - this.positionOffsetY;\n \n // Constrain to viewport if needed\n if (this.options.constrainToViewport) {\n const rect = this.element.getBoundingClientRect();\n const viewportWidth = document.documentElement.clientWidth;\n const viewportHeight = document.documentElement.clientHeight;\n \n // Keep at least 100px visible\n const minVisible = 100;\n const minX = -(rect.width - minVisible);\n const minY = -(rect.height - minVisible);\n const maxX = viewportWidth - minVisible;\n const maxY = viewportHeight - minVisible;\n \n newX = Math.max(minX, Math.min(newX, maxX));\n newY = Math.max(minY, Math.min(newY, maxY));\n }\n \n this.element.style.left = `${newX}px`;\n this.element.style.top = `${newY}px`;\n \n // Call custom handler if provided\n if (this.options.onDrag) {\n this.options.onDrag({ x: newX, y: newY });\n }\n }\n\n stopDragging(): void {\n this.isDragging = false;\n this.element.classList.remove(`${this.options.classPrefix}-dragging`);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n\n // Remove the non-passive pointermove listener that was added in startDragging().\n if ('PointerEvent' in window) {\n document.removeEventListener('pointermove', this.handlers.pointermove);\n }\n \n // Mark as manually positioned\n this.manuallyPositioned = true;\n \n // Call custom handler if provided\n if (this.options.onDragEnd) {\n this.options.onDragEnd();\n }\n }\n\n startResizing(clientX: number, clientY: number): void {\n this.isResizing = true;\n this.resizeStartX = clientX;\n this.resizeStartY = clientY;\n \n const rect = this.element.getBoundingClientRect();\n this.resizeStartWidth = rect.width;\n this.resizeStartHeight = rect.height;\n this.resizeStartLeft = rect.left;\n this.resizeStartTop = rect.top;\n \n this.element.classList.add(`${this.options.classPrefix}-resizing`);\n document.body.style.userSelect = 'none';\n\n // Register the non-passive pointermove listener only for the duration of\n // the resize so it does not block compositor-threaded scroll at other times.\n if ('PointerEvent' in window) {\n document.addEventListener('pointermove', this.handlers.pointermove, { passive: false });\n }\n \n // Call custom handler if provided\n if (this.options.onResizeStart) {\n this.options.onResizeStart();\n }\n }\n\n resize(clientX: number, clientY: number): void {\n if (!this.isResizing) return;\n\n const deltaX = clientX - this.resizeStartX;\n const deltaY = clientY - this.resizeStartY;\n \n let newWidth = this.resizeStartWidth;\n let newHeight = this.resizeStartHeight;\n let newLeft = this.resizeStartLeft;\n let newTop = this.resizeStartTop;\n\n // Handle horizontal resizing\n const resizeDirection = this.resizeDirection ?? '';\n\n if (resizeDirection.includes('e')) {\n newWidth = Math.max(this.options.minWidth, this.resizeStartWidth + deltaX);\n }\n if (resizeDirection.includes('w')) {\n const proposedWidth = Math.max(this.options.minWidth, this.resizeStartWidth - deltaX);\n newLeft = this.resizeStartLeft + (this.resizeStartWidth - proposedWidth);\n newWidth = proposedWidth;\n }\n\n const maxWidthOption = typeof this.options.maxWidth === 'function'\n ? this.options.maxWidth()\n : this.options.maxWidth;\n if (typeof maxWidthOption === 'number' && Number.isFinite(maxWidthOption)) {\n const clampedWidth = Math.min(newWidth, maxWidthOption);\n if (clampedWidth !== newWidth && resizeDirection.includes('w')) {\n newLeft += newWidth - clampedWidth;\n }\n newWidth = clampedWidth;\n }\n\n // Handle vertical resizing (if not maintaining aspect ratio)\n if (!this.options.maintainAspectRatio) {\n if (resizeDirection.includes('s')) {\n newHeight = Math.max(this.options.minHeight, this.resizeStartHeight + deltaY);\n }\n if (resizeDirection.includes('n')) {\n const proposedHeight = Math.max(this.options.minHeight, this.resizeStartHeight - deltaY);\n newTop = this.resizeStartTop + (this.resizeStartHeight - proposedHeight);\n newHeight = proposedHeight;\n }\n\n const maxHeightOption = typeof this.options.maxHeight === 'function'\n ? this.options.maxHeight()\n : this.options.maxHeight;\n if (typeof maxHeightOption === 'number' && Number.isFinite(maxHeightOption)) {\n const clampedHeight = Math.min(newHeight, maxHeightOption);\n if (clampedHeight !== newHeight && resizeDirection.includes('n')) {\n newTop += newHeight - clampedHeight;\n }\n newHeight = clampedHeight;\n }\n }\n\n // Apply new dimensions\n this.element.style.width = `${newWidth}px`;\n if (!this.options.maintainAspectRatio) {\n this.element.style.height = `${newHeight}px`;\n } else {\n this.element.style.height = 'auto';\n }\n \n // Apply new position if resizing from west or north\n if (resizeDirection.includes('w')) {\n this.element.style.left = `${newLeft}px`;\n }\n if (resizeDirection.includes('n') && !this.options.maintainAspectRatio) {\n this.element.style.top = `${newTop}px`;\n }\n \n // Call custom handler if provided\n if (this.options.onResize) {\n this.options.onResize({ width: newWidth, height: newHeight, left: newLeft, top: newTop });\n }\n }\n\n stopResizing(): void {\n this.isResizing = false;\n this.resizeDirection = null;\n this.element.classList.remove(`${this.options.classPrefix}-resizing`);\n document.body.style.userSelect = '';\n\n // Remove the non-passive pointermove listener that was added in startResizing().\n if ('PointerEvent' in window) {\n document.removeEventListener('pointermove', this.handlers.pointermove);\n }\n \n // Mark as manually positioned\n this.manuallyPositioned = true;\n \n // Call custom handler if provided\n if (this.options.onResizeEnd) {\n this.options.onResizeEnd();\n }\n }\n\n toggleKeyboardDragMode(): void {\n if (this.keyboardDragMode) {\n this.disableKeyboardDragMode();\n } else {\n this.enableKeyboardDragMode();\n }\n }\n\n enableKeyboardDragMode(): void {\n this.keyboardDragMode = true;\n this.keyboardResizeMode = false;\n this.element.classList.add(`${this.options.classPrefix}-keyboard-drag`);\n this.element.classList.remove(`${this.options.classPrefix}-keyboard-resize`);\n this.focusElement();\n }\n\n disableKeyboardDragMode(): void {\n this.keyboardDragMode = false;\n this.element.classList.remove(`${this.options.classPrefix}-keyboard-drag`);\n }\n\n toggleKeyboardResizeMode(): void {\n if (this.keyboardResizeMode) {\n this.disableKeyboardResizeMode();\n } else {\n this.enableKeyboardResizeMode();\n }\n }\n\n enableKeyboardResizeMode(): void {\n this.keyboardResizeMode = true;\n this.keyboardDragMode = false;\n this.element.classList.add(`${this.options.classPrefix}-keyboard-resize`);\n this.element.classList.remove(`${this.options.classPrefix}-keyboard-drag`);\n this.focusElement();\n }\n\n disableKeyboardResizeMode(): void {\n this.keyboardResizeMode = false;\n this.element.classList.remove(`${this.options.classPrefix}-keyboard-resize`);\n }\n\n enablePointerResizeMode({ focus = true }: { focus?: boolean } = {}): void {\n if (!this.hasManagedResizeHandles()) {\n this.enableKeyboardResizeMode();\n return;\n }\n\n if (this.pointerResizeMode) {\n return;\n }\n\n this.pointerResizeMode = true;\n this.setManagedHandlesVisible(true);\n this.element.classList.add(`${this.options.classPrefix}-resizable`);\n this.enableKeyboardResizeMode();\n\n if (focus) {\n this.focusElement();\n }\n\n if (typeof this.options.onPointerResizeToggle === 'function') {\n this.options.onPointerResizeToggle(true);\n }\n }\n\n disablePointerResizeMode({ focus = false }: { focus?: boolean } = {}): void {\n if (!this.pointerResizeMode) {\n return;\n }\n\n this.pointerResizeMode = false;\n this.setManagedHandlesVisible(false);\n this.element.classList.remove(`${this.options.classPrefix}-resizable`);\n this.disableKeyboardResizeMode();\n\n if (focus) {\n this.focusElement();\n }\n\n if (typeof this.options.onPointerResizeToggle === 'function') {\n this.options.onPointerResizeToggle(false);\n }\n }\n\n togglePointerResizeMode(): boolean {\n if (this.pointerResizeMode) {\n this.disablePointerResizeMode();\n } else {\n this.enablePointerResizeMode();\n }\n return this.pointerResizeMode;\n }\n\n focusElement(): void {\n if (typeof this.element.focus === 'function') {\n try {\n this.element.focus({ preventScroll: true });\n } catch {\n // Some browsers do not support the preventScroll option; fallback without it\n this.element.focus();\n }\n }\n }\n\n keyboardDrag(key: string, shiftKey: boolean): void {\n const step = shiftKey ? this.options.keyboardStepLarge : this.options.keyboardStep;\n \n // Get current position\n let currentLeft = parseFloat(this.element.style.left) || 0;\n let currentTop = parseFloat(this.element.style.top) || 0;\n \n // If element is still centered with transform, convert to absolute position first\n const computedStyle = window.getComputedStyle(this.element);\n if (computedStyle.transform !== 'none') {\n const rect = this.element.getBoundingClientRect();\n currentLeft = rect.left;\n currentTop = rect.top;\n this.element.style.transform = 'none';\n this.element.style.left = `${currentLeft}px`;\n this.element.style.top = `${currentTop}px`;\n }\n \n // Calculate new position\n let newX = currentLeft;\n let newY = currentTop;\n\n switch(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 // Apply position\n this.element.style.left = `${newX}px`;\n this.element.style.top = `${newY}px`;\n \n // Call custom handler if provided\n if (this.options.onDrag) {\n this.options.onDrag({ x: newX, y: newY });\n }\n }\n\n keyboardResize(key: string, shiftKey: boolean): void {\n const step = shiftKey ? this.options.keyboardStepLarge : this.options.keyboardStep;\n const rect = this.element.getBoundingClientRect();\n \n let width = rect.width;\n let height = rect.height;\n\n // Adjust width/height based on arrow key\n switch(key) {\n case 'ArrowLeft':\n width -= step;\n break;\n case 'ArrowRight':\n width += step;\n break;\n case 'ArrowUp':\n if (this.options.maintainAspectRatio) {\n width += step;\n } else {\n height -= step;\n }\n break;\n case 'ArrowDown':\n if (this.options.maintainAspectRatio) {\n width -= step;\n } else {\n height += step;\n }\n break;\n }\n\n // Constrain to minimum dimensions\n width = Math.max(this.options.minWidth, width);\n height = Math.max(this.options.minHeight, height);\n\n // Apply new dimensions\n this.element.style.width = `${width}px`;\n if (!this.options.maintainAspectRatio) {\n this.element.style.height = `${height}px`;\n } else {\n this.element.style.height = 'auto';\n }\n \n // Call custom handler if provided\n if (this.options.onResize) {\n this.options.onResize({ width, height });\n }\n }\n\n resetPosition(): void {\n this.element.style.left = '50%';\n this.element.style.top = '50%';\n this.element.style.transform = 'translate(-50%, -50%)';\n this.element.style.right = '';\n this.element.style.bottom = '';\n \n // Clear manual positioning flag\n this.manuallyPositioned = false;\n \n // Call custom handler if provided\n if (this.options.onDrag) {\n this.options.onDrag({ centered: true });\n }\n }\n\n destroy(): void {\n const dragHandle = this.options.dragHandle || this.element;\n \n this.disablePointerResizeMode();\n \n // Remove drag events\n dragHandle.removeEventListener('mousedown', this.handlers.mousedown);\n dragHandle.removeEventListener('touchstart', this.handlers.touchstart);\n dragHandle.removeEventListener('pointerdown', this.handlers.pointerdown);\n \n // Remove document-level events\n document.removeEventListener('mousemove', this.handlers.mousemove);\n document.removeEventListener('mouseup', this.handlers.mouseup);\n document.removeEventListener('touchmove', this.handlers.touchmove);\n document.removeEventListener('touchend', this.handlers.touchend);\n document.removeEventListener('pointermove', this.handlers.pointermove);\n document.removeEventListener('pointerup', this.handlers.pointerup);\n document.removeEventListener('pointercancel', this.handlers.pointercancel);\n \n // Remove keyboard events\n this.element.removeEventListener('keydown', this.handlers.keydown);\n \n // Remove resize handle events\n if (this.options.resizeHandles && this.options.resizeHandles.length > 0) {\n this.options.resizeHandles.forEach(handle => {\n handle.removeEventListener('mousedown', this.handlers.resizeHandleMousedown);\n handle.removeEventListener('touchstart', this.handlers.resizeHandleMousedown);\n handle.removeEventListener('pointerdown', this.handlers.resizeHandlePointerDown);\n });\n }\n \n // Clean up classes\n this.element.classList.remove(\n `${this.options.classPrefix}-dragging`,\n `${this.options.classPrefix}-resizing`,\n `${this.options.classPrefix}-keyboard-drag`,\n `${this.options.classPrefix}-keyboard-resize`\n );\n }\n}\n\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
@@ -84,4 +84,4 @@ function loadScriptOnce(url, options = {}) {
|
|
|
84
84
|
export {
|
|
85
85
|
loadScriptOnce
|
|
86
86
|
};
|
|
87
|
-
//# sourceMappingURL=vidply.chunk-
|
|
87
|
+
//# sourceMappingURL=vidply.chunk-HOYEMJSD.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
@@ -27,4 +27,4 @@ export {
|
|
|
27
27
|
focusElement,
|
|
28
28
|
focusFirstElement
|
|
29
29
|
};
|
|
30
|
-
//# sourceMappingURL=vidply.chunk-
|
|
30
|
+
//# sourceMappingURL=vidply.chunk-JAKZNGOR.js.map
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
6
6
|
import {
|
|
7
7
|
StorageManager,
|
|
8
8
|
deriveTrackLabel
|
|
9
|
-
} from "./vidply.chunk-
|
|
9
|
+
} from "./vidply.chunk-UHMVDBDB.js";
|
|
10
10
|
import {
|
|
11
11
|
debounce,
|
|
12
12
|
isMobile,
|
|
13
13
|
rafWithTimeout,
|
|
14
14
|
reducedMotionScrollOptions
|
|
15
|
-
} from "./vidply.chunk-
|
|
15
|
+
} from "./vidply.chunk-5IK3IC5V.js";
|
|
16
16
|
import {
|
|
17
17
|
DOMUtils,
|
|
18
18
|
i18n
|
|
19
|
-
} from "./vidply.chunk-
|
|
19
|
+
} from "./vidply.chunk-NSMAZCMB.js";
|
|
20
20
|
|
|
21
21
|
// src/controls/CaptionManager.ts
|
|
22
22
|
var CaptionManager = class {
|
|
@@ -450,4 +450,4 @@ var CaptionManager = class {
|
|
|
450
450
|
export {
|
|
451
451
|
CaptionManager
|
|
452
452
|
};
|
|
453
|
-
//# sourceMappingURL=vidply.chunk-
|
|
453
|
+
//# sourceMappingURL=vidply.chunk-LDVFAFGC.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/controls/CaptionManager.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Caption/Subtitle Manager\n */\n\nimport {DOMUtils} from '../utils/DOMUtils.js';\nimport {i18n} from '../i18n/i18n.js';\nimport {StorageManager} from '../utils/StorageManager.js';\nimport {debounce, isMobile, rafWithTimeout, reducedMotionScrollOptions} from '../utils/PerformanceUtils.js';\nimport {deriveTrackLabel} from '../utils/TrackLabelUtils.js';\nimport type { Player } from '../core/Player.js';\n\n/**\n * Deduplicated subtitle/captions entry shown in the captions menu. Native HLS\n * on Safari can expose the same language as both `SUBTITLES` (WebVTT sidecar)\n * and `CLOSED-CAPTIONS` (inband CEA-608) groups; the duplicates are kept in\n * `alternatives` so we can listen on all of them and use whichever delivers\n * cues first.\n */\nexport type CaptionTrackEntry = {\n track: TextTrack;\n language: string;\n label: string;\n kind: string;\n index: number;\n isDefault: boolean;\n alternatives: TextTrack[];\n};\n\ntype CueChangeHandler = () => void;\n\nexport class CaptionManager {\n player: Player;\n _altCueChangeHandler: CueChangeHandler | null = null;\n cueChangeHandler: CueChangeHandler | null = null;\n currentCue: VTTCue | null;\n currentTrack: CaptionTrackEntry | null;\n debouncedPositionCaptions!: () => void;\n element!: HTMLElement;\n storage: StorageManager;\n tracks: CaptionTrackEntry[];\n\n constructor(player: Player) {\n this.player = player;\n this.tracks = [];\n this.currentTrack = null;\n this.currentCue = null;\n\n // Storage manager\n this.storage = new StorageManager('vidply');\n\n // Load saved preferences\n this.loadSavedPreferences();\n\n this.init();\n }\n \n loadSavedPreferences() {\n const saved = this.storage.getCaptionPreferences();\n if (saved) {\n if (typeof saved.fontSize === 'string') this.player.options.captionsFontSize = saved.fontSize;\n if (typeof saved.fontFamily === 'string') this.player.options.captionsFontFamily = saved.fontFamily;\n if (typeof saved.color === 'string') this.player.options.captionsColor = saved.color;\n if (typeof saved.backgroundColor === 'string') this.player.options.captionsBackgroundColor = saved.backgroundColor;\n if (typeof saved.opacity === 'number') this.player.options.captionsOpacity = saved.opacity;\n }\n }\n \n saveCaptionPreferences() {\n this.storage.saveCaptionPreferences({\n fontSize: this.player.options.captionsFontSize,\n fontFamily: this.player.options.captionsFontFamily,\n color: this.player.options.captionsColor,\n backgroundColor: this.player.options.captionsBackgroundColor,\n opacity: this.player.options.captionsOpacity\n });\n }\n\n init() {\n this.createElement();\n this.loadTracks();\n this.attachEvents();\n\n // Only enable captions via captionsDefault option if no default track was found\n // (loadTracks() already enables tracks with the default attribute)\n if (this.player.options.captionsDefault && this.tracks.length > 0 && !this.currentTrack) {\n this.enable();\n }\n }\n\n createElement() {\n // The native <track> is rendered hidden and captions are drawn into\n // this overlay, so assistive tech cannot read cues from the track\n // itself. aria-live=\"polite\" makes each cue change announceable for\n // screen-reader users (notably deaf-blind/braille users) without\n // interrupting other speech (WCAG 1.2.2, 4.1.3).\n this.element = DOMUtils.createElement('div', {\n className: `${this.player.options.classPrefix}-captions`,\n attributes: {\n 'role': 'region',\n 'aria-label': i18n.t('player.captions'),\n 'aria-live': 'polite'\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 let defaultTrackIndex = -1;\n\n // Safari's native HLS can expose both SUBTITLES (WebVTT sidecar) and\n // CLOSED-CAPTIONS (inband CEA-608) groups as separate TextTrack objects\n // with the same language and label. Deduplicate to one menu entry per\n // language+label, storing the extras as alternatives. enable() will\n // listen on all of them and use whichever delivers cues first.\n const seen = new Map();\n\n for (let i = 0; i < textTracks.length; i++) {\n const track = textTracks[i];\n if (!track) continue;\n\n if ((track.kind === 'subtitles' || track.kind === 'captions') && !track._vidplyStale) {\n track.mode = 'hidden';\n\n const dedupeKey = `${track.language}|${track.label}`;\n const existing = seen.get(dedupeKey);\n\n if (existing) {\n existing.alternatives.push(track);\n continue;\n }\n\n const trackElement = this.player.findTrackElement(track) as Element | undefined;\n const isDefault = trackElement ? trackElement.hasAttribute('default') : false;\n const entry: CaptionTrackEntry = {\n track,\n language: track.language,\n label: deriveTrackLabel(track.label, track.language),\n kind: track.kind,\n index: i,\n isDefault,\n alternatives: []\n };\n\n this.tracks.push(entry);\n seen.set(dedupeKey, entry);\n\n if (isDefault) {\n defaultTrackIndex = this.tracks.length - 1;\n }\n }\n }\n \n if (defaultTrackIndex >= 0) {\n requestAnimationFrame(() => {\n this.enable(defaultTrackIndex);\n });\n }\n }\n\n /**\n * Sync hls.js subtitle rendition to match the given language.\n * Matches by lang, language, or falls back to name/label.\n */\n private _syncHlsSubtitleTrack(targetLang: string, targetLabel?: string) {\n const renderer = this.player.renderer;\n if (!renderer?.hls || !renderer.hls.subtitleTracks?.length) return;\n\n const tracks = renderer.hls.subtitleTracks as Array<{ lang?: string; name?: string }>;\n let hlsIndex = tracks.findIndex(\n (t) => t.lang === targetLang\n );\n // Fallback: match by name/label\n if (hlsIndex < 0 && targetLabel) {\n hlsIndex = tracks.findIndex(\n (t) => t.name === targetLabel\n );\n }\n if (hlsIndex >= 0 && renderer.hls.subtitleTrack !== hlsIndex) {\n renderer.hls.subtitleTrack = hlsIndex;\n this.player.log(`HLS subtitle track set to index ${hlsIndex} (${targetLang})`, 'info');\n }\n }\n\n attachEvents() {\n this.player.on('timeupdate', () => {\n this.updateCaptions();\n });\n\n // When hls.js finishes loading new subtitle cues, refresh captions\n this.player.on('textcuesupdate', () => {\n this.updateCaptions();\n });\n\n this.player.on('captionschange', () => {\n this.updateStyles();\n });\n \n // Debounced resize handler to avoid excessive recalculations\n this.debouncedPositionCaptions = debounce(() => {\n this.positionCaptionsOnMobile();\n }, 150);\n \n window.addEventListener('resize', this.debouncedPositionCaptions, {\n signal: this.player.lifecycleSignal\n });\n \n // Recalculate on fullscreen change with RAF\n this.player.on('enterfullscreen', () => {\n rafWithTimeout(() => this.positionCaptionsOnMobile(), 100);\n });\n \n this.player.on('exitfullscreen', () => {\n rafWithTimeout(() => this.positionCaptionsOnMobile(), 100);\n });\n }\n\n enable(trackIndex = 0) {\n if (this.tracks.length === 0) {\n return;\n }\n\n // Disable current track and clean up alternative listeners\n this._cleanupTrackListeners();\n\n // Enable selected track\n const selectedTrack = this.tracks[trackIndex];\n\n if (selectedTrack && selectedTrack.track) {\n selectedTrack.track.mode = 'hidden';\n this.currentTrack = selectedTrack;\n this.player.state.captionsEnabled = true;\n\n if (selectedTrack.language) {\n this.element.setAttribute('lang', selectedTrack.language);\n }\n\n // Bind handlers to locals so the non-null narrowing survives both\n // closure captures and `this.X = …` reassignments. Without this,\n // `addEventListener(this.cueChangeHandler)` widens to `… | null`\n // and stops type-checking even though we just assigned a function.\n const cueChangeHandler: CueChangeHandler = () => {\n this.updateCaptions();\n };\n this.cueChangeHandler = cueChangeHandler;\n selectedTrack.track.addEventListener('cuechange', cueChangeHandler);\n\n // Native HLS dedup: Safari can expose duplicate TextTrack objects\n // for the same language (SUBTITLES vs CLOSED-CAPTIONS groups) but\n // only one actually delivers cues. Listen on all alternatives and\n // swap to whichever fires first with real cues.\n if (selectedTrack.alternatives && selectedTrack.alternatives.length > 0) {\n const altCueChangeHandler: CueChangeHandler = () => {\n if (this.currentTrack !== selectedTrack) return;\n for (const alt of selectedTrack.alternatives) {\n if (alt.activeCues && alt.activeCues.length > 0) {\n this.player.log(`Switching to alternative caption track for \"${selectedTrack.label}\"`, 'info');\n selectedTrack.track.removeEventListener('cuechange', cueChangeHandler);\n selectedTrack.alternatives.forEach((a) => a.removeEventListener('cuechange', altCueChangeHandler));\n selectedTrack.track = alt;\n selectedTrack.track.addEventListener('cuechange', cueChangeHandler);\n this._altCueChangeHandler = null;\n this.updateCaptions();\n return;\n }\n }\n };\n this._altCueChangeHandler = altCueChangeHandler;\n selectedTrack.alternatives.forEach((alt) => {\n alt.mode = 'hidden';\n alt.addEventListener('cuechange', altCueChangeHandler);\n });\n }\n\n // The \"ready\" sense actually lives on the underlying <track> HTML\n // element — not on the TextTrack itself, which has no `readyState`\n // or `load` event. Look the element up so this is type-safe and\n // also fires the load callback in browsers where TextTrack alone\n // would never have done so.\n const trackElement = this.player.findTrackElement(selectedTrack.track) as HTMLTrackElement | undefined;\n const ensureTrackReady = () => {\n if (trackElement && trackElement.readyState < 2) {\n const onTrackLoad = () => {\n trackElement.removeEventListener('load', onTrackLoad);\n trackElement.removeEventListener('error', onTrackLoad);\n requestAnimationFrame(() => {\n if (this.currentTrack && this.currentTrack.track === selectedTrack.track) {\n this.updateCaptions();\n }\n });\n };\n trackElement.addEventListener('load', onTrackLoad, { once: true });\n trackElement.addEventListener('error', onTrackLoad, { once: true });\n } else {\n requestAnimationFrame(() => {\n if (this.currentTrack && this.currentTrack.track === selectedTrack.track) {\n this.updateCaptions();\n }\n });\n }\n };\n\n requestAnimationFrame(() => {\n if (this.currentTrack && this.currentTrack.track === selectedTrack.track) {\n ensureTrackReady();\n }\n });\n\n // Sync hls.js subtitle rendition to match the selected track language\n this._syncHlsSubtitleTrack(selectedTrack.language, selectedTrack.label);\n\n this.player.emit('captionsenabled', selectedTrack);\n }\n }\n\n _cleanupTrackListeners() {\n if (this.currentTrack && this.currentTrack.track) {\n const cueChangeHandler = this.cueChangeHandler;\n if (cueChangeHandler) {\n this.currentTrack.track.removeEventListener('cuechange', cueChangeHandler);\n }\n const altCueChangeHandler = this._altCueChangeHandler;\n if (altCueChangeHandler && this.currentTrack.alternatives) {\n this.currentTrack.alternatives.forEach((alt) => {\n alt.removeEventListener('cuechange', altCueChangeHandler);\n });\n }\n this.currentTrack.track.mode = 'hidden';\n }\n this._altCueChangeHandler = null;\n }\n\n disable() {\n this._cleanupTrackListeners();\n this.currentTrack = null;\n\n this.element.style.display = 'none';\n this.element.replaceChildren();\n this.element.removeAttribute('lang');\n this.currentCue = null;\n this.player.state.captionsEnabled = false;\n this.player.emit('captionsdisabled');\n }\n\n updateCaptions() {\n if (!this.currentTrack || !this.currentTrack.track) {\n return;\n }\n\n // When the renderer handles its own caption display (e.g. dash.js TTML\n // rendering div), skip VidPly's caption overlay entirely.\n if (this.player.renderer?.handlesOwnCaptions?.()) {\n return;\n }\n\n // Ensure track mode is set to 'hidden' (not 'disabled') to receive cue updates\n // 'hidden' mode loads cues and fires cuechange events, but doesn't show native captions\n if (this.currentTrack.track.mode === 'disabled') {\n this.currentTrack.track.mode = 'hidden';\n }\n\n if (this.currentTrack.track.mode === 'showing') {\n this.currentTrack.track.mode = 'hidden';\n }\n\n if (!this.currentTrack.track.activeCues) {\n if (this.currentTrack.track.cues && this.currentTrack.track.cues.length > 0) {\n if (this.currentCue) {\n this.element.replaceChildren();\n this.element.style.display = 'none';\n this.currentCue = null;\n }\n }\n return;\n }\n\n const activeCues = this.currentTrack.track.activeCues;\n const isAudioPlayer = this.player.element.tagName.toLowerCase() === 'audio';\n\n if (activeCues.length > 0) {\n // VTT/SRT subtitle tracks deliver `VTTCue` instances (which extend\n // TextTrackCue with `.text`). The lib.dom typing widens this to\n // `TextTrackCue`, so cast at the boundary.\n const cue = activeCues[0] as VTTCue;\n\n if (this.currentCue !== cue) {\n this.currentCue = cue;\n\n const rawText = cue.text || '';\n if (!rawText.trim()) {\n return;\n }\n\n const fragment = DOMUtils.renderVTTToDOM(rawText);\n\n if (isAudioPlayer) {\n const existingCues = this.element.querySelectorAll(`.${this.player.options.classPrefix}-caption-cue`);\n existingCues.forEach((el: Element) => el.classList.remove(`${this.player.options.classPrefix}-caption-active`));\n\n const cueId = `cue-${cue.startTime}-${cue.endTime}`;\n let cueElement = this.element.querySelector(`[data-cue-id=\"${cueId}\"]`);\n\n if (!cueElement) {\n cueElement = document.createElement('div');\n cueElement.className = `${this.player.options.classPrefix}-caption-cue`;\n cueElement.setAttribute('data-cue-id', cueId);\n cueElement.replaceChildren(fragment);\n this.element.appendChild(cueElement);\n } else {\n cueElement.replaceChildren(fragment);\n }\n\n cueElement.classList.add(`${this.player.options.classPrefix}-caption-active`);\n\n requestAnimationFrame(() => {\n if (cueElement) {\n cueElement.scrollIntoView(reducedMotionScrollOptions('center'));\n }\n });\n } else {\n this.element.replaceChildren(fragment);\n }\n\n this.element.style.display = 'block';\n this.positionCaptionsOnMobile();\n this.player.emit('captionchange', cue);\n }\n } else if (this.currentCue) {\n if (!isAudioPlayer) {\n this.element.replaceChildren();\n this.element.style.display = 'none';\n }\n this.currentCue = null;\n }\n }\n \n positionCaptionsOnMobile() {\n if (!this.element || this.element.style.display === 'none') {\n return;\n }\n \n const isFullscreen = this.player.state?.fullscreen || false;\n const mobile = isMobile();\n \n if (!mobile && !isFullscreen) {\n // Reset to CSS defaults on desktop\n this.element.style.bottom = '';\n return;\n }\n \n const controls = this.player.controlBar?.element;\n if (!controls) {\n return;\n }\n \n // Use requestAnimationFrame to ensure layout is complete\n requestAnimationFrame(() => {\n if (!this.element || this.element.style.display === 'none') {\n return;\n }\n \n const controlsRect = controls.getBoundingClientRect();\n if (!this.player.videoWrapper) return;\n const wrapperRect = this.player.videoWrapper.getBoundingClientRect();\n const bottomOffset = wrapperRect.bottom - controlsRect.top + 16;\n \n this.element.style.bottom = `${bottomOffset}px`;\n \n if (this.player.options.debug) {\n console.log('[VidPly] Caption position:', {\n mobile,\n isFullscreen,\n controlsHeight: controlsRect.height,\n bottomOffset: `${bottomOffset}px`\n });\n }\n });\n }\n\n // VTT formatting is parsed via DOMUtils.renderVTTToDOM() which returns\n // a DocumentFragment built with createElement / createTextNode. The\n // previous regex-based parseVTTFormatting helper was removed because\n // it produced strings that were assigned to `innerHTML`, which is\n // unsafe for cue text from third-party WebVTT sources.\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: string, alpha: number) {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n if (result && result[1] && result[2] && result[3]) {\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: string, value: string | number) {\n // The persisted preference shape is mixed (string for font/colors,\n // number for opacity). Cast through the player's loose options\n // index so we don't have to split this method into 5 strongly-typed\n // overloads when the underlying string-keyed bag is itself loose.\n switch (property) {\n case 'fontSize':\n this.player.options.captionsFontSize = String(value);\n break;\n case 'fontFamily':\n this.player.options.captionsFontFamily = String(value);\n break;\n case 'color':\n this.player.options.captionsColor = String(value);\n break;\n case 'backgroundColor':\n this.player.options.captionsBackgroundColor = String(value);\n break;\n case 'opacity':\n this.player.options.captionsOpacity = Number(value);\n break;\n }\n\n this.updateStyles();\n this.saveCaptionPreferences();\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 /**\n * Refresh tracks list - useful when HLS adds subtitle tracks dynamically\n */\n refreshTracks() {\n // Store current track info to restore after refresh\n const currentLanguage = this.currentTrack?.language;\n const wasEnabled = this.player.state.captionsEnabled;\n \n // Disable current caption\n if (this.currentTrack) {\n this.disable();\n }\n \n // Clear existing tracks\n this.tracks = [];\n \n // Reload tracks from video element\n this.loadTracks();\n \n this.player.log(`Caption tracks refreshed, found ${this.tracks.length} tracks`, 'info');\n \n // Try to restore previous track if it exists\n if (wasEnabled && currentLanguage && this.tracks.length > 0) {\n const matchingIndex = this.tracks.findIndex((t) => t.language === currentLanguage);\n if (matchingIndex >= 0) {\n this.enable(matchingIndex);\n }\n }\n \n return this.tracks.length;\n }\n\n switchTrack(trackIndex: number) {\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"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
@@ -471,10 +471,10 @@ var en = {
|
|
|
471
471
|
|
|
472
472
|
// src/i18n/translations.ts
|
|
473
473
|
var builtInLanguageLoaders = {
|
|
474
|
-
de: () => import("./vidply.de-
|
|
475
|
-
es: () => import("./vidply.es-
|
|
476
|
-
fr: () => import("./vidply.fr-
|
|
477
|
-
ja: () => import("./vidply.ja-
|
|
474
|
+
de: () => import("./vidply.de-5W5LBFSJ.js"),
|
|
475
|
+
es: () => import("./vidply.es-SHDAT6L6.js"),
|
|
476
|
+
fr: () => import("./vidply.fr-2JANOMNB.js"),
|
|
477
|
+
ja: () => import("./vidply.ja-WWMSTEJH.js")
|
|
478
478
|
};
|
|
479
479
|
function getBaseTranslations() {
|
|
480
480
|
return { en };
|
|
@@ -658,4 +658,4 @@ export {
|
|
|
658
658
|
shallowSanitize,
|
|
659
659
|
i18n
|
|
660
660
|
};
|
|
661
|
-
//# sourceMappingURL=vidply.chunk-
|
|
661
|
+
//# sourceMappingURL=vidply.chunk-NSMAZCMB.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/DOMUtils.ts", "../../src/utils/Sanitize.ts", "../../src/i18n/languages/en.ts", "../../src/i18n/translations.ts", "../../src/i18n/i18n.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Options accepted by {@link DOMUtils.createElement}.\n *\n * `innerHTML` is deliberately **not** exposed here. Code that needs to\n * inject raw markup must do so explicitly at the call site where the\n * source of the markup is auditable; DOMUtils is the \"safe by default\"\n * surface.\n */\nexport interface CreateElementOptions {\n className?: string;\n attributes?: Record<string, string | undefined>;\n textContent?: string;\n style?: Partial<CSSStyleDeclaration>;\n children?: (Node | null | undefined)[];\n}\n\nfunction createElementImpl<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n options?: CreateElementOptions\n): HTMLElementTagNameMap[K];\nfunction createElementImpl(tag: string, options?: CreateElementOptions): HTMLElement;\nfunction createElementImpl(tag: string, options: CreateElementOptions = {}): HTMLElement {\n const element = document.createElement(tag);\n\n if (options.className) {\n element.className = options.className;\n }\n\n if (options.attributes) {\n for (const [key, value] of Object.entries(options.attributes)) {\n if (value !== undefined) {\n element.setAttribute(key, value);\n }\n }\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 for (const child of options.children) {\n if (child) element.appendChild(child);\n }\n }\n\n return element;\n}\n\nexport const DOMUtils = {\n createElement: createElementImpl,\n\n show(element: HTMLElement | null | undefined): void {\n if (element?.style) {\n element.style.display = '';\n }\n },\n\n hide(element: HTMLElement | null | undefined): void {\n if (element?.style) {\n element.style.display = 'none';\n }\n },\n\n fadeIn(element: HTMLElement | null, duration = 300, onComplete?: () => void): void {\n if (!element) return;\n\n element.style.opacity = '0';\n element.style.display = '';\n element.style.transition = `opacity ${duration}ms ease`;\n\n // Force reflow to ensure transition works\n void element.offsetHeight;\n\n element.style.opacity = '1';\n\n if (onComplete) {\n let called = false;\n const cleanup = () => {\n if (called) return;\n called = true;\n element.removeEventListener('transitionend', cleanup);\n onComplete();\n };\n element.addEventListener('transitionend', cleanup, { once: true });\n setTimeout(cleanup, duration + 50);\n }\n },\n\n fadeOut(element: HTMLElement | null, duration = 300, onComplete?: () => void): void {\n if (!element) return;\n\n element.style.transition = `opacity ${duration}ms ease`;\n element.style.opacity = '0';\n\n let called = false;\n const cleanup = () => {\n if (called) return;\n called = true;\n element.removeEventListener('transitionend', cleanup);\n element.style.display = 'none';\n if (onComplete) onComplete();\n };\n\n element.addEventListener('transitionend', cleanup, { once: true });\n setTimeout(cleanup, duration + 50);\n },\n\n offset(element: HTMLElement | null): { top: number; left: number; width: number; height: number } {\n if (!element) return { top: 0, left: 0, width: 0, height: 0 };\n\n const rect = element.getBoundingClientRect();\n return {\n top: rect.top + window.scrollY,\n left: rect.left + window.scrollX,\n width: rect.width,\n height: rect.height\n };\n },\n\n escapeHTML(str: string): string {\n const escapeMap: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n };\n return str.replace(/[&<>\"']/g, char => escapeMap[char] ?? char);\n },\n\n /**\n * Render a WebVTT cue's text safely.\n *\n * The previous implementation ran a regex-based blacklist over the cue\n * string and assigned the result to `innerHTML`, which is a known-unsafe\n * pattern (mutation-XSS bypasses, attribute-name tricks, etc.). Caption\n * text on most sites is fetched verbatim from external `.vtt` files that\n * the embedding page has no control over (third-party HLS/DASH manifests,\n * user-supplied playlists, ...) so this code path is reachable by\n * untrusted authors.\n *\n * The new implementation tokenizes only the WebVTT inline tags allowed by\n * the spec (`<b>`, `<i>`, `<u>`, `<c[.class]>`, `<v authorName>`) and\n * builds the resulting DOM via `document.createElement` /\n * `document.createTextNode`. Anything else (script, iframe, attributes,\n * URL schemes, character refs, ...) is rendered as literal text.\n *\n * Cue input is hard-capped at 10,000 characters before parsing to\n * eliminate ReDoS and runaway-DOM concerns.\n */\n renderVTTToDOM(text: string): DocumentFragment {\n const MAX_CUE_LENGTH = 10_000;\n const safeInput = text.length > MAX_CUE_LENGTH ? text.slice(0, MAX_CUE_LENGTH) : text;\n const fragment = document.createDocumentFragment();\n const stack: HTMLElement[] = [];\n\n const append = (node: Node): void => {\n const target = stack[stack.length - 1] ?? fragment;\n target.appendChild(node);\n };\n\n const tagPattern = /<(\\/)?([a-z])(?:\\.([\\w.-]{1,200}))?(?:\\s+([^<>]{0,500}))?>/i;\n let cursor = 0;\n\n while (cursor < safeInput.length) {\n const remaining = safeInput.slice(cursor);\n const match = tagPattern.exec(remaining);\n if (!match || match.index === undefined) {\n append(document.createTextNode(remaining));\n break;\n }\n\n if (match.index > 0) {\n append(document.createTextNode(remaining.slice(0, match.index)));\n }\n\n const [, closing, tagLetter, classList, voiceName] = match;\n const tag = (tagLetter || '').toLowerCase();\n\n if (closing) {\n const top = stack[stack.length - 1];\n if (top && top.dataset.vttTag === tag) {\n stack.pop();\n }\n } else if (tag === 'b' || tag === 'i' || tag === 'u') {\n const elementTag = tag === 'b' ? 'strong' : tag === 'i' ? 'em' : 'u';\n const node = document.createElement(elementTag);\n node.dataset.vttTag = tag;\n append(node);\n stack.push(node);\n } else if (tag === 'c') {\n const span = document.createElement('span');\n span.dataset.vttTag = tag;\n span.classList.add('caption-class');\n if (classList) {\n for (const cls of classList.split('.').filter(Boolean)) {\n if (/^[\\w-]+$/.test(cls)) {\n span.classList.add(`caption-class-${cls}`);\n }\n }\n }\n append(span);\n stack.push(span);\n } else if (tag === 'v') {\n const span = document.createElement('span');\n span.dataset.vttTag = tag;\n span.classList.add('caption-voice');\n if (voiceName) {\n // Voice name is text; never an attribute. data-voice mirrors the\n // historical hook used by `caption-voice` styles.\n span.dataset.voice = voiceName.trim().slice(0, 200);\n }\n append(span);\n stack.push(span);\n } else {\n // Unknown tag — render literally as escaped text so authors can see\n // the bug without it becoming an injection vector.\n append(document.createTextNode(match[0]));\n }\n\n cursor += match.index + match[0].length;\n }\n\n return fragment;\n },\n\n createTooltip(text: string, classPrefix = 'vidply'): HTMLElement {\n return this.createElement('span', {\n className: `${classPrefix}-tooltip`,\n textContent: text,\n attributes: { 'aria-hidden': 'true' }\n });\n },\n\n attachTooltip(element: HTMLElement | null, text: string, classPrefix = 'vidply'): void {\n if (!element || !text) return;\n\n element.querySelector(`.${classPrefix}-tooltip`)?.remove();\n\n const tooltip = this.createTooltip(text, classPrefix);\n element.appendChild(tooltip);\n\n const visibleClass = `${classPrefix}-tooltip-visible`;\n const show = () => tooltip.classList.add(visibleClass);\n const hide = () => tooltip.classList.remove(visibleClass);\n\n element.addEventListener('mouseenter', show);\n element.addEventListener('mouseleave', hide);\n element.addEventListener('focus', show);\n element.addEventListener('blur', hide);\n },\n\n createButtonText(text: string, classPrefix = 'vidply'): HTMLElement {\n return this.createElement('span', {\n className: `${classPrefix}-button-text`,\n textContent: text,\n attributes: { 'aria-hidden': 'true' }\n });\n },\n\n addClass(element: HTMLElement | null | undefined, className: string): void {\n element?.classList?.add(className);\n },\n\n removeClass(element: HTMLElement | null | undefined, className: string): void {\n element?.classList?.remove(className);\n },\n\n toggleClass(element: HTMLElement | null | undefined, className: string): void {\n element?.classList?.toggle(className);\n },\n\n hasClass(element: HTMLElement | null | undefined, className: string): boolean {\n return element?.classList?.contains(className) ?? false;\n }\n};\n", "/**\n * Prototype-pollution defence helpers.\n *\n * Every time the player mixes attacker-influenced data (JSON from\n * `data-vidply-options`, persisted values from `localStorage`,\n * translation catalogues fetched over HTTP, theme-variable overrides)\n * into an object with a normal prototype, the keys\n * `__proto__`, `prototype`, and `constructor` are stripped on the way in.\n *\n * This module centralises that logic so the three separate copies that\n * used to live in `core/Player.ts`, `utils/StorageManager.ts`,\n * `i18n/i18n.ts`, and `index.ts` cannot drift apart silently.\n */\n\n/** Keys that are forbidden in attacker-influenced input. Frozen so no\n * caller can accidentally mutate the shared set at runtime. */\nexport const PROTO_FORBIDDEN_KEYS: ReadonlySet<string> = Object.freeze(\n new Set(['__proto__', 'prototype', 'constructor'])\n);\n\n/** Return `true` if the key would risk prototype pollution. */\nexport function isForbiddenKey(key: PropertyKey): boolean {\n return PROTO_FORBIDDEN_KEYS.has(String(key));\n}\n\n/**\n * One-level copy of `input` that drops forbidden keys. The result has\n * a null prototype so further property access can't accidentally hit\n * `Object.prototype`. The generic `T` cast matches the ergonomic\n * pattern `shallowSanitize<MyShape>(dirty)` used by callers that know\n * the expected shape.\n */\nexport function shallowSanitize<T extends Record<string, unknown>>(input: T): T {\n const out: Record<string, unknown> = Object.create(null);\n for (const [key, value] of Object.entries(input)) {\n if (isForbiddenKey(key)) continue;\n out[key] = value;\n }\n return out as T;\n}\n\n/**\n * Recursive, plain-object-only sanitiser. Arrays and primitives are\n * passed through unchanged; plain objects are copied onto a null\n * prototype with forbidden keys filtered.\n *\n * This is the shape needed by the i18n layer (nested translation\n * catalogues) and by any code that merges deeply nested options.\n */\nexport function deepSanitize<T = unknown>(input: unknown): T {\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n // For non-objects we still want a null-prototype fallback in the\n // \"expected an object but got garbage\" case — matches the previous\n // i18n behaviour so catalogue loaders stay defensive.\n if (input && typeof input === 'object') {\n return input as T;\n }\n return Object.create(null) as T;\n }\n const out: Record<string, unknown> = Object.create(null);\n for (const [key, value] of Object.entries(input as Record<string, unknown>)) {\n if (isForbiddenKey(key)) continue;\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n out[key] = deepSanitize(value);\n } else {\n out[key] = value;\n }\n }\n return out as T;\n}\n", "/**\n * English translations for VidPly\n */\n\nexport const 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 playlist: 'Toggle playlist',\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 floatingPlayer: 'Floating player',\n floatingPlayerClose: 'Close floating player',\n floatingPlayerEnter: 'Pop out video',\n floatingPlayerExit: 'Dock video',\n floatingPlayerDialog: 'Floating video player. Press D to drag, R to resize, Escape to close.',\n download: 'Download',\n downloadWithFormat: 'Download {format}',\n downloadWithSize: 'Download ({size})',\n downloadWithFormatSize: 'Download {format} ({size})',\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 closeSignLanguage: 'Close sign language video',\n signLanguageSettings: 'Sign language settings',\n startPlaybackFirst: 'Please start playback first.',\n startPlaybackForAudioDescription: 'Please start playback first to use audio description.',\n startPlaybackForSignLanguage: 'Please start playback first to use 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 signLanguageDragResize: 'Sign Language Video - Press D to drag with keyboard, R to resize',\n signLanguageDragActive: 'Sign Language Video - Drag mode active. Use arrow keys to move, Escape to exit.',\n signLanguageResizeActive: 'Sign Language Video - Resize mode active. Use left/right arrow keys to resize, Escape to exit.',\n enableSignDragMode: 'Enable drag mode. Shortcut: D key',\n disableSignDragMode: 'Disable drag mode. Shortcut: D key',\n enableSignDragModeAria: 'Enable toggle keyboard drag mode with arrow keys. Shortcut: D key',\n disableSignDragModeAria: 'Disable toggle keyboard drag mode with arrow keys. Shortcut: D key',\n enableSignResizeMode: 'Enable resize mode. Shortcut: R key',\n disableSignResizeMode: 'Disable resize mode. Shortcut: R key',\n enableSignResizeModeAria: 'Enable keyboard resize mode with arrow keys. Shortcut: R key',\n disableSignResizeModeAria: 'Disable keyboard resize mode with arrow keys. Shortcut: R key',\n signDragModeHint: 'Drag mode: arrow keys to move, Esc to exit',\n signResizeModeHint: 'Resize mode: arrow keys to resize, Esc to exit',\n signDragModeDisabled: 'Sign language drag mode disabled.',\n signResizeModeDisabled: 'Sign language resize mode disabled.',\n resizeHandle: 'Resize {direction} corner',\n moreOptions: 'More options',\n noMoreOptions: 'No additional options available',\n // Screen-reader announcements (used by KeyboardManager.announceAction)\n playing: 'Playing',\n paused: 'Paused',\n muted: 'Muted',\n unmuted: 'Unmuted',\n captionsOn: 'Captions on',\n captionsOff: 'Captions off',\n volumePercent: 'Volume {percent} percent',\n volumePercentMuted: 'Muted',\n speedRate: 'Speed {rate}x'\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 normal: 'Normal',\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 showInMainView: 'Show sign language in main video',\n hideInMainView: 'Hide sign language from main video'\n },\n transcript: {\n title: 'Transcript',\n ariaLabel: 'Video Transcript',\n close: 'Close transcript',\n loading: 'Loading transcript...',\n noTranscript: 'No transcript available for this video.',\n settings: 'Transcript settings. Press Enter to open menu, or D to enable drag mode',\n keyboardDragMode: 'Toggle keyboard drag mode with arrow keys. Shortcut: D key',\n keyboardDragActive: '⌨️ Keyboard Drag Mode Active (Arrow keys to move, Shift+Arrows for large steps, D or ESC to exit)',\n dragResizePrompt: 'Press D to drag or R to resize. Use Home to reset position, Esc to close.',\n dragModeEnabled: 'Keyboard drag mode enabled. Use arrow keys to move, Shift+Arrow for larger steps. Press D or Esc to exit.',\n dragModeDisabled: 'Keyboard drag mode disabled.',\n enableDragMode: 'Enable drag mode. Shortcut: D key',\n disableDragMode: 'Disable drag mode. Shortcut: D key',\n enableDragModeAria: 'Enable toggle keyboard drag mode with arrow keys. Shortcut: D key',\n disableDragModeAria: 'Disable toggle keyboard drag mode with arrow keys. Shortcut: D key',\n resizeWindow: 'Resize Window',\n disableResizeWindow: 'Disable Resize Mode',\n enableResizeMode: 'Enable resize mode. Shortcut: R key',\n disableResizeMode: 'Disable resize mode. Shortcut: R key',\n enableResizeModeAria: 'Enable keyboard resize mode with arrow keys. Shortcut: R key',\n disableResizeModeAria: 'Disable keyboard resize mode with arrow keys. Shortcut: R key',\n resizeModeHint: 'Resize handles enabled. Drag edges or corners to adjust. Press Esc or R to exit.',\n resizeModeEnabled: 'Resize mode enabled. Drag edges or corners to adjust. Press Esc or R to exit.',\n resizeModeDisabled: 'Resize mode disabled.',\n dragModeBadge: 'Drag mode: arrow keys to move, Esc to exit',\n resizeModeBadge: 'Resize mode: drag edges or corners, Esc to exit',\n positionReset: 'Transcript position reset.',\n styleTranscript: 'Open transcript style settings',\n closeMenu: 'Close Menu',\n styleTitle: 'Transcript Style',\n autoscroll: 'Autoscroll',\n settingsMenu: 'Transcript dialog settings',\n showTimestamps: 'Show timestamps',\n hideTimestamps: 'Hide timestamps',\n showTimestampsAria: 'Show timestamps in transcript',\n hideTimestampsAria: 'Hide timestamps in transcript',\n seekTo: 'Seek to {time}'\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 time: {\n display: 'Time display',\n durationPrefix: 'Duration: ',\n of: 'of',\n hour: '{count} hour',\n hours: '{count} hours',\n minute: '{count} minute',\n minutes: '{count} minutes',\n second: '{count} second',\n seconds: '{count} seconds'\n },\n resume: {\n prompt: 'Resume from {time}?',\n resume: 'Resume',\n startOver: 'Start Over'\n },\n playlist: {\n title: 'Playlist',\n trackOf: 'Track {current} of {total}',\n nowPlaying: 'Now playing: Track {current} of {total}. {title}{artist}',\n by: ' by ',\n untitled: 'Untitled',\n trackUntitled: 'Track {number}',\n currentlyPlaying: 'Currently playing',\n notPlaying: 'Not playing',\n pressEnterPlay: 'Press Enter to play',\n pressEnterRestart: 'Press Enter to restart',\n keyboardInstructions: 'Playlist navigation: Use Up and Down arrow keys to move between tracks. Press Page Up or Page Down to skip 5 tracks. Press Home to go to first track, End to go to last track. Press Enter or Space to play the selected track.',\n endOfPlaylist: 'End of playlist. {current} of {total}.',\n beginningOfPlaylist: 'Beginning of playlist. 1 of {total}.',\n jumpedToLastTrack: 'Jumped to last track. {current} of {total}.',\n jumpedToFirstTrack: 'Jumped to first track. 1 of {total}.',\n firstTrack: 'First track. 1 of {total}.',\n lastTrack: 'Last track. {current} of {total}.'\n }\n};\n\n", "import { en } from './languages/en.js';\n\nexport type TranslationData = Record<string, unknown>;\n\nconst builtInLanguageLoaders: Record<string, () => Promise<Record<string, TranslationData>>> = {\n de: () => import('./languages/de.js') as Promise<Record<string, TranslationData>>,\n es: () => import('./languages/es.js') as Promise<Record<string, TranslationData>>,\n fr: () => import('./languages/fr.js') as Promise<Record<string, TranslationData>>,\n ja: () => import('./languages/ja.js') as Promise<Record<string, TranslationData>>\n};\n\nexport function getBaseTranslations(): Record<string, TranslationData> {\n return { en };\n}\n\nexport function getBuiltInLanguageLoaders(): Record<string, () => Promise<Record<string, TranslationData>>> {\n return builtInLanguageLoaders;\n}\n\nexport async function loadBuiltInTranslation(lang: string): Promise<TranslationData | null> {\n const loader = builtInLanguageLoaders[lang];\n if (!loader) return null;\n\n const module = await loader();\n return (module[lang] || (module as Record<string, unknown>).default || null) as TranslationData | null;\n}\n\nexport const translations = getBaseTranslations();\n", "import { getBaseTranslations, getBuiltInLanguageLoaders, loadBuiltInTranslation, type TranslationData } from './translations.js';\nimport { deepSanitize, isForbiddenKey } from '../utils/Sanitize.js';\n\ndeclare global {\n interface Window {\n jsyaml?: { load(input: string): unknown };\n }\n}\n\n/**\n * Escape RegExp meta-characters so a placeholder name like\n * `{name.first}` does not turn into a wildcard or backreference when\n * compiled into a `RegExp`.\n */\nfunction escapeRegExp(input: string): string {\n return input.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Recursively copy a translation object onto a null-prototype map and\n * drop forbidden keys (`__proto__`, `prototype`, `constructor`) so a\n * malicious translation file cannot pollute Object.prototype on its way\n * through `Object.assign`.\n */\nfunction deepSanitizeTranslations(input: unknown): TranslationData {\n return deepSanitize<TranslationData>(input);\n}\n\nclass I18n {\n currentLanguage: string;\n translations: Record<string, TranslationData>;\n private loadingPromises: Map<string, Promise<unknown>>;\n private builtInLanguageLoaders: Record<string, () => Promise<Record<string, TranslationData>>>;\n\n constructor() {\n this.currentLanguage = 'en';\n this.translations = Object.create(null) as Record<string, TranslationData>;\n Object.assign(this.translations, getBaseTranslations());\n this.loadingPromises = new Map();\n this.builtInLanguageLoaders = getBuiltInLanguageLoaders();\n }\n\n setLanguage(lang: string): void {\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(): string {\n return this.currentLanguage;\n }\n\n async ensureLanguage(lang: string): Promise<string | null> {\n const normalizedLang = (lang || '').toLowerCase();\n if (!normalizedLang) return this.currentLanguage;\n\n if (this.translations[normalizedLang]) {\n return normalizedLang;\n }\n\n if (this.loadingPromises.has(normalizedLang)) {\n await this.loadingPromises.get(normalizedLang);\n return this.translations[normalizedLang] ? normalizedLang : null;\n }\n\n if (!this.builtInLanguageLoaders[normalizedLang]) {\n return null;\n }\n\n const loadPromise = (async () => {\n try {\n const loaded = await loadBuiltInTranslation(normalizedLang);\n if (loaded) {\n this.translations[normalizedLang] = deepSanitizeTranslations(loaded);\n }\n } catch (error) {\n console.warn(`Language \"${normalizedLang}\" failed to load:`, error);\n } finally {\n this.loadingPromises.delete(normalizedLang);\n }\n })();\n\n this.loadingPromises.set(normalizedLang, loadPromise);\n await loadPromise;\n\n return this.translations[normalizedLang] ? normalizedLang : null;\n }\n\n t(key: string, replacements: Record<string, string | number> = {}): string {\n const keys = key.split('.');\n let value: unknown = this.translations[this.currentLanguage];\n\n for (const k of keys) {\n if (value && typeof value === 'object' && k in (value as Record<string, unknown>)) {\n value = (value as Record<string, unknown>)[k];\n } else {\n value = this.translations.en;\n for (const fallbackKey of keys) {\n if (value && typeof value === 'object' && fallbackKey in (value as Record<string, unknown>)) {\n value = (value as Record<string, unknown>)[fallbackKey];\n } else {\n return key;\n }\n }\n break;\n }\n }\n\n if (typeof value === 'string') {\n let result = value;\n for (const [placeholder, replacement] of Object.entries(replacements)) {\n if (isForbiddenKey(placeholder)) continue;\n const safe = escapeRegExp(placeholder);\n result = result.replace(new RegExp(`\\\\{${safe}\\\\}`, 'g'), String(replacement));\n }\n return result;\n }\n\n return typeof value === 'string' ? value : key;\n }\n\n addTranslation(lang: string, newTranslations: TranslationData): void {\n if (isForbiddenKey(lang)) {\n console.warn(`[VidPly] Refusing to register language with forbidden name \"${lang}\"`);\n return;\n }\n if (!this.translations[lang]) {\n this.translations[lang] = Object.create(null) as TranslationData;\n }\n const sanitized = deepSanitizeTranslations(newTranslations);\n Object.assign(this.translations[lang], sanitized);\n }\n\n /**\n * Load a translation file from a URL. Bounded by an `AbortSignal.timeout`\n * (default 8s) plus an optional caller-supplied signal — typically the\n * Player's lifecycle controller — so a torn-down player does not keep\n * the request alive.\n */\n async loadLanguageFromUrl(\n langCode: string,\n url: string,\n options: { signal?: AbortSignal; timeoutMs?: number } = {}\n ): Promise<unknown> {\n if (this.loadingPromises.has(url)) {\n return this.loadingPromises.get(url);\n }\n\n const loadPromise = (async () => {\n const signals: AbortSignal[] = [];\n if (options.signal) signals.push(options.signal);\n if (typeof AbortSignal !== 'undefined' && typeof AbortSignal.timeout === 'function') {\n signals.push(AbortSignal.timeout(options.timeoutMs ?? 8000));\n }\n const signal = signals.length === 0\n ? undefined\n : signals.length === 1\n ? signals[0]\n : (AbortSignal as { any?: (sigs: AbortSignal[]) => AbortSignal }).any?.(signals) ?? signals[0];\n\n try {\n const response = await fetch(url, { signal });\n if (!response.ok) {\n throw new Error(`Failed to load language file: ${response.statusText}`);\n }\n\n const contentType = response.headers.get('content-type') || '';\n let loadedTranslations: TranslationData;\n\n const buffer = await response.arrayBuffer();\n const utf8Text = new TextDecoder('utf-8').decode(buffer);\n\n if (contentType.includes('application/json') || url.endsWith('.json')) {\n loadedTranslations = JSON.parse(utf8Text);\n } else if (\n contentType.includes('text/yaml') ||\n contentType.includes('application/x-yaml') ||\n url.endsWith('.yaml') ||\n url.endsWith('.yml')\n ) {\n try {\n loadedTranslations = JSON.parse(utf8Text);\n } catch {\n if (typeof window !== 'undefined' && window.jsyaml) {\n loadedTranslations = window.jsyaml.load(utf8Text) as TranslationData;\n } else {\n console.warn('YAML parsing requires js-yaml library. Please include it or use JSON format.');\n throw new Error('YAML parsing not available. Please use JSON format or include js-yaml library.');\n }\n }\n } else {\n loadedTranslations = JSON.parse(utf8Text);\n }\n\n this.addTranslation(langCode, loadedTranslations);\n return loadedTranslations;\n } catch (error) {\n console.error(`Error loading language file from ${url}:`, error);\n throw error;\n } finally {\n this.loadingPromises.delete(url);\n }\n })();\n\n this.loadingPromises.set(url, loadPromise);\n return loadPromise;\n }\n\n async loadLanguagesFromUrls(\n languageMap: Record<string, string>,\n options: { signal?: AbortSignal; timeoutMs?: number } = {}\n ): Promise<void> {\n const promises = Object.entries(languageMap).map(([langCode, url]) =>\n this.loadLanguageFromUrl(langCode, url, options)\n );\n await Promise.all(promises);\n }\n}\n\nexport const i18n = new I18n();\n"],
|
|
5
|
+
"mappings": ";;;;;;;AAqBA,SAAS,kBAAkB,KAAa,UAAgC,CAAC,GAAgB;AACvF,QAAM,UAAU,SAAS,cAAc,GAAG;AAE1C,MAAI,QAAQ,WAAW;AACrB,YAAQ,YAAY,QAAQ;AAAA,EAC9B;AAEA,MAAI,QAAQ,YAAY;AACtB,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,UAAU,GAAG;AAC7D,UAAI,UAAU,QAAW;AACvB,gBAAQ,aAAa,KAAK,KAAK;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,aAAa;AACvB,YAAQ,cAAc,QAAQ;AAAA,EAChC;AAEA,MAAI,QAAQ,OAAO;AACjB,WAAO,OAAO,QAAQ,OAAO,QAAQ,KAAK;AAAA,EAC5C;AAEA,MAAI,QAAQ,UAAU;AACpB,eAAW,SAAS,QAAQ,UAAU;AACpC,UAAI,MAAO,SAAQ,YAAY,KAAK;AAAA,IACtC;AAAA,EACF;AAEA,SAAO;AACT;AAEO,IAAM,WAAW;AAAA,EACtB,eAAe;AAAA,EAEf,KAAK,SAA+C;AAClD,QAAI,SAAS,OAAO;AAClB,cAAQ,MAAM,UAAU;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,KAAK,SAA+C;AAClD,QAAI,SAAS,OAAO;AAClB,cAAQ,MAAM,UAAU;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,OAAO,SAA6B,WAAW,KAAK,YAA+B;AACjF,QAAI,CAAC,QAAS;AAEd,YAAQ,MAAM,UAAU;AACxB,YAAQ,MAAM,UAAU;AACxB,YAAQ,MAAM,aAAa,WAAW,QAAQ;AAG9C,SAAK,QAAQ;AAEb,YAAQ,MAAM,UAAU;AAExB,QAAI,YAAY;AACd,UAAI,SAAS;AACb,YAAM,UAAU,MAAM;AACpB,YAAI,OAAQ;AACZ,iBAAS;AACT,gBAAQ,oBAAoB,iBAAiB,OAAO;AACpD,mBAAW;AAAA,MACb;AACA,cAAQ,iBAAiB,iBAAiB,SAAS,EAAE,MAAM,KAAK,CAAC;AACjE,iBAAW,SAAS,WAAW,EAAE;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,QAAQ,SAA6B,WAAW,KAAK,YAA+B;AAClF,QAAI,CAAC,QAAS;AAEd,YAAQ,MAAM,aAAa,WAAW,QAAQ;AAC9C,YAAQ,MAAM,UAAU;AAExB,QAAI,SAAS;AACb,UAAM,UAAU,MAAM;AACpB,UAAI,OAAQ;AACZ,eAAS;AACT,cAAQ,oBAAoB,iBAAiB,OAAO;AACpD,cAAQ,MAAM,UAAU;AACxB,UAAI,WAAY,YAAW;AAAA,IAC7B;AAEA,YAAQ,iBAAiB,iBAAiB,SAAS,EAAE,MAAM,KAAK,CAAC;AACjE,eAAW,SAAS,WAAW,EAAE;AAAA,EACnC;AAAA,EAEA,OAAO,SAA2F;AAChG,QAAI,CAAC,QAAS,QAAO,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,EAAE;AAE5D,UAAM,OAAO,QAAQ,sBAAsB;AAC3C,WAAO;AAAA,MACL,KAAK,KAAK,MAAM,OAAO;AAAA,MACvB,MAAM,KAAK,OAAO,OAAO;AAAA,MACzB,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAAA,EAEA,WAAW,KAAqB;AAC9B,UAAM,YAAoC;AAAA,MACxC,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AACA,WAAO,IAAI,QAAQ,YAAY,UAAQ,UAAU,IAAI,KAAK,IAAI;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,eAAe,MAAgC;AAC7C,UAAM,iBAAiB;AACvB,UAAM,YAAY,KAAK,SAAS,iBAAiB,KAAK,MAAM,GAAG,cAAc,IAAI;AACjF,UAAM,WAAW,SAAS,uBAAuB;AACjD,UAAM,QAAuB,CAAC;AAE9B,UAAM,SAAS,CAAC,SAAqB;AACnC,YAAM,SAAS,MAAM,MAAM,SAAS,CAAC,KAAK;AAC1C,aAAO,YAAY,IAAI;AAAA,IACzB;AAEA,UAAM,aAAa;AACnB,QAAI,SAAS;AAEb,WAAO,SAAS,UAAU,QAAQ;AAChC,YAAM,YAAY,UAAU,MAAM,MAAM;AACxC,YAAM,QAAQ,WAAW,KAAK,SAAS;AACvC,UAAI,CAAC,SAAS,MAAM,UAAU,QAAW;AACvC,eAAO,SAAS,eAAe,SAAS,CAAC;AACzC;AAAA,MACF;AAEA,UAAI,MAAM,QAAQ,GAAG;AACnB,eAAO,SAAS,eAAe,UAAU,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC;AAAA,MACjE;AAEA,YAAM,CAAC,EAAE,SAAS,WAAW,WAAW,SAAS,IAAI;AACrD,YAAM,OAAO,aAAa,IAAI,YAAY;AAE1C,UAAI,SAAS;AACX,cAAM,MAAM,MAAM,MAAM,SAAS,CAAC;AAClC,YAAI,OAAO,IAAI,QAAQ,WAAW,KAAK;AACrC,gBAAM,IAAI;AAAA,QACZ;AAAA,MACF,WAAW,QAAQ,OAAO,QAAQ,OAAO,QAAQ,KAAK;AACpD,cAAM,aAAa,QAAQ,MAAM,WAAW,QAAQ,MAAM,OAAO;AACjE,cAAM,OAAO,SAAS,cAAc,UAAU;AAC9C,aAAK,QAAQ,SAAS;AACtB,eAAO,IAAI;AACX,cAAM,KAAK,IAAI;AAAA,MACjB,WAAW,QAAQ,KAAK;AACtB,cAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,aAAK,QAAQ,SAAS;AACtB,aAAK,UAAU,IAAI,eAAe;AAClC,YAAI,WAAW;AACb,qBAAW,OAAO,UAAU,MAAM,GAAG,EAAE,OAAO,OAAO,GAAG;AACtD,gBAAI,WAAW,KAAK,GAAG,GAAG;AACxB,mBAAK,UAAU,IAAI,iBAAiB,GAAG,EAAE;AAAA,YAC3C;AAAA,UACF;AAAA,QACF;AACA,eAAO,IAAI;AACX,cAAM,KAAK,IAAI;AAAA,MACjB,WAAW,QAAQ,KAAK;AACtB,cAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,aAAK,QAAQ,SAAS;AACtB,aAAK,UAAU,IAAI,eAAe;AAClC,YAAI,WAAW;AAGb,eAAK,QAAQ,QAAQ,UAAU,KAAK,EAAE,MAAM,GAAG,GAAG;AAAA,QACpD;AACA,eAAO,IAAI;AACX,cAAM,KAAK,IAAI;AAAA,MACjB,OAAO;AAGL,eAAO,SAAS,eAAe,MAAM,CAAC,CAAC,CAAC;AAAA,MAC1C;AAEA,gBAAU,MAAM,QAAQ,MAAM,CAAC,EAAE;AAAA,IACnC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,MAAc,cAAc,UAAuB;AAC/D,WAAO,KAAK,cAAc,QAAQ;AAAA,MAChC,WAAW,GAAG,WAAW;AAAA,MACzB,aAAa;AAAA,MACb,YAAY,EAAE,eAAe,OAAO;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,SAA6B,MAAc,cAAc,UAAgB;AACrF,QAAI,CAAC,WAAW,CAAC,KAAM;AAEvB,YAAQ,cAAc,IAAI,WAAW,UAAU,GAAG,OAAO;AAEzD,UAAM,UAAU,KAAK,cAAc,MAAM,WAAW;AACpD,YAAQ,YAAY,OAAO;AAE3B,UAAM,eAAe,GAAG,WAAW;AACnC,UAAM,OAAO,MAAM,QAAQ,UAAU,IAAI,YAAY;AACrD,UAAM,OAAO,MAAM,QAAQ,UAAU,OAAO,YAAY;AAExD,YAAQ,iBAAiB,cAAc,IAAI;AAC3C,YAAQ,iBAAiB,cAAc,IAAI;AAC3C,YAAQ,iBAAiB,SAAS,IAAI;AACtC,YAAQ,iBAAiB,QAAQ,IAAI;AAAA,EACvC;AAAA,EAEA,iBAAiB,MAAc,cAAc,UAAuB;AAClE,WAAO,KAAK,cAAc,QAAQ;AAAA,MAChC,WAAW,GAAG,WAAW;AAAA,MACzB,aAAa;AAAA,MACb,YAAY,EAAE,eAAe,OAAO;AAAA,IACtC,CAAC;AAAA,EACH;AAAA,EAEA,SAAS,SAAyC,WAAyB;AACzE,aAAS,WAAW,IAAI,SAAS;AAAA,EACnC;AAAA,EAEA,YAAY,SAAyC,WAAyB;AAC5E,aAAS,WAAW,OAAO,SAAS;AAAA,EACtC;AAAA,EAEA,YAAY,SAAyC,WAAyB;AAC5E,aAAS,WAAW,OAAO,SAAS;AAAA,EACtC;AAAA,EAEA,SAAS,SAAyC,WAA4B;AAC5E,WAAO,SAAS,WAAW,SAAS,SAAS,KAAK;AAAA,EACpD;AACF;;;ACxQO,IAAM,uBAA4C,OAAO;AAAA,EAC9D,oBAAI,IAAI,CAAC,aAAa,aAAa,aAAa,CAAC;AACnD;AAGO,SAAS,eAAe,KAA2B;AACxD,SAAO,qBAAqB,IAAI,OAAO,GAAG,CAAC;AAC7C;AASO,SAAS,gBAAmD,OAAa;AAC9E,QAAM,MAA+B,uBAAO,OAAO,IAAI;AACvD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,eAAe,GAAG,EAAG;AACzB,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAUO,SAAS,aAA0B,OAAmB;AAC3D,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAI/D,QAAI,SAAS,OAAO,UAAU,UAAU;AACtC,aAAO;AAAA,IACT;AACA,WAAO,uBAAO,OAAO,IAAI;AAAA,EAC3B;AACA,QAAM,MAA+B,uBAAO,OAAO,IAAI;AACvD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAgC,GAAG;AAC3E,QAAI,eAAe,GAAG,EAAG;AACzB,QAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,UAAI,GAAG,IAAI,aAAa,KAAK;AAAA,IAC/B,OAAO;AACL,UAAI,GAAG,IAAI;AAAA,IACb;AAAA,EACF;AACA,SAAO;AACT;;;ACjEO,IAAM,KAAK;AAAA,EAChB,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,UAAU;AAAA,IACV,OAAO;AAAA,IACP,KAAK;AAAA,IACL,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IACrB,qBAAqB;AAAA,IACrB,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,IACtB,UAAU;AAAA,IACV,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,IAClB,wBAAwB;AAAA,IACxB,aAAa;AAAA,IACb,UAAU;AAAA,IACV,UAAU;AAAA,IACV,aAAa;AAAA,IACb,cAAc;AAAA,IACd,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,WAAW;AAAA,IACX,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,oBAAoB;AAAA,IACpB,kCAAkC;AAAA,IAClC,8BAA8B;AAAA,IAC9B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,WAAW;AAAA,IACX,wBAAwB;AAAA,IACxB,wBAAwB;AAAA,IACxB,0BAA0B;AAAA,IAC1B,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,wBAAwB;AAAA,IACxB,yBAAyB;AAAA,IACzB,sBAAsB;AAAA,IACtB,uBAAuB;AAAA,IACvB,0BAA0B;AAAA,IAC1B,2BAA2B;AAAA,IAC3B,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,sBAAsB;AAAA,IACtB,wBAAwB;AAAA,IACxB,cAAc;AAAA,IACd,aAAa;AAAA,IACb,eAAe;AAAA;AAAA,IAEf,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,WAAW;AAAA,EACb;AAAA,EACA,UAAU;AAAA,IACR,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,SAAS;AAAA,EACX;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,cAAc;AAAA,IACZ,WAAW;AAAA,IACX,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AAAA,EACA,aAAa;AAAA,IACX,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,EACX;AAAA,EACA,kBAAkB;AAAA,IAChB,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,MAAM;AAAA,IACN,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EAClB;AAAA,EACA,YAAY;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,IACX,OAAO;AAAA,IACP,SAAS;AAAA,IACT,cAAc;AAAA,IACd,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,oBAAoB;AAAA,IACpB,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,cAAc;AAAA,IACd,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,uBAAuB;AAAA,IACvB,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,IACpB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,QAAQ;AAAA,EACV;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO;AAAA,IACP,UAAU;AAAA,IACV,UAAU;AAAA,IACV,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,EACV;AAAA,EACA,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAW;AAAA,EACb;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,sBAAsB;AAAA,IACtB,eAAe;AAAA,IACf,qBAAqB;AAAA,IACrB,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,IACpB,YAAY;AAAA,IACZ,WAAW;AAAA,EACb;AACF;;;ACpNA,IAAM,yBAAyF;AAAA,EAC7F,IAAI,MAAM,OAAO,yBAAmB;AAAA,EACpC,IAAI,MAAM,OAAO,yBAAmB;AAAA,EACpC,IAAI,MAAM,OAAO,yBAAmB;AAAA,EACpC,IAAI,MAAM,OAAO,yBAAmB;AACtC;AAEO,SAAS,sBAAuD;AACrE,SAAO,EAAE,GAAG;AACd;AAEO,SAAS,4BAA4F;AAC1G,SAAO;AACT;AAEA,eAAsB,uBAAuB,MAA+C;AAC1F,QAAM,SAAS,uBAAuB,IAAI;AAC1C,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,SAAS,MAAM,OAAO;AAC5B,SAAQ,OAAO,IAAI,KAAM,OAAmC,WAAW;AACzE;AAEO,IAAM,eAAe,oBAAoB;;;ACbhD,SAAS,aAAa,OAAuB;AAC3C,SAAO,MAAM,QAAQ,uBAAuB,MAAM;AACpD;AAQA,SAAS,yBAAyB,OAAiC;AACjE,SAAO,aAA8B,KAAK;AAC5C;AAEA,IAAM,OAAN,MAAW;AAAA,EACT;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EAER,cAAc;AACZ,SAAK,kBAAkB;AACvB,SAAK,eAAe,uBAAO,OAAO,IAAI;AACtC,WAAO,OAAO,KAAK,cAAc,oBAAoB,CAAC;AACtD,SAAK,kBAAkB,oBAAI,IAAI;AAC/B,SAAK,yBAAyB,0BAA0B;AAAA,EAC1D;AAAA,EAEA,YAAY,MAAoB;AAC9B,QAAI,KAAK,aAAa,IAAI,GAAG;AAC3B,WAAK,kBAAkB;AAAA,IACzB,OAAO;AACL,cAAQ,KAAK,aAAa,IAAI,sCAAsC;AACpE,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,cAAsB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,eAAe,MAAsC;AACzD,UAAM,kBAAkB,QAAQ,IAAI,YAAY;AAChD,QAAI,CAAC,eAAgB,QAAO,KAAK;AAEjC,QAAI,KAAK,aAAa,cAAc,GAAG;AACrC,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,gBAAgB,IAAI,cAAc,GAAG;AAC5C,YAAM,KAAK,gBAAgB,IAAI,cAAc;AAC7C,aAAO,KAAK,aAAa,cAAc,IAAI,iBAAiB;AAAA,IAC9D;AAEA,QAAI,CAAC,KAAK,uBAAuB,cAAc,GAAG;AAChD,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,YAAY;AAC/B,UAAI;AACF,cAAM,SAAS,MAAM,uBAAuB,cAAc;AAC1D,YAAI,QAAQ;AACV,eAAK,aAAa,cAAc,IAAI,yBAAyB,MAAM;AAAA,QACrE;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,KAAK,aAAa,cAAc,qBAAqB,KAAK;AAAA,MACpE,UAAE;AACA,aAAK,gBAAgB,OAAO,cAAc;AAAA,MAC5C;AAAA,IACF,GAAG;AAEH,SAAK,gBAAgB,IAAI,gBAAgB,WAAW;AACpD,UAAM;AAEN,WAAO,KAAK,aAAa,cAAc,IAAI,iBAAiB;AAAA,EAC9D;AAAA,EAEA,EAAE,KAAa,eAAgD,CAAC,GAAW;AACzE,UAAM,OAAO,IAAI,MAAM,GAAG;AAC1B,QAAI,QAAiB,KAAK,aAAa,KAAK,eAAe;AAE3D,eAAW,KAAK,MAAM;AACpB,UAAI,SAAS,OAAO,UAAU,YAAY,KAAM,OAAmC;AACjF,gBAAS,MAAkC,CAAC;AAAA,MAC9C,OAAO;AACL,gBAAQ,KAAK,aAAa;AAC1B,mBAAW,eAAe,MAAM;AAC9B,cAAI,SAAS,OAAO,UAAU,YAAY,eAAgB,OAAmC;AAC3F,oBAAS,MAAkC,WAAW;AAAA,UACxD,OAAO;AACL,mBAAO;AAAA,UACT;AAAA,QACF;AACA;AAAA,MACF;AAAA,IACF;AAEA,QAAI,OAAO,UAAU,UAAU;AAC7B,UAAI,SAAS;AACb,iBAAW,CAAC,aAAa,WAAW,KAAK,OAAO,QAAQ,YAAY,GAAG;AACrE,YAAI,eAAe,WAAW,EAAG;AACjC,cAAM,OAAO,aAAa,WAAW;AACrC,iBAAS,OAAO,QAAQ,IAAI,OAAO,MAAM,IAAI,OAAO,GAAG,GAAG,OAAO,WAAW,CAAC;AAAA,MAC/E;AACA,aAAO;AAAA,IACT;AAEA,WAAO,OAAO,UAAU,WAAW,QAAQ;AAAA,EAC7C;AAAA,EAEA,eAAe,MAAc,iBAAwC;AACnE,QAAI,eAAe,IAAI,GAAG;AACxB,cAAQ,KAAK,+DAA+D,IAAI,GAAG;AACnF;AAAA,IACF;AACA,QAAI,CAAC,KAAK,aAAa,IAAI,GAAG;AAC5B,WAAK,aAAa,IAAI,IAAI,uBAAO,OAAO,IAAI;AAAA,IAC9C;AACA,UAAM,YAAY,yBAAyB,eAAe;AAC1D,WAAO,OAAO,KAAK,aAAa,IAAI,GAAG,SAAS;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,oBACJ,UACA,KACA,UAAwD,CAAC,GACvC;AAClB,QAAI,KAAK,gBAAgB,IAAI,GAAG,GAAG;AACjC,aAAO,KAAK,gBAAgB,IAAI,GAAG;AAAA,IACrC;AAEA,UAAM,eAAe,YAAY;AAC/B,YAAM,UAAyB,CAAC;AAChC,UAAI,QAAQ,OAAQ,SAAQ,KAAK,QAAQ,MAAM;AAC/C,UAAI,OAAO,gBAAgB,eAAe,OAAO,YAAY,YAAY,YAAY;AACnF,gBAAQ,KAAK,YAAY,QAAQ,QAAQ,aAAa,GAAI,CAAC;AAAA,MAC7D;AACA,YAAM,SAAS,QAAQ,WAAW,IAC9B,SACA,QAAQ,WAAW,IACjB,QAAQ,CAAC,IACR,YAA+D,MAAM,OAAO,KAAK,QAAQ,CAAC;AAEjG,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,KAAK,EAAE,OAAO,CAAC;AAC5C,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,IAAI,MAAM,iCAAiC,SAAS,UAAU,EAAE;AAAA,QACxE;AAEA,cAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,YAAI;AAEJ,cAAM,SAAS,MAAM,SAAS,YAAY;AAC1C,cAAM,WAAW,IAAI,YAAY,OAAO,EAAE,OAAO,MAAM;AAEvD,YAAI,YAAY,SAAS,kBAAkB,KAAK,IAAI,SAAS,OAAO,GAAG;AACrE,+BAAqB,KAAK,MAAM,QAAQ;AAAA,QAC1C,WACE,YAAY,SAAS,WAAW,KAChC,YAAY,SAAS,oBAAoB,KACzC,IAAI,SAAS,OAAO,KACpB,IAAI,SAAS,MAAM,GACnB;AACA,cAAI;AACF,iCAAqB,KAAK,MAAM,QAAQ;AAAA,UAC1C,QAAQ;AACN,gBAAI,OAAO,WAAW,eAAe,OAAO,QAAQ;AAClD,mCAAqB,OAAO,OAAO,KAAK,QAAQ;AAAA,YAClD,OAAO;AACL,sBAAQ,KAAK,8EAA8E;AAC3F,oBAAM,IAAI,MAAM,gFAAgF;AAAA,YAClG;AAAA,UACF;AAAA,QACF,OAAO;AACL,+BAAqB,KAAK,MAAM,QAAQ;AAAA,QAC1C;AAEA,aAAK,eAAe,UAAU,kBAAkB;AAChD,eAAO;AAAA,MACT,SAAS,OAAO;AACd,gBAAQ,MAAM,oCAAoC,GAAG,KAAK,KAAK;AAC/D,cAAM;AAAA,MACR,UAAE;AACA,aAAK,gBAAgB,OAAO,GAAG;AAAA,MACjC;AAAA,IACF,GAAG;AAEH,SAAK,gBAAgB,IAAI,KAAK,WAAW;AACzC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,sBACJ,aACA,UAAwD,CAAC,GAC1C;AACf,UAAM,WAAW,OAAO,QAAQ,WAAW,EAAE;AAAA,MAAI,CAAC,CAAC,UAAU,GAAG,MAC9D,KAAK,oBAAoB,UAAU,KAAK,OAAO;AAAA,IACjD;AACA,UAAM,QAAQ,IAAI,QAAQ;AAAA,EAC5B;AACF;AAEO,IAAM,OAAO,IAAI,KAAK;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
@@ -133,4 +133,4 @@ export {
|
|
|
133
133
|
createIconElement,
|
|
134
134
|
createPlayOverlay
|
|
135
135
|
};
|
|
136
|
-
//# sourceMappingURL=vidply.chunk-
|
|
136
|
+
//# sourceMappingURL=vidply.chunk-RQG3MA7W.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/icons/Icons.ts"],
|
|
4
|
+
"sourcesContent": ["const iconPaths: Record<string, string> = {\n play: `<path d=\"M8 5v14l11-7z\"/>`,\n pause: `<path d=\"M6 4h4v16H6V4zm8 0h4v16h-4V4z\"/>`,\n stop: `<rect x=\"6\" y=\"6\" width=\"12\" height=\"12\"/>`,\n rewind: `<path d=\"M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z\"/>`,\n forward: `<path d=\"M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z\"/>`,\n skipPrevious: `<path d=\"M6 6h2v12H6V6zm3 6l8.5 6V6L9 12z\"/>`,\n skipNext: `<path d=\"M16 6h2v12h-2V6zM6 6l8.5 6L6 18V6z\"/>`,\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 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 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 volumeLow: `<path d=\"M7 9v6h4l5 5V4l-5 5H7z\"/>`,\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 fullscreen: `<path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"/>`,\n fullscreenExit: `<path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"/>`,\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 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 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 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 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 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 check: `<path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/>`,\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 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 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 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 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 chapters: `<path d=\"M3 5h2v2H3V5zm0 4h2v2H3V9zm0 4h2v2H3v-2zm0 4h2v2H3v-2zM7 5h14v2H7V5zm0 4h14v2H7V9zm0 4h14v2H7v-2zm0 4h14v2H7v-2z\"/>`,\n audioDescription: `<rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\"/><text x=\"12\" y=\"14.5\" text-anchor=\"middle\" font-size=\"8\" font-weight=\"bold\" font-family=\"Arial, sans-serif\" fill=\"currentColor\">AD</text>`,\n audioDescriptionOn: `<rect x=\"2\" y=\"5\" width=\"20\" height=\"14\" rx=\"2\" fill=\"currentColor\"/><text x=\"12\" y=\"14.5\" text-anchor=\"middle\" font-size=\"8\" font-weight=\"bold\" font-family=\"Arial, sans-serif\" class=\"vidply-icon-ad-fg\">AD</text>`,\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 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 signLanguagePip: `<g transform=\"scale(1.2) translate(1, 1)\"><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><polygon points=\"14,23 23,14 23,23\" fill=\"currentColor\"/>`,\n signLanguagePipOn: `<g transform=\"scale(1.2) translate(1, 1)\"><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><polygon points=\"14,23 23,14 23,23\" fill=\"currentColor\"/>`,\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 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 move: `<path d=\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\"/>`,\n resize: `<path d=\"M21.71 11.29l-9-9c-.39-.39-1.02-.39-1.41 0l-9 9c-.39.39-.39 1.02 0 1.41l9 9c.39.39 1.02.39 1.41 0l9-9c.39-.38.39-1.01 0-1.41zM14 14.5V12h-4v2.5L7 11l3-3.5V10h4V7.5l3 3.5-3 3.5z\"/>`,\n clock: `<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 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z\"/><path d=\"M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z\"/>`,\n download: `<path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"/>`\n};\n\n// The `xmlns` declaration is mandatory for `DOMParser.parseFromString`\n// with `image/svg+xml`: without it, XML parsing leaves the child\n// elements (`<path>`, `<rect>`, `<g>`, `<text>`, `<polygon>`) in the\n// null namespace, so the browser can't render them as SVG shapes.\n// The old `innerHTML`-based path worked by accident because the HTML\n// parser treats `<svg>` as a special token and places its descendants\n// in the SVG namespace automatically.\nconst svgWrapper = (paths: string) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">${paths}</svg>`;\n\nexport const Icons: Record<string, string> = Object.fromEntries(\n Object.entries(iconPaths).map(([key, value]) => [key, svgWrapper(value)])\n);\n\nexport function getIcon(name: string): string {\n return Icons[name] || Icons.play || '';\n}\n\n/**\n * Parse every icon once at module load into an SVG template element and\n * clone it per call. This replaces the previous `wrapper.innerHTML = …`\n * approach: `innerHTML` is disallowed by strict CSP (`require-trusted-types-for`)\n * and is slower because the browser has to re-tokenise the same string on\n * every icon render.\n *\n * The icon SVG strings are trusted constants defined in this module, so\n * parsing via `DOMParser` is safe.\n */\nconst iconTemplates: Record<string, SVGSVGElement> = (() => {\n const parser = new DOMParser();\n const templates: Record<string, SVGSVGElement> = {};\n for (const [key, paths] of Object.entries(iconPaths)) {\n const doc = parser.parseFromString(svgWrapper(paths), 'image/svg+xml');\n const root = doc.documentElement;\n // A parse failure produces a `<parsererror>` element as the\n // document root; reject that and skip the entry rather than\n // storing a broken template that would render as nothing.\n if (\n root &&\n root.nodeName.toLowerCase() === 'svg' &&\n !root.querySelector('parsererror')\n ) {\n templates[key] = root as unknown as SVGSVGElement;\n }\n }\n return templates;\n})();\n\nexport function createIconElement(name: string, className = ''): HTMLElement {\n const wrapper = document.createElement('span');\n wrapper.className = `vidply-icon ${className}`.trim();\n wrapper.setAttribute('aria-hidden', 'true');\n\n const template = iconTemplates[name] || iconTemplates.play;\n if (template) {\n wrapper.appendChild(template.cloneNode(true));\n }\n return wrapper;\n}\n\nexport function createPlayOverlay(): SVGSVGElement {\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 const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n const filterId = `vidply-play-shadow-${Math.random().toString(36).slice(2, 11)}`;\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 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 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"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
6
6
|
import {
|
|
7
7
|
i18n,
|
|
8
8
|
shallowSanitize
|
|
9
|
-
} from "./vidply.chunk-
|
|
9
|
+
} from "./vidply.chunk-NSMAZCMB.js";
|
|
10
10
|
|
|
11
11
|
// src/utils/StorageManager.ts
|
|
12
12
|
function clamp(n, min, max) {
|
|
@@ -255,4 +255,4 @@ export {
|
|
|
255
255
|
StorageManager,
|
|
256
256
|
deriveTrackLabel
|
|
257
257
|
};
|
|
258
|
-
//# sourceMappingURL=vidply.chunk-
|
|
258
|
+
//# sourceMappingURL=vidply.chunk-UHMVDBDB.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/StorageManager.ts", "../../src/utils/TrackLabelUtils.ts"],
|
|
4
|
+
"sourcesContent": ["import { shallowSanitize } from './Sanitize.js';\n\n/**\n * Type guard helpers used by the validated `get()` overload below.\n * Each guard accepts an unknown JSON value and tells TypeScript whether\n * it matches the expected runtime shape.\n */\nexport type Validator<T> = (value: unknown) => value is T;\n\ninterface WatchProgressEntry {\n currentTime: number;\n duration: number;\n percentage: number;\n updatedAt: number;\n}\n\n/**\n * Loose alias for stored preference payloads. Numeric/string-typed fields\n * are validated at the boundary (`isPlainObject`) and clamped where it\n * matters (volume, playbackSpeed). Individual properties remain `unknown`\n * so callers must narrow before use.\n */\nexport type StoredPreferences = Record<string, unknown>;\n\nfunction clamp(n: number, min: number, max: number): number {\n if (!Number.isFinite(n)) return min;\n if (n < min) return min;\n if (n > max) return max;\n return n;\n}\n\nfunction isFiniteNonNegative(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0;\n}\n\nfunction isWatchProgressEntry(value: unknown): value is WatchProgressEntry {\n if (!value || typeof value !== 'object') return false;\n const v = value as Record<string, unknown>;\n return (\n isFiniteNonNegative(v.currentTime) &&\n isFiniteNonNegative(v.duration) &&\n typeof v.percentage === 'number' &&\n Number.isFinite(v.percentage) &&\n typeof v.updatedAt === 'number' &&\n Number.isFinite(v.updatedAt)\n );\n}\n\nexport class StorageManager {\n private namespace: string;\n private storage: Storage | null;\n\n static MAX_WATCH_PROGRESS_ENTRIES = 100;\n\n constructor(namespace = 'vidply') {\n this.namespace = namespace;\n this.storage = this.isStorageAvailable() ? localStorage : null;\n }\n\n /**\n * `localStorage` access can throw in private-browsing modes (Safari) and\n * is undefined in non-DOM environments. Both are tolerated here so the\n * Player still works (without persistence) when storage is unavailable.\n */\n isStorageAvailable(): boolean {\n try {\n if (typeof localStorage === 'undefined') return false;\n const test = '__storage_test__';\n localStorage.setItem(test, test);\n localStorage.removeItem(test);\n return true;\n } catch {\n return false;\n }\n }\n\n getKey(key: string): string {\n return `${this.namespace}_${key}`;\n }\n\n set(key: string, value: unknown): boolean {\n if (!this.storage) return false;\n\n try {\n const namespacedKey = this.getKey(key);\n this.storage.setItem(namespacedKey, JSON.stringify(value));\n return true;\n } catch (e) {\n console.warn('Failed to save to localStorage:', e);\n return false;\n }\n }\n\n /**\n * Generic get. Accepts an optional `validator` so callers can assert the\n * runtime shape of the parsed JSON before trusting it. Falls back to\n * `defaultValue` if the payload fails validation.\n */\n get<T = unknown>(key: string, defaultValue: T | null = null, validator?: Validator<T>): T | null {\n if (!this.storage) return defaultValue;\n\n try {\n const namespacedKey = this.getKey(key);\n const raw = this.storage.getItem(namespacedKey);\n if (raw === null) return defaultValue;\n const parsed: unknown = JSON.parse(raw);\n if (validator && !validator(parsed)) {\n console.warn(`[VidPly] Discarding malformed localStorage payload for \"${key}\"`);\n return defaultValue;\n }\n return parsed as T;\n } catch (e) {\n console.warn('Failed to read from localStorage:', e);\n return defaultValue;\n }\n }\n\n remove(key: string): boolean {\n if (!this.storage) return false;\n\n try {\n const namespacedKey = this.getKey(key);\n this.storage.removeItem(namespacedKey);\n return true;\n } catch (e) {\n console.warn('Failed to remove from localStorage:', e);\n return false;\n }\n }\n\n clear(): boolean {\n if (!this.storage) return false;\n\n try {\n const storage = this.storage;\n const keys = Object.keys(storage);\n keys.forEach(key => {\n if (key.startsWith(this.namespace)) {\n storage.removeItem(key);\n }\n });\n return true;\n } catch (e) {\n console.warn('Failed to clear localStorage:', e);\n return false;\n }\n }\n\n saveTranscriptPreferences(preferences: StoredPreferences): boolean {\n return this.set('transcript_preferences', shallowSanitize(preferences));\n }\n\n getTranscriptPreferences(): StoredPreferences | null {\n return this.get<StoredPreferences>(\n 'transcript_preferences',\n null,\n isPlainObject as Validator<StoredPreferences>\n );\n }\n\n saveCaptionPreferences(preferences: StoredPreferences): boolean {\n return this.set('caption_preferences', shallowSanitize(preferences));\n }\n\n getCaptionPreferences(): StoredPreferences | null {\n return this.get<StoredPreferences>('caption_preferences', null, isPlainObject as Validator<StoredPreferences>);\n }\n\n savePlayerPreferences(preferences: StoredPreferences): boolean {\n // Numeric ranges are clamped here so a tampered storage payload cannot\n // ship a `volume: 1e9` straight to a renderer.\n const sanitized = shallowSanitize(preferences);\n if (typeof sanitized.volume === 'number') {\n sanitized.volume = clamp(sanitized.volume, 0, 1);\n }\n if (typeof sanitized.playbackSpeed === 'number') {\n sanitized.playbackSpeed = clamp(sanitized.playbackSpeed, 0.1, 4);\n }\n return this.set('player_preferences', sanitized);\n }\n\n getPlayerPreferences(): StoredPreferences | null {\n const value = this.get<StoredPreferences>('player_preferences', null, isPlainObject as Validator<StoredPreferences>);\n if (!value) return null;\n if (typeof value.volume === 'number') {\n value.volume = clamp(value.volume, 0, 1);\n }\n if (typeof value.playbackSpeed === 'number') {\n value.playbackSpeed = clamp(value.playbackSpeed, 0.1, 4);\n }\n return value;\n }\n\n saveSignLanguagePreferences(preferences: StoredPreferences): boolean {\n return this.set('sign_language_preferences', shallowSanitize(preferences));\n }\n\n getSignLanguagePreferences(): StoredPreferences | null {\n return this.get<StoredPreferences>('sign_language_preferences', null, isPlainObject as Validator<StoredPreferences>);\n }\n\n saveFloatingPreferences(preferences: StoredPreferences): boolean {\n return this.set('floating_preferences', shallowSanitize(preferences));\n }\n\n getFloatingPreferences(): StoredPreferences | null {\n return this.get<StoredPreferences>('floating_preferences', null, isPlainObject as Validator<StoredPreferences>);\n }\n\n /**\n * Persist watch progress for a video id. Numeric inputs are validated +\n * clamped so a caller cannot poison the store with `Infinity`/negatives.\n */\n saveWatchProgress(videoId: string, currentTime: number, duration: number): boolean {\n if (typeof videoId !== 'string' || !videoId) return false;\n if (!Number.isFinite(currentTime) || !Number.isFinite(duration) || duration <= 0) return false;\n\n const safeDuration = clamp(duration, 0.001, 24 * 60 * 60); // cap to 24h to neutralize gigantic numbers\n const safeCurrent = clamp(currentTime, 0, safeDuration);\n\n const allProgress = this.get<Record<string, WatchProgressEntry>>(\n 'watch_progress',\n Object.create(null),\n isWatchProgressMap\n ) ?? Object.create(null) as Record<string, WatchProgressEntry>;\n\n const percentage = (safeCurrent / safeDuration) * 100;\n\n allProgress[videoId] = {\n currentTime: safeCurrent,\n duration: safeDuration,\n percentage: clamp(percentage, 0, 100),\n updatedAt: Date.now()\n };\n\n const entries = Object.entries(allProgress);\n if (entries.length > StorageManager.MAX_WATCH_PROGRESS_ENTRIES) {\n entries.sort((a, b) => a[1].updatedAt - b[1].updatedAt);\n const toRemove = entries.length - StorageManager.MAX_WATCH_PROGRESS_ENTRIES;\n for (let i = 0; i < toRemove; i++) {\n const entry = entries[i];\n if (entry) {\n delete allProgress[entry[0]];\n }\n }\n }\n\n return this.set('watch_progress', allProgress);\n }\n\n getWatchProgress(videoId: string): WatchProgressEntry | null {\n if (!videoId) return null;\n const allProgress = this.get<Record<string, WatchProgressEntry>>(\n 'watch_progress',\n Object.create(null),\n isWatchProgressMap\n ) ?? Object.create(null) as Record<string, WatchProgressEntry>;\n const entry = allProgress[videoId];\n return entry && isWatchProgressEntry(entry) ? entry : null;\n }\n\n clearWatchProgress(videoId: string): boolean {\n if (!videoId) return false;\n const allProgress = this.get<Record<string, WatchProgressEntry>>(\n 'watch_progress',\n Object.create(null),\n isWatchProgressMap\n ) ?? Object.create(null) as Record<string, WatchProgressEntry>;\n if (allProgress[videoId]) {\n delete allProgress[videoId];\n return this.set('watch_progress', allProgress);\n }\n return true;\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isWatchProgressMap(value: unknown): value is Record<string, WatchProgressEntry> {\n if (!isPlainObject(value)) return false;\n for (const entry of Object.values(value)) {\n if (!isWatchProgressEntry(entry)) return false;\n }\n return true;\n}\n", "import { i18n } from '../i18n/i18n.js';\n\n/**\n * Derive a human-readable label for a TextTrack when the source manifest\n * (DASH AdaptationSet, HLS rendition, etc.) didn't provide one. dash.js\n * falls back to the AdaptationSet @id (typically a digit like \"2\", \"3\")\n * when no <Label> child element is present, which surfaces as cryptic\n * \"2\"/\"3\" entries in the captions menu.\n *\n * dash.js 5.x additionally derives the label as `element.id ?? element.lang`.\n * When neither is present in the MPD, the value is JS `null`, and the\n * browser's TextTrack API stringifies it to the literal \"null\". We treat\n * \"null\"/\"undefined\" (any casing) as placeholders too, and fall back to a\n * localized language name via Intl.DisplayNames.\n */\nexport function deriveTrackLabel(\n rawLabel: string | null | undefined,\n language: string | null | undefined,\n fallbackKey = 'player.captions'\n): string {\n const cleanLabel = (rawLabel ?? '').trim();\n const cleanLang = (language ?? '').trim();\n\n const looksLikePlaceholder =\n cleanLabel === '' ||\n /^\\d+$/.test(cleanLabel) ||\n /^(null|undefined)$/i.test(cleanLabel);\n if (!looksLikePlaceholder) {\n return cleanLabel;\n }\n\n const cleanLangIsUsable =\n cleanLang !== '' && !/^(null|undefined)$/i.test(cleanLang);\n\n if (cleanLangIsUsable) {\n try {\n // Use endonyms: each language shown in its own name\n // (\"English\", \"Deutsch\") rather than translated into the UI\n // language (\"Englisch\", \"Deutsch\").\n const displayNames = new Intl.DisplayNames([cleanLang, 'en'], { type: 'language' });\n const name = displayNames.of(cleanLang);\n if (name && name.toLowerCase() !== cleanLang.toLowerCase()) {\n return name;\n }\n } catch {\n // Intl.DisplayNames may be unavailable — fall through to the code.\n }\n return cleanLang.toUpperCase();\n }\n\n return i18n.t(fallbackKey);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;AAwBA,SAAS,MAAM,GAAW,KAAa,KAAqB;AAC1D,MAAI,CAAC,OAAO,SAAS,CAAC,EAAG,QAAO;AAChC,MAAI,IAAI,IAAK,QAAO;AACpB,MAAI,IAAI,IAAK,QAAO;AACpB,SAAO;AACT;AAEA,SAAS,oBAAoB,OAAiC;AAC5D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,SAAS;AACzE;AAEA,SAAS,qBAAqB,OAA6C;AACzE,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,IAAI;AACV,SACE,oBAAoB,EAAE,WAAW,KACjC,oBAAoB,EAAE,QAAQ,KAC9B,OAAO,EAAE,eAAe,YACxB,OAAO,SAAS,EAAE,UAAU,KAC5B,OAAO,EAAE,cAAc,YACvB,OAAO,SAAS,EAAE,SAAS;AAE/B;AAEO,IAAM,iBAAN,MAAM,gBAAe;AAAA,EAClB;AAAA,EACA;AAAA,EAER,OAAO,6BAA6B;AAAA,EAEpC,YAAY,YAAY,UAAU;AAChC,SAAK,YAAY;AACjB,SAAK,UAAU,KAAK,mBAAmB,IAAI,eAAe;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,qBAA8B;AAC5B,QAAI;AACF,UAAI,OAAO,iBAAiB,YAAa,QAAO;AAChD,YAAM,OAAO;AACb,mBAAa,QAAQ,MAAM,IAAI;AAC/B,mBAAa,WAAW,IAAI;AAC5B,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAO,KAAqB;AAC1B,WAAO,GAAG,KAAK,SAAS,IAAI,GAAG;AAAA,EACjC;AAAA,EAEA,IAAI,KAAa,OAAyB;AACxC,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,gBAAgB,KAAK,OAAO,GAAG;AACrC,WAAK,QAAQ,QAAQ,eAAe,KAAK,UAAU,KAAK,CAAC;AACzD,aAAO;AAAA,IACT,SAAS,GAAG;AACV,cAAQ,KAAK,mCAAmC,CAAC;AACjD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAiB,KAAa,eAAyB,MAAM,WAAoC;AAC/F,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,gBAAgB,KAAK,OAAO,GAAG;AACrC,YAAM,MAAM,KAAK,QAAQ,QAAQ,aAAa;AAC9C,UAAI,QAAQ,KAAM,QAAO;AACzB,YAAM,SAAkB,KAAK,MAAM,GAAG;AACtC,UAAI,aAAa,CAAC,UAAU,MAAM,GAAG;AACnC,gBAAQ,KAAK,2DAA2D,GAAG,GAAG;AAC9E,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,SAAS,GAAG;AACV,cAAQ,KAAK,qCAAqC,CAAC;AACnD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,OAAO,KAAsB;AAC3B,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,gBAAgB,KAAK,OAAO,GAAG;AACrC,WAAK,QAAQ,WAAW,aAAa;AACrC,aAAO;AAAA,IACT,SAAS,GAAG;AACV,cAAQ,KAAK,uCAAuC,CAAC;AACrD,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,QAAiB;AACf,QAAI,CAAC,KAAK,QAAS,QAAO;AAE1B,QAAI;AACF,YAAM,UAAU,KAAK;AACrB,YAAM,OAAO,OAAO,KAAK,OAAO;AAChC,WAAK,QAAQ,SAAO;AAClB,YAAI,IAAI,WAAW,KAAK,SAAS,GAAG;AAClC,kBAAQ,WAAW,GAAG;AAAA,QACxB;AAAA,MACF,CAAC;AACD,aAAO;AAAA,IACT,SAAS,GAAG;AACV,cAAQ,KAAK,iCAAiC,CAAC;AAC/C,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,0BAA0B,aAAyC;AACjE,WAAO,KAAK,IAAI,0BAA0B,gBAAgB,WAAW,CAAC;AAAA,EACxE;AAAA,EAEA,2BAAqD;AACnD,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,uBAAuB,aAAyC;AAC9D,WAAO,KAAK,IAAI,uBAAuB,gBAAgB,WAAW,CAAC;AAAA,EACrE;AAAA,EAEA,wBAAkD;AAChD,WAAO,KAAK,IAAuB,uBAAuB,MAAM,aAA6C;AAAA,EAC/G;AAAA,EAEA,sBAAsB,aAAyC;AAG7D,UAAM,YAAY,gBAAgB,WAAW;AAC7C,QAAI,OAAO,UAAU,WAAW,UAAU;AACxC,gBAAU,SAAS,MAAM,UAAU,QAAQ,GAAG,CAAC;AAAA,IACjD;AACA,QAAI,OAAO,UAAU,kBAAkB,UAAU;AAC/C,gBAAU,gBAAgB,MAAM,UAAU,eAAe,KAAK,CAAC;AAAA,IACjE;AACA,WAAO,KAAK,IAAI,sBAAsB,SAAS;AAAA,EACjD;AAAA,EAEA,uBAAiD;AAC/C,UAAM,QAAQ,KAAK,IAAuB,sBAAsB,MAAM,aAA6C;AACnH,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,OAAO,MAAM,WAAW,UAAU;AACpC,YAAM,SAAS,MAAM,MAAM,QAAQ,GAAG,CAAC;AAAA,IACzC;AACA,QAAI,OAAO,MAAM,kBAAkB,UAAU;AAC3C,YAAM,gBAAgB,MAAM,MAAM,eAAe,KAAK,CAAC;AAAA,IACzD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,4BAA4B,aAAyC;AACnE,WAAO,KAAK,IAAI,6BAA6B,gBAAgB,WAAW,CAAC;AAAA,EAC3E;AAAA,EAEA,6BAAuD;AACrD,WAAO,KAAK,IAAuB,6BAA6B,MAAM,aAA6C;AAAA,EACrH;AAAA,EAEA,wBAAwB,aAAyC;AAC/D,WAAO,KAAK,IAAI,wBAAwB,gBAAgB,WAAW,CAAC;AAAA,EACtE;AAAA,EAEA,yBAAmD;AACjD,WAAO,KAAK,IAAuB,wBAAwB,MAAM,aAA6C;AAAA,EAChH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,SAAiB,aAAqB,UAA2B;AACjF,QAAI,OAAO,YAAY,YAAY,CAAC,QAAS,QAAO;AACpD,QAAI,CAAC,OAAO,SAAS,WAAW,KAAK,CAAC,OAAO,SAAS,QAAQ,KAAK,YAAY,EAAG,QAAO;AAEzF,UAAM,eAAe,MAAM,UAAU,MAAO,KAAK,KAAK,EAAE;AACxD,UAAM,cAAc,MAAM,aAAa,GAAG,YAAY;AAEtD,UAAM,cAAc,KAAK;AAAA,MACvB;AAAA,MACA,uBAAO,OAAO,IAAI;AAAA,MAClB;AAAA,IACF,KAAK,uBAAO,OAAO,IAAI;AAEvB,UAAM,aAAc,cAAc,eAAgB;AAElD,gBAAY,OAAO,IAAI;AAAA,MACrB,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY,MAAM,YAAY,GAAG,GAAG;AAAA,MACpC,WAAW,KAAK,IAAI;AAAA,IACtB;AAEA,UAAM,UAAU,OAAO,QAAQ,WAAW;AAC1C,QAAI,QAAQ,SAAS,gBAAe,4BAA4B;AAC9D,cAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS;AACtD,YAAM,WAAW,QAAQ,SAAS,gBAAe;AACjD,eAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,cAAM,QAAQ,QAAQ,CAAC;AACvB,YAAI,OAAO;AACT,iBAAO,YAAY,MAAM,CAAC,CAAC;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK,IAAI,kBAAkB,WAAW;AAAA,EAC/C;AAAA,EAEA,iBAAiB,SAA4C;AAC3D,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,cAAc,KAAK;AAAA,MACvB;AAAA,MACA,uBAAO,OAAO,IAAI;AAAA,MAClB;AAAA,IACF,KAAK,uBAAO,OAAO,IAAI;AACvB,UAAM,QAAQ,YAAY,OAAO;AACjC,WAAO,SAAS,qBAAqB,KAAK,IAAI,QAAQ;AAAA,EACxD;AAAA,EAEA,mBAAmB,SAA0B;AAC3C,QAAI,CAAC,QAAS,QAAO;AACrB,UAAM,cAAc,KAAK;AAAA,MACvB;AAAA,MACA,uBAAO,OAAO,IAAI;AAAA,MAClB;AAAA,IACF,KAAK,uBAAO,OAAO,IAAI;AACvB,QAAI,YAAY,OAAO,GAAG;AACxB,aAAO,YAAY,OAAO;AAC1B,aAAO,KAAK,IAAI,kBAAkB,WAAW;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cAAc,OAAkD;AACvE,SAAO,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,mBAAmB,OAA6D;AACvF,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO;AAClC,aAAW,SAAS,OAAO,OAAO,KAAK,GAAG;AACxC,QAAI,CAAC,qBAAqB,KAAK,EAAG,QAAO;AAAA,EAC3C;AACA,SAAO;AACT;;;AC/QO,SAAS,iBACZ,UACA,UACA,cAAc,mBACR;AACN,QAAM,cAAc,YAAY,IAAI,KAAK;AACzC,QAAM,aAAa,YAAY,IAAI,KAAK;AAExC,QAAM,uBACF,eAAe,MACf,QAAQ,KAAK,UAAU,KACvB,sBAAsB,KAAK,UAAU;AACzC,MAAI,CAAC,sBAAsB;AACvB,WAAO;AAAA,EACX;AAEA,QAAM,oBACF,cAAc,MAAM,CAAC,sBAAsB,KAAK,SAAS;AAE7D,MAAI,mBAAmB;AACnB,QAAI;AAIA,YAAM,eAAe,IAAI,KAAK,aAAa,CAAC,WAAW,IAAI,GAAG,EAAE,MAAM,WAAW,CAAC;AAClF,YAAM,OAAO,aAAa,GAAG,SAAS;AACtC,UAAI,QAAQ,KAAK,YAAY,MAAM,UAAU,YAAY,GAAG;AACxD,eAAO;AAAA,MACX;AAAA,IACJ,QAAQ;AAAA,IAER;AACA,WAAO,UAAU,YAAY;AAAA,EACjC;AAEA,SAAO,KAAK,EAAE,WAAW;AAC7B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* VidPly v1.2.
|
|
2
|
+
* VidPly v1.2.1 - Universal, Accessible Video Player
|
|
3
3
|
* (c) 2026 Matthias Peltzer
|
|
4
4
|
* Released under GPL-2.0-or-later License
|
|
5
5
|
*/
|
|
6
6
|
import {
|
|
7
7
|
createIconElement
|
|
8
|
-
} from "./vidply.chunk-
|
|
8
|
+
} from "./vidply.chunk-RQG3MA7W.js";
|
|
9
9
|
import {
|
|
10
10
|
focusElement
|
|
11
|
-
} from "./vidply.chunk-
|
|
11
|
+
} from "./vidply.chunk-JAKZNGOR.js";
|
|
12
12
|
import {
|
|
13
13
|
reducedMotionScrollOptions
|
|
14
|
-
} from "./vidply.chunk-
|
|
14
|
+
} from "./vidply.chunk-5IK3IC5V.js";
|
|
15
15
|
import {
|
|
16
16
|
DOMUtils,
|
|
17
17
|
i18n
|
|
18
|
-
} from "./vidply.chunk-
|
|
18
|
+
} from "./vidply.chunk-NSMAZCMB.js";
|
|
19
19
|
|
|
20
20
|
// src/utils/FormUtils.ts
|
|
21
21
|
function createLabeledSelect({
|
|
@@ -639,4 +639,4 @@ export {
|
|
|
639
639
|
createMenuItem,
|
|
640
640
|
DraggablePanel
|
|
641
641
|
};
|
|
642
|
-
//# sourceMappingURL=vidply.chunk-
|
|
642
|
+
//# sourceMappingURL=vidply.chunk-W5BR65JY.js.map
|