@asicupv/paella-video-plugins
Version:
More video formats for Paella Player
1 lines • 1.86 MB
Source Map (JSON)
{"version":3,"file":"paella-video-plugins.umd.cjs","sources":["../../paella-core/dist/paella-core.js","../src/plugins/VideoPluginsModule.js","../src/plugins/es.upv.paella.hlsVideoFormat.js","../src/plugins/es.upv.paella.hlsLiveVideoFormat.js","../src/icons/captions_cc.js","../src/plugins/es.upv.paella.hlsCaptionsSelectorPlugin.js","../src/plugins/es.upv.paella.mp4MultiQualityPlugin.js","../src/index.js","../../../node_modules/hls.js/dist/hls.mjs"],"sourcesContent":["var yt = (i) => {\n throw TypeError(i);\n};\nvar Be = (i, e, t) => e.has(i) || yt(\"Cannot \" + t);\nvar d = (i, e, t) => (Be(i, e, \"read from private field\"), t ? t.call(i) : e.get(i)), I = (i, e, t) => e.has(i) ? yt(\"Cannot add the same private member more than once\") : e instanceof WeakSet ? e.add(i) : e.set(i, t), k = (i, e, t, n) => (Be(i, e, \"write to private field\"), n ? n.call(i, t) : e.set(i, t), t), ze = (i, e, t) => (Be(i, e, \"access private method\"), t);\nconst m = Object.freeze({\n PLAY: \"paella:play\",\n PAUSE: \"paella:pause\",\n STOP: \"paella:stop\",\n ENDED: \"paella:ended\",\n SEEK: \"paella:seek\",\n FULLSCREEN_CHANGED: \"paella:fullscreenchanged\",\n ENTER_FULLSCREEN: \"paella:enterfullscreen\",\n EXIT_FULLSCREEN: \"paella:exitfullscreen\",\n VOLUME_CHANGED: \"paella:volumeChanged\",\n TIMEUPDATE: \"paella:timeupdate\",\n TRIMMING_CHANGED: \"paella:trimmingChanged\",\n CAPTIONS_CHANGED: \"paella:captionsChanged\",\n CAPTIONS_ENABLED: \"paella:captionsEnabled\",\n CAPTIONS_DISABLED: \"paella:captionsDisabled\",\n BUTTON_PRESS: \"paella:buttonPress\",\n SHOW_POPUP: \"paella:showPopUp\",\n HIDE_POPUP: \"paella:hidePopUp\",\n MANIFEST_LOADED: \"paella:manifestLoaded\",\n STREAM_LOADED: \"paella:streamLoaded\",\n PLAYER_LOADED: \"paella:playerLoaded\",\n PLAYER_UNLOADED: \"paella:playerUnloaded\",\n RESIZE: \"paella:resize\",\n RESIZE_END: \"paella:resizeEnd\",\n LAYOUT_CHANGED: \"paella:layoutChanged\",\n PLAYBACK_RATE_CHANGED: \"paella:playbackRateChanged\",\n VIDEO_QUALITY_CHANGED: \"paella:videoQualityChanged\",\n HIDE_UI: \"paella:hideUI\",\n SHOW_UI: \"paella:showUI\",\n COOKIE_CONSENT_CHANGED: \"paella:cookieConsentChanged\",\n LOG: \"paella:log\"\n});\nfunction M(i, e, t, n = !0) {\n return i.__eventListeners__ = i.__eventListeners__ || {}, Array.isArray(e) || (e = [e]), e.forEach((s) => {\n i.__eventListeners__[s] = i.__eventListeners__[s] || [], i.__eventListeners__[s].push({\n callback: t,\n unregisterOnUnload: n\n });\n }), t;\n}\nfunction E(i, e, t = {}) {\n i.__eventListeners__ && i.__eventListeners__[e] && i.__eventListeners__[e].forEach((n) => n.callback(t));\n}\nfunction se(i, e, t = {}) {\n i.ready && E(i, e, t);\n}\nfunction Ti(i) {\n if (i.__eventListeners__)\n for (const e in i.__eventListeners__)\n i.__eventListeners__[e] = i.__eventListeners__[e].filter((t) => t.unregisterOnUnload == !1), i.log.debug(\"Unregister event: \" + i.__eventListeners__[e]);\n}\nfunction Dt(i) {\n return new Promise((e, t) => {\n fetch(i).then((n) => n.text()).then((n) => {\n e(n);\n }).catch((n) => t(n));\n });\n}\nfunction xt(i) {\n const e = new URLSearchParams(window.location.search);\n return e.has(i) ? e.get(i) : null;\n}\nfunction At(i) {\n const e = window.location.hash.replace(\"#\", \"?\"), t = new URLSearchParams(e);\n return t.has(i) ? t.get(i) : null;\n}\nfunction z(i, e) {\n const t = e || \"/\";\n return i = i.map((n, s) => (s && (n = n.replace(new RegExp(\"^\" + t), \"\")), s !== i.length - 1 && (n = n.replace(new RegExp(t + \"$\"), \"\")), n)), i.join(t);\n}\nfunction Mt(i) {\n return new RegExp(\"^([a-z]+://|//)\", \"i\").test(i) || /^\\//.test(i);\n}\nfunction Me(i) {\n try {\n return new URL(i).pathname.split(\"/\").pop();\n } catch {\n return i.split(\"/\").pop();\n }\n}\nfunction Rt(i) {\n return i.split(\".\").reduce((e, t, n, s) => n < s.length - 1 ? e !== \"\" ? `${e}.${t}` : t : e, \"\");\n}\nfunction it(i) {\n const e = (t) => {\n const n = t.split(\"/\").reduce((s, a, r, o) => r < o.length - 1 ? s !== \"\" ? `${s}/${a}` : a : s, \"\");\n return (t[0] === \"/\" ? `/${n}` : n) + \"/\";\n };\n try {\n const t = new URL(i);\n return t.origin + e(t.pathname);\n } catch {\n return e(i);\n }\n}\nfunction nt(i) {\n return Me(i).split(\".\").pop();\n}\nfunction Y(i, e) {\n return Mt(e) ? e : z([i.manifestUrl, e]);\n}\nfunction Vt(i) {\n i.__hideTimerPaused__ = !0;\n}\nfunction st(i) {\n i.__hideTimerPaused__ = !1;\n}\nfunction Nt(i, e = \"hideUiTime\") {\n var a;\n i.__hideTimer__ = null;\n const t = async () => i.__hideTimerPaused__ ? (i.log.debug(\"UI not hidden because the auto hide timer is paused\"), !1) : n() ? (i.log.debug(\"UI not hidden because there is a focused element\"), !1) : (await i.hideUserInterface(), !0);\n (a = i.config.ui) != null && a.hideOnMouseLeave && i.containerElement.addEventListener(\"mouseleave\", () => {\n t();\n });\n const n = () => {\n const r = document.activeElement, o = document.querySelector(\":focus-visible\");\n return (i.playbackBar.element.contains(r) || i.videoContainer.element.contains(r)) && [\n \"input\",\n \"textarea\",\n \"button\"\n ].find((l) => r.tagName.toLowerCase(l)) !== -1 && o;\n }, s = async () => {\n i.__hideTimer__ && clearTimeout(i.__hideTimer__), await i.showUserInterface(), i.__hideTimer__ = setTimeout(async () => {\n i.__hideTimer__ = null, t() || s();\n }, i[e]);\n };\n i.containerElement.addEventListener(\"mousemove\", async (r) => {\n s();\n }), M(i, m.PLAY, async () => {\n s();\n }), M(i, m.PAUSE, async () => {\n await i.showUserInterface();\n }), M(i, m.ENDED, async () => {\n await i.showUserInterface();\n }), document.addEventListener(\"keydown\", async () => {\n s();\n });\n}\nfunction Ut(i) {\n i.__hideTimer__ && (clearTimeout(i.__hideTimer__), delete i.__hideTimer__);\n}\nfunction ie(i) {\n const e = Math.floor(i / 60 / 60), t = Math.floor(i / 60) - e * 60, n = Math.floor(i % 60);\n return (e > 0 ? e.toString().padStart(2, \"0\") + \":\" : \"\") + t.toString().padStart(2, \"0\") + \":\" + n.toString().padStart(2, \"0\");\n}\nfunction Ae(i) {\n const t = /^(?:(\\d+):){0,1}(\\d+):(\\d+)(\\.\\d+)?$/.exec(i);\n if (t) {\n const n = t[1] !== void 0 ? Number(t[1]) : 0, s = Number(t[2]), a = Number(t[3]);\n return n * 3600 + s * 60 + a;\n }\n return null;\n}\nfunction Ye(i) {\n const t = /^(?:(\\d+):){0,1}(\\d+):(\\d+)\\.(\\d+)?$/.exec(i);\n if (t) {\n const n = t[1] !== void 0 ? Number(t[1]) : 0, s = Number(t[2]), a = Number(t[3]), r = t[4] && Number(t[4]) || 0;\n return n * 36e5 + s * 6e4 + a * 1e3 + r;\n }\n return null;\n}\nfunction ne(i, e, t = 365) {\n let n = /* @__PURE__ */ new Date();\n n.setTime(n.getTime() + t * 24 * 60 * 60 * 1e3);\n let s = `expires=${n.toUTCString()}`;\n document.cookie = `${i}=${e};${s};path=/;SameSite=None;` + (/Apple/.test(navigator.vendor) ? \"\" : \"Secure;\");\n}\nfunction Ft(i, e, t, n, s = 365) {\n i.cookieConsent.getConsentForType(e) && ne(t, n, s);\n}\nfunction Z(i) {\n let e = i + \"=\", n = decodeURIComponent(document.cookie).split(\";\");\n for (let s = 0; s < n.length; ++s) {\n let a = n[s];\n for (; a.charAt(0) == \" \"; )\n a = a.substring(1);\n if (a.indexOf(e) == 0)\n return a.substring(e.length, a.length);\n }\n return \"\";\n}\nfunction Si(i) {\n const e = Z(i), t = Number(e);\n return e !== \"\" && !isNaN(t) ? t : null;\n}\nfunction Ii(i) {\n try {\n return JSON.parse(Z(i));\n } catch {\n return null;\n }\n}\nfunction at(i, e = !0) {\n return new Promise((t) => {\n const n = document.createElement(\"link\");\n n.setAttribute(\"rel\", \"stylesheet\"), n.setAttribute(\"href\", i), n.onload = () => t(n);\n const s = document.getElementsByTagName(\"head\")[0];\n e && s.appendChild(n), t();\n });\n}\nfunction Ot(i) {\n document.getElementsByTagName(\"head\")[0].removeChild(i);\n}\nfunction we(i, e, t = !0) {\n for (const n in e) {\n const s = i[n];\n let a = e[n];\n t && Array.isArray(s) && Array.isArray(a) ? (s.forEach((r) => {\n a = a.filter((o) => typeof r == \"object\" && typeof o == \"object\" && r.id === o.id ? (we(r, o, t), !1) : !0);\n }), a.forEach((r) => {\n s.push(r);\n })) : typeof s == \"object\" && a ? we(s, a, t) : i[n] = e[n];\n }\n}\nfunction Ke(i, { excludedTags: e = null } = {}) {\n const t = document.createElement(\"div\");\n t.innerHTML = i;\n const n = [\"script\"];\n return e && n.push(...e), n.flatMap((s) => Array.from(t.getElementsByTagName(s))).forEach((s) => {\n s.parentElement.removeChild(s);\n }), t.innerHTML;\n}\nlet xe = null;\nfunction rt(i) {\n if (!i) return !1;\n xe || (xe = document.createElement(\"video\"));\n let e = xe.canPlayType(i);\n if (e === \"maybe\" || e === \"probably\")\n return !0;\n if (/video\\/mp4/i.test(i))\n return e = xe.canPlayType(\"video/mp4\"), e === \"maybe\" || e === \"probably\";\n}\nconst ua = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({\n __proto__: null,\n clearAutoHideTimer: Ut,\n getCookie: Z,\n getFileExtension: nt,\n getHashParameter: At,\n getJSONCookie: Ii,\n getNumericCookie: Si,\n getUrlFileName: Me,\n getUrlParameter: xt,\n isAbsoluteUrl: Mt,\n joinPath: z,\n loadStyle: at,\n loadSvgIcon: Dt,\n mergeObjects: we,\n pauseAutoHideUiTimer: Vt,\n removeExtension: Rt,\n removeFileName: it,\n resolveResourcePath: Y,\n resumeAutoHideUiTimer: st,\n sanitizeHTML: Ke,\n secondsToTime: ie,\n setCookie: ne,\n setCookieIfAllowed: Ft,\n setupAutoHideUiTimer: Nt,\n supportsVideoType: rt,\n timeToMilliseconds: Ye,\n timeToSeconds: Ae,\n unloadStyle: Ot\n}, Symbol.toStringTag, { value: \"Module\" }));\nasync function ki(i, e) {\n return e.log.debug(\"Using default configuration loading function.\"), (await fetch(i)).json();\n}\nasync function Di(i, e) {\n return e.log.debug(\"Using default getVideoId function\"), At(\"id\") || xt(\"id\") || i.fallbackId;\n}\nasync function xi(i, e, t, n) {\n return n.log.debug(\"Using default getManifestUrl function\"), z([i, e]);\n}\nasync function Ai(i, e, t, n) {\n return n.log.debug(\"Using default getManifestFileUrl function\"), z([i, e]);\n}\nasync function Mi(i, e, t) {\n t.log.debug(\"Using default loadVideoManifest function\");\n const n = await fetch(i);\n if (n.ok)\n try {\n return await n.json();\n } catch {\n throw new Error(t.translate(\"Error parsing video manifest. Unexpected file format.\"));\n }\n else\n throw new Error(t.translate(\"Error loading video manifest: $1 $2\", [n.status, n.statusText]));\n}\nvar be;\nclass de {\n constructor(e) {\n I(this, be, null);\n k(this, be, e);\n }\n get player() {\n return d(this, be);\n }\n}\nbe = new WeakMap();\nfunction $t({ tag: i = \"div\", attributes: e = {}, children: t = \"\", innerText: n = \"\", parent: s = null }) {\n const a = document.createElement(i);\n a.innerText = n;\n for (let r in e)\n a.setAttribute(r, e[r]);\n return a.innerHTML = t, s && s.appendChild(a), a;\n}\nfunction b(i, e = null) {\n const t = document.createElement(\"div\");\n t.innerHTML = i;\n const n = t.children[0];\n return e && e.appendChild(n), n;\n}\nvar V;\nclass G extends de {\n constructor(t, { tag: n = \"div\", attributes: s = [], children: a = \"\", parent: r = null }) {\n super(t);\n I(this, V, null);\n k(this, V, $t({ tag: n, attributes: s, children: a, parent: r })), Object.defineProperty(this, n, {\n get: () => d(this, V)\n });\n }\n get element() {\n return d(this, V);\n }\n get parent() {\n return d(this, V).parentElement;\n }\n hide() {\n this.element.style.display = \"none\";\n }\n show(t = \"block\") {\n this.element.style.display = null;\n }\n get isVisible() {\n const t = window.getComputedStyle(this.element);\n return t.display !== \"none\" && t.display !== \"\";\n }\n setAttribute(t, n) {\n d(this, V).setAttribute(t, n);\n }\n removeFromParent() {\n var t;\n (t = d(this, V).parentElement) == null || t.removeChild(d(this, V));\n }\n setParent(t) {\n this.removeFromParent(), t.appendChild(d(this, V));\n }\n}\nV = new WeakMap();\nconst Ri = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 256 256\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" xmlns:serif=\"http://www.serif.com/\" style=\"fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;\">\n <g transform=\"matrix(1,0,0,1,3,-3.88857)\">\n <path d=\"M128,35.819C65.633,35.819 14.999,86.453 14.999,148.82C14.999,163.127 17.663,176.817 22.549,189.403L22.475,189.447C11.612,170.791 5.889,149.588 5.889,128C5.889,60.56 60.56,5.889 128,5.889L128,35.819Z\" style=\"fill:url(#_Linear1);\"/>\n </g>\n <g transform=\"matrix(-1,1.22465e-16,-1.22465e-16,-1,258,251.914)\">\n <path d=\"M128,35.819C65.633,35.819 14.999,86.453 14.999,148.82C14.999,163.127 17.663,176.817 22.549,189.403L22.475,189.447C11.612,170.791 5.889,149.588 5.889,128C5.889,60.56 60.56,5.889 128,5.889L128,35.819Z\" style=\"fill:url(#_Linear2);\"/>\n </g>\n <defs>\n <linearGradient id=\"_Linear1\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\" gradientUnits=\"userSpaceOnUse\" gradientTransform=\"matrix(-89.3028,140.734,-140.734,-89.3028,144.417,48.7125)\"><stop offset=\"0\" style=\"stop-color:rgb(13,13,13);stop-opacity:1\"/><stop offset=\"1\" style=\"stop-color:rgb(175,175,175);stop-opacity:0.5\"/></linearGradient>\n <linearGradient id=\"_Linear2\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\" gradientUnits=\"userSpaceOnUse\" gradientTransform=\"matrix(-89.3028,140.734,-140.734,-89.3028,144.417,48.7125)\"><stop offset=\"0\" style=\"stop-color:rgb(13,13,13);stop-opacity:1\"/><stop offset=\"1\" style=\"stop-color:rgb(175,175,175);stop-opacity:0.5\"/></linearGradient>\n </defs>\n</svg>\n`;\nclass Vi extends G {\n constructor(e) {\n super(e, { parent: e.containerElement }), this.element.className = \"loader-container\";\n }\n async create() {\n b(`<i>${Ri}</i>`, this.element);\n }\n get debug() {\n return !1;\n }\n}\nconst Ni = `<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 256 256\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" xmlns:serif=\"http://www.serif.com/\" style=\"fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;\">\n <g id=\"Cancel\" transform=\"matrix(5.54545,6.8353e-32,6.8353e-32,5.54545,-2567.37,-10735.5)\">\n <path d=\"M486.05,1937C498.192,1937 508.05,1946.86 508.05,1959C508.05,1971.14 498.192,1981 486.05,1981C473.908,1981 464.05,1971.14 464.05,1959C464.05,1946.86 473.908,1937 486.05,1937ZM478.979,1950.52L477.565,1951.93L484.636,1959L477.565,1966.07L478.979,1967.49L486.05,1960.41L493.121,1967.49L494.535,1966.07L487.464,1959L494.535,1951.93L493.121,1950.52L486.05,1957.59L478.979,1950.52Z\" style=\"fill:rgb(210,0,0);\"/>\n </g>\n</svg>\n`;\nclass Ge extends G {\n constructor(e, t = \"\") {\n super(e, { parent: e.containerElement }), this.element.className = \"error-container\", b(`\n <div>\n <i>${Ni}</i>\n <p>${t}</p>\n </div>`, this.element);\n }\n}\nclass he extends de {\n constructor(e, t) {\n super(e), this._name = t;\n }\n getPluginModuleInstance() {\n return null;\n }\n get config() {\n return this._config;\n }\n get type() {\n return \"none\";\n }\n get order() {\n var e;\n return ((e = this._config) == null ? void 0 : e.order) || 0;\n }\n get description() {\n var e;\n return ((e = this._config) == null ? void 0 : e.description) || \"\";\n }\n get name() {\n return this._name;\n }\n async isEnabled() {\n var e;\n return (e = this.config) == null ? void 0 : e.enabled;\n }\n async load() {\n }\n async unload() {\n }\n}\nclass Ue extends he {\n get type() {\n return \"video\";\n }\n get streamType() {\n return \"mp4\";\n }\n async isCompatible() {\n return !1;\n }\n async getVideoInstance() {\n return null;\n }\n getCompatibleFileExtensions() {\n return [];\n }\n getManifestData(e) {\n }\n}\nconst Re = [];\nasync function Ui(i) {\n await $(i, \"video\", (e) => {\n Re.push(e);\n });\n}\nasync function Fi(i) {\n Re.slice(0);\n}\nfunction Bt(i) {\n if (Re.length === 0)\n throw Error(\"No video plugins loaded. Note that `loadVideoPlugins()` must to be called before using `getVideoPlugins()`.\");\n return Re;\n}\nfunction Oi(i, e) {\n const t = nt(e);\n return Bt().find((s) => s.getCompatibleFileExtensions().indexOf(t) !== -1);\n}\nasync function $i(i, e) {\n const t = Bt();\n let n = null;\n for (const s of t)\n if (await s.isCompatible(e)) {\n n = s;\n break;\n }\n return n;\n}\nasync function Bi() {\n return await new Promise((e) => {\n const t = document.createElement(\"audio\"), n = setTimeout(() => e(!1), 100);\n t.addEventListener(\"volumechange\", (s) => {\n clearTimeout(n), e(!0);\n }), t.volume = 0.5;\n });\n}\nclass ot extends G {\n constructor(e, t, n) {\n const s = {\n class: \"video-player\"\n };\n super(t, { tag: e, attributes: s, parent: n }), this._streamProvider = null, this._streamData = null, this._ready = !1;\n }\n async isVolumeApiAvailable() {\n return await Bi();\n }\n get streamData() {\n return this._streamData;\n }\n get ready() {\n return this._ready;\n }\n async load(e, t) {\n return this._streamProvider = t, this._streamData = e, await this.loadStreamData(e);\n }\n get isMainAudioPlayer() {\n return this._streamProvider.mainAudioPlayer === this;\n }\n // The player must call _videoEndedCallback when the video is ended\n onVideoEnded(e) {\n this._videoEndedCallback = e;\n }\n // The video instance must implement the following functions and properties\n async play() {\n return !1;\n }\n async pause() {\n return !1;\n }\n async duration() {\n return -1;\n }\n get currentTimeSync() {\n return -1;\n }\n async currentTime() {\n return -1;\n }\n async setCurrentTime() {\n return !1;\n }\n async volume() {\n return -1;\n }\n async setVolume() {\n return !1;\n }\n initVolume(e) {\n this._initialVolume = e;\n }\n async paused() {\n return !0;\n }\n async playbackRate() {\n return -1;\n }\n async setPlaybackRate() {\n return !1;\n }\n async getQualities() {\n return null;\n }\n async setQuality() {\n return !1;\n }\n get currentQuality() {\n return null;\n }\n async getDimensions() {\n return null;\n }\n async supportsMultiaudio() {\n return !1;\n }\n async getAudioTracks() {\n return null;\n }\n async setCurrentAudioTrack() {\n }\n get currentAudioTrack() {\n return null;\n }\n async loadStreamData(e) {\n return !1;\n }\n get isEnabled() {\n return this._enabled;\n }\n async enable() {\n this._enabled = !0;\n }\n async disable() {\n this._enabled = !1;\n }\n}\nclass Fe extends de {\n get moduleName() {\n return this.player.log.warn(`Incomplete player module definition: '${__filename}.moduleName'`), \"-\";\n }\n get moduleVersion() {\n return this.player.log.warn(`Incomplete player module definition: '${__filename}.moduleVersion'`), \"0.0.0\";\n }\n async getDictionaries() {\n return null;\n }\n}\nconst zi = \"@asicupv/paella-core\", Gi = { \".\": \"./dist/paella-core.js\", \"./src/\": \"./src/\", \"./paella-core.css\": \"./dist/paella-core.css\" }, Hi = \"2.2.8\", ji = \"Multi stream HTML video player\", qi = \"./dist/paella-core.js\", Wi = [\"dist/paella-core.css\", \"dist/paella-core.js\", \"dist/paella-core.umd.cjs\", \"dist/paella-core.js.map\", \"dist/paella-core.umd.cjs.map\", \"dist/paella-core.d.ts\"], Qi = \"./dist/paella-core.js\", Zi = \"module\", Yi = { dev: \"vite build --watch\", build: \"vite build --emptyOutDir\" }, Ki = { type: \"git\", url: \"git+https://github.com/polimediaupv/paella-player.git\" }, Ji = [\"html\", \"player\", \"video\", \"hls\"], Xi = \"Fernando Serrano Carpena <ferserc1@gmail.com>\", en = \"ECL-2.0\", tn = { url: \"https://github.com/polimediaupv/paella-player/issues\" }, nn = \"https://github.com/polimediaupv/paella-player#readme\", sn = { typescript: \"^5.8.3\", vite: \"^6.0.11\" }, an = { \"@ferserc1/input-style-unifier\": \"^0.0.2\", \"vite-plugin-static-copy\": \"^3.0.0\" }, Ie = {\n name: zi,\n exports: Gi,\n version: Hi,\n description: ji,\n main: qi,\n files: Wi,\n module: Qi,\n type: Zi,\n scripts: Yi,\n repository: Ki,\n keywords: Ji,\n author: Xi,\n license: en,\n bugs: tn,\n homepage: nn,\n devDependencies: sn,\n dependencies: an\n};\nlet He = null;\nclass pe extends Fe {\n static Get() {\n return He || (He = new pe()), He;\n }\n get moduleName() {\n return \"paella-core default video formats\";\n }\n get moduleVersion() {\n return Ie.version;\n }\n}\nfunction rn(i) {\n return new Promise((e, t) => {\n const n = new Image();\n n.addEventListener(\"load\", (s) => {\n e(n);\n }), n.addEventListener(\"error\", (s) => {\n t(new Error(\"Could not load preview image. The preview image is required in audio only streams\"));\n }), n.src = i;\n });\n}\nfunction on(i, e, t) {\n return new Promise((n, s) => {\n e.oncanplay = () => n(), e.onerror = () => s(new Error(i.translate(\"Error loading audio: $1\", [t]))), e.src = Y(i, t), n();\n });\n}\nclass ln extends ot {\n constructor(e, t, n) {\n super(\"audio\", e, t), this.isMainAudio = n, this._ready = !1;\n }\n get streamType() {\n return \"audio\";\n }\n waitForLoaded() {\n return new Promise((e) => {\n const t = () => {\n this._ready ? e() : setTimeout(t, 100);\n };\n t();\n });\n }\n async play() {\n await this.waitForLoaded(), this.audio.play();\n }\n async pause() {\n await this.waitForLoaded(), this.audio.pause();\n }\n async duration() {\n return await this.waitForLoaded(), this.audio.duration;\n }\n get currentTimeSync() {\n var e;\n return ((e = this.audio) == null ? void 0 : e.currentTime) || 0;\n }\n async currentTime() {\n return await this.waitForLoaded(), this.audio.currentTime;\n }\n async setCurrentTime(e) {\n await this.waitForLoaded(), this.audio.currentTime = e;\n }\n async volume() {\n return await this.waitForLoaded(), this.audio.volume;\n }\n async setVolume(e) {\n await this.waitForLoaded(), this.audio.volume = e;\n }\n async paused() {\n return await this.waitForLoaded(), this.audio.paused;\n }\n async playbackRate() {\n return await this.waitForLoaded(), this.audio.playbackRate;\n }\n async setPlaybackRate(e) {\n await this.waitForLoaded(), this.audio.playbackRate = e;\n }\n // getQualities(), setQuality(q), get currentQuality(): audio format does not support multiquality\n async getDimensions() {\n return {\n w: this._previewImage.width,\n h: this._previewImage.height\n };\n }\n async loadStreamData(e = null) {\n this._streamData = this._streamData || e, this.player.log.debug(\"es.upv.paella.audioVideoFormat: loadStreamData\");\n const t = this.player.videoManifest.metadata.preview;\n if (!t || t == null)\n throw new Error(\"Invalid video manifest data: preview image is required\");\n if (this._previewImage = await rn(t), this._imageContainer = document.createElement(\"div\"), this._imageContainer.className = \"image-container\", this.parent.appendChild(this._imageContainer), this._imageContainer.appendChild(this._previewImage), this._source = e.sources.audio && e.sources.audio[0], !this._source)\n throw new Error(\"Invalid source in audio only video stream\");\n if (!this.isMainAudioPlayer)\n throw new Error(\"Audio only video stream must be main audio player. Check the role property at video manifest\");\n await on(this.player, this.audio, this._source.src);\n const n = () => {\n const s = this.player.videoContainer.baseVideoRect.offsetWidth / this.player.videoContainer.baseVideoRect.offsetHeight, a = this._previewImage.width / this._previewImage.height;\n s > a ? (this._previewImage.classList.add(\"landscape\"), this._previewImage.classList.remove(\"portrait\")) : (this._previewImage.classList.add(\"portrait\"), this._previewImage.classList.remove(\"landscape\"));\n };\n this.player.frameList.frames.length > 0 && this.audio.addEventListener(\"timeupdate\", (s) => {\n const a = this.player.frameList.getImage(s.target.currentTime, !0);\n this._previewImage.src != a.url && (this._previewImage.src = a.url, this._previewImage.onload = () => n());\n }), window.addEventListener(\"resize\", (s) => n()), n(), this._ready = !0;\n }\n}\nclass cn extends Ue {\n getPluginModuleInstance() {\n return pe.Get();\n }\n get name() {\n return super.name || \"es.upv.paella.audioVideoFormat\";\n }\n get streamType() {\n return \"audio\";\n }\n async isCompatible(e) {\n return e.sources.audio != null;\n }\n async getVideoInstance(e, t) {\n return new ln(this.player, e, t);\n }\n getCompatibleFileExtensions() {\n return [\"m4a\", \"mp3\"];\n }\n getManifestData(e) {\n return {\n audio: e.map((t) => ({\n src: t\n }))\n };\n }\n}\nclass zt extends ot {\n constructor(e, t, n, s) {\n super(\"video\", e, t), this._config = s || {};\n const a = this._config.crossOrigin ?? \"\";\n this.element.setAttribute(\"playsinline\", \"\"), a !== !1 && this.element.setAttribute(\"crossorigin\", a), this.isMainAudio = n, this.element.setAttribute(\"autoplay\", \"\"), this.element.autoplay = !0, n || (this.element.muted = !0), this._videoEnabled = !0;\n }\n async play() {\n if (this._videoEnabled)\n try {\n return await this.waitForLoaded(), this.video.play();\n } catch {\n }\n else\n this._disabledProperties.paused = !1;\n }\n async pause() {\n if (this._videoEnabled)\n return await this.waitForLoaded(), this.video.pause();\n this._disabledProperties.paused = !0;\n }\n async duration() {\n return this._videoEnabled ? (await this.waitForLoaded(), this.video.duration) : this._disabledProperties.duration;\n }\n get currentTimeSync() {\n return this._videoEnabled ? this.ready ? this.video.currentTime : -1 : this._disabledProperties.currentTime;\n }\n async currentTime() {\n return this._videoEnabled ? (await this.waitForLoaded(), this.currentTimeSync) : this._disabledProperties.currentTime;\n }\n async setCurrentTime(e) {\n return this._videoEnabled ? (await this.waitForLoaded(), this.video.currentTime = e) : (this._disabledProperties.currentTime = e, e);\n }\n async volume() {\n return this._videoEnabled ? (await this.waitForLoaded(), this.video.volume) : this._disabledProperties.volume;\n }\n async setVolume(e) {\n return this._videoEnabled ? (await this.waitForLoaded(), e === 0 ? this.video.setAttribute(\"muted\", \"\") : this.video.removeAttribute(\"muted\"), this.video.volume = e) : (this._disabledProperties.volume = e, e);\n }\n async paused() {\n return this._videoEnabled ? (await this.waitForLoaded(), this.video.paused) : this._disabledProperties.paused;\n }\n async playbackRate() {\n return this._videoEnabled ? (await this.waitForLoaded(), await this.video.playbackRate) : this._disabledProperties.playbackRate;\n }\n async setPlaybackRate(e) {\n return this._videoEnabled ? (await this.waitForLoaded(), this.video.playbackRate = e) : (this._disabledProperties.playbackRate = e, e);\n }\n async getQualities() {\n }\n async setQuality() {\n }\n get currentQuality() {\n return 0;\n }\n async getDimensions() {\n return this._videoEnabled ? (await this.waitForLoaded(), { w: this.video.videoWidth, h: this.video.videoHeight }) : { w: this._disabledProperties.videoWidth, h: this._disabledProperties.videoHeight };\n }\n saveDisabledProperties(e) {\n this._disabledProperties = {\n duration: e.duration,\n volume: e.volume,\n videoWidth: e.videoWidth,\n videoHeight: e.videoHeight,\n playbackRate: e.playbackRate,\n paused: e.paused,\n currentTime: e.currentTime\n };\n }\n async loadStreamData(e = null) {\n this._streamData = this._streamData || e, this.player.log.debug(\"es.upv.paella.htmlVideoFormat: loadStreamData\"), this._sources = e.sources.html, this._currentQuality = 0, this.isMainAudioPlayer || (this.video.muted = !0), this._sources.forEach(({ src: t, mimetype: n }) => {\n t = Y(this.player, t);\n const s = document.createElement(\"source\");\n s.src = t, s.type = n, this.video.appendChild(s);\n }), this._endedCallback = this._endedCallback || (() => {\n typeof this._videoEndedCallback == \"function\" && this._videoEndedCallback();\n }), this.video.addEventListener(\"ended\", this._endedCallback);\n try {\n await this.video.play();\n } catch {\n }\n await this.waitForLoaded(), this.player.log.debug(`es.upv.paella.htmlVideoFormat (${this.streamData.content}): video loaded and ready.`), this.saveDisabledProperties(this.video);\n }\n async clearStreamData() {\n this.video.src = \"\", this.video.removeEventListener(\"ended\", this._endedCallback), this.video.removeEventListener(\"loadeddata\", this._handleLoadedCallback), this._ready = !1;\n }\n get isEnabled() {\n return this._videoEnabled;\n }\n async enable() {\n this._videoEnabled = !0;\n }\n async disable() {\n return this.isMainAudio ? this.player.log.debug(\"video.disable() - the video is not disabled because it is the main audio source.\") : this._videoEnabled = !1, this._videoEnabled;\n }\n waitForLoaded() {\n return new Promise((e, t) => {\n this.video.readyState >= 2 && (this._ready = !0), this.ready ? e() : (this._handleLoadedCallback = (n) => {\n this.video.readyState >= 2 && (this.video.pause(), this._ready = !0, e());\n }, this.video.addEventListener(\"loadeddata\", this._handleLoadedCallback));\n });\n }\n}\nclass un extends Ue {\n getPluginModuleInstance() {\n return pe.Get();\n }\n get name() {\n return super.name || \"es.upv.paella.htmlVideoFormat\";\n }\n get streamType() {\n return \"html\";\n }\n async isCompatible(e) {\n const { html: t } = e.sources;\n return t && t.some((n) => rt(n.mimetype));\n }\n async getVideoInstance(e, t) {\n return new zt(this.player, e, t, this.config);\n }\n getCompatibleFileExtensions() {\n return [\"m4v\", \"mp4\", \"ogg\", \"webm\", \"ogv\"];\n }\n getManifestData(e) {\n const t = (n) => {\n switch (nt(n)) {\n case \"mp4\":\n case \"m4v\":\n return \"video/mp4\";\n case \"webm\":\n return \"video/webm\";\n case \"ogg\":\n case \"ogv\":\n return \"video/ogg\";\n default:\n return null;\n }\n };\n return {\n html: e.map((n) => ({\n src: n,\n mimetype: t(n)\n }))\n };\n }\n}\nclass dn {\n constructor({ label: e, shortLabel: t, isAuto: n = !1, index: s = 0, src: a = \"\", width: r = -1, height: o = -1, bitrate: l = -1 }) {\n this._label = e, this._shortLabel = t, this._index = s, this._src = a, this._res = {\n w: r,\n h: o\n }, this._bitrate = l, this._isAuto = n;\n }\n get label() {\n return this._label;\n }\n get shortLabel() {\n return this._shortLabel;\n }\n get index() {\n return this._index;\n }\n get src() {\n return this._src;\n }\n get res() {\n return this._res;\n }\n get bitrate() {\n return this._bitrate;\n }\n get isAuto() {\n return this._isAuto;\n }\n get quality() {\n return this._res.w !== -1 && this._res.h !== -1 ? this._res.w * this._res.h : this._bitrate;\n }\n compare(e) {\n return e.quality - this.quality;\n }\n}\nfunction Gt(i) {\n let e = this._currentSource.frames[0];\n this._currentSource.frames.some((t) => {\n if (t.time <= this._currentTime)\n e = t;\n else\n return !0;\n }), this.img.src = e.src;\n}\nfunction hn() {\n this._startTimestamp = Date.now();\n const i = () => {\n this._timer = setTimeout(i, 250);\n const e = Date.now(), t = e - this._startTimestamp;\n this._currentTime += t / 1e3, this._startTimestamp = e, Gt.apply(this, [this._currentTime]);\n };\n i();\n}\nfunction pn() {\n this._timer && (clearTimeout(this._timer), this._timer = null);\n}\nclass gn extends ot {\n constructor(e, t) {\n super(\"img\", e, t), this._currentTime = 0, this._startTimesamp = 0, this._playbackRate = 1, this._timer = null, this.video = this.domElement;\n }\n async play() {\n hn.apply(this);\n }\n async pause() {\n pn.apply(this);\n }\n async duration() {\n return this._currentSource.duration;\n }\n get currentTimeSync() {\n return this._currentTime;\n }\n async currentTime() {\n return this._currentTime;\n }\n async setCurrentTime(e) {\n this._currentTime = e, Gt.apply(this, [e]);\n }\n async volume() {\n return 0;\n }\n async setVolume(e) {\n }\n async paused() {\n return this._timer === null;\n }\n async playbackRate() {\n return this._playbackRate;\n }\n async setPlaybackRate(e) {\n this._playbackRate = e;\n }\n async getQualities() {\n return this._qualities;\n }\n async setQuality() {\n }\n get currentQuality() {\n return this._currentQuality;\n }\n async getDimensions() {\n return this._currentSource.res;\n }\n async loadStreamData(e) {\n return this._sources = e.sources.image, this._qualities = this._sources.map((t) => new dn({\n src: t.frames[0].src,\n label: `${t.res.w}x${t.res.h}`,\n shortLabel: `${t.res.h}p`,\n width: t.res.w,\n height: t.res.h\n })), this._currentQuality = this._qualities.length - 1, this._qualities.forEach((t, n) => {\n this._qualities[this._currentQuality].compare(t) > 0 && (this._currentQuality = n);\n }), this._currentSource = this._sources[this._currentQuality], this._sources.forEach((t) => {\n t.frames.sort((n, s) => n.time - s.time);\n }), !0;\n }\n}\nclass mn extends Ue {\n getPluginModuleInstance() {\n return pe.Get();\n }\n get name() {\n return super.name || \"es.upv.paella.imageVideoFormat\";\n }\n get streamType() {\n return \"image\";\n }\n async isCompatible(e) {\n return e.sources.image != null;\n }\n async getVideoInstance(e, t) {\n return new gn(this.player, e, this.config, t);\n }\n}\nclass fn extends zt {\n constructor(e, t, n, s) {\n super(e, t, n, s);\n }\n // This function is called when the player loads, and it should\n // make everything ready for video playback to begin.\n async loadStreamData(e = null) {\n this._streamData = this._streamData || e, this.player.log.debug(\"es.upv.paella.mp4VideoFormat: loadStreamData\"), this._currentSource || (this._sources = null, this._currentQuality = 0, this._sources = e.sources.mp4, this._sources.sort((t, n) => Number(t.res.w) - Number(n.res.w)), this._currentQuality = this._sources.length - 1, this._currentSource = this._sources[this._currentQuality]), this.isMainAudioPlayer || (this.video.muted = !0), this._initialVolume && (this.video.volume = this._initialVolume, this._initialVolume === 0 && (this.video.muted = !0)), this.video.src = Y(this.player, this._currentSource.src), this._endedCallback = this._endedCallback || (() => {\n typeof this._videoEndedCallback == \"function\" && this._videoEndedCallback();\n }), this.video.addEventListener(\"ended\", this._endedCallback);\n try {\n await this.video.play();\n } catch {\n }\n await this.waitForLoaded(), this.player.log.debug(`es.upv.paella.mp4VideoFormat (${this.streamData.content}): video loaded and ready.`), this.saveDisabledProperties(this.video);\n }\n}\nclass yn extends Ue {\n getPluginModuleInstance() {\n return pe.Get();\n }\n get name() {\n return super.name || \"es.upv.paella.mp4VideoFormat\";\n }\n get streamType() {\n return \"mp4\";\n }\n isCompatible(e) {\n var n;\n const { mp4: t } = e.sources;\n return t && rt((n = t[0]) == null ? void 0 : n.mimetype);\n }\n async getVideoInstance(e, t) {\n return new fn(this.player, e, t, this.config);\n }\n getCompatibleFileExtensions() {\n return [\"m4v\", \"mp4\"];\n }\n getManifestData(e) {\n return {\n mp4: e.map((t) => ({\n src: t,\n mimetype: \"video/mp4\"\n }))\n };\n }\n}\nasync function vn(i) {\n const e = [];\n await $(i, \"captions\", async (t) => {\n e.push(t);\n });\n for (let t in e) {\n const s = await e[t].getCaptions(), a = i.captionsCanvas;\n s.forEach((r) => a.addCaptions(r));\n }\n}\nclass Ht extends he {\n get type() {\n return \"captions\";\n }\n async load() {\n this.player.log.debug(\"load captions plugin\");\n }\n async getCaptions() {\n return this.player.log.warn(`CaptionsPlugin ${this.name}: getCaptions() is not implemented.`), [];\n }\n}\nclass jt {\n get cues() {\n return this._cues;\n }\n get label() {\n return this._label;\n }\n get language() {\n return this._lang;\n }\n set label(e) {\n this._label = e;\n }\n set language(e) {\n this._lang = e;\n }\n constructor(e = \"\", t = \"\") {\n this._cues = [], this._label = e, this._lang = t;\n }\n addCue({ label: e = \"\", start: t, end: n, captions: s }) {\n const a = {\n label: e\n };\n if (typeof s == \"string\")\n a.captions = [s];\n else if (Array.isArray(s))\n a.captions = s;\n else\n throw Error(\"Invalid cue caption format: must be an array of strings or a string\");\n if (typeof t == \"string\")\n a.start = Ae(t), a.startString = t;\n else if (typeof t == \"number\")\n a.start = t, a.startString = ie(t);\n else\n throw Error(\"Invalid cue timestamp format: must be a valid time string or a number of seconds\");\n if (typeof n == \"string\")\n a.end = Ae(n), a.endString = n;\n else if (typeof n == \"number\")\n a.end = n, a.endString = ie(n);\n else\n throw Error(\"Invalid cue timestamp format: must be a valid time string or a number of seconds\");\n return this._cues.push(a), a;\n }\n getCue(e) {\n if (typeof e == \"string\")\n e = Ae(e);\n else if (typeof e != \"number\")\n throw Error(\"Invalid time instant format getting cue\");\n let t = null;\n return this._cues.some((n) => {\n if (e >= n.start && e <= n.end)\n return t = n, !0;\n }), t;\n }\n}\nfunction vt(i, e) {\n const t = {}, s = new DOMParser().parseFromString(e, \"text/xml\");\n return Array.from(s.getElementsByTagName(\"div\")).forEach((a) => {\n const r = a.getAttribute(\"xml:lang\") || \"unknonw\";\n t[r] = t[r] || new jt(i.translate(r), r), Array.from(a.getElementsByTagName(\"p\")).forEach((o) => {\n const l = Ye(o.getAttribute(\"begin\"));\n t[r].addCue({\n label: `caption_${o.getAttribute(\"xml:id\") || l}`,\n start: l / 1e3,\n end: Ye(o.getAttribute(\"end\")) / 1e3,\n captions: o.innerHTML\n });\n });\n }), t;\n}\nclass _n {\n constructor(e, t = \"\") {\n this.player = e, this._text = t, this._captions = vt(this.player, t);\n }\n get text() {\n return this._text;\n }\n set text(e) {\n this._text = e, this._captions = vt(e);\n }\n get captions() {\n return this._captions;\n }\n}\nlet je = null;\nclass ge extends Fe {\n static Get() {\n return je || (je = new ge()), je;\n }\n get moduleName() {\n return \"paella-core default plugins\";\n }\n get moduleVersion() {\n return Ie.version;\n }\n}\nclass wn extends Ht {\n getPluginModuleInstance() {\n return ge.Get();\n }\n get name() {\n return super.name || \"es.upv.paella.dfxpManifestCaptionsPlugin\";\n }\n async isEnabled() {\n return await super.isEnabled() && this.player.videoManifest.captions && this.player.videoManifest.captions.length > 0;\n }\n async getCaptions() {\n const e = [], t = [];\n return this.player.videoManifest.captions.forEach((n) => {\n t.push(new Promise(async (s, a) => {\n if (/dfxp/i.test(n.format)) {\n const r = Y(this.player, n.url), o = await fetch(r);\n if (o.ok) {\n let l = await o.text();\n l = l.replace(/[^\\x09\\x0A\\x0D\\x20-\\xFF\\x85\\xA0-\\uD7FF\\uE000-\\uFDCF\\uFDE0-\\uFFFD]/gm, \"\"), l = l.replace(/&\\w+;/gmi, \"\"), l = l.replaceAll(\"<br>\", \"\");\n const u = new _n(this.player, l);\n Object.entries(u.captions).forEach(([f, h]) => {\n e.push(h);\n }), s();\n } else\n a();\n } else\n a();\n }));\n }), await Promise.allSettled(t), e;\n }\n}\nclass lt extends he {\n constructor(e, t, n) {\n super(e, t, n), this.__uiPlugin = !0;\n }\n async getDictionaries() {\n return null;\n }\n}\nlet ct = \"en\", qt = \"\";\nconst ae = {};\nfunction Wt(i) {\n const e = ae[ct] || {}, t = ae[qt] || {};\n return e[i] || t[i] || i;\n}\nfunction Qt(i) {\n ct = i;\n}\nfunction Zt() {\n return ct;\n}\nfunction Yt(i, e) {\n ae[i] = ae[i] || {};\n for (const t in e) {\n const n = e[t];\n ae[i][t] = n;\n }\n}\nfunction Kt() {\n return ae;\n}\nfunction Jt(i) {\n return i.config.defaultLanguage || navigator.language;\n}\nlet Xt = Wt, ei = Qt, ti = Zt, ii = Yt, ni = Kt, si = Jt;\nfunction Ce(i, e = null) {\n const t = Xt(i);\n if (Array.isArray(e)) {\n let n = t;\n return e.forEach((s, a) => {\n const r = `$${a + 1}`;\n n = n.replace(r, s);\n }), n;\n } else\n return t;\n}\nfunction _t(i) {\n ei(i);\n}\nfunction Cn() {\n return ti();\n}\nfunction ve(i, e) {\n ii(i, e);\n}\nfunction bn() {\n return ni();\n}\nfunction ai(i) {\n return si(i);\n}\nfunction Ln(i) {\n Xt = i;\n}\nfunction Pn(i) {\n ei = i;\n}\nfunction En(i) {\n ti = i;\n}\nfunction Tn(i) {\n ii = i;\n}\nfunction Sn(i) {\n ni = i;\n}\nfunction In(i) {\n si = i;\n}\nfunction kn(i) {\n qt = ai(i);\n}\nasync function Ve(i, e) {\n var u, f;\n const t = b(\"<li></li>\", e);\n t.plugin = i;\n const n = Ce(i.ariaLabel), s = Ce(i.description), a = i.dynamicWidth ? \"dynamic-width\" : \"fixed-width\", r = i.id ? `id=\"${i.id}\" ` : \"\", o = i.buttonName ? `name=\"${i.buttonName}\" ` : \"\", l = i.tabIndex ? ` tabindex=\"${i.tabIndex}\" ` : \"\";\n if (i.interactive) {\n const h = b(`\n\t\t\t<button type=\"button\" ${r}${o}class=\"${a}\"${l}aria-label=\"${n}\" title=\"${s}\">\n\t\t\t</button>\n\t\t`, t);\n i.className !== \"\" && h.classList.add(i.className), i._button = h, i._container = t, h._pluginData = i, t._pluginData = i, h.addEventListener(\"click\", (c) => {\n const p = h._pluginData;\n E(p.player, m.BUTTON_PRESS, {\n plugin: p\n }), p.action(c, null), c.stopPropagation(), c.pageX !== 0 && c.pageY !== 0 && document.activeElement.blur();\n });\n let g = null;\n const L = () => {\n g && (clearTimeout(g), g = null);\n }, y = () => {\n L(), g = setTimeout(() => {\n i.leftSideContainerPresent && i.leftSideContainer.classList.add(\"hidden\"), i.rightSideContainerPresent && i.rightSideContainer.classList.add(\"hidden\"), g = null;\n }, 300);\n }, _ = () => {\n L(), i.leftSideContainerPresent && i.leftSideContainer.classList.remove(\"hidden\"), i.rightSideContainerPresent && i.rightSideContainer.classList.remove(\"hidden\");\n };\n h.addEventListener(\"focus\", _), h.addEventListener(\"mouseover\", _), h.addEventListener(\"mouseout\", y), h.addEventListener(\"blur\", y), (((u = i.player.config.accessibility) == null ? void 0 : u.clickWithSpacebar) !== void 0 ? (f = i.player.config.accessibility) == null ? void 0 : f.clickWithSpacebar : !0) || (h.addEventListener(\"keyup\", (c) => {\n c.keyCode == 32 && c.preventDefault();\n }), h.addEventListener(\"keydown\", (c) => {\n c.keyCode == 32 && c.preventDefault();\n })), i.className !== \"\" && h.classList.add(i.className);\n } else {\n const h = b(`\n\t\t\t<div ${r}${o} class=\"non-interactive ${a}\" title=\"${s}\">\n\t\t\t</div>\n\t\t`, t);\n i._button = h, i._container = t, h._pluginData = i, t._pluginData = i, i.className !== \"\" && h.classList.add(i.className);\n }\n}\nconst wt = () => {\n const i = document.createElement(\"span\");\n return i.classList.add(\"side-container\"), i.classList.add(\"hidden\"), i;\n};\nclass Dn {\n onIconChanged(e, t, n) {\n }\n onTitleChanged(e, t, n) {\n }\n onStateChanged(e, t, n, s, a) {\n }\n}\nvar Le, Je, q, W, Pe;\nclass ut extends lt {\n constructor() {\n super(...arguments);\n I(this, Le);\n I(this, q, null);\n I(this, W, null);\n I(this, Pe, []);\n }\n get type() {\n return \"button\";\n }\n // _container and _button are loaded in PlaybackBar\n get container() {\n return this._container;\n }\n get button() {\n return this._button;\n }\n get interactive() {\n return !0;\n }\n get dynamicWidth() {\n return !1;\n }\n getId() {\n return null;\n }\n get id() {\n return this.config.id || this.getId();\n }\n getButtonName() {\n return null;\n }\n get buttonName() {\n return this.config.name || this.getButtonName() || this.name;\n }\n get ariaLabel() {\n return this.config.ariaLabel || this.getAriaLabel();\n }\n getAriaLabel() {\n return \"\";\n }\n get tabIndex() {\n return this.config.tabIndex || this.getTabIndex();\n }\n getTabIndex() {\n return null;\n }\n getDescription() {\n return \"\";\n }\n get description() {\n return this.config.description || this.getDescription();\n }\n get minContainerSize() {\n return this.config.minContainerSize || this.getMinContainerSize();\n }\n getMinContainerSize() {\n return 0;\n }\n setObserver(t) {\n if (t instanceof Dn)\n this._observer = t;\n else if (typeof t.onIconChanged == \"function\" || typeof t.onTitleChanged == \"function\" || typeof t.onStateChanged == \"function\")\n this._observer = t;\n else\n throw new Error(\"Invalid observer for ButtonPlugin\");\n }\n get icon() {\n return this._icon || (this._icon = \"\"), this._icon;\n }\n set icon(t) {\n typeof t == \"string\" && (t = Ke(t)), this._icon = t, ze(this, Le, Je).call(this);\n }\n get haveIcon() {\n return this.icon !== \"\";\n }\n get menuIcon() {\n return this._menuIcon || (this._menuIcon = \"\"), this._menuIcon;\n }\n set menuIcon(t) {\n typeof t == \"string\" && (t = Ke(t)), this._menuIcon = t, ze(this, Le, Je).call(this);\n }\n get haveMenuIcon() {\n return this.menuIcon !== \"\";\n }\n get isMenuButton() {\n var s, a, r;\n const t = ((s = this.config) == null ? void 0 : s.parentContainer) === \"playbackBar\" || !((a = this.config) != null && a.parentContainer), n = ((r = this.config) == null ? void 0 : r.parentContainer) === \"videoContainer\";\n return !t && !n;\n }\n get title() {\n return this._title || \"\";\n }\n set title(t) {\n var n;\n if (this._title = t, t && this._button instanceof HTMLElement) {\n const s = this._button.querySelector(\"span\") || b(`<span class=\"button-title-${this.titleSize}\"></span>`, this._button);\n s.innerHTML = t;\n } else if (this._button instanceof HTMLElement) {\n const s = this._button.querySelector(\"span\");\n s && this._button.removeChild(s);\n }\n (n = this._observer) != null && n.onTitleChanged && this._observer.onTitleChanged(this, this._title, t);\n }\n // \"small\", \"medium\", \"large\"\n get titleSize() {\n return \"medium\";\n }\n // \"left\" or \"right\"\n get side() {\n var n;\n return ((n = this.config) == null ? void 0 : n.side) || \"left\";\n }\n get closePopUps() {\n return this.config.closePopUps || this.getClosePopUps();\n }\n getClosePopUps() {\n return !0;\n }\n // \"playbackBar\" or \"videoContainer\"\n get parentContainer() {\n var n;\n return ((n = this.config) == null ? void 0 : n.parentContainer) || \"playbackBar\";\n }\n get className() {\n return \"\";\n }\n enable() {\n this._enabled = !0, this.show();\n }\n disable() {\n this._enabled = !1, this.hide();\n }\n hide() {\n this._button && (this._button.style.display = \"none\");\n }\n show() {\n if (this._enabled === !1)\n return;\n const { width: t } = this.player.playbackBar.containerSize;\n this._button && (t > this.minContainerSize || this.parentContainer !== \"playbackBar\") && (this._button.style.display = null);\n }\n get leftSideContainer() {\n return d(this, q) || (k(this, q, wt()), this.container.appendChild(d(this, q))), d(this, q);\n }\n get leftSideContainerPresent() {\n return d(this, q) !== null;\n }\n get rightSideContainer() {\n return d(this, W) || (k(this, W, wt()), this.container.appendChild(d(this, W))), d(this, W);\n }\n get rightSideContainerPresent() {\n return d(this, W) !== null;\n }\n get stateText() {\n return null;\n }\n get stateIcon() {\n return null;\n }\n setState({ text: t = null, icon: n = null } = {}) {\n var r, o;\n const s = this._statusText, a = this._statusIcon;\n this._statusText = t, this._statusIcon = n, d(this, Pe).forEach((l) => l(this)), this._statusIcon && (this.icon = this._statusIcon, this.menuIcon = this._statusIcon), this._statusText && (this.title = this._statusText), (o =