{"version":3,"file":"paella-zoom-plugin.umd.cjs","sources":["../../paella-core/dist/paella-core.js","../src/dictionaries.js","../src/plugins/ZoomPluginsModule.js","../src/plugins/es.upv.paella.zoomPlugin.js","../src/icons/mini-zoom-in.js","../src/plugins/es.upv.paella.zoomInButtonPlugin.js","../src/icons/mini-zoom-out.js","../src/plugins/es.upv.paella.zoomOutButtonPlugin.js","../src/plugins/es.upv.paella.zoomMenuButtonPlugin.js","../src/plugins/es.upv.paella.canvasZoomInButtonPlugin.js","../src/plugins/es.upv.paella.canvasZoomOutButtonPlugin.js","../src/index.js"],"sourcesContent":["var Lt = (i) => {\n  throw TypeError(i);\n};\nvar Be = (i, e, t) => e.has(i) || Lt(\"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) ? Lt(\"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 Ai(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 zt(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 Gt(i) {\n  const e = new URLSearchParams(window.location.search);\n  return e.has(i) ? e.get(i) : null;\n}\nfunction Ht(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 jt(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 qt(i) {\n  return i.split(\".\").reduce((e, t, n, s) => n < s.length - 1 ? e !== \"\" ? `${e}.${t}` : t : e, \"\");\n}\nfunction lt(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 ct(i) {\n  return Me(i).split(\".\").pop();\n}\nfunction Y(i, e) {\n  return jt(e) ? e : z([i.manifestUrl, e]);\n}\nfunction Wt(i) {\n  i.__hideTimerPaused__ = !0;\n}\nfunction ut(i) {\n  i.__hideTimerPaused__ = !1;\n}\nfunction Qt(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 Zt(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 Yt(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 Mi(i) {\n  const e = Z(i), t = Number(e);\n  return e !== \"\" && !isNaN(t) ? t : null;\n}\nfunction Ri(i) {\n  try {\n    return JSON.parse(Z(i));\n  } catch {\n    return null;\n  }\n}\nfunction dt(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 Kt(i) {\n  if (!i)\n    return;\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 ht(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: Zt,\n  getCookie: Z,\n  getFileExtension: ct,\n  getHashParameter: Ht,\n  getJSONCookie: Ri,\n  getNumericCookie: Mi,\n  getUrlFileName: Me,\n  getUrlParameter: Gt,\n  isAbsoluteUrl: jt,\n  joinPath: z,\n  loadStyle: dt,\n  loadSvgIcon: zt,\n  mergeObjects: we,\n  pauseAutoHideUiTimer: Wt,\n  removeExtension: qt,\n  removeFileName: lt,\n  resolveResourcePath: Y,\n  resumeAutoHideUiTimer: ut,\n  sanitizeHTML: Ke,\n  secondsToTime: ie,\n  setCookie: ne,\n  setCookieIfAllowed: Yt,\n  setupAutoHideUiTimer: Qt,\n  supportsVideoType: ht,\n  timeToMilliseconds: Ye,\n  timeToSeconds: Ae,\n  unloadStyle: Kt\n}, Symbol.toStringTag, { value: \"Module\" }));\nasync function Vi(i, e) {\n  return e.log.debug(\"Using default configuration loading function.\"), (await fetch(i)).json();\n}\nasync function Ni(i, e) {\n  return e.log.debug(\"Using default getVideoId function\"), Ht(\"id\") || Gt(\"id\") || i.fallbackId;\n}\nasync function Ui(i, e, t, n) {\n  return n.log.debug(\"Using default getManifestUrl function\"), z([i, e]);\n}\nasync function Fi(i, e, t, n) {\n  return n.log.debug(\"Using default getManifestFileUrl function\"), z([i, e]);\n}\nasync function Oi(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 Jt({ 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, Jt({ 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 $i = `<?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 Bi extends G {\n  constructor(e) {\n    super(e, { parent: e.containerElement }), this.element.className = \"loader-container\";\n  }\n  async create() {\n    b(`<i>${$i}</i>`, this.element);\n  }\n  get debug() {\n    return !1;\n  }\n}\nconst zi = `<?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>${zi}</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 Gi(i) {\n  await $(i, \"video\", (e) => {\n    Re.push(e);\n  });\n}\nasync function Hi(i) {\n  Re.slice(0);\n}\nfunction Xt(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 ji(i, e) {\n  const t = ct(e);\n  return Xt().find((s) => s.getCompatibleFileExtensions().indexOf(t) !== -1);\n}\nasync function qi(i, e) {\n  const t = Xt();\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 Wi() {\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 pt 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 Wi();\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 Qi = \"@asicupv/paella-core\", Zi = { \".\": \"./dist/paella-core.js\", \"./src/\": \"./src/\", \"./paella-core.css\": \"./dist/paella-core.css\" }, Yi = \"2.2.10\", Ki = \"Multi stream HTML video player\", Ji = \"./dist/paella-core.js\", Xi = [\"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\"], en = \"./dist/paella-core.js\", tn = \"module\", nn = { dev: \"vite build --watch\", build: \"vite build --emptyOutDir\" }, sn = { type: \"git\", url: \"git+https://github.com/polimediaupv/paella-player.git\" }, an = [\"html\", \"player\", \"video\", \"hls\"], rn = \"Fernando Serrano Carpena <ferserc1@gmail.com>\", on = \"ECL-2.0\", ln = { url: \"https://github.com/polimediaupv/paella-player/issues\" }, cn = \"https://github.com/polimediaupv/paella-player#readme\", un = { typescript: \"^5.8.3\", vite: \"^6.0.11\" }, dn = { \"@ferserc1/input-style-unifier\": \"^0.0.2\", \"vite-plugin-static-copy\": \"^3.0.0\" }, Ie = {\n  name: Qi,\n  exports: Zi,\n  version: Yi,\n  description: Ki,\n  main: Ji,\n  files: Xi,\n  module: en,\n  type: tn,\n  scripts: nn,\n  repository: sn,\n  keywords: an,\n  author: rn,\n  license: on,\n  bugs: ln,\n  homepage: cn,\n  devDependencies: un,\n  dependencies: dn\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 hn(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 pn(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 gn extends pt {\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 hn(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 pn(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 mn 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 gn(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 ei extends pt {\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 fn 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) => ht(n.mimetype));\n  }\n  async getVideoInstance(e, t) {\n    return new ei(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 (ct(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 yn {\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 ti(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 _n() {\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, ti.apply(this, [this._currentTime]);\n  };\n  i();\n}\nfunction vn() {\n  this._timer && (clearTimeout(this._timer), this._timer = null);\n}\nclass wn extends pt {\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    _n.apply(this);\n  }\n  async pause() {\n    vn.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, ti.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 yn({\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 Cn 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 wn(this.player, e, this.config, t);\n  }\n}\nclass bn extends ei {\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 Ln 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 && ht((n = t[0]) == null ? void 0 : n.mimetype);\n  }\n  async getVideoInstance(e, t) {\n    return new bn(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 Pn(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 ii 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 ni {\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 Pt(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 ni(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 En {\n  constructor(e, t = \"\") {\n    this.player = e, this._text = t, this._captions = Pt(this.player, t);\n  }\n  get text() {\n    return this._text;\n  }\n  set text(e) {\n    this._text = e, this._captions = Pt(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 Tn extends ii {\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 En(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 gt 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 mt = \"en\", si = \"\";\nconst ae = {};\nfunction Je(i) {\n  const e = ae[mt] || {}, t = ae[si] || {};\n  return e[i] || t[i] || i;\n}\nfunction Xe(i) {\n  mt = i;\n}\nfunction et() {\n  return mt;\n}\nfunction tt(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 it() {\n  return ae;\n}\nfunction nt(i) {\n  return i.config.defaultLanguage || navigator.language;\n}\nlet ai = Je, ri = Xe, oi = et, li = tt, ci = it, ui = nt;\nfunction Ce(i, e = null) {\n  const t = ai(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 Et(i) {\n  ri(i);\n}\nfunction Sn() {\n  return oi();\n}\nfunction _e(i, e) {\n  li(i, e);\n}\nfunction In() {\n  return ci();\n}\nfunction di(i) {\n  return ui(i);\n}\nfunction Tt(i) {\n  ai = i;\n}\nfunction St(i) {\n  ri = i;\n}\nfunction It(i) {\n  oi = i;\n}\nfunction kt(i) {\n  li = i;\n}\nfunction Dt(i) {\n  ci = i;\n}\nfunction xt(i) {\n  ui = i;\n}\nfunction kn(i) {\n  si = di(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    }, v = () => {\n      L(), i.leftSideContainerPresent && i.leftSideContainer.classList.remove(\"hidden\"), i.rightSideContainerPresent && i.rightSideContainer.classList.remove(\"hidden\");\n    };\n    h.addEventListener(\"focus\", v), h.addEventListener(\"mouseover\", v), 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 At = () => {\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, st, q, W, Pe;\nclass ft extends gt {\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, st).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, st).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, At()), 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, At()), 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 = (r = this._observer) == null ? void 0 : r.onStateChanged) == null || o.call(r, this, s, t, a, n);\n  }\n  onStateChange(t) {\n    typeof t == \"function\" ? d(this, Pe).push(t) : this.player.log.warn(\"Invalid callback for ButtonPlugin.onStateChange\");\n  }\n  async action(t, n = null) {\n  }\n  onResize({ width: t, height: n }) {\n    t < this.minContainerSize ? this.hide() : this.show();\n  }\n  focus() {\n    var t;\n    (t = this.button) == null || t.focus();\n  }\n  blur() {\n    var t;\n    (t = this.button) == null || t.blur();\n  }\n  isFocus() {\n    return this.button === document.activeElement;\n  }\n}\nLe = new WeakSet(), st = function() {\n  var s;\n  const t = this.isMenuButton ? this._menuIcon : this._icon, n = this.isMenuButton && this.haveMenuIcon ? this.menuIcon : this.icon;\n  if (n && this._button instanceof HTMLElement) {\n    const a = this._button.querySelector(\"i\") || b(\"<i></i>\", this._button);\n    a.innerHTML = n;\n  } else if (this._button instanceof HTMLElement) {\n    const a = this._button.querySelector(\"i\");\n    a && this._button.removeChild(a);\n  }\n  (s = this._observer) != null && s.onIconChanged && this._observer.onIconChanged(this, t, n);\n}, q = new WeakMap(), W = new WeakMap(), Pe = new WeakMap();\nconst xn = `<svg width=\"100%\"\n    height=\"100%\" viewBox=\"0 0 24 24\"\n    style=\"stroke:none;fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;\">\n    <g id=\"play\">\n        <path\n            d=\"M19.662,11.155C19.952,11.338 20.128,11.657 20.128,12C20.128,12.343 19.952,12.662 19.662,12.845C16.249,15 7.228,20.698 3.572,23.007C3.257,23.206 2.857,23.218 2.53,23.038C2.203,22.858 2,22.514 2,22.14C2,17.638 2,6.199 2,1.78C2,1.423 2.194,1.094 2.508,0.921C2.821,0.748 3.203,0.76 3.505,0.951C7.117,3.232 16.228,8.986 19.662,11.155Z\" />\n    </g>\n</svg>\n`, An = `<svg width=\"100%\"\n    height=\"100%\" viewBox=\"0 0 26 24\"\n    style=\"stroke:none;fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;\">\n    <path\n        d=\"M10,1.353L10,20.647C10,21.394 9.394,22 8.647,22L1.353,22C0.606,22 0,21.394 0,20.647L0,1.353C0,0.606 0.606,0 1.353,0L8.647,0C9.394,0 10,0.606 10,1.353Z\" />\n    <path\n        d=\"M24,1.353L24,20.647C24,21.394 23.394,22 22.647,22L15.353,22C14.606,22 14,21.394 14,20.647L14,1.353C14,0.606 14.606,0 15.353,0L22.647,0C23.394,0 24,0.606 24,1.353Z\" />\n</svg>`, Mn = `<?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 40 42\" 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.94013e-16,0.689169,-0.784942,2.23746e-16,110.436,-203.562)\">\n        <g id=\"play\">\n            <path d=\"M304.588,115.214C304.588,105.205 313.901,97.079 325.373,97.079C336.844,97.079 346.157,105.205 346.157,115.214C346.157,125.223 336.844,133.349 325.373,133.349L325.373,128.287C333.642,128.287 340.356,122.43 340.356,115.214C340.356,107.999 333.642,102.141 325.373,102.141C317.103,102.141 310.39,107.999 310.39,115.214L304.588,115.214Z\"/>\n            <g transform=\"matrix(-2.33361,-6.00363e-16,1.21708e-15,-2.59724,320.246,134.358)\">\n                <path d=\"M5.454,3.35L9.398,7.505L1.511,7.505L5.454,3.35Z\"/>\n            </g>\n        </g>\n    </g>\n</svg>\n`;\nclass Rn extends ft {\n  getPluginModuleInstance() {\n    return ge.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.playPauseButton\";\n  }\n  async load() {\n    const e = this.player.getCustomPluginIcon(this.name, \"play\") || xn, t = this.player.getCustomPluginIcon(this.name, \"pause\") || An, n = this.player.getCustomPluginIcon(this.name, \"replay\") || Mn;\n    this.icon = e, this.player.translate(this.config.ariaLabelPause || \"pause\");\n    const s = this.player.translate(this.config.ariaLabelPlay || \"play\");\n    M(this.player, m.PLAY, () => {\n      this.icon = t, this.button.ariaLabel = s, this.button.title = this.config.ariaLabelPause || s;\n    }), M(this.player, m.PAUSE, () => {\n      this.icon = e, this.button.ariaLabel = s, this.button.title = this.config.ariaLabelPause || s;\n    }), M(this.player, m.ENDED, () => {\n      this.icon = n, this.button.ariaLabel = s, this.button.title = this.config.ariaLabelPause || s;\n    }), M(this.player, m.STOP, () => {\n      this.icon = e, this.button.ariaLabel = s, this.button.title = this.config.ariaLabelPause || s;\n    });\n  }\n  async action() {\n    await this.player.paused() ? await this.player.videoContainer.play() : await this.player.videoContainer.pause();\n  }\n}\nconst Mt = \"(?:\\\\d*:){1,2}\\\\d*(?:\\\\.\\\\d+)?\", Vn = `(${Mt})\\\\s*\\\\-\\\\->\\\\s*(${Mt})`, Nn = {\n  cueTiming: new RegExp(Vn)\n}, Un = (i, e, t, n) => {\n  const s = Nn.cueTiming.exec(e);\n  if (s) {\n    const a = n[t - 1], r = [];\n    for (let o = 1; t + o < n.length && n[t + o] !== \"\"; ++o)\n      r.push(n[t + o]);\n    i.addCue({\n      label: a,\n      start: s[1],\n      end: s[2],\n      captions: r\n    });\n  }\n};\nfunction Rt(i) {\n  const e = new ni();\n  return i !== \"\" && (i = i.replace(/\\r\\n/gm, `\n`), i = i.replace(/\\r/gm, `\n`), i.split(/\\n/).forEach((t, n, s) => {\n    Un(e, t, n, s);\n  })), e;\n}\nclass Fn {\n  constructor(e = \"\") {\n    this._text = e, this._captions = Rt(e);\n  }\n  get text() {\n    return this._text;\n  }\n  set text(e) {\n    this._text = e, this._captions = Rt(e);\n  }\n  get captions() {\n    return this._captions;\n  }\n}\nclass On extends ii {\n  getPluginModuleInstance() {\n    return ge.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.vttManifestCaptionsPlugin\";\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 (/vtt/i.test(n.format)) {\n          const r = Y(this.player, n.url), o = await fetch(r);\n          if (o.ok) {\n            const l = await o.text(), u = new Fn(l);\n            u.captions.label = n.text, u.captions.language = n.lang, e.push(u.captions), s();\n          } else\n            a();\n        } else\n          a();\n      }));\n    }), await Promise.allSettled(t), e;\n  }\n}\nclass $n extends ft {\n  getPluginModuleInstance() {\n    return ge.Get();\n  }\n  get name() {\n    return \"es.upv.paella.currentTimeLabel\";\n  }\n  async load() {\n    this.title = ie(0);\n    const e = async () => {\n      const t = await this.player.videoContainer.currentTime();\n      let n = ie(t);\n      if (this.config.showTotalTime) {\n        const s = await this.player.videoContainer.duration();\n        n += ` / ${ie(s)}`;\n      }\n      this.title = n;\n    };\n    this.player.bindEvent(m.TIMEUPDATE, () => e()), this.player.bindEvent(m.TRIMMING_CHANGED, () => e()), this.player.bindEvent(m.SEEK, () => e());\n  }\n  get interactive() {\n    return !1;\n  }\n  get dynamicWidth() {\n    return !0;\n  }\n}\nfunction Oe(i, e) {\n  return vi(i, \"layout\").filter((n) => n.config && n.config.enabled && n.canApply(e));\n}\nfunction hi(i, e) {\n  const t = Oe(i, e), n = [];\n  return t.forEach((s) => {\n    n.push(...s.getValidContentIds(e));\n  }), n;\n}\nfunction Bn(i, e) {\n  const t = [];\n  return vi(i, \"layout\").filter((n) => {\n    var s, a;\n    if ((s = n.config) != null && s.enabled && ((a = n.config) != null && a.validContent))\n      return n.config.validContent.every((r) => r.content.length === e);\n  }).forEach((n) => n.config.validContent.forEach((s) => t.push(s.content))), t;\n}\nfunction pi(i, e, t) {\n  const n = Oe(i, e);\n  let s = null;\n  return n.some((a) => {\n    if (a.getValidContentIds(e).indexOf(t) !== -1)\n      return s = a, !0;\n  }), s;\n}\nfunction zn(i, e) {\n  const t = Oe(i, e), n = hi(i, e);\n  let s = [];\n  return t.forEach((a) => {\n    s = [...s, ...a.config.validContent];\n  }), s.filter((a) => n.indexOf(a.id) !== -1);\n}\nfunction gi(i, e, t, n = null) {\n  const s = pi(i, e, t);\n  if (s) {\n    const a = s.getLayoutStructure(e, t, n);\n    return a.plugin = s, a;\n  }\n  return null;\n}\nclass me extends gt {\n  get type() {\n    return \"layout\";\n  }\n  get layoutType() {\n    return \"static\";\n  }\n  getTabIndexStart() {\n    return 10;\n  }\n  get tabIndexStart() {\n    var e;\n    return ((e = this.config) == null ? void 0 : e.tabIndexStart) || this.getTabIndexStart();\n  }\n  // Return the layout identifier, for example, presenter-presentation\n  get identifier() {\n    return \"default\";\n  }\n  get icon() {\n    return \"icon.png\";\n  }\n  // Return the array of valid content in the configuration of the plugin\n  get validContent() {\n    var e;\n    return ((e = this.config) == null ? void 0 : e.validContent) || [];\n  }\n  get validContentIds() {\n    const e = [];\n    return this.validContent.forEach((t) => e.push(t.id)), e;\n  }\n  // Gets the valid content ids that matches the streamData\n  getValidContentIds(e) {\n    const t = [];\n    return this.validContent.forEach((n) => {\n      n.content.every((s) => e.some((a) => s === a.content)) && t.push(n.id);\n    }), t;\n  }\n  // Get the valid stream data combination, according to the plugin configuration\n  // The result of this function must be an array of arrays with all the possible\n  // combinations. For example, for a dual stream layout and three elements in\n  // streamData that matches the valid content, the resulting valid streams must be:\n  // [\n  //      [streamA, streamB],\n  //      [streamA, streamC],\n  //      [streamC, streamB]   \n  // ]\n  getValidStreams(e) {\n    const t = [];\n    return this.validContent.forEach((n) => {\n      let s = [];\n      n.content.every((a) => e.some((r) => {\n        if (a === r.content)\n          return s.push(r), !0;\n      })) && t.push(s);\n    }), t;\n  }\n  canApply(e) {\n    return this.getValidStreams(e).length > 0;\n  }\n  getLayoutStructure() {\n    return {};\n  }\n  // Add buttons to videos\n  // [\n  //      icon    (required)\n  //      click   (required)\n  //      tabIndex\n  //      ariaLabel\n  //      title\n  //      className\n  //      position (CanvasButtonPosition.LEFT, CanvasButtonPosition.CENTER, CanvasButtonPosition.RIGHT)\n  //]\n  getVideoCanvasButtons(e, t, n) {\n    return [];\n  }\n}\nfunction Gn(i) {\n  return {\n    icon: i.icon,\n    position: i.position,\n    title: i.description,\n    ariaLabel: i.ariaLabel,\n    name: i.buttonName,\n    click: async (e) => {\n      const t = i.player.videoContainer.streamProvider.streams[e];\n      await i.action(e, t == null ? void 0 : t.player, t == null ? void 0 : t.canvas, t == null ? void 0 : t.canvasPlugin);\n    }\n  };\n}\nasync function Hn(i, e) {\n  const t = [];\n  return await $(\n    i,\n    \"canvasButton\",\n    async (n) => {\n      i.log.debug(` Canvas button plugin: ${n.name}`), t.push(n);\n    }\n  ), t.filter((n) => n.content.indexOf(e.content) !== -1).map((n) => Gn(n));\n}\nclass da extends gt {\n  get type() {\n    return \"canvasButton\";\n  }\n  get content() {\n    return this._config.content || [\"presenter\"];\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;\n  }\n  get description() {\n    return this.config.description || this.getDescription();\n  }\n  getDescription() {\n    return \"\";\n  }\n  get icon() {\n    return this._icon;\n  }\n  set icon(e) {\n    this._icon = e;\n  }\n  get side() {\n    var e;\n    return ((e = this.config) == null ? void 0 : e.side) || \"left\";\n  }\n  get buttonName() {\n    return this.name;\n  }\n  get position() {\n    switch (this.side) {\n      case \"left\":\n        return S.LEFT;\n      case \"center\":\n        return S.CENTER;\n      case \"right\":\n        return S.RIGHT;\n      default:\n        throw new Error(`Invalid CanvasButtonPlugin side set: ${this.side}`);\n    }\n  }\n  async action(e) {\n    this.player.log.warn(`Action not implemented in canvas button plugin ${this.name}`);\n  }\n}\nconst at = [];\nasync function jn(i) {\n  await $(i, \"canvas\", (e) => {\n    at.push(e);\n  });\n}\nasync function qn(i) {\n}\nfunction Wn(i, e) {\n  if (at.length === 0)\n    throw Error(\"No canvas plugins loaded. Note that `loadCanvasPlugins()` must to be called before use `getCanvasPlugins()`\");\n  let t = null;\n  return at.some((n) => {\n    if (n.isCompatible(e))\n      return t = n, !0;\n  }), t;\n}\nconst S = Object.freeze({\n  LEFT: \"left\",\n  CENTER: \"center\",\n  RIGHT: \"right\"\n}), Qn = function({\n  icon: i,\n  tabIndex: e,\n  ariaLabel: t,\n  title: n,\n  className: s,\n  position: a = S.CENTER,\n  click: r,\n  content: o,\n  name: l\n}) {\n  if (!i)\n    throw new Error(\"Error in video layout definition. getVideoCanvasButtons(): missing 'icon' attribute.\");\n  if (!r)\n    throw new Error(\"Error in video layout definition. getVideoCanvasButtons(): missing 'click' function.\");\n  let u = `class=\"align-${a}${s ? \" \" + s : \"\"}\"`;\n  t && (u += ` aria-label=\"${t}\"`), n && (u += ` title=\"${n}\"`), e !== void 0 && (u += ` tabindex=\"${e}\"`), l !== void 0 && (u += ` name=\"${l}\"`);\n  const f = b(`\n        <button ${u}><i class=\"button-icon\" style=\"pointer-events: none\">${i}</i></button>\n    `);\n  switch (a) {\n    case \"left\":\n      this.leftButtonsArea.appendChild(f);\n      break;\n    case \"center\":\n      this.centerButtonsArea.appendChild(f);\n      break;\n    case \"right\":\n      this.rightButtonsArea.appendChild(f);\n      break;\n  }\n  return f.addEventListener(\"click\", async (h) => (h.stopPropagation(), await r(o), !1)), f;\n}, rt = async (i, e, t, n, s) => {\n  const a = e.plugin;\n  let r = a.tabIndexStart;\n  const o = await Hn(i, n), l = [];\n  return [\n    ...o,\n    ...a.getVideoCanvasButtons(e, n.content, n, t)\n  ].forEach((f) => {\n    f.tabIndex = r++, f.content = s;\n    const h = Qn.apply(t, [f]);\n    l.push(h);\n  }), l;\n}, ot = (i, e, t) => {\n  let { tabIndexStart: n } = e.plugin;\n  t.sort((s, a) => {\n    const r = s.getBoundingClientRect().left, o = a.getBoundingClientRect().left;\n    return r - o;\n  }).forEach((s) => {\n    s.setAttribute(\"tabindex\", n++);\n  });\n};\nclass mi extends G {\n  constructor(e, t, n) {\n    super(t, { tag: e, parent: n }), this.element.className = \"video-canvas\", this._userArea = null, this._buttonsArea = b(`\n        <div class=\"button-area\">\n            <div class=\"buttons-left\"></div>\n            <div class=\"buttons-center\"></div>\n            <div class=\"buttons-right\"></div>\n        </div>\n        `, this.element);\n  }\n  async loadCanvas(e) {\n    throw Error(`${this.name}: loadCanvas() not implemented`);\n  }\n  get userArea() {\n    return this._userArea || (this._userArea = document.createElement(\"div\"), this._userArea.className = \"user-area\", this.element.appendChild(this._userArea)), this._userArea;\n  }\n  get leftButtonsArea() {\n    return this._buttonsArea.querySelector(\".buttons-left\");\n  }\n  get centerButtonsArea() {\n    return this._buttonsArea.querySelector(\".buttons-center\");\n  }\n  get rightButtonsArea() {\n    return this._buttonsArea.querySelector(\".buttons-right\");\n  }\n  clearButtonsArea() {\n    this._buttonsArea.childNodes.forEach((e) => {\n      e.innerHTML = \"\";\n    });\n  }\n  showButtons() {\n    this._buttonsArea.style.display = null;\n  }\n  hideButtons() {\n    this._buttonsArea.style.display = \"none\";\n  }\n}\nclass fi extends he {\n  get type() {\n    return \"canvas\";\n  }\n  get canvasType() {\n    return \"\";\n  }\n  isCompatible(e) {\n    return Array.isArray(e == null ? void 0 : e.canvas) ? e.canvas.indexOf(this.canvasType) !== -1 : e.canvas === this.canvasType;\n  }\n  getCanvasInstance(e) {\n    throw Error(`${this.name} canvas plugin: getCanvasInstance() not implemented`);\n  }\n}\nlet qe = null;\nclass K extends Fe {\n  static Get() {\n    return qe || (qe = new K()), qe;\n  }\n  get moduleName() {\n    return \"paella-core default video layouts\";\n  }\n  get moduleVersion() {\n    return Ie.version;\n  }\n}\nconst yt = `<?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 40 40\" 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(0.920758,0,0,0.920758,2.50561,1.21236)\">\n        <path d=\"M11.937,17.699L11.937,21.044C11.937,21.656 11.573,22.209 11.012,22.451C10.45,22.693 9.798,22.578 9.354,22.158L1.874,15.1C1.568,14.811 1.394,14.408 1.394,13.986C1.394,13.564 1.568,13.161 1.874,12.872L9.354,5.814C9.798,5.394 10.45,5.279 11.012,5.521C11.573,5.763 11.937,6.316 11.937,6.928L11.937,10.272L22.937,10.272C23.783,10.272 24.469,10.958 24.469,11.804L24.469,16.168C24.469,17.014 23.783,17.699 22.937,17.699L11.937,17.699ZM26.063,23.11L26.063,19.765C26.063,19.153 26.427,18.6 26.988,18.358C27.55,18.116 28.201,18.231 28.646,18.651L36.126,25.709C36.432,25.999 36.606,26.402 36.606,26.823C36.606,27.245 36.432,27.648 36.126,27.937L28.646,34.996C28.201,35.415 27.55,35.53 26.988,35.288C26.427,35.046 26.063,34.493 26.063,33.882L26.063,30.537L15.063,30.537C14.217,30.537 13.531,29.851 13.531,29.005L13.531,24.641C13.531,23.795 14.217,23.11 15.063,23.11L26.063,23.11Z\"/>\n    </g>\n</svg>\n`, Ne = `<?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 40 40\" 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(-0.620305,0,0,0.839332,25.2077,0.462208)\">\n        <path d=\"M-20.625,8.591C-20.625,6.174 -17.975,4.215 -14.704,4.215L31.492,4.215C34.763,4.215 37.413,6.174 37.413,8.591L37.413,35.582C37.413,37.998 34.763,39.957 31.492,39.957L-14.704,39.957C-17.975,39.957 -20.625,37.998 -20.625,35.582L-20.625,8.591ZM1.285,12.825L8.1,7.789L-15.786,7.789L-15.786,25.442L-8.972,20.406L6.737,32.016L16.994,24.435L1.285,12.825Z\" />\n    </g>\n</svg>\n`, ve = `<?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 40 40\" 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(0.707107,0.707107,-0.707107,0.707107,20,-8.28427)\">\n        <path d=\"M23,17L23,4.998C23,4.203 22.684,3.44 22.122,2.878C21.56,2.316 20.797,2 20.002,2C20.001,2 19.999,2 19.998,2C19.203,2 18.44,2.316 17.878,2.878C17.316,3.44 17,4.203 17,4.998C17,9.375 17,17 17,17L4.998,17C4.203,17 3.44,17.316 2.878,17.878C2.316,18.44 2,19.203 2,19.998C2,19.999 2,20.001 2,20.002C2,20.797 2.316,21.56 2.878,22.122C3.44,22.684 4.203,23 4.998,23C9.375,23 17,23 17,23L17,35.002C17,35.797 17.316,36.56 17.878,37.122C18.44,37.684 19.203,38 19.998,38C19.999,38 20.001,38 20.002,38C20.797,38 21.56,37.684 22.122,37.122C22.684,36.56 23,35.797 23,35.002C23,30.625 23,23 23,23L35.002,23C35.797,23 36.56,22.684 37.122,22.122C37.684,21.56 38,20.797 38,20.002C38,20.001 38,19.999 38,19.998C38,19.203 37.684,18.44 37.122,17.878C36.56,17.316 35.797,17 35.002,17C30.625,17 23,17 23,17Z\"/>\n    </g>\n</svg>`, ke = `<?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 40 40\" 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>\n        <path d=\"M18,13.029L18,26.971C18,27.509 17.786,28.025 17.406,28.406C17.025,28.786 16.509,29 15.971,29L3.029,29C2.491,29 1.975,28.786 1.594,28.406C1.214,28.025 1,27.509 1,26.971L1,13.029C1,12.491 1.214,11.975 1.594,11.594C1.975,11.214 2.491,11 3.029,11L15.971,11C16.509,11 17.025,11.214 17.406,11.594C17.786,11.975 18,12.491 18,13.029ZM39,13.029L39,26.971C39,27.509 38.786,28.025 38.406,28.406C38.025,28.786 37.509,29 36.971,29L24.029,29C23.491,29 22.975,28.786 22.594,28.406C22.214,28.025 22,27.509 22,26.971L22,13.029C22,12.491 22.214,11.975 22.594,11.594C22.975,11.214 23.491,11 24.029,11L36.971,11C37.509,11 38.025,11.214 38.406,11.594C38.786,11.975 39,12.491 39,13.029ZM21,7L21,33L19,33L19,7L21,7Z\"/>\n    </g>\n</svg>\n`, Zn = `<?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 40 40\" 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(-0.620305,0,0,0.839332,25.2077,0.462208)\">\n        <g transform=\"matrix(-1.61211,0,0,1.19142,40.6376,-0.550686)\">\n            <path d=\"M38.001,14.89L16.256,14.89C15.767,14.89 15.297,15.084 14.951,15.43C14.605,15.776 14.41,16.246 14.41,16.735C14.41,21.528 14.41,33.999 14.41,33.999L5.673,33.999C3.644,33.999 2,32.355 2,30.327L2,7.673C2,5.644 3.644,4 5.673,4L34.329,4C36.358,4 38.001,5.644 38.001,7.673L38.001,14.89Z\"/>\n        </g>\n        <g transform=\"matrix(-1.62701,0,0,1.19712,41.1319,-0.602464)\">\n            <path d=\"M39.174,17.858C39.174,17.501 39.032,17.158 38.781,16.906C38.529,16.653 38.188,16.511 37.833,16.511C33.587,16.511 20.516,16.511 17.043,16.511C16.816,16.511 16.598,16.602 16.438,16.763C16.278,16.924 16.188,17.142 16.188,17.37C16.188,20.366 16.188,30.369 16.188,34.019C16.188,34.376 16.329,34.719 16.581,34.971C16.832,35.224 17.173,35.366 17.529,35.366C21.597,35.366 33.765,35.366 37.833,35.366C38.188,35.366 38.529,35.224 38.781,34.971C39.032,34.719 39.174,34.376 39.174,34.019C39.174,30.548 39.174,21.329 39.174,17.858Z\"/>\n        </g>\n    </g>\n</svg>\n`;\nclass Vt extends me {\n  getPluginModuleInstance() {\n    return K.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.dualVideoDynamic\";\n  }\n  get layoutType() {\n    return \"dynamic\";\n  }\n  async load() {\n    this.pipContentIds = this.config.pipContentIds || [], this.allowSwitchSide = this.config.allowSwitchSide !== void 0 ? this.config.allowSwitchSide : !0;\n  }\n  getVideoCanvasButtons(e, t, n, s) {\n    const a = this.player.getCustomPluginIcon(this.name, \"iconMaximize\") || Ne, r = this.player.getCustomPluginIcon(this.name, \"iconSideBySide\") || ke, o = this.player.getCustomPluginIcon(this.name, \"iconSwitchSide\") || yt, l = this.player.getCustomPluginIcon(this.name, \"iconClose\") || ve, u = this.player.getCustomPluginIcon(this.name, \"iconPiP\") || Zn, f = () => this._currentContent.find((y) => y.id === t), h = () => f().size === 25, g = () => f().size > 50, L = [];\n    return h() || g() ? L.push({\n      icon: r,\n      position: S.LEFT,\n      title: this.player.translate(\"Dual stream 50%\"),\n      ariaLabel: this.player.translate(\"Dual stream 50%\"),\n      name: this.name + \":iconSideBySide\",\n      click: async () => {\n        this._currentContent.forEach((y) => {\n          y.size = 50;\n        }), await this.player.videoContainer.updateLayout();\n      }\n    }) : L.push({\n      icon: a,\n      position: S.LEFT,\n      title: this.player.translate(\"Maximize video\"),\n      ariaLabel: this.player.translate(\"Maximize video\"),\n      name: this.name + \":iconMaximize\",\n      click: async () => {\n        this._currentContent.forEach((y) => {\n          y.size = y.id === t ? 75 : 25;\n        }), await this.player.videoContainer.updateLayout();\n      }\n    }), this.allowSwitchSide && L.push({\n      icon: o,\n      position: S.LEFT,\n      title: this.player.translate(\"Switch side\"),\n      ariaLabel: this.player.translate(\"Switch side\"),\n      name: this.name + \":iconSwitchSide\",\n      click: async () => {\n        const y = this._currentContent[0].id, v = this._currentContent[1].id, P = this._currentContent[0].size, c = this._currentContent[1].size;\n        this._currentContent[0].id = v, this._currentContent[0].size = c, this._currentContent[1].id = y, this._currentContent[1].size = P, await this.player.videoContainer.updateLayout();\n      }\n    }), L.push({\n      icon: l,\n      position: S.RIGHT,\n      title: this.player.translate(\"Close video\"),\n      ariaLabel: this.player.translate(\"Close video\"),\n      name: this.name + \":iconClose\",\n      click: async () => {\n        const v = this.player.videoContainer.validContentIds.filter((P) => P.indexOf(\"-\") === -1).find((P) => P != t);\n        await this.player.videoContainer.setLayout(v);\n      }\n    }), this.pipContentIds.length > 0 && L.push({\n      icon: u,\n      position: S.LEFT,\n      title: this.player.translate(\"Picture-in-picture\"),\n      ariaLabel: this.player.translate(\"Picture-in-picture\"),\n      name: this.name + \":iconPiP\",\n      click: async () => {\n        const y = this.player.videoContainer.validContentIds.find((v) => this.pipContentIds.indexOf(v) !== -1);\n        await this.player.videoContainer.setLayout(y, t);\n      }\n    }), L;\n  }\n  getLayoutStructure(e, t, n) {\n    if (!this._currentContent) {\n      const { content: s } = this.validContent.find((a) => a.id === t);\n      this._currentContent = s.map((a) => ({\n        id: a,\n        size: 50\n      }));\n    }\n    return {\n      id: \"dual-dynamic\",\n      videos: [\n        {\n          content: this._currentContent[0].id,\n          visible: !0,\n          size: this._currentContent[0].size\n        },\n        {\n          content: this._currentContent[1].id,\n          visible: !0,\n          size: this._currentContent[1].size\n        }\n      ]\n    };\n  }\n}\nconst yi = `<?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 40 40\" 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(-0.620305,0,0,0.839332,25.2077,0.462208)\">\n        <g transform=\"matrix(-1.50139,0,0,1.10483,39.8625,1.72153)\">\n            <path d=\"M22.034,28.802C22.58,28.752 23.089,28.64 23.626,28.496C28.793,27.112 31.864,21.792 30.48,16.625C30.189,15.54 29.715,14.525 29.088,13.619L31.915,8.722C33.663,10.535 34.942,12.776 35.606,15.251C37.748,23.248 32.996,31.48 24.999,33.622C24.011,33.887 23.04,34.063 22.034,34.123L22.034,40.015L13,31.5L22.034,23.015L22.034,28.802Z\" />\n        </g>\n        <g transform=\"matrix(1.50139,1.35303e-16,1.83867e-16,-1.10483,-24.8768,44.5033)\">\n            <path d=\"M22.161,28.786C22.706,28.736 23.089,28.64 23.626,28.496C28.793,27.112 31.864,21.792 30.48,16.625C30.189,15.54 29.715,14.525 29.088,13.619L31.915,8.722C33.663,10.535 34.942,12.776 35.606,15.251C37.748,23.248 32.996,31.48 24.999,33.622C24.011,33.887 23.167,34.048 22.161,34.107L22.161,40L13,31.5L22.161,23L22.161,28.786Z\" />\n        </g>\n    </g>\n</svg>\n`, Yn = `<?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 40 40\" 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(-0.620305,0,0,0.839332,25.2077,0.462208)\">\n        <g transform=\"matrix(-1.61211,0,0,1.25099,40.6376,0.938594)\">\n            <path d=\"M26,18.498C26,16.566 24.356,15 22.327,15C17.811,15 10.189,15 5.673,15C3.644,15 2,16.566 2,18.498C2,22.151 2,27.849 2,31.502C2,33.434 3.644,35 5.673,35C10.189,35 17.811,35 22.327,35C24.356,35 26,33.434 26,31.502C26,27.849 26,22.151 26,18.498Z\" />\n        </g>\n        <path d=\"M-2.889,42.341L-16.002,42.341C-17.664,42.341 -19.01,41.345 -19.01,40.117L-19.01,11.346L-15.787,13.728L-15.787,36.879C-15.787,37.695 -15.348,38.478 -14.567,39.056C-13.785,39.633 -12.726,39.958 -11.621,39.958L-2.889,39.958L-2.889,42.341ZM30.962,18.512L30.962,8.485C30.962,7.669 30.523,6.886 29.741,6.308C28.96,5.731 27.9,5.406 26.795,5.406L-4.721,5.406L-7.945,3.024L31.181,3.024C32.842,3.024 34.189,4.019 34.189,5.247L34.189,18.512L30.962,18.512Z\" />\n        <g transform=\"matrix(-0.595969,-0.440448,-1.13993,0.842464,17.4661,11.4472)\">\n            <path d=\"M18.389,14.006L18.389,18L5,11L18.389,4L18.389,7.994L36,7.994L36,14.006L18.389,14.006Z\" />\n        </g>\n    </g>\n</svg>\n`;\nlet O = 0;\nconst _t = [\n  // First layout: side by side\n  {\n    id: \"side-by-side\",\n    videos: [\n      {\n        content: null,\n        rect: [\n          { aspectRatio: \"16/9\", width: 560, height: 315, top: 218, left: 712 },\n          { aspectRatio: \"16/10\", width: 560, height: 350, top: 206, left: 712 },\n          { aspectRatio: \"4/3\", width: 560, height: 420, top: 173, left: 712 },\n          { aspectRatio: \"5/3\", width: 560, height: 336, top: 206, left: 712 },\n          { aspectRatio: \"5/4\", width: 560, height: 448, top: 160, left: 712 }\n        ],\n        visible: !0,\n        layer: 1\n      },\n      {\n        content: null,\n        rect: [\n          { aspectRatio: \"16/9\", width: 688, height: 387, top: 166, left: 10 },\n          { aspectRatio: \"16/10\", width: 688, height: 430, top: 148, left: 10 },\n          { aspectRatio: \"4/3\", width: 688, height: 516, top: 111, left: 10 },\n          { aspectRatio: \"5/3\", width: 690, height: 414, top: 154, left: 10 },\n          { aspectRatio: \"5/4\", width: 690, height: 552, top: 96, left: 10 }\n        ],\n        visible: !0,\n        layer: \"1\"\n      }\n    ],\n    buttons: []\n  },\n  // Second layout: PIP left\n  {\n    id: \"pip-left\",\n    videos: [\n      {\n        content: null,\n        rect: [\n          { aspectRatio: \"16/9\", left: 0, top: 0, width: 1280, height: 720 },\n          { aspectRatio: \"16/10\", left: 64, top: 0, width: 1152, height: 720 },\n          { aspectRatio: \"5/3\", left: 40, top: 0, width: 1200, height: 720 },\n          { aspectRatio: \"5/4\", left: 190, top: 0, width: 900, height: 720 },\n          { aspectRatio: \"4/3\", left: 160, top: 0, width: 960, height: 720 }\n        ],\n        visible: !0,\n        layer: 1\n      },\n      {\n        content: null,\n        rect: [\n          { aspectRatio: \"16/9\", left: 50, top: 470, width: 350, height: 197 },\n          { aspectRatio: \"16/10\", left: 50, top: 448, width: 350, height: 219 },\n          { aspectRatio: \"5/3\", left: 50, top: 457, width: 350, height: 210 },\n          { aspectRatio: \"5/4\", left: 50, top: 387, width: 350, height: 280 },\n          { aspectRatio: \"4/3\", left: 50, top: 404, width: 350, height: 262 }\n        ],\n        visible: !0,\n        layer: 2\n      }\n    ],\n    buttons: []\n  },\n  // Third layout: PIP right\n  {\n    id: \"pip-right\",\n    videos: [\n      {\n        content: null,\n        rect: [\n          { aspectRatio: \"16/9\", left: 0, top: 0, width: 1280, height: 720 },\n          { aspectRatio: \"16/10\", left: 64, top: 0, width: 1152, height: 720 },\n          { aspectRatio: \"5/3\", left: 40, top: 0, width: 1200, height: 720 },\n          { aspectRatio: \"5/4\", left: 190, top: 0, width: 900, height: 720 },\n          { aspectRatio: \"4/3\", left: 160, top: 0, width: 960, height: 720 }\n        ],\n        visible: !0,\n        layer: 1\n      },\n      {\n        content: null,\n        rect: [\n          { aspectRatio: \"16/9\", left: 880, top: 470, width: 350, height: 197 },\n          { aspectRatio: \"16/10\", left: 880, top: 448, width: 350, height: 219 },\n          { aspectRatio: \"5/3\", left: 880, top: 457, width: 350, height: 210 },\n          { aspectRatio: \"5/4\", left: 880, top: 387, width: 350, height: 280 },\n          { aspectRatio: \"4/3\", left: 880, top: 404, width: 350, height: 262 }\n        ],\n        visible: !0,\n        layer: 2\n      }\n    ],\n    buttons: []\n  }\n];\nfunction Kn(i) {\n  return O = (O + 1) % _t.length, vt(i);\n}\nfunction fe(i, e) {\n  return O = e < _t.length ? e : O, vt(i);\n}\nfunction vt(i) {\n  let e = JSON.parse(JSON.stringify(_t[O]));\n  return e.videos[0].content = i[0], e.videos[1].content = i[1], e;\n}\nclass Jn extends me {\n  getPluginModuleInstance() {\n    return K.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.dualVideo\";\n  }\n  get identifier() {\n    return \"dual-video\";\n  }\n  async load() {\n    let e = Z(\"dualVideoLayoutIndex\");\n    e !== \"\" && (O = Number(e)), this.player.log.debug(\"Dual video layout loaded\");\n  }\n  getValidStreams(e) {\n    return super.getValidStreams(e).filter((t) => t.length === 2);\n  }\n  switchContent() {\n    const e = this._currentContent[0], t = this._currentContent[1];\n    this._currentContent[0] = t, this._currentContent[1] = e, this.player.videoContainer.updateLayout();\n  }\n  async switchMinimized() {\n    Kn(this._currentContent), await this.player.videoContainer.updateLayout();\n  }\n  async minimizeVideo(e) {\n    let t = !0;\n    if (e === this._currentContent[0]) {\n      const n = this._currentContent[0], s = this._currentContent[1];\n      this._currentContent[0] = s, this._currentContent[1] = n, t = !1;\n    }\n    O === 1 && t ? fe(this._currentContent, 2) : fe(this._currentContent, 1), await this.player.videoContainer.updateLayout();\n  }\n  async maximizeVideo(e) {\n    let t = !0;\n    if (e === this._currentContent[1]) {\n      const n = this._currentContent[0], s = this._currentContent[1];\n      this._currentContent[0] = s, this._currentContent[1] = n, t = !1;\n    }\n    O === 1 && t ? fe(this._currentContent, 2) : fe(this._currentContent, 1), await this.player.videoContainer.updateLayout();\n  }\n  async setSideBySide() {\n    fe(this._currentContent, 0), await this.player.videoContainer.updateLayout();\n  }\n  get minimizedContent() {\n    return O === 0 ? \"\" : this._currentContent[1];\n  }\n  async closeVideo(e) {\n    const n = this.player.videoContainer.validContentIds.filter((s) => s.indexOf(\"-\") === -1).find((s) => s != e);\n    await this.player.videoContainer.setLayout(n);\n  }\n  getVideoCanvasButtons(e, t, n, s) {\n    if (e.id === \"side-by-side\")\n      return [\n        // Swap\n        {\n          icon: this.player.getCustomPluginIcon(this.name, \"iconRotate\") || yi,\n          position: S.LEFT,\n          title: this.player.translate(\"Swap position of the videos\"),\n          ariaLabel: this.player.translate(\"Swap position of the videos\"),\n          name: this.name + \":iconRotate\",\n          click: async () => {\n            await this.switchContent();\n          }\n        },\n        // Minimize\n        {\n          icon: this.player.getCustomPluginIcon(this.name, \"iconMaximize\") || Ne,\n          position: S.LEFT,\n          title: this.player.translate(\"Maximize video\"),\n          ariaLabel: this.player.translate(\"Maximize video\"),\n          name: this.name + \":iconMaximize\",\n          click: async () => {\n            await this.maximizeVideo(t);\n          }\n        },\n        // Close\n        {\n          icon: this.player.getCustomPluginIcon(this.name, \"iconClose\") || ve,\n          position: S.RIGHT,\n          title: this.player.translate(\"Close video\"),\n          ariaLabel: this.player.translate(\"Close video\"),\n          name: this.name + \":iconClose\",\n          click: async () => {\n            await this.closeVideo(t);\n          }\n        }\n      ];\n    {\n      const a = [];\n      return t === this.minimizedContent ? (a.push({\n        icon: this.player.getCustomPluginIcon(this.name, \"iconMaximize\") || Ne,\n        position: S.LEFT,\n        title: this.player.translate(\"Maximize video\"),\n        ariaLabel: this.player.translate(\"Maximize video\"),\n        name: this.name + \":iconMaximize\",\n        click: async () => {\n          await this.switchContent();\n        }\n      }), a.push({\n        icon: this.player.getCustomPluginIcon(this.name, \"iconSwitchSide\") || yt,\n        position: S.LEFT,\n        title: this.player.translate(\"Place the video on the other side of the screen\"),\n        ariaLabel: this.player.translate(\"Place the video on the other side of the screen\"),\n        name: this.name + \":iconSwitchSide\",\n        click: async () => {\n          await this.minimizeVideo(t);\n        }\n      }), a.push({\n        icon: this.player.getCustomPluginIcon(this.name, \"iconClose\") || ve,\n        position: S.RIGHT,\n        title: this.player.translate(\"Close video\"),\n        ariaLabel: this.player.translate(\"Close video\"),\n        name: this.name + \":iconClose\",\n        click: async () => {\n          await this.closeVideo(t);\n        }\n      })) : (a.push({\n        icon: this.player.getCustomPluginIcon(this.name, \"iconMinimize\") || Yn,\n        position: S.LEFT,\n        title: this.player.translate(\"Minimize video\"),\n        ariaLabel: this.player.translate(\"Minimize video\"),\n        name: this.name + \":iconMinimize\",\n        click: async () => {\n          await this.switchContent();\n        }\n      }), a.push({\n        icon: this.player.getCustomPluginIcon(this.name, \"iconSideBySide\") || ke,\n        position: S.LEFT,\n        title: this.player.translate(\"Put the videos side by side\"),\n        ariaLabel: this.player.translate(\"Put the videos side by side\"),\n        name: this.name + \":iconSideBySide\",\n        click: async () => {\n          await this.setSideBySide();\n        }\n      }), a.push({\n        icon: this.player.getCustomPluginIcon(this.name, \"iconClose\") || ve,\n        position: S.RIGHT,\n        title: this.player.translate(\"Close video\"),\n        ariaLabel: this.player.translate(\"Close video\"),\n        name: this.name + \":iconClose\",\n        click: async () => {\n          await this.closeVideo(t);\n        }\n      })), a;\n    }\n  }\n  getLayoutStructure(e, t) {\n    if (!this._currentContent || this._currentContentId !== t) {\n      const { content: a } = this.validContent.find((l) => l.id === t);\n      this._currentContent = a, this._currentContentId = t;\n      const r = Z(\"dualVideoLayoutContent0\"), o = Z(\"dualVideoLayoutContent1\");\n      r !== \"\" && o !== \"\" && this._currentContent.indexOf(r) !== -1 && this._currentContent.indexOf(o) !== -1 && (this._currentContent[0] = r, this._currentContent[1] = o);\n    }\n    const n = vt(this._currentContent), s = {\n      id: n.id,\n      player: this.player,\n      name: { es: \"Dos streams con posición dinámica\" },\n      hidden: !1,\n      videos: n.videos,\n      buttons: []\n    };\n    return ne(\"dualVideoLayoutIndex\", O), ne(\"dualVideoLayoutContent0\", this._currentContent[0]), ne(\"dualVideoLayoutContent1\", this._currentContent[1]), s;\n  }\n}\nconst Nt = {\n  id: \"pip-left\",\n  name: { es: \"Dos streams imagen dentro de imagen\" },\n  hidden: !1,\n  videos: [\n    {\n      content: null,\n      rect: [\n        { aspectRatio: \"16/9\", left: 0, top: 0, width: 1280, height: 720 },\n        { aspectRatio: \"16/10\", left: 64, top: 0, width: 1152, height: 720 },\n        { aspectRatio: \"5/3\", left: 40, top: 0, width: 1200, height: 720 },\n        { aspectRatio: \"5/4\", left: 190, top: 0, width: 900, height: 720 },\n        { aspectRatio: \"4/3\", left: 160, top: 0, width: 960, height: 720 },\n        { aspectRatio: \"9/16\", left: 617, top: 17, width: 386, height: 687 }\n      ],\n      visible: !0,\n      layer: 1\n    },\n    {\n      content: null,\n      rect: [\n        { aspectRatio: \"16/9\", left: 50, top: 470, width: 350, height: 197 },\n        { aspectRatio: \"16/10\", left: 50, top: 448, width: 350, height: 219 },\n        { aspectRatio: \"5/3\", left: 50, top: 457, width: 350, height: 210 },\n        { aspectRatio: \"5/4\", left: 50, top: 387, width: 350, height: 280 },\n        { aspectRatio: \"4/3\", left: 50, top: 404, width: 350, height: 262 },\n        { aspectRatio: \"9/16\", left: 224, top: 301, width: 224, height: 400 }\n      ],\n      visible: !0,\n      layer: 2\n    }\n  ],\n  buttons: []\n}, Xn = {\n  id: \"pip-right\",\n  name: { es: \"Dos streams imagen dentro de imagen a la derecha\" },\n  hidden: !1,\n  videos: [\n    {\n      content: null,\n      rect: [\n        { aspectRatio: \"16/9\", left: 0, top: 0, width: 1280, height: 720 },\n        { aspectRatio: \"16/10\", left: 64, top: 0, width: 1152, height: 720 },\n        { aspectRatio: \"5/3\", left: 40, top: 0, width: 1200, height: 720 },\n        { aspectRatio: \"5/4\", left: 190, top: 0, width: 900, height: 720 },\n        { aspectRatio: \"4/3\", left: 160, top: 0, width: 960, height: 720 },\n        { aspectRatio: \"9/16\", left: 242, top: 17, width: 386, height: 687 }\n      ],\n      visible: !0,\n      layer: 1\n    },\n    {\n      content: null,\n      rect: [\n        { aspectRatio: \"16/9\", left: 880, top: 470, width: 350, height: 197 },\n        { aspectRatio: \"16/10\", left: 880, top: 448, width: 350, height: 219 },\n        { aspectRatio: \"5/3\", left: 880, top: 457, width: 350, height: 210 },\n        { aspectRatio: \"5/4\", left: 880, top: 387, width: 350, height: 280 },\n        { aspectRatio: \"4/3\", left: 880, top: 404, width: 350, height: 262 },\n        { aspectRatio: \"9/16\", left: 887, top: 304, width: 224, height: 400 }\n      ],\n      visible: !0,\n      layer: 2\n    }\n  ],\n  buttons: []\n};\nclass es extends me {\n  getPluginModuleInstance() {\n    return K.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.dualVideoPiP\";\n  }\n  get identifier() {\n    return \"dual-video-pip\";\n  }\n  async load() {\n    this._currentLayout = Nt, this.dualVideoContentIds = this.config.dualVideoContentIds || [];\n  }\n  getValidStreams(e) {\n    return super.getValidStreams(e).filter((t) => t.length === 2);\n  }\n  getVideoCanvasButtons(e, t, n, s) {\n    const a = this.player.getCustomPluginIcon(this.name, \"iconClose\") || ve, r = this.player.getCustomPluginIcon(this.name, \"iconSwitchSide\") || yt, o = this.player.getCustomPluginIcon(this.name, \"iconMaximize\") || Ne, l = this.player.getCustomPluginIcon(this.name, \"iconSideBySide\") || ke, u = [\n      {\n        icon: a,\n        position: S.RIGHT,\n        title: this.player.translate(\"Close video\"),\n        ariaLabel: this.player.translate(\"Close video\"),\n        name: this.name + \":iconClose\",\n        click: async () => {\n          const h = this.player.videoContainer.validContentIds.filter((g) => g.indexOf(\"-\") === -1).find((g) => g !== t);\n          await this.player.videoContainer.setLayout(h);\n        }\n      }\n    ];\n    return t === this._pipVideo ? (u.push({\n      icon: r,\n      position: S.LEFT,\n      title: this.player.translate(\"Switch side\"),\n      ariaLabel: this.player.translate(\"Switch side\"),\n      name: this.name + \":iconSwitchSide\",\n      click: async () => {\n        this.switchSide(), await this.player.videoContainer.updateLayout(this._fullVideo);\n      }\n    }), u.push({\n      icon: o,\n      position: S.LEFT,\n      title: this.player.translate(\"Maximize video\"),\n      ariaLabel: this.player.translate(\"Maximize video\"),\n      name: this.name + \":iconMaximize\",\n      click: async () => {\n        this.switchSources(), await this.player.videoContainer.updateLayout(this._fullVideo);\n      }\n    })) : this.dualVideoContentIds.length > 0 && u.push({\n      icon: l,\n      position: S.LEFT,\n      title: this.player.translate(\"Set side by side\"),\n      ariaLabel: this.player.translate(\"Set side by side\"),\n      name: this.name + \":iconSideBySide\",\n      click: async () => {\n        const f = this.player.videoContainer.validContentIds, h = this.dualVideoContentIds.find((g) => f.indexOf(g) !== -1);\n        h && this.player.videoContainer.setLayout(h);\n      }\n    }), u;\n  }\n  switchSide() {\n    this._currentLayout.id === \"pip-left\" ? this._currentLayout = Xn : this._currentLayout = Nt;\n  }\n  switchSources() {\n    const e = this._pipVideo;\n    this._pipVideo = this._fullVideo, this._fullVideo = e;\n  }\n  getLayoutStructure(e, t, n) {\n    const { content: s } = this.validContent.find((r) => r.id === t);\n    n && s.find((r) => r === n) ? (this._fullVideo = n, this._pipVideo = s.find((r) => r !== n)) : (!this._pipVideo || !this._fullVideo) && (this._pipVideo = s[0], this._fullVideo = s[1]);\n    const a = JSON.parse(JSON.stringify(this._currentLayout));\n    return a.player = this.player, a.videos[0].content = this._fullVideo, a.videos[1].content = this._pipVideo, a;\n  }\n}\nclass ts extends me {\n  getPluginModuleInstance() {\n    return K.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.singleVideo\";\n  }\n  get identifier() {\n    return \"single-video\";\n  }\n  async load() {\n    this.player.log.debug(\"Single video layout loaded\"), this.dualVideoContentIds = this.config.dualVideoContentIds || [\n      \"presenter-presentation-dynamic\",\n      \"presenter-2-presentation-dynamic\",\n      \"presenter-presenter-2-dynamic\",\n      \"presenter-presentation\",\n      \"presenter-2-presentation\",\n      \"presenter-presenter-2\"\n    ];\n  }\n  getValidStreams(e) {\n    return super.getValidStreams(e).filter((t) => t.length === 1);\n  }\n  getVideoCanvasButtons(e, t, n, s) {\n    return this._multiStream ? [\n      {\n        icon: this.player.getCustomPluginIcon(this.name, \"iconSideBySide\") || ke,\n        position: S.LEFT,\n        title: this.player.translate(\"Two videos 50%\"),\n        ariaLabel: this.player.translate(\"Two videos 50%\"),\n        name: this.name + \":iconSideBySide\",\n        click: () => {\n          const a = this.player.videoContainer.validContentIds, r = this.dualVideoContentIds.find((o) => a.indexOf(o) !== -1);\n          r && this.player.videoContainer.setLayout(r);\n        }\n      }\n    ] : [];\n  }\n  getLayoutStructure(e, t) {\n    const n = this.validContent.find((a) => a.id === t), s = {\n      player: this.player,\n      name: { es: \"One stream\" },\n      hidden: !1,\n      videos: [\n        {\n          content: n.content[0],\n          rect: [\n            { aspectRatio: \"1/1\", left: 280, top: 0, width: 720, height: 720 },\n            { aspectRatio: \"6/5\", left: 208, top: 0, width: 864, height: 720 },\n            { aspectRatio: \"5/4\", left: 190, top: 0, width: 900, height: 720 },\n            { aspectRatio: \"4/3\", left: 160, top: 0, width: 960, height: 720 },\n            { aspectRatio: \"11/8\", left: 145, top: 0, width: 990, height: 720 },\n            { aspectRatio: \"1.41/1\", left: 132, top: 0, width: 1015, height: 720 },\n            { aspectRatio: \"1.43/1\", left: 125, top: 0, width: 1029, height: 720 },\n            { aspectRatio: \"3/2\", left: 100, top: 0, width: 1080, height: 720 },\n            { aspectRatio: \"16/10\", left: 64, top: 0, width: 1152, height: 720 },\n            { aspectRatio: \"5/3\", left: 40, top: 0, width: 1200, height: 720 },\n            { aspectRatio: \"16/9\", left: 0, top: 0, width: 1280, height: 720 },\n            { aspectRatio: \"1.85/1\", left: 0, top: 14, width: 1280, height: 692 },\n            { aspectRatio: \"2.35/1\", left: 0, top: 87, width: 1280, height: 544 },\n            { aspectRatio: \"2.41/1\", left: 0, top: 94, width: 1280, height: 531 },\n            { aspectRatio: \"2.76/1\", left: 0, top: 128, width: 1280, height: 463 }\n          ],\n          visible: !0,\n          layer: 1\n        }\n      ],\n      background: { content: \"slide_professor_paella.jpg\", zIndex: 5, rect: { left: 0, top: 0, width: 1280, height: 720 }, visible: !0, layer: 0 },\n      logos: [{ content: \"paella_logo.png\", zIndex: 5, rect: { top: 10, left: 10, width: 49, height: 42 } }],\n      buttons: [],\n      onApply: function() {\n      }\n    };\n    return e.length > 1 && (this._multiStream = !0), s;\n  }\n}\nclass is extends me {\n  getPluginModuleInstance() {\n    return K.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.singleVideoDynamic\";\n  }\n  get layoutType() {\n    return \"dynamic\";\n  }\n  async load() {\n    this.player.log.debug(\"Single video dynamic layout loaded\"), this.dualVideoContentIds = this.config.dualVideoContentIds || [\n      \"presenter-presentation-dynamic\",\n      \"presenter-2-presentation-dynamic\",\n      \"presenter-presenter-2-dynamic\",\n      \"presenter-presentation\",\n      \"presenter-2-presentation\",\n      \"presenter-presenter-2\"\n    ];\n  }\n  getVideoCanvasButtons(e, t, n, s) {\n    const a = this.player.getCustomPluginIcon(this.name, \"iconSideBySide\") || ke, r = [];\n    return this._multiStream && r.push({\n      icon: a,\n      position: S.LEFT,\n      title: this.player.translate(\"Dual stream 50%\"),\n      ariaLabel: this.player.translate(\"Dual stream 50%\"),\n      name: this.name + \":iconSideBySide\",\n      click: async () => {\n        const o = this.player.videoContainer.validContentIds, l = this.dualVideoContentIds.find((u) => o.indexOf(u) !== -1);\n        l && this.player.videoContainer.setLayout(l);\n      }\n    }), r;\n  }\n  getLayoutStructure(e, t, n) {\n    e.length > 1 && (this._multiStream = !0);\n    const { content: s } = this.validContent.find((a) => a.id === t);\n    return this._currentContent = s.map((a) => ({\n      id: a,\n      size: 50\n    })), {\n      id: \"single-dynamic\",\n      videos: [\n        {\n          content: this._currentContent[0].id,\n          visible: !0,\n          size: this._currentContent[0].size\n        }\n      ]\n    };\n  }\n}\nconst ns = {\n  videos: [\n    {\n      content: {},\n      rect: [\n        { aspectRatio: \"16/9\", left: 239, top: 17, width: 803, height: 451 }\n      ],\n      visible: !0,\n      layer: 1\n    },\n    {\n      content: {},\n      rect: [\n        { aspectRatio: \"16/9\", left: 44, top: 482, width: 389, height: 218 }\n      ],\n      visible: !0,\n      layer: 1\n    },\n    {\n      content: {},\n      rect: [\n        { aspectRatio: \"16/9\", left: 847, top: 482, width: 389, height: 218 }\n      ],\n      visible: !0,\n      layer: 1\n    }\n  ],\n  buttons: [\n    {\n      rect: { left: 618, top: 495, width: 45, height: 45 },\n      onClick: function(i) {\n        this.rotate();\n      },\n      label: \"Rotate\",\n      icon: \"icon_rotate.svg\",\n      layer: 2\n    }\n  ]\n};\nfunction ss(i) {\n  let e = JSON.parse(JSON.stringify(ns));\n  return e.videos[0].content = i[0], e.videos[1].content = i[1], e.videos[2].content = i[2], e;\n}\nclass as extends me {\n  getPluginModuleInstance() {\n    return K.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.tripleVideo\";\n  }\n  get identifier() {\n    return \"triple-video\";\n  }\n  async load() {\n    this.player.log.debug(\"Triple video layout loaded\");\n  }\n  getValidStreams(e) {\n    return super.getValidStreams(e).filter((t) => t.length === 3);\n  }\n  switchContent() {\n    const e = this._currentContent[0], t = this._currentContent[1], n = this._currentContent[2];\n    this._currentContent[0] = n, this._currentContent[1] = e, this._currentContent[2] = t, this.player.videoContainer.updateLayout();\n  }\n  getLayoutStructure(e, t) {\n    if (!this._currentContent || this._currentContentId !== t) {\n      this._currentContentId = t;\n      const { content: a } = this.validContent.find((r) => r.id === t);\n      this._currentContent = a;\n    }\n    const n = ss(this._currentContent);\n    return {\n      player: this.player,\n      name: { es: \"Three streams with dynamic position\" },\n      hidden: !1,\n      videos: n.videos,\n      buttons: [\n        {\n          rect: n.buttons[0].rect,\n          onClick: () => {\n            this.switchContent();\n          },\n          label: \"Switch\",\n          icon: yi,\n          layer: 2,\n          ariaLabel: \"Swap the position of the videos\",\n          title: \"Swap the position of the videos\"\n        }\n      ]\n    };\n  }\n}\nclass rs extends mi {\n  constructor(e, t) {\n    super(\"div\", e, t), this.element.classList.add(\"image-canvas\");\n  }\n  async loadCanvas(e) {\n    e.element.style.width = \"100%\", e.element.style.height = \"100%\";\n  }\n}\nclass os extends fi {\n  get name() {\n    return super.name || \"es.upv.paella.audioCanvas\";\n  }\n  get canvasType() {\n    return \"audio\";\n  }\n  getCanvasInstance(e) {\n    return new rs(this.player, e);\n  }\n}\nclass ls extends mi {\n  constructor(e, t) {\n    super(\"div\", e, t);\n  }\n  async loadCanvas(e) {\n    e.element.style.width = \"100%\", e.element.style.height = \"100%\", e.element.style.position = \"absolute\", e.element.style.top = \"0\", e.element.style.left = \"0\";\n  }\n}\nclass cs extends fi {\n  get name() {\n    return super.name || \"es.upv.paella.videoCanvas\";\n  }\n  get canvasType() {\n    return \"video\";\n  }\n  async isCompatible(e) {\n    return !Array.isArray(e.canvas) || e.canvas.length === 0 ? !0 : await super.isCompatible(e);\n  }\n  getCanvasInstance(e) {\n    return new ls(this.player, e);\n  }\n}\nclass _i extends he {\n  get type() {\n    return \"data\";\n  }\n  get context() {\n    return this.config.context || [];\n  }\n  async read() {\n    throw Error(`DataPlugin.read() not implemented in data plugin '${this.name}'`);\n  }\n  async write() {\n    throw Error(`DataPlugin.write() not implemented in data plugin '${this.name}'`);\n  }\n  async remove() {\n    throw Error(`DataPlugin.remove() not implemented in data plugin '${this.name}'`);\n  }\n}\nclass us extends de {\n  constructor(e) {\n    super(e), this._dataPlugins = {}, $(this.player, \"data\", async (t) => {\n      var n;\n      (n = t.context) == null || n.forEach((s) => {\n        this._dataPlugins[s] = this._dataPlugins[s] || [], this._dataPlugins[s].push(t);\n      });\n    });\n  }\n  getDataPlugin(e) {\n    let t = this._dataPlugins[e] && this._dataPlugins[e].length > 0 && this._dataPlugins[e][0];\n    if (t || (t = this._dataPlugins.default && this._dataPlugins.default.length > 0 && this._dataPlugins.default[0]), !t)\n      throw Error(`No data plugin found for context '${e}'`);\n    return t;\n  }\n  getDataPlugins(e) {\n    let t = this._dataPlugins[e] && this._dataPlugins[e].length > 0 && this._dataPlugins[e];\n    if (t || (t = this._dataPlugins.default && this._dataPlugins.default.length > 0 && this._dataPlugins.default), !t)\n      throw Error(`No data plugin found for context '${e}'`);\n    return t;\n  }\n  async read(e, t) {\n    return await this.getDataPlugin(e).read(e, t);\n  }\n  async write(e, t, n) {\n    const s = this.getDataPlugins(e);\n    if (Array.isArray(s)) {\n      let a = null;\n      for (let r = 0; r < s.length; ++r)\n        a = await s[r].write(e, t, n);\n      return a;\n    } else {\n      if (s)\n        return await s.write(e, t, n);\n      this.player.log.warn(`No such data plugin found for context '${e}'`);\n    }\n  }\n  async remove(e, t) {\n    const n = this.getDataPlugins(e);\n    if (n.length > 1) {\n      let s = null;\n      for (let a = 0; a < n.length; ++a)\n        s = await n[a].remove(e, t);\n      return s;\n    } else\n      return await n.remove(e, t);\n  }\n}\nlet We = null;\nclass $e extends Fe {\n  static Get() {\n    return We || (We = new $e()), We;\n  }\n  get moduleName() {\n    return \"paella-core default data plugins\";\n  }\n  get moduleVersion() {\n    return Ie.version;\n  }\n}\nclass ds extends _i {\n  getPluginModuleInstance() {\n    return $e.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.cookieDataPlugin\";\n  }\n  serializeKey(e, t) {\n    return typeof t == \"object\" && (t = JSON.stringify(t)), `${e}|${t}`;\n  }\n  async read(e, t) {\n    const n = this.serializeKey(e, t);\n    let s = Z(n);\n    try {\n      s = JSON.parse(s);\n    } catch {\n    }\n    return this.player.log.debug(`CookieDataPlugin.read: ${n}`), s;\n  }\n  async write(e, t, n) {\n    const s = this.serializeKey(e, t);\n    if (n && typeof n == \"object\")\n      try {\n        n = JSON.stringify(n);\n      } catch {\n        this.player.log.warn(`CookieDataPlugin.write: ${s}: invalid data object.`), n = \"\";\n      }\n    ne(s, n), this.player.log.debug(`CookieDataPlugin.write: ${s}`);\n  }\n  async remove(e, t) {\n    const n = this.serializeKey(e, t);\n    ne(n, \"\"), this.player.log.debug(`CookieDataPlugin.remove: ${n}`);\n  }\n}\nclass hs extends _i {\n  getPluginModuleInstance() {\n    return $e.Get();\n  }\n  get name() {\n    return super.name || \"es.upv.paella.localStorageDataPlugin\";\n  }\n  serializeKey(e, t) {\n    return typeof t == \"object\" && (t = JSON.stringify(t)), `${e}|${t}`;\n  }\n  async read(e, t) {\n    const n = this.serializeKey(e, t);\n    let s = localStorage.getItem(n);\n    try {\n      s = JSON.parse(s);\n    } catch {\n    }\n    return this.player.log.debug(`LocalStorageDataPlugin.read: ${n}`), s;\n  }\n  async write(e, t, n) {\n    const s = this.serializeKey(e, t);\n    if (n && typeof n == \"object\")\n      try {\n        n = JSON.stringify(n);\n      } catch {\n        this.player.log.warn(`LocalStorageDataPlugin.write: ${s}: invalid data object.`), n = \"\";\n      }\n    localStorage.setItem(s, n), this.player.log.debug(`LocalStorageDataPlugin.write: ${s}`);\n  }\n  async remove(e, t) {\n    const n = this.serializeKey(e, t);\n    localStorage.setItem(n, \"\"), this.player.log.debug(`LocalStorageDataPlugin.remove: ${n}`);\n  }\n}\nconst ps = [\n  {\n    plugin: mn,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: fn,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: Cn,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: Ln,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: Tn,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: Rn,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: On,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: $n,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: Vt,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: Jn,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: es,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: ts,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: is,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: Vt,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: as,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: os,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: cs,\n    config: {\n      enabled: !1\n    }\n  },\n  {\n    plugin: ds,\n    config: {\n      enabled: !1,\n      context: [\"default\"]\n    }\n  },\n  {\n    plugin: hs,\n    config: {\n      enable: !0,\n      context: [\"default\"]\n    }\n  }\n];\nclass gs extends ft {\n  constructor() {\n    super(...arguments), this._refreshContent = !0;\n  }\n  set refreshContent(e) {\n    this._refreshContent = e;\n  }\n  get refreshContent() {\n    return this._refreshContent;\n  }\n  get closeParentPopUp() {\n    return this.config.closeParentPopUp || this.getCloseParentPopUp();\n  }\n  getCloseParentPopUp() {\n    return !1;\n  }\n  async action(e, t) {\n    super.action(e, t), this.parentPopUp = t, await this.showPopUp();\n  }\n  get parentPopUp() {\n    return this._parentPopUp;\n  }\n  set parentPopUp(e) {\n    this._parentPopUp = e;\n  }\n  get popUp() {\n    return this._popUp;\n  }\n  get menuTitle() {\n    return this.config.menuTitle || null;\n  }\n  get moveable() {\n    return this.config.moveable ?? !1;\n  }\n  get resizeable() {\n    return this.config.resizeable ?? !1;\n  }\n  get customPopUpClass() {\n    return this.config.customPopUpClass ?? \"\";\n  }\n  get closeActions() {\n    var n, s;\n    const e = ((n = this.config.closeActions) == null ? void 0 : n.clickOutside) ?? !0, t = ((s = this.config.closeActions) == null ? void 0 : s.closeButton) ?? !1;\n    return {\n      clickOutside: e,\n      closeButton: t\n    };\n  }\n  get currentContent() {\n    return this._currentContent;\n  }\n  async getContent() {\n    return b(\"<p>Pop Up Button Plugin Content</p>\");\n  }\n  async checkRefreshContent() {\n    if (this.refreshContent) {\n      const e = await this.getContent();\n      this._currentContent.innerHTML = \"\", Array.from(e.children).forEach((n) => this._currentContent.appendChild(n));\n    }\n  }\n  get popUpType() {\n    return this.config.popUpType || \"modal\";\n  }\n  hidePopUp() {\n    this.player.playbackBar.popUp.isHidden || this.player.playbackBar.popUp.hide();\n  }\n  async showPopUp() {\n    this._keyEventHandler || (this._keyEventHandler = (t) => {\n      t.key === \"Escape\" && this.hidePopUp();\n    }, this.button.addEventListener(\"keydown\", this._keyEventHandler));\n    const e = this.player.playbackBar.popUp;\n    if (e.isHidden || this._contentId !== e.currentContentId) {\n      const t = await this.getContent();\n      this._currentContent = t, this._contentId = e.show({\n        title: this.menuTitle || this.description,\n        content: t,\n        attachRight: this.popUpType === \"timeline\" || this.side === \"right\",\n        attachLeft: this.popUpType === \"timeline\" || this.side === \"left\",\n        parent: this.parentPopUp\n      });\n    } else\n      e.hide();\n  }\n}\nconst ms = (i) => i ? `<span class=\"menu-title\">${i}</span>` : \"\", fs = (i) => i ? `<i class=\"menu-icon\">${i}</i>` : \"\", ys = (i) => i ? `aria-label=\"${i}\"` : \"\", _s = (i) => i ? `<span class=\"state-text\">${i}</span>` : \"\", vs = (i) => i ? `<i class=\"state-icon\">${i}</i>` : \"\", ws = (i, e) => i || e ? `<span class=\"button-state\">${_s(i)}${vs(e)}</span>` : \"\";\nfunction Cs({ itemData: i, buttonType: e, container: t, allItems: n, menuName: s, selectedItems: a, itemPlugin: r }) {\n  const { id: o = 0, title: l = null, icon: u = null, iconText: f = null, showTitle: h = !0, stateText: g = null, stateIcon: L = null } = i, y = this, v = document.createElement(\"li\"), P = a[o] ?? !1, c = b(`\n\t\t<button class=\"menu-button-item${P ? \" selected\" : \"\"}\" ${ys(l)} data-id=\"${o}\"\" id=\"${y.name}_menuItem_${o}\">\n\t\t\t${fs(u)}\n\t\t\t${h ? ms(l) : \"\"}\n\t\t\t${g || L ? ws(g, L) : \"\"}\n\t\t</button>\n\t`);\n  return r && (r._button = c), c.addEventListener(\"keydown\", (p) => {\n    var w;\n    const C = () => {\n      p.stopPropagation(), p.preventDefault();\n    };\n    if (p.key === \"ArrowUp\") {\n      const T = c.dataPrev;\n      T == null || T.focus(), C();\n    } else if (p.key === \"ArrowDown\") {\n      const T = c.dataNext;\n      T == null || T.focus(), C();\n    } else if (p.key === \"Tab\") {\n      const T = p.shiftKey ? p.target.dataPrev : p.target.dataNext;\n      T == null || T.focus(), C();\n    } else p.key === \"Escape\" && (this.player.playbackBar.popUp.pop() ? (w = y.button) == null || w.focus() : this.focus(), C());\n  }), c.addEventListener(\"click\", async (p) => {\n    if (e === \"check\") {\n      const C = n.find((w) => w.id === o);\n      a[o] = !a[o], y.itemSelected(C, n);\n    } else if (e === \"radio\") {\n      a[o] = !0;\n      let C = null;\n      n.forEach((w) => {\n        w.id === o ? C = w : a[w.id] = !1;\n      }), y.itemSelected(C, n);\n    } else {\n      const C = n.find((w) => w.id === o);\n      y.itemSelected(C, n);\n    }\n    await y.checkRefreshContent(), p.stopPropagation(), y.closeOnSelect && (y.closeMenu(), ut(y.player));\n  }), v.appendChild(c), t.appendChild(v), v;\n}\nclass bs extends gs {\n  get closeOnSelect() {\n    return this.config.closeOnSelect === void 0 && (this.buttonType !== \"check\" ? this.config.closeOnSelect = !0 : this.config.closeOnSelect = !1), this.config.closeOnSelect;\n  }\n  setSelected(e, t) {\n    this._selectedItems && (this._selectedItems[e] = t);\n  }\n  async getContent() {\n    var r, o;\n    const e = (r = document.activeElement) == null ? void 0 : r.id, t = b(\"<menu></menu>\");\n    this._content = t;\n    const n = await this.getMenu();\n    this._menuItems = n, this._selectedItems || (this._selectedItems = {}, this._menuItems.forEach((l) => {\n      l.selected !== void 0 && l.selected !== null && (this._selectedItems[l.id] = l.selected);\n    }));\n    const s = self.crypto.randomUUID(), a = n.map((l) => Cs.apply(this, [{\n      itemData: l,\n      buttonType: typeof this.buttonType == \"function\" ? this.buttonType() : this.buttonType,\n      container: t,\n      allItems: n,\n      menuName: s,\n      selectedItems: this._selectedItems,\n      itemPlugin: l.plugin\n    }]));\n    return a.forEach((l, u, f) => {\n      const h = l.querySelector(\"button\");\n      let g = f[u + 1], L = f[u - 1];\n      u === f.length - 1 && (g = f[0]), u === 0 && (L = f[f.length - 1]), h.dataNext = g == null ? void 0 : g.querySelector(\"button\"), h.dataPrev = L == null ? void 0 : L.querySelector(\"button\");\n    }), this._firstItem = (o = a[0]) == null ? void 0 : o.querySelector(\"button\"), e && setTimeout(() => {\n      var l;\n      (l = document.getElementById(e)) == null || l.focus();\n    }, 10), t;\n  }\n  get menuTitle() {\n    return this.config.menuTitle || null;\n  }\n  async getMenu() {\n    return [\n      { id: 0, title: \"Option 1\" },\n      { id: 1, title: \"Option 2\" },\n      { id: 2, title: \"Option 3\" },\n      { id: 3, title: \"Option 4\" },\n      { id: 4, title: \"Option 5\" }\n    ];\n  }\n  // Returns the menuItems with the current menu state\n  get menuItems() {\n    return this._menuItems;\n  }\n  // If showTitles is false, then the 'title' attribute of the menu\n  // items is used only as aria-label.\n  // If the menu item has no icon, then the `showTitles` property is ignored\n  get showTitles() {\n    return !0;\n  }\n  get buttonType() {\n    return \"radio\";\n  }\n  itemSelected(e, t) {\n    this.player.log.warn(`MenuButtonPlugin (${this.name}): itemSelected() function not implemented.`);\n  }\n  closeMenu() {\n    this.player.playbackBar.popUp.hide();\n  }\n  async showPopUp() {\n    this.refreshContent = !0, await super.showPopUp(), this.player.containsFocus && this._firstItem && this._firstItem.focus();\n  }\n}\nclass Ls extends bs {\n  get closeOnSelect() {\n    return this.config.closeOnSelect ?? !1;\n  }\n  async load() {\n    this._iconPath && (this.icon = await zt(this._iconPath));\n  }\n  async getContent() {\n    return this._buttonPlugins || (this._buttonPlugins = [], await $(this.player, \"button\", async (e) => {\n      this.player.log.debug(`Load button plugins into \"${this.groupName}\" container`), this._buttonPlugins.push(e), e.setObserver(this);\n    }, async (e) => e.parentContainer === this.groupName ? await e.isEnabled() : !1)), await super.getContent();\n  }\n  onIconChanged(e, t, n) {\n  }\n  onTitleChanged(e, t, n) {\n  }\n  onStateChanged(e, t, n, s, a) {\n  }\n  get groupName() {\n    var e;\n    return ((e = this.config) == null ? void 0 : e.groupName) || \"buttonGroup\";\n  }\n  get popUpType() {\n    return \"no-modal\";\n  }\n  getClosePopUps() {\n    return !1;\n  }\n  buttonType() {\n    return \"button\";\n  }\n  async getMenu() {\n    return this._buttonPlugins.map((e) => ({\n      id: e.name,\n      title: e.title || e.description,\n      icon: e.menuIcon !== \"\" ? e.menuIcon : e.icon,\n      stateText: e.stateText,\n      stateIcon: e.stateIcon,\n      plugin: e,\n      iconText: e.title\n    }));\n  }\n  itemSelected(e, t) {\n    const n = this._buttonPlugins.find((s) => s.name === e.id);\n    if (n) {\n      const s = new Event(\"menuitemselected\");\n      n.action(s, this.currentContent);\n    }\n  }\n  async showPopUp() {\n    var e;\n    await super.showPopUp(), setTimeout(() => {\n      this._firstItem && this._firstItem.focus();\n    }, 50), (e = this.buttons) == null || e.forEach((t) => {\n      t.style.display === \"none\" ? this.hideButtonContainer(t) : this.showButtonContainer(t);\n    });\n  }\n  get buttons() {\n    return this._content && Array.from(this._content.getElementsByClassName(\"button-plugin\"));\n  }\n  hideButtonContainer(e) {\n    var n;\n    const t = (n = e.parentNode) == null ? void 0 : n.parentNode;\n    t && (t.style.display = \"none\");\n  }\n  showButtonContainer(e) {\n    var n;\n    const t = (n = e.parentNode) == null ? void 0 : n.parentNode;\n    t && (t.style.display = null);\n  }\n}\nconst wt = (i, e, t, n = {}) => {\n  const s = new i(e, t);\n  return t = s.name || t, t ? (e.config.plugins && e.config.plugins[t] && we(n, e.config.plugins[t], !1), s._config = n, s) : (e.log.warn(`The instance of the ${i.name} plugin cannot be created because it is being loaded explicitly and does not have the name property implemented.`), null);\n};\nfunction Ct(i, e, t, n, s = !1) {\n  const a = t.type;\n  let r = -1;\n  if (i.__pluginData__.pluginInstances[a] && i.__pluginData__.pluginInstances[a].find((l, u) => {\n    if (l.name === t.name)\n      return r = u, !0;\n  }) && !s) {\n    i.log.info(`Plugin ${t.name} of type ${a} already registered.`);\n    return;\n  }\n  i.__pluginData__.pluginClasses[e] = n, i.__pluginData__.pluginInstances[a] = i.__pluginData__.pluginInstances[a] || [], r !== -1 && i.__pluginData__.pluginInstances[a].splice(r, 1), i.__pluginData__.pluginInstances[a].push(t), i.__pluginModules = i.__pluginModules || [];\n  const o = t.getPluginModuleInstance();\n  if (o && (o._player = o._player || i, !i.__pluginModules.find((l) => l.constructor.name === o.constructor.name))) {\n    const l = o.moduleName, u = o.moduleVersion;\n    i.log.debug(`Plugin module imported: ${l}: v${u}`), i.__pluginModules.push(o);\n  }\n}\nfunction Ps(i, e) {\n  let t = null, n = { enabled: !0 };\n  if (typeof e == \"function\" ? t = e : typeof e == \"object\" && typeof e.plugin == \"function\" && (t = e.plugin, n = e.config), !t)\n    i.log.warn(\"Error importing plugin with explicit import API. Check the 'plugins' array at init params\");\n  else {\n    const s = wt(t, i, null, n);\n    if (!s)\n      i.log.warn(`Unable to create an instance of the plugin ${t.name}`);\n    else {\n      const a = s.constructor.name;\n      Ct(i, a, s, t, !0);\n    }\n  }\n}\nfunction ha(i, e) {\n  const t = i.config;\n  e.keys().forEach((n) => {\n    const s = e(n), a = n.substring(2, n.length - 3);\n    if (t.plugins[a]) {\n      const r = s.default, o = wt(r, i, a, {});\n      Ct(i, n, o, r, !1);\n    } else if (/^[a-z0-9]+$/i.test(a)) {\n      i.__pluginModules = i.__pluginModules || [];\n      const r = s.default, o = new r(i);\n      if (!i.__pluginModules.find((l) => l.constructor.name === o.constructor.name)) {\n        const l = o.moduleName, u = o.moduleVersion;\n        i.log.debug(`Plugin module imported: ${l}: v${u}`), i.__pluginModules.push(o);\n      }\n    }\n  });\n}\nfunction Es(i) {\n  const e = i.config;\n  if (i.__pluginData__ = i.__pluginData__ || {\n    pluginClasses: [],\n    pluginInstances: {}\n  }, i.__pluginData__.pluginClasses.length !== 0) return;\n  [\n    ...ps,\n    ...i.initParams.plugins\n  ].forEach((n) => {\n    Ps(i, n);\n  });\n  const { buttonGroups: t } = e;\n  t && t.forEach((n, s) => {\n    const a = `button_group_${s}`, r = wt(Ls, i, a, n);\n    r._iconPath = z([i.configResourcesUrl, n.icon]), Ct(i, r.type, r, `ButtonGroupPlugin${s}`, !1);\n  }), i.log.debug(\"Plugins have been registered:\");\n}\nfunction Ts(i) {\n  delete i.__pluginData__;\n}\nfunction vi(i, e) {\n  var t;\n  return ((t = i.__pluginData__) == null ? void 0 : t.pluginInstances[e]) || [];\n}\nasync function $(i, e, t = null, n = null) {\n  if (!i.__pluginData__.pluginInstances[e]) {\n    i.log.info(`There are no defined plugins of type '${e}'`);\n    return;\n  }\n  i.__pluginData__.pluginInstances[e].sort((s, a) => s.order - a.order), i.__pluginData__.pluginInstances[e].forEach((s) => i.log.debug(`type: ${e}, name: ${s.name}`)), typeof n != \"function\" && (n = async function(s) {\n    return await s.isEnabled();\n  });\n  for (const s in i.__pluginData__.pluginInstances[e]) {\n    const a = i.__pluginData__.pluginInstances[e][s];\n    if (await n(a)) {\n      if (a.__uiPlugin) {\n        const o = await a.getDictionaries();\n        if (typeof o == \"object\")\n          for (const l in o) {\n            const u = o[l];\n            i.addDictionary(l, u);\n          }\n      }\n      typeof t == \"function\" && await t(a), await a.load();\n    }\n  }\n}\nasync function wi(i, e) {\n  var t;\n  (t = i.__pluginData__.pluginInstances[e]) == null || t.forEach(async (n) => {\n    await n.unload();\n  });\n}\nfunction Ss(i) {\n  var t;\n  const e = (n, s) => {\n    if (!n)\n      throw new Error(`Invalid video manifest: ${s}`);\n  };\n  e(i.streams, \"missing 'streams' object.\"), e(i.streams.length > 0, \"the 'streams' array is empty.\"), e((t = i.metadata) == null ? void 0 : t.preview, \"the 'metadata.preview' field is required.\");\n}\nclass Is extends de {\n  constructor(e, t) {\n    super(e, t), this._videoContainer = t, this._streamData = null, this._streams = null, this._players = [], this._mainAudioPlayer = null, this._streamSyncTimer = null, this._trimming = {\n      enabled: !1,\n      start: 100,\n      end: 200\n    };\n  }\n  async load(e) {\n    this._streamData = e, this._streams = {};\n    let t = this.player.config.defaultAudioStream || \"presenter\";\n    this._streamData.length === 1 && (t = this._streamData[0].content), e.some((n) => {\n      if (n.role === \"mainAudio\")\n        return t = n.content, !0;\n    }), this.player.log.debug(\"Finding compatible video plugins\"), await jn(this.player);\n    for (const n of this._streamData) {\n      const s = Wn(this.player, n);\n      if (!s)\n        throw Error(`Canvas plugin not found: ${n.canvas}`);\n      const a = n.content === t, r = await qi(this.player, n);\n      if (!r)\n        throw Error(`Incompatible stream type: ${n.content}`);\n      this._streams[n.content] = {\n        stream: n,\n        isMainAudio: a,\n        videoPlugin: r,\n        canvasPlugin: s\n      };\n    }\n    for (const n in this._streams) {\n      const s = this._streams[n];\n      s.canvas = await s.canvasPlugin.getCanvasInstance(this._videoContainer), s.player = await s.videoPlugin.getVideoInstance(s.canvas.element, s.isMainAudio), t === n ? (this._mainAudioPlayer = s.player, s.player.initVolume(1)) : s.player.initVolume(0), await s.player.load(s.stream, this), await s.canvas.loadCanvas(s.player), s.player.onVideoEnded(() => {\n        this.executeAction(\"pause\"), this.executeAction(\"setCurrentTime\", 0), se(this.player, m.ENDED);\n      }), this._players.push(s.player);\n    }\n    if (this.mainAudioPlayer === null)\n      throw this.player.log.error(\"The video stream containing the audio track could not be identified. The `role` attribute must be specified in the main video stream, or the `defaultAudioStream` attribute must be set correctly in the player configuration.\"), new Error(\"The video stream containing the audio track could not be identified.\");\n  }\n  async unload() {\n    this.stopStreamSync(), await qn(this.player);\n  }\n  get players() {\n    return this._players;\n  }\n  // This is the raw streamData loaded from the video manifest\n  get streamData() {\n    return this._streamData;\n  }\n  // This property stores the available streams, indexed by the content identifier, and contains the\n  // stream data, the video plugin and the player, for each content identifier.\n  get streams() {\n    return this._streams;\n  }\n  get mainAudioPlayer() {\n    return this._mainAudioPlayer;\n  }\n  get isTrimEnabled() {\n    var e, t, n;\n    return ((e = this._trimming) == null ? void 0 : e.enabled) && ((t = this._trimming) == null ? void 0 : t.end) > ((n = this._trimming) == null ? void 0 : n.start);\n  }\n  get trimStart() {\n    var e;\n    return (e = this._trimming) == null ? void 0 : e.start;\n  }\n  get trimEnd() {\n    var e;\n    return (e = this._trimming) == null ? void 0 : e.end;\n  }\n  async setTrimming({ enabled: e, start: t, end: n }) {\n    if (t >= n)\n      throw Error(`Error setting trimming: start time (${t}) must be lower than end time ${n}`);\n    this._trimming = {\n      enabled: e,\n      start: t,\n      end: n\n    };\n    const s = await this.currentTime();\n    se(this.player, m.TIMEUPDATE, { currentTime: e ? t + s : s });\n  }\n  startStreamSync() {\n    this._timeSync = !0;\n    const e = async () => {\n      if (!this._players.length) {\n        this.player.log.warn(\"Player not yet loaded. Waiting for video sync.\");\n        return;\n      }\n      let t = this.mainAudioPlayer.currentTimeSync;\n      const n = 0.2;\n      if (this.players.length > 1)\n        for (let s = 0; s < this.players.length; ++s) {\n          const a = this.players[s];\n          if (a !== this.mainAudioPlayer) {\n            const r = a.currentTimeSync;\n            Math.abs(t - r) > n && (this.player.log.debug(\"Video synchronization triggered\"), a.setCurrentTime(t));\n          }\n        }\n      if (this.isTrimEnabled) {\n        let s = t - this.trimStart;\n        if (this.trimEnd <= t) {\n          await this.executeAction(\"pause\"), await this.setCurrentTime(0), this.stopStreamSync(), t = 0, se(this.player, m.ENDED, {});\n          return;\n        } else t < this.trimStart && (await this.setCurrentTime(0), t = this.trimStart, s = 0);\n        se(this.player, m.TIMEUPDATE, { currentTime: s }), this._timeupdateTimer = setTimeout(() => {\n          this._timeSync && e();\n        }, 250);\n      } else this._timeSync && (se(this.player, m.TIMEUPDATE, { currentTime: t }), this._timeupdateTimer = setTimeout(() => {\n        e();\n      }, 250));\n    };\n    e();\n  }\n  stopStreamSync() {\n    this._timeSync = !1, this._timeupdateTimer && clearTimeout(this._timeupdateTimer);\n  }\n  executeAction(e, t = []) {\n    return Array.isArray(t) || (t = [t]), new Promise((n) => {\n      let s = [], a = [];\n      this.players.forEach((r) => {\n        a.push(new Promise((o) => {\n          r[e](...t).then((l) => {\n            s.push(l), o();\n          });\n        }));\n      }), Promise.allSettled(a).then(() => n(s));\n    });\n  }\n  get isLiveStream() {\n    return this._streamData.some((e) => Array.from(Object.keys(e.sources)).indexOf(\"hlsLive\") !== -1);\n  }\n  async play() {\n    return this.startStreamSync(), await this.executeAction(\"play\");\n  }\n  async pause() {\n    return this.stopStreamSync(), await this.executeAction(\"pause\");\n  }\n  async stop() {\n    this.stopStreamSync(), await this.executeAction(\"pause\"), await this.executeAction(\"setCurrentTime\", 0);\n  }\n  async paused() {\n    return (await this.executeAction(\"paused\"))[0];\n  }\n  async setCurrentTime(e) {\n    const t = await this.duration();\n    e < 0 ? e = 0 : e > t && (e = t);\n    const n = (await this.executeAction(\"currentTime\"))[0];\n    let s = null;\n    if (this.isTrimEnabled) {\n      e = e + this.trimStart, e = e >= this.trimEnd ? this.trimEnd : e;\n      const r = (await this.executeAction(\"setCurrentTime\", [e]))[0], o = (await this.executeAction(\"currentTime\"))[0];\n      s = {\n        result: r,\n        prevTime: n - this.trimStart,\n        newTime: o - this.trimStart\n      };\n    } else {\n      const r = (await this.executeAction(\"setCurrentTime\", [e]))[0], o = (await this.executeAction(\"currentTime\"))[0];\n      s = { result: r, prevTime: n, newTime: o };\n    }\n    const a = await this.currentTime();\n    return se(this.player, m.TIMEUPDATE, { currentTime: a }), s;\n  }\n  async currentTime() {\n    const e = await this.mainAudioPlayer.currentTime();\n    return this.isTrimEnabled ? e - this.trimStart : e;\n  }\n  async currentTimeIgnoringTrimming() {\n    return await this.mainAudioPlayer.currentTime();\n  }\n  async volume() {\n    return this.mainAudioPlayer ? await this.mainAudioPlayer.volume() : (await this.executeAction(\"volume\"))[0];\n  }\n  async setVolume(e) {\n    return this.mainAudioPlayer ? await this.mainAudioPlayer.setVolume(e) : (await this.executeAction(\"setVolume\", [e]))[0];\n  }\n  async duration() {\n    return this.isTrimEnabled ? this.trimEnd - this.trimStart : await this.durationIgnoringTrimming();\n  }\n  async durationIgnoringTrimming() {\n    return (await this.executeAction(\"duration\")).reduce((t, n) => Math.min(t, n), Number.MAX_VALUE);\n  }\n  async playbackRate() {\n    return (await this.executeAction(\"playbackRate\"))[0];\n  }\n  async setPlaybackRate(e) {\n    return (await this.executeAction(\"setPlaybackRate\", [e]))[0];\n  }\n  async getQualityReferencePlayer() {\n    let e = null, t = [];\n    if (Object.keys(this.streams).length > 0)\n      for (const n in this.streams) {\n        const s = this.streams[n], a = await s.player.getQualities() || [];\n        !e && a.length > t.length && (t = a, e = s.player);\n      }\n    return e || this.mainAudioPlayer;\n  }\n  async getCurrentQuality() {\n    return (await this.getQualityReferencePlayer()).currentQuality;\n  }\n  async getQualities() {\n    return await (await this.getQualityReferencePlayer()).getQualities();\n  }\n  async setQuality(e) {\n    const n = await (await this.getQualityReferencePlayer()).getQualities(), s = n.length;\n    let a = -1;\n    if (n.some((r, o) => (e.index === r.index && (a = o), a !== -1)), a >= 0) {\n      const r = a / s;\n      for (const o in this.streams) {\n        const l = this.streams[o], u = await l.player.getQualities() || [];\n        if (this.player.log.debug(u), u.length > 1) {\n          const f = Math.round(u.length * r), h = u[f];\n          await l.player.setQuality(h);\n        }\n      }\n    }\n  }\n  async supportsMultiaudio() {\n    return this.mainAudioPlayer.supportsMultiaudio();\n  }\n  async getAudioTracks() {\n    return this.mainAudioPlayer.getAudioTracks();\n  }\n  async setCurrentAudioTrack(e) {\n    return this.mainAudioPlayer.setCurrentAudioTrack(e);\n  }\n  get currentAudioTrack() {\n    return this.mainAudioPlayer.currentAudioTrack;\n  }\n}\nconst U = Object.freeze({\n  TOP_LEFT: \"topLeft\",\n  TOP_MIDDLE: \"topMiddle\",\n  TOP_RIGHT: \"topRight\",\n  CENTER_LEFT: \"centerLeft\",\n  CENTER_MIDDLE: \"centerMiddle\",\n  CENTER_RIGHT: \"centerRight\",\n  BOTTOM_LEFT: \"bottomLeft\",\n  BOTTOM_MIDDLE: \"bottomMiddle\",\n  BOTTOM_RIGHT: \"bottomRight\"\n}), B = (i, e, t, n, s) => {\n  n = n || \"\", t = t || 1e3;\n  const a = b(`\n        <div class=\"message-content ${n}\">\n            ${i ? `<i class=\"icon\">${i}</i>` : \"\"}\n            ${e ? `<p class=\"text\">${e}</p>` : \"\"}\n        </div>\n    `);\n  return s.innerHTML = \"\", s.appendChild(a), s.timer && (clearTimeout(s.timer), s.timer = null), s.timer = setTimeout(() => {\n    s.removeChild(a);\n  }, t), a;\n};\nclass ks extends G {\n  constructor(e, t) {\n    const n = { class: \"video-container-message\" };\n    super(e, { attributes: n, parent: t }), this._topLeftContainer = b('<div class=\"container top-left\"></div>', this.element), this._topMiddleContainer = b('<div class=\"container top-middle\"></div>', this.element), this._topRightContainer = b('<div class=\"container top-right\"></div>', this.element), this._centerLeftContainer = b('<div class=\"container center-left\"></div>', this.element), this._centerMiddleContainer = b('<div class=\"container center-middle\"></div>', this.element), this._centerRightContainer = b('<div class=\"container center-right\"></div>', this.element), this._bottomLeftContainer = b('<div class=\"container bottom-left\"></div>', this.element), this._bottomMiddleContainer = b('<div class=\"container bottom-middle\"></div>', this.element), this._bottomRightContainer = b('<div class=\"container bottom-right\"></div>', this.element);\n  }\n  show({ icon: e = null, text: t = \"\", timeout: n = 1e3, position: s = U.CENTER_MIDDLE, cssClass: a = \"\" }) {\n    switch (s) {\n      case U.TOP_LEFT:\n        B.apply(this, [e, t, n, a, this._topLeftContainer]);\n        break;\n      case U.TOP_MIDDLE:\n        B.apply(this, [e, t, n, a, this._topMiddleContainer]);\n        break;\n      case U.TOP_RIGHT:\n        B.apply(this, [e, t, n, a, this._topRightContainer]);\n        break;\n      case U.CENTER_LEFT:\n        B.apply(this, [e, t, n, a, this._centerLeftContainer]);\n        break;\n      case U.CENTER_MIDDLE:\n        B.apply(this, [e, t, n, a, this._centerMiddleContainer]);\n        break;\n      case U.CENTER_RIGHT:\n        B.apply(this, [e, t, n, a, this._centerRightContainer]);\n        break;\n      case U.BOTTOM_LEFT:\n        B.apply(this, [e, t, n, a, this._bottomLeftContainer]);\n        break;\n      case U.BOTTOM_MIDDLE:\n        B.apply(this, [e, t, n, a, this._bottomMiddleContainer]);\n        break;\n      case U.BOTTOM_RIGHT:\n        B.apply(this, [e, t, n, a, this._bottomRightContainer]);\n        break;\n    }\n  }\n}\nconst _ = Object.freeze({\n  UNLOADED: 0,\n  LOADING_MANIFEST: 1,\n  MANIFEST: 2,\n  LOADING_PLAYER: 3,\n  LOADED: 4,\n  UNLOADING_MANIFEST: 5,\n  UNLOADING_PLAYER: 6,\n  ERROR: 7\n});\nfunction Ds(i, e) {\n  return Array.isArray[e] || (e = [e]), ji(i, e).getManifestData(e);\n}\nasync function xs(i) {\n  return { w: 1280, h: 720 };\n}\nasync function Ci(i) {\n  var e;\n  for (const t in this.streamProvider.streams) {\n    const n = ((e = i == null ? void 0 : i.videos) == null ? void 0 : e.find((a) => a.content === t)) != null, s = this.streamProvider.streams[t];\n    n && !s.player.isEnabled ? await s.player.enable() : !n && s.player.isEnabled && await s.player.disable();\n  }\n}\nfunction bi() {\n  for (const i in this.streamProvider.streams) {\n    const e = this.streamProvider.streams[i];\n    e.canvas.element.style.display = \"none\", this._hiddenVideos.appendChild(e.canvas.element);\n  }\n}\nasync function As() {\n  var a, r;\n  const i = gi(this.player, this.streamProvider.streamData, this._layoutId, this._mainLayoutContent);\n  await Ci.apply(this, [i]), bi.apply(this);\n  const e = await xs(this.player), t = 100 / e.w, n = 100 / e.h;\n  if (this.baseVideoRect.classList.remove(\"dynamic\"), this.baseVideoRect.classList.add(\"static\"), (a = i == null ? void 0 : i.videos) != null && a.length) {\n    const o = [];\n    for (const l of i.videos) {\n      const u = this.streamProvider.streams[l.content], { stream: f, player: h, canvas: g } = u, L = await h.getDimensions(), y = L.w / L.h;\n      let v = Number.MAX_VALUE, P = null;\n      g.clearButtonsArea(), o.push(await rt(this.player, i, g, l, l.content)), l.rect.forEach((c) => {\n        const p = /^(\\d+.?\\d*)\\/(\\d+.?\\d*)$/.exec(c.aspectRatio), C = p ? Number(p[1]) / Number(p[2]) : 1, w = Math.abs(y - C);\n        w < v && (P = c, v = w);\n      }), g.element.style.display = \"block\", g.element.style.position = \"absolute\", g.element.style.left = `${(P == null ? void 0 : P.left) * t}%`, g.element.style.top = `${(P == null ? void 0 : P.top) * n}%`, g.element.style.width = `${(P == null ? void 0 : P.width) * t}%`, g.element.style.height = `${(P == null ? void 0 : P.height) * n}%`, g.element.style.zIndex = l.layer, this.baseVideoRect.appendChild(g.element);\n    }\n    setTimeout(() => {\n      ot(this.player, i, o.flat());\n    }, 100);\n  }\n  const s = this.baseVideoRect.getElementsByClassName(\"video-layout-button\");\n  return Array.from(s).forEach((o) => this.baseVideoRect.removeChild(o)), (r = i == null ? void 0 : i.buttons) == null || r.forEach((o) => {\n    const l = Jt({\n      tag: \"button\",\n      attributes: {\n        class: \"video-layout-button\",\n        \"aria-label\": Ce(o.ariaLabel),\n        title: Ce(o.title),\n        style: `\n                    left: ${o.rect.left * t}%;\n                    top: ${o.rect.top * n}%;\n                    width: ${o.rect.width * t}%;\n                    height: ${o.rect.height * n}%;\n                    z-index: ${o.layer};\n                `\n      },\n      parent: this.baseVideoRect,\n      children: o.icon\n    });\n    l.layout = i, l.buttonAction = o.onClick, l.addEventListener(\"click\", async (u) => {\n      E(this.player, m.BUTTON_PRESS, {\n        plugin: i.plugin,\n        layoutStructure: i\n      }), await u.target.buttonAction.apply(u.target.layout), u.stopPropagation();\n    }), this._layoutButtons.push(l);\n  }), !0;\n}\nasync function Ms() {\n  var r, o, l, u, f, h;\n  const i = gi(this.player, this.streamProvider.streamData, this._layoutId, this._mainLayoutContent);\n  await Ci.apply(this, [i]), bi.apply(this), this.baseVideoRect.classList.add(\"dynamic\"), this.baseVideoRect.classList.remove(\"static\"), this.baseVideoRect.innerHTML = \"\";\n  const e = this.element.clientWidth, t = this.element.clientHeight, n = e > t;\n  if (this.baseVideoRect.classList.remove(\"align-center\"), this.baseVideoRect.classList.remove(\"align-top\"), this.baseVideoRect.classList.remove(\"align-bottom\"), this.baseVideoRect.classList.remove(\"align-left\"), this.baseVideoRect.classList.remove(\"align-right\"), n) {\n    const g = ((o = (r = this.player.config.videoContainer) == null ? void 0 : r.dynamicLayout) == null ? void 0 : o.landscapeVerticalAlignment) || \"align-center\";\n    this.baseVideoRect.classList.remove(\"portrait\"), this.baseVideoRect.classList.add(\"landscape\"), this.baseVideoRect.classList.add(g);\n  } else {\n    const g = ((u = (l = this.player.config.videoContainer) == null ? void 0 : l.dynamicLayout) == null ? void 0 : u.portraitHorizontalAlignment) || \"align-center\";\n    this.baseVideoRect.classList.add(\"portrait\"), this.baseVideoRect.classList.remove(\"landscape\"), this.baseVideoRect.classList.add(g);\n  }\n  const s = this.baseVideoRect.clientWidth, a = this.element.clientHeight;\n  if (((f = i == null ? void 0 : i.videos) == null ? void 0 : f.length) === 1) {\n    const g = [], L = [], y = i.videos[0], v = this.streamProvider.streams[y.content], { player: P, canvas: c } = v;\n    c.clearButtonsArea(), L.push(await rt(this.player, i, c, y, y.content)), c.element.style = {}, c.element.style.display = \"block\", c.element.style.width = \"100%\", c.element.style.height = \"100%\", c.element.style.overflow = \"hidden\", c.element.style.position = \"relative\", g.push(c.element), c.element.sortIndex = 0, g.forEach((p) => this.baseVideoRect.appendChild(p)), setTimeout(() => {\n      ot(this.player, i, L.flat());\n    }, 100);\n  } else if ((h = i == null ? void 0 : i.videos) != null && h.length) {\n    let g = 0;\n    const L = [], y = [];\n    for (const v of i.videos) {\n      const P = this.streamProvider.streams[v.content], { player: c, canvas: p } = P, C = await c.getDimensions(), w = C.w / C.h, T = s, J = a, H = (n ? T : J) * v.size / 100;\n      let j = Math.round(n ? H : H * w), N = Math.round(n ? H / w : H);\n      j > T && (j = T, N = Math.round(j / w)), N > J && (N = J, j = Math.round(N * w)), p.clearButtonsArea(), y.push(await rt(this.player, i, p, v, v.content)), p.element.style = {}, p.element.style.display = \"block\", p.element.style.width = `${j}px`, p.element.style.height = `${N}px`, p.element.style.overflow = \"hidden\", p.element.style.position = \"relative\", p.element.sortIndex = g++, L.push(p.element);\n    }\n    if (n) {\n      const v = b('<div class=\"landscape-container\"></div>', this.baseVideoRect);\n      L.forEach((P) => v.appendChild(P));\n    } else\n      L.forEach((v) => this.baseVideoRect.appendChild(v));\n    setTimeout(() => {\n      ot(this.player, i, y.flat());\n    }, 100);\n  }\n  return !0;\n}\nclass Rs extends G {\n  constructor(e, t) {\n    var r;\n    const n = \"base-video-rect\", s = {\n      class: \"video-container\"\n    };\n    (r = e.config.videoContainer) != null && r.overPlaybackBar && (s.class += \" over-playback-bar\");\n    const a = `\n            <div class=\"${n}\"></div>\n            <div class=\"hidden-videos-container\" style=\"display: none\"></div>\n        `;\n    super(e, { attributes: s, children: a, parent: t }), this._hiddenVideos = this.element.getElementsByClassName(\"hidden-videos-container\")[0], this._baseVideoRect = this.element.getElementsByClassName(n)[0], this.element.addEventListener(\"click\", async () => {\n      await this.paused() ? await this.play() : await this.pause();\n    }), this._ready = !1, this._players = [], this._streamProvider = new Is(this.player, this.baseVideoRect);\n  }\n  get layoutId() {\n    return this._layoutId;\n  }\n  get mainLayoutContent() {\n    return this._mainLayoutContent;\n  }\n  async setLayout(e, t = null) {\n    var n, s;\n    if (this.validContentIds.indexOf(e) === -1)\n      return !1;\n    {\n      const a = (s = (n = this.player.config.videoContainer) == null ? void 0 : n.restoreVideoLayout) == null ? void 0 : s.global;\n      await this.player.preferences.set(\"videoLayout\", e, { global: a }), await this.player.preferences.set(\"videoLayoutMainContent\", t, { global: a });\n      const r = this._layoutId;\n      this._layoutId = e, this._mainLayoutContent = t, await this.updateLayout(), r !== e && E(this.player, m.LAYOUT_CHANGED, { prevLayout: r, layoutId: e });\n    }\n  }\n  get validContentIds() {\n    return this._validContentIds;\n  }\n  get validContentSettings() {\n    return this._validContentSettings;\n  }\n  get validLayouts() {\n    return Oe(this.player, this.streamData);\n  }\n  get streamData() {\n    return this._streamData;\n  }\n  get baseVideoRect() {\n    return this._baseVideoRect;\n  }\n  get streamProvider() {\n    return this._streamProvider;\n  }\n  async create() {\n    this._baseVideoRect.style.display = \"none\", await $(this.player, \"layout\"), await Gi(this.player);\n  }\n  async load(e) {\n    var o, l, u, f, h, g, L, y, v, P;\n    if (this._streamData = e, (l = (o = this.player.config.videoContainer) == null ? void 0 : o.restoreVideoLayout) != null && l.enabled) {\n      const c = (f = (u = this.player.config.videoContainer) == null ? void 0 : u.restoreVideoLayout) == null ? void 0 : f.global;\n      this._layoutId = await this.player.preferences.get(\"videoLayout\", { global: c }) || this.player.config.defaultLayout, this._mainLayoutContent = await this.player.preferences.get(\"videoLayoutMainContent\", { global: c }) || null;\n    } else\n      this._layoutId = this.player.config.defaultLayout, this._mainLayoutContent = null;\n    await this.streamProvider.load(e), this._validContentIds = hi(this.player, e), this._validContentSettings = zn(this.player, e), await this.updateLayout(null, !0);\n    const t = b(\n      '<div class=\"button-plugins left-side\"></div>',\n      this.element\n    ), n = b(\n      '<div class=\"button-plugins right-side\"></div>',\n      this.element\n    );\n    this._buttonPlugins = [t, n], this.player.log.debug(\"Loading videoContainer button plugins\"), await $(this.player, \"button\", async (c) => {\n      this.player.log.debug(` Button plugin: ${c.name}`), c.side === \"left\" ? await Ve(c, t) : c.side === \"right\" && await Ve(c, n);\n    }, async (c) => c.parentContainer === \"videoContainer\" ? await c.isEnabled() : !1), this._baseVideoRect.style.display = \"\";\n    const s = await this.player.preferences.get(\"volume\", { global: !0 }), a = await this.player.preferences.get(\"playbackRate\", { global: !0 }), r = await this.player.preferences.get(\"lastKnownTime\", { global: !1 });\n    if ((h = this.player.config.videoContainer) != null && h.restoreVolume && s !== null && s !== void 0 && await this.streamProvider.setVolume(s), (g = this.player.config.videoContainer) != null && g.restorePlaybackRate && a !== null && a !== void 0 && await this.streamProvider.setPlaybackRate(a), this.player.videoManifest.trimming && await this.player.videoContainer.setTrimming(this.player.videoManifest.trimming), (y = (L = this.player.config.videoContainer) == null ? void 0 : L.restoreLastTime) != null && y.enabled && !this.streamProvider.isLiveStream) {\n      const c = async () => {\n        if (!await this.paused()) {\n          const C = await this.currentTime();\n          await this.player.preferences.set(\"lastKnownTime\", C, { global: !1 });\n        }\n        setTimeout(c, 1e3);\n      };\n      if (r) {\n        const p = await this.player.preferences.get(\"lastKnownTime\", { global: !1 }), C = await this.duration(), w = (P = (v = this.player.config.videoContainer) == null ? void 0 : v.restoreLastTime) == null ? void 0 : P.remainingSeconds;\n        C - p > w && await this.setCurrentTime(p);\n      }\n      c();\n    }\n    this._messageContainer = new ks(this.player, this.element), this._ready = !0;\n  }\n  async unload() {\n    this.removeFromParent(), await wi(this.player, \"layout\"), await Hi(this.player), await this.streamProvider.unload();\n  }\n  // Return true if the layout this.layoutId is compatible with the current stream data.\n  async updateLayout(e = null) {\n    const t = arguments[1];\n    if (e && (this._mainLayoutContent = e), !t && this.player.state !== _.LOADED)\n      return;\n    if (this._updateInProgress)\n      return this.player.log.warn(\"Recursive update layout detected\"), !1;\n    this._updateInProgress = !0;\n    let n = !0;\n    this._layoutButtons = [], (!this._layoutId || this._validContentIds.indexOf(this._layoutId) === -1) && (this._layoutId = this.player.config.defaultLayout, this._mainLayoutContent = null, this._validContentIds.indexOf(this._layoutId) === -1 && (this._layoutId = this._validContentIds[0]), n = !1);\n    const s = pi(this.player, this.streamProvider.streamData, this._layoutId);\n    return s.layoutType === \"static\" ? n = As.apply(this) : s.layoutType === \"dynamic\" && (n = Ms.apply(this)), this._updateInProgress = !1, n;\n  }\n  hideUserInterface() {\n    if (this._layoutButtons && this._buttonPlugins) {\n      this.player.log.debug(\"Hide video container user interface\");\n      const e = (t) => {\n        t._prevDisplay = t.style.display, t.style.display = \"none\";\n      };\n      this._layoutButtons.forEach(e), this._buttonPlugins.forEach(e);\n      for (const t in this.streamProvider.streams)\n        this.streamProvider.streams[t].canvas.hideButtons();\n    }\n  }\n  showUserInterface() {\n    if (this._layoutButtons && this._buttonPlugins) {\n      const e = (t) => t.style.display = t._prevDisplay || \"block\";\n      this._layoutButtons.forEach(e), this._buttonPlugins.forEach(e);\n      for (const t in this.streamProvider.streams)\n        this.streamProvider.streams[t].canvas.showButtons();\n    }\n  }\n  get message() {\n    return this._messageContainer;\n  }\n  get elementSize() {\n    return { w: this.element.offsetWidth, h: this.element.offsetHeight };\n  }\n  get ready() {\n    return this._ready;\n  }\n  get isLiveStream() {\n    return this.streamProvider.isLiveStream;\n  }\n  async play() {\n    const e = await this.streamProvider.play();\n    return E(this.player, m.PLAY), e;\n  }\n  async pause() {\n    const e = await this.streamProvider.pause();\n    return E(this.player, m.PAUSE), e;\n  }\n  async stop() {\n    this.streamProvider.stop(), E(this.player, m.STOP);\n  }\n  async paused() {\n    return this.streamProvider.paused();\n  }\n  async setCurrentTime(e) {\n    const t = await this.streamProvider.setCurrentTime(e);\n    return E(this.player, m.SEEK, { prevTime: t.prevTime, newTime: t.newTime }), t.result;\n  }\n  async currentTime() {\n    return this.streamProvider.currentTime();\n  }\n  async volume() {\n    return this.streamProvider.volume();\n  }\n  async setVolume(e) {\n    const t = await this.streamProvider.setVolume(e);\n    return E(this.player, m.VOLUME_CHANGED, { volume: e }), await this.player.preferences.set(\"volume\", e, { global: !0 }), t;\n  }\n  async duration() {\n    return await this.streamProvider.duration();\n  }\n  async playbackRate() {\n    return await this.streamProvider.playbackRate();\n  }\n  async setPlaybackRate(e) {\n    const t = await this.streamProvider.setPlaybackRate(e);\n    return E(this.player, m.PLAYBACK_RATE_CHANGED, { newPlaybackRate: e }), await this.player.preferences.set(\"playbackRate\", e, { global: !0 }), t;\n  }\n  get isTrimEnabled() {\n    return this.streamProvider.isTrimEnabled;\n  }\n  get trimStart() {\n    return this.streamProvider.trimStart;\n  }\n  get trimEnd() {\n    return this.streamProvider.trimEnd;\n  }\n  async setTrimming({ enabled: e, start: t, end: n }) {\n    const s = await this.streamProvider.setTrimming({\n      enabled: e,\n      start: t,\n      end: n\n    });\n    return E(this.player, m.TRIMMING_CHANGED, {\n      enabled: e,\n      start: t,\n      end: n\n    }), s;\n  }\n  getVideoRect(e = null) {\n    var n, s;\n    let t = this.baseVideoRect;\n    if (typeof e == \"string\") {\n      if (t = (n = this.streamProvider.streams[e]) == null ? void 0 : n.canvas.element, !t)\n        return this.player.log.warn(`videoContainer.getVideoRect: Invalid target '${e}'. Valid targets are: ${Object.keys(this.streamProvider.streams).join(\", \")}`), this.player.log.warn(\"Please, configure a valid target in the 'targetContent' property of the configuration file, or provide a valid target in the 'frameList.targetContent' property of the video manifest\"), null;\n    } else e === 0 && (t = (s = this.streamProvider.streams[Object.keys(this.streamProvider.streams)[0]]) == null ? void 0 : s.canvas.element);\n    return {\n      x: t == null ? void 0 : t.offsetLeft,\n      y: t == null ? void 0 : t.offsetTop,\n      width: t == null ? void 0 : t.offsetWidth,\n      height: t == null ? void 0 : t.offsetHeight,\n      element: t\n    };\n  }\n  appendChild(e, t = null, n = 1) {\n    if (t) {\n      const { width: s, height: a } = this.getVideoRect();\n      t.x = t.x * 100 / s, t.width = t.width * 100 / s, t.y = t.y * 100 / a, t.height = t.height * 100 / a, e.style.position = \"absolute\", e.style.left = `${t.x}%`, e.style.top = `${t.y}%`, e.style.width = `${t.width}%`, e.style.height = `${t.height}%`, n !== null && (e.style.zIndex = n);\n    }\n    return this.baseVideoRect.appendChild(e), e;\n  }\n  removeChild(e) {\n    this.baseVideoRect.removeChild(e);\n  }\n}\nconst Vs = `<?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 300 300\" 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    <rect id=\"Play\" x=\"0\" y=\"0\" width=\"300\" height=\"300\" style=\"fill:none;\"/>\n    <g id=\"Play1\" serif:id=\"Play\">\n        <g transform=\"matrix(1.21457,0,0,1.21457,-55.8704,-35.2227)\">\n            <circle cx=\"169.5\" cy=\"152.5\" r=\"123.5\" style=\"fill:rgb(128,128,128);\"/>\n            <path d=\"M169.5,29C237.662,29 293,84.338 293,152.5C293,220.662 237.662,276 169.5,276C101.338,276 46,220.662 46,152.5C46,84.338 101.338,29 169.5,29ZM169.5,37.233C233.117,37.233 284.767,88.883 284.767,152.5C284.767,216.117 233.117,267.767 169.5,267.767C105.883,267.767 54.233,216.117 54.233,152.5C54.233,88.883 105.883,37.233 169.5,37.233Z\" style=\"fill:rgb(235,235,235);\"/>\n        </g>\n        <g transform=\"matrix(6.12323e-17,1,-1,6.12323e-17,347,-59)\">\n            <path d=\"M209,82L317,253L101,253L209,82Z\" style=\"fill:rgb(235,235,235);\"/>\n        </g>\n    </g>\n</svg>\n`, Ns = `\n    background-color: #e4e4e4;\n    width: 100%;\n    height: 100%;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    cursor: pointer;\n    position: absolute;\n    top: 50%;\n    transform: translateY(-50%); \n`, Qe = `\n    width: 100%;\n`, Us = `\n    position: absolute; \n    top: 0px; \n    left: 0px; \n    right: 0px; \n    bottom: 0px; \n    display: flex;\n    align-content: center;\n    justify-content: center;\n    align-items: center;\n`, Fs = `\n    pointer-events: none;\n    width: 20%;\n    max-width: 400px;\n    min-width: 100px;\n    opacity: 0.6;\n`, Os = `\n    display: block;\n    width: 20%;\n    background: none;\n    border: none;\n    cursor: pointer;\n`;\nclass $s extends G {\n  constructor(e, t, n, s) {\n    const a = {\n      class: \"preview-container\",\n      style: Ns,\n      role: \"button\",\n      \"aria-label\": \"Play video\"\n    };\n    super(e, { attributes: a, parent: t }), this._img = b(`\n        <div style=\"${Qe}\">\n            ${n ? `<img style=\"${Qe}\" src=\"${n}\" class=\"preview-image-landscape\" alt=\"\"/>` : \"\"}\n            ${s ? `<img style=\"${Qe}\" src=\"${s}\" class=\"preview-image-portrait\" alt=\"\"/>` : \"\"}\n            <div style=\"${Us}\">\n                <button style=\"${Os}\" role=\"button\" aria-label=\"Play video\">\n                    <i class=\"preview-play-icon\" style=\"${Fs}\">${Vs}</i>\n                </button>\n            </div>\n        </div>\n        `, this.element), this.element.setAttribute(\"id\", \"playerContainerClickArea\"), this.element.addEventListener(\"click\", (l) => {\n      e.play();\n    });\n    const r = n && s, o = () => {\n      if (r) {\n        const l = this.element.clientWidth / this.element.clientHeight, u = Array.from(this.element.getElementsByClassName(\"preview-image-landscape\")), f = Array.from(this.element.getElementsByClassName(\"preview-image-portrait\"));\n        l >= 1 ? (u.forEach((h) => h.style.display = \"\"), f.forEach((h) => h.style.display = \"none\")) : (u.forEach((h) => h.style.display = \"none\"), f.forEach((h) => h.style.display = \"\"));\n      }\n    };\n    window.addEventListener(\"resize\", () => {\n      o();\n    }), o();\n  }\n  loadBackgroundImage(e) {\n    this._img.setAttribute(\"src\", e);\n  }\n}\nconst Bs = (i) => {\n  const e = document.createElement(\"section\");\n  return e.classList.add(\"pop-up\"), e.innerHTML = `\n        <header class=\"pop-up-title\">\n            <button class=\"action-back\">\n                <svg width=\"44\" height=\"44\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n                    <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/>\n                    <path d=\"M15 6l-6 6l6 6\" />\n                </svg>\n            </button>\n            <h2>title</h2>\n        </header>\n        <div class=\"pop-up-content\">\n        </div>\n    `, i.appendChild(e), e.setTitle = (t) => {\n    e.querySelector(\"header.pop-up-title h2\").textContent = t;\n  }, e.popButton = () => e.querySelector(\"header.pop-up-title button\"), e.onPopClicked = (t) => {\n    e._clickCallback && e.popButton().removeEventListener(\"click\", e._clickCallback), e._clickCallback = t, e.popButton().addEventListener(\"click\", t);\n  }, e.hidePopButton = () => e.popButton().style.display = \"none\", e.showPopButton = () => e.popButton().style.display = \"\", e.setContent = (t) => {\n    e.querySelector(\"div.pop-up-content\").innerHTML = \"\", e.querySelector(\"div.pop-up-content\").appendChild(t);\n  }, e;\n};\nlet zs = 0;\nfunction Gs() {\n  return ++zs;\n}\nvar ee, D, A, Ee;\nclass Hs {\n  constructor(e) {\n    I(this, ee, null);\n    I(this, D, null);\n    I(this, A, []);\n    I(this, Ee, \"\");\n    k(this, ee, e), k(this, D, document.createElement(\"div\")), d(this, D).className = \"pop-up-wrapper\", e.element.prepend(d(this, D)), d(this, D).classList.add(\"hidden\"), d(this, D).addEventListener(\"click\", (t) => t.stopPropagation()), d(this, ee).element.addEventListener(\"click\", (t) => {\n      t.stopPropagation(), this.hide();\n    });\n  }\n  get title() {\n    return d(this, Ee);\n  }\n  set title(e) {\n    k(this, Ee, e);\n  }\n  get currentContent() {\n    return d(this, A).length && d(this, A)[d(this, A).length - 1];\n  }\n  get currentContentId() {\n    var e;\n    return ((e = this.currentContent) == null ? void 0 : e.dataContentId) ?? -1;\n  }\n  show({ content: e, title: t = \"\", parent: n = null, attachLeft: s = !1, attachRight: a = !1 }) {\n    if (!e)\n      throw new Error(\"PlaybackBarPopUp.show(): No content provided.\");\n    e.setAttribute(\"data-pop-up-content-id\", Gs()), e.dataContentId = e.getAttribute(\"data-pop-up-content-id\");\n    const r = d(this, A).length && d(this, A)[d(this, A).length - 1], o = n && n.getAttribute(\"data-pop-up-content-id\");\n    r && r.getAttribute(\"data-pop-up-content-id\") !== o ? (d(this, D).innerHTML = \"\", k(this, A, [])) : r && r.container.classList.add(\"out\"), d(this, A).push(e), d(this, ee).element.classList.add(\"pop-up-active\"), d(this, D).classList.remove(\"hidden\");\n    const l = Bs(d(this, D));\n    return l.setTitle(t), e.container = l, s === !0 ? d(this, D).classList.add(\"left\") : d(this, D).classList.remove(\"left\"), a === !0 ? d(this, D).classList.add(\"right\") : d(this, D).classList.remove(\"right\"), l.setContent(e), d(this, A).length > 1 ? l.onPopClicked(() => {\n      d(this, A).pop(), d(this, A)[d(this, A).length - 1].container.classList.remove(\"out\"), d(this, D).removeChild(l);\n    }) : l.hidePopButton(), this.title = t, e.dataContentId;\n  }\n  pop() {\n    if (d(this, D).querySelectorAll(\".pop-up\").length === 1)\n      return this.hide(), !1;\n    const e = new Event(\"click\");\n    return d(this, D).querySelector(\".pop-up:not(.out) .action-back\").dispatchEvent(e), !0;\n  }\n  hide() {\n    d(this, ee).element.classList.remove(\"pop-up-active\"), d(this, D).classList.add(\"hidden\");\n  }\n  get isHidden() {\n    return d(this, D).classList.contains(\"hidden\");\n  }\n}\nee = new WeakMap(), D = new WeakMap(), A = new WeakMap(), Ee = new WeakMap();\nvar Te, re, oe, Q, le, Se, ce, R, te, ue;\nclass js extends G {\n  constructor(t, n) {\n    var f;\n    const s = ((f = t.config.progressIndicator) == null ? void 0 : f.inlineMode) ?? !1;\n    super(t, { attributes: { class: \"playback-bar-container\" }, parent: n });\n    I(this, Te, null);\n    I(this, re, null);\n    I(this, oe, null);\n    I(this, Q, null);\n    I(this, le, null);\n    I(this, Se, null);\n    I(this, ce, null);\n    I(this, R, null);\n    I(this, te, !0);\n    I(this, ue, []);\n    k(this, Te, new Hs(this)), this.element.addEventListener(\"mouseenter\", () => Wt(t)), this.element.addEventListener(\"mouseleave\", () => ut(t)), k(this, re, b('<section class=\"playback-bar\"></section>', this.element)), k(this, oe, b(\"<div></div>\")), k(this, Q, b(\"<nav></nav>\")), k(this, le, b(\"<ul></ul>\", d(this, Q))), k(this, Se, b(\"<div></div>\", d(this, Q))), k(this, ce, b(\"<ul></ul>\", d(this, Q)));\n    const r = t._initParams.getProgressIndicator, o = 1e3, l = 0, u = 100;\n    s ? k(this, R, r({ container: d(this, Se), player: t, duration: o, currentTime: l, precision: u })) : (d(this, re).appendChild(d(this, oe)), k(this, R, r({ container: d(this, oe), player: t, duration: o, currentTime: l, precision: u }))), d(this, R).onChange(async (h) => {\n      await t.videoContainer.setCurrentTime(h);\n    }), d(this, re).appendChild(d(this, Q));\n  }\n  get popUp() {\n    return d(this, Te);\n  }\n  get enabled() {\n    return d(this, te);\n  }\n  set enabled(t) {\n    k(this, te, t), d(this, te) ? this.showUserInterface() : this.hide();\n  }\n  async load() {\n    k(this, ue, []), this.player.log.debug(\"Loading button plugins\"), await $(this.player, \"button\", async (s) => {\n      this.player.log.debug(` Button plugin: ${s.name}`), d(this, ue).push(s), s.side === \"left\" ? await Ve(s, this.buttonPluginsLeft) : s.side === \"right\" && await Ve(s, this.buttonPluginsRight);\n    }, async (s) => s.parentContainer === \"playbackBar\" ? await s.isEnabled() : !1);\n    const t = await this.player.videoContainer.duration();\n    d(this, R).setDuration(t), this.player.frameList.frames.forEach((s, a, r) => {\n      const o = r[a + 1], l = o ? o.time - s.time : t - s.time;\n      d(this, R).addMarker({ time: s.time, duration: t, frameDuration: l, addGap: a < r.length - 1 });\n    }), this.player.bindEvent([this.player.Events.TIMEUPDATE, this.player.Events.SEEK], (s) => {\n      d(this, R).setCurrentTime(s.newTime ?? s.currentTime);\n    }), this.player.bindEvent(this.player.Events.TRIMMING_CHANGED, async (s) => {\n      const a = s.end - s.start;\n      d(this, R).setDuration(a);\n      const r = await this.player.videoContainer.currentTime();\n      d(this, R).setCurrentTime(r);\n    }), this.onResize();\n    const n = this.element.querySelector(\".playback-bar\").offsetHeight;\n    this.player.containerElement.style.setProperty(\"--playback-bar-height\", `${n}px`);\n  }\n  async unload() {\n    this.removeFromParent(), await wi(this.player, \"button\"), d(this, le).innerHTML = \"\", d(this, ce).innerHTML = \"\";\n  }\n  hideUserInterface() {\n    this.player.log.debug(\"Hide playback bar user interface\"), this.hide();\n  }\n  showUserInterface() {\n    var t;\n    if (d(this, te)) {\n      const s = ((t = this.player.config.progressIndicator) == null ? void 0 : t.inlineMode) ?? !1 ? \"flex\" : \"block\";\n      this.show(s), this.onResize();\n    }\n  }\n  get buttonPluginsRight() {\n    return d(this, ce);\n  }\n  get buttonPluginsLeft() {\n    return d(this, le);\n  }\n  get progressIndicator() {\n    return d(this, R);\n  }\n  get containerSize() {\n    const t = this.element.clientWidth, n = this.element.clientHeight;\n    return { width: t, height: n };\n  }\n  onResize() {\n    const { containerSize: t } = this;\n    d(this, ue).forEach((n) => n.onResize(t));\n  }\n}\nTe = new WeakMap(), re = new WeakMap(), oe = new WeakMap(), Q = new WeakMap(), le = new WeakMap(), Se = new WeakMap(), ce = new WeakMap(), R = new WeakMap(), te = new WeakMap(), ue = new WeakMap();\nconst Li = [\n  { maxWidth: 400, className: \"size-s\" },\n  { maxWidth: 600, className: \"size-m\" },\n  { maxWidth: 900, className: \"size-l\" },\n  { maxWidth: 1100, className: \"size-xl\" },\n  { className: \"size-xxl\" }\n], qs = (i) => Li.find((e) => e.maxWidth && e.maxWidth >= i || e.maxWidth === void 0).className;\nclass Ws extends G {\n  constructor(e, t) {\n    const n = {\n      class: \"captions-canvas visible-ui\"\n    };\n    super(e, { tag: \"div\", attributes: n, parent: t }), this._captionsContainer = b(`\n            <div class=\"text-container\">\n            </div>\n        `, this.element), this._captions = [], this.hide(), this._currentCaptions = null;\n    const s = async (a) => {\n      const o = (e.videoContainer.isTrimEnabled ? e.videoContainer.trimStart : 0) + (a.currentTime || a.newTime || 0);\n      if (this._currentCaptions) {\n        const l = this._currentCaptions.getCue(o);\n        this._captionsContainer.innerHTML = \"\", l && l.captions.forEach((u) => {\n          this._captionsContainer.innerHTML += u, this._captionsContainer.innerHTML += \"<br/>\";\n        }), l ? this._captionsContainer.style.display = null : this._captionsContainer.style.display = \"none\", this.resize();\n      }\n    };\n    M(this.player, m.TIMEUPDATE, s), M(this.player, m.SEEK, s), M(this.player, m.RESIZE, () => this.resize()), M(this.player, m.SHOW_UI, () => this.element.classList.add(\"visible-ui\")), M(this.player, m.HIDE_UI, () => this.element.classList.remove(\"visible-ui\"));\n  }\n  async load() {\n    await Pn(this.player);\n  }\n  unload() {\n  }\n  resize() {\n    const e = qs(this._captionsContainer.clientWidth);\n    Li.forEach((t) => this.element.classList.remove(t.className)), this.element.classList.add(e);\n  }\n  addCaptions(e) {\n    this._captions.push(e), E(this.player, m.CAPTIONS_CHANGED, { captions: this._captions });\n  }\n  get captions() {\n    return this._captions;\n  }\n  get currentCaptions() {\n    return this._currentCaptions;\n  }\n  getCaptions({ label: e, index: t, lang: n }) {\n    if (e === void 0 && t === void 0 && n === void 0)\n      throw Error(\"Could not find captions: you must specify the label, the index or the language\");\n    return t !== void 0 ? this._captions[t] : this._captions.find((s) => {\n      if (e !== void 0)\n        return s.label === e;\n      if (n !== void 0)\n        return s.language === n;\n    });\n  }\n  enableCaptions(e) {\n    const t = this.getCaptions(e);\n    if (t !== this._currentCaptions && (this._currentCaptions = t, this.currentCaptions)) {\n      const { language: n, label: s } = this.currentCaptions;\n      E(this.player, m.CAPTIONS_ENABLED, { language: n, label: s });\n    }\n    this.show();\n  }\n  disableCaptions() {\n    this.currentCaptions && E(this.player, m.CAPTIONS_DISABLED), this._currentCaptions = null, this.hide();\n  }\n}\nasync function Qs(i) {\n  await $(i, \"eventLog\", async (e) => {\n    e.events.forEach((t) => {\n      M(i, t, async (n) => {\n        await e.onEvent(t, n);\n      });\n    });\n  });\n}\nasync function Zs(i) {\n}\nclass pa extends he {\n  get type() {\n    return \"eventLog\";\n  }\n  get events() {\n    return [];\n  }\n  async onEvent(e, t) {\n    this.player.log.warn(`${this.name}: onEvent() function is not overwritten.`);\n  }\n}\nconst Pi = (i) => !1, Ei = (i) => i.description;\nclass Ys {\n  constructor(e, t) {\n    this._player = e, this._cookieConsentData = e.config.cookieConsent || [], this._getConsentCallback = t.getConsent || Pi, this._getDescriptionCallback = t.getDescription || Ei, this._cookieConsentData.forEach((n) => {\n      n.description = this._getDescriptionCallback(n);\n    }), this.updateConsentData();\n  }\n  updateConsentData() {\n    this._cookieConsentData.forEach((e) => {\n      e.value = this._getConsentCallback(e.type) || e.required;\n    }), E(this._player, m.COOKIE_CONSENT_CHANGED, { cookieConsent: this });\n  }\n  getConsentForType(e) {\n    const t = this._cookieConsentData.find((n) => n.type === e);\n    return (t == null ? void 0 : t.value) || !1;\n  }\n}\nfunction Ks({ container: i }) {\n  i.innerHTML = `\n        <div class=\"timeline-preview hidden\">\n            <img src=\"\" alt=\"\" />\n            <p></p>\n        </div>\n    `;\n  const e = i.querySelector(\"img\"), t = i.querySelector(\"p\"), n = i.querySelector(\".timeline-preview\");\n  return {\n    setImage(a, r) {\n      a !== e.src && (e.src = a, e.alt = r);\n    },\n    setText(a) {\n      t.innerText = a;\n    },\n    setPosition(a) {\n      a > 0.5 ? (n.style.left = \"\", n.style.right = `${100 - a * 100}%`) : (n.style.right = \"\", n.style.left = `${a * 100}%`);\n    },\n    show() {\n      n.classList.remove(\"hidden\");\n    },\n    hide() {\n      n.classList.add(\"hidden\");\n    }\n  };\n}\nfunction Js({ container: i, player: e, duration: t = 100, currentTime: n = 0, precision: s = 100 }) {\n  i.classList.add(\"progress-indicator\"), i.classList.add(\"custom-progress-indicator\"), i.innerHTML = `\n        <div class=\"range-container\">\n            <div class=\"timeline-preview-container\"></div>\n            <div class=\"tracker\">\n                <div class=\"elapsed\"></div>\n                <div class=\"remaining\"></div>\n            </div>\n            <input type=\"range\" min=\"0\" max=\"${t * s}\" value=\"${n * s}\" tabindex=\"0\" role=\"slider\" class=\"slider\">\n            <ul class=\"markers-container\"></ul>\n        </div>\n    `;\n  const a = i.querySelector(\".elapsed\"), r = i.querySelector(\".remaining\"), o = i.querySelector(\".slider\"), l = i.querySelector(\".timeline-preview-container\"), u = Ks({ container: l });\n  let f = !1, h = null;\n  const g = [], L = (c) => {\n    var p;\n    return (p = g.find((C) => C.time < c && C.time + C.frameDuration >= c)) == null ? void 0 : p.marker;\n  }, y = {\n    player: e,\n    elapsed: a,\n    remaining: r,\n    range: o,\n    timeLinePreview: u,\n    markersContainer: i.querySelector(\".markers-container\"),\n    addMarker({ time: c, duration: p, frameDuration: C, addGap: w = !0 }) {\n      const T = b(`<li>\n                <div class=\"elapsed\"></div>\n                <div class=\"remaining\"></div>\n            </li>`);\n      T.style.left = `${c / p * 100}%`, T.style.width = w ? `calc(${C / p * 100}% - var(--slide-marker-gap))` : `${C / p * 100}%`, this.markersContainer.appendChild(T), g.push({\n        marker: T,\n        time: c,\n        frameDuration: C\n      });\n    },\n    updateRemaining() {\n      const c = this.range.value / this.range.max * 100;\n      this.elapsed.style.width = `${c}%`, this.remaining.style.width = `${100 - c}%`;\n      const p = L(this.range.value / s), C = g.findIndex((w) => w.marker === p);\n      g.forEach((w, T) => {\n        if (T < C)\n          w.marker.querySelector(\".elapsed\").style.width = \"100%\", w.marker.querySelector(\".remaining\").style.width = \"0%\";\n        else if (T === C) {\n          const J = (this.range.value / s - w.time) / w.frameDuration * 100;\n          w.marker.querySelector(\".elapsed\").style.width = `${J}%`, w.marker.querySelector(\".remaining\").style.width = `${100 - J}%`;\n        } else\n          w.marker.querySelector(\".elapsed\").style.width = \"0%\", w.marker.querySelector(\".remaining\").style.width = \"100%\";\n      });\n    },\n    setDuration(c) {\n      f || (this.range.max = c * s, this.updateRemaining());\n    },\n    setCurrentTime(c) {\n      f || (this.range.value = c * s, this.updateRemaining());\n    },\n    onChange(c) {\n      h = c;\n    },\n    hideTimeLine() {\n      i.classList.add(\"hide-timeline\");\n    }\n  };\n  o.addEventListener(\"pointerdown\", () => {\n    f = !0;\n  });\n  let v = null;\n  o.addEventListener(\"mousemove\", async (c) => {\n    var C;\n    const p = ((C = e.frameList) == null ? void 0 : C.frames) || [];\n    if (p && p.length) {\n      const w = await e.videoContainer.duration(), T = c.target.clientWidth, H = c.layerX / T, j = H * w, N = p.filter((xi) => xi.time <= j).pop(), Di = N && (N.thumb || N.url), bt = N && ie(w * H), De = L(j);\n      De !== v && v !== null && v.classList.remove(\"active\"), De && De.classList.add(\"active\"), v = De, u.setImage(Di, bt), u.setText(bt), u.setPosition(H), u.show();\n    }\n  }), o.addEventListener(\"mouseleave\", () => {\n    u.hide(), v && v.classList.remove(\"active\");\n  }), o.addEventListener(\"pointerup\", () => {\n    var c;\n    f = !1, (c = document.activeElement) == null || c.blur(), typeof h == \"function\" && h(o.value / s);\n  }), o.addEventListener(\"input\", () => {\n    y.updateRemaining();\n  });\n  const P = async (c) => {\n    const p = await e.videoContainer.currentTime();\n    await e.videoContainer.setCurrentTime(p + c);\n  };\n  return o.addEventListener(\"keydown\", (c) => {\n    c.key === \"ArrowLeft\" ? (P(-10), c.preventDefault(), c.stopPropagation()) : c.key === \"ArrowRight\" && (P(10), c.preventDefault(), c.stopPropagation());\n  }), y.updateRemaining(), y;\n}\nconst x = Object.freeze({\n  DISABLED: 0,\n  ERROR: 1,\n  WARN: 2,\n  INFO: 3,\n  DEBUG: 4,\n  VERBOSE: 5\n});\nlet Ti = x.INFO;\nconst Si = (i, e = null) => {\n  const t = typeof i == \"string\" ? x[i.toUpperCase()] : i;\n  if (t < x.DISABLED || t > x.VERBOSE)\n    throw Error(`setLogLevel: invalid log level ${t}`);\n  e ? (e.__logSettings = e.__logSettings || {}, e.__logSettings.logLevel = t) : Ti = t;\n}, Ii = (i = null) => i ? i.__logSettings.logLevel : Ti, ye = ({\n  msg: i,\n  level: e = x.INFO,\n  player: t = null,\n  context: n = \"paella-core\"\n}) => {\n  t && !t.__logSettings && Si(t, x.INFO);\n  const s = Ii(t);\n  if (e < x.DISABLED)\n    throw Error(`printMessage: invalid log level ${e}`);\n  if (t && E(t, m.LOG, { severity: e, context: n, message: i, currentLogLevel: s }), e <= s)\n    switch (e) {\n      case x.ERROR:\n        console.error(`${n} - Error: ${i}`);\n        break;\n      case x.WARN:\n        console.warn(`${n} - Warning: ${i}`);\n        break;\n      case x.INFO:\n        console.info(`${n} - Info: ${i}`);\n        break;\n      case x.DEBUG:\n        console.debug(`${n} - Debug: ${i}`);\n        break;\n      case x.VERBOSE:\n        console.log(`${n} - Verbose: ${i}`);\n        break;\n    }\n}, X = {\n  setLevel: (i, e = null) => {\n    Si(i, e);\n  },\n  currentLevel: (i = null) => Ii(i),\n  error: (i, e = null, t = \"paella-core\") => {\n    ye({\n      msg: i,\n      level: x.ERROR,\n      player: e,\n      context: t\n    });\n  },\n  warn: (i, e = null, t = \"paella-core\") => {\n    ye({\n      msg: i,\n      level: x.WARN,\n      player: e,\n      context: t\n    });\n  },\n  info: (i, e = null, t = \"paella-core\") => {\n    ye({\n      msg: i,\n      level: x.INFO,\n      player: e,\n      context: t\n    });\n  },\n  debug: (i, e = null, t = \"paella-core\") => {\n    ye({\n      msg: i,\n      level: x.DEBUG,\n      player: e,\n      context: t\n    });\n  },\n  verbose: (i, e = null, t = \"paella-core\") => {\n    ye({\n      msg: i,\n      level: x.VERBOSE,\n      player: e,\n      context: t\n    });\n  }\n};\nclass Xs {\n  constructor(e, t = \"paella-core\") {\n    this._player = e, this._context = t;\n  }\n  get context() {\n    return this._context;\n  }\n  get player() {\n    return this._player;\n  }\n  setLevel(e) {\n    X.setLevel(e, this._player);\n  }\n  currentLevel() {\n    return X.currentLevel(this._player);\n  }\n  error(e, t = null) {\n    X.error(e, this._player, t || this._context);\n  }\n  warn(e, t = null) {\n    X.warn(e, this._player, t || this._context);\n  }\n  info(e, t = null) {\n    X.info(e, this._player, t || this._context);\n  }\n  debug(e, t = null) {\n    X.debug(e, this._player, t || this._context);\n  }\n  verbose(e, t = null) {\n    X.verbose(e, this._player, t || this._context);\n  }\n}\nconst Ut = {}, Ze = '{ \"global\": {}, \"videos\": {} }';\nasync function Ft() {\n  switch (this.source.name) {\n    case \"cookie\":\n      try {\n        return JSON.parse(Z(\"preferences\"));\n      } catch {\n        return JSON.parse(Ze);\n      }\n    case \"dataPlugin\":\n      try {\n        return await this.player.data.read(this.source.context, {}) || JSON.parse(Ze);\n      } catch {\n        return JSON.parse(Ze);\n      }\n  }\n}\nasync function ea(i) {\n  switch (this.source.name) {\n    case \"cookie\":\n      Yt(this.player, this.source.consentType, \"preferences\", JSON.stringify(i));\n      break;\n    case \"dataPlugin\":\n      await this.player.data.write(this.source.context, {}, i);\n      break;\n  }\n}\nclass ta extends de {\n  constructor(e) {\n    super(e);\n    const { currentSource: t, sources: n } = e.config.preferences || {\n      currentSource: \"cookie\",\n      sources: {\n        cookie: {\n          consentType: \"necessary\"\n        }\n      }\n    };\n    if (this.source = n[t], this.source.name = t, this._loaded = !1, !this.source)\n      throw Error(\"Invalid configuration in preferences. Check the configuration file.\");\n  }\n  async set(e, t, { global: n = !1 } = {}) {\n    const s = await Ft.apply(this);\n    n ? s.global[e] = t : (s.videos[this.player.videoId] = s.videos[this.player.videoId] || {}, s.videos[this.player.videoId][e] = t), await ea.apply(this, [s]);\n  }\n  async get(e, { global: t = !1 } = {}) {\n    const n = await Ft.apply(this);\n    return t ? n.global[e] : n.videos[this.player.videoId] && n.videos[this.player.videoId][e] || void 0;\n  }\n}\nfunction ia(i) {\n  var e;\n  (e = this._skinData) != null && e.configOverrides && we(i, this._skinData.configOverrides);\n}\nasync function na() {\n  var i;\n  if ((i = this._skinData) != null && i.styleSheets) {\n    const e = [];\n    this._skinData.styleSheets.forEach((t) => {\n      if (!/\\{.*/.test(t)) if (this._externalResourcesAllowed) {\n        const n = z([this._skinUrl, t]);\n        e.push(new Promise(async (s) => {\n          await dt(n, !1), s();\n        }));\n      } else\n        throw new Error(\"No external resources allowed loading skin object\");\n    }), await Promise.allSettled(e);\n  }\n}\nasync function sa() {\n  var i;\n  if (this.player.__skinStyleSheets__ = this.player.__skinStyleSheets__ || [], (i = this._skinData) != null && i.styleSheets) {\n    const e = [];\n    this._skinData.styleSheets.forEach((t) => {\n      if (/\\{.*/.test(t))\n        e.push(new Promise((n) => {\n          const s = document.createElement(\"style\");\n          s.innerHTML = t, this.player.__skinStyleSheets__.push(s), document.head.appendChild(s), n();\n        }));\n      else {\n        const n = z([this._skinUrl, t]);\n        e.push(new Promise(async (s) => {\n          const a = await dt(n);\n          this.player.__skinStyleSheets__.push(a), s();\n        }));\n      }\n    }), await Promise.allSettled(e);\n  }\n}\nfunction Ot() {\n  this.player.__skinStyleSheets__ = this.player.__skinStyleSheets__ || [], this.player.__skinStyleSheets__.forEach((i) => {\n    Kt(i);\n  }), this.player.__skinStyleSheets__ = [];\n}\nasync function aa() {\n  var i;\n  Array.isArray((i = this._skinData) == null ? void 0 : i.icons) && await Promise.all(this._skinData.icons.map(({ plugin: e, identifier: t, icon: n }) => new Promise(async (s, a) => {\n    const r = document.createElement(\"div\");\n    if (r.innerHTML = n, r.children[0] && r.children[0].tagName === \"svg\")\n      s();\n    else if (this._externalResourcesAllowed) {\n      const o = z([this._skinUrl, n]);\n      (await fetch(o)).ok ? s() : a(new Error(`Skin icon not found at URL '${o}'`));\n    } else\n      throw new Error(\"No external resources allowed loading skin object\");\n  })));\n}\nasync function ra() {\n  var i;\n  Array.isArray((i = this._skinData) == null ? void 0 : i.icons) && await Promise.all(this._skinData.icons.map(({ plugin: e, identifier: t, icon: n }) => new Promise(async (s, a) => {\n    const r = document.createElement(\"div\");\n    if (r.innerHTML = n, r.children[0] && r.children[0].tagName === \"svg\")\n      this.player.addCustomPluginIcon(e, t, n), s();\n    else {\n      const o = z([this._skinUrl, n]), l = await fetch(o);\n      if (l.ok) {\n        const u = await l.text();\n        this.player.addCustomPluginIcon(e, t, u), s();\n      } else\n        a(new Error(`Skin icon not found at URL '${o}'`));\n    }\n  })));\n}\nclass oa {\n  constructor(e) {\n    this._player = e;\n  }\n  get player() {\n    return this._player;\n  }\n  async loadSkin(e) {\n    const t = this._player.state === _.LOADED && !await this._player.paused(), n = this._player.state === _.LOADED ? await this._player.currentTime() : 0;\n    if (typeof e == \"string\") {\n      this._skinUrl = lt(e), this._externalResourcesAllowed = !0;\n      const s = await fetch(e);\n      if (!s.ok)\n        throw new Error(`Error loading skin from URL ${e}`);\n      this._skinData = await s.json();\n    } else typeof e == \"object\" && (this._skinUrl = \"\", this._externalResourcesAllowed = !1, this._skinData = e);\n    try {\n      await na.apply(this), await aa.apply(this), (this._player.state === _.LOADED || this._player.state === _.MANIFEST) && (await this._player.reload(), await this._player.play(), await this._player.setCurrentTime(n), t || await this._player.pause());\n    } catch (s) {\n      throw this._skinUrl = \"\", this._externalResourcesAllowed = !0, this._skinData = {}, s;\n    }\n  }\n  unloadSkin() {\n    var e, t;\n    Array.isArray((e = this._skinData) == null ? void 0 : e.icons) && ((t = this._skinData) == null || t.icons.forEach(({ plugin: n, identifier: s }) => {\n      this.player.removeCustomPluginIcon(n, s);\n    })), this._skinUrl = null, this._skinData = {}, (this._player.state === _.LOADED || this._player.state === _.MANIFEST) && this._player.reload();\n  }\n}\nclass la {\n  constructor(e, t) {\n    this._player = t, this._videoManifest = JSON.parse(JSON.stringify(e)), this._metadata = this._videoManifest.metadata || {}, this._streams = {}, this._frameList = {}, this._trimming = this._videoManifest.trimming, this._captions = this._videoManifest.captions, this._visibleTimeLine = this._videoManifest.visibleTimeLine;\n    function n() {\n      if (this.streams.length !== 1)\n        return null;\n      if (this.isAudioOnly)\n        return this.audioOnlySource.src;\n      const s = this.streams[0];\n      if (!(s.sources.mp4 || s.sources.hls || s.sources.hlsLive))\n        return null;\n      const r = document.createElement(\"video\");\n      if (s.sources.mp4 && s.sources.mp4.length && r.canPlayType(s.sources.mp4[0].mimetype || \"video/mp4\") === \"probably\")\n        return s.sources.mp4[0].src;\n      const o = s.sources.hls || s.sources.hlsLive;\n      return o && o.length && r.canPlayType(o[0].mimetype || \"application/vnd.apple.mpegurl\") !== \"\" && /safari/i.test(navigator.userAgent) ? o[0].src : null;\n    }\n    this._streams = {\n      streams: this._videoManifest.streams,\n      get contents() {\n        return this.streams.map((s) => s.content);\n      },\n      getStream(s) {\n        return this.streams.find((a) => a.content === s);\n      },\n      getSourceTypes(s) {\n        const a = this.getStream(s);\n        return a && Object.keys(a.sources) || null;\n      },\n      getCanvasTypes(s) {\n        const a = this.getStream(s);\n        return a ? a.canvas || [\"video\"] : null;\n      },\n      get isAudioOnly() {\n        const s = this.contents.length === 1 && this.contents[0], a = s && this.getCanvasTypes(s) || [], r = this.getStream(s);\n        return a.length === 1 && a[0] === \"audio\" && r.sources.audio && r.sources.audio.length > 0;\n      },\n      get audioOnlySource() {\n        return this.isAudioOnly ? this.getStream(this.contents[0]).sources.audio[0] : null;\n      },\n      get isNativelyPlayable() {\n        return n.apply(this) !== null;\n      },\n      get nativeSource() {\n        return n.apply(this);\n      },\n      get nativeType() {\n        return this.isNativelyPlayable ? this.isAudioOnly ? \"audio\" : \"video\" : null;\n      },\n      get nativePlayer() {\n        const s = this.nativeType;\n        if (s) {\n          const a = document.createElement(s);\n          return a.src = this.nativeSource, a;\n        } else\n          return null;\n      }\n    }, this._videoManifest.frameList && !Array.isArray(this._videoManifest.frameList) && typeof this._videoManifest.frameList == \"object\" && typeof this._videoManifest.frameList.targetContent == \"string\" && Array.isArray(this._videoManifest.frameList.frames) ? this._frameList = this._videoManifest.frameList : Array.isArray(this._videoManifest.frameList) ? this._frameList = {\n      targetContent: null,\n      frames: this._videoManifest.frameList\n    } : this._frameList = {\n      targetContent: null,\n      frames: []\n    }, this._frameList.frames.sort((s, a) => s.time - a.time), this._frameList.getImage = (s, a = !1) => {\n      var r, o;\n      return (r = this._player) != null && r.videoContainer && this._player._videoContainer.isTrimEnabled && !a ? s += this._player.videoContainer.trimStart : !((o = this._player) != null && o._videoContainer) && !a && console.warn(\"frameList.getImage(): player instance is null. The trimming information will be ignored.\"), [...this._frameList.frames].sort((l, u) => u.time - l.time).find((l) => l.time < s);\n    }, Object.defineProperty(this._frameList, \"isEmpty\", {\n      get() {\n        return Array.isArray(e.frameList) && e.frameList.length === 0 || !e.frameList;\n      }\n    }), Object.freeze(this._metadata), Object.freeze(this._streams), Object.freeze(this._trimming), Object.freeze(this._captions);\n  }\n  get metadata() {\n    return this._metadata;\n  }\n  get streams() {\n    return this._streams;\n  }\n  get frameList() {\n    return this._frameList;\n  }\n  get captions() {\n    return this._captions;\n  }\n  get trimming() {\n    return this._trimming;\n  }\n  get visibleTimeLine() {\n    return this._visibleTimeLine;\n  }\n}\nconst F = Object.freeze([\n  \"UNLOADED\",\n  \"LOADING_MANIFEST\",\n  \"MANIFEST\",\n  \"LOADING_PLAYER\",\n  \"LOADED\",\n  \"UNLOADING_MANIFEST\",\n  \"UNLOADING_PLAYER\",\n  \"ERROR\"\n]);\nfunction ki() {\n  var t, n, s, a, r, o, l, u;\n  const i = ((n = (t = this.videoManifest) == null ? void 0 : t.metadata) == null ? void 0 : n.preview) && Y(this, (a = (s = this.videoManifest) == null ? void 0 : s.metadata) == null ? void 0 : a.preview) || this.defaultVideoPreview, e = ((o = (r = this.videoManifest) == null ? void 0 : r.metadata) == null ? void 0 : o.previewPortrait) && Y(this, (u = (l = this.videoManifest) == null ? void 0 : l.metadata) == null ? void 0 : u.previewPortrait) || this.defaultVideoPreviewPortrait;\n  this._previewContainer = new $s(this, this._containerElement, i, e);\n}\nasync function $t() {\n  this._playerState = _.LOADING_MANIFEST, this._manifestLoaded = !0, this.log.debug(\"Loading paella player\"), this._config = await this.initParams.loadConfig(this.configUrl, this), ia.apply(this.skin, [this._config]), kn(this), this._defaultVideoPreview = this._config.defaultVideoPreview || this._initParams.defaultVideoPreview || \"\", this._defaultVideoPreviewPortrait = this._config.defaultVideoPreviewPortrait || this._initParams.defaultVideoPreviewPortrait || \"\", this._cookieConsent = new Ys(this, {\n    getConsent: this._initParams.getCookieConsentFunction,\n    getDescription: this._initParams.getCookieDescriptionFunction\n  }), this._preferences = new ta(this);\n  const i = new URLSearchParams(window.location.search), e = new URLSearchParams();\n  for (const [s, a] of i)\n    e.append(s.toLowerCase(), a);\n  const t = e.get(\"loglevel\"), n = t && Array.from(Object.keys(x)).indexOf(t.toUpperCase()) !== -1 ? t : this._config.logLevel || \"INFO\";\n  this._log.setLevel(n), await this._initParams.loadDictionaries(this), Es(this), await Qs(this), this._videoContainer = new Rs(this, this._containerElement), await this.videoContainer.create();\n  for (const s of this.pluginModules) {\n    const a = s.getDictionaries && await s.getDictionaries();\n    if (a)\n      for (const r in a)\n        _e(r, a[r]);\n  }\n}\nasync function Bt() {\n  var i, e;\n  this.log.debug(\"Video manifest loaded:\"), this.log.debug(this.videoManifest), this._data = new us(this);\n  for (const t in Ut) {\n    const n = Ut[t];\n    _e(t, n);\n  }\n  if (this._playerState = _.MANIFEST, E(this, m.MANIFEST_LOADED), (e = (i = this.videoManifest) == null ? void 0 : i.metadata) != null && e.preview)\n    ki.apply(this);\n  else\n    throw new Error(\"No preview image found in video manifest, and no default preview image defined.\");\n  Ss(this._videoManifest);\n}\nclass ga {\n  constructor(e, t = {}) {\n    this._log = new Xs(this), this._packageData = Ie, this._log.setLevel(x.VERBOSE), window.__paella_instances__ = window.__paella_instances__ || [], window.__paella_instances__.push(this), this.log.debug(\"New paella player instance\"), typeof e == \"string\" && (e = document.getElementById(e)), e.classList.add(\"player-container\"), this.log.debug(\"Loading skin manager\"), this._skin = new oa(this), this._containerElement = e, this._initParams = t, this._initParams.manifestFileName = this._initParams.manifestFileName || \"data.json\", this._initParams.loadConfig = this._initParams.loadConfig || Vi, this._initParams.getVideoId = this._initParams.getVideoId || Ni, this._initParams.getManifestUrl = this._initParams.getManifestUrl || Ui, this._initParams.getManifestFileUrl = this._initParams.getManifestFileUrl || Fi, this._initParams.loadVideoManifest = this._initParams.loadVideoManifest || Oi, this._initParams.translateFunction = this._initParams.translateFunction || Je, this._initParams.getLanguageFunction = this._initParams.getLanguageFunction || et, this._initParams.setLanguageFunction = this._initParams.setLanguageFunction || Xe, this._initParams.addDictionaryFunction = this._initParams.addDictionaryFunction || tt, this._initParams.getDictionariesFunction = this._initParams.getDictionariesFunction || it, this._initParams.getDefaultLanguageFunction = this._initParams.getDefaultLanguageFunction || nt, this._initParams.Loader = this._initParams.customLoader || Bi, this._initParams.getCookieConsentFunction = this._initParams.getCookieConsentFunction || Pi, this._initParams.getCookieDescriptionFunction = this._initParams.getCookieDescriptionFunction || Ei, this._initParams.getProgressIndicator = this._initParams.getProgressIndicator || Js, this._initParams.loadDictionaries = this._initParams.loadDictionaries || async function(a) {\n      _e(\"en\", {\n        Hello: \"Hello\",\n        World: \"World\"\n      }), _e(\"es\", {\n        Hello: \"Hola\",\n        World: \"Mundo\"\n      }), Et(navigator.language.substring(0, 2));\n    };\n    const n = this._initParams.plugins || [];\n    this._initParams.plugins = [\n      ...n\n    ], Tt(this._initParams.translateFunction), St(this._initParams.setLanguageFunction), It(this._initParams.getLanguageFunction), kt(this._initParams.addDictionaryFunction), Dt(this._initParams.getDictionariesFunction), xt(this._initParams.getDefaultLanguageFunction), this._config = null, this._defaultVideoPreview = \"\", this._defaultVideoPreviewPortrait = \"\", this._videoId = null, this._manifestUrl = null, this._manifestFileUrl = null, this._manifestData = null, this._videoManifest = null, this._playerLoaded = !1;\n    const s = () => {\n      this.resize();\n    };\n    this._resizeEventListener = window.addEventListener(\"resize\", s), this.containerElement.addEventListener(\"fullscreenchange\", () => {\n      E(this, m.FULLSCREEN_CHANGED, { status: this.isFullscreen }), this.isFullscreen ? E(this, m.ENTER_FULLSCREEN) : E(this, m.EXIT_FULLSCREEN);\n    }), this._playerState = _.UNLOADED, this._customPluginIcons = {};\n  }\n  get version() {\n    return this._packageData.version;\n  }\n  get pluginModules() {\n    return this.__pluginModules || [];\n  }\n  get log() {\n    return this._log;\n  }\n  get ready() {\n    return this._playerState === _.LOADED;\n  }\n  get state() {\n    return this._playerState;\n  }\n  get stateText() {\n    return F[this.state];\n  }\n  get Events() {\n    return m;\n  }\n  get preferences() {\n    return this._preferences;\n  }\n  get skin() {\n    return this._skin;\n  }\n  get containsFocus() {\n    return this.containerElement.contains(document.activeElement);\n  }\n  get hideUiTime() {\n    return this._hideUiTime;\n  }\n  set hideUiTime(e) {\n    this._hideUiTime = e;\n  }\n  get containerSize() {\n    return { w: this._containerElement.offsetWidth, h: this._containerElement.offsetHeight };\n  }\n  get containerElement() {\n    return this._containerElement;\n  }\n  get initParams() {\n    return this._initParams;\n  }\n  get cookieConsent() {\n    return this._cookieConsent;\n  }\n  get configLoaded() {\n    return this.configUrl !== null;\n  }\n  get videoManifestLoaded() {\n    return this.videoManifest !== null;\n  }\n  get videoLoaded() {\n    var e;\n    return ((e = this.videoContainer) == null ? void 0 : e.ready) || !1;\n  }\n  get playerLoaded() {\n    return this._playerLoaded;\n  }\n  get configResourcesUrl() {\n    var e;\n    return ((e = this._initParams) == null ? void 0 : e.configResourcesUrl) || \"config/\";\n  }\n  get configUrl() {\n    var e;\n    return ((e = this._initParams) == null ? void 0 : e.configUrl) || \"config/config.json\";\n  }\n  get config() {\n    return this._config;\n  }\n  get defaultVideoPreview() {\n    return this._defaultVideoPreview;\n  }\n  get defaultVideoPreviewPortrait() {\n    return this._defaultVideoPreviewPortrait;\n  }\n  get videoId() {\n    return this._videoId;\n  }\n  // Base URL where the video repository is located, for example \"repository/\"\n  get repositoryUrl() {\n    var e, t;\n    return ((e = this._initParams) == null ? void 0 : e.repositoryUrl) || ((t = this.config) == null ? void 0 : t.repositoryUrl) || \"\";\n  }\n  // Base URL where the video manifest file is located, for example \"repository/[video_id]\"\n  get manifestUrl() {\n    return this._manifestUrl;\n  }\n  // Video manifest file name, for example \"data.json\"\n  get manifestFileName() {\n    var e, t;\n    return ((e = this.config) == null ? void 0 : e.manifestFileName) || ((t = this._initParams) == null ? void 0 : t.manifestFileName) || \"\";\n  }\n  // Full path of the video manifest, for example \"repository/[video_id]/data.json\"\n  get manifestFileUrl() {\n    return this._manifestFileUrl;\n  }\n  // Video manifest file content (data.json)\n  get videoManifest() {\n    return this._videoManifest;\n  }\n  get previewContainer() {\n    return this._previewContainer;\n  }\n  get videoContainer() {\n    return this._videoContainer;\n  }\n  get playbackBar() {\n    return this._playbackBar;\n  }\n  get captionsCanvas() {\n    return this._captionsCanvas;\n  }\n  get data() {\n    return this._data;\n  }\n  get PlayerState() {\n    return _;\n  }\n  get PlayerStateNames() {\n    return F;\n  }\n  // Manifest query functions\n  get metadata() {\n    var e;\n    return ((e = this._manifestParser) == null ? void 0 : e.metadata) || {};\n  }\n  get streams() {\n    var e;\n    return ((e = this._manifestParser) == null ? void 0 : e.streams) || [];\n  }\n  get frameList() {\n    var e;\n    return ((e = this._manifestParser) == null ? void 0 : e.frameList) || { frames: [] };\n  }\n  get captions() {\n    var e;\n    return ((e = this._manifestParser) == null ? void 0 : e.captions) || [];\n  }\n  get trimming() {\n    var e;\n    return ((e = this._manifestParser) == null ? void 0 : e.trimming) || {};\n  }\n  get visibleTimeLine() {\n    var e;\n    return ((e = this._manifestParser) == null ? void 0 : e.visibleTimeLine) || !0;\n  }\n  /**\n   * Translate a word or phrase.\n   * @param {string} word - The word to translate.\n   * @param {Object} [keys=null] - Optional keys for placeholders.\n   * @returns {string} - The translated word.\n   */\n  translate(e, t = null) {\n    return Ce(e, t);\n  }\n  /**\n   * Set the current language.\n   * @param {string} lang - The language code.\n   */\n  setLanguage(e) {\n    Et(e);\n  }\n  /**\n   * Get the current language.\n   * @returns {string} - The current language code.\n   */\n  getLanguage() {\n    return Sn();\n  }\n  /**\n   * Add a dictionary for a specific language.\n   * @param {string} lang - The language code.\n   * @param {Object} dict - The dictionary object.\n   */\n  addDictionary(e, t) {\n    _e(e, t);\n  }\n  /**\n   * Get all loaded dictionaries.\n   * @returns {Object} - The dictionaries.\n   */\n  getDictionaries() {\n    return In();\n  }\n  /**\n   * Get the default language.\n   * @returns {string} - The default language code.\n   */\n  getDefaultLanguage() {\n    return di(this);\n  }\n  /**\n   * Bind an event to the player.\n   * @param {string} eventName - The event name.\n   * @param {Function} fn - The callback function.\n   * @param {boolean} [unregisterOnUnload=true] - Whether to unregister the event on unload.\n   */\n  bindEvent(e, t, n = !0) {\n    M(this, e, (s) => t(s), n);\n  }\n  getPlugin(e, t = null) {\n    if (t) {\n      const n = this.__pluginData__.pluginInstances[t];\n      if (n)\n        return n.find((s) => {\n          if (s.name === e)\n            return s;\n        });\n    } else {\n      const n = {};\n      for (const s in this.__pluginData__.pluginInstances) {\n        const r = this.__pluginData__.pluginInstances[s].find((o) => {\n          if (o.name === e)\n            return o;\n        });\n        r && (n[s] = r);\n      }\n      return n;\n    }\n  }\n  waitState(e) {\n    return new Promise((t, n) => {\n      const s = () => {\n        this.state === e ? t() : setTimeout(s, 50);\n      };\n      typeof e == \"string\" && (e = _[e]), (e < 0 || e > Object.values(_).length) && n(Error(`Invalid player state '${e}'`)), s();\n    });\n  }\n  /**\n   * Load a video from a URL.\n   * @param {string|string[]} url - The video URL(s).\n   * @param {Object} [options] - Additional options.\n   * @param {string} [options.title] - The video title.\n   * @param {number} [options.duration] - The video duration.\n   * @param {string} [options.preview] - The preview image URL.\n   * @param {string} [options.previewPortrait] - The portrait preview image URL.\n   */\n  async loadUrl(e, { title: t, duration: n, preview: s, previewPortrait: a } = {}) {\n    if (this._playerState !== _.UNLOADED)\n      throw new Error(this.translate(\"loadUrl(): Invalid current player state: $1\", [F[this._playerState]]));\n    if (this._manifestLoaded)\n      throw new Error(this.translate(\"loadUrl(): Invalid current player state: $1\", [F[this._playerState]]));\n    if (!e)\n      throw new Error(this.translate(\"loadUrl(): No URL specified.\"));\n    Array.isArray(e) || (e = [e]), t || (t = Me(e[0]), this.log.warn(\"Paella.loadUrl(): no title specified. Using URL file name as video name.\"));\n    try {\n      if (await $t.apply(this), !s && (this.defaultVideoPreview !== \"\" || this.defaultVideoPreviewPortrait !== \"\"))\n        s = this.defaultVideoPreview, a = this.defaultVideoPreviewPortrait, this.log.warn(\"Paella.loadUrl(): no preview image specified. Using default preview image.\");\n      else if (!s && !a)\n        throw new Error(\"Paella.loadUrl(): no preview image specified and no default preview image configured.\");\n      this._videoId = qt(Me(e[0])), this._manifestUrl = lt(e[0]), this._manifestFileUrl = e[0], this.log.debug(`Loading video with identifier '${this.videoId}' from URL '${this.manifestFileUrl}'`);\n      const r = Bn(this, e.length)[0];\n      this._videoManifest = {\n        metadata: {\n          duration: n,\n          title: t,\n          preview: s,\n          previewPortrait: a\n        },\n        streams: e.map((o, l) => ({\n          sources: Ds(this, o),\n          content: r[l],\n          role: l === 0 ? \"mainAudio\" : null\n        }))\n      }, await Bt.apply(this);\n    } catch (r) {\n      throw this._playerState = _.ERROR, this.log.error(r), this._errorContainer = new Ge(this, this.translate(r.message)), r;\n    }\n  }\n  /**\n   * Load the video manifest.\n   */\n  async loadManifest() {\n    if (this._playerState !== _.UNLOADED)\n      throw new Error(this.translate(\"loadManifest(): Invalid current player state: $1\", [F[this._playerState]]));\n    if (!this._manifestLoaded)\n      try {\n        if (await $t.apply(this), this._videoId = await this.initParams.getVideoId(this._config, this), this.videoId === null)\n          throw new Error(\"No video identifier specified\");\n        this._manifestUrl = await this.initParams.getManifestUrl(this.repositoryUrl, this.videoId, this._config, this), this._manifestFileUrl = await this.initParams.getManifestFileUrl(this._manifestUrl, this.manifestFileName, this._config, this), this.log.debug(`Loading video with identifier '${this.videoId}' from URL '${this.manifestFileUrl}'`), this._videoManifest = await this.initParams.loadVideoManifest(this.manifestFileUrl, this._config, this), this._videoManifest.metadata = this._videoManifest.metadata || {}, !this._videoManifest.metadata.preview && (this.defaultVideoPreview !== \"\" || this.defaultVideoPreviewPortrait !== \"\") && (this._videoManifest.metadata.preview = this.defaultVideoPreview, this._videoManifest.metadata.previewPortrait = this.defaultVideoPreviewPortrait, this.log.warn(\"Paella.loadUrl(): no preview image specified. Using default preview image.\")), this._manifestParser = new la(this.videoManifest, this), Ot.apply(this.skin), await ra.apply(this.skin), await sa.apply(this.skin), await Bt.apply(this);\n      } catch (e) {\n        throw this._playerState = _.ERROR, this.log.error(e), this._errorContainer = new Ge(this, this.translate(e.message)), e;\n      }\n  }\n  /**\n   * Load the player interface.\n   */\n  async loadPlayer() {\n    var e, t, n;\n    try {\n      if (this._captionsCanvas = new Ws(this, this._containerElement), this._playerState !== _.MANIFEST)\n        throw new Error(this.translate(\"loadPlayer(): Invalid current player state: $1\", [F[this._playerState]]));\n      this._playerState = _.LOADING_PLAYER, (e = this._previewContainer) == null || e.removeFromParent(), this._loader = new this.initParams.Loader(this), await this._loader.create(), await this.videoContainer.load((t = this.videoManifest) == null ? void 0 : t.streams), E(this, m.STREAM_LOADED), this._playbackBar = new js(this, this.containerElement), await this._playbackBar.load(), this._hideUiTime = ((n = this.config.ui) == null ? void 0 : n.hideUITimer) ?? 5e3, Qt(this), this._captionsCanvas.load(), this._playerState = _.LOADED, await this.videoContainer.updateLayout(), E(this, m.PLAYER_LOADED), !(this.videoManifest.metadata.visibleTimeLine ?? !0) && this.playbackBar.progressIndicator.hideTimeLine(), this._loader.debug || (this._loader.removeFromParent(), this._loader = null);\n    } catch (s) {\n      throw this._playerState = _.ERROR, this._loader && (this._loader.removeFromParent(), this._loader = null), this._errorContainer = new Ge(this, s.message), s;\n    }\n  }\n  /**\n   * Load the player (manifest and interface).\n   */\n  async load() {\n    switch (this.state) {\n      case _.UNLOADED:\n        await this.loadManifest(), await this.loadPlayer();\n        break;\n      case _.MANIFEST:\n        await this.loadPlayer();\n        break;\n      case _.LOADED:\n        break;\n      default:\n        throw new Error(this.translate(\"Could not load player: state transition in progress: $1\", [F[this.state]]));\n    }\n  }\n  /**\n   * Unload the player.\n   */\n  async unload() {\n    switch (this.state) {\n      case _.UNLOADED:\n        break;\n      case _.MANIFEST:\n        await this.unloadManifest();\n        break;\n      case _.LOADED:\n      case _.ERROR:\n        await this.unloadPlayer(), await this.unloadManifest();\n        break;\n      default:\n        throw new Error(this.translate(\"Could not unload player: state transition in progress: $1\", [F[this.state]]));\n    }\n  }\n  /**\n   * Unloads and then completely removes this Paella instance. Reverts all\n   * effects of the constructor. This method is useful for SPAs where\n   * the instance should be completely removed on navigation.\n   */\n  async destroy() {\n    if (await this.unload(), window.removeEventListener(\"resize\", this._resizeEventListener), Tt(Je), St(Xe), It(et), kt(tt), Dt(it), xt(nt), window.__paella_instances__ && typeof window.__paella_instances___ == \"array\") {\n      const e = window.__paella_instances__.indexOf(this);\n      e > -1 && window.__paella_instances__.splice(e, 1);\n    }\n  }\n  /**\n   * Unloads the video manifest and all its resources.\n   * @returns {Promise<void>}\n   */\n  async unloadManifest() {\n    var e;\n    if (this._playerState !== _.MANIFEST && this._playerState !== _.ERROR)\n      throw new Error(this.translate(\"unloadManifest(): Invalid current player state: $1\", [F[this._playerState]]));\n    this._errorContainer && (this._errorContainer.removeFromParent(), this._errorContainer = null), this._playerState = _.UNLOADING_MANIFEST, this.log.debug(\"Unloading paella player\"), await Zs(), await Ts(this), this._manifestLoaded = !1, (e = this._previewContainer) == null || e.removeFromParent(), this._preferences = null, this._playerState = _.UNLOADED, Ot.apply(this.skin);\n  }\n  /**\n   * Unload the player interface.\n   * @returns {Promise<void>}\n   */\n  async unloadPlayer() {\n    var e, t, n, s, a;\n    if (this._playerState !== _.LOADED && this._playerState !== _.ERROR)\n      throw new Error(this.translate(\"unloadManifest(): Invalid current player state: $1\", [F[this._playerState]]));\n    this._errorContainer && (this._errorContainer.removeFromParent(), this._errorContainer = null), this._playerState = _.UNLOADING_PLAYER, await ((e = this._videoContainer) == null ? void 0 : e.unload()), this._videoContainer = null, await ((t = this._playbackBar) == null ? void 0 : t.unload()), this._playbackBar = null, (n = this._captionsCanvas) == null || n.unload(), this._captionsCanvas = null, Zt(this), E(this, m.PLAYER_UNLOADED), (a = (s = this.videoManifest) == null ? void 0 : s.metadata) != null && a.preview && ki.apply(this), Ai(this), this._playerState = _.MANIFEST;\n  }\n  /**\n   * Reload the player.\n   * @param {Function} [onUnloadFn=null] - Function to call after unloading.\n   * @returns {Promise<void>}\n   */\n  async reload(e = null) {\n    switch (this.state) {\n      case _.UNLOADED:\n        break;\n      case _.MANIFEST:\n        await this.unloadManifest();\n        break;\n      case _.LOADED:\n        await this.unload();\n        break;\n    }\n    typeof e == \"function\" && await e(), await this.load();\n  }\n  async resize() {\n    var e, t;\n    if ((e = this.videoContainer) == null || e.updateLayout(), (t = this.playbackBar) == null || t.onResize(), this.videoContainer) {\n      const n = () => ({\n        w: this.videoContainer.element.offsetWidth,\n        h: this.videoContainer.element.offsetHeight\n      });\n      E(this, m.RESIZE, { size: n() }), this._resizeEndTimer && clearTimeout(this._resizeEndTimer), this._resizeEndTimer = setTimeout(() => {\n        E(this, m.RESIZE_END, { size: n() });\n      }, 1e3);\n    }\n  }\n  /**\n   * Hide the user interface.\n   * @returns {Promise<void>}\n   */\n  async hideUserInterface() {\n    var e, t, n;\n    await ((e = this.videoContainer) == null ? void 0 : e.paused()) || (this._uiHidden = !0, (t = this.videoContainer) == null || t.hideUserInterface(), (n = this.playbackBar) == null || n.hideUserInterface(), E(this, m.HIDE_UI));\n  }\n  /**\n   * Show the user interface.\n   * @returns {Promise<void>}\n   */\n  async showUserInterface() {\n    var e, t;\n    (e = this.videoContainer) == null || e.showUserInterface(), (t = this.playbackBar) == null || t.showUserInterface(), this._uiHidden && E(this, m.SHOW_UI), this._uiHidden = !1;\n  }\n  /**\n   * Play the video.\n   * @returns {Promise<void>}\n   */\n  async play() {\n    return this.videoContainer.ready || await this.loadPlayer(), await this.videoContainer.play();\n  }\n  /**\n   * Pause the video.\n   * @returns {Promise<void>}\n   */\n  async pause() {\n    var e;\n    return await ((e = this.videoContainer) == null ? void 0 : e.pause());\n  }\n  /**\n   * Toggle between play and pause.\n   * @returns {Promise<void>}\n   */\n  async togglePlay() {\n    return this.videoContainer.ready ? await this.paused() ? await this.play() : await this.pause() : await this.play();\n  }\n  /**\n   * Check if the video is paused.\n   * @returns {Promise<boolean>}\n   */\n  async paused() {\n    return this.videoContainer ? this.videoContainer.paused() : !0;\n  }\n  /**\n   * Stop the video.\n   * @returns {Promise<void>}\n   */\n  async stop() {\n    var e;\n    return await ((e = this.videoContainer) == null ? void 0 : e.stop());\n  }\n  /**\n   * Set the current playback time.\n   * @param {number} t - The time in seconds.\n   * @returns {Promise<void>}\n   */\n  async setCurrentTime(e) {\n    var t;\n    return await ((t = this.videoContainer) == null ? void 0 : t.setCurrentTime(e));\n  }\n  /**\n   * Get the current playback time.\n   * @returns {Promise<number>}\n   */\n  async currentTime() {\n    var e;\n    return (e = this.videoContainer) == null ? void 0 : e.currentTime();\n  }\n  /**\n   * Get the current volume.\n   * @returns {Promise<number>}\n   */\n  async volume() {\n    var e;\n    return (e = this.videoContainer) == null ? void 0 : e.volume();\n  }\n  /**\n   * Set the volume.\n   * @param {number} v - The volume level (0-1).\n   * @returns {Promise<void>}\n   */\n  async setVolume(e) {\n    var t;\n    return (t = this.videoContainer) == null ? void 0 : t.setVolume(e);\n  }\n  /**\n   * Get the video duration.\n   * @returns {Promise<number>}\n   */\n  async duration() {\n    var e;\n    return (e = this.videoContainer) == null ? void 0 : e.duration();\n  }\n  /**\n   * Get the playback rate.\n   * @returns {Promise<number>}\n   */\n  async playbackRate() {\n    var e;\n    return (e = this.videoContainer) == null ? void 0 : e.playbackRate();\n  }\n  /**\n   * Set the playback rate.\n   * @param {number} r - The playback rate.\n   * @returns {Promise<void>}\n   */\n  async setPlaybackRate(e) {\n    var t;\n    return (t = this.videoContainer) == null ? void 0 : t.setPlaybackRate(e);\n  }\n  /**\n   * Skip forward by a number of seconds.\n   * @param {number} s - The number of seconds to skip.\n   * @returns {Promise<void>}\n   */\n  async skipSeconds(e) {\n    const t = await this.currentTime();\n    return await this.setCurrentTime(t + e);\n  }\n  /**\n   * Rewind by a number of seconds.\n   * @param {number} s - The number of seconds to rewind.\n   * @returns {Promise<void>}\n   */\n  async rewindSeconds(e) {\n    const t = await this.currentTime();\n    return await this.setCurrentTime(t - e);\n  }\n  /**\n   * Check if fullscreen is supported.\n   * @returns {boolean}\n   */\n  isFullScreenSupported() {\n    return this.containerElement.requestFullscreen || this.containerElement.webkitRequestFullScreen;\n  }\n  /**\n   * Enter fullscreen mode.\n   * @returns {Promise<void>}\n   */\n  async enterFullscreen() {\n    let e = null;\n    return this.containerElement.requestFullscreen ? e = this.containerElement.requestFullscreen() : this.containerElement.webkitRequestFullScreen && (this.log.debug(\"Safari enter fullscreen\"), e = this.containerElement.webkitRequestFullScreen()), setTimeout(() => this.resize(), 500), e;\n  }\n  /**\n   * Exit fullscreen mode.\n   * @returns {Promise<void>}\n   */\n  async exitFullscreen() {\n    if (document.exitFullscreen && this.isFullscreen)\n      return document.exitFullscreen();\n    if (document.webkitCancelFullScreen && this.isFullscreen)\n      return this.log.debug(\"Safari exit fullscreen\"), document.webkitCancelFullScreen();\n  }\n  /**\n   * Check if the player is in fullscreen mode.\n   * @returns {boolean}\n   */\n  get isFullscreen() {\n    return document.fullscreenElement === this.containerElement || document.webkitFullscreenElement === this.containerElement;\n  }\n  /**\n   * Add a custom plugin icon.\n   * @param {string} pluginName - The plugin unique identifier, for example `es.upv.paella.playPauseButton`.\n   * @param {string} iconName - The icon name in the plugin.\n   * @param {string} svgData - The SVG data for the icon.\n   */\n  addCustomPluginIcon(e, t, n) {\n    this._customPluginIcons[`${e}-${t}`] = n;\n  }\n  /**\n   *  Remove a custom plugin icon.\n   * @param {string} pluginName - The plugin unique identifier, for example `es.upv.paella.playPauseButton`.\n   * @param {string} iconName - The icon name in the plugin.\n   */\n  removeCustomPluginIcon(e, t) {\n    this._customPluginIcons[`${e}-${t}`] = null;\n  }\n  /**\n   * Get a custom plugin icon.\n   * @param {string} pluginName - The plugin name.\n   * @param {string} iconName - The icon name.\n   * @returns {string|null} - The SVG data for the icon, or null if not found.\n   */\n  getCustomPluginIcon(e, t) {\n    return this._requestedCustomIcons = this._requestedCustomIcons || [], this._requestedCustomIcons.find((n) => n.pluginName === e && n.iconName === t) || this._requestedCustomIcons.push({\n      pluginName: e,\n      iconName: t\n    }), this._customPluginIcons[`${e}-${t}`];\n  }\n  /**\n   * Get the list of requested custom icons.\n   * @type {Array}\n   */\n  get requestedCustomIcons() {\n    return this._requestedCustomIcons || [];\n  }\n}\nclass ma {\n  constructor({\n    id: e,\n    name: t,\n    groupId: n = \"\",\n    language: s = \"\",\n    selected: a = !1\n  }) {\n    this._id = e, this._name = t, this._groupId = n, this._lang = s, this._selected = a;\n  }\n  get id() {\n    return this._id;\n  }\n  get name() {\n    return this._name;\n  }\n  get groupId() {\n    return this._groupId;\n  }\n  get language() {\n    return this._lang;\n  }\n  get selected() {\n    return this._selected;\n  }\n  set selected(e) {\n    this._selected = e;\n  }\n}\nexport {\n  gn as AudioOnlyVideo,\n  ma as AudioTrackData,\n  mn as AudioVideoPlugin,\n  Ls as ButtonGroupPlugin,\n  ft as ButtonPlugin,\n  mi as Canvas,\n  da as CanvasButtonPlugin,\n  S as CanvasButtonPosition,\n  fi as CanvasPlugin,\n  ni as Captions,\n  ii as CaptionsPlugin,\n  $n as CurrentTimeLabelPlugin,\n  En as DFXPParser,\n  us as Data,\n  _i as DataPlugin,\n  Tn as DfxpManifestCaptionsPlugin,\n  G as DomClass,\n  Vt as DualVideoDynamicLayoutPlugin,\n  Jn as DualVideoLayoutPlugin,\n  pa as EventLogPlugin,\n  m as Events,\n  ei as HtmlVideo,\n  fn as HtmlVideoFormatPlugin,\n  wn as ImageVideo,\n  Cn as ImageVideoFormatPlugin,\n  x as LOG_LEVEL,\n  Bi as Loader,\n  Xs as Log,\n  la as ManifestParser,\n  bs as MenuButtonPlugin,\n  bn as Mp4Video,\n  Ln as Mp4VideoFormatPlugin,\n  ga as Paella,\n  ge as PaellaCorePlugins,\n  Rn as PlayPauseButtonPlugin,\n  de as PlayerResource,\n  _ as PlayerState,\n  F as PlayerStateNames,\n  he as Plugin,\n  Fe as PluginModule,\n  gs as PopUpButtonPlugin,\n  ts as SingleVideoLayoutPlugin,\n  as as TripleVideoLayoutPlugin,\n  gt as UserInterfacePlugin,\n  pt as Video,\n  ls as VideoCanvas,\n  cs as VideoCanvasPlugin,\n  U as VideoContainerMessagePosition,\n  me as VideoLayout,\n  Ue as VideoPlugin,\n  yn as VideoQualityItem,\n  On as VttManifestCaptionsPlugin,\n  Fn as WebVTTParser,\n  _e as addDictionary,\n  M as bindEvent,\n  Ss as checkManifestIntegrity,\n  Jt as createElement,\n  b as createElementWithHtmlText,\n  Js as createProgressIndicator,\n  Ks as createTimeLinePreview,\n  tt as defaultAddDictionaryFunction,\n  Pi as defaultGetCookieConsentCallback,\n  Ei as defaultGetCookieDescriptionCallback,\n  nt as defaultGetDefaultLanguageFunction,\n  it as defaultGetDictionariesFunction,\n  et as defaultGetLanguageFunction,\n  Fi as defaultGetManifestFileUrlFunction,\n  Ui as defaultGetManifestUrlFunction,\n  Ni as defaultGetVideoIdFunction,\n  Vi as defaultLoadConfigFunction,\n  Oi as defaultLoadVideoManifestFunction,\n  Xe as defaultSetLanguageFunction,\n  Je as defaultTranslateFunction,\n  di as getDefaultLanguage,\n  In as getDictionaries,\n  Sn as getLanguage,\n  vi as getPluginsOfType,\n  ha as importPlugins,\n  Wi as isVolumeApiAvailable,\n  $ as loadPluginsOfType,\n  X as log,\n  Pt as parseDFXP,\n  Rt as parseWebVTT,\n  ps as plugins,\n  Et as setLanguage,\n  Ce as translate,\n  E as triggerEvent,\n  se as triggerIfReady,\n  ua as utils\n};\n//# sourceMappingURL=paella-core.js.map\n","import de from \"./i18n/de-DE.json\";\nimport en from \"./i18n/en-US.json\";\nimport es from \"./i18n/es-ES.json\";\n\nconst defaultDictionaries = {\n    de,\n    en,\n    es\n};\n\nexport default defaultDictionaries;","import { PluginModule } from \"@asicupv/paella-core\";\nimport packageData from \"../../package.json\";\nimport dictionaries from '../dictionaries';\n\nlet g_pluginModule = null;\n\nexport default class ZoomPluginsModule extends PluginModule {\n    static Get() {\n        if (!g_pluginModule) {\n            g_pluginModule = new ZoomPluginsModule();\n        }\n        return g_pluginModule;\n    }\n\n    get moduleName() {\n        return packageData.name;\n    }\n\n    get moduleVersion() {\n        return packageData.version;\n    }\n\n    async getDictionaries() {\n        return dictionaries;\n    }\n}","import { CanvasPlugin, Canvas, createElementWithHtmlText } from '@asicupv/paella-core';\nimport ZoomPluginsModule from './ZoomPluginsModule';\n\nimport \"../styles/zoom.css\";\n\n\nfunction setZoom(container, playerElement, newZoom) {\n    const containerSize = {\n        w: container.offsetWidth,\n        h: container.offsetHeight\n    };\n    const containerCenter = {\n        left: containerSize.w / 2,\n        top: containerSize.h / 2 \n    }\n    \n    playerElement.style.width = `${newZoom * 100}%`;\n    playerElement.style.height = `${newZoom * 100}%`;\n\n    const playerSize = {\n        left: playerElement.offsetLeft,\n        top: playerElement.offsetTop,\n        w: playerElement.offsetWidth,\n        h: playerElement.offsetHeight\n    };\n    const playerCenter = {\n        left: playerSize.w / 2,\n        top: playerSize.h / 2\n    };\n    const offset = {\n        left: playerCenter.left - containerCenter.left,\n        top: playerCenter.top - containerCenter.top\n    };\n    \n    if (newZoom == 1) {\n        playerElement.style.left = `0px`;\n        playerElement.style.top = `0px`;\n        offset.left = containerCenter.left;\n        offset.top = containerCenter.top;\n    }\n    else {\n        playerElement.style.left = `-${offset.left}px`;\n        playerElement.style.top = `-${offset.top}px`;\n    }\n\n    return offset;\n}\n\nfunction movePlayer(player, currentPosition, offset) {\n    const newPosition = {\n        left: currentPosition.left + offset.left,\n        top: currentPosition.top + offset.top\n    }\n    const parent = player.parentElement;\n    \n    player.style.top = `-${newPosition.top}px`;\n\n    const top = (player.offsetHeight + player.offsetTop) - parent.offsetHeight;\n    if (top<0) {\n        newPosition.top = currentPosition.top;\n    }\n\n    player.style.left = `-${newPosition.left}px`;\n    const left = (player.offsetWidth + player.offsetLeft) - parent.offsetWidth;\n    if (left<0) {\n        newPosition.left = currentPosition.left;\n    }\n\n    return newPosition;\n}\n\nexport class ZoomCanvas extends Canvas {\n    constructor(player, videoContainer, config) {\n        super('div', player, videoContainer);\n        this.config = config;\n        this._maxZoom = this.config.maxZoom || 4;\n        this._showButtons = this.config.showButtons!==undefined ? this.config.showButtons : true;\n    }\n\n    async loadCanvas(player) {\n        this.currentZoom = 1;\n        this._videoPlayer = player;\n\n        player.element.style.width = \"100%\";\n        player.element.style.height = \"100%\";\n        player.element.style.position = \"absolute\";\n        player.element.style.top = \"0\";\n        player.element.style.left = \"0\";\n\n        this.element.style.overflow = \"hidden\";\n        this.element.style.position = \"relative\";\n\n        const zoomHandle = evt => {\n            evt.stopPropagation();\n            if (!evt.altKey) {\n                this.showAltKeyMessage();\n                return;\n            }\n            this.hideAltKeyMessage();\n            const delta = evt.deltaY !== undefined ? evt.deltaY * 0.1 : evt.detail * 4;\n            const newZoom = this.currentZoom + delta * -0.01;\n            if (newZoom>1 && newZoom<=this._maxZoom) {\n                this.currentZoom = newZoom;\n                this._playerCenter = setZoom(this.element, this._videoPlayer.element, this.currentZoom);\n            }\n            else if (newZoom <= 1) {\n                this.currentZoom = 1;\n                this._playerCenter = setZoom(this.element, this._videoPlayer.element, this.currentZoom);\n            }\n            evt.preventDefault();\n        };\n        \n        this.element.addEventListener(\"DOMMouseScroll\", zoomHandle);\n        this.element.addEventListener(\"mousewheel\", zoomHandle);\n\n        let drag = false;\n        let preventClick = false;\n        let dragPosition = null;\n        const beginDrag = () => drag = true;\n        const endDrag = () => drag = false;\n        const cancelClick = evt => {\n            if (preventClick) {\n                evt.stopPropagation();\n                evt.preventDefault();\n            }\n        }\n        this.element.addEventListener(\"mousedown\", beginDrag);\n        this.element.addEventListener(\"mouseleave\", endDrag);\n        this.element.addEventListener(\"mouseup\", endDrag);\n        this.element.addEventListener(\"click\", cancelClick);\n        this.element.addEventListener(\"mouseup\", cancelClick);\n\n        this.element.addEventListener(\"mousemove\", evt => {\n            if (drag && this._playerCenter) {\n                if (dragPosition === null) {\n                    dragPosition = { left: evt.clientX, top: evt.clientY };\n                }\n                preventClick = true;\n                const offset = { \n                    left: dragPosition.left - evt.clientX, \n                    top: dragPosition.top - evt.clientY\n                };\n                if (this.currentZoom == 1) {\n                    this._playerCenter = { left: 0, top: 0 };\n                }\n                else {\n                    this._playerCenter = movePlayer(this._videoPlayer.element, this._playerCenter, offset);\n                }\n                dragPosition = { left: evt.clientX, top: evt.clientY };\n            }\n            else {\n                preventClick = false;\n                dragPosition = null;\n            }\n        });\n\n        // \"press alt\" message\n        const message = this.player.translate(\"Use Alt+Scroll to zoom\");\n        this._zoomMessage = createElementWithHtmlText(`\n            <div class=\"zoom-message\">${message}</div>\n        `, this.element);\n        this._zoomMessage.style.display = \"none\";\n    }\n\n    showAltKeyMessage() {\n        if (this._hideTimeout) {\n            clearTimeout(this._hideTimeout);\n        }\n        this._zoomMessage.style.display = \"\";\n        this._hideTimeout = setTimeout(() => {\n            this.hideAltKeyMessage();\n        }, 2000);\n    }\n\n    hideAltKeyMessage() {\n        this._zoomMessage.style.display = \"none\";\n        this._hideTimeout = null;\n    }\n\n    zoomIn() {\n        const zoom = this.currentZoom * 1.1;\n        if (zoom<this._maxZoom) {\n            this.currentZoom = zoom;\n            this._playerCenter = setZoom(this.element, this._videoPlayer.element, this.currentZoom);\n        }\n    }\n\n    zoomOut() {\n        const zoom = this.currentZoom * 0.9;\n        if (zoom>=1) {\n            this.currentZoom = zoom;\n            this._playerCenter = setZoom(this.element, this._videoPlayer.element, this.currentZoom);\n        }\n    }\n}\n\nexport default class ZoomCanvasPlugin extends CanvasPlugin {\n    getPluginModuleInstance() {\n        return ZoomPluginsModule.Get();\n    }\n\n    get name() {\n        return super.name || \"es.upv.paella.zoomPlugin\";\n    }\n\n    get canvasType() { return \"video\"; }\n\n    isCompatible(stream) {\n        if (!Array.isArray(stream.canvas) || stream.canvas.length === 0) {\n            // By default, the default canvas is HTML video canvas\n            return true;\n        }\n        \n        return super.isCompatible(stream);\n    }\n\n    getCanvasInstance(videoContainer) {\n        return new ZoomCanvas(this.player, videoContainer, this.config);\n    }\n}\n","\nexport const ZoomInIcon = `<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 32 32\" style=\"fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;\">\n    <path d=\"M17.094,18.048C15.976,18.956 14.551,19.5 13,19.5C9.413,19.5 6.5,16.587 6.5,13C6.5,9.413 9.413,6.5 13,6.5C16.587,6.5 19.5,9.413 19.5,13C19.5,14.522 18.976,15.923 18.098,17.031L19.553,18.487C20.094,17.958 20.962,17.962 21.498,18.498L25.522,22.522C26.062,23.062 26.062,23.938 25.522,24.478L24.519,25.481C23.98,26.02 23.103,26.02 22.563,25.481L18.539,21.457C18,20.917 18,20.041 18.539,19.501L18.543,19.497L17.094,18.048ZM13,8C15.76,8 18,10.24 18,13C18,15.76 15.76,18 13,18C10.24,18 8,15.76 8,13C8,10.24 10.24,8 13,8ZM13.927,11.886L15.927,11.886L15.927,13.886L13.927,13.886L13.927,15.886L11.927,15.886L11.927,13.886L9.927,13.886L9.927,11.886L11.927,11.886L11.927,9.886L13.927,9.886L13.927,11.886Z\"/>\n</svg>`;\n","import { ButtonPlugin } from '@asicupv/paella-core';\nimport { ZoomCanvas } from './es.upv.paella.zoomPlugin';\n\nimport ZoomPluginsModule from './ZoomPluginsModule';\n\nimport { ZoomInIcon as defaultZoomInButton } from '../icons/mini-zoom-in.js';\n\nexport default class ZoomInButtonPlugin extends ButtonPlugin {\n    getPluginModuleInstance() {\n        return ZoomPluginsModule.Get();\n    }\n\n    get name() {\n        return super.name || \"es.upv.paella.zoomInButtonPlugin\";\n    }\n\n    getAriaLabel() {\n        return \"Zoom in\";\n    }\n\n    getDescription() {\n        return this.getAriaLabel();\n    }\n\n    async isEnabled() {\n        if (!(await super.isEnabled())) {\n            return false;\n        }\n        \n        this.target = this.config.target;\n        this._canvas = this.player.videoContainer.streamProvider.streams[this.target].canvas;\n        return this._canvas instanceof ZoomCanvas;\n    }\n\n    async load() {\n        this.icon = this.player.getCustomPluginIcon(this.name,\"zoomInIcon\") || defaultZoomInButton;\n    }\n\n    async action() {\n        this._canvas.zoomIn();\n    }\n}\n","export const ZoomOutIcon = `<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 32 32\" version=\"1.1\" style=\"fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;\">\n    <path d=\"M17.094,18.048C15.976,18.956 14.551,19.5 13,19.5C9.413,19.5 6.5,16.587 6.5,13C6.5,9.413 9.413,6.5 13,6.5C16.587,6.5 19.5,9.413 19.5,13C19.5,14.522 18.976,15.923 18.098,17.031L19.553,18.487C20.094,17.958 20.962,17.962 21.498,18.498L25.522,22.522C26.062,23.062 26.062,23.938 25.522,24.478L24.519,25.481C23.98,26.02 23.103,26.02 22.563,25.481L18.539,21.457C18,20.917 18,20.041 18.539,19.501L18.543,19.497L17.094,18.048ZM13,8C15.76,8 18,10.24 18,13C18,15.76 15.76,18 13,18C10.24,18 8,15.76 8,13C8,10.24 10.24,8 13,8ZM9.927,11.886L15.927,11.886L15.927,13.886L9.927,13.886L9.927,11.886Z\"/>\n</svg>`;\n","import { ButtonPlugin } from '@asicupv/paella-core';\nimport { ZoomCanvas } from './es.upv.paella.zoomPlugin';\nimport ZoomPluginsModule from './ZoomPluginsModule';\n\nimport { ZoomOutIcon as defaultZoomOutButton } from '../icons/mini-zoom-out.js';\n\nexport default class ZoomOutButtonPlugin extends ButtonPlugin {\n    getPluginModuleInstance() {\n        return ZoomPluginsModule.Get();\n    }\n\n    get name() {\n        return super.name || \"es.upv.paella.zoomOutButtonPlugin\";\n    }\n\n    getAriaLabel() {\n        return \"Zoom out\";\n    }\n\n    getDescription() {\n        return this.getAriaLabel();\n    }\n\n    async isEnabled() {\n        if (!(await super.isEnabled())) {\n            return false;\n        }\n        \n        this.target = this.config.target;\n        this._canvas = this.player.videoContainer.streamProvider.streams[this.target].canvas;\n        return this._canvas instanceof ZoomCanvas;\n    }\n\n    async load() {\n        this.icon = this.player.getCustomPluginIcon(this.name,\"zoomOutIcon\") || defaultZoomOutButton;\n    }\n\n    async action() {\n        this._canvas.zoomOut();\n    }\n}\n","import { MenuButtonPlugin } from '@asicupv/paella-core';\nimport { ZoomCanvas } from './es.upv.paella.zoomPlugin';\n\nimport ZoomPluginsModule from './ZoomPluginsModule';\n\nimport { ZoomInIcon as defaultZoomInButton } from '../icons/mini-zoom-in.js';\nimport { ZoomOutIcon as defaultZoomOutButton } from '../icons/mini-zoom-out.js';\n\nexport default class ZoomMenuButtonPlugin extends MenuButtonPlugin {\n    getPluginModuleInstance() {\n        return ZoomPluginsModule.Get();\n    }\n\n    get name() {\n        return super.name || \"es.upv.paella.zoomMenuButtonPlugin\";\n    }\n\n    getAriaLabel() {\n        return \"Show video zoom options\";\n    }\n\n    getDescription() {\n        return this.getAriaLabel();\n    }\n\n    async isEnabled() {\n        if (!(await super.isEnabled())) {\n            return false;\n        }\n        \n        this._target = this.config.target || \"presenter\";\n        this._canvas = this.player.videoContainer.streamProvider.streams[this._target].canvas;\n        return this._canvas instanceof ZoomCanvas;\n    }\n\n    async load() {\n        this.icon = this.player.getCustomPluginIcon(this.name,\"zoomInIcon\") || defaultZoomInButton;\n    }\n\n    async getMenu() {\n        return [\n            {\n                id: \"in\",\n                title: \"Zoom in\",\n                icon: this.player.getCustomPluginIcon(this.name,\"zoomInIcon\") || defaultZoomInButton\n            },\n            {\n                id: \"out\",\n                title: \"Zoom out\",\n                icon: this.player.getCustomPluginIcon(this.name,\"zoomOutIcon\") || defaultZoomOutButton\n            }\n        ]\n    }\n\n    get buttonType() {\n        return \"button\"\n    }\n\n    get showTitles() {\n        return false;\n    }\n\n    itemSelected(itemData) {\n        switch (itemData.id) {\n        case \"in\":\n            this._canvas.zoomIn();\n            break;\n        case \"out\":\n            this._canvas.zoomOut();\n            break;\n        }\n    }\n}\n","import { CanvasButtonPlugin } from \"@asicupv/paella-core\";\nimport { ZoomCanvas } from \"./es.upv.paella.zoomPlugin\";\n\nimport ZoomPluginsModule from \"./ZoomPluginsModule\";\n\nimport { ZoomInIcon as defaultZoomInButton } from '../icons/mini-zoom-in.js';\n\nexport default class CanvasZoomInButtonPlugin extends CanvasButtonPlugin {\n    getPluginModuleInstance() {\n        return ZoomPluginsModule.Get();\n    }\n\n    get name() {\n        return super.name || \"es.upv.paella.canvasZoomInButtonPlugin\";\n    }\n\n    async isEnabled() {\n        if (!(await super.isEnabled())) {\n            return false;\n        }\n        \n        let result = false;\n        this._streams = this.player.videoContainer.streamProvider.streams;\n        for (const s in this._streams) {\n            result ||= this._streams[s].canvas instanceof ZoomCanvas;\n        }\n        \n        return result;\n    }\n    \n    async load() {\n        this.icon = this.player.getCustomPluginIcon(this.name,\"zoomInIcon\") || defaultZoomInButton;\n    }\n\n    async action(content, videoPlayer, videoCanvas, canvasPlugin) {\n        if (videoCanvas instanceof ZoomCanvas) {\n            videoCanvas.zoomIn();\n        }\n    }\n}","import { CanvasButtonPlugin } from \"@asicupv/paella-core\";\nimport { ZoomCanvas } from \"./es.upv.paella.zoomPlugin\";\n\nimport ZoomPluginsModule from \"./ZoomPluginsModule\";\n\nimport { ZoomOutIcon as defaultZoomOutButton } from '../icons/mini-zoom-out.js';\n\nexport default class CanvasZoomOutButtonPlugin extends CanvasButtonPlugin {\n    getPluginModuleInstance() {\n        return ZoomPluginsModule.Get();\n    }\n\n    get name() {\n        return super.name || \"es.upv.paella.canvasZoomOutButtonPlugin\";\n    }\n\n    async isEnabled() {\n        if (!(await super.isEnabled())) {\n            return false;\n        }\n        \n        let result = false;\n        this._streams = this.player.videoContainer.streamProvider.streams;\n        for (const s in this._streams) {\n            result ||= this._streams[s].canvas instanceof ZoomCanvas;\n        }\n        \n        return result;\n    }\n    \n    async load() {\n        this.icon = this.player.getCustomPluginIcon(this.name,\"zoomOutIcon\") || defaultZoomOutButton;\n    }\n\n    async action(content, videoPlayer, videoCanvas, canvasPlugin) {\n        if (videoCanvas instanceof ZoomCanvas) {\n            videoCanvas.zoomOut();\n        }\n    }\n}","import ZoomCanvas from './plugins/es.upv.paella.zoomPlugin';\nimport ZoomInButton from './plugins/es.upv.paella.zoomInButtonPlugin';\nimport ZoomOutButton from './plugins/es.upv.paella.zoomOutButtonPlugin';\nimport ZoomMenuButton from './plugins/es.upv.paella.zoomMenuButtonPlugin';\nimport CanvasZoomInButton from './plugins/es.upv.paella.canvasZoomInButtonPlugin';\nimport CanvasZoomOutButton from './plugins/es.upv.paella.canvasZoomOutButtonPlugin';\n\nexport const zoomPlugins = [\n    {\n        plugin: ZoomCanvas,\n        config: {\n            enabled: false\n        }\n    },\n    {\n        plugin: ZoomInButton,\n        config: {\n            enabled: false\n        }\n    },\n    {\n        plugin: ZoomOutButton,\n        config: {\n            enabled: false\n        }\n    },\n    {\n        plugin: ZoomMenuButton,\n        config: {\n            enabled: false\n        }\n    },\n    {\n        plugin: CanvasZoomInButton,\n        config: {\n            enabled: false\n        }\n    },\n    {\n        plugin: CanvasZoomOutButton,\n        config: {\n            enabled: false\n        }\n    }\n];\n\nexport const allPlugins = zoomPlugins;\n\nexport const ZoomCanvasPlugin = ZoomCanvas;\nexport const ZoomInButtonPlugin = ZoomInButton;\nexport const ZoomOutButtonPlugin = ZoomOutButton;\nexport const ZoomMenuButtonPlugin = ZoomMenuButton;\nexport const CanvasZoomInButtonPlugin = CanvasZoomInButton;\nexport const CanvasZoomOutButtonPlugin = CanvasZoomOutButton;\n"],"names":["Lt","i","Be","e","t","d","I","k","n","ze","ut","Ke","s","be","de$1","Jt","a","r","b","V","G","de","he","Fe","gt","At","Dn","Le","st","q","W","Pe","ft","o","l","da","S","mi","fi","gs","ms","fs","ys","_s","vs","ws","Cs","u","f","h","g","L","y","v","P","c","w","C","T","bs","defaultDictionaries","g_pluginModule","ZoomPluginsModule","PluginModule","packageData","dictionaries","setZoom","container","playerElement","newZoom","containerSize","containerCenter","playerSize","playerCenter","offset","movePlayer","player","currentPosition","newPosition","parent","ZoomCanvas","Canvas","videoContainer","config","zoomHandle","evt","delta","drag","preventClick","dragPosition","beginDrag","endDrag","cancelClick","message","createElementWithHtmlText","zoom","CanvasPlugin","stream","ZoomInIcon","ButtonPlugin","defaultZoomInButton","ZoomOutIcon","defaultZoomOutButton","MenuButtonPlugin","itemData","CanvasButtonPlugin","result","content","videoPlayer","videoCanvas","canvasPlugin","zoomPlugins","ZoomInButton","ZoomOutButton","ZoomMenuButton","CanvasZoomInButton","CanvasZoomOutButton","allPlugins","ZoomCanvasPlugin","ZoomInButtonPlugin","ZoomOutButtonPlugin","ZoomMenuButtonPlugin","CanvasZoomInButtonPlugin","CanvasZoomOutButtonPlugin"],"mappings":"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"}